diff options
| author | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 20:20:15 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 20:20:15 -0800 |
| commit | 5bf3be033f504f5fd79690fbb13d720407314e40 (patch) | |
| tree | 96b4fdb8c54f2477829c648e6078a0e54f5e7a6e | |
| parent | 98b8803038fa999212c37952adad1e04144f0ab7 (diff) | |
v2.4.10.1 -> v2.4.10.2
- me/Al Viro: fix bdget() oops with block device modules that don't
clean up after they exit
- Alan Cox: continued merging (drivers, license tags)
- David Miller: sparc update, network fixes
- Christoph Hellwig: work around broken drivers that add a gendisk more
than once
- Jakub Jelinek: handle more ELF loading special cases
- Trond Myklebust: NFS client and lockd reclaimer cleanups/fixes
- Greg KH: USB updates
- Mikael Pettersson: sparate out local APIC / IO-APIC config options
820 files changed, 16703 insertions, 10798 deletions
@@ -603,6 +603,13 @@ S: Alexandra Terrace S: Guildford, GU1 3DA S: United Kingdom +N: Cristian Mihail Craciunescu +W: http://www.dnt.ro/~cristi/ +E: cristi@dnt.ro +D: Support for Xircom PGSDB9 (firmware and host driver) +S: Bucharest +S: Romania + N: Laurence Culhane E: loz@holmes.demon.co.uk D: Wrote the initial alpha SLIP code diff --git a/Documentation/Configure.help b/Documentation/Configure.help index dcb1390f6568..599a550017f5 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -120,17 +120,30 @@ CONFIG_SMP If you don't know what to do here, say N. -APIC and IO-APIC Support on Uniprocessors +IO-APIC Support on Uniprocessors CONFIG_X86_UP_IOAPIC - APIC (Advanced Programmable Interrupt Controller) is a scheme for - delivering hardware interrupt requests to the CPU. It is commonly - used on systems with several CPU's. If you have a single-CPU system - which uses APIC, you can say Y here to use it. If you say Y here - even though your machine doesn't have APIC, then the kernel will - still run with no slowdown at all. - - If you have system with several CPU's, you do not need to say Y - here: APIC will be used automatically. + An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an + SMP-capable replacement for PC-style interrupt controllers. Most + SMP systems and a small number of uniprocessor systems have one. + If you have a single-CPU system with an IO-APIC, you can say Y here + to use it. If you say Y here even though your machine doesn't have + an IO-APIC, then the kernel will still run with no slowdown at all. + + If you have a system with several CPUs, you do not need to say Y + here: the IO-APIC will be used automatically. + +Local APIC Support on Uniprocessors +CONFIG_X86_UP_APIC + A local APIC (Advanced Programmable Interrupt Controller) is an + integrated interrupt controller in the CPU. If you have a single-CPU + system which has a processor with a local APIC, you can say Y here to + enable and use it. If you say Y here even though your machine doesn't + have a local APIC, then the kernel will still run with no slowdown at + all. The local APIC supports CPU-generated self-interrupts (timer, + performance counters), and the NMI watchdog which detects hard lockups. + + If you have a system with several CPUs, you do not need to say Y + here: the local APIC will be used automatically. Kernel math emulation CONFIG_MATH_EMULATION diff --git a/Documentation/DocBook/mousedrivers.tmpl b/Documentation/DocBook/mousedrivers.tmpl index f349d1c4db71..d5d19703068b 100644 --- a/Documentation/DocBook/mousedrivers.tmpl +++ b/Documentation/DocBook/mousedrivers.tmpl @@ -241,16 +241,12 @@ void cleanup_module(void) <programlisting> struct file_operations our_mouse_fops = { - NULL, /* Mice don't seek */ - read_mouse, /* You can read a mouse */ - write_mouse, /* This won't do a lot */ - NULL, /* No readdir - not a directory */ - poll_mouse, /* Poll */ - NULL, /* No ioctl calls */ - NULL, /* No mmap */ - open_mouse, /* Called on open */ - NULL, /* Flush - 2.2+ only */ - close_mouse, /* Called on close */ + owner: THIS_MODULE, /* Automatic usage management */ + read: read_mouse, /* You can read a mouse */ + write: write_mouse, /* This won't do a lot */ + poll: poll_mouse, /* Poll */ + open: open_mouse, /* Called on open */ + release: close_mouse, /* Called on close */ }; </programlisting> @@ -262,6 +258,18 @@ struct file_operations our_mouse_fops = { configuration interfaces via ioctl calls. </para> <para> + The syntax we use is not standard C as such. GCC provides the ability + to initialise fields by name, and this generally makes the method table + much easier to read than counting through NULL pointers and remembering + the order by hand. + </para> + <para> + The owner field is used to manage the locking of module load an + unloading. It is obviously important that a module is not unloaded while + in use. When your device is opened the module specified by "owner" is + locked. When it is finally released the module is unlocked. + </para> + <para> The open and close routines need to manage enabling and disabling the interrupts for the mouse as well as stopping the mouse being unloaded when it is no longer required. @@ -278,12 +286,9 @@ static int open_mouse(struct inode *inode, struct file *file) if(mouse_users++) return 0; - MOD_INC_USE_COUNT; - if(request_irq(mouse_intr, OURMOUSE_IRQ, 0, "ourmouse", NULL)) { mouse_users--; - MOD_DEC_USE_COUNT; return -EBUSY; } mouse_dx = 0; @@ -301,11 +306,6 @@ static int open_mouse(struct inode *inode, struct file *file) <returnvalue>0</returnvalue> for success. </para> <para> - Firstly we use <function>MOD_INC_USE_COUNT</function> to ensure that - while the mouse is open nobody will unload it and cause a nasty crash. - We must do this before we sleep - and grabbing the interrupt might sleep. - </para> - <para> We grab the interrupt and thus start mouse interrupts. If the interrupt has been borrowed by some other driver then <function>request_irq</function> will fail and we will return an error. If we were capable of sharing an @@ -328,7 +328,6 @@ static int close_mouse(struct inode *inode, struct file *file) if(--mouse_users) return 0; free_irq(OURMOUSE_IRQ, NULL); - MOD_DEC_USE_COUNT; return 0; } </programlisting> @@ -336,8 +335,7 @@ static int close_mouse(struct inode *inode, struct file *file) We count off a user and provided that there are still other users need take no further action. The last person closing the mouse causes us to free up the interrupt. This stops interrupts from the mouse from using - our CPU time, and lets us use <function>MOD_DEC_USE_COUNT</function> so - that the mouse can now be unloaded. + our CPU time, and ensures that the mouse can now be unloaded. </para> <para> We can fill in the write handler at this point as the write function for @@ -718,14 +716,14 @@ static void ourmouse_interrupt(int irq, void *dev_id, struct pt_regs *regs) struct wait_queue wait = { current, NULL }; add_wait_queue(&mouse_wait, &wait); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); while(!mouse_event) { if(file->f_flags&O_NDELAY) { remove_wait_queue(&mouse_wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EWOULDBLOCK; } if(signal_pending(current)) @@ -735,11 +733,11 @@ static void ourmouse_interrupt(int irq, void *dev_id, struct pt_regs *regs) return -ERESTARTSYS; } schedule(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); } remove_wait_wait(&mouse_wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); </programlisting> <para> @@ -889,18 +887,13 @@ static void ourmouse_interrupt(int irq, void *dev_id, struct pt_regs *regs) <programlisting> struct file_operations our_mouse_fops = { - NULL, /* Mice don't seek */ - read_mouse, /* You can read a mouse */ - write_mouse, /* This won't do a lot */ - NULL, /* No readdir - not a directory */ - poll_mouse, /* Poll */ - NULL, /* No ioctl calls */ - NULL, /* No mmap */ - open_mouse, /* Called on open */ - NULL, /* Flush */ - close_mouse, /* Called on close */ - NULL, /* No fsync on a mouse */ - fasync_mouse, /* Asynchronous I/O */ + owner: THIS_MODULE + read: read_mouse, /* You can read a mouse */ + write: write_mouse, /* This won't do a lot */ + poll: poll_mouse, /* Poll */ + open: open_mouse, /* Called on open */ + release: close_mouse, /* Called on close */ + fasync: fasync_mouse, /* Asynchronous I/O */ }; </programlisting> diff --git a/Documentation/fb/matroxfb.txt b/Documentation/fb/matroxfb.txt index 83b529fd64da..508aaa1878ef 100644 --- a/Documentation/fb/matroxfb.txt +++ b/Documentation/fb/matroxfb.txt @@ -216,6 +216,13 @@ dfp - enables digital flat panel interface. This option is incompatible wit secondary (TV) output - if DFP is active, TV output must be inactive and vice versa. DFP always uses same timing as primary (monitor) output. +dfp:X - use settings X for digital flat panel interface. X is number from + 0 to 0xFF, and meaning of each individual bit is described in + G400 manual, in description of DAC register 0x1F. For normal operation + you should set all bits to zero, except lowest bit. This lowest bit + selects who is source of display clocks, whether G400, or panel. + Default value is now read back from hardware - so you should specify + this value only if you are also using `init' parameter. vesa:X - selects startup videomode. X is number from 0 to 0x1FF, see table above for detailed explanation. Default is 640x480x8bpp if driver has 8bpp support. Otherwise first available of 640x350x4bpp, @@ -280,6 +287,8 @@ Currently there are following known bugs: + interlaced text mode is not supported; it looks like hardware limitation, but I'm not sure. + Gxx0 SGRAM/SDRAM is not autodetected. + + If you are using more than one framebuffer device, you must boot kernel + with 'video=scrollback:0'. + maybe more... And following misfeatures: + SVGALib does not restore screen on exit. diff --git a/Documentation/filesystems/fat_cvf.txt b/Documentation/filesystems/fat_cvf.txt index 9082cbe4e9da..25bbe2d128ab 100644 --- a/Documentation/filesystems/fat_cvf.txt +++ b/Documentation/filesystems/fat_cvf.txt @@ -112,7 +112,7 @@ struct cvf_format int (*mount_cvf) (struct super_block*sb,char*options); int (*unmount_cvf) (struct super_block*sb); [...] - void (*cvf_zero_cluster) (struct inode*inode,int clusternr); + void (*zero_out_cluster) (struct inode*, int clusternr); } This structure defines the capabilities of a CVF module. It must be filled @@ -161,8 +161,8 @@ It contains... functions. NULL means use the original FAT driver functions instead. If you really want "no action", write a function that does nothing and hang it in instead. - - cvf_zero_cluster: - The cvf_zero_cluster function is called when the fat driver wants to + - zero_out_cluster: + The zero_out_cluster function is called when the fat driver wants to zero out a (new) cluster. This is important for directories (mkdir). If it is NULL, the FAT driver defaults to overwriting the whole cluster with zeros. Note that clusternr is absolute, not relative diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt index 21ffe7b06bd4..0b1f791c05df 100644 --- a/Documentation/oops-tracing.txt +++ b/Documentation/oops-tracing.txt @@ -201,3 +201,26 @@ Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com 820 4th St. N. Fargo, ND 58122 Phone: 701-234-7556 + + +--------------------------------------------------------------------------- +Tainted kernels: + +Some oops reports contain the string 'Tainted: ' after the program +counter, this indicates that the kernel has been tainted by some +mechanism. The string is followed by a series of position sensitive +characters, each representing a particular tainted value. + + 1: 'G' if all modules loaded have a GPL or compatible license, 'P' if + any proprietary module has been loaded. Modules without a + MODULE_LICENSE or with a MODULE_LICENSE that is not recognised by + insmod as GPL compatible are assumed to be proprietary. + + 2: 'F' if any module was force loaded by insmod -f, ' ' if all + modules were loaded normally. + +The primary reason for the 'Tainted: ' string is to tell kernel +debuggers if this is a clean kernel or if anything unusual has +occurred. Tainting is permanent, even if an offending module is +unloading the tainted value remains to indicate that the kernel is not +trustworthy. diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 171578283634..fdff7a57850e 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -39,6 +39,7 @@ show up in /proc/sys/kernel: - rtsig-max - sg-big-buff [ generic SCSI device (sg) ] - shmmax [ sysv ipc ] +- tainted - version - zero-paged [ PPC only ] @@ -220,6 +221,19 @@ kernel. This value defaults to SHMMAX. ============================================================== +tainted: + +Non-zero if the kernel has been tainted. Numeric values, which +can be ORed together: + + 1 - A module with a non-GPL license has been loaded, this + includes modules with no license. + Set by modutils >= 2.4.9. + 2 - A module was force loaded by insmod -f. + Set by modutils >= 2.4.9. + +============================================================== + zero-paged: (PPC only) When enabled (non-zero), Linux-PPC will pre-zero pages in diff --git a/MAINTAINERS b/MAINTAINERS index 19fd52b67e9f..54d70521487c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -132,6 +132,14 @@ L: linux-sound@vger.kernel.org W: http://www.uni-karlsruhe.de/~Robert.Siemer/Private/ S: Maintained +ACP/MWAVE MODEM +P: Paul B Schroeder +M: paulsch@us.ibm.com +P: Mike Sullivan +M: sullivam@us.ibm.com +W: http://www.ibm.com/linux/ltc/ +S: Supported + ACPI P: Andy Grover M: andrew.grover@intel.com @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 11 -EXTRAVERSION =-pre1 +EXTRAVERSION =-pre2 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 4b655b3430a2..e4ca5f6ac724 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -214,7 +214,8 @@ show_regs(struct pt_regs * regs) { printk("\n"); printk("Pid: %d, comm: %20s\n", current->pid, current->comm); - printk("ps: %04lx pc: [<%016lx>] CPU %d\n", regs->ps, regs->pc, smp_processor_id()); + printk("ps: %04lx pc: [<%016lx>] CPU %d %s\n", + regs->ps, regs->pc, smp_processor_id(), print_tainted()); printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1); printk(" r0: %016lx r1: %016lx r2: %016lx r3: %016lx\n", regs->r0, regs->r1, regs->r2, regs->r3); diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index ca4d01f5cf0b..4b6f52900b6f 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -53,8 +53,8 @@ opDEC_check(void) void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15) { - printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx\n", - regs->pc, regs->r26, regs->ps); + printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx %s\n", + regs->pc, regs->r26, regs->ps, print_tainted()); printk("v0 = %016lx t0 = %016lx t1 = %016lx\n", regs->r0, regs->r1, regs->r2); printk("t2 = %016lx t3 = %016lx t4 = %016lx\n", diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 5c9d87a7d00b..f3440360866e 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -158,10 +158,10 @@ void show_regs(struct pt_regs * regs) flags = condition_codes(regs); - printk("pc : [<%08lx>] lr : [<%08lx>]\n" + printk("pc : [<%08lx>] lr : [<%08lx>] %s\n" "sp : %08lx ip : %08lx fp : %08lx\n", instruction_pointer(regs), - regs->ARM_lr, regs->ARM_sp, + regs->ARM_lr, print_tainted(), regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); printk("r10: %08lx r9 : %08lx r8 : %08lx\n", regs->ARM_r10, regs->ARM_r9, diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c index 9fcda3abd2b8..48cec40d0cb9 100644 --- a/arch/cris/kernel/traps.c +++ b/arch/cris/kernel/traps.c @@ -138,8 +138,8 @@ show_registers(struct pt_regs * regs) register. */ unsigned long usp = rdusp(); - printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", - regs->irp, regs->srp, regs->dccr, usp, regs->mof ); + printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx %s\n", + regs->irp, regs->srp, regs->dccr, usp, regs->mof, print_tainted()); printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", regs->r0, regs->r1, regs->r2, regs->r3); printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", diff --git a/arch/i386/config.in b/arch/i386/config.in index d3ef1ed5e4a2..e79f163d9c42 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -170,10 +170,13 @@ bool 'Math emulation' CONFIG_MATH_EMULATION bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR bool 'Symmetric multi-processing support' CONFIG_SMP if [ "$CONFIG_SMP" != "y" ]; then - bool 'APIC and IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC + bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC + dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC + if [ "$CONFIG_X86_UP_APIC" = "y" ]; then + define_bool CONFIG_X86_LOCAL_APIC y + fi if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then define_bool CONFIG_X86_IO_APIC y - define_bool CONFIG_X86_LOCAL_APIC y fi fi diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 9c8a891632cc..23cd39973a17 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -311,7 +311,6 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR_D700 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set CONFIG_SCSI_SYM53C8XX=y @@ -753,6 +752,7 @@ CONFIG_USB_STORAGE=y # # CONFIG_USB_PEGASUS is not set # CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_USBNET is not set diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 922c62923261..03f124138beb 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -689,7 +689,6 @@ static void apm_power_off(void) (void) apm_set_power_state(APM_STATE_OFF); } -#ifdef CONFIG_MAGIC_SYSRQ /* * Magic sysrq key and handler for the power off function */ @@ -703,7 +702,6 @@ struct sysrq_key_op sysrq_poweroff_op = { help_msg: "Off", action_msg: "Power Off\n" }; -#endif #ifdef CONFIG_APM_DO_ENABLE @@ -1672,7 +1670,7 @@ static int __init apm_init(void) apm_info.realmode_power_off = 1; /* User can override, but default is to trust DMI */ if (apm_disabled != -1) - apm_info.disabled = 1; + apm_info.disabled = apm_disabled; /* * Fix for the Compaq Contura 3/25c which reports BIOS version 0.1 @@ -1699,8 +1697,7 @@ static int __init apm_init(void) } if (apm_info.disabled) { - if(apm_disabled == 1) - printk(KERN_NOTICE "apm: disabled on user request.\n"); + printk(KERN_NOTICE "apm: disabled on user request.\n"); return -ENODEV; } if ((smp_num_cpus > 1) && !power_off) { diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 7d1635f2a31e..a49ecf616b99 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -442,7 +442,7 @@ void show_regs(struct pt_regs * regs) printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs,regs->eip, smp_processor_id()); if (regs->xcs & 3) printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); - printk(" EFLAGS: %08lx\n",regs->eflags); + printk(" EFLAGS: %08lx %s\n",regs->eflags, print_tainted()); printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", regs->eax,regs->ebx,regs->ecx,regs->edx); printk("ESI: %08lx EDI: %08lx EBP: %08lx", diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 03181864d651..d0e694913d00 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -200,8 +200,8 @@ void show_registers(struct pt_regs *regs) esp = regs->esp; ss = regs->xss & 0xffff; } - printk("CPU: %d\nEIP: %04x:[<%08lx>]\nEFLAGS: %08lx\n", - smp_processor_id(), 0xffff & regs->xcs, regs->eip, regs->eflags); + printk("CPU: %d\nEIP: %04x:[<%08lx>] %s\nEFLAGS: %08lx\n", + smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags); printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->eax, regs->ebx, regs->ecx, regs->edx); printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index d1fc4cb4e92c..004b93544d14 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -63,8 +63,8 @@ show_regs (struct pt_regs *regs) { unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; - printk("\npsr : %016lx ifs : %016lx ip : [<%016lx>]\n", - regs->cr_ipsr, regs->cr_ifs, ip); + printk("\npsr : %016lx ifs : %016lx ip : [<%016lx>] %s\n", + regs->cr_ipsr, regs->cr_ifs, ip, print_tainted()); printk("unat: %016lx pfs : %016lx rsc : %016lx\n", regs->ar_unat, regs->ar_pfs, regs->ar_rsc); printk("rnat: %016lx bsps: %016lx pr : %016lx\n", diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 6052ecd225a6..c62ca9f008d8 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -109,8 +109,8 @@ void machine_power_off(void) void show_regs(struct pt_regs * regs) { printk("\n"); - printk("Format %02x Vector: %04x PC: %08lx Status: %04x\n", - regs->format, regs->vector, regs->pc, regs->sr); + printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n", + regs->format, regs->vector, regs->pc, regs->sr, print_tainted()); printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n", regs->orig_d0, regs->d0, regs->a2, regs->a1); printk("A0: %08lx D5: %08lx D4: %08lx\n", diff --git a/arch/mips/mm/mips32.c b/arch/mips/mm/mips32.c index a4bac6eddb53..4e16f4b4acc5 100644 --- a/arch/mips/mm/mips32.c +++ b/arch/mips/mm/mips32.c @@ -739,8 +739,8 @@ void show_regs(struct pt_regs * regs) regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); /* Saved cp0 registers. */ - printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, regs->cp0_status, regs->cp0_cause); + printk("epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", + regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause); } void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, diff --git a/arch/mips/mm/r2300.c b/arch/mips/mm/r2300.c index 25fd07bc1d19..f1244c655118 100644 --- a/arch/mips/mm/r2300.c +++ b/arch/mips/mm/r2300.c @@ -665,8 +665,10 @@ void show_regs(struct pt_regs * regs) /* * Saved cp0 registers */ - printk("epc : %08lx\nStatus: %08x\nCause : %08x\n", - (unsigned long) regs->cp0_epc, (unsigned int) regs->cp0_status, + printk("epc : %08lx %s\nStatus: %08x\nCause : %08x\n", + (unsigned long) regs->cp0_epc, + print_tainted(), + (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause); } diff --git a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c index fdb468daecd4..30f94d6e5a9c 100644 --- a/arch/mips/mm/r4xx0.c +++ b/arch/mips/mm/r4xx0.c @@ -2364,8 +2364,8 @@ void show_regs(struct pt_regs * regs) regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); /* Saved cp0 registers. */ - printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, regs->cp0_status, regs->cp0_cause); + printk("epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", + regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause); } void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, diff --git a/arch/mips/mm/r5432.c b/arch/mips/mm/r5432.c index 1b9c0cbe9a92..b380ac3d5033 100644 --- a/arch/mips/mm/r5432.c +++ b/arch/mips/mm/r5432.c @@ -765,8 +765,8 @@ void show_regs(struct pt_regs * regs) regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); /* Saved cp0 registers. */ - printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, regs->cp0_status, regs->cp0_cause); + printk("epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", + regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause); } void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, diff --git a/arch/mips/mm/rm7k.c b/arch/mips/mm/rm7k.c index 313a77495278..407e8a592e8a 100644 --- a/arch/mips/mm/rm7k.c +++ b/arch/mips/mm/rm7k.c @@ -507,8 +507,8 @@ void show_regs(struct pt_regs * regs) regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); /* Saved cp0 registers. */ - printk(KERN_INFO "epc : %08lx\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, regs->cp0_status, regs->cp0_cause); + printk(KERN_INFO "epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", + regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause); } void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, diff --git a/arch/mips64/mm/andes.c b/arch/mips64/mm/andes.c index 487639887f62..f9d3cc2c07ca 100644 --- a/arch/mips64/mm/andes.c +++ b/arch/mips64/mm/andes.c @@ -326,8 +326,8 @@ static void andes_show_regs(struct pt_regs *regs) printk("Lo : %016lx\n", regs->lo); /* Saved cp0 registers. */ - printk("epc : %016lx\nbadvaddr: %016lx\n", - regs->cp0_epc, regs->cp0_badvaddr); + printk("epc : %016lx %s\nbadvaddr: %016lx\n", + regs->cp0_epc, print_tainted(), regs->cp0_badvaddr); printk("Status : %08x\nCause : %08x\n", (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause); } diff --git a/arch/mips64/mm/r4xx0.c b/arch/mips64/mm/r4xx0.c index 59f52ce36233..8338b520cb80 100644 --- a/arch/mips64/mm/r4xx0.c +++ b/arch/mips64/mm/r4xx0.c @@ -2109,8 +2109,8 @@ static void r4k_show_regs(struct pt_regs *regs) printk("Lo : %016lx\n", regs->lo); /* Saved cp0 registers. */ - printk("epc : %016lx\nbadvaddr: %016lx\n", - regs->cp0_epc, regs->cp0_badvaddr); + printk("epc : %016lx %s\nbadvaddr: %016lx\n", + regs->cp0_epc, print_tainted(), regs->cp0_badvaddr); printk("Status : %08x\nCause : %08x\n", (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause); } diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index d8555370208a..d901209f27cc 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -82,7 +82,7 @@ void show_regs(struct pt_regs *regs) printk(" YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\nPSW: "); printbinary(regs->gr[0], 32); - printk("\n"); + printk(" %s\n", print_tainted()); for (i = 0; i < 32; i += 4) { int j; diff --git a/arch/parisc/mm/pa11.c b/arch/parisc/mm/pa11.c index 42f0d57f6278..0b2db6674db7 100644 --- a/arch/parisc/mm/pa11.c +++ b/arch/parisc/mm/pa11.c @@ -127,8 +127,9 @@ static void pa11_show_regs(struct pt_regs * regs) /* * Saved cp0 registers */ - printk("epc : %08lx\nStatus: %08x\nCause : %08x\n", - (unsigned long) regs->cp0_epc, (unsigned int) regs->cp0_status, + printk("epc : %08lx %s\nStatus: %08x\nCause : %08x\n", + (unsigned long) regs->cp0_epc, print_tainted(), + (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause); } diff --git a/arch/parisc/mm/pa20.c b/arch/parisc/mm/pa20.c index cbc0343a0113..069c916ca65e 100644 --- a/arch/parisc/mm/pa20.c +++ b/arch/parisc/mm/pa20.c @@ -127,8 +127,9 @@ static void pa20_show_regs(struct pt_regs * regs) /* * Saved cp0 registers */ - printk("epc : %08lx\nStatus: %08x\nCause : %08x\n", - (unsigned long) regs->cp0_epc, (unsigned int) regs->cp0_status, + printk("epc : %08lx %s\nStatus: %08x\nCause : %08x\n", + (unsigned long) regs->cp0_epc, print_tainted(), + (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause); } diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 1ada6a519cbf..008125b44638 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -243,8 +243,8 @@ void show_regs(struct pt_regs * regs) { int i; - printk("NIP: %08lX XER: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx\n", - regs->nip, regs->xer, regs->link, regs->gpr[1], regs,regs->trap); + printk("NIP: %08lX XER: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx %s\n", + regs->nip, regs->xer, regs->link, regs->gpr[1], regs,regs->trap, print_tainted()); printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 2278f89c24ec..8b35ad8f8e70 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -191,8 +191,8 @@ SMIException(struct pt_regs *regs) void UnknownException(struct pt_regs *regs) { - printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", - regs->nip, regs->msr, regs->trap); + printk("Bad trap at PC: %lx, SR: %lx, vector=%lx %s\n", + regs->nip, regs->msr, regs->trap, print_tainted()); _exception(SIGTRAP, regs); } @@ -338,9 +338,9 @@ StackOverflow(struct pt_regs *regs) void trace_syscall(struct pt_regs *regs) { - printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld\n", + printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n", current, current->pid, regs->nip, regs->link, regs->gpr[0], - regs->ccr&0x10000000?"Error=":"", regs->gpr[3]); + regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted()); } #ifdef CONFIG_8xx @@ -376,8 +376,8 @@ SoftwareEmulation(struct pt_regs *regs) void TAUException(struct pt_regs *regs) { - printk("TAU trap at PC: %lx, SR: %lx, vector=%lx\n", - regs->nip, regs->msr, regs->trap); + printk("TAU trap at PC: %lx, SR: %lx, vector=%lx %s\n", + regs->nip, regs->msr, regs->trap, print_tainted()); } #endif /* CONFIG_INT_TAU */ diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 365e6ed543d8..368ed1da536e 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -129,9 +129,10 @@ static int sprintf_regs(int line, char *buff, struct task_struct *task, struct p break; case sp_psw: if(regs) - linelen=sprintf(buff, "%s PSW: %08lx %08lx\n", mode, + linelen=sprintf(buff, "%s PSW: %08lx %08lx %s\n", mode, (unsigned long) regs->psw.mask, - (unsigned long) regs->psw.addr); + (unsigned long) regs->psw.addr, + print_tainted()); else linelen=sprintf(buff,"pt_regs=NULL some info unavailable\n"); break; diff --git a/arch/s390x/kernel/process.c b/arch/s390x/kernel/process.c index 9b19fd185d00..f0f504a834f1 100644 --- a/arch/s390x/kernel/process.c +++ b/arch/s390x/kernel/process.c @@ -133,9 +133,10 @@ static int sprintf_regs(int line, char *buff, struct task_struct *task, struct p break; case sp_psw: if(regs) - linelen=sprintf(buff, "%s PSW: %016lx %016lx\n", mode, + linelen=sprintf(buff, "%s PSW: %016lx %016lx %s\n", mode, (unsigned long) regs->psw.mask, - (unsigned long) regs->psw.addr); + (unsigned long) regs->psw.addr, + print_tainted()); else linelen=sprintf(buff,"pt_regs=NULL some info unavailable\n"); break; diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index cfbc41b68924..e31ddbd7fc8b 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -81,8 +81,8 @@ void machine_power_off(void) void show_regs(struct pt_regs * regs) { printk("\n"); - printk("PC : %08lx SP : %08lx SR : %08lx TEA : %08x\n", - regs->pc, regs->regs[15], regs->sr, ctrl_inl(MMU_TEA)); + printk("PC : %08lx SP : %08lx SR : %08lx TEA : %08x %s\n", + regs->pc, regs->regs[15], regs->sr, ctrl_inl(MMU_TEA), print_tainted()); printk("R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", regs->regs[0],regs->regs[1], regs->regs[2],regs->regs[3]); diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 1820eb12a865..fc07121c823e 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -268,8 +268,8 @@ void show_stackframe(struct sparc_stackf *sf) void show_regs(struct pt_regs * regs) { - printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx\n", regs->psr, - regs->pc, regs->npc, regs->y); + printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx %s\n", regs->psr, + regs->pc, regs->npc, regs->y, print_tainted()); printk("g0: %08lx g1: %08lx g2: %08lx g3: %08lx ", regs->u_regs[0], regs->u_regs[1], regs->u_regs[2], regs->u_regs[3]); diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index 6cf5fbe74903..34e289ed2843 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.99 2001/07/17 16:17:33 anton Exp $ +/* $Id: init.c,v 1.100 2001/09/21 22:51:47 davem Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 4ceb4ee89c05..a396f202be89 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -753,6 +753,7 @@ CONFIG_USB_DABUSB=m # CONFIG_USB_PEGASUS=m CONFIG_USB_CATC=m +CONFIG_USB_CDCETHER=m CONFIG_USB_KAWETH=m CONFIG_USB_USBNET=m diff --git a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S index bfdd713eb23a..b74c15fce09e 100644 --- a/arch/sparc64/kernel/dtlb_backend.S +++ b/arch/sparc64/kernel/dtlb_backend.S @@ -1,4 +1,4 @@ -/* $Id: dtlb_backend.S,v 1.14 2001/09/07 18:26:17 kanoj Exp $ +/* $Id: dtlb_backend.S,v 1.15 2001/09/24 21:54:09 davem Exp $ * dtlb_backend.S: Back end to DTLB miss replacement strategy. * This is included directly into the trap table. * @@ -13,12 +13,14 @@ sllx %g2, 62, r1 #define FILL_VALID_SZ_BITS2(r1) #define FILL_VALID_SZ_BITS_NOP nop -#else /* PAGE_SHIFT */ +#elif PAGE_SHIFT == 16 #define FILL_VALID_SZ_BITS1(r1) \ or %g0, 5, r1 #define FILL_VALID_SZ_BITS2(r1) \ sllx r1, 61, r1 #define FILL_VALID_SZ_BITS_NOP +#else +#error unsupported PAGE_SIZE #endif /* PAGE_SHIFT */ #define VPTE_BITS (_PAGE_CP | _PAGE_CV | _PAGE_P ) diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index f1a739402819..01ec3fe6c110 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -282,8 +282,8 @@ void __show_regs(struct pt_regs * regs) local_irq_count(smp_processor_id()), irqs_running()); #endif - printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x\n", regs->tstate, - regs->tpc, regs->tnpc, regs->y); + printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x %s\n", regs->tstate, + regs->tpc, regs->tnpc, regs->y, print_tainted()); printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n", regs->u_regs[0], regs->u_regs[1], regs->u_regs[2], regs->u_regs[3]); @@ -349,8 +349,8 @@ void show_regs(struct pt_regs *regs) void show_regs32(struct pt_regs32 *regs) { - printk("PSR: %08x PC: %08x NPC: %08x Y: %08x\n", regs->psr, - regs->pc, regs->npc, regs->y); + printk("PSR: %08x PC: %08x NPC: %08x Y: %08x %s\n", regs->psr, + regs->pc, regs->npc, regs->y, print_tainted()); printk("g0: %08x g1: %08x g2: %08x g3: %08x ", regs->u_regs[0], regs->u_regs[1], regs->u_regs[2], regs->u_regs[3]); diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 3b5d37ed1f75..d62aef43cfa5 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -25,6 +25,7 @@ #include <asm/uaccess.h> #include <asm/psrcompat.h> #include <asm/visasm.h> +#include <asm/spitfire.h> #define MAGIC_CONSTANT 0x80000000 @@ -596,7 +597,7 @@ flush_and_out: spitfire_put_dcache_tag(va, 0x0); /* No need to mess with I-cache on Cheetah. */ } else { - for (va = 0; va < (PAGE_SIZE << 1); va += 32) + for (va = 0; va < L1DCACHE_SIZE; va += 32) spitfire_put_dcache_tag(va, 0x0); if (request == PTRACE_PEEKTEXT || request == PTRACE_POKETEXT || diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 37f5476a34c5..5830873d8f02 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.66 2001/09/20 00:35:31 davem Exp $ +/* $Id: setup.c,v 1.67 2001/09/21 03:17:06 kanoj Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) @@ -38,6 +38,7 @@ #include <asm/idprom.h> #include <asm/head.h> #include <asm/starfire.h> +#include <asm/hardirq.h> #ifdef CONFIG_IP_PNP #include <net/ipconfig.h> @@ -95,6 +96,14 @@ int prom_callback(long *args) if (!(cmd = (char *)args[0])) return -1; + /* + * The callback can be invoked on the cpu that first dropped + * into prom_cmdline after taking the serial interrupt, or on + * a slave processor that was smp_captured() if the + * administrator has done a switch-cpu inside obp. In either + * case, the cpu is marked as in-interrupt. Drop IRQ locks. + */ + irq_exit(smp_processor_id(), 0); save_and_cli(flags); cons = console_drivers; while (cons) { @@ -271,6 +280,10 @@ int prom_callback(long *args) register_console(cons); } restore_flags(flags); + /* + * Restore in-interrupt status for a resume from obp. + */ + irq_enter(smp_processor_id(), 0); return 0; } diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index a2a49becc8a9..0633e4b9537d 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.111 2001/08/30 03:22:00 kanoj Exp $ +/* $Id: sparc64_ksyms.c,v 1.112 2001/09/25 23:30:23 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -278,6 +278,7 @@ EXPORT_SYMBOL(__strlen); EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(__strlen_user); +EXPORT_SYMBOL(__strnlen_user); EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strncpy); EXPORT_SYMBOL(strcat); diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 1deac8f74ce8..46daa65a876c 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.178 2001/08/13 14:40:07 davem Exp $ +/* $Id: sys_sparc32.c,v 1.179 2001/09/25 00:48:09 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -4015,7 +4015,7 @@ asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); set_fs(old_fs); - if (!ret && offset && put_user(of, offset)) + if (offset && put_user(of, offset)) return -EFAULT; return ret; diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index c4729f8c354a..90063fb4135b 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.78 2001/09/14 19:49:32 kanoj Exp $ +/* $Id: traps.c,v 1.79 2001/09/21 02:14:39 kanoj Exp $ * arch/sparc64/kernel/traps.c * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -1637,44 +1637,6 @@ void do_tof_tl1(struct pt_regs *regs) die_if_kernel("TL1: Tag Overflow Exception", regs); } -#ifdef CONFIG_EC_FLUSH_TRAP -void cache_flush_trap(struct pt_regs *regs) -{ -#ifndef CONFIG_SMP - unsigned node = linux_cpus[get_cpuid()].prom_node; -#else -#error cache_flush_trap not supported on sparc64/SMP yet -#endif - -#if 0 -/* Broken */ - int size = prom_getintdefault(node, "ecache-size", 512*1024); - int i, j; - unsigned long addr; - struct page *page, *end; - - regs->tpc = regs->tnpc; - regs->tnpc = regs->tnpc + 4; - if (!capable(CAP_SYS_ADMIN)) return; - size >>= PAGE_SHIFT; - addr = PAGE_OFFSET - PAGE_SIZE; - page = mem_map - 1; - end = mem_map + max_mapnr; - for (i = 0; i < size; i++) { - do { - addr += PAGE_SIZE; - page++; - if (page >= end) - return; - } while (!PageReserved(page)); - /* E-Cache line size is 64B. Let us pollute it :)) */ - for (j = 0; j < PAGE_SIZE; j += 64) - __asm__ __volatile__ ("ldx [%0 + %1], %%g1" : : "r" (j), "r" (addr) : "g1"); - } -#endif -} -#endif - void do_getpsr(struct pt_regs *regs) { regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate); diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S index 008c780fd1cd..182fb0f96dc6 100644 --- a/arch/sparc64/kernel/ttable.S +++ b/arch/sparc64/kernel/ttable.S @@ -1,4 +1,4 @@ -/* $Id: ttable.S,v 1.34 2001/08/12 09:08:56 davem Exp $ +/* $Id: ttable.S,v 1.35 2001/09/21 02:14:39 kanoj Exp $ * ttable.S: Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions. * * Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu) @@ -144,12 +144,7 @@ tl0_resv164: BTRAP(0x164) BTRAP(0x165) BTRAP(0x166) BTRAP(0x167) BTRAP(0x168) tl0_resv169: BTRAP(0x169) BTRAP(0x16a) BTRAP(0x16b) BTRAP(0x16c) tl0_linux64: LINUX_64BIT_SYSCALL_TRAP tl0_gsctx: TRAP(sparc64_get_context) TRAP(sparc64_set_context) -tl0_resv170: BTRAP(0x170) BTRAP(0x171) -#ifdef CONFIG_EC_FLUSH_TRAP - TRAP(cache_flush_trap) -#else - BTRAP(0x172) -#endif +tl0_resv170: BTRAP(0x170) BTRAP(0x171) BTRAP(0x172) tl0_resv173: BTRAP(0x173) BTRAP(0x174) BTRAP(0x175) BTRAP(0x176) BTRAP(0x177) tl0_resv178: BTRAP(0x178) BTRAP(0x179) BTRAP(0x17a) BTRAP(0x17b) BTRAP(0x17c) tl0_resv17d: BTRAP(0x17d) BTRAP(0x17e) BTRAP(0x17f) diff --git a/arch/sparc64/lib/VIScopy.S b/arch/sparc64/lib/VIScopy.S index b944a0ae7d67..17f9d718b3d2 100644 --- a/arch/sparc64/lib/VIScopy.S +++ b/arch/sparc64/lib/VIScopy.S @@ -1,4 +1,4 @@ -/* $Id: VIScopy.S,v 1.25 2000/11/01 09:29:19 davem Exp $ +/* $Id: VIScopy.S,v 1.26 2001/09/27 04:36:24 kanoj Exp $ * VIScopy.S: High speed copy operations utilizing the UltraSparc * Visual Instruction Set. * @@ -310,17 +310,6 @@ __memcpy_begin: .globl __memcpy .type __memcpy,@function - .globl __memcpy_384plus - .type __memcpy_384plus,@function - - .globl __memcpy_16plus - .type __memcpy_16plus,@function - - .globl __memcpy_short - .type __memcpy_short,@function - - .globl __memcpy_entry - .type __memcpy_entry,@function memcpy_private: __memcpy: memcpy: mov ASI_P, asi_src ! IEU0 Group @@ -395,7 +384,6 @@ cheetah_patch_copyops: .align 32 #ifdef __KERNEL__ -__memcpy_384plus: andcc %o0, 7, %g2 ! IEU1 Group #endif VIS_enter: @@ -735,9 +723,6 @@ __memcpy_entry: bleu,pn %xcc, __memcpy_short ! CTI cmp %o2, (64 * 6) ! IEU1 Group bgeu,pn %xcc, VIS_enter ! CTI -#ifdef __KERNEL__ -__memcpy_16plus: -#endif andcc %o0, 7, %g2 ! IEU1 Group sub %o0, %o1, %g5 ! IEU0 andcc %g5, 3, %o5 ! IEU1 Group diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S index aef9062230a9..dedc03521902 100644 --- a/arch/sparc64/lib/blockops.S +++ b/arch/sparc64/lib/blockops.S @@ -1,4 +1,4 @@ -/* $Id: blockops.S,v 1.35 2001/09/04 16:39:53 kanoj Exp $ +/* $Id: blockops.S,v 1.36 2001/09/24 21:44:03 davem Exp $ * blockops.S: UltraSparc block zero optimized routines. * * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com) @@ -25,7 +25,7 @@ #if (PAGE_SHIFT == 13) || (PAGE_SHIFT == 19) #define PAGE_SIZE_REM 0x80 -#elif (PAGE_SHIFT == 16) || (PAGE_SHIFT == 21) +#elif (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22) #define PAGE_SIZE_REM 0x100 #else #error Wrong PAGE_SHIFT specified @@ -64,7 +64,7 @@ _copy_page: /* %o0=dest, %o1=src */ cmp %o2, PAGE_SIZE_REM bne,pt %xcc, 1b add %o0, 0x40, %o0 -#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 21) +#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22) TOUCH(f0, f2, f4, f6, f8, f10, f12, f14) ldda [%o1] ASI_BLK_P, %f32 stda %f48, [%o0] ASI_BLK_P @@ -287,7 +287,7 @@ spitfire_copy_user_page: cmp %o2, PAGE_SIZE_REM bne,pt %xcc, 1b add %o0, 0x40, %o0 -#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 21) +#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22) TOUCH(f0, f2, f4, f6, f8, f10, f12, f14) ldda [%o1] ASI_BLK_P, %f32 stda %f48, [%o0] ASI_BLK_P @@ -353,7 +353,7 @@ copy_page_using_blkcommit: cmp %o2, PAGE_SIZE_REM bne,pt %xcc, 1b add %o0, 0x40, %o0 -#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 21) +#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22) TOUCH(f0, f2, f4, f6, f8, f10, f12, f14) ldda [%o1] ASI_BLK_P, %f32 stda %f48, [%o0] ASI_BLK_COMMIT_P diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 718e8d93d7ab..80304a447a5c 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.189 2001/09/02 23:27:18 kanoj Exp $ +/* $Id: init.c,v 1.193 2001/09/25 22:47:35 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -30,6 +30,7 @@ #include <asm/dma.h> #include <asm/starfire.h> #include <asm/tlb.h> +#include <asm/spitfire.h> mmu_gather_t mmu_gathers[NR_CPUS]; @@ -113,16 +114,17 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p if (VALID_PAGE(page) && page->mapping && test_bit(PG_dcache_dirty, &page->flags)) { - __flush_dcache_page(page->virtual, - (tlb_type == spitfire)); +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ + __flush_dcache_page(page->virtual, (tlb_type == spitfire)); +#else + if (tlb_type == spitfire) /* fix local I$ coherency */ + __flush_icache_page(__get_phys((unsigned long)(page->virtual))); +#endif clear_bit(PG_dcache_dirty, &page->flags); } __update_mmu_cache(vma, address, pte); } -/* In arch/sparc64/mm/ultra.S */ -extern void __flush_icache_page(unsigned long); - void flush_icache_range(unsigned long start, unsigned long end) { /* Cheetah has coherent I-cache. */ @@ -887,23 +889,28 @@ struct pgtable_cache_struct pgt_quicklists; * addresses. The idea is that if the vpte color and PAGE_OFFSET range * color is the same, then when the kernel initializes the pagetable * using the later address range, accesses with the first address - * range will not see the newly initialized data rather than the - * garbage. + * range will see the newly initialized data rather than the garbage. */ - +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ +#define DC_ALIAS_SHIFT 1 +#else +#define DC_ALIAS_SHIFT 0 +#endif pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) { - struct page *page = alloc_pages(GFP_KERNEL, 1); - unsigned long color = ((address >> (PAGE_SHIFT + 10)) & 1UL); + struct page *page = alloc_pages(GFP_KERNEL, DC_ALIAS_SHIFT); + unsigned long color = VPTE_COLOR(address); if (page) { unsigned long *to_free; unsigned long paddr; pte_t *pte; +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ set_page_count((page + 1), 1); +#endif paddr = (unsigned long) page_address(page); - memset((char *)paddr, 0, (PAGE_SIZE << 1)); + memset((char *)paddr, 0, (PAGE_SIZE << DC_ALIAS_SHIFT)); if (!color) { pte = (pte_t *) paddr; @@ -913,10 +920,12 @@ pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) to_free = (unsigned long *) paddr; } +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ /* Now free the other one up, adjust cache size. */ *to_free = (unsigned long) pte_quicklist[color ^ 0x1]; pte_quicklist[color ^ 0x1] = to_free; pgtable_cache_size++; +#endif return pte; } diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 003ee2842271..c09f7b7d3b1f 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -1,4 +1,4 @@ -/* $Id: ultra.S,v 1.57 2001/09/06 19:27:17 kanoj Exp $ +/* $Id: ultra.S,v 1.61 2001/09/25 18:04:51 kanoj Exp $ * ultra.S: Don't expand these all over the place... * * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com) @@ -237,6 +237,16 @@ __spitfire_flush_tlb_range_pbp_slow: retl /*IC22*/ wrpr %g1, 0x0, %pstate +/* + * The following code flushes one page_size worth. + */ +#if (PAGE_SHIFT == 13) +#define ITAG_MASK 0xfe +#elif (PAGE_SHIFT == 16) +#define ITAG_MASK 0x7fe +#else +#error unsupported PAGE_SIZE +#endif .align 32 .globl __flush_icache_page __flush_icache_page: /* %o0 = phys_page */ @@ -250,7 +260,7 @@ __flush_icache_page: /* %o0 = phys_page */ or %o0, %g1, %o0 ! VALID+phys-addr comparitor sllx %g2, 1, %g2 - andn %g2, 0xfe, %g2 ! IC_tag mask + andn %g2, ITAG_MASK, %g2 ! IC_tag mask nop nop nop @@ -313,6 +323,16 @@ flush_dcpage_cheetah: retl nop +#if (PAGE_SHIFT == 13) +#define DTAG_MASK 0x3 +#elif (PAGE_SHIFT == 16) +#define DTAG_MASK 0x1f +#elif (PAGE_SHIFT == 19) +#define DTAG_MASK 0xff +#elif (PAGE_SHIFT == 22) +#define DTAG_MASK 0x3ff +#endif + flush_dcpage_spitfire: clr %o4 srlx %o0, 11, %o0 @@ -323,19 +343,19 @@ flush_dcpage_spitfire: add %o4, (1 << 5), %o4 ! IEU0 ldxa [%o4] ASI_DCACHE_TAG, %g2 ! LSU Group o3 available add %o4, (1 << 5), %o4 ! IEU0 - andn %o3, 0x3, %o3 ! IEU1 + andn %o3, DTAG_MASK, %o3 ! IEU1 ldxa [%o4] ASI_DCACHE_TAG, %g3 ! LSU Group add %o4, (1 << 5), %o4 ! IEU0 - andn %g1, 0x3, %g1 ! IEU1 + andn %g1, DTAG_MASK, %g1 ! IEU1 cmp %o0, %o3 ! IEU1 Group be,a,pn %xcc, dflush1 ! CTI sub %o4, (4 << 5), %o4 ! IEU0 (Group) cmp %o0, %g1 ! IEU1 Group - andn %g2, 0x3, %g2 ! IEU0 + andn %g2, DTAG_MASK, %g2 ! IEU0 be,a,pn %xcc, dflush2 ! CTI sub %o4, (3 << 5), %o4 ! IEU0 (Group) cmp %o0, %g2 ! IEU1 Group - andn %g3, 0x3, %g3 ! IEU0 + andn %g3, DTAG_MASK, %g3 ! IEU0 be,a,pn %xcc, dflush3 ! CTI sub %o4, (2 << 5), %o4 ! IEU0 (Group) cmp %o0, %g3 ! IEU1 Group diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c index 3ac73f8e2c22..bb254f7ef321 100644 --- a/arch/sparc64/prom/misc.c +++ b/arch/sparc64/prom/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.19 2000/06/30 10:18:38 davem Exp $ +/* $Id: misc.c,v 1.20 2001/09/21 03:17:07 kanoj Exp $ * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * @@ -59,25 +59,15 @@ prom_cmdline(void) prom_palette (1); #endif - /* We always arrive here via a serial interrupt. - * So in order for everything to work reliably, even - * on SMP, we need to drop the IRQ locks we hold. - */ #ifdef CONFIG_SMP - irq_exit(smp_processor_id(), 0); smp_capture(); -#else - local_irq_count(smp_processor_id())--; #endif p1275_cmd ("enter", P1275_INOUT(0,0)); #ifdef CONFIG_SMP smp_release(); - irq_enter(smp_processor_id(), 0); spin_unlock_wait(&__br_write_locks[BR_GLOBALIRQ_LOCK].lock); -#else - local_irq_count(smp_processor_id())++; #endif #ifdef CONFIG_SUN_CONSOLE diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 843dd8f8e21f..36de551e6beb 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -47,9 +47,27 @@ EXPORT_SYMBOL(gendisk_head); void add_gendisk(struct gendisk *gp) { + struct gendisk *sgp; + write_lock(&gendisk_lock); + + /* + * In 2.5 this will go away. Fix the drivers who rely on + * old behaviour. + */ + + for (sgp = gendisk_head; sgp; sgp = sgp->next) + { + if (sgp == gp) + { +// printk(KERN_ERR "add_gendisk: device major %d is buggy and added a live gendisk!\n", +// sgp->major) + goto out; + } + } gp->next = gendisk_head; gendisk_head = gp; +out: write_unlock(&gendisk_lock); } diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c new file mode 100644 index 000000000000..54f2f46d9d51 --- /dev/null +++ b/drivers/char/mwave/3780i.c @@ -0,0 +1,730 @@ +/* +* +* 3780i.c -- helper routines for the 3780i DSP +* +* +* Written By: Mike Sullivan IBM Corporation +* +* Copyright (C) 1999 IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* NO WARRANTY +* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR +* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT +* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is +* solely responsible for determining the appropriateness of using and +* distributing the Program and assumes all risks associated with its +* exercise of rights under this Agreement, including but not limited to +* the risks and costs of program errors, damage to or loss of data, +* programs or equipment, and unavailability or interruption of operations. +* +* DISCLAIMER OF LIABILITY +* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +* 10/23/2000 - Alpha Release +* First release to the public +*/ + +#include <linux/version.h> +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/unistd.h> +#include <linux/delay.h> +#include <linux/ioport.h> +#include <linux/init.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/system.h> +#include <asm/irq.h> +#include <asm/bitops.h> +#include "smapi.h" +#include "mwavedd.h" +#include "3780i.h" + +static spinlock_t dsp_lock = SPIN_LOCK_UNLOCKED; +static unsigned long flags; + + +static void PaceMsaAccess(unsigned short usDspBaseIO) +{ + if(current->need_resched) + schedule(); + udelay(100); + if(current->need_resched) + schedule(); +} + +unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO, + unsigned long ulMsaAddr) +{ + unsigned short val; + + PRINTK_3(TRACE_3780I, + "3780i::dsp3780I_ReadMsaCfg entry usDspBaseIO %x ulMsaAddr %lx\n", + usDspBaseIO, ulMsaAddr); + + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr); + OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16)); + val = InWordDsp(DSP_MsaDataDSISHigh); + spin_unlock_irqrestore(&dsp_lock, flags); + + PRINTK_2(TRACE_3780I, "3780i::dsp3780I_ReadMsaCfg exit val %x\n", val); + + return val; +} + +void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, + unsigned long ulMsaAddr, unsigned short usValue) +{ + + PRINTK_4(TRACE_3780I, + "3780i::dsp3780i_WriteMsaCfg entry usDspBaseIO %x ulMsaAddr %lx usValue %x\n", + usDspBaseIO, ulMsaAddr, usValue); + + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr); + OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16)); + OutWordDsp(DSP_MsaDataDSISHigh, usValue); + spin_unlock_irqrestore(&dsp_lock, flags); +} + +void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, + unsigned char ucValue) +{ + DSP_ISA_SLAVE_CONTROL rSlaveControl; + DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; + + + PRINTK_4(TRACE_3780I, + "3780i::dsp3780i_WriteGenCfg entry usDspBaseIO %x uIndex %x ucValue %x\n", + usDspBaseIO, uIndex, ucValue); + + MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl); + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780i_WriteGenCfg rSlaveControl %x\n", + MKBYTE(rSlaveControl)); + + rSlaveControl_Save = rSlaveControl; + rSlaveControl.ConfigMode = TRUE; + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780i_WriteGenCfg entry rSlaveControl+ConfigMode %x\n", + MKBYTE(rSlaveControl)); + + OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl)); + OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex); + OutByteDsp(DSP_ConfigData, ucValue); + OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save)); + + PRINTK_1(TRACE_3780I, "3780i::dsp3780i_WriteGenCfg exit\n"); + + +} + +unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, + unsigned uIndex) +{ + DSP_ISA_SLAVE_CONTROL rSlaveControl; + DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; + unsigned char ucValue; + + + PRINTK_3(TRACE_3780I, + "3780i::dsp3780i_ReadGenCfg entry usDspBaseIO %x uIndex %x\n", + usDspBaseIO, uIndex); + + MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl); + rSlaveControl_Save = rSlaveControl; + rSlaveControl.ConfigMode = TRUE; + OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl)); + OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex); + ucValue = InByteDsp(DSP_ConfigData); + OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save)); + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780i_ReadGenCfg exit ucValue %x\n", ucValue); + + + return ucValue; +} + +int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, + unsigned short *pIrqMap, + unsigned short *pDmaMap) +{ + unsigned short usDspBaseIO = pSettings->usDspBaseIO; + int i; + DSP_UART_CFG_1 rUartCfg1; + DSP_UART_CFG_2 rUartCfg2; + DSP_HBRIDGE_CFG_1 rHBridgeCfg1; + DSP_HBRIDGE_CFG_2 rHBridgeCfg2; + DSP_BUSMASTER_CFG_1 rBusmasterCfg1; + DSP_BUSMASTER_CFG_2 rBusmasterCfg2; + DSP_ISA_PROT_CFG rIsaProtCfg; + DSP_POWER_MGMT_CFG rPowerMgmtCfg; + DSP_HBUS_TIMER_CFG rHBusTimerCfg; + DSP_LBUS_TIMEOUT_DISABLE rLBusTimeoutDisable; + DSP_CHIP_RESET rChipReset; + DSP_CLOCK_CONTROL_1 rClockControl1; + DSP_CLOCK_CONTROL_2 rClockControl2; + DSP_ISA_SLAVE_CONTROL rSlaveControl; + DSP_HBRIDGE_CONTROL rHBridgeControl; + unsigned short ChipID = 0; + unsigned short tval; + + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780I_EnableDSP entry pSettings->bDSPEnabled %x\n", + pSettings->bDSPEnabled); + + + if (!pSettings->bDSPEnabled) { + PRINTK_ERROR( KERN_ERR "3780i::dsp3780I_EnableDSP: Error: DSP not enabled. Aborting.\n" ); + return -EIO; + } + + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780i_EnableDSP entry pSettings->bModemEnabled %x\n", + pSettings->bModemEnabled); + + if (pSettings->bModemEnabled) { + rUartCfg1.Reserved = rUartCfg2.Reserved = 0; + rUartCfg1.IrqActiveLow = pSettings->bUartIrqActiveLow; + rUartCfg1.IrqPulse = pSettings->bUartIrqPulse; + rUartCfg1.Irq = + (unsigned char) pIrqMap[pSettings->usUartIrq]; + switch (pSettings->usUartBaseIO) { + case 0x03F8: + rUartCfg1.BaseIO = 0; + break; + case 0x02F8: + rUartCfg1.BaseIO = 1; + break; + case 0x03E8: + rUartCfg1.BaseIO = 2; + break; + case 0x02E8: + rUartCfg1.BaseIO = 3; + break; + } + rUartCfg2.Enable = TRUE; + } + + rHBridgeCfg1.Reserved = rHBridgeCfg2.Reserved = 0; + rHBridgeCfg1.IrqActiveLow = pSettings->bDspIrqActiveLow; + rHBridgeCfg1.IrqPulse = pSettings->bDspIrqPulse; + rHBridgeCfg1.Irq = (unsigned char) pIrqMap[pSettings->usDspIrq]; + rHBridgeCfg1.AccessMode = 1; + rHBridgeCfg2.Enable = TRUE; + + + rBusmasterCfg2.Reserved = 0; + rBusmasterCfg1.Dma = (unsigned char) pDmaMap[pSettings->usDspDma]; + rBusmasterCfg1.NumTransfers = + (unsigned char) pSettings->usNumTransfers; + rBusmasterCfg1.ReRequest = (unsigned char) pSettings->usReRequest; + rBusmasterCfg1.MEMCS16 = pSettings->bEnableMEMCS16; + rBusmasterCfg2.IsaMemCmdWidth = + (unsigned char) pSettings->usIsaMemCmdWidth; + + + rIsaProtCfg.Reserved = 0; + rIsaProtCfg.GateIOCHRDY = pSettings->bGateIOCHRDY; + + rPowerMgmtCfg.Reserved = 0; + rPowerMgmtCfg.Enable = pSettings->bEnablePwrMgmt; + + rHBusTimerCfg.LoadValue = + (unsigned char) pSettings->usHBusTimerLoadValue; + + rLBusTimeoutDisable.Reserved = 0; + rLBusTimeoutDisable.DisableTimeout = + pSettings->bDisableLBusTimeout; + + MKWORD(rChipReset) = ~pSettings->usChipletEnable; + + rClockControl1.Reserved1 = rClockControl1.Reserved2 = 0; + rClockControl1.N_Divisor = pSettings->usN_Divisor; + rClockControl1.M_Multiplier = pSettings->usM_Multiplier; + + rClockControl2.Reserved = 0; + rClockControl2.PllBypass = pSettings->bPllBypass; + + /* Issue a soft reset to the chip */ + /* Note: Since we may be coming in with 3780i clocks suspended, we must keep + * soft-reset active for 10ms. + */ + rSlaveControl.ClockControl = 0; + rSlaveControl.SoftReset = TRUE; + rSlaveControl.ConfigMode = FALSE; + rSlaveControl.Reserved = 0; + + PRINTK_4(TRACE_3780I, + "3780i::dsp3780i_EnableDSP usDspBaseIO %x index %x taddr %x\n", + usDspBaseIO, DSP_IsaSlaveControl, + usDspBaseIO + DSP_IsaSlaveControl); + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780i_EnableDSP rSlaveContrl %x\n", + MKWORD(rSlaveControl)); + + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); + MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl); + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780i_EnableDSP rSlaveControl 2 %x\n", tval); + + + for (i = 0; i < 11; i++) + udelay(2000); + + rSlaveControl.SoftReset = FALSE; + OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); + + MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl); + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780i_EnableDSP rSlaveControl 3 %x\n", tval); + + + /* Program our general configuration registers */ + WriteGenCfg(DSP_HBridgeCfg1Index, MKBYTE(rHBridgeCfg1)); + WriteGenCfg(DSP_HBridgeCfg2Index, MKBYTE(rHBridgeCfg2)); + WriteGenCfg(DSP_BusMasterCfg1Index, MKBYTE(rBusmasterCfg1)); + WriteGenCfg(DSP_BusMasterCfg2Index, MKBYTE(rBusmasterCfg2)); + WriteGenCfg(DSP_IsaProtCfgIndex, MKBYTE(rIsaProtCfg)); + WriteGenCfg(DSP_PowerMgCfgIndex, MKBYTE(rPowerMgmtCfg)); + WriteGenCfg(DSP_HBusTimerCfgIndex, MKBYTE(rHBusTimerCfg)); + + if (pSettings->bModemEnabled) { + WriteGenCfg(DSP_UartCfg1Index, MKBYTE(rUartCfg1)); + WriteGenCfg(DSP_UartCfg2Index, MKBYTE(rUartCfg2)); + } + + + rHBridgeControl.EnableDspInt = FALSE; + rHBridgeControl.MemAutoInc = TRUE; + rHBridgeControl.IoAutoInc = FALSE; + rHBridgeControl.DiagnosticMode = FALSE; + + PRINTK_3(TRACE_3780I, + "3780i::dsp3780i_EnableDSP DSP_HBridgeControl %x rHBridgeControl %x\n", + DSP_HBridgeControl, MKWORD(rHBridgeControl)); + + OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); + spin_unlock_irqrestore(&dsp_lock, flags); + WriteMsaCfg(DSP_LBusTimeoutDisable, MKWORD(rLBusTimeoutDisable)); + WriteMsaCfg(DSP_ClockControl_1, MKWORD(rClockControl1)); + WriteMsaCfg(DSP_ClockControl_2, MKWORD(rClockControl2)); + WriteMsaCfg(DSP_ChipReset, MKWORD(rChipReset)); + + ChipID = ReadMsaCfg(DSP_ChipID); + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780I_EnableDSP exiting bRC=TRUE, ChipID %x\n", + ChipID); + + return 0; +} + +int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings) +{ + unsigned short usDspBaseIO = pSettings->usDspBaseIO; + DSP_ISA_SLAVE_CONTROL rSlaveControl; + + + PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP entry\n"); + + rSlaveControl.ClockControl = 0; + rSlaveControl.SoftReset = TRUE; + rSlaveControl.ConfigMode = FALSE; + rSlaveControl.Reserved = 0; + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); + + udelay(5); + + rSlaveControl.ClockControl = 1; + OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); + spin_unlock_irqrestore(&dsp_lock, flags); + + udelay(5); + + + PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP exit\n"); + + return 0; +} + +int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings) +{ + unsigned short usDspBaseIO = pSettings->usDspBaseIO; + DSP_BOOT_DOMAIN rBootDomain; + DSP_HBRIDGE_CONTROL rHBridgeControl; + + + PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset entry\n"); + + spin_lock_irqsave(&dsp_lock, flags); + /* Mask DSP to PC interrupt */ + MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); + + PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rHBridgeControl %x\n", + MKWORD(rHBridgeControl)); + + rHBridgeControl.EnableDspInt = FALSE; + OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); + spin_unlock_irqrestore(&dsp_lock, flags); + + /* Reset the core via the boot domain register */ + rBootDomain.ResetCore = TRUE; + rBootDomain.Halt = TRUE; + rBootDomain.NMI = TRUE; + rBootDomain.Reserved = 0; + + PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rBootDomain %x\n", + MKWORD(rBootDomain)); + + WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); + + /* Reset all the chiplets and then reactivate them */ + WriteMsaCfg(DSP_ChipReset, 0xFFFF); + udelay(5); + WriteMsaCfg(DSP_ChipReset, + (unsigned short) (~pSettings->usChipletEnable)); + + + PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset exit bRC=0\n"); + + return 0; +} + + +int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings) +{ + unsigned short usDspBaseIO = pSettings->usDspBaseIO; + DSP_BOOT_DOMAIN rBootDomain; + DSP_HBRIDGE_CONTROL rHBridgeControl; + + + PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run entry\n"); + + + /* Transition the core to a running state */ + rBootDomain.ResetCore = TRUE; + rBootDomain.Halt = FALSE; + rBootDomain.NMI = TRUE; + rBootDomain.Reserved = 0; + WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); + + udelay(5); + + rBootDomain.ResetCore = FALSE; + WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); + udelay(5); + + rBootDomain.NMI = FALSE; + WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); + udelay(5); + + /* Enable DSP to PC interrupt */ + spin_lock_irqsave(&dsp_lock, flags); + MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); + rHBridgeControl.EnableDspInt = TRUE; + + PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Run rHBridgeControl %x\n", + MKWORD(rHBridgeControl)); + + OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); + spin_unlock_irqrestore(&dsp_lock, flags); + + + PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run exit bRC=TRUE\n"); + + return 0; +} + + +int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer, + unsigned uCount, unsigned long ulDSPAddr) +{ + unsigned short *pusBuffer = pvBuffer; + unsigned short val; + + + PRINTK_5(TRACE_3780I, + "3780i::dsp3780I_ReadDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", + usDspBaseIO, pusBuffer, uCount, ulDSPAddr); + + + /* Set the initial MSA address. No adjustments need to be made to data store addresses */ + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); + OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); + spin_unlock_irqrestore(&dsp_lock, flags); + + /* Transfer the memory block */ + while (uCount-- != 0) { + spin_lock_irqsave(&dsp_lock, flags); + val = InWordDsp(DSP_MsaDataDSISHigh); + spin_unlock_irqrestore(&dsp_lock, flags); + if(put_user(val, pusBuffer++)) + return -EFAULT; + + PRINTK_3(TRACE_3780I, + "3780I::dsp3780I_ReadDStore uCount %x val %x\n", + uCount, val); + + PaceMsaAccess(usDspBaseIO); + } + + + PRINTK_1(TRACE_3780I, + "3780I::dsp3780I_ReadDStore exit bRC=TRUE\n"); + + return 0; +} + +int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, + void *pvBuffer, unsigned uCount, + unsigned long ulDSPAddr) +{ + unsigned short *pusBuffer = pvBuffer; + unsigned short val; + + + PRINTK_5(TRACE_3780I, + "3780i::dsp3780I_ReadAndDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", + usDspBaseIO, pusBuffer, uCount, ulDSPAddr); + + + /* Set the initial MSA address. No adjustments need to be made to data store addresses */ + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); + OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); + spin_unlock_irqrestore(&dsp_lock, flags); + + /* Transfer the memory block */ + while (uCount-- != 0) { + spin_lock_irqsave(&dsp_lock, flags); + val = InWordDsp(DSP_ReadAndClear); + spin_unlock_irqrestore(&dsp_lock, flags); + if(put_user(val, pusBuffer++)) + return -EFAULT; + + PRINTK_3(TRACE_3780I, + "3780I::dsp3780I_ReadAndCleanDStore uCount %x val %x\n", + uCount, val); + + PaceMsaAccess(usDspBaseIO); + } + + + PRINTK_1(TRACE_3780I, + "3780I::dsp3780I_ReadAndClearDStore exit bRC=TRUE\n"); + + return 0; +} + + +int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer, + unsigned uCount, unsigned long ulDSPAddr) +{ + unsigned short *pusBuffer = pvBuffer; + + + PRINTK_5(TRACE_3780I, + "3780i::dsp3780D_WriteDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", + usDspBaseIO, pusBuffer, uCount, ulDSPAddr); + + + /* Set the initial MSA address. No adjustments need to be made to data store addresses */ + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); + OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); + spin_unlock_irqrestore(&dsp_lock, flags); + + /* Transfer the memory block */ + while (uCount-- != 0) { + unsigned short val; + if(get_user(val, pusBuffer++)) + return -EFAULT; + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_MsaDataDSISHigh, val); + spin_unlock_irqrestore(&dsp_lock, flags); + + PRINTK_3(TRACE_3780I, + "3780I::dsp3780I_WriteDStore uCount %x val %x\n", + uCount, val); + + PaceMsaAccess(usDspBaseIO); + } + + + PRINTK_1(TRACE_3780I, + "3780I::dsp3780D_WriteDStore exit bRC=TRUE\n"); + + return 0; +} + + +int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer, + unsigned uCount, unsigned long ulDSPAddr) +{ + unsigned short *pusBuffer = pvBuffer; + + PRINTK_5(TRACE_3780I, + "3780i::dsp3780I_ReadIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", + usDspBaseIO, pusBuffer, uCount, ulDSPAddr); + + /* + * Set the initial MSA address. To convert from an instruction store + * address to an MSA address + * shift the address two bits to the left and set bit 22 + */ + ulDSPAddr = (ulDSPAddr << 2) | (1 << 22); + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); + OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); + spin_unlock_irqrestore(&dsp_lock, flags); + + /* Transfer the memory block */ + while (uCount-- != 0) { + unsigned short val_lo, val_hi; + spin_lock_irqsave(&dsp_lock, flags); + val_lo = InWordDsp(DSP_MsaDataISLow); + val_hi = InWordDsp(DSP_MsaDataDSISHigh); + spin_unlock_irqrestore(&dsp_lock, flags); + if(put_user(val_lo, pusBuffer++)) + return -EFAULT; + if(put_user(val_hi, pusBuffer++)) + return -EFAULT; + + PRINTK_4(TRACE_3780I, + "3780I::dsp3780I_ReadIStore uCount %x val_lo %x val_hi %x\n", + uCount, val_lo, val_hi); + + PaceMsaAccess(usDspBaseIO); + + } + + PRINTK_1(TRACE_3780I, + "3780I::dsp3780I_ReadIStore exit bRC=TRUE\n"); + + return 0; +} + + +int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer, + unsigned uCount, unsigned long ulDSPAddr) +{ + unsigned short *pusBuffer = pvBuffer; + + PRINTK_5(TRACE_3780I, + "3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", + usDspBaseIO, pusBuffer, uCount, ulDSPAddr); + + + /* + * Set the initial MSA address. To convert from an instruction store + * address to an MSA address + * shift the address two bits to the left and set bit 22 + */ + ulDSPAddr = (ulDSPAddr << 2) | (1 << 22); + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); + OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); + spin_unlock_irqrestore(&dsp_lock, flags); + + /* Transfer the memory block */ + while (uCount-- != 0) { + unsigned short val_lo, val_hi; + if(get_user(val_lo, pusBuffer++)) + return -EFAULT; + if(get_user(val_hi, pusBuffer++)) + return -EFAULT; + spin_lock_irqsave(&dsp_lock, flags); + OutWordDsp(DSP_MsaDataISLow, val_lo); + OutWordDsp(DSP_MsaDataDSISHigh, val_hi); + spin_unlock_irqrestore(&dsp_lock, flags); + + PRINTK_4(TRACE_3780I, + "3780I::dsp3780I_WriteIStore uCount %x val_lo %x val_hi %x\n", + uCount, val_lo, val_hi); + + PaceMsaAccess(usDspBaseIO); + + } + + PRINTK_1(TRACE_3780I, + "3780I::dsp3780I_WriteIStore exit bRC=TRUE\n"); + + return 0; +} + + +int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, + unsigned short *pusIPCSource) +{ + DSP_HBRIDGE_CONTROL rHBridgeControl; + unsigned short temp; + + + PRINTK_3(TRACE_3780I, + "3780i::dsp3780I_GetIPCSource entry usDspBaseIO %x pusIPCSource %p\n", + usDspBaseIO, pusIPCSource); + + /* + * Disable DSP to PC interrupts, read the interupt register, + * clear the pending IPC bits, and reenable DSP to PC interrupts + */ + spin_lock_irqsave(&dsp_lock, flags); + MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); + rHBridgeControl.EnableDspInt = FALSE; + OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); + + *pusIPCSource = InWordDsp(DSP_Interrupt); + temp = (unsigned short) ~(*pusIPCSource); + + PRINTK_3(TRACE_3780I, + "3780i::dsp3780I_GetIPCSource, usIPCSource %x ~ %x\n", + *pusIPCSource, temp); + + OutWordDsp(DSP_Interrupt, (unsigned short) ~(*pusIPCSource)); + + rHBridgeControl.EnableDspInt = TRUE; + OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); + spin_unlock_irqrestore(&dsp_lock, flags); + + + PRINTK_2(TRACE_3780I, + "3780i::dsp3780I_GetIPCSource exit usIPCSource %x\n", + *pusIPCSource); + + return 0; +} diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h new file mode 100644 index 000000000000..86328909637c --- /dev/null +++ b/drivers/char/mwave/3780i.h @@ -0,0 +1,362 @@ +/* +* +* 3780i.h -- declarations for 3780i.c +* +* +* Written By: Mike Sullivan IBM Corporation +* +* Copyright (C) 1999 IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* NO WARRANTY +* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR +* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT +* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is +* solely responsible for determining the appropriateness of using and +* distributing the Program and assumes all risks associated with its +* exercise of rights under this Agreement, including but not limited to +* the risks and costs of program errors, damage to or loss of data, +* programs or equipment, and unavailability or interruption of operations. +* +* DISCLAIMER OF LIABILITY +* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +* 10/23/2000 - Alpha Release +* First release to the public +*/ + +#ifndef _LINUX_3780I_H +#define _LINUX_3780I_H + +#include <asm/io.h> + +/* DSP I/O port offsets and definitions */ +#define DSP_IsaSlaveControl 0x0000 /* ISA slave control register */ +#define DSP_IsaSlaveStatus 0x0001 /* ISA slave status register */ +#define DSP_ConfigAddress 0x0002 /* General config address register */ +#define DSP_ConfigData 0x0003 /* General config data register */ +#define DSP_HBridgeControl 0x0002 /* HBridge control register */ +#define DSP_MsaAddrLow 0x0004 /* MSP System Address, low word */ +#define DSP_MsaAddrHigh 0x0006 /* MSP System Address, high word */ +#define DSP_MsaDataDSISHigh 0x0008 /* MSA data register: d-store word or high byte of i-store */ +#define DSP_MsaDataISLow 0x000A /* MSA data register: low word of i-store */ +#define DSP_ReadAndClear 0x000C /* MSA read and clear data register */ +#define DSP_Interrupt 0x000E /* Interrupt register (IPC source) */ + +typedef struct { + unsigned char ClockControl:1; /* RW: Clock control: 0=normal, 1=stop 3780i clocks */ + unsigned char SoftReset:1; /* RW: Soft reset 0=normal, 1=soft reset active */ + unsigned char ConfigMode:1; /* RW: Configuration mode, 0=normal, 1=config mode */ + unsigned char Reserved:5; /* 0: Reserved */ +} DSP_ISA_SLAVE_CONTROL; + + +typedef struct { + unsigned short EnableDspInt:1; /* RW: Enable DSP to X86 ISA interrupt 0=mask it, 1=enable it */ + unsigned short MemAutoInc:1; /* RW: Memory address auto increment, 0=disable, 1=enable */ + unsigned short IoAutoInc:1; /* RW: I/O address auto increment, 0=disable, 1=enable */ + unsigned short DiagnosticMode:1; /* RW: Disgnostic mode 0=nromal, 1=diagnostic mode */ + unsigned short IsaPacingTimer:12; /* R: ISA access pacing timer: count of core cycles stolen */ +} DSP_HBRIDGE_CONTROL; + + +/* DSP register indexes used with the configuration register address (index) register */ +#define DSP_UartCfg1Index 0x0003 /* UART config register 1 */ +#define DSP_UartCfg2Index 0x0004 /* UART config register 2 */ +#define DSP_HBridgeCfg1Index 0x0007 /* HBridge config register 1 */ +#define DSP_HBridgeCfg2Index 0x0008 /* HBridge config register 2 */ +#define DSP_BusMasterCfg1Index 0x0009 /* ISA bus master config register 1 */ +#define DSP_BusMasterCfg2Index 0x000A /* ISA bus master config register 2 */ +#define DSP_IsaProtCfgIndex 0x000F /* ISA protocol control register */ +#define DSP_PowerMgCfgIndex 0x0010 /* Low poser suspend/resume enable */ +#define DSP_HBusTimerCfgIndex 0x0011 /* HBUS timer load value */ + +typedef struct { + unsigned char IrqActiveLow:1; /* RW: IRQ active high or low: 0=high, 1=low */ + unsigned char IrqPulse:1; /* RW: IRQ pulse or level: 0=level, 1=pulse */ + unsigned char Irq:3; /* RW: IRQ selection */ + unsigned char BaseIO:2; /* RW: Base I/O selection */ + unsigned char Reserved:1; /* 0: Reserved */ +} DSP_UART_CFG_1; + +typedef struct { + unsigned char Enable:1; /* RW: Enable I/O and IRQ: 0=FALSE, 1=TRUE */ + unsigned char Reserved:7; /* 0: Reserved */ +} DSP_UART_CFG_2; + +typedef struct { + unsigned char IrqActiveLow:1; /* RW: IRQ active high=0 or low=1 */ + unsigned char IrqPulse:1; /* RW: IRQ pulse=1 or level=0 */ + unsigned char Irq:3; /* RW: IRQ selection */ + unsigned char AccessMode:1; /* RW: 16-bit register access method 0=byte, 1=word */ + unsigned char Reserved:2; /* 0: Reserved */ +} DSP_HBRIDGE_CFG_1; + +typedef struct { + unsigned char Enable:1; /* RW: enable I/O and IRQ: 0=FALSE, 1=TRUE */ + unsigned char Reserved:7; /* 0: Reserved */ +} DSP_HBRIDGE_CFG_2; + + +typedef struct { + unsigned char Dma:3; /* RW: DMA channel selection */ + unsigned char NumTransfers:2; /* RW: Maximum # of transfers once being granted the ISA bus */ + unsigned char ReRequest:2; /* RW: Minumum delay between releasing the ISA bus and requesting it again */ + unsigned char MEMCS16:1; /* RW: ISA signal MEMCS16: 0=disabled, 1=enabled */ +} DSP_BUSMASTER_CFG_1; + +typedef struct { + unsigned char IsaMemCmdWidth:2; /* RW: ISA memory command width */ + unsigned char Reserved:6; /* 0: Reserved */ +} DSP_BUSMASTER_CFG_2; + + +typedef struct { + unsigned char GateIOCHRDY:1; /* RW: Enable IOCHRDY gating: 0=FALSE, 1=TRUE */ + unsigned char Reserved:7; /* 0: Reserved */ +} DSP_ISA_PROT_CFG; + +typedef struct { + unsigned char Enable:1; /* RW: Enable low power suspend/resume 0=FALSE, 1=TRUE */ + unsigned char Reserved:7; /* 0: Reserved */ +} DSP_POWER_MGMT_CFG; + +typedef struct { + unsigned char LoadValue:8; /* RW: HBUS timer load value */ +} DSP_HBUS_TIMER_CFG; + + + +/* DSP registers that exist in MSA I/O space */ +#define DSP_ChipID 0x80000000 +#define DSP_MspBootDomain 0x80000580 +#define DSP_LBusTimeoutDisable 0x80000580 +#define DSP_ClockControl_1 0x8000058A +#define DSP_ClockControl_2 0x8000058C +#define DSP_ChipReset 0x80000588 +#define DSP_GpioModeControl_15_8 0x80000082 +#define DSP_GpioDriverEnable_15_8 0x80000076 +#define DSP_GpioOutputData_15_8 0x80000072 + +typedef struct { + unsigned short NMI:1; /* RW: non maskable interrupt */ + unsigned short Halt:1; /* RW: Halt MSP clock */ + unsigned short ResetCore:1; /* RW: Reset MSP core interface */ + unsigned short Reserved:13; /* 0: Reserved */ +} DSP_BOOT_DOMAIN; + +typedef struct { + unsigned short DisableTimeout:1; /* RW: Disable LBus timeout */ + unsigned short Reserved:15; /* 0: Reserved */ +} DSP_LBUS_TIMEOUT_DISABLE; + +typedef struct { + unsigned short Memory:1; /* RW: Reset memory interface */ + unsigned short SerialPort1:1; /* RW: Reset serial port 1 interface */ + unsigned short SerialPort2:1; /* RW: Reset serial port 2 interface */ + unsigned short SerialPort3:1; /* RW: Reset serial port 3 interface */ + unsigned short Gpio:1; /* RW: Reset GPIO interface */ + unsigned short Dma:1; /* RW: Reset DMA interface */ + unsigned short SoundBlaster:1; /* RW: Reset soundblaster interface */ + unsigned short Uart:1; /* RW: Reset UART interface */ + unsigned short Midi:1; /* RW: Reset MIDI interface */ + unsigned short IsaMaster:1; /* RW: Reset ISA master interface */ + unsigned short Reserved:6; /* 0: Reserved */ +} DSP_CHIP_RESET; + +typedef struct { + unsigned short N_Divisor:6; /* RW: (N) PLL output clock divisor */ + unsigned short Reserved1:2; /* 0: reserved */ + unsigned short M_Multiplier:6; /* RW: (M) PLL feedback clock multiplier */ + unsigned short Reserved2:2; /* 0: reserved */ +} DSP_CLOCK_CONTROL_1; + +typedef struct { + unsigned short PllBypass:1; /* RW: PLL Bypass */ + unsigned short Reserved:15; /* 0: Reserved */ +} DSP_CLOCK_CONTROL_2; + +typedef struct { + unsigned short Latch8:1; + unsigned short Latch9:1; + unsigned short Latch10:1; + unsigned short Latch11:1; + unsigned short Latch12:1; + unsigned short Latch13:1; + unsigned short Latch14:1; + unsigned short Latch15:1; + unsigned short Mask8:1; + unsigned short Mask9:1; + unsigned short Mask10:1; + unsigned short Mask11:1; + unsigned short Mask12:1; + unsigned short Mask13:1; + unsigned short Mask14:1; + unsigned short Mask15:1; +} DSP_GPIO_OUTPUT_DATA_15_8; + +typedef struct { + unsigned short Enable8:1; + unsigned short Enable9:1; + unsigned short Enable10:1; + unsigned short Enable11:1; + unsigned short Enable12:1; + unsigned short Enable13:1; + unsigned short Enable14:1; + unsigned short Enable15:1; + unsigned short Mask8:1; + unsigned short Mask9:1; + unsigned short Mask10:1; + unsigned short Mask11:1; + unsigned short Mask12:1; + unsigned short Mask13:1; + unsigned short Mask14:1; + unsigned short Mask15:1; +} DSP_GPIO_DRIVER_ENABLE_15_8; + +typedef struct { + unsigned short GpioMode8:2; + unsigned short GpioMode9:2; + unsigned short GpioMode10:2; + unsigned short GpioMode11:2; + unsigned short GpioMode12:2; + unsigned short GpioMode13:2; + unsigned short GpioMode14:2; + unsigned short GpioMode15:2; +} DSP_GPIO_MODE_15_8; + +/* Component masks that are defined in dspmgr.h */ +#define MW_ADC_MASK 0x0001 +#define MW_AIC2_MASK 0x0006 +#define MW_MIDI_MASK 0x0008 +#define MW_CDDAC_MASK 0x8001 +#define MW_AIC1_MASK 0xE006 +#define MW_UART_MASK 0xE00A +#define MW_ACI_MASK 0xE00B + +/* +* Definition of 3780i configuration structure. Unless otherwise stated, +* these values are provided as input to the 3780i support layer. At present, +* the only values maintained by the 3780i support layer are the saved UART +* registers. +*/ +typedef struct _DSP_3780I_CONFIG_SETTINGS { + + /* Location of base configuration register */ + unsigned short usBaseConfigIO; + + /* Enables for various DSP components */ + int bDSPEnabled; + int bModemEnabled; + int bInterruptClaimed; + + /* IRQ, DMA, and Base I/O addresses for various DSP components */ + unsigned short usDspIrq; + unsigned short usDspDma; + unsigned short usDspBaseIO; + unsigned short usUartIrq; + unsigned short usUartBaseIO; + + /* IRQ modes for various DSP components */ + int bDspIrqActiveLow; + int bUartIrqActiveLow; + int bDspIrqPulse; + int bUartIrqPulse; + + /* Card abilities */ + unsigned uIps; + unsigned uDStoreSize; + unsigned uIStoreSize; + unsigned uDmaBandwidth; + + /* Adapter specific 3780i settings */ + unsigned short usNumTransfers; + unsigned short usReRequest; + int bEnableMEMCS16; + unsigned short usIsaMemCmdWidth; + int bGateIOCHRDY; + int bEnablePwrMgmt; + unsigned short usHBusTimerLoadValue; + int bDisableLBusTimeout; + unsigned short usN_Divisor; + unsigned short usM_Multiplier; + int bPllBypass; + unsigned short usChipletEnable; /* Used with the chip reset register to enable specific chiplets */ + + /* Saved UART registers. These are maintained by the 3780i support layer. */ + int bUartSaved; /* True after a successful save of the UART registers */ + unsigned char ucIER; /* Interrupt enable register */ + unsigned char ucFCR; /* FIFO control register */ + unsigned char ucLCR; /* Line control register */ + unsigned char ucMCR; /* Modem control register */ + unsigned char ucSCR; /* Scratch register */ + unsigned char ucDLL; /* Divisor latch, low byte */ + unsigned char ucDLM; /* Divisor latch, high byte */ +} DSP_3780I_CONFIG_SETTINGS; + + +/* 3780i support functions */ +int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, + unsigned short *pIrqMap, + unsigned short *pDmaMap); +int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings); +int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings); +int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings); +int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer, + unsigned uCount, unsigned long ulDSPAddr); +int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, + void *pvBuffer, unsigned uCount, + unsigned long ulDSPAddr); +int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer, + unsigned uCount, unsigned long ulDSPAddr); +int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer, + unsigned uCount, unsigned long ulDSPAddr); +int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer, + unsigned uCount, unsigned long ulDSPAddr); +unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO, + unsigned long ulMsaAddr); +void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, + unsigned long ulMsaAddr, unsigned short usValue); +void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, + unsigned char ucValue); +unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, + unsigned uIndex); +int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, + unsigned short *pusIPCSource); + +/* I/O port access macros */ +#define MKWORD(var) (*((unsigned short *)(&var))) +#define MKBYTE(var) (*((unsigned char *)(&var))) + +#define WriteMsaCfg(addr,value) dsp3780I_WriteMsaCfg(usDspBaseIO,addr,value) +#define ReadMsaCfg(addr) dsp3780I_ReadMsaCfg(usDspBaseIO,addr) +#define WriteGenCfg(index,value) dsp3780I_WriteGenCfg(usDspBaseIO,index,value) +#define ReadGenCfg(index) dsp3780I_ReadGenCfg(usDspBaseIO,index) + +#define InWordDsp(index) inw(usDspBaseIO+index) +#define InByteDsp(index) inb(usDspBaseIO+index) +#define OutWordDsp(index,value) outw(value,usDspBaseIO+index) +#define OutByteDsp(index,value) outb(value,usDspBaseIO+index) + +#endif diff --git a/drivers/char/mwave/Makefile b/drivers/char/mwave/Makefile new file mode 100644 index 000000000000..70048f070fe3 --- /dev/null +++ b/drivers/char/mwave/Makefile @@ -0,0 +1,25 @@ +# +# Makefile for ACP Modem (Mwave). +# +# See the README file in this directory for more info. <paulsch@us.ibm.com> +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now inherited from the +# parent makes.. +# + +# To compile in lots (~20 KiB) of run-time enablable printk()s for debugging: +EXTRA_CFLAGS += -DMW_TRACE + +# To have the mwave driver disable other uarts if necessary +# EXTRA_CFLAGS += -DMWAVE_FUTZ_WITH_OTHER_DEVICES + +O_TARGET := mwave.o + +obj-y := mwavedd.o smapi.o tp3780i.o 3780i.o +obj-m := $(O_TARGET) + +include $(TOPDIR)/Rules.make diff --git a/drivers/char/mwave/README b/drivers/char/mwave/README new file mode 100644 index 000000000000..70f8d19fb79f --- /dev/null +++ b/drivers/char/mwave/README @@ -0,0 +1,50 @@ +Module options +-------------- + +The mwave module takes the following options. Note that these options +are not saved by the BIOS and so do not persist after unload and reload. + + mwave_debug=value, where value is bitwise OR of trace flags: + 0x0001 mwavedd api tracing + 0x0002 smapi api tracing + 0x0004 3780i tracing + 0x0008 tp3780i tracing + + Tracing only occurs if the driver has been compiled with the + MW_TRACE macro #defined (i.e. let EXTRA_CFLAGS += -DMW_TRACE + in the Makefile). + + mwave_3780i_irq=5/7/10/11/15 + If the dsp irq has not been setup and stored in bios by the + thinkpad configuration utility then this parameter allows the + irq used by the dsp to be configured. + + mwave_3780i_io=0x130/0x350/0x0070/0xDB0 + If the dsp io range has not been setup and stored in bios by the + thinkpad configuration utility then this parameter allows the + io range used by the dsp to be configured. + + mwave_uart_irq=3/4 + If the mwave's uart irq has not been setup and stored in bios by the + thinkpad configuration utility then this parameter allows the + irq used by the mwave uart to be configured. + + mwave_uart_io=0x3f8/0x2f8/0x3E8/0x2E8 + If the uart io range has not been setup and stored in bios by the + thinkpad configuration utility then this parameter allows the + io range used by the mwave uart to be configured. + +Example to enable the 3780i DSP using ttyS1 resources: + + insmod mwave mwave_3780i_irq=10 mwave_3780i_io=0x0130 mwave_uart_irq=3 mwave_uart_io=0x2f8 + +Accessing the driver +-------------------- + +You must also create a node for the driver. Without devfs: + mkdir -p /dev/modems + mknod --mode=660 /dev/modems/mwave c 10 219 +With devfs: + mkdir -p /dev/modems + ln -s ../misc/mwave /dev/modems/mwave + diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c new file mode 100644 index 000000000000..839904342781 --- /dev/null +++ b/drivers/char/mwave/mwavedd.c @@ -0,0 +1,638 @@ +/* +* +* mwavedd.c -- mwave device driver +* +* +* Written By: Mike Sullivan IBM Corporation +* +* Copyright (C) 1999 IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* NO WARRANTY +* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR +* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT +* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is +* solely responsible for determining the appropriateness of using and +* distributing the Program and assumes all risks associated with its +* exercise of rights under this Agreement, including but not limited to +* the risks and costs of program errors, damage to or loss of data, +* programs or equipment, and unavailability or interruption of operations. +* +* DISCLAIMER OF LIABILITY +* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +* 10/23/2000 - Alpha Release +* First release to the public +*/ + +#include <linux/version.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/major.h> +#include <linux/miscdevice.h> +#include <linux/proc_fs.h> +#include <linux/serial.h> +#include <linux/sched.h> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#include <linux/spinlock.h> +#else +#include <asm/spinlock.h> +#endif +#include <linux/delay.h> +#include "smapi.h" +#include "mwavedd.h" +#include "3780i.h" +#include "tp3780i.h" + +#ifndef __exit +#define __exit +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +static int mwave_get_info(char *buf, char **start, off_t offset, int len); +#else +static int mwave_read_proc(char *buf, char **start, off_t offset, int xlen, int unused); +static struct proc_dir_entry mwave_proc = { + 0, /* unsigned short low_ino */ + 5, /* unsigned short namelen */ + "mwave", /* const char *name */ + S_IFREG | S_IRUGO, /* mode_t mode */ + 1, /* nlink_t nlink */ + 0, /* uid_t uid */ + 0, /* gid_t gid */ + 0, /* unsigned long size */ + NULL, /* struct inode_operations *ops */ + &mwave_read_proc /* int (*get_info) (...) */ +}; +#endif + +/* +* These parameters support the setting of MWave resources. Note that no +* checks are made against other devices (ie. superio) for conflicts. +* We'll depend on users using the tpctl utility to do that for now +*/ +int mwave_debug = 0; +int mwave_3780i_irq = 0; +int mwave_3780i_io = 0; +int mwave_uart_irq = 0; +int mwave_uart_io = 0; +MODULE_PARM(mwave_debug, "i"); +MODULE_PARM(mwave_3780i_irq, "i"); +MODULE_PARM(mwave_3780i_io, "i"); +MODULE_PARM(mwave_uart_irq, "i"); +MODULE_PARM(mwave_uart_io, "i"); + +static int mwave_open(struct inode *inode, struct file *file); +static int mwave_close(struct inode *inode, struct file *file); +static int mwave_ioctl(struct inode *inode, struct file *filp, + unsigned int iocmd, unsigned long ioarg); + +MWAVE_DEVICE_DATA mwave_s_mdd; + +static int mwave_open(struct inode *inode, struct file *file) +{ + unsigned int retval = 0; + + PRINTK_3(TRACE_MWAVE, + "mwavedd::mwave_open, entry inode %x file %x\n", + (int) inode, (int) file); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_open, exit return retval %x\n", retval); + + MOD_INC_USE_COUNT; + return retval; +} + +static int mwave_close(struct inode *inode, struct file *file) +{ + unsigned int retval = 0; + + PRINTK_3(TRACE_MWAVE, + "mwavedd::mwave_close, entry inode %x file %x\n", + (int) inode, (int) file); + + PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_close, exit retval %x\n", + retval); + + MOD_DEC_USE_COUNT; + return retval; +} + +static int mwave_ioctl(struct inode *inode, struct file *file, + unsigned int iocmd, unsigned long ioarg) +{ + unsigned int retval = 0; + pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; + + PRINTK_5(TRACE_MWAVE, + "mwavedd::mwave_ioctl, entry inode %x file %x cmd %x arg %x\n", + (int) inode, (int) file, iocmd, (int) ioarg); + + switch (iocmd) { + + case IOCTL_MW_RESET: + PRINTK_1(TRACE_MWAVE, + "mwavedd::mwave_ioctl, IOCTL_MW_RESET calling tp3780I_ResetDSP\n"); + retval = tp3780I_ResetDSP(&pDrvData->rBDData); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl, IOCTL_MW_RESET retval %x from tp3780I_ResetDSP\n", + retval); + break; + + case IOCTL_MW_RUN: + PRINTK_1(TRACE_MWAVE, + "mwavedd::mwave_ioctl, IOCTL_MW_RUN calling tp3780I_StartDSP\n"); + retval = tp3780I_StartDSP(&pDrvData->rBDData); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl, IOCTL_MW_RUN retval %x from tp3780I_StartDSP\n", + retval); + break; + + case IOCTL_MW_DSP_ABILITIES: { + MW_ABILITIES rAbilities; + + PRINTK_1(TRACE_MWAVE, + "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES calling tp3780I_QueryAbilities\n"); + retval = tp3780I_QueryAbilities(&pDrvData->rBDData, &rAbilities); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES retval %x from tp3780I_QueryAbilities\n", + retval); + if (retval == 0) { + if( copy_to_user((char *) ioarg, (char *) &rAbilities, sizeof(MW_ABILITIES)) ) + return -EFAULT; + } + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES exit retval %x\n", + retval); + } + break; + + case IOCTL_MW_READ_DATA: + case IOCTL_MW_READCLEAR_DATA: { + MW_READWRITE rReadData; + unsigned short *pusBuffer = 0; + + if( copy_from_user((char *) &rReadData, (char *) ioarg, sizeof(MW_READWRITE)) ) + return -EFAULT; + pusBuffer = (unsigned short *) (rReadData.pBuf); + + PRINTK_4(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_READ_DATA, size %lx, ioarg %lx pusBuffer %p\n", + rReadData.ulDataLength, ioarg, pusBuffer); + retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd, + (void *) pusBuffer, rReadData.ulDataLength, rReadData.usDspAddress); + } + break; + + case IOCTL_MW_READ_INST: { + MW_READWRITE rReadData; + unsigned short *pusBuffer = 0; + + if( copy_from_user((char *) &rReadData, (char *) ioarg, sizeof(MW_READWRITE)) ) + return -EFAULT; + pusBuffer = (unsigned short *) (rReadData.pBuf); + + PRINTK_4(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_READ_INST, size %lx, ioarg %lx pusBuffer %p\n", + rReadData.ulDataLength / 2, ioarg, + pusBuffer); + retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, + iocmd, pusBuffer, + rReadData.ulDataLength / 2, + rReadData.usDspAddress); + } + break; + + case IOCTL_MW_WRITE_DATA: { + MW_READWRITE rWriteData; + unsigned short *pusBuffer = 0; + + if( copy_from_user((char *) &rWriteData, (char *) ioarg, sizeof(MW_READWRITE)) ) + return -EFAULT; + pusBuffer = (unsigned short *) (rWriteData.pBuf); + + PRINTK_4(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA, size %lx, ioarg %lx pusBuffer %p\n", + rWriteData.ulDataLength, ioarg, + pusBuffer); + retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd, + pusBuffer, rWriteData.ulDataLength, rWriteData.usDspAddress); + } + break; + + case IOCTL_MW_WRITE_INST: { + MW_READWRITE rWriteData; + unsigned short *pusBuffer = 0; + + if( copy_from_user((char *) &rWriteData, (char *) ioarg, sizeof(MW_READWRITE)) ) + return -EFAULT; + pusBuffer = (unsigned short *) (rWriteData.pBuf); + + PRINTK_4(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST, size %lx, ioarg %lx pusBuffer %p\n", + rWriteData.ulDataLength, ioarg, + pusBuffer); + retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData, iocmd, + pusBuffer, rWriteData.ulDataLength, rWriteData.usDspAddress); + } + break; + + case IOCTL_MW_REGISTER_IPC: { + unsigned int ipcnum = (unsigned int) ioarg; + + PRINTK_3(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x entry usIntCount %x\n", + ipcnum, + pDrvData->IPCs[ipcnum].usIntCount); + + if (ipcnum > 16) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_REGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum); + return -EINVAL; + } + pDrvData->IPCs[ipcnum].bIsHere = FALSE; + pDrvData->IPCs[ipcnum].bIsEnabled = TRUE; + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + current->nice = -20; /* boost to provide priority timing */ + #else + current->priority = 0x28; /* boost to provide priority timing */ + #endif + + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x exit\n", + ipcnum); + } + break; + + case IOCTL_MW_GET_IPC: { + unsigned int ipcnum = (unsigned int) ioarg; + spinlock_t ipc_lock = SPIN_LOCK_UNLOCKED; + unsigned long flags; + + PRINTK_3(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x, usIntCount %x\n", + ipcnum, + pDrvData->IPCs[ipcnum].usIntCount); + if (ipcnum > 16) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_GET_IPC: Error: Invalid ipcnum %x\n", ipcnum); + return -EINVAL; + } + + if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) { + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl, thread for ipc %x going to sleep\n", + ipcnum); + + spin_lock_irqsave(&ipc_lock, flags); + /* check whether an event was signalled by */ + /* the interrupt handler while we were gone */ + if (pDrvData->IPCs[ipcnum].usIntCount == 1) { /* first int has occurred (race condition) */ + pDrvData->IPCs[ipcnum].usIntCount = 2; /* first int has been handled */ + spin_unlock_irqrestore(&ipc_lock, flags); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x handling first int\n", + ipcnum); + } else { /* either 1st int has not yet occurred, or we have already handled the first int */ + pDrvData->IPCs[ipcnum].bIsHere = TRUE; + interruptible_sleep_on(&pDrvData->IPCs[ipcnum].ipc_wait_queue); + pDrvData->IPCs[ipcnum].bIsHere = FALSE; + if (pDrvData->IPCs[ipcnum].usIntCount == 1) { + pDrvData->IPCs[ipcnum]. + usIntCount = 2; + } + spin_unlock_irqrestore(&ipc_lock, flags); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x woke up and returning to application\n", + ipcnum); + } + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC, returning thread for ipc %x processing\n", + ipcnum); + } + } + break; + + case IOCTL_MW_UNREGISTER_IPC: { + unsigned int ipcnum = (unsigned int) ioarg; + + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC ipcnum %x\n", + ipcnum); + if (ipcnum > 16) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_UNREGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum); + return -EINVAL; + } + if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) { + pDrvData->IPCs[ipcnum].bIsEnabled = FALSE; + if (pDrvData->IPCs[ipcnum].bIsHere == TRUE) { + wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue); + } + } + } + break; + + default: + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: Error: Unrecognized iocmd %x\n", iocmd); + return -ENOTTY; + break; + } /* switch */ + + PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_ioctl, exit retval %x\n", retval); + + return retval; +} + + +static ssize_t mwave_read(struct file *file, char *buf, size_t count, + loff_t * ppos) +{ + PRINTK_5(TRACE_MWAVE, + "mwavedd::mwave_read entry file %p, buf %p, count %x ppos %p\n", + file, buf, count, ppos); + + return -EINVAL; +} + + +static ssize_t mwave_write(struct file *file, const char *buf, + size_t count, loff_t * ppos) +{ + PRINTK_5(TRACE_MWAVE, + "mwavedd::mwave_write entry file %p, buf %p, count %x ppos %p\n", + file, buf, count, ppos); + + return -EINVAL; +} + + +static int register_serial_portandirq(unsigned int port, int irq) +{ + struct serial_struct serial; + + switch ( port ) { + case 0x3f8: + case 0x2f8: + case 0x3e8: + case 0x2e8: + /* OK */ + break; + default: + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::register_serial_portandirq: Error: Illegal port %x\n", port ); + return -1; + } /* switch */ + /* port is okay */ + + switch ( irq ) { + case 3: + case 4: + case 5: + case 7: + /* OK */ + break; + default: + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::register_serial_portandirq: Error: Illegal irq %x\n", irq ); + return -1; + } /* switch */ + /* irq is okay */ + + memset(&serial, 0, sizeof(serial)); + serial.port = port; + serial.irq = irq; + serial.flags = ASYNC_SHARE_IRQ; + + return register_serial(&serial); +} + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +static struct file_operations mwave_fops = { + owner:THIS_MODULE, + read:mwave_read, + write:mwave_write, + ioctl:mwave_ioctl, + open:mwave_open, + release:mwave_close +}; +#else +static struct file_operations mwave_fops = { + NULL, /* lseek */ + mwave_read, /* read */ + mwave_write, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + mwave_ioctl, /* ioctl */ + NULL, /* mmap */ + mwave_open, /* open */ + NULL, /* flush */ + mwave_close /* release */ +}; +#endif + +static struct miscdevice mwave_misc_dev = { MWAVE_MINOR, "mwave", &mwave_fops }; + +/* +* mwave_init is called on module load +* +* mwave_exit is called on module unload +* mwave_exit is also used to clean up after an aborted mwave_init +*/ +static void __exit mwave_exit(void) +{ + pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; + + PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit entry\n"); + + if (pDrvData->bProcEntryCreated) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + remove_proc_entry("mwave", NULL); +#else + proc_unregister(&proc_root, mwave_proc.low_ino); +#endif + } + if ( pDrvData->sLine >= 0 ) { + unregister_serial(pDrvData->sLine); + } + if (pDrvData->bMwaveDevRegistered) { + misc_deregister(&mwave_misc_dev); + } + if (pDrvData->bDSPEnabled) { + tp3780I_DisableDSP(&pDrvData->rBDData); + } + if (pDrvData->bResourcesClaimed) { + tp3780I_ReleaseResources(&pDrvData->rBDData); + } + if (pDrvData->bBDInitialized) { + tp3780I_Cleanup(&pDrvData->rBDData); + } + + PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit exit\n"); +} + +module_exit(mwave_exit); + +static int __init mwave_init(void) +{ + int i; + int retval = 0; + unsigned int resultMiscRegister; + pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; + + memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA)); + + PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_init entry\n"); + + pDrvData->bBDInitialized = FALSE; + pDrvData->bResourcesClaimed = FALSE; + pDrvData->bDSPEnabled = FALSE; + pDrvData->bDSPReset = FALSE; + pDrvData->bMwaveDevRegistered = FALSE; + pDrvData->sLine = -1; + pDrvData->bProcEntryCreated = FALSE; + + for (i = 0; i < 16; i++) { + pDrvData->IPCs[i].bIsEnabled = FALSE; + pDrvData->IPCs[i].bIsHere = FALSE; + pDrvData->IPCs[i].usIntCount = 0; /* no ints received yet */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + init_waitqueue_head(&pDrvData->IPCs[i].ipc_wait_queue); +#endif + } + + retval = tp3780I_InitializeBoardData(&pDrvData->rBDData); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_init, return from tp3780I_InitializeBoardData retval %x\n", + retval); + if (retval) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_init: Error: Failed to initialize board data\n"); + goto cleanup_error; + } + pDrvData->bBDInitialized = TRUE; + + retval = tp3780I_CalcResources(&pDrvData->rBDData); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_init, return from tp3780I_CalcResources retval %x\n", + retval); + if (retval) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to calculate resources\n"); + goto cleanup_error; + } + + retval = tp3780I_ClaimResources(&pDrvData->rBDData); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_init, return from tp3780I_ClaimResources retval %x\n", + retval); + if (retval) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to claim resources\n"); + goto cleanup_error; + } + pDrvData->bResourcesClaimed = TRUE; + + retval = tp3780I_EnableDSP(&pDrvData->rBDData); + PRINTK_2(TRACE_MWAVE, + "mwavedd::mwave_init, return from tp3780I_EnableDSP retval %x\n", + retval); + if (retval) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to enable DSP\n"); + goto cleanup_error; + } + pDrvData->bDSPEnabled = TRUE; + + resultMiscRegister = misc_register(&mwave_misc_dev); + if (resultMiscRegister < 0) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to register misc device\n"); + goto cleanup_error; + } + pDrvData->bMwaveDevRegistered = TRUE; + + pDrvData->sLine = register_serial_portandirq( + pDrvData->rBDData.rDspSettings.usUartBaseIO, + pDrvData->rBDData.rDspSettings.usUartIrq + ); + if (pDrvData->sLine < 0) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to register serial driver\n"); + goto cleanup_error; + } + /* uart is registered */ + + if ( +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + !create_proc_info_entry("mwave", 0, NULL, mwave_get_info) +#else + proc_register(&proc_root, &mwave_proc) +#endif + ) { + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_init: Error: Failed to register /proc/mwave\n"); + goto cleanup_error; + } + pDrvData->bProcEntryCreated = TRUE; + + /* SUCCESS! */ + return 0; + + cleanup_error: + PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_init: Error: Failed to initialize\n"); + mwave_exit(); /* clean up */ + + return -EIO; +} + +module_init(mwave_init); + + +/* +* proc entry stuff added by Ian Pilcher <pilcher@us.ibm.com> +*/ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +static int mwave_get_info(char *buf, char **start, off_t offset, int len) +{ + DSP_3780I_CONFIG_SETTINGS *pSettings = &mwave_s_mdd.rBDData.rDspSettings; + + char *out = buf; + + out += sprintf(out, "3780i_IRQ %i\n", pSettings->usDspIrq); + out += sprintf(out, "3780i_DMA %i\n", pSettings->usDspDma); + out += sprintf(out, "3780i_IO %#.4x\n", pSettings->usDspBaseIO); + out += sprintf(out, "UART_IRQ %i\n", pSettings->usUartIrq); + out += sprintf(out, "UART_IO %#.4x\n", pSettings->usUartBaseIO); + + return out - buf; +} +#else /* kernel version < 2.4.0 */ +static int mwave_read_proc(char *buf, char **start, off_t offset, + int xlen, int unused) +{ + DSP_3780I_CONFIG_SETTINGS *pSettings = &mwave_s_mdd.rBDData.rDspSettings; + int len; + + len = sprintf(buf, "3780i_IRQ %i\n", pSettings->usDspIrq); + len += sprintf(&buf[len], "3780i_DMA %i\n", pSettings->usDspDma); + len += sprintf(&buf[len], "3780i_IO %#.4x\n", pSettings->usDspBaseIO); + len += sprintf(&buf[len], "UART_IRQ %i\n", pSettings->usUartIrq); + len += sprintf(&buf[len], "UART_IO %#.4x\n", pSettings->usUartBaseIO); + + return len; +} +#endif diff --git a/drivers/char/mwave/mwavedd.h b/drivers/char/mwave/mwavedd.h new file mode 100644 index 000000000000..1335b74a3099 --- /dev/null +++ b/drivers/char/mwave/mwavedd.h @@ -0,0 +1,151 @@ +/* +* +* mwavedd.h -- declarations for mwave device driver +* +* +* Written By: Mike Sullivan IBM Corporation +* +* Copyright (C) 1999 IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* NO WARRANTY +* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR +* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT +* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is +* solely responsible for determining the appropriateness of using and +* distributing the Program and assumes all risks associated with its +* exercise of rights under this Agreement, including but not limited to +* the risks and costs of program errors, damage to or loss of data, +* programs or equipment, and unavailability or interruption of operations. +* +* DISCLAIMER OF LIABILITY +* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +* 10/23/2000 - Alpha Release +* First release to the public +*/ + +#ifndef _LINUX_MWAVEDD_H +#define _LINUX_MWAVEDD_H +#include "3780i.h" +#include "tp3780i.h" +#include "mwavepub.h" +#include <linux/ioctl.h> +#include <asm/uaccess.h> + +extern int mwave_debug; +extern int mwave_3780i_irq; +extern int mwave_3780i_io; +extern int mwave_uart_irq; +extern int mwave_uart_io; + +#define PRINTK_ERROR printk +#define KERN_ERR_MWAVE KERN_ERR "mwave: " + +#define TRACE_MWAVE 0x0001 +#define TRACE_SMAPI 0x0002 +#define TRACE_3780I 0x0004 +#define TRACE_TP3780I 0x0008 + +#ifdef MW_TRACE +#define PRINTK_1(f,s) \ + if (f & (mwave_debug)) { \ + printk(s); \ + } + +#define PRINTK_2(f,s,v1) \ + if (f & (mwave_debug)) { \ + printk(s,v1); \ + } + +#define PRINTK_3(f,s,v1,v2) \ + if (f & (mwave_debug)) { \ + printk(s,v1,v2); \ + } + +#define PRINTK_4(f,s,v1,v2,v3) \ + if (f & (mwave_debug)) { \ + printk(s,v1,v2,v3); \ + } + +#define PRINTK_5(f,s,v1,v2,v3,v4) \ + if (f & (mwave_debug)) { \ + printk(s,v1,v2,v3,v4); \ + } + +#define PRINTK_6(f,s,v1,v2,v3,v4,v5) \ + if (f & (mwave_debug)) { \ + printk(s,v1,v2,v3,v4,v5); \ + } + +#define PRINTK_7(f,s,v1,v2,v3,v4,v5,v6) \ + if (f & (mwave_debug)) { \ + printk(s,v1,v2,v3,v4,v5,v6); \ + } + +#define PRINTK_8(f,s,v1,v2,v3,v4,v5,v6,v7) \ + if (f & (mwave_debug)) { \ + printk(s,v1,v2,v3,v4,v5,v6,v7); \ + } + +#else +#define PRINTK_1(f,s) +#define PRINTK_2(f,s,v1) +#define PRINTK_3(f,s,v1,v2) +#define PRINTK_4(f,s,v1,v2,v3) +#define PRINTK_5(f,s,v1,v2,v3,v4) +#define PRINTK_6(f,s,v1,v2,v3,v4,v5) +#define PRINTK_7(f,s,v1,v2,v3,v4,v5,v6) +#define PRINTK_8(f,s,v1,v2,v3,v4,v5,v6,v7) +#endif + + +typedef struct _MWAVE_IPC { + unsigned short usIntCount; /* 0=none, 1=first, 2=greater than 1st */ + BOOLEAN bIsEnabled; + BOOLEAN bIsHere; + /* entry spin lock */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + wait_queue_head_t ipc_wait_queue; +#else + struct wait_queue *ipc_wait_queue; +#endif +} MWAVE_IPC; + +typedef struct _MWAVE_DEVICE_DATA { + THINKPAD_BD_DATA rBDData; /* board driver's data area */ + unsigned long ulIPCSource_ISR; /* IPC source bits for recently processed intr, set during ISR processing */ + unsigned long ulIPCSource_DPC; /* IPC source bits for recently processed intr, set during DPC processing */ + BOOLEAN bBDInitialized; + BOOLEAN bResourcesClaimed; + BOOLEAN bDSPEnabled; + BOOLEAN bDSPReset; + MWAVE_IPC IPCs[16]; + BOOLEAN bMwaveDevRegistered; + BOOLEAN bProcEntryCreated; + short sLine; + +} MWAVE_DEVICE_DATA, *pMWAVE_DEVICE_DATA; + +#endif diff --git a/drivers/char/mwave/mwavepub.h b/drivers/char/mwave/mwavepub.h new file mode 100644 index 000000000000..01578db4989d --- /dev/null +++ b/drivers/char/mwave/mwavepub.h @@ -0,0 +1,94 @@ +/* +* +* mwavepub.h -- PUBLIC declarations for the mwave driver +* and applications using it +* +* +* Written By: Mike Sullivan IBM Corporation +* +* Copyright (C) 1999 IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* NO WARRANTY +* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR +* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT +* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is +* solely responsible for determining the appropriateness of using and +* distributing the Program and assumes all risks associated with its +* exercise of rights under this Agreement, including but not limited to +* the risks and costs of program errors, damage to or loss of data, +* programs or equipment, and unavailability or interruption of operations. +* +* DISCLAIMER OF LIABILITY +* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +* 10/23/2000 - Alpha Release +* First release to the public +*/ + +#ifndef _LINUX_MWAVEPUB_H +#define _LINUX_MWAVEPUB_H + +#ifndef MWAVEM_APP_DIST +#include <linux/miscdevice.h> +#endif + +#ifdef MWAVEM_APP_DIST +#define MWAVE_MINOR 219 +#endif + +typedef struct _MW_ABILITIES { + unsigned long instr_per_sec; + unsigned long data_size; + unsigned long inst_size; + unsigned long bus_dma_bw; + unsigned short uart_enable; + short component_count; + unsigned long component_list[7]; + char mwave_os_name[16]; + char bios_task_name[16]; +} MW_ABILITIES, *pMW_ABILITIES; + + +typedef struct _MW_READWRITE { + unsigned short usDspAddress; /* The dsp address */ + unsigned long ulDataLength; /* The size in bytes of the data or user buffer */ + void *pBuf; /* Input:variable sized buffer */ +} MW_READWRITE, *pMW_READWRITE; + +#define IOCTL_MW_RESET _IO(MWAVE_MINOR,1) +#define IOCTL_MW_RUN _IO(MWAVE_MINOR,2) +#define IOCTL_MW_DSP_ABILITIES _IOR(MWAVE_MINOR,3,MW_ABILITIES) +#define IOCTL_MW_READ_DATA _IOR(MWAVE_MINOR,4,MW_READWRITE) +#define IOCTL_MW_READCLEAR_DATA _IOR(MWAVE_MINOR,5,MW_READWRITE) +#define IOCTL_MW_READ_INST _IOR(MWAVE_MINOR,6,MW_READWRITE) +#define IOCTL_MW_WRITE_DATA _IOW(MWAVE_MINOR,7,MW_READWRITE) +#define IOCTL_MW_WRITE_INST _IOW(MWAVE_MINOR,8,MW_READWRITE) +#define IOCTL_MW_REGISTER_IPC _IOW(MWAVE_MINOR,9,int) +#define IOCTL_MW_UNREGISTER_IPC _IOW(MWAVE_MINOR,10,int) +#define IOCTL_MW_GET_IPC _IOW(MWAVE_MINOR,11,int) +#define IOCTL_MW_TRACE _IOR(MWAVE_MINOR,12,MW_READWRITE) + + +#endif diff --git a/drivers/char/mwave/smapi.c b/drivers/char/mwave/smapi.c new file mode 100644 index 000000000000..6ac317f3747d --- /dev/null +++ b/drivers/char/mwave/smapi.c @@ -0,0 +1,563 @@ +/* +* +* smapi.c -- SMAPI interface routines +* +* +* Written By: Mike Sullivan IBM Corporation +* +* Copyright (C) 1999 IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* NO WARRANTY +* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR +* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT +* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is +* solely responsible for determining the appropriateness of using and +* distributing the Program and assumes all risks associated with its +* exercise of rights under this Agreement, including but not limited to +* the risks and costs of program errors, damage to or loss of data, +* programs or equipment, and unavailability or interruption of operations. +* +* DISCLAIMER OF LIABILITY +* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +* 10/23/2000 - Alpha Release +* First release to the public +*/ + +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/mc146818rtc.h> /* CMOS defines */ +#include "smapi.h" +#include "mwavedd.h" + +static unsigned short g_usSmapiPort = 0; + + +int smapi_request(unsigned short inBX, unsigned short inCX, + unsigned short inDI, unsigned short inSI, + unsigned short *outAX, unsigned short *outBX, + unsigned short *outCX, unsigned short *outDX, + unsigned short *outDI, unsigned short *outSI) +{ + unsigned short myoutAX = 2, *pmyoutAX = &myoutAX; + unsigned short myoutBX = 3, *pmyoutBX = &myoutBX; + unsigned short myoutCX = 4, *pmyoutCX = &myoutCX; + unsigned short myoutDX = 5, *pmyoutDX = &myoutDX; + unsigned short myoutDI = 6, *pmyoutDI = &myoutDI; + unsigned short myoutSI = 7, *pmyoutSI = &myoutSI; + unsigned short usSmapiOK = -EIO, *pusSmapiOK = &usSmapiOK; + unsigned int inBXCX = (inBX << 16) | inCX; + unsigned int inDISI = (inDI << 16) | inSI; + int retval = 0; + + PRINTK_5(TRACE_SMAPI, "inBX %x inCX %x inDI %x inSI %x\n", + inBX, inCX, inDI, inSI); + + __asm__ __volatile__("movw $0x5380,%%ax\n\t" + "movl %7,%%ebx\n\t" + "shrl $16, %%ebx\n\t" + "movw %7,%%cx\n\t" + "movl %8,%%edi\n\t" + "shrl $16,%%edi\n\t" + "movw %8,%%si\n\t" + "movw %9,%%dx\n\t" + "out %%al,%%dx\n\t" + "out %%al,$0x4F\n\t" + "cmpb $0x53,%%ah\n\t" + "je 2f\n\t" + "1:\n\t" + "orb %%ah,%%ah\n\t" + "jnz 2f\n\t" + "movw %%ax,%0\n\t" + "movw %%bx,%1\n\t" + "movw %%cx,%2\n\t" + "movw %%dx,%3\n\t" + "movw %%di,%4\n\t" + "movw %%si,%5\n\t" + "movw $1,%6\n\t" + "2:\n\t":"=m"(*(unsigned short *) pmyoutAX), + "=m"(*(unsigned short *) pmyoutBX), + "=m"(*(unsigned short *) pmyoutCX), + "=m"(*(unsigned short *) pmyoutDX), + "=m"(*(unsigned short *) pmyoutDI), + "=m"(*(unsigned short *) pmyoutSI), + "=m"(*(unsigned short *) pusSmapiOK) + :"m"(inBXCX), "m"(inDISI), "m"(g_usSmapiPort) + :"%eax", "%ebx", "%ecx", "%edx", "%edi", + "%esi"); + + PRINTK_8(TRACE_SMAPI, + "myoutAX %x myoutBX %x myoutCX %x myoutDX %x myoutDI %x myoutSI %x usSmapiOK %x\n", + myoutAX, myoutBX, myoutCX, myoutDX, myoutDI, myoutSI, + usSmapiOK); + *outAX = myoutAX; + *outBX = myoutBX; + *outCX = myoutCX; + *outDX = myoutDX; + *outDI = myoutDI; + *outSI = myoutSI; + + retval = (usSmapiOK == 1) ? 0 : -EIO; + PRINTK_2(TRACE_SMAPI, "smapi::smapi_request exit retval %x\n", retval); + return retval; +} + + +int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings) +{ + int bRC = -EIO; + unsigned short usAX, usBX, usCX, usDX, usDI, usSI; + unsigned short ausDspBases[] = { 0x0030, 0x4E30, 0x8E30, 0xCE30, 0x0130, 0x0350, 0x0070, 0x0DB0 }; + unsigned short ausUartBases[] = { 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; + unsigned short numDspBases = 8; + unsigned short numUartBases = 4; + + PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg entry\n"); + + bRC = smapi_request(0x1802, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) { + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Error: Could not get DSP Settings. Aborting.\n"); + return bRC; + } + + PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n"); + + pSettings->bDSPPresent = ((usBX & 0x0100) != 0); + pSettings->bDSPEnabled = ((usCX & 0x0001) != 0); + pSettings->usDspIRQ = usSI & 0x00FF; + pSettings->usDspDMA = (usSI & 0xFF00) >> 8; + if ((usDI & 0x00FF) < numDspBases) { + pSettings->usDspBaseIO = ausDspBases[usDI & 0x00FF]; + } else { + pSettings->usDspBaseIO = 0; + } + PRINTK_6(TRACE_SMAPI, + "smapi::smapi_query_DSP_cfg get DSP Settings bDSPPresent %x bDSPEnabled %x usDspIRQ %x usDspDMA %x usDspBaseIO %x\n", + pSettings->bDSPPresent, pSettings->bDSPEnabled, + pSettings->usDspIRQ, pSettings->usDspDMA, + pSettings->usDspBaseIO); + + /* check for illegal values */ + if ( pSettings->usDspBaseIO == 0 ) + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP base I/O address is 0\n"); + if ( pSettings->usDspIRQ == 0 ) + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP IRQ line is 0\n"); + + bRC = smapi_request(0x1804, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) { + PRINTK_ERROR("smapi::smapi_query_DSP_cfg: Error: Could not get DSP modem settings. Aborting.\n"); + return bRC; + } + + PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n"); + + pSettings->bModemEnabled = ((usCX & 0x0001) != 0); + pSettings->usUartIRQ = usSI & 0x000F; + if (((usSI & 0xFF00) >> 8) < numUartBases) { + pSettings->usUartBaseIO = ausUartBases[(usSI & 0xFF00) >> 8]; + } else { + pSettings->usUartBaseIO = 0; + } + + PRINTK_4(TRACE_SMAPI, + "smapi::smapi_query_DSP_cfg get DSP modem settings bModemEnabled %x usUartIRQ %x usUartBaseIO %x\n", + pSettings->bModemEnabled, + pSettings->usUartIRQ, + pSettings->usUartBaseIO); + + /* check for illegal values */ + if ( pSettings->usUartBaseIO == 0 ) + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART base I/O address is 0\n"); + if ( pSettings->usUartIRQ == 0 ) + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART IRQ line is 0\n"); + + PRINTK_2(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg exit bRC %x\n", bRC); + + return bRC; +} + + +int smapi_set_DSP_cfg(void) +{ + int bRC = -EIO; + int i; + unsigned short usAX, usBX, usCX, usDX, usDI, usSI; + unsigned short ausDspBases[] = { 0x0030, 0x4E30, 0x8E30, 0xCE30, 0x0130, 0x0350, 0x0070, 0x0DB0 }; + unsigned short ausUartBases[] = { 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; + unsigned short ausDspIrqs[] = { 5, 7, 10, 11, 15 }; + unsigned short ausUartIrqs[] = { 3, 4 }; + + unsigned short numDspBases = 8; + unsigned short numUartBases = 4; + unsigned short numDspIrqs = 5; + unsigned short numUartIrqs = 2; + unsigned short dspio_index = 0, uartio_index = 0; + + PRINTK_5(TRACE_SMAPI, + "smapi::smapi_set_DSP_cfg entry mwave_3780i_irq %x mwave_3780i_io %x mwave_uart_irq %x mwave_uart_io %x\n", + mwave_3780i_irq, mwave_3780i_io, mwave_uart_irq, mwave_uart_io); + + if (mwave_3780i_io) { + for (i = 0; i < numDspBases; i++) { + if (mwave_3780i_io == ausDspBases[i]) + break; + } + if (i == numDspBases) { + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_io address %x. Aborting.\n", mwave_3780i_io); + return bRC; + } + dspio_index = i; + } + + if (mwave_3780i_irq) { + for (i = 0; i < numDspIrqs; i++) { + if (mwave_3780i_irq == ausDspIrqs[i]) + break; + } + if (i == numDspIrqs) { + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_irq %x. Aborting.\n", mwave_3780i_irq); + return bRC; + } + } + + if (mwave_uart_io) { + for (i = 0; i < numUartBases; i++) { + if (mwave_uart_io == ausUartBases[i]) + break; + } + if (i == numUartBases) { + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_io address %x. Aborting.\n", mwave_uart_io); + return bRC; + } + uartio_index = i; + } + + + if (mwave_uart_irq) { + for (i = 0; i < numUartIrqs; i++) { + if (mwave_uart_irq == ausUartIrqs[i]) + break; + } + if (i == numUartIrqs) { + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_irq %x. Aborting.\n", mwave_uart_irq); + return bRC; + } + } + + if (mwave_uart_irq || mwave_uart_io) { + + /* Check serial port A */ + bRC = smapi_request(0x1402, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + /* bRC == 0 */ + if (usBX & 0x0100) { /* serial port A is present */ + if (usCX & 1) { /* serial port is enabled */ + if ((usSI & 0xFF) == mwave_uart_irq) { +#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_ERROR(KERN_ERR_MWAVE +#else + PRINTK_3(TRACE_SMAPI, +#endif + "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq); +#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_1(TRACE_SMAPI, + "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n"); + bRC = smapi_request(0x1403, 0x0100, 0, usSI, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request(0x1402, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; +#else + goto exit_conflict; +#endif + } else { + if ((usSI >> 8) == uartio_index) { +#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_ERROR(KERN_ERR_MWAVE +#else + PRINTK_3(TRACE_SMAPI, +#endif + "smapi::smapi_set_DSP_cfg: Serial port A base I/O address index %x conflicts with uartio_index %x\n", usSI >> 8, uartio_index); +#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_1(TRACE_SMAPI, + "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n"); + bRC = smapi_request (0x1403, 0x0100, 0, usSI, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request (0x1402, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; +#else + goto exit_conflict; +#endif + } + } + } + } + + /* Check serial port B */ + bRC = smapi_request(0x1404, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + /* bRC == 0 */ + if (usBX & 0x0100) { /* serial port B is present */ + if (usCX & 1) { /* serial port is enabled */ + if ((usSI & 0xFF) == mwave_uart_irq) { +#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_ERROR(KERN_ERR_MWAVE +#else + PRINTK_3(TRACE_SMAPI, +#endif + "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq); +#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_1(TRACE_SMAPI, + "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n"); + bRC = smapi_request(0x1405, 0x0100, 0, usSI, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request(0x1404, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; +#else + goto exit_conflict; +#endif + } else { + if ((usSI >> 8) == uartio_index) { +#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_ERROR(KERN_ERR_MWAVE +#else + PRINTK_3(TRACE_SMAPI, +#endif + "smapi::smapi_set_DSP_cfg: Serial port B base I/O address index %x conflicts with uartio_index %x\n", usSI >> 8, uartio_index); +#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_1 (TRACE_SMAPI, + "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n"); + bRC = smapi_request (0x1405, 0x0100, 0, usSI, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request (0x1404, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; +#else + goto exit_conflict; +#endif + } + } + } + } + + /* Check IR port */ + bRC = smapi_request(0x1700, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request(0x1704, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + /* bRC == 0 */ + if ((usCX & 0xff) == mwave_uart_irq) { /* serial port is enabled */ +#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_ERROR(KERN_ERR_MWAVE +#else + PRINTK_3(TRACE_SMAPI, +#endif + "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq); +#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_1(TRACE_SMAPI, + "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n"); + bRC = smapi_request(0x1701, 0x0100, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request(0x1700, 0, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request(0x1705, 0x01ff, 0, usSI, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request(0x1704, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; +#else + goto exit_conflict; +#endif + } else { + if ((usSI & 0xff) == uartio_index) { +#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_ERROR(KERN_ERR_MWAVE +#else + PRINTK_3(TRACE_SMAPI, +#endif + "smapi::smapi_set_DSP_cfg: IR port base I/O address index %x conflicts with uartio_index %x\n", usSI & 0xff, uartio_index); +#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES + PRINTK_1(TRACE_SMAPI, + "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n"); + bRC = smapi_request(0x1701, 0x0100, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request(0x1700, 0, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request(0x1705, 0x01ff, 0, usSI, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + bRC = smapi_request(0x1704, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; +#else + goto exit_conflict; +#endif + } + } + } + + bRC = smapi_request(0x1802, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + + if (mwave_3780i_io) { + usDI = dspio_index;; + } + if (mwave_3780i_irq) { + usSI = (usSI & 0xff00) | mwave_3780i_irq; + } + + bRC = smapi_request(0x1803, 0x0101, usDI, usSI, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + + bRC = smapi_request(0x1804, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + + if (mwave_uart_io) { + usSI = (usSI & 0x00ff) | (uartio_index << 8); + } + if (mwave_uart_irq) { + usSI = (usSI & 0xff00) | mwave_uart_irq; + } + bRC = smapi_request(0x1805, 0x0101, 0, usSI, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + + bRC = smapi_request(0x1802, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + + bRC = smapi_request(0x1804, 0x0000, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + if (bRC) goto exit_smapi_request_error; + +/* normal exit: */ + PRINTK_1(TRACE_SMAPI, "smapi::smapi_set_DSP_cfg exit\n"); + return 0; + +exit_conflict: + /* Message has already been printed */ + return -EIO; + +exit_smapi_request_error: + PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg exit on smapi_request error bRC %x\n", bRC); + return bRC; +} + + +int smapi_set_DSP_power_state(BOOLEAN bOn) +{ + int bRC = -EIO; + unsigned short usAX, usBX, usCX, usDX, usDI, usSI; + unsigned short usPowerFunction; + + PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state entry bOn %x\n", bOn); + + usPowerFunction = (bOn) ? 1 : 0; + + bRC = smapi_request(0x4901, 0x0000, 0, usPowerFunction, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + + PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state exit bRC %x\n", bRC); + + return bRC; +} + + +int SmapiQuerySystemID(void) +{ + int bRC = -EIO; + unsigned short usAX = 0xffff, usBX = 0xffff, usCX = 0xffff, + usDX = 0xffff, usDI = 0xffff, usSI = 0xffff; + + printk("smapi::SmapiQUerySystemID entry\n"); + bRC = smapi_request(0x0000, 0, 0, 0, + &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); + + if (bRC == 0) { + printk("AX=%x, BX=%x, CX=%x, DX=%x, DI=%x, SI=%x\n", + usAX, usBX, usCX, usDX, usDI, usSI); + } else { + printk("smapi::SmapiQuerySystemID smapi_request error\n"); + } + + return bRC; +} + + +int smapi_init(void) +{ + int retval = -EIO; + unsigned short usSmapiID = 0; + unsigned long flags; + + PRINTK_1(TRACE_SMAPI, "smapi::smapi_init entry\n"); + + spin_lock_irqsave(&rtc_lock, flags); + usSmapiID = CMOS_READ(0x7C); + usSmapiID |= (CMOS_READ(0x7D) << 8); + spin_unlock_irqrestore(&rtc_lock, flags); + PRINTK_2(TRACE_SMAPI, "smapi::smapi_init usSmapiID %x\n", usSmapiID); + + if (usSmapiID == 0x5349) { + spin_lock_irqsave(&rtc_lock, flags); + g_usSmapiPort = CMOS_READ(0x7E); + g_usSmapiPort |= (CMOS_READ(0x7F) << 8); + spin_unlock_irqrestore(&rtc_lock, flags); + if (g_usSmapiPort == 0) { + PRINTK_ERROR("smapi::smapi_init, ERROR unable to read from SMAPI port\n"); + } else { + PRINTK_2(TRACE_SMAPI, + "smapi::smapi_init, exit TRUE g_usSmapiPort %x\n", + g_usSmapiPort); + retval = 0; + //SmapiQuerySystemID(); + } + } else { + PRINTK_ERROR("smapi::smapi_init, ERROR invalid usSmapiID\n"); + retval = -ENXIO; + } + + return retval; +} diff --git a/drivers/char/mwave/smapi.h b/drivers/char/mwave/smapi.h new file mode 100644 index 000000000000..64b2ec1420e3 --- /dev/null +++ b/drivers/char/mwave/smapi.h @@ -0,0 +1,80 @@ +/* +* +* smapi.h -- declarations for SMAPI interface routines +* +* +* Written By: Mike Sullivan IBM Corporation +* +* Copyright (C) 1999 IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* NO WARRANTY +* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR +* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT +* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is +* solely responsible for determining the appropriateness of using and +* distributing the Program and assumes all risks associated with its +* exercise of rights under this Agreement, including but not limited to +* the risks and costs of program errors, damage to or loss of data, +* programs or equipment, and unavailability or interruption of operations. +* +* DISCLAIMER OF LIABILITY +* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +* 10/23/2000 - Alpha Release +* First release to the public +*/ + +#ifndef _LINUX_SMAPI_H +#define _LINUX_SMAPI_H + +#define TRUE 1 +#define FALSE 0 +#define BOOLEAN int + +typedef struct { + int bDSPPresent; + int bDSPEnabled; + int bModemEnabled; + int bMIDIEnabled; + int bSblstEnabled; + unsigned short usDspIRQ; + unsigned short usDspDMA; + unsigned short usDspBaseIO; + unsigned short usUartIRQ; + unsigned short usUartBaseIO; + unsigned short usMidiIRQ; + unsigned short usMidiBaseIO; + unsigned short usSndblstIRQ; + unsigned short usSndblstDMA; + unsigned short usSndblstBaseIO; +} SMAPI_DSP_SETTINGS; + +int smapi_init(void); +int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings); +int smapi_set_DSP_cfg(void); +int smapi_set_DSP_power_state(BOOLEAN bOn); + + +#endif diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c new file mode 100644 index 000000000000..c34783aeb5be --- /dev/null +++ b/drivers/char/mwave/tp3780i.c @@ -0,0 +1,589 @@ +/* +* +* tp3780i.c -- board driver for 3780i on ThinkPads +* +* +* Written By: Mike Sullivan IBM Corporation +* +* Copyright (C) 1999 IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* NO WARRANTY +* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR +* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT +* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is +* solely responsible for determining the appropriateness of using and +* distributing the Program and assumes all risks associated with its +* exercise of rights under this Agreement, including but not limited to +* the risks and costs of program errors, damage to or loss of data, +* programs or equipment, and unavailability or interruption of operations. +* +* DISCLAIMER OF LIABILITY +* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +* 10/23/2000 - Alpha Release +* First release to the public +*/ + +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/ptrace.h> +#include <linux/ioport.h> +#include <asm/io.h> +#include "smapi.h" +#include "mwavedd.h" +#include "tp3780i.h" +#include "3780i.h" +#include "mwavepub.h" + +extern MWAVE_DEVICE_DATA mwave_s_mdd; + +static unsigned short s_ausThinkpadIrqToField[16] = + { 0xFFFF, 0xFFFF, 0xFFFF, 0x0001, 0x0002, 0x0003, 0xFFFF, 0x0004, + 0xFFFF, 0xFFFF, 0x0005, 0x0006, 0xFFFF, 0xFFFF, 0xFFFF, 0x0007 }; +static unsigned short s_ausThinkpadDmaToField[8] = + { 0x0001, 0x0002, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0003, 0x0004 }; +static unsigned short s_numIrqs = 16, s_numDmas = 8; + + +static void EnableSRAM(THINKPAD_BD_DATA * pBDData) +{ + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + unsigned short usDspBaseIO = pSettings->usDspBaseIO; + DSP_GPIO_OUTPUT_DATA_15_8 rGpioOutputData; + DSP_GPIO_DRIVER_ENABLE_15_8 rGpioDriverEnable; + DSP_GPIO_MODE_15_8 rGpioMode; + + PRINTK_1(TRACE_TP3780I, "tp3780i::EnableSRAM, entry\n"); + + MKWORD(rGpioMode) = ReadMsaCfg(DSP_GpioModeControl_15_8); + rGpioMode.GpioMode10 = 0; + WriteMsaCfg(DSP_GpioModeControl_15_8, MKWORD(rGpioMode)); + + MKWORD(rGpioDriverEnable) = 0; + rGpioDriverEnable.Enable10 = TRUE; + rGpioDriverEnable.Mask10 = TRUE; + WriteMsaCfg(DSP_GpioDriverEnable_15_8, MKWORD(rGpioDriverEnable)); + + MKWORD(rGpioOutputData) = 0; + rGpioOutputData.Latch10 = 0; + rGpioOutputData.Mask10 = TRUE; + WriteMsaCfg(DSP_GpioOutputData_15_8, MKWORD(rGpioOutputData)); + + PRINTK_1(TRACE_TP3780I, "tp3780i::EnableSRAM exit\n"); +} + + +static void UartInterrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + PRINTK_3(TRACE_TP3780I, + "tp3780i::UartInterrupt entry irq %x dev_id %x\n", irq, (int) dev_id); +} + +static void DspInterrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pDrvData->rBDData.rDspSettings; + unsigned short usDspBaseIO = pSettings->usDspBaseIO; + unsigned short usIPCSource = 0, usIsolationMask, usPCNum; + + PRINTK_3(TRACE_TP3780I, + "tp3780i::DspInterrupt entry irq %x dev_id %x\n", irq, (int) dev_id); + + if (dsp3780I_GetIPCSource(usDspBaseIO, &usIPCSource) == 0) { + PRINTK_2(TRACE_TP3780I, + "tp3780i::DspInterrupt, return from dsp3780i_GetIPCSource, usIPCSource %x\n", + usIPCSource); + usIsolationMask = 1; + for (usPCNum = 1; usPCNum <= 16; usPCNum++) { + if (usIPCSource & usIsolationMask) { + usIPCSource &= ~usIsolationMask; + PRINTK_3(TRACE_TP3780I, + "tp3780i::DspInterrupt usPCNum %x usIPCSource %x\n", + usPCNum, usIPCSource); + if (pDrvData->IPCs[usPCNum - 1].usIntCount == 0) { + pDrvData->IPCs[usPCNum - 1].usIntCount = 1; + } + PRINTK_2(TRACE_TP3780I, + "tp3780i::DspInterrupt usIntCount %x\n", + pDrvData->IPCs[usPCNum - 1].usIntCount); + if (pDrvData->IPCs[usPCNum - 1].bIsEnabled == TRUE) { + PRINTK_2(TRACE_TP3780I, + "tp3780i::DspInterrupt, waking up usPCNum %x\n", + usPCNum - 1); + wake_up_interruptible(&pDrvData->IPCs[usPCNum - 1].ipc_wait_queue); + } else { + PRINTK_2(TRACE_TP3780I, + "tp3780i::DspInterrupt, no one waiting for IPC %x\n", + usPCNum - 1); + } + } + if (usIPCSource == 0) + break; + /* try next IPC */ + usIsolationMask = usIsolationMask << 1; + } + } else { + PRINTK_1(TRACE_TP3780I, + "tp3780i::DspInterrupt, return false from dsp3780i_GetIPCSource\n"); + } + PRINTK_1(TRACE_TP3780I, "tp3780i::DspInterrupt exit\n"); +} + + +int tp3780I_InitializeBoardData(THINKPAD_BD_DATA * pBDData) +{ + int retval = 0; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_InitializeBoardData entry pBDData %p\n", pBDData); + + pBDData->bDSPEnabled = FALSE; + pSettings->bInterruptClaimed = FALSE; + + retval = smapi_init(); + if (retval) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_InitializeBoardData: Error: SMAPI is not available on this machine\n"); + } else { + if (mwave_3780i_irq || mwave_3780i_io || mwave_uart_irq || mwave_uart_io) { + retval = smapi_set_DSP_cfg(); + } + } + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_InitializeBoardData exit retval %x\n", retval); + + return retval; +} + +int tp3780I_Cleanup(THINKPAD_BD_DATA * pBDData) +{ + int retval = 0; + + PRINTK_2(TRACE_TP3780I, + "tp3780i::tp3780I_Cleanup entry and exit pBDData %p\n", pBDData); + + return retval; +} + +int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData) +{ + SMAPI_DSP_SETTINGS rSmapiInfo; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + + PRINTK_2(TRACE_TP3780I, + "tp3780i::tp3780I_CalcResources entry pBDData %p\n", pBDData); + + if (smapi_query_DSP_cfg(&rSmapiInfo)) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_CalcResources: Error: Could not query DSP config. Aborting.\n"); + return -EIO; + } + + /* Sanity check */ + if ( + ( rSmapiInfo.usDspIRQ == 0 ) + || ( rSmapiInfo.usDspBaseIO == 0 ) + || ( rSmapiInfo.usUartIRQ == 0 ) + || ( rSmapiInfo.usUartBaseIO == 0 ) + ) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_CalcResources: Error: Illegal resource setting. Aborting.\n"); + return -EIO; + } + + pSettings->bDSPEnabled = (rSmapiInfo.bDSPEnabled && rSmapiInfo.bDSPPresent); + pSettings->bModemEnabled = rSmapiInfo.bModemEnabled; + pSettings->usDspIrq = rSmapiInfo.usDspIRQ; + pSettings->usDspDma = rSmapiInfo.usDspDMA; + pSettings->usDspBaseIO = rSmapiInfo.usDspBaseIO; + pSettings->usUartIrq = rSmapiInfo.usUartIRQ; + pSettings->usUartBaseIO = rSmapiInfo.usUartBaseIO; + + pSettings->uDStoreSize = TP_ABILITIES_DATA_SIZE; + pSettings->uIStoreSize = TP_ABILITIES_INST_SIZE; + pSettings->uIps = TP_ABILITIES_INTS_PER_SEC; + + if (pSettings->bDSPEnabled && pSettings->bModemEnabled && pSettings->usDspIrq == pSettings->usUartIrq) { + pBDData->bShareDspIrq = pBDData->bShareUartIrq = 1; + } else { + pBDData->bShareDspIrq = pBDData->bShareUartIrq = 0; + } + + PRINTK_1(TRACE_TP3780I, "tp3780i::tp3780I_CalcResources exit\n"); + + return 0; +} + + +int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData) +{ + int retval = 0; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + struct resource *pres; +#endif + + PRINTK_2(TRACE_TP3780I, + "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i"); + if ( pres == NULL ) retval = -EIO; +#else + retval = check_region(pSettings->usDspBaseIO, 16); + if (!retval) request_region(pSettings->usDspBaseIO, 16, "mwave_3780i"); +#endif + if (retval) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO); + retval = -EIO; + } + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ClaimResources exit retval %x\n", retval); + + return retval; +} + +int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData) +{ + int retval = 0; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + + PRINTK_2(TRACE_TP3780I, + "tp3780i::tp3780I_ReleaseResources entry pBDData %p\n", pBDData); + + release_region(pSettings->usDspBaseIO & (~3), 16); + + if (pSettings->bInterruptClaimed) { + free_irq(pSettings->usDspIrq, 0); + pSettings->bInterruptClaimed = FALSE; + } + + PRINTK_2(TRACE_TP3780I, + "tp3780i::tp3780I_ReleaseResources exit retval %x\n", retval); + + return retval; +} + + + +int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) +{ + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + BOOLEAN bDSPPoweredUp = FALSE, bDSPEnabled = FALSE, bInterruptAllocated = FALSE; + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData); + + if (pBDData->bDSPEnabled) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: DSP already enabled!\n"); + goto exit_cleanup; + } + + if (!pSettings->bDSPEnabled) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780::tp3780I_EnableDSP: Error: pSettings->bDSPEnabled not set\n"); + goto exit_cleanup; + } + + if ( + (pSettings->usDspIrq >= s_numIrqs) + || (pSettings->usDspDma >= s_numDmas) + || (s_ausThinkpadIrqToField[pSettings->usDspIrq] == 0xFFFF) + || (s_ausThinkpadDmaToField[pSettings->usDspDma] == 0xFFFF) + ) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: invalid irq %x\n", pSettings->usDspIrq); + goto exit_cleanup; + } + + if ( + ((pSettings->usDspBaseIO & 0xF00F) != 0) + || (pSettings->usDspBaseIO & 0x0FF0) == 0 + ) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid DSP base I/O address %x\n", pSettings->usDspBaseIO); + goto exit_cleanup; + } + + if (pSettings->bModemEnabled) { + if ( + pSettings->usUartIrq >= s_numIrqs + || s_ausThinkpadIrqToField[pSettings->usUartIrq] == 0xFFFF + ) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid UART IRQ %x\n", pSettings->usUartIrq); + goto exit_cleanup; + } + switch (pSettings->usUartBaseIO) { + case 0x03F8: + case 0x02F8: + case 0x03E8: + case 0x02E8: + break; + + default: + PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Invalid UART base I/O address %x\n", pSettings->usUartBaseIO); + goto exit_cleanup; + } + } + + pSettings->bDspIrqActiveLow = pSettings->bDspIrqPulse = TRUE; + pSettings->bUartIrqActiveLow = pSettings->bUartIrqPulse = TRUE; + + if (pBDData->bShareDspIrq) { + pSettings->bDspIrqActiveLow = FALSE; + } + if (pBDData->bShareUartIrq) { + pSettings->bUartIrqActiveLow = FALSE; + } + + pSettings->usNumTransfers = TP_CFG_NumTransfers; + pSettings->usReRequest = TP_CFG_RerequestTimer; + pSettings->bEnableMEMCS16 = TP_CFG_MEMCS16; + pSettings->usIsaMemCmdWidth = TP_CFG_IsaMemCmdWidth; + pSettings->bGateIOCHRDY = TP_CFG_GateIOCHRDY; + pSettings->bEnablePwrMgmt = TP_CFG_EnablePwrMgmt; + pSettings->usHBusTimerLoadValue = TP_CFG_HBusTimerValue; + pSettings->bDisableLBusTimeout = TP_CFG_DisableLBusTimeout; + pSettings->usN_Divisor = TP_CFG_N_Divisor; + pSettings->usM_Multiplier = TP_CFG_M_Multiplier; + pSettings->bPllBypass = TP_CFG_PllBypass; + pSettings->usChipletEnable = TP_CFG_ChipletEnable; + + if (request_irq(pSettings->usUartIrq, &UartInterrupt, 0, "mwave_uart", 0)) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Could not get UART IRQ %x\n", pSettings->usUartIrq); + goto exit_cleanup; + } else { /* no conflict just release */ + free_irq(pSettings->usUartIrq, 0); + } + + if (request_irq(pSettings->usDspIrq, &DspInterrupt, 0, "mwave_3780i", 0)) { + PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Could not get 3780i IRQ %x\n", pSettings->usDspIrq); + goto exit_cleanup; + } else { + PRINTK_3(TRACE_TP3780I, + "tp3780i::tp3780I_EnableDSP, got interrupt %x bShareDspIrq %x\n", + pSettings->usDspIrq, pBDData->bShareDspIrq); + bInterruptAllocated = TRUE; + pSettings->bInterruptClaimed = TRUE; + } + + smapi_set_DSP_power_state(FALSE); + if (smapi_set_DSP_power_state(TRUE)) { + PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: smapi_set_DSP_power_state(TRUE) failed\n"); + goto exit_cleanup; + } else { + bDSPPoweredUp = TRUE; + } + + if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) { + PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n"); + goto exit_cleanup; + } else { + bDSPEnabled = TRUE; + } + + EnableSRAM(pBDData); + + pBDData->bDSPEnabled = TRUE; + + PRINTK_1(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP exit\n"); + + return 0; + +exit_cleanup: + PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n"); + if (bDSPEnabled) + dsp3780I_DisableDSP(pSettings); + if (bDSPPoweredUp) + smapi_set_DSP_power_state(FALSE); + if (bInterruptAllocated) { + free_irq(pSettings->usDspIrq, 0); + pSettings->bInterruptClaimed = FALSE; + } + return -EIO; +} + + +int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData) +{ + int retval = 0; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP entry pBDData %p\n", pBDData); + + if (pBDData->bDSPEnabled) { + dsp3780I_DisableDSP(&pBDData->rDspSettings); + if (pSettings->bInterruptClaimed) { + free_irq(pSettings->usDspIrq, 0); + pSettings->bInterruptClaimed = FALSE; + } + smapi_set_DSP_power_state(FALSE); + pBDData->bDSPEnabled = FALSE; + } + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP exit retval %x\n", retval); + + return retval; +} + + +int tp3780I_ResetDSP(THINKPAD_BD_DATA * pBDData) +{ + int retval = 0; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ResetDSP entry pBDData %p\n", + pBDData); + + if (dsp3780I_Reset(pSettings) == 0) { + EnableSRAM(pBDData); + } else { + retval = -EIO; + } + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ResetDSP exit retval %x\n", retval); + + return retval; +} + + +int tp3780I_StartDSP(THINKPAD_BD_DATA * pBDData) +{ + int retval = 0; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_StartDSP entry pBDData %p\n", pBDData); + + if (dsp3780I_Run(pSettings) == 0) { + // @BUG @TBD EnableSRAM(pBDData); + } else { + retval = -EIO; + } + + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_StartDSP exit retval %x\n", retval); + + return retval; +} + + +int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities) +{ + int retval = 0; + + PRINTK_2(TRACE_TP3780I, + "tp3780i::tp3780I_QueryAbilities entry pBDData %p\n", pBDData); + + /* fill out standard constant fields */ + pAbilities->instr_per_sec = pBDData->rDspSettings.uIps; + pAbilities->data_size = pBDData->rDspSettings.uDStoreSize; + pAbilities->inst_size = pBDData->rDspSettings.uIStoreSize; + pAbilities->bus_dma_bw = pBDData->rDspSettings.uDmaBandwidth; + + /* fill out dynamically determined fields */ + pAbilities->component_list[0] = 0x00010000 | MW_ADC_MASK; + pAbilities->component_list[1] = 0x00010000 | MW_ACI_MASK; + pAbilities->component_list[2] = 0x00010000 | MW_AIC1_MASK; + pAbilities->component_list[3] = 0x00010000 | MW_AIC2_MASK; + pAbilities->component_list[4] = 0x00010000 | MW_CDDAC_MASK; + pAbilities->component_list[5] = 0x00010000 | MW_MIDI_MASK; + pAbilities->component_list[6] = 0x00010000 | MW_UART_MASK; + pAbilities->component_count = 7; + + /* Fill out Mwave OS and BIOS task names */ + + memcpy(pAbilities->mwave_os_name, TP_ABILITIES_MWAVEOS_NAME, + sizeof(TP_ABILITIES_MWAVEOS_NAME)); + memcpy(pAbilities->bios_task_name, TP_ABILITIES_BIOSTASK_NAME, + sizeof(TP_ABILITIES_BIOSTASK_NAME)); + + PRINTK_1(TRACE_TP3780I, + "tp3780i::tp3780I_QueryAbilities exit retval=SUCCESSFUL\n"); + + return retval; +} + +int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, + void *pvBuffer, unsigned int uCount, + unsigned long ulDSPAddr) +{ + int retval = 0; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + unsigned short usDspBaseIO = pSettings->usDspBaseIO; + BOOLEAN bRC = 0; + + PRINTK_6(TRACE_TP3780I, + "tp3780i::tp3780I_ReadWriteDspDStore entry pBDData %p, uOpcode %x, pvBuffer %p, uCount %x, ulDSPAddr %lx\n", + pBDData, uOpcode, pvBuffer, uCount, ulDSPAddr); + + if (pBDData->bDSPEnabled) { + switch (uOpcode) { + case IOCTL_MW_READ_DATA: + bRC = dsp3780I_ReadDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); + break; + + case IOCTL_MW_READCLEAR_DATA: + bRC = dsp3780I_ReadAndClearDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); + break; + + case IOCTL_MW_WRITE_DATA: + bRC = dsp3780I_WriteDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); + break; + } + } + + retval = (bRC) ? -EIO : 0; + PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ReadWriteDspDStore exit retval %x\n", retval); + + return retval; +} + + +int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, + void *pvBuffer, unsigned int uCount, + unsigned long ulDSPAddr) +{ + int retval = 0; + DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + unsigned short usDspBaseIO = pSettings->usDspBaseIO; + BOOLEAN bRC = 0; + + PRINTK_6(TRACE_TP3780I, + "tp3780i::tp3780I_ReadWriteDspIStore entry pBDData %p, uOpcode %x, pvBuffer %p, uCount %x, ulDSPAddr %lx\n", + pBDData, uOpcode, pvBuffer, uCount, ulDSPAddr); + + if (pBDData->bDSPEnabled) { + switch (uOpcode) { + case IOCTL_MW_READ_INST: + bRC = dsp3780I_ReadIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); + break; + + case IOCTL_MW_WRITE_INST: + bRC = dsp3780I_WriteIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); + break; + } + } + + retval = (bRC) ? -EIO : 0; + + PRINTK_2(TRACE_TP3780I, + "tp3780i::tp3780I_ReadWriteDspIStore exit retval %x\n", retval); + + return retval; +} + diff --git a/drivers/char/mwave/tp3780i.h b/drivers/char/mwave/tp3780i.h new file mode 100644 index 000000000000..70fde5ceffca --- /dev/null +++ b/drivers/char/mwave/tp3780i.h @@ -0,0 +1,103 @@ +/* +* +* tp3780i.h -- declarations for tp3780i.c +* +* +* Written By: Mike Sullivan IBM Corporation +* +* Copyright (C) 1999 IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* NO WARRANTY +* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR +* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT +* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is +* solely responsible for determining the appropriateness of using and +* distributing the Program and assumes all risks associated with its +* exercise of rights under this Agreement, including but not limited to +* the risks and costs of program errors, damage to or loss of data, +* programs or equipment, and unavailability or interruption of operations. +* +* DISCLAIMER OF LIABILITY +* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +* 10/23/2000 - Alpha Release +* First release to the public +*/ + +#ifndef _LINUX_TP3780I_H +#define _LINUX_TP3780I_H + +#include <asm/io.h> +#include "mwavepub.h" + + +/* DSP abilities constants for 3780i based Thinkpads */ +#define TP_ABILITIES_INTS_PER_SEC 39160800 +#define TP_ABILITIES_DATA_SIZE 32768 +#define TP_ABILITIES_INST_SIZE 32768 +#define TP_ABILITIES_MWAVEOS_NAME "mwaveos0700.dsp" +#define TP_ABILITIES_BIOSTASK_NAME "mwbio701.dsp" + + +/* DSP configuration values for 3780i based Thinkpads */ +#define TP_CFG_NumTransfers 3 /* 16 transfers */ +#define TP_CFG_RerequestTimer 1 /* 2 usec */ +#define TP_CFG_MEMCS16 0 /* Disabled, 16-bit memory assumed */ +#define TP_CFG_IsaMemCmdWidth 3 /* 295 nsec (16-bit) */ +#define TP_CFG_GateIOCHRDY 0 /* No IOCHRDY gating */ +#define TP_CFG_EnablePwrMgmt 1 /* Enable low poser suspend/resume */ +#define TP_CFG_HBusTimerValue 255 /* HBus timer load value */ +#define TP_CFG_DisableLBusTimeout 0 /* Enable LBus timeout */ +#define TP_CFG_N_Divisor 32 /* Clock = 39.1608 Mhz */ +#define TP_CFG_M_Multiplier 37 /* " */ +#define TP_CFG_PllBypass 0 /* dont bypass */ +#define TP_CFG_ChipletEnable 0xFFFF /* Enable all chiplets */ + +typedef struct { + int bDSPEnabled; + int bShareDspIrq; + int bShareUartIrq; + DSP_3780I_CONFIG_SETTINGS rDspSettings; +} THINKPAD_BD_DATA; + +int tp3780I_InitializeBoardData(THINKPAD_BD_DATA * pBDData); +int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData); +int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData); +int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData); +int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData); +int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData); +int tp3780I_ResetDSP(THINKPAD_BD_DATA * pBDData); +int tp3780I_StartDSP(THINKPAD_BD_DATA * pBDData); +int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities); +int tp3780I_Cleanup(THINKPAD_BD_DATA * pBDData); +int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, + void *pvBuffer, unsigned int uCount, + unsigned long ulDSPAddr); +int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, + void *pvBuffer, unsigned int uCount, + unsigned long ulDSPAddr); + + +#endif diff --git a/drivers/char/softdog.c b/drivers/char/softdog.c index 132d311068e0..8342877b3a8b 100644 --- a/drivers/char/softdog.c +++ b/drivers/char/softdog.c @@ -46,6 +46,7 @@ static int soft_margin = TIMER_MARGIN; /* in seconds */ MODULE_PARM(soft_margin,"i"); +MODULE_LICENSE("GPL"); /* * Our timer diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index ec9efd78ab2c..ebca79af8ce3 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -47,13 +47,13 @@ static void sysrq_handle_loglevel(int key, struct pt_regs *pt_regs, int i; i = key - '0'; console_loglevel = 7; - printk("%d\n", i); + printk("Loglevel set to %d\n", i); console_loglevel = i; } static struct sysrq_key_op sysrq_loglevel_op = { handler: sysrq_handle_loglevel, help_msg: "loglevel0-8", - action_msg: "Loglevel set to ", + action_msg: "Changing Loglevel", }; @@ -68,7 +68,7 @@ static void sysrq_handle_SAK(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_SAK_op = { handler: sysrq_handle_SAK, help_msg: "saK", - action_msg: "SAK\n", + action_msg: "SAK", }; #endif @@ -82,7 +82,7 @@ static void sysrq_handle_unraw(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_unraw_op = { handler: sysrq_handle_unraw, help_msg: "unRaw", - action_msg: "Keyboard mode set to XLATE\n", + action_msg: "Keyboard mode set to XLATE", }; @@ -94,7 +94,7 @@ static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_reboot_op = { handler: sysrq_handle_reboot, help_msg: "reBoot", - action_msg: "Resetting\n", + action_msg: "Resetting", }; @@ -225,18 +225,18 @@ static void sysrq_handle_sync(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_sync_op = { handler: sysrq_handle_sync, help_msg: "Sync", - action_msg: "Emergency Sync\n", + action_msg: "Emergency Sync", }; static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs, struct kbd_struct *kbd, struct tty_struct *tty) { emergency_sync_scheduled = EMERG_REMOUNT; - wakeup_bdflush(); + wakeup_bdflush(0); } static struct sysrq_key_op sysrq_mountro_op = { handler: sysrq_handle_mountro, help_msg: "Unmount", - action_msg: "Emergency Remount R/0\n", + action_msg: "Emergency Remount R/0", }; /* END SYNC SYSRQ HANDLERS BLOCK */ @@ -252,7 +252,7 @@ static void sysrq_handle_showregs(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_showregs_op = { handler: sysrq_handle_showregs, help_msg: "showPc", - action_msg: "Show Regs\n", + action_msg: "Show Regs", }; @@ -263,7 +263,7 @@ static void sysrq_handle_showstate(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_showstate_op = { handler: sysrq_handle_showstate, help_msg: "showTasks", - action_msg: "Show State\n", + action_msg: "Show State", }; @@ -274,7 +274,7 @@ static void sysrq_handle_showmem(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_showmem_op = { handler: sysrq_handle_showmem, help_msg: "showMem", - action_msg: "Show Memory\n", + action_msg: "Show Memory", }; /* SHOW SYSRQ HANDLERS BLOCK */ @@ -307,7 +307,7 @@ static void sysrq_handle_term(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_term_op = { handler: sysrq_handle_term, help_msg: "tErm", - action_msg: "Terminate All Tasks\n", + action_msg: "Terminate All Tasks", }; static void sysrq_handle_kill(int key, struct pt_regs *pt_regs, @@ -318,7 +318,7 @@ static void sysrq_handle_kill(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_kill_op = { handler: sysrq_handle_kill, help_msg: "kIll", - action_msg: "Kill All Tasks\n", + action_msg: "Kill All Tasks", }; static void sysrq_handle_killall(int key, struct pt_regs *pt_regs, @@ -329,7 +329,7 @@ static void sysrq_handle_killall(int key, struct pt_regs *pt_regs, static struct sysrq_key_op sysrq_killall_op = { handler: sysrq_handle_killall, help_msg: "killalL", - action_msg: "Kill All Tasks (even init)\n", + action_msg: "Kill All Tasks (even init)", }; /* END SIGNAL SYSRQ HANDLERS BLOCK */ @@ -462,8 +462,9 @@ void __handle_sysrq_nolock(int key, struct pt_regs *pt_regs, op_p = __sysrq_get_key_op(key); if (op_p) { - printk ("%s", op_p->action_msg); - op_p->handler(key, pt_regs, kbd, tty); + printk ("%s\n", op_p->action_msg); + console_loglevel = orig_log_level; + op_p->handler(key, pt_regs, kbd, tty); } else { printk("HELP : "); /* Only print the help msg once per handler */ @@ -474,8 +475,8 @@ void __handle_sysrq_nolock(int key, struct pt_regs *pt_regs, printk ("%s ", sysrq_key_table[i]->help_msg); } printk ("\n"); + console_loglevel = orig_log_level; } - console_loglevel = orig_log_level; } EXPORT_SYMBOL(handle_sysrq); diff --git a/drivers/i2c/i2c-adap-ite.c b/drivers/i2c/i2c-adap-ite.c index c6a35dafcf32..ee1fc803785a 100644 --- a/drivers/i2c/i2c-adap-ite.c +++ b/drivers/i2c/i2c-adap-ite.c @@ -299,6 +299,7 @@ EXPORT_NO_SYMBOLS; */ MODULE_AUTHOR("MontaVista Software <www.mvista.com>"); MODULE_DESCRIPTION("I2C-Bus adapter routines for ITE IIC bus adapter"); +MODULE_LICENSE("GPL"); MODULE_PARM(base, "i"); MODULE_PARM(irq, "i"); diff --git a/drivers/i2c/i2c-algo-bit.c b/drivers/i2c/i2c-algo-bit.c index 1ec91dbd6266..a26a6e16f7cb 100644 --- a/drivers/i2c/i2c-algo-bit.c +++ b/drivers/i2c/i2c-algo-bit.c @@ -621,6 +621,7 @@ EXPORT_SYMBOL(i2c_bit_del_bus); #ifdef MODULE MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); +MODULE_LICENSE("GPL"); MODULE_PARM(bit_test, "i"); MODULE_PARM(bit_scan, "i"); diff --git a/drivers/i2c/i2c-algo-ite.c b/drivers/i2c/i2c-algo-ite.c index 194d1f78a732..8c417ddc2ae9 100644 --- a/drivers/i2c/i2c-algo-ite.c +++ b/drivers/i2c/i2c-algo-ite.c @@ -844,6 +844,7 @@ EXPORT_SYMBOL(i2c_iic_del_bus); */ MODULE_AUTHOR("MontaVista Software <www.mvista.com>"); MODULE_DESCRIPTION("ITE iic algorithm"); +MODULE_LICENSE("GPL"); MODULE_PARM(iic_test, "i"); MODULE_PARM(iic_scan, "i"); diff --git a/drivers/i2c/i2c-algo-pcf.c b/drivers/i2c/i2c-algo-pcf.c index 5618b7557f17..dd0ad032bdc8 100644 --- a/drivers/i2c/i2c-algo-pcf.c +++ b/drivers/i2c/i2c-algo-pcf.c @@ -596,6 +596,7 @@ EXPORT_SYMBOL(i2c_pcf_del_bus); #ifdef MODULE MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>"); MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm"); +MODULE_LICENSE("GPL"); MODULE_PARM(pcf_test, "i"); MODULE_PARM(pcf_scan, "i"); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b9db448d274b..1e0f15552d70 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1369,6 +1369,7 @@ MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_DESCRIPTION("I2C-Bus main module"); MODULE_PARM(i2c_debug, "i"); MODULE_PARM_DESC(i2c_debug,"debug level"); +MODULE_LICENSE("GPL"); int init_module(void) { diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index a0eb4ca1b13f..b5659bc7defd 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -530,6 +530,7 @@ EXPORT_NO_SYMBOLS; MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_DESCRIPTION("I2C /dev entries driver"); +MODULE_LICENSE("GPL"); int init_module(void) { diff --git a/drivers/i2c/i2c-elektor.c b/drivers/i2c/i2c-elektor.c index 590f42ff2c62..31cfa966dfe4 100644 --- a/drivers/i2c/i2c-elektor.c +++ b/drivers/i2c/i2c-elektor.c @@ -277,6 +277,7 @@ EXPORT_NO_SYMBOLS; #ifdef MODULE MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>"); MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter"); +MODULE_LICENSE("GPL"); MODULE_PARM(base, "i"); MODULE_PARM(irq, "i"); diff --git a/drivers/i2c/i2c-elv.c b/drivers/i2c/i2c-elv.c index 0fcd9a65b35f..4968f694f7ec 100644 --- a/drivers/i2c/i2c-elv.c +++ b/drivers/i2c/i2c-elv.c @@ -199,8 +199,9 @@ EXPORT_NO_SYMBOLS; #ifdef MODULE MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); -MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter") -; +MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter"); +MODULE_LICENSE("GPL"); + MODULE_PARM(base, "i"); diff --git a/drivers/i2c/i2c-philips-par.c b/drivers/i2c/i2c-philips-par.c index ce9d7df2785f..fcba15245998 100644 --- a/drivers/i2c/i2c-philips-par.c +++ b/drivers/i2c/i2c-philips-par.c @@ -291,6 +291,7 @@ EXPORT_NO_SYMBOLS; MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_DESCRIPTION("I2C-Bus adapter routines for Philips parallel port adapter"); +MODULE_LICENSE("GPL"); MODULE_PARM(type, "i"); diff --git a/drivers/i2c/i2c-velleman.c b/drivers/i2c/i2c-velleman.c index 95c12a289826..3f553591d900 100644 --- a/drivers/i2c/i2c-velleman.c +++ b/drivers/i2c/i2c-velleman.c @@ -189,6 +189,7 @@ EXPORT_NO_SYMBOLS; #ifdef MODULE MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter"); +MODULE_LICENSE("GPL"); MODULE_PARM(base, "i"); diff --git a/drivers/ide/ataraid.c b/drivers/ide/ataraid.c index 49521c09bee0..18f7cb1de98d 100644 --- a/drivers/ide/ataraid.c +++ b/drivers/ide/ataraid.c @@ -63,12 +63,6 @@ static DECLARE_MUTEX(ataraid_sem); /* Bitmap for the devices currently in use */ static unsigned int ataraiduse; -/* structure for the splitting of bufferheads */ - -struct ataraid_bh_private { - struct buffer_head *parent; - atomic_t count; -}; /* stub fops functions */ @@ -121,7 +115,7 @@ static int ataraid_make_request (request_queue_t *q, int rw, struct buffer_head return -EINVAL; } -static struct buffer_head *get_bhead(void) +struct buffer_head *ataraid_get_bhead(void) { void *ptr = NULL; while (!ptr) { @@ -135,7 +129,9 @@ static struct buffer_head *get_bhead(void) return ptr; } -static struct ataraid_bh_private *get_private(void) +EXPORT_SYMBOL(ataraid_get_bhead); + +struct ataraid_bh_private *ataraid_get_private(void) { void *ptr = NULL; while (!ptr) { @@ -149,7 +145,9 @@ static struct ataraid_bh_private *get_private(void) return ptr; } -static void ataraid_end_request(struct buffer_head *bh, int uptodate) +EXPORT_SYMBOL(ataraid_get_private); + +void ataraid_end_request(struct buffer_head *bh, int uptodate) { struct ataraid_bh_private *private = bh->b_private; @@ -164,17 +162,19 @@ static void ataraid_end_request(struct buffer_head *bh, int uptodate) kfree(bh); } +EXPORT_SYMBOL(ataraid_end_request); + static void ataraid_split_request(request_queue_t *q, int rw, struct buffer_head * bh) { struct buffer_head *bh1,*bh2; struct ataraid_bh_private *private; - bh1=get_bhead(); - bh2=get_bhead(); + bh1=ataraid_get_bhead(); + bh2=ataraid_get_bhead(); /* If either of those ever fails we're doomed */ if ((!bh1)||(!bh2)) BUG(); - private = get_private(); + private = ataraid_get_private(); if (private==NULL) BUG(); @@ -249,7 +249,7 @@ static __init int ataraid_init(void) { ataraid_hardsect_size[i] = 512; ataraid_blksize_size[i] = 1024; - ataraid_readahead[i] = 32; + ataraid_readahead[i] = 1023; } if (blksize_size[ATAMAJOR]==NULL) @@ -317,4 +317,5 @@ EXPORT_SYMBOL(ataraid_get_device); EXPORT_SYMBOL(ataraid_release_device); EXPORT_SYMBOL(ataraid_gendisk); EXPORT_SYMBOL(ataraid_register_disk); +MODULE_LICENSE("GPL"); diff --git a/drivers/ide/ataraid.h b/drivers/ide/ataraid.h index 3e909c0945ec..282089ea54af 100644 --- a/drivers/ide/ataraid.h +++ b/drivers/ide/ataraid.h @@ -49,6 +49,12 @@ struct geom { unsigned char sectors; }; +/* structure for the splitting of bufferheads */ + +struct ataraid_bh_private { + struct buffer_head *parent; + atomic_t count; +}; extern struct gendisk ataraid_gendisk; @@ -56,4 +62,11 @@ extern int ataraid_get_device(struct raid_device_operations *fops); extern void ataraid_release_device(int device); extern int get_blocksize(kdev_t dev); extern void ataraid_register_disk(int device,long size); +extern struct buffer_head *ataraid_get_bhead(void); +extern struct ataraid_bh_private *ataraid_get_private(void); +extern void ataraid_end_request(struct buffer_head *bh, int uptodate); + + + + diff --git a/drivers/ide/hptraid.c b/drivers/ide/hptraid.c index 9f23df75a314..5738ff1cbf9b 100644 --- a/drivers/ide/hptraid.c +++ b/drivers/ide/hptraid.c @@ -306,8 +306,8 @@ static void __init probedisk(int major, int minor,int device) if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) { int j=0; struct gendisk *gd; - raid[device].disk[i].bdev = bdev; + /* This is supposed to prevent others from stealing our underlying disks */ /* now blank the /proc/partitions table for the wrong partition table, so that scripts don't accidentally mount it and crash the kernel */ /* XXX: the 0 is an utter hack --hch */ @@ -408,12 +408,12 @@ static void __exit hptraid_exit (void) { int i,device; for (device = 0; device<16; device++) { - for (i=0;i<8;i++) { + for (i=0;i<8;i++) { struct block_device *bdev = raid[device].disk[i].bdev; raid[device].disk[i].bdev = NULL; if (bdev) blkdev_put(bdev, BDEV_RAW); - } + } if (raid[device].sectors) ataraid_release_device(device); } @@ -432,3 +432,4 @@ static int hptraid_release(struct inode * inode, struct file * filp) module_init(hptraid_init); module_exit(hptraid_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index 4a199ca71912..8af34e95583a 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -74,6 +74,9 @@ static int irq_list[4] = { -1 }; MODULE_PARM(irq_mask, "i"); MODULE_PARM(irq_list, "1-4i"); +MODULE_LICENSE("GPL"); + + /*====================================================================*/ static const char ide_major[] = { diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c index 8f473d078bd7..bd86b98b7625 100644 --- a/drivers/ide/ide-pci.c +++ b/drivers/ide/ide-pci.c @@ -693,6 +693,8 @@ check_if_enabled: */ if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265)) && (secondpdc++==1) && (port==1) ) goto controller_ok; + if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262)) && (secondpdc++==1) && (port==1) ) + goto controller_ok; if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val)) continue; /* port not enabled */ diff --git a/drivers/ide/pdcraid.c b/drivers/ide/pdcraid.c index 78f3174a5f30..1f205f2051fa 100644 --- a/drivers/ide/pdcraid.c +++ b/drivers/ide/pdcraid.c @@ -36,14 +36,32 @@ static int pdcraid_open(struct inode * inode, struct file * filp); static int pdcraid_release(struct inode * inode, struct file * filp); static int pdcraid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -static int pdcraid_make_request (request_queue_t *q, int rw, struct buffer_head * bh); +static int pdcraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh); +static int pdcraid1_make_request (request_queue_t *q, int rw, struct buffer_head * bh); +struct disk_dev { + int major; + int minor; + int device; +}; + +static struct disk_dev devlist[]= { + {IDE0_MAJOR, 0, -1 }, + {IDE0_MAJOR, 64, -1 }, + {IDE1_MAJOR, 0, -1 }, + {IDE1_MAJOR, 64, -1 }, + {IDE2_MAJOR, 0, -1 }, + {IDE2_MAJOR, 64, -1 }, + {IDE3_MAJOR, 0, -1 }, + {IDE3_MAJOR, 64, -1 }, +}; struct pdcdisk { kdev_t device; unsigned long sectors; struct block_device *bdev; + unsigned long last_pos; }; struct pdcraid { @@ -58,21 +76,31 @@ struct pdcraid { unsigned int cutoff_disks[8]; }; -static struct raid_device_operations pdcraid_ops = { +static struct raid_device_operations pdcraid0_ops = { open: pdcraid_open, release: pdcraid_release, ioctl: pdcraid_ioctl, - make_request: pdcraid_make_request + make_request: pdcraid0_make_request +}; + +static struct raid_device_operations pdcraid1_ops = { + open: pdcraid_open, + release: pdcraid_release, + ioctl: pdcraid_ioctl, + make_request: pdcraid1_make_request }; static struct pdcraid raid[16]; + static int pdcraid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { unsigned int minor; - unsigned long sectors; + unsigned long sectors,*larg; - if (!inode || !inode->i_rdev) + + + if (!inode || !inode->i_rdev) return -EINVAL; minor = MINOR(inode->i_rdev)>>SHIFT; @@ -121,6 +149,7 @@ static int pdcraid_ioctl(struct inode *inode, struct file *file, unsigned int cm return blk_ioctl(inode->i_rdev, cmd, arg); default: + printk("Invalid ioctl \n"); return -EINVAL; }; @@ -128,7 +157,49 @@ static int pdcraid_ioctl(struct inode *inode, struct file *file, unsigned int cm } -static int pdcraid_make_request (request_queue_t *q, int rw, struct buffer_head * bh) +unsigned long partition_map_normal(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride) +{ + return block + partition_off; +} + +unsigned long partition_map_linux(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride) +{ + unsigned long newblock; + + newblock = stride - (partition_off%stride); if (newblock == stride) newblock = 0; + newblock += block; + newblock = newblock % partition_size; + newblock += partition_off; + + return newblock; +} + +static int funky_remap[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +unsigned long partition_map_linux_raid0_4disk(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride) +{ + unsigned long newblock,temp,temp2; + + newblock = stride - (partition_off%stride); if (newblock == stride) newblock = 0; + + if (block < (partition_size / (8*stride))*8*stride ) { + temp = block % stride; + temp2 = block / stride; + temp2 = ((temp2>>3)<<3)|(funky_remap[temp2&7]); + block = temp2*stride+temp; + } + + + newblock += block; + newblock = newblock % partition_size; + newblock += partition_off; + + return newblock; +} + + + +static int pdcraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh) { unsigned long rsect; unsigned long rsect_left,rsect_accum = 0; @@ -159,7 +230,7 @@ static int pdcraid_make_request (request_queue_t *q, int rw, struct buffer_head /* Partitions need adding of the start sector of the partition to the requested sector */ - rsect += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect; + rsect = partition_map_normal(rsect, ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect, ataraid_gendisk.part[MINOR(bh->b_rdev)].nr_sects, thisraid->stride); /* Woops we need to split the request to avoid crossing a stride barrier */ if ((rsect/thisraid->stride) != ((rsect+(bh->b_size/512)-1)/thisraid->stride)) { @@ -208,9 +279,114 @@ static int pdcraid_make_request (request_queue_t *q, int rw, struct buffer_head * Let the main block layer submit the IO and resolve recursion: */ return 1; + + outerr: + buffer_IO_error(bh); + return 0; +} + +static int pdcraid1_write_request(request_queue_t *q, int rw, struct buffer_head * bh) +{ + struct buffer_head *bh1; + struct ataraid_bh_private *private; + int device; + int i; + + device = (bh->b_rdev >> SHIFT)&MAJOR_MASK; + private = ataraid_get_private(); + if (private==NULL) + BUG(); + + private->parent = bh; + + atomic_set(&private->count,raid[device].disks); + + + for (i = 0; i< raid[device].disks; i++) { + bh1=ataraid_get_bhead(); + /* If this ever fails we're doomed */ + if (!bh1) + BUG(); + + /* dupe the bufferhead and update the parts that need to be different */ + memcpy(bh1, bh, sizeof(*bh)); + + bh1->b_end_io = ataraid_end_request; + bh1->b_private = private; + bh1->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect; /* partition offset */ + bh1->b_rdev = raid[device].disk[i].device; + + /* update the last known head position for the drive */ + raid[device].disk[i].last_pos = bh1->b_rsector+(bh1->b_size>>9); + + generic_make_request(rw,bh1); + } + return 0; +} + +static int pdcraid1_read_request (request_queue_t *q, int rw, struct buffer_head * bh) +{ + int device; + int dist; + int bestsofar,bestdist,i; + static int previous; + + /* Reads are simple in principle. Pick a disk and go. + Initially I cheat by just picking the one which the last known + head position is closest by. + Later on, online/offline checking and performance needs adding */ + + device = (bh->b_rdev >> SHIFT)&MAJOR_MASK; + bh->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect; + + bestsofar = 0; + bestdist = raid[device].disk[0].last_pos - bh->b_rsector; + if (bestdist<0) + bestdist=-bestdist; + if (bestdist>4095) + bestdist=4095; + + for (i=1 ; i<raid[device].disks; i++) { + dist = raid[device].disk[i].last_pos - bh->b_rsector; + if (dist<0) + dist = -dist; + if (dist>4095) + dist=4095; + + if (bestdist==dist) { /* it's a tie; try to do some read balancing */ + if ((previous>bestsofar)&&(previous<=i)) + bestsofar = i; + previous = (previous + 1) % raid[device].disks; + } else if (bestdist>dist) { + bestdist = dist; + bestsofar = i; + } + + } + + bh->b_rdev = raid[device].disk[bestsofar].device; + raid[device].disk[bestsofar].last_pos = bh->b_rsector+(bh->b_size>>9); + + /* + * Let the main block layer submit the IO and resolve recursion: + */ + + return 1; } +static int pdcraid1_make_request (request_queue_t *q, int rw, struct buffer_head * bh) +{ + /* Read and Write are totally different cases; split them totally here */ + if (rw==READA) + rw = READ; + + if (rw==READ) + return pdcraid1_read_request(q,rw,bh); + else + return pdcraid1_write_request(q,rw,bh); +} + #include "pdcraid.h" static unsigned long calc_pdcblock_offset (int major,int minor) @@ -288,12 +464,22 @@ static unsigned int calc_sb_csum (unsigned int* ptr) return sum; } -static void __init probedisk(int major, int minor,int device) +static int cookie = 0; + +static void __init probedisk(int devindex,int device, int raidlevel) { int i; + int major, minor; struct promise_raid_conf *prom; static unsigned char block[4096]; + struct block_device *bdev; + + if (devlist[devindex].device!=-1) /* already assigned to another array */ + return; + major = devlist[devindex].major; + minor = devlist[devindex].minor; + if (read_disk_sb(major,minor,(unsigned char*)&block,sizeof(block))) return; @@ -302,26 +488,23 @@ static void __init probedisk(int major, int minor,int device) /* the checksums must match */ if (prom->checksum != calc_sb_csum((unsigned int*)prom)) return; - if (prom->raid.type!=0x00) /* Only raid 0 is supported right now */ + if (prom->raid.type!=raidlevel) /* different raidlevel */ + return; + + if ((cookie!=0) && (cookie != prom->raid.magic_1)) /* different array */ return; + cookie = prom->raid.magic_1; /* This looks evil. But basically, we have to search for our adapternumber in the arraydefinition, both of which are in the superblock */ for (i=0;(i<prom->raid.total_disks)&&(i<8);i++) { if ( (prom->raid.disk[i].channel== prom->raid.channel) && (prom->raid.disk[i].device == prom->raid.device) ) { - struct block_device *bdev = bdget(MKDEV(major,minor)); - if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) { - struct gendisk *gd; - int j; - /* This is supposed to prevent others from stealing our underlying disks */ + + bdev = bdget(MKDEV(major,minor)); + if (bdev && blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_RAW) == 0) { raid[device].disk[i].bdev = bdev; - gd=get_gendisk(major); - if (gd!=NULL) { - for (j=1+(minor<<gd->minor_shift);j<((minor+1)<<gd->minor_shift);j++) - gd->part[j].nr_sects=0; - } } raid[device].disk[i].device = MKDEV(major,minor); raid[device].disk[i].sectors = prom->raid.disk_secs; @@ -331,7 +514,7 @@ static void __init probedisk(int major, int minor,int device) raid[device].geom.heads = prom->raid.heads+1; raid[device].geom.sectors = prom->raid.sectors; raid[device].geom.cylinders = prom->raid.cylinders+1; - + devlist[devindex].device=device; } } @@ -362,62 +545,91 @@ static void __init fill_cutoff(int device) } } -static __init int pdcraid_init_one(int device) +static __init int pdcraid_init_one(int device,int raidlevel) { + request_queue_t *q; int i,count; - probedisk(IDE0_MAJOR, 0, device); - probedisk(IDE0_MAJOR, 64, device); - probedisk(IDE1_MAJOR, 0, device); - probedisk(IDE1_MAJOR, 64, device); - probedisk(IDE2_MAJOR, 0, device); - probedisk(IDE2_MAJOR, 64, device); - probedisk(IDE3_MAJOR, 0, device); - probedisk(IDE3_MAJOR, 64, device); + probedisk(0, device, raidlevel); + probedisk(1, device, raidlevel); + probedisk(2, device, raidlevel); + probedisk(3, device, raidlevel); + probedisk(4, device, raidlevel); + probedisk(5, device, raidlevel); + probedisk(6, device, raidlevel); + probedisk(7, device, raidlevel); - fill_cutoff(device); + if (raidlevel==0) + fill_cutoff(device); /* Initialize the gendisk structure */ ataraid_register_disk(device,raid[device].sectors); count=0; - printk(KERN_INFO "Promise Fasttrak(tm) Softwareraid driver for linux version 0.02\n"); for (i=0;i<8;i++) { if (raid[device].disk[i].device!=0) { - printk(KERN_INFO "Drive %i is %li Mb \n", - i,raid[device].disk[i].sectors/2048); + printk(KERN_INFO "Drive %i is %li Mb (%i / %i) \n", + i,raid[device].disk[i].sectors/2048,MAJOR(raid[device].disk[i].device),MINOR(raid[device].disk[i].device)); count++; } } if (count) { - printk(KERN_INFO "Raid array consists of %i drives. \n",count); + printk(KERN_INFO "Raid%i array consists of %i drives. \n",raidlevel,count); return 0; } else { - printk(KERN_INFO "No raid array found\n"); return -ENODEV; } } static __init int pdcraid_init(void) { - int retval,device; + int i,retval,device,count=0; + + do { - device=ataraid_get_device(&pdcraid_ops); - if (device<0) - return -ENODEV; - retval = pdcraid_init_one(device); - if (retval) - ataraid_release_device(device); - return retval; + cookie = 0; + device=ataraid_get_device(&pdcraid0_ops); + if (device<0) + break; + retval = pdcraid_init_one(device,0); + if (retval) { + ataraid_release_device(device); + break; + } else { + count++; + } + } while (1); + + do { + + cookie = 0; + device=ataraid_get_device(&pdcraid1_ops); + if (device<0) + break; + retval = pdcraid_init_one(device,1); + if (retval) { + ataraid_release_device(device); + break; + } else { + count++; + } + } while (1); + + if (count) { + printk(KERN_INFO "Promise Fasttrak(tm) Softwareraid driver for linux version 0.03beta\n"); + return 0; + } + printk(KERN_DEBUG "Promise Fasttrak(tm) Softwareraid driver 0.03beta: No raid array found\n"); + return -ENODEV; } static void __exit pdcraid_exit (void) { int i,device; for (device = 0; device<16; device++) { - for (i=0;i<8;i++) { + for (i=0;i<8;i++) { struct block_device *bdev = raid[device].disk[i].bdev; raid[device].disk[i].bdev = NULL; if (bdev) @@ -441,3 +653,4 @@ static int pdcraid_release(struct inode * inode, struct file * filp) module_init(pdcraid_init); module_exit(pdcraid_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/ieee1394/ieee1394_syms.c b/drivers/ieee1394/ieee1394_syms.c index 4833964d8c06..e5a07889a543 100644 --- a/drivers/ieee1394/ieee1394_syms.c +++ b/drivers/ieee1394/ieee1394_syms.c @@ -79,3 +79,4 @@ EXPORT_SYMBOL(hpsb_guid_get_entry); EXPORT_SYMBOL(hpsb_nodeid_get_entry); EXPORT_SYMBOL(hpsb_get_host_by_ne); EXPORT_SYMBOL(hpsb_guid_fill_packet); +MODULE_LICENSE("GPL"); diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 8e0509de9ac6..8c68f145bdcb 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -2402,6 +2402,7 @@ EXPORT_SYMBOL(ohci1394_unregister_video); MODULE_AUTHOR("Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>"); MODULE_DESCRIPTION("Driver for PCI OHCI IEEE-1394 controllers"); +MODULE_LICENSE("GPL"); static void __devexit ohci1394_remove_one(struct pci_dev *pdev) { diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index 072214af9242..ee7d5b99150c 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c @@ -1627,6 +1627,7 @@ static struct pci_driver lynx_pcidriver = { MODULE_AUTHOR("Andreas E. Bombe <andreas.bombe@munich.netsurf.de>"); MODULE_DESCRIPTION("driver for Texas Instruments PCI Lynx IEEE-1394 controller"); +MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("pcilynx"); MODULE_DEVICE_TABLE(pci, pci_table); diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index eb79e761cd44..03a72ab10eb3 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -1031,3 +1031,4 @@ static void __exit cleanup_raw1394(void) module_init(init_raw1394); module_exit(cleanup_raw1394); +MODULE_LICENSE("GPL"); diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 5e34bcba2b00..810d6ffb7659 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -1639,6 +1639,7 @@ static struct hpsb_highlevel_ops hl_ops = { MODULE_AUTHOR("Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>"); MODULE_DESCRIPTION("driver for digital video on OHCI board"); MODULE_SUPPORTED_DEVICE(VIDEO1394_DRIVER_NAME); +MODULE_LICENSE("GPL"); static void __exit video1394_exit_module (void) { diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index f4164acc26d7..ec72e8895816 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -398,3 +398,5 @@ module_exit(evdev_exit); MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_DESCRIPTION("Event character device driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/input/input.c b/drivers/input/input.c index 330b2e2db287..b6e8f5756b27 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -37,6 +37,8 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_DESCRIPTION("Input layer module"); +MODULE_LICENSE("GPL"); + EXPORT_SYMBOL(input_register_device); EXPORT_SYMBOL(input_unregister_device); diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index ff20461302f3..260f5d206a6e 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -84,6 +84,7 @@ static struct joydev *joydev_table[JOYDEV_MINORS]; MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_DESCRIPTION("Joystick device driver"); +MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("input/js"); static int joydev_correct(int value, struct js_corr *corr) diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index dab3e6d76579..9b8ad23910a0 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -314,9 +314,9 @@ static ssize_t mousedev_write(struct file * file, const char * buffer, size_t co case 0xf2: /* Get ID */ switch (list->mode) { - case 0: list->ps2[1] = 0; - case 1: list->ps2[1] = 3; - case 2: list->ps2[1] = 4; + case 0: list->ps2[1] = 0; break; + case 1: list->ps2[1] = 3; break; + case 2: list->ps2[1] = 4; break; } list->bufsiz = 2; break; @@ -497,6 +497,8 @@ module_exit(mousedev_exit); MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_DESCRIPTION("Input driver to PS/2 or ImPS/2 device driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(xres, "i"); MODULE_PARM_DESC(xres, "Horizontal screen resolution"); MODULE_PARM(yres, "i"); diff --git a/drivers/isdn/act2000/act2000.h b/drivers/isdn/act2000/act2000.h index adffe94b1888..af991db4d434 100644 --- a/drivers/isdn/act2000/act2000.h +++ b/drivers/isdn/act2000/act2000.h @@ -1,36 +1,20 @@ -/* $Id: act2000.h,v 1.8.6.2 2001/02/16 16:43:23 kai Exp $ +/* $Id: act2000.h,v 1.8.6.3 2001/09/23 22:24:32 kai Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. * - * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) - * Thanks to Friedemann Baitinger and IBM Germany - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Author Fritz Elfert + * Copyright by Fritz Elfert <fritz@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Thanks to Friedemann Baitinger and IBM Germany * */ #ifndef act2000_h #define act2000_h -#ifdef __KERNEL__ -/* Kernel includes */ - -#include <linux/module.h> -#include <linux/version.h> -#endif - #define ACT2000_IOCTL_SETPORT 1 #define ACT2000_IOCTL_GETPORT 2 #define ACT2000_IOCTL_SETIRQ 3 diff --git a/drivers/isdn/act2000/act2000_isa.c b/drivers/isdn/act2000/act2000_isa.c index 889161b870e7..5bde8e15689c 100644 --- a/drivers/isdn/act2000/act2000_isa.c +++ b/drivers/isdn/act2000/act2000_isa.c @@ -1,23 +1,14 @@ -/* $Id: act2000_isa.c,v 1.11.6.2 2001/07/18 16:25:12 kai Exp $ +/* $Id: act2000_isa.c,v 1.11.6.3 2001/09/23 22:24:32 kai Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). * - * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) - * Thanks to Friedemann Baitinger and IBM Germany - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Author Fritz Elfert + * Copyright by Fritz Elfert <fritz@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Thanks to Friedemann Baitinger and IBM Germany * */ diff --git a/drivers/isdn/act2000/act2000_isa.h b/drivers/isdn/act2000/act2000_isa.h index 0b705d33fe59..caee2ba8047f 100644 --- a/drivers/isdn/act2000/act2000_isa.h +++ b/drivers/isdn/act2000/act2000_isa.h @@ -1,23 +1,14 @@ -/* $Id: act2000_isa.h,v 1.4 2000/11/12 16:32:06 kai Exp $ +/* $Id: act2000_isa.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). * - * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) - * Thanks to Friedemann Baitinger and IBM Germany - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Author Fritz Elfert + * Copyright by Fritz Elfert <fritz@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Thanks to Friedemann Baitinger and IBM Germany * */ diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c index ee126cb2cc5e..011d6e18ea85 100644 --- a/drivers/isdn/act2000/capi.c +++ b/drivers/isdn/act2000/capi.c @@ -1,24 +1,15 @@ -/* $Id: capi.c,v 1.9.6.1 2001/02/16 16:43:23 kai Exp $ +/* $Id: capi.c,v 1.9.6.2 2001/09/23 22:24:32 kai Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. - * CAPI encoder/decoder + * CAPI encoder/decoder * - * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) - * Thanks to Friedemann Baitinger and IBM Germany - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Author Fritz Elfert + * Copyright by Fritz Elfert <fritz@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Thanks to Friedemann Baitinger and IBM Germany * */ diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h index fb64fa877c9f..88570a1fb328 100644 --- a/drivers/isdn/act2000/capi.h +++ b/drivers/isdn/act2000/capi.h @@ -1,23 +1,14 @@ -/* $Id: capi.h,v 1.6.6.1 2001/02/16 16:43:23 kai Exp $ +/* $Id: capi.h,v 1.6.6.2 2001/09/23 22:24:32 kai Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. * - * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) - * Thanks to Friedemann Baitinger and IBM Germany - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Author Fritz Elfert + * Copyright by Fritz Elfert <fritz@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Thanks to Friedemann Baitinger and IBM Germany * */ diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c index 9508f961bd06..3c9743862862 100644 --- a/drivers/isdn/act2000/module.c +++ b/drivers/isdn/act2000/module.c @@ -1,29 +1,21 @@ -/* $Id: module.c,v 1.14.6.3 2001/07/13 09:20:11 kai Exp $ +/* $Id: module.c,v 1.14.6.4 2001/09/23 22:24:32 kai Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. * - * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) - * Thanks to Friedemann Baitinger and IBM Germany - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Author Fritz Elfert + * Copyright by Fritz Elfert <fritz@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Thanks to Friedemann Baitinger and IBM Germany * */ #include "act2000.h" #include "act2000_isa.h" #include "capi.h" +#include <linux/module.h> #include <linux/init.h> static unsigned short act2000_isa_ports[] = @@ -41,9 +33,9 @@ static int act_port = -1; /* -1 = Autoprobe */ static int act_irq = -1; static char *act_id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -MODULE_DESCRIPTION( "Driver for IBM Active 2000 ISDN card"); +MODULE_DESCRIPTION( "ISDN4Linux: Driver for IBM Active 2000 ISDN card"); MODULE_AUTHOR( "Fritz Elfert"); -MODULE_SUPPORTED_DEVICE( "ISDN subsystem"); +MODULE_LICENSE( "GPL"); MODULE_PARM_DESC(act_bus, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA"); MODULE_PARM_DESC(membase, "Base port address of first card"); MODULE_PARM_DESC(act_irq, "IRQ of first card"); diff --git a/drivers/isdn/avmb1/avm_cs.c b/drivers/isdn/avmb1/avm_cs.c index b3b74b2b08b7..aca2ec81ea96 100644 --- a/drivers/isdn/avmb1/avm_cs.c +++ b/drivers/isdn/avmb1/avm_cs.c @@ -1,10 +1,13 @@ -/*====================================================================== - - A PCMCIA client driver for AVM B1/M1/M2 - - Written by Carsten Paeth, calle@calle.in-berlin.de - -======================================================================*/ +/* $Id: avm_cs.c,v 1.4.6.3 2001/09/23 22:24:33 kai Exp $ + * + * A PCMCIA client driver for AVM B1/M1/M2 + * + * Copyright 1999 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ #include <linux/module.h> #include <linux/kernel.h> @@ -35,6 +38,12 @@ /*====================================================================*/ +MODULE_DESCRIPTION("CAPI4Linux: PCMCIA client driver for AVM B1/M1/M2"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); + +/*====================================================================*/ + /* Parameters that can be set with 'insmod' */ /* This means pick from 15, 12, 11, 10, 9, 7, 5, 4, and 3 */ diff --git a/drivers/isdn/avmb1/avmcard.h b/drivers/isdn/avmb1/avmcard.h index 73c45cb93e3f..e33fb0d8dd41 100644 --- a/drivers/isdn/avmb1/avmcard.h +++ b/drivers/isdn/avmb1/avmcard.h @@ -1,7 +1,9 @@ -/* - * $Id: avmcard.h,v 1.8.6.3 2001/05/17 21:15:33 kai Exp $ +/* $Id: avmcard.h,v 1.8.6.4 2001/09/23 22:24:33 kai Exp $ + * + * Copyright 1999 by Carsten Paeth <calle@calle.de> * - * Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/avmb1/b1.c b/drivers/isdn/avmb1/b1.c index 2ccbd29bb440..bf8a49bcef05 100644 --- a/drivers/isdn/avmb1/b1.c +++ b/drivers/isdn/avmb1/b1.c @@ -1,9 +1,11 @@ -/* - * $Id: b1.c,v 1.20.6.6 2001/05/17 21:15:33 kai Exp $ +/* $Id: b1.c,v 1.20.6.7 2001/09/23 22:24:33 kai Exp $ * * Common module for AVM B1 cards. * - * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1999 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -25,11 +27,13 @@ #include "capicmd.h" #include "capiutil.h" -static char *revision = "$Revision: 1.20.6.6 $"; +static char *revision = "$Revision: 1.20.6.7 $"; /* ------------------------------------------------------------- */ -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); +MODULE_DESCRIPTION("CAPI4Linux: Common support for active AVM cards"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/avmb1/b1dma.c b/drivers/isdn/avmb1/b1dma.c index b79c0cf485e7..c948463f6d15 100644 --- a/drivers/isdn/avmb1/b1dma.c +++ b/drivers/isdn/avmb1/b1dma.c @@ -1,10 +1,12 @@ -/* - * $Id: b1dma.c,v 1.11.6.7 2001/07/18 16:02:15 kai Exp $ +/* $Id: b1dma.c,v 1.11.6.8 2001/09/23 22:24:33 kai Exp $ * * Common module for AVM B1 cards that support dma with AMCC * - * (c) Copyright 2000 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 2000 by Carsten Paeth <calle@calle.de> * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #include <linux/config.h> @@ -30,11 +32,13 @@ #error FIXME: driver requires 32-bit platform #endif -static char *revision = "$Revision: 1.11.6.7 $"; +static char *revision = "$Revision: 1.11.6.8 $"; /* ------------------------------------------------------------- */ -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); +MODULE_DESCRIPTION("CAPI4Linux: DMA support for active AVM cards"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); static int suppress_pollack = 0; MODULE_PARM(suppress_pollack, "0-1i"); diff --git a/drivers/isdn/avmb1/b1isa.c b/drivers/isdn/avmb1/b1isa.c index bd241e648128..81de6545049d 100644 --- a/drivers/isdn/avmb1/b1isa.c +++ b/drivers/isdn/avmb1/b1isa.c @@ -1,10 +1,12 @@ -/* - * $Id: b1isa.c,v 1.10.6.5 2001/05/17 20:41:51 kai Exp $ +/* $Id: b1isa.c,v 1.10.6.6 2001/09/23 22:24:33 kai Exp $ * * Module for AVM B1 ISA-card. * - * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1999 by Carsten Paeth <calle@calle.de> * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #include <linux/module.h> @@ -22,11 +24,13 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.10.6.5 $"; +static char *revision = "$Revision: 1.10.6.6 $"; /* ------------------------------------------------------------- */ -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); +MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 ISA card"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/avmb1/b1pci.c b/drivers/isdn/avmb1/b1pci.c index 34d1a630f2f3..ef38a321ee8d 100644 --- a/drivers/isdn/avmb1/b1pci.c +++ b/drivers/isdn/avmb1/b1pci.c @@ -1,10 +1,12 @@ -/* - * $Id: b1pci.c,v 1.29.6.4 2001/05/17 20:41:51 kai Exp $ +/* $Id: b1pci.c,v 1.29.6.5 2001/09/23 22:24:33 kai Exp $ * * Module for AVM B1 PCI-card. * - * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1999 by Carsten Paeth <calle@calle.de> * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #include <linux/config.h> @@ -24,7 +26,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.29.6.4 $"; +static char *revision = "$Revision: 1.29.6.5 $"; /* ------------------------------------------------------------- */ @@ -34,7 +36,9 @@ static struct pci_device_id b1pci_pci_tbl[] __initdata = { }; MODULE_DEVICE_TABLE(pci, b1pci_pci_tbl); -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); +MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 PCI card"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/avmb1/b1pcmcia.c b/drivers/isdn/avmb1/b1pcmcia.c index 09b33ed32e7c..635553d9d986 100644 --- a/drivers/isdn/avmb1/b1pcmcia.c +++ b/drivers/isdn/avmb1/b1pcmcia.c @@ -1,10 +1,12 @@ -/* - * $Id: b1pcmcia.c,v 1.12.6.4 2001/05/17 20:41:51 kai Exp $ +/* $Id: b1pcmcia.c,v 1.12.6.5 2001/09/23 22:24:33 kai Exp $ * * Module for AVM B1/M1/M2 PCMCIA-card. * - * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1999 by Carsten Paeth <calle@calle.de> * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #include <linux/module.h> @@ -23,11 +25,13 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.12.6.4 $"; +static char *revision = "$Revision: 1.12.6.5 $"; /* ------------------------------------------------------------- */ -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); +MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM PCMCIA cards"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/avmb1/c4.c b/drivers/isdn/avmb1/c4.c index 7554c8465d81..b9d66d69ddf2 100644 --- a/drivers/isdn/avmb1/c4.c +++ b/drivers/isdn/avmb1/c4.c @@ -1,9 +1,11 @@ -/* - * $Id: c4.c,v 1.20.6.10 2001/06/09 15:14:15 kai Exp $ +/* $Id: c4.c,v 1.20.6.11 2001/09/23 22:24:33 kai Exp $ * * Module for AVM C4 & C2 card. * - * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1999 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -27,7 +29,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.20.6.10 $"; +static char *revision = "$Revision: 1.20.6.11 $"; #undef CONFIG_C4_DEBUG #undef CONFIG_C4_POLLDEBUG @@ -43,7 +45,9 @@ static struct pci_device_id c4_pci_tbl[] __initdata = { }; MODULE_DEVICE_TABLE(pci, c4_pci_tbl); -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); +MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM C2/C4 cards"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); MODULE_PARM(suppress_pollack, "0-1i"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/avmb1/capi.c b/drivers/isdn/avmb1/capi.c index f9d771c0803d..b453e3b9fa02 100644 --- a/drivers/isdn/avmb1/capi.c +++ b/drivers/isdn/avmb1/capi.c @@ -1,9 +1,11 @@ -/* - * $Id: capi.c,v 1.44.6.13 2001/08/13 07:46:15 kai Exp $ +/* $Id: capi.c,v 1.44.6.15 2001/09/28 08:05:29 kai Exp $ * * CAPI 2.0 Interface for Linux * - * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1996 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -43,9 +45,11 @@ #include "capifs.h" #endif -static char *revision = "$Revision: 1.44.6.13 $"; +static char *revision = "$Revision: 1.44.6.15 $"; -MODULE_AUTHOR("Carsten Paeth (calle@calle.in-berlin.de)"); +MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); #undef _DEBUG_REFCOUNT /* alloc/free and open/close debug */ #undef _DEBUG_TTYFUNCS /* call to tty_driver */ @@ -768,7 +772,7 @@ capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos) if ((retval = copy_from_user(skb_put(skb, count), buf, count))) { kfree_skb(skb); - return retval; + return -EFAULT; } mlen = CAPIMSG_LEN(skb->data); if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { @@ -1182,7 +1186,7 @@ capinc_raw_write(struct file *file, const char *buf, size_t count, loff_t *ppos) skb_reserve(skb, CAPI_DATA_B3_REQ_LEN); if ((retval = copy_from_user(skb_put(skb, count), buf, count))) { kfree_skb(skb); - return retval; + return -EFAULT; } while (skb_queue_len(&mp->outqueue) > CAPINC_MAX_SENDQUEUE) { @@ -1360,7 +1364,7 @@ int capinc_tty_write(struct tty_struct * tty, int from_user, #ifdef _DEBUG_TTYFUNCS printk(KERN_DEBUG "capinc_tty_write: copy_from_user=%d\n", retval); #endif - return retval; + return -EFAULT; } } else { memcpy(skb_put(skb, count), buf, count); diff --git a/drivers/isdn/avmb1/capicmd.h b/drivers/isdn/avmb1/capicmd.h index d9566f10d603..b58635f722da 100644 --- a/drivers/isdn/avmb1/capicmd.h +++ b/drivers/isdn/avmb1/capicmd.h @@ -1,11 +1,14 @@ -/* - * $Id: capicmd.h,v 1.2.6.1 2001/05/17 20:41:51 kai Exp $ +/* $Id: capicmd.h,v 1.2.6.2 2001/09/23 22:24:33 kai Exp $ * * CAPI 2.0 Interface for Linux * - * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1997 by Carsten Paeth <calle@calle.de> * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ + #ifndef __CAPICMD_H__ #define __CAPICMD_H__ diff --git a/drivers/isdn/avmb1/capidev.h b/drivers/isdn/avmb1/capidev.h index cf0b41c051e2..37424a51573b 100644 --- a/drivers/isdn/avmb1/capidev.h +++ b/drivers/isdn/avmb1/capidev.h @@ -1,9 +1,11 @@ -/* - * $Id: capidev.h,v 1.6.6.1 2001/05/17 20:41:51 kai Exp $ +/* $Id: capidev.h,v 1.6.6.2 2001/09/23 22:24:33 kai Exp $ * * CAPI 2.0 Interface for Linux * - * (c) Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1996 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/avmb1/capidrv.c b/drivers/isdn/avmb1/capidrv.c index 2a1145e05bfc..d90606fe1917 100644 --- a/drivers/isdn/avmb1/capidrv.c +++ b/drivers/isdn/avmb1/capidrv.c @@ -1,9 +1,11 @@ -/* - * $Id: capidrv.c,v 1.39.6.6 2001/05/17 20:41:51 kai Exp $ +/* $Id: capidrv.c,v 1.39.6.7 2001/09/23 22:24:33 kai Exp $ * * ISDN4Linux Driver, using capi20 interface (kernelcapi) * - * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1997 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -33,10 +35,12 @@ #include "capicmd.h" #include "capidrv.h" -static char *revision = "$Revision: 1.39.6.6 $"; +static char *revision = "$Revision: 1.39.6.7 $"; static int debugmode = 0; -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); +MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); MODULE_PARM(debugmode, "i"); /* -------- type definitions ----------------------------------------- */ diff --git a/drivers/isdn/avmb1/capidrv.h b/drivers/isdn/avmb1/capidrv.h index 245993e3218e..1e698e1e269f 100644 --- a/drivers/isdn/avmb1/capidrv.h +++ b/drivers/isdn/avmb1/capidrv.h @@ -1,11 +1,14 @@ -/* - * $Id: capidrv.h,v 1.2.8.1 2001/05/17 20:41:51 kai Exp $ +/* $Id: capidrv.h,v 1.2.8.2 2001/09/23 22:24:33 kai Exp $ * * ISDN4Linux Driver, using capi20 interface (kernelcapi) * - * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1997 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #ifndef __CAPIDRV_H__ #define __CAPIDRV_H__ diff --git a/drivers/isdn/avmb1/capifs.c b/drivers/isdn/avmb1/capifs.c index 4e611ab62b3a..745b6bd112cb 100644 --- a/drivers/isdn/avmb1/capifs.c +++ b/drivers/isdn/avmb1/capifs.c @@ -1,10 +1,12 @@ -/* - * $Id: capifs.c,v 1.14.6.7 2001/05/24 08:29:08 kai Exp $ +/* $Id: capifs.c,v 1.14.6.8 2001/09/23 22:24:33 kai Exp $ * - * (c) Copyright 2000 by Carsten Paeth (calle@calle.de) + * Copyright 2000 by Carsten Paeth <calle@calle.de> * * Heavily based on devpts filesystem from H. Peter Anvin * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #include <linux/version.h> @@ -26,9 +28,11 @@ #include <asm/bitops.h> #include <asm/uaccess.h> -MODULE_AUTHOR("Carsten Paeth <calle@calle.de>"); +MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); -static char *revision = "$Revision: 1.14.6.7 $"; +static char *revision = "$Revision: 1.14.6.8 $"; struct capifs_ncci { struct inode *inode; diff --git a/drivers/isdn/avmb1/capifs.h b/drivers/isdn/avmb1/capifs.h index 8ee489e3ac9a..9b7478630e43 100644 --- a/drivers/isdn/avmb1/capifs.h +++ b/drivers/isdn/avmb1/capifs.h @@ -1,7 +1,9 @@ -/* - * $Id: capifs.h,v 1.2.6.1 2001/05/17 20:41:51 kai Exp $ +/* $Id: capifs.h,v 1.2.6.2 2001/09/23 22:24:33 kai Exp $ * - * (c) Copyright 2000 by Carsten Paeth (calle@calle.de) + * Copyright 2000 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/avmb1/capilli.h b/drivers/isdn/avmb1/capilli.h index da64a183b673..411ffa7fe1e0 100644 --- a/drivers/isdn/avmb1/capilli.h +++ b/drivers/isdn/avmb1/capilli.h @@ -1,11 +1,14 @@ -/* - * $Id: capilli.h,v 1.4 1999/07/23 08:51:05 calle Exp $ +/* $Id: capilli.h,v 1.4.8.1 2001/09/23 22:24:33 kai Exp $ * * Kernel CAPI 2.0 Driver Interface for Linux * - * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1999 by Carsten Paeth <calle@calle.de> * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ + #ifndef __CAPILLI_H__ #define __CAPILLI_H__ diff --git a/drivers/isdn/avmb1/capiutil.c b/drivers/isdn/avmb1/capiutil.c index 4f9ed040c12d..ce07a56cd55b 100644 --- a/drivers/isdn/avmb1/capiutil.c +++ b/drivers/isdn/avmb1/capiutil.c @@ -1,12 +1,15 @@ -/* - * $Id: capiutil.c,v 1.13.6.3 2001/05/17 20:41:51 kai Exp $ +/* $Id: capiutil.c,v 1.13.6.4 2001/09/23 22:24:33 kai Exp $ * * CAPI 2.0 convert capi message to capi message struct * * From CAPI 2.0 Development Kit AVM 1995 (msg.c) - * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de) + * Rewritten for Linux 1996 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #include <linux/module.h> #include <linux/string.h> #include <linux/ctype.h> @@ -18,6 +21,10 @@ #include <linux/config.h> #include "capiutil.h" +MODULE_DESCRIPTION("CAPI4Linux: CAPI message conversion support"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); + /* from CAPI2.0 DDK AVM Berlin GmbH */ #ifndef CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON diff --git a/drivers/isdn/avmb1/capiutil.h b/drivers/isdn/avmb1/capiutil.h index ab7f1ceb72dc..2e79f816703b 100644 --- a/drivers/isdn/avmb1/capiutil.h +++ b/drivers/isdn/avmb1/capiutil.h @@ -1,12 +1,15 @@ -/* - * $Id: capiutil.h,v 1.5.6.1 2001/05/17 20:41:51 kai Exp $ - * +/* $Id: capiutil.h,v 1.5.6.2 2001/09/23 22:24:33 kai Exp $ + * * CAPI 2.0 defines & types - * - * From CAPI 2.0 Development Kit AVM 1995 (capi20.h) - * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de) - * + * + * From CAPI 2.0 Development Kit AVM 1995 (msg.c) + * Rewritten for Linux 1996 by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ + #ifndef __CAPIUTIL_H__ #define __CAPIUTIL_H__ diff --git a/drivers/isdn/avmb1/kcapi.c b/drivers/isdn/avmb1/kcapi.c index bc41a5eab803..12fd800b19c1 100644 --- a/drivers/isdn/avmb1/kcapi.c +++ b/drivers/isdn/avmb1/kcapi.c @@ -1,11 +1,14 @@ -/* - * $Id: kcapi.c,v 1.21.6.7 2001/06/09 15:14:15 kai Exp $ +/* $Id: kcapi.c,v 1.21.6.8 2001/09/23 22:24:33 kai Exp $ * * Kernel CAPI 2.0 Module * - * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1999 by Carsten Paeth <calle@calle.de> * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ + #define CONFIG_AVMB1_COMPAT #include <linux/config.h> @@ -30,7 +33,7 @@ #include <linux/b1lli.h> #endif -static char *revision = "$Revision: 1.21.6.7 $"; +static char *revision = "$Revision: 1.21.6.8 $"; /* ------------------------------------------------------------- */ @@ -41,10 +44,12 @@ static char *revision = "$Revision: 1.21.6.7 $"; /* ------------------------------------------------------------- */ -int showcapimsgs = 0; +static int showcapimsgs = 0; -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); -MODULE_PARM(showcapimsgs, "0-4i"); +MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); +MODULE_PARM(showcapimsgs, "i"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/avmb1/t1isa.c b/drivers/isdn/avmb1/t1isa.c index a655763a617d..7bfb21aa8f5e 100644 --- a/drivers/isdn/avmb1/t1isa.c +++ b/drivers/isdn/avmb1/t1isa.c @@ -1,10 +1,12 @@ -/* - * $Id: t1isa.c,v 1.16.6.6 2001/05/17 21:15:33 kai Exp $ +/* $Id: t1isa.c,v 1.16.6.7 2001/09/23 22:24:34 kai Exp $ * * Module for AVM T1 HEMA-card. * - * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1999 by Carsten Paeth <calle@calle.de> * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #include <linux/module.h> @@ -23,11 +25,13 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.16.6.6 $"; +static char *revision = "$Revision: 1.16.6.7 $"; /* ------------------------------------------------------------- */ -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); +MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 HEMA ISA card"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/avmb1/t1pci.c b/drivers/isdn/avmb1/t1pci.c index 71fa25326447..79aa41a87f9b 100644 --- a/drivers/isdn/avmb1/t1pci.c +++ b/drivers/isdn/avmb1/t1pci.c @@ -1,10 +1,12 @@ -/* - * $Id: t1pci.c,v 1.13.6.5 2001/05/17 20:41:51 kai Exp $ +/* $Id: t1pci.c,v 1.13.6.6 2001/09/23 22:24:34 kai Exp $ * * Module for AVM T1 PCI-card. * - * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * Copyright 1999 by Carsten Paeth <calle@calle.de> * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #include <linux/config.h> @@ -24,7 +26,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.13.6.5 $"; +static char *revision = "$Revision: 1.13.6.6 $"; #undef CONFIG_T1PCI_DEBUG #undef CONFIG_T1PCI_POLLDEBUG @@ -37,7 +39,9 @@ static struct pci_device_id t1pci_pci_tbl[] __initdata = { }; MODULE_DEVICE_TABLE(pci, t1pci_pci_tbl); -MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>"); +MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 PCI card"); +MODULE_AUTHOR("Carsten Paeth"); +MODULE_LICENSE("GPL"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/divert/divert_init.c b/drivers/isdn/divert/divert_init.c index edb4afb8af1a..48587a672255 100644 --- a/drivers/isdn/divert/divert_init.c +++ b/drivers/isdn/divert/divert_init.c @@ -1,23 +1,11 @@ -/* - * $Id: divert_init.c,v 1.5.6.2 2001/01/24 22:18:17 kai Exp $ +/* $Id divert_init.c,v 1.5.6.2 2001/01/24 22:18:17 kai Exp $ * * Module init for DSS1 diversion services for i4l. * * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -26,6 +14,10 @@ #include <linux/init.h> #include "isdn_divert.h" +MODULE_DESCRIPTION("ISDN4Linux: Call diversion support"); +MODULE_AUTHOR("Werner Cornelius"); +MODULE_LICENSE("GPL"); + /********************/ /* needed externals */ /********************/ @@ -70,7 +62,7 @@ static int __init divert_init(void) /* Module deinit code */ /**********************/ static void __exit divert_exit(void) -{ long flags; +{ unsigned long flags; int i; save_flags(flags); diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index b9dec5ff40eb..ce1a5cb85d96 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c @@ -1,23 +1,11 @@ -/* - * $Id: divert_procfs.c,v 1.11.6.1 2001/08/13 07:46:15 kai Exp $ +/* $Id: divert_procfs.c,v 1.11.6.2 2001/09/23 22:24:36 kai Exp $ * * Filesystem handling for the diversion supplementary services. * * Copyright 1998 by Werner Cornelius (werner@isdn4linux.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -50,7 +38,7 @@ void put_info_buffer(char *cp) { struct divert_info *ib; - long flags; + unsigned long flags; if (if_used <= 0) return; @@ -145,7 +133,7 @@ isdn_divert_poll(struct file *file, poll_table * wait) static int isdn_divert_open(struct inode *ino, struct file *filep) { - long flags; + unsigned long flags; lock_kernel(); save_flags(flags); @@ -168,7 +156,7 @@ static int isdn_divert_close(struct inode *ino, struct file *filep) { struct divert_info *inf; - long flags; + unsigned long flags; lock_kernel(); save_flags(flags); @@ -199,7 +187,7 @@ isdn_divert_ioctl(struct inode *inode, struct file *file, { divert_ioctl dioctl; int i; - long flags; + unsigned long flags; divert_rule *rulep; char *cp; diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c index 87f0c2b94497..568530d54987 100644 --- a/drivers/isdn/divert/isdn_divert.c +++ b/drivers/isdn/divert/isdn_divert.c @@ -1,30 +1,14 @@ -/* - * $Id: isdn_divert.c,v 1.6.6.2 2001/02/16 16:43:25 kai Exp $ +/* $Id: isdn_divert.c,v 1.6.6.3 2001/09/23 22:24:36 kai Exp $ * * DSS1 main diversion supplementary handling for i4l. * * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - - -#define __NO_VERSION__ -#include <linux/module.h> #include <linux/version.h> #include <linux/proc_fs.h> #include "isdn_divert.h" @@ -67,7 +51,7 @@ static unsigned char extern_wait_max = 4; /* maximum wait in s for external proc /* timer callback function */ /***************************/ static void deflect_timer_expire(ulong arg) -{ long flags; +{ unsigned long flags; struct call_struc *cs = (struct call_struc *) arg; save_flags(flags); @@ -125,7 +109,7 @@ static void deflect_timer_expire(ulong arg) int cf_command(int drvid, int mode, u_char proc, char *msn, u_char service, char *fwd_nr, ulong *procid) -{ long flags; +{ unsigned long flags; int retval,msnlen; int fwd_len; char *p,*ielenp,tmp[60]; @@ -221,7 +205,7 @@ int cf_command(int drvid, int mode, int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) { struct call_struc *cs; isdn_ctrl ic; - long flags; + unsigned long flags; int i; if ((cmd & 0x7F) > 2) return(-EINVAL); /* invalid command */ @@ -292,7 +276,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) /********************************/ int insertrule(int idx, divert_rule *newrule) { struct deflect_struc *ds,*ds1=NULL; - long flags; + unsigned long flags; if (!(ds = (struct deflect_struc *) kmalloc(sizeof(struct deflect_struc), GFP_KERNEL))) @@ -338,7 +322,7 @@ int insertrule(int idx, divert_rule *newrule) /***********************************/ int deleterule(int idx) { struct deflect_struc *ds,*ds1; - long flags; + unsigned long flags; if (idx < 0) { save_flags(flags); @@ -406,7 +390,7 @@ divert_rule *getruleptr(int idx) /*************************************************/ int isdn_divert_icall(isdn_ctrl *ic) { int retval = 0; - long flags; + unsigned long flags; struct call_struc *cs = NULL; struct deflect_struc *dv; char *p,*p1; @@ -558,7 +542,7 @@ int isdn_divert_icall(isdn_ctrl *ic) void deleteprocs(void) { struct call_struc *cs, *cs1; - long flags; + unsigned long flags; save_flags(flags); cli(); @@ -716,7 +700,7 @@ int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) int prot_stat_callback(isdn_ctrl *ic) { struct call_struc *cs, *cs1; int i; - long flags; + unsigned long flags; cs = divert_head; /* start of list */ cs1 = NULL; @@ -807,7 +791,7 @@ int prot_stat_callback(isdn_ctrl *ic) /***************************/ int isdn_divert_stat_callback(isdn_ctrl *ic) { struct call_struc *cs, *cs1; - long flags; + unsigned long flags; int retval; retval = -1; diff --git a/drivers/isdn/divert/isdn_divert.h b/drivers/isdn/divert/isdn_divert.h index 84390c9976c5..08df6f492183 100644 --- a/drivers/isdn/divert/isdn_divert.h +++ b/drivers/isdn/divert/isdn_divert.h @@ -1,27 +1,14 @@ -/* - * $Id: isdn_divert.h,v 1.5 2000/11/13 22:51:47 kai Exp $ +/* $Id: isdn_divert.h,v 1.5.6.1 2001/09/23 22:24:36 kai Exp $ * * Header for the diversion supplementary ioctl interface. * * Copyright 1998 by Werner Cornelius (werner@ikt.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #include <linux/ioctl.h> #include <linux/types.h> diff --git a/drivers/isdn/eicon/Divas_mod.c b/drivers/isdn/eicon/Divas_mod.c index 1293f064f872..3bfa23b57591 100644 --- a/drivers/isdn/eicon/Divas_mod.c +++ b/drivers/isdn/eicon/Divas_mod.c @@ -1,23 +1,9 @@ - /* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #include <linux/config.h> #include <linux/init.h> #include <linux/fs.h> @@ -35,6 +21,10 @@ #include "uxio.h" +MODULE_DESCRIPTION("ISDN4Linux: Driver for Eicon Diva Server cards"); +MODULE_AUTHOR("Armin Schindler"); +MODULE_LICENSE("GPL"); + #ifdef MODULE #include "idi.h" void DIVA_DIDD_Write(DESCRIPTOR *, int); @@ -52,7 +42,6 @@ divas_init(void) printk(KERN_DEBUG "DIVA Server Driver - Version 2.0.16\n"); - #if !defined(CONFIG_PCI) printk(KERN_WARNING "CONFIG_PCI is not defined!\n"); return -ENODEV; diff --git a/drivers/isdn/eicon/adapter.h b/drivers/isdn/eicon/adapter.h index e8a37498c32d..761aebcd5f5b 100644 --- a/drivers/isdn/eicon/adapter.h +++ b/drivers/isdn/eicon/adapter.h @@ -1,29 +1,15 @@ - /* + * Main internal include file for Diva Server driver * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.7 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - -/* Main internal include file for Diva Server driver */ - #if !defined(ADAPTER_H) #define ADAPTER_H diff --git a/drivers/isdn/eicon/bri.c b/drivers/isdn/eicon/bri.c index e03c104d373b..aa56bf85b017 100644 --- a/drivers/isdn/eicon/bri.c +++ b/drivers/isdn/eicon/bri.c @@ -1,23 +1,10 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.8 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/eicon/common.c b/drivers/isdn/eicon/common.c index 014064b22aa6..f2b4d0452139 100644 --- a/drivers/isdn/eicon/common.c +++ b/drivers/isdn/eicon/common.c @@ -1,27 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.15 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #include "eicon.h" #include "sys.h" #include "idi.h" diff --git a/drivers/isdn/eicon/constant.h b/drivers/isdn/eicon/constant.h index f039fd52a7e2..b389cb92b30a 100644 --- a/drivers/isdn/eicon/constant.h +++ b/drivers/isdn/eicon/constant.h @@ -1,28 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.0 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - - /*------------------------------------------------------------------*/ /* Q.931 information elements maximum length */ /* excluding the identifier, including the length field */ diff --git a/drivers/isdn/eicon/divalog.h b/drivers/isdn/eicon/divalog.h index 48c0596b944b..858b66e70e88 100644 --- a/drivers/isdn/eicon/divalog.h +++ b/drivers/isdn/eicon/divalog.h @@ -1,31 +1,15 @@ - /* + * Include file for defining the kernel loggger messages + * These definitions are shared between the klog driver and the + * klogd daemon process * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.0 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* - * Include file for defining the kernel loggger messages - * These definitions are shared between the klog driver and the - * klogd daemon process */ #if !defined(_KLOGMSG_H) diff --git a/drivers/isdn/eicon/divas.h b/drivers/isdn/eicon/divas.h index 3ea401edcd6e..90d45e478fe6 100644 --- a/drivers/isdn/eicon/divas.h +++ b/drivers/isdn/eicon/divas.h @@ -1,29 +1,15 @@ - /* + * External Diva Server driver include file * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.5 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - -/* External Diva Server driver include file */ - #if !defined(DIVAS_H) #define DIVAS_H diff --git a/drivers/isdn/eicon/dsp_defs.h b/drivers/isdn/eicon/dsp_defs.h index 35ab16e67284..20d3c08f3304 100644 --- a/drivers/isdn/eicon/dsp_defs.h +++ b/drivers/isdn/eicon/dsp_defs.h @@ -1,27 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.0 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #ifndef DSP_DEFS_H_ #define DSP_DEFS_H_ diff --git a/drivers/isdn/eicon/dspdids.h b/drivers/isdn/eicon/dspdids.h index 618fda717c88..000a8ba1b2fb 100644 --- a/drivers/isdn/eicon/dspdids.h +++ b/drivers/isdn/eicon/dspdids.h @@ -1,27 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.0 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #ifndef DSPDIDS_H_ #define DSPDIDS_H_ diff --git a/drivers/isdn/eicon/eicon.h b/drivers/isdn/eicon/eicon.h index 23d772561660..77f90cbb87cc 100644 --- a/drivers/isdn/eicon/eicon.h +++ b/drivers/isdn/eicon/eicon.h @@ -1,28 +1,16 @@ -/* $Id: eicon.h,v 1.23.6.4 2001/06/09 15:14:16 kai Exp $ +/* $Id: eicon.h,v 1.23.6.5 2001/09/23 22:24:37 kai Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * - * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) + * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1998-2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #ifndef eicon_h #define eicon_h diff --git a/drivers/isdn/eicon/eicon_dsp.h b/drivers/isdn/eicon/eicon_dsp.h index 1470fa7e6d85..2ccfeb0fb815 100644 --- a/drivers/isdn/eicon/eicon_dsp.h +++ b/drivers/isdn/eicon/eicon_dsp.h @@ -1,25 +1,13 @@ -/* $Id: eicon_dsp.h,v 1.7 2000/05/07 08:51:04 armin Exp $ +/* $Id: eicon_dsp.h,v 1.7.6.1 2001/09/23 22:24:37 kai Exp $ * * ISDN lowlevel-module for Eicon active cards. - * DSP definitions + * DSP definitions * * Copyright 1999,2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/eicon/eicon_idi.c b/drivers/isdn/eicon/eicon_idi.c index 2227a1f954e2..c3786a86d08d 100644 --- a/drivers/isdn/eicon/eicon_idi.c +++ b/drivers/isdn/eicon/eicon_idi.c @@ -1,7 +1,7 @@ -/* $Id: eicon_idi.c,v 1.41.6.2 2001/04/07 21:41:44 armin Exp $ +/* $Id: eicon_idi.c,v 1.41.6.3 2001/09/23 22:24:37 kai Exp $ * * ISDN lowlevel-module for Eicon active cards. - * IDI interface + * IDI interface * * Copyright 1998-2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) @@ -11,19 +11,8 @@ * capabilities with Diva Server cards. * (dor@deutschemailbox.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -36,7 +25,7 @@ #undef EICON_FULL_SERVICE_OKTETT -char *eicon_idi_revision = "$Revision: 1.41.6.2 $"; +char *eicon_idi_revision = "$Revision: 1.41.6.3 $"; eicon_manifbuf *manbuf; diff --git a/drivers/isdn/eicon/eicon_idi.h b/drivers/isdn/eicon/eicon_idi.h index a11039219312..c0cab657b4d9 100644 --- a/drivers/isdn/eicon/eicon_idi.h +++ b/drivers/isdn/eicon/eicon_idi.h @@ -1,4 +1,4 @@ -/* $Id: eicon_idi.h,v 1.11 2000/05/07 08:51:04 armin Exp $ +/* $Id: eicon_idi.h,v 1.11.6.1 2001/09/23 22:24:37 kai Exp $ * * ISDN lowlevel-module for the Eicon active cards. * IDI-Interface @@ -6,20 +6,8 @@ * Copyright 1998-2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/eicon/eicon_io.c b/drivers/isdn/eicon/eicon_io.c index f21a045c247e..ff61c5f10c5a 100644 --- a/drivers/isdn/eicon/eicon_io.c +++ b/drivers/isdn/eicon/eicon_io.c @@ -1,4 +1,4 @@ -/* $Id: eicon_io.c,v 1.13.6.1 2001/02/16 09:09:50 armin Exp $ +/* $Id: eicon_io.c,v 1.13.6.2 2001/09/23 22:24:37 kai Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * Code for communicating with hardware. @@ -6,26 +6,14 @@ * Copyright 1999,2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * * Thanks to Eicon Networks for * documents, informations and hardware. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * */ - #include <linux/config.h> #include "eicon.h" #include "uxio.h" diff --git a/drivers/isdn/eicon/eicon_isa.c b/drivers/isdn/eicon/eicon_isa.c index 1d2ece7cd938..1feffef7eba3 100644 --- a/drivers/isdn/eicon/eicon_isa.c +++ b/drivers/isdn/eicon/eicon_isa.c @@ -1,4 +1,4 @@ -/* $Id: eicon_isa.c,v 1.16 2000/06/12 12:44:02 armin Exp $ +/* $Id: eicon_isa.c,v 1.16.6.1 2001/09/23 22:24:37 kai Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * Hardware-specific code for old ISA cards. @@ -7,19 +7,8 @@ * Copyright 1998-2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -31,7 +20,7 @@ #define release_shmem release_region #define request_shmem request_region -char *eicon_isa_revision = "$Revision: 1.16 $"; +char *eicon_isa_revision = "$Revision: 1.16.6.1 $"; #undef EICON_MCA_DEBUG diff --git a/drivers/isdn/eicon/eicon_isa.h b/drivers/isdn/eicon/eicon_isa.h index 1c8034f77786..7502aabecb8c 100644 --- a/drivers/isdn/eicon/eicon_isa.h +++ b/drivers/isdn/eicon/eicon_isa.h @@ -1,4 +1,4 @@ -/* $Id: eicon_isa.h,v 1.10 2000/05/07 08:51:04 armin Exp $ +/* $Id: eicon_isa.h,v 1.10.6.1 2001/09/23 22:24:37 kai Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * @@ -6,19 +6,8 @@ * Copyright 1998-2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/eicon/eicon_mod.c b/drivers/isdn/eicon/eicon_mod.c index 8efd798505a9..b7c0adb47e33 100644 --- a/drivers/isdn/eicon/eicon_mod.c +++ b/drivers/isdn/eicon/eicon_mod.c @@ -1,4 +1,4 @@ -/* $Id: eicon_mod.c,v 1.37.6.5 2001/07/17 19:42:31 armin Exp $ +/* $Id: eicon_mod.c,v 1.37.6.6 2001/09/23 22:24:37 kai Exp $ * * ISDN lowlevel-module for Eicon active cards. * @@ -6,6 +6,9 @@ * Copyright 1998-2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * * Thanks to Eicon Networks for * documents, informations and hardware. * @@ -14,20 +17,6 @@ * capabilities with Diva Server cards. * (dor@deutschemailbox.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * */ #define DRIVERNAME "Eicon active ISDN driver" @@ -55,7 +44,7 @@ static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains start of card-list */ -static char *eicon_revision = "$Revision: 1.37.6.5 $"; +static char *eicon_revision = "$Revision: 1.37.6.6 $"; extern char *eicon_pci_revision; extern char *eicon_isa_revision; @@ -84,9 +73,9 @@ static int irq = -1; #endif static char *id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -MODULE_DESCRIPTION( "Driver for Eicon active ISDN cards"); +MODULE_DESCRIPTION( "ISDN4Linux: Driver for Eicon active ISDN cards"); MODULE_AUTHOR( "Armin Schindler"); -MODULE_SUPPORTED_DEVICE( "ISDN subsystem"); +MODULE_LICENSE( "GPL"); MODULE_PARM_DESC(id, "ID-String of first card"); MODULE_PARM(id, "s"); #ifdef CONFIG_ISDN_DRV_EICON_ISA diff --git a/drivers/isdn/eicon/eicon_pci.c b/drivers/isdn/eicon/eicon_pci.c index 8d5b60f98b78..69c0a0b790a6 100644 --- a/drivers/isdn/eicon/eicon_pci.c +++ b/drivers/isdn/eicon/eicon_pci.c @@ -1,4 +1,4 @@ -/* $Id: eicon_pci.c,v 1.15.6.2 2001/02/16 09:09:50 armin Exp $ +/* $Id: eicon_pci.c,v 1.15.6.3 2001/09/23 22:24:37 kai Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * Hardware-specific code for PCI cards. @@ -6,23 +6,12 @@ * Copyright 1998-2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * * Thanks to Eicon Networks for * documents, informations and hardware. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * */ #include <linux/config.h> @@ -35,7 +24,7 @@ #include "adapter.h" #include "uxio.h" -char *eicon_pci_revision = "$Revision: 1.15.6.2 $"; +char *eicon_pci_revision = "$Revision: 1.15.6.3 $"; #if CONFIG_PCI /* intire stuff is only for PCI */ #ifdef CONFIG_ISDN_DRV_EICON_PCI diff --git a/drivers/isdn/eicon/eicon_pci.h b/drivers/isdn/eicon/eicon_pci.h index 17fd4183a7a9..7e615c6f3e0b 100644 --- a/drivers/isdn/eicon/eicon_pci.h +++ b/drivers/isdn/eicon/eicon_pci.h @@ -1,23 +1,12 @@ -/* $Id: eicon_pci.h,v 1.6 2000/05/07 08:51:04 armin Exp $ +/* $Id: eicon_pci.h,v 1.6.6.1 2001/09/23 22:24:37 kai Exp $ * * ISDN low-level module for Eicon active ISDN-Cards (PCI part). * * Copyright 1998-2000 by Armin Schindler (mac@melware.de) * Copyright 1999,2000 Cytronics & Melware (info@melware.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/eicon/fourbri.c b/drivers/isdn/eicon/fourbri.c index 0efb16fed1d4..42c4c0a09561 100644 --- a/drivers/isdn/eicon/fourbri.c +++ b/drivers/isdn/eicon/fourbri.c @@ -1,28 +1,15 @@ - /* + * Diva Server 4BRI specific part of initialisation * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.7 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - -/* Diva Server 4BRI specific part of initialisation */ #include "sys.h" #include "idi.h" #include "divas.h" diff --git a/drivers/isdn/eicon/fpga.c b/drivers/isdn/eicon/fpga.c index dda2f1ae07eb..be858533804b 100644 --- a/drivers/isdn/eicon/fpga.c +++ b/drivers/isdn/eicon/fpga.c @@ -1,27 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.2 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #include "sys.h" #include "idi.h" #include "uxio.h" diff --git a/drivers/isdn/eicon/idi.c b/drivers/isdn/eicon/idi.c index 62b4342f70d8..6167db1cdb87 100644 --- a/drivers/isdn/eicon/idi.c +++ b/drivers/isdn/eicon/idi.c @@ -1,30 +1,14 @@ - /* + * Core driver for Diva Server cards + * Implements the IDI interface * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.8 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* - * Core driver for Diva Server cards - * Implements the IDI interface */ #include "idi.h" diff --git a/drivers/isdn/eicon/idi.h b/drivers/isdn/eicon/idi.h index eda433110984..2dde67d2502d 100644 --- a/drivers/isdn/eicon/idi.h +++ b/drivers/isdn/eicon/idi.h @@ -1,29 +1,15 @@ - /* + * External IDI interface * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.0 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - -/* External IDI interface */ - #if !defined(IDI_H) #define IDI_H diff --git a/drivers/isdn/eicon/kprintf.c b/drivers/isdn/eicon/kprintf.c index 3357bca2666a..a21d66cc5262 100644 --- a/drivers/isdn/eicon/kprintf.c +++ b/drivers/isdn/eicon/kprintf.c @@ -1,32 +1,15 @@ - /* + * Source file for kernel interface to kernel log facility * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.3 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* - * Source file for kernel interface to kernel log facility */ - #include "eicon.h" #include "sys.h" #include <stdarg.h> diff --git a/drivers/isdn/eicon/lincfg.c b/drivers/isdn/eicon/lincfg.c index 58bdc5613f1e..92d9e891f2e2 100644 --- a/drivers/isdn/eicon/lincfg.c +++ b/drivers/isdn/eicon/lincfg.c @@ -1,27 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.9 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #include <linux/fs.h> #undef N_DATA /* Because we have our own definition */ diff --git a/drivers/isdn/eicon/linchr.c b/drivers/isdn/eicon/linchr.c index 017a85aca479..a2edf3839c77 100644 --- a/drivers/isdn/eicon/linchr.c +++ b/drivers/isdn/eicon/linchr.c @@ -1,23 +1,10 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.12 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/eicon/linio.c b/drivers/isdn/eicon/linio.c index a00321c0b73f..b20057bb279d 100644 --- a/drivers/isdn/eicon/linio.c +++ b/drivers/isdn/eicon/linio.c @@ -1,27 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.16 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #define N_DATA #include <asm/io.h> diff --git a/drivers/isdn/eicon/linsys.c b/drivers/isdn/eicon/linsys.c index 3288f2983153..14b0dab638e2 100644 --- a/drivers/isdn/eicon/linsys.c +++ b/drivers/isdn/eicon/linsys.c @@ -1,27 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.10 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #include <linux/sched.h> #undef N_DATA #include <linux/tqueue.h> diff --git a/drivers/isdn/eicon/log.c b/drivers/isdn/eicon/log.c index b292adf50650..aa27e631a279 100644 --- a/drivers/isdn/eicon/log.c +++ b/drivers/isdn/eicon/log.c @@ -1,29 +1,13 @@ - /* + * Source file for diva log facility * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.5 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* - * Source file for diva log facility */ #include "sys.h" diff --git a/drivers/isdn/eicon/pc.h b/drivers/isdn/eicon/pc.h index 1adfe4dac4bc..1e20fc33b226 100644 --- a/drivers/isdn/eicon/pc.h +++ b/drivers/isdn/eicon/pc.h @@ -1,27 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.2 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #ifndef PC_H_INCLUDED #define PC_H_INCLUDED diff --git a/drivers/isdn/eicon/pc_maint.h b/drivers/isdn/eicon/pc_maint.h index f6fa6733dc04..660db8ec62ff 100644 --- a/drivers/isdn/eicon/pc_maint.h +++ b/drivers/isdn/eicon/pc_maint.h @@ -1,27 +1,13 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.0 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - #ifndef PC_MAINT_H #define PC_MAINT_H diff --git a/drivers/isdn/eicon/pr_pc.h b/drivers/isdn/eicon/pr_pc.h index 7634c7b7da94..3d79cc8c3cb8 100644 --- a/drivers/isdn/eicon/pr_pc.h +++ b/drivers/isdn/eicon/pr_pc.h @@ -1,23 +1,10 @@ - /* - * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.0 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/eicon/pri.c b/drivers/isdn/eicon/pri.c index ee15449742ac..e240cdda5847 100644 --- a/drivers/isdn/eicon/pri.c +++ b/drivers/isdn/eicon/pri.c @@ -1,28 +1,15 @@ - /* + * Diva Server PRI specific part of initialisation * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.5 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - -/* Diva Server PRI specific part of initialisation */ #include "sys.h" #include "idi.h" #include "divas.h" diff --git a/drivers/isdn/eicon/sys.h b/drivers/isdn/eicon/sys.h index 3a69dbba063e..d789237d5729 100644 --- a/drivers/isdn/eicon/sys.h +++ b/drivers/isdn/eicon/sys.h @@ -1,29 +1,15 @@ - /* + * Environment provided by system and miscellaneous definitions * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.2 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - -/* Environment provided by system and miscellaneous definitions */ - #if !defined(SYS_H) #define SYS_H diff --git a/drivers/isdn/eicon/uxio.h b/drivers/isdn/eicon/uxio.h index 449f1a7d0ee9..0a261dc0b5d9 100644 --- a/drivers/isdn/eicon/uxio.h +++ b/drivers/isdn/eicon/uxio.h @@ -1,29 +1,13 @@ - /* + * Interface to Unix specific code for performing card I/O * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.6 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* - * Interface to Unix specific code for performing card I/O */ #if !defined(UXIO_H) diff --git a/drivers/isdn/eicon/xlog.c b/drivers/isdn/eicon/xlog.c index 0dd9c123f163..3312842208e1 100644 --- a/drivers/isdn/eicon/xlog.c +++ b/drivers/isdn/eicon/xlog.c @@ -1,30 +1,14 @@ - /* + * Unix Eicon active card driver + * XLOG related functions * * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision : 1.2 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* - * Unix Eicon active card driver - * XLOG related functions */ #include "sys.h" diff --git a/drivers/isdn/hisax/amd7930.c b/drivers/isdn/hisax/amd7930.c index c6cf3dd2df05..4ba74c9e4933 100644 --- a/drivers/isdn/hisax/amd7930.c +++ b/drivers/isdn/hisax/amd7930.c @@ -1,8 +1,12 @@ -/* $Id: amd7930.c,v 1.5.6.3 2001/06/11 22:08:37 kai Exp $ +/* $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 (baccala@FreeSoft.org) + * Author Brent Baccala + * Copyright by Brent Baccala <baccala@FreeSoft.org> + * + * 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 @@ -94,7 +98,7 @@ #include "rawhdlc.h" #include <linux/interrupt.h> -static const char *amd7930_revision = "$Revision: 1.5.6.3 $"; +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 diff --git a/drivers/isdn/hisax/arcofi.c b/drivers/isdn/hisax/arcofi.c index 11154150db85..640ee8378eb0 100644 --- a/drivers/isdn/hisax/arcofi.c +++ b/drivers/isdn/hisax/arcofi.c @@ -1,10 +1,12 @@ -/* $Id: arcofi.c,v 1.12.6.1 2001/02/16 16:43:25 kai Exp $ +/* $Id: arcofi.c,v 1.12.6.2 2001/09/23 22:24:46 kai Exp $ * - * arcofi.c Ansteuerung ARCOFI 2165 + * Ansteuerung ARCOFI 2165 * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/arcofi.h b/drivers/isdn/hisax/arcofi.h index badf9f01000f..00c44d3ce972 100644 --- a/drivers/isdn/hisax/arcofi.h +++ b/drivers/isdn/hisax/arcofi.h @@ -1,10 +1,12 @@ -/* $Id: arcofi.h,v 1.6.6.1 2001/02/16 16:43:25 kai Exp $ +/* $Id: arcofi.h,v 1.6.6.2 2001/09/23 22:24:46 kai Exp $ * - * arcofi.h Ansteuerung ARCOFI 2165 + * Ansteuerung ARCOFI 2165 * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c index f92ee9af0017..abca6000b983 100644 --- a/drivers/isdn/hisax/asuscom.c +++ b/drivers/isdn/hisax/asuscom.c @@ -1,12 +1,14 @@ -/* $Id: asuscom.c,v 1.11.6.2 2001/07/13 09:20:12 kai Exp $ +/* $Id: asuscom.c,v 1.11.6.3 2001/09/23 22:24:46 kai Exp $ * - * asuscom.c low level stuff for ASUSCOM NETWORK INC. ISDNLink cards + * low level stuff for ASUSCOM NETWORK INC. ISDNLink cards * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> * - * Thanks to ASUSCOM NETWORK INC. Taiwan and Dynalink NL for informations + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License + * Thanks to ASUSCOM NETWORK INC. Taiwan and Dynalink NL for information * */ @@ -20,7 +22,7 @@ extern const char *CardType[]; -const char *Asuscom_revision = "$Revision: 1.11.6.2 $"; +const char *Asuscom_revision = "$Revision: 1.11.6.3 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/avm_a1.c b/drivers/isdn/hisax/avm_a1.c index 66126727f50b..5feebd23be2b 100644 --- a/drivers/isdn/hisax/avm_a1.c +++ b/drivers/isdn/hisax/avm_a1.c @@ -1,12 +1,15 @@ -/* $Id: avm_a1.c,v 2.13.6.1 2001/02/16 16:43:25 kai Exp $ +/* $Id: avm_a1.c,v 2.13.6.2 2001/09/23 22:24:46 kai Exp $ * - * avm_a1.c low level stuff for AVM A1 (Fritz) isdn cards + * low level stuff for AVM A1 (Fritz) isdn cards * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #define __NO_VERSION__ #include <linux/init.h> #include "hisax.h" @@ -15,7 +18,7 @@ #include "isdnl1.h" extern const char *CardType[]; -static const char *avm_revision = "$Revision: 2.13.6.1 $"; +static const char *avm_revision = "$Revision: 2.13.6.2 $"; #define AVM_A1_STAT_ISAC 0x01 #define AVM_A1_STAT_HSCX 0x02 diff --git a/drivers/isdn/hisax/avm_a1p.c b/drivers/isdn/hisax/avm_a1p.c index f726af636627..fa39db5a9bab 100644 --- a/drivers/isdn/hisax/avm_a1p.c +++ b/drivers/isdn/hisax/avm_a1p.c @@ -1,14 +1,18 @@ -/* $Id: avm_a1p.c,v 2.7.6.1 2001/02/16 16:43:25 kai Exp $ +/* $Id: avm_a1p.c,v 2.7.6.2 2001/09/23 22:24:46 kai Exp $ * - * avm_a1p.c low level stuff for the following AVM cards: - * A1 PCMCIA - * FRITZ!Card PCMCIA - * FRITZ!Card PCMCIA 2.0 + * low level stuff for the following AVM cards: + * A1 PCMCIA + * FRITZ!Card PCMCIA + * FRITZ!Card PCMCIA 2.0 * - * Author Carsten Paeth (calle@calle.in-berlin.de) + * Author Carsten Paeth + * Copyright by Carsten Paeth <calle@calle.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License */ + #define __NO_VERSION__ #include <linux/init.h> #include "hisax.h" @@ -53,7 +57,7 @@ #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) -static const char *avm_revision = "$Revision: 2.7.6.1 $"; +static const char *avm_revision = "$Revision: 2.7.6.2 $"; static inline u_char ReadISAC(struct IsdnCardState *cs, u_char offset) diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index f4b13f07bcf7..9215b06ae57c 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -1,13 +1,17 @@ -/* $Id: avm_pci.c,v 1.22.6.5 2001/06/09 15:14:16 kai Exp $ +/* $Id: avm_pci.c,v 1.22.6.6 2001/09/23 22:24:46 kai Exp $ * - * avm_pci.c low level stuff for AVM Fritz!PCI and ISA PnP isdn cards - * Thanks to AVM, Berlin for informations + * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * Thanks to AVM, Berlin for information * */ + #define __NO_VERSION__ #include <linux/config.h> #include <linux/init.h> @@ -18,7 +22,7 @@ #include <linux/interrupt.h> extern const char *CardType[]; -static const char *avm_pci_rev = "$Revision: 1.22.6.5 $"; +static const char *avm_pci_rev = "$Revision: 1.22.6.6 $"; #define AVM_FRITZ_PCI 1 #define AVM_FRITZ_PNP 2 diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c index e4231124970e..7fc219b97f23 100644 --- a/drivers/isdn/hisax/bkm_a4t.c +++ b/drivers/isdn/hisax/bkm_a4t.c @@ -1,12 +1,12 @@ -/* $Id: bkm_a4t.c,v 1.13.6.5 2001/07/18 16:02:15 kai Exp $ - * bkm_a4t.c low level stuff for T-Berkom A4T - * derived from the original file sedlbauer.c - * derived from the original file niccy.c - * derived from the original file netjet.c +/* $Id: bkm_a4t.c,v 1.13.6.6 2001/09/23 22:24:46 kai Exp $ * - * Author Roland Klabunde (R.Klabunde@Berkom.de) + * low level stuff for T-Berkom A4T * - * This file is (c) under GNU General Public License + * Author Roland Klabunde + * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -24,7 +24,7 @@ extern const char *CardType[]; -const char *bkm_a4t_revision = "$Revision: 1.13.6.5 $"; +const char *bkm_a4t_revision = "$Revision: 1.13.6.6 $"; static inline u_char diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c index 68daf48ec5f6..26d1e8e9e6a4 100644 --- a/drivers/isdn/hisax/bkm_a8.c +++ b/drivers/isdn/hisax/bkm_a8.c @@ -1,14 +1,15 @@ -/* $Id: bkm_a8.c,v 1.14.6.6 2001/07/18 16:02:15 kai Exp $ - * bkm_a8.c low level stuff for Scitel Quadro (4*S0, passive) - * derived from the original file sedlbauer.c - * derived from the original file niccy.c - * derived from the original file netjet.c +/* $Id: bkm_a8.c,v 1.14.6.7 2001/09/23 22:24:46 kai Exp $ * - * Author Roland Klabunde (R.Klabunde@Berkom.de) + * low level stuff for Scitel Quadro (4*S0, passive) * - * This file is (c) under GNU General Public License + * Author Roland Klabunde + * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #define __NO_VERSION__ #include <linux/config.h> @@ -27,7 +28,7 @@ extern const char *CardType[]; -const char sct_quadro_revision[] = "$Revision: 1.14.6.6 $"; +const char sct_quadro_revision[] = "$Revision: 1.14.6.7 $"; static const char *sct_quadro_subtypes[] = { diff --git a/drivers/isdn/hisax/bkm_ax.h b/drivers/isdn/hisax/bkm_ax.h index 17cab1215c2f..029e0a277661 100644 --- a/drivers/isdn/hisax/bkm_ax.h +++ b/drivers/isdn/hisax/bkm_ax.h @@ -1,9 +1,12 @@ -/* $Id: bkm_ax.h,v 1.5.6.2 2001/02/16 16:43:25 kai Exp $ - * bkm_ax.h low level decls for T-Berkom cards A4T and Scitel Quadro (4*S0, passive) +/* $Id: bkm_ax.h,v 1.5.6.3 2001/09/23 22:24:46 kai Exp $ * - * Author Roland Klabunde (R.Klabunde@Berkom.de) + * low level decls for T-Berkom cards A4T and Scitel Quadro (4*S0, passive) * - * This file is (c) under GNU General Public License + * Author Roland Klabunde + * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index 66087a18e119..47cee5b06810 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c @@ -1,17 +1,23 @@ -/* $Id: callc.c,v 2.51.6.5 2001/08/23 19:44:23 kai Exp $ +/* $Id: callc.c,v 2.51.6.6 2001/09/23 22:24:46 kai Exp $ * - * Author Karsten Keil (keil@isdn4linux.de) - * based on the teles driver from Jan den Ouden + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert + * + * based on the teles driver from Jan den Ouden * * Thanks to Jan den Ouden * Fritz Elfert * */ + #define __NO_VERSION__ +#include <linux/module.h> #include <linux/init.h> #include "hisax.h" #include "../avmb1/capicmd.h" /* this should be moved in a common place */ @@ -20,7 +26,7 @@ #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module)) #endif /* MODULE */ -const char *lli_revision = "$Revision: 2.51.6.5 $"; +const char *lli_revision = "$Revision: 2.51.6.6 $"; extern struct IsdnCard cards[]; extern int nrcards; diff --git a/drivers/isdn/hisax/cert.c b/drivers/isdn/hisax/cert.c index af7c4e14c477..d30048be976c 100644 --- a/drivers/isdn/hisax/cert.c +++ b/drivers/isdn/hisax/cert.c @@ -1,10 +1,13 @@ -/* $Id: cert.c,v 2.3.6.2 2001/07/27 09:08:27 kai Exp $ +/* $Id: cert.c,v 2.3.6.3 2001/09/23 22:24:47 kai Exp $ * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * */ diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 7a2db6d34384..0af9a604c049 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -1,11 +1,19 @@ -/* $Id: config.c,v 2.57.6.18 2001/08/27 22:19:05 kai Exp $ +/* $Id: config.c,v 2.57.6.20 2001/09/23 22:24:47 kai Exp $ * - * Author Karsten Keil (keil@isdn4linux.de) - * based on the teles driver from Jan den Ouden + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * by Kai Germaschewski <kai.germaschewski@gmx.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert + * + * based on the teles driver from Jan den Ouden * */ + #include <linux/types.h> #include <linux/stddef.h> #include <linux/timer.h> @@ -365,7 +373,9 @@ static int irq[8] __devinitdata = { 0, }; static int mem[8] __devinitdata = { 0, }; static char *id __devinitdata = HiSaxID; +MODULE_DESCRIPTION("ISDN4Linux: Driver for passive ISDN cards"); MODULE_AUTHOR("Karsten Keil"); +MODULE_LICENSE("GPL"); MODULE_PARM(type, "1-8i"); MODULE_PARM(protocol, "1-8i"); MODULE_PARM(io, "1-8i"); diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 0089c40fab78..02478dc5e3ab 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -1,14 +1,17 @@ -/* $Id: diva.c,v 1.25.6.4 2001/02/16 16:43:25 kai Exp $ +/* $Id: diva.c,v 1.25.6.5 2001/09/23 22:24:47 kai Exp $ * - * diva.c low level stuff for Eicon.Diehl Diva Family ISDN cards + * low level stuff for Eicon.Diehl Diva Family ISDN cards * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * - * Thanks to Eicon Technology for documents and informations + * Thanks to Eicon Technology for documents and information * */ @@ -24,7 +27,7 @@ extern const char *CardType[]; -const char *Diva_revision = "$Revision: 1.25.6.4 $"; +const char *Diva_revision = "$Revision: 1.25.6.5 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index 0d3b99d188ca..7fdeb01c955b 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c @@ -1,14 +1,17 @@ -/* $Id: elsa.c,v 2.26.6.5 2001/07/18 16:25:12 kai Exp $ +/* $Id: elsa.c,v 2.26.6.6 2001/09/23 22:24:47 kai Exp $ * - * elsa.c low level stuff for Elsa isdn cards + * low level stuff for Elsa isdn cards * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * - * Thanks to Elsa GmbH for documents and informations + * Thanks to Elsa GmbH for documents and information * * Klaus Lichtenwalder (Klaus.Lichtenwalder@WebForum.DE) * for ELSA PCMCIA support @@ -30,7 +33,7 @@ extern const char *CardType[]; -const char *Elsa_revision = "$Revision: 2.26.6.5 $"; +const char *Elsa_revision = "$Revision: 2.26.6.6 $"; const char *Elsa_Types[] = {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro", "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index 4fb4cc1d0af1..b79f67749311 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -4,6 +4,7 @@ This driver is for the Elsa PCM ISDN Cards, i.e. the MicroLink + The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of @@ -21,6 +22,17 @@ Modifications from dummy_cs.c are Copyright (C) 1999-2001 Klaus Lichtenwalder <Lichtenwalder@ACM.org>. All Rights Reserved. + Alternatively, the contents of this file may be used under the + terms of the GNU General Public License version 2 (the "GPL"), in + which case the provisions of the GPL are applicable instead of the + above. If you wish to allow the use of your version of this file + only under the terms of the GPL and not to allow others to use + your version of this file under the MPL, indicate your decision + by deleting the provisions above and replace them with the notice + and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this + file under either the MPL or the GPL. + ======================================================================*/ #include <linux/module.h> @@ -43,6 +55,10 @@ #include <pcmcia/ds.h> #include <pcmcia/bus_ops.h> +MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards"); +MODULE_AUTHOR("Klaus Lichtenwalder"); +MODULE_LICENSE("Dual MPL/GPL"); + /* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If you do not define PCMCIA_DEBUG at all, all the debug code will be @@ -56,7 +72,7 @@ static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); static char *version = -"elsa_cs.c $Revision: 1.1.2.1 $ $Date: 2001/04/15 08:01:34 $ (K.Lichtenwalder)"; +"elsa_cs.c $Revision: 1.1.2.2 $ $Date: 2001/09/23 22:24:47 $ (K.Lichtenwalder)"; #else #define DEBUG(n, args...) #endif diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c index 62f1bf4ac7c7..87783425773f 100644 --- a/drivers/isdn/hisax/elsa_ser.c +++ b/drivers/isdn/hisax/elsa_ser.c @@ -1,10 +1,12 @@ -/* $Id: elsa_ser.c,v 2.10.6.3 2001/08/17 12:34:26 kai Exp $ +/* $Id: elsa_ser.c,v 2.10.6.4 2001/09/23 22:24:47 kai Exp $ * * stuff for the serial modem on ELSA cards * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #include <linux/config.h> #include <linux/serial.h> #include <linux/serial_reg.h> diff --git a/drivers/isdn/hisax/fsm.c b/drivers/isdn/hisax/fsm.c index 423306a057f5..630e2704993d 100644 --- a/drivers/isdn/hisax/fsm.c +++ b/drivers/isdn/hisax/fsm.c @@ -1,15 +1,21 @@ -/* $Id: fsm.c,v 1.14.6.3 2001/08/23 19:44:23 kai Exp $ +/* $Id: fsm.c,v 1.14.6.4 2001/09/23 22:24:47 kai Exp $ * - * Author Karsten Keil (keil@isdn4linux.de) - * based on the teles driver from Jan den Ouden + * Finite state machine + * + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * by Kai Germaschewski <kai.germaschewski@gmx.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * * Thanks to Jan den Ouden * Fritz Elfert * - * This file is (c) under GNU General Public License - * */ + #define __NO_VERSION__ +#include <linux/module.h> #include <linux/init.h> #include "hisax.h" diff --git a/drivers/isdn/hisax/fsm.h b/drivers/isdn/hisax/fsm.h index 3a77d1eabdd0..f02f7da1688d 100644 --- a/drivers/isdn/hisax/fsm.h +++ b/drivers/isdn/hisax/fsm.h @@ -1,3 +1,16 @@ +/* $Id: fsm.h,v 1.3.2.2 2001/09/23 22:24:47 kai Exp $ + * + * Finite state machine + * + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * by Kai Germaschewski <kai.germaschewski@gmx.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ + #ifndef __FSM_H__ #define __FSM_H__ diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c index ef41f52393d0..0cdd30860b67 100644 --- a/drivers/isdn/hisax/gazel.c +++ b/drivers/isdn/hisax/gazel.c @@ -1,13 +1,16 @@ -/* $Id: gazel.c,v 2.11.6.6 2001/06/08 08:48:46 kai Exp $ +/* $Id: gazel.c,v 2.11.6.7 2001/09/23 22:24:47 kai Exp $ * - * gazel.c low level stuff for Gazel isdn cards + * low level stuff for Gazel isdn cards * * Author BeWan Systems * based on source code from Karsten Keil - * - * This file is (c) under GNU General Public License + * Copyright by BeWan Systems + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #include <linux/config.h> #include <linux/init.h> #define __NO_VERSION__ @@ -19,7 +22,7 @@ #include <linux/pci.h> extern const char *CardType[]; -const char *gazel_revision = "$Revision: 2.11.6.6 $"; +const char *gazel_revision = "$Revision: 2.11.6.7 $"; #define R647 1 #define R685 2 diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c index b33dedaaaae1..cb8eb837f5c2 100644 --- a/drivers/isdn/hisax/hfc_2bds0.c +++ b/drivers/isdn/hisax/hfc_2bds0.c @@ -1,12 +1,15 @@ -/* $Id: hfc_2bds0.c,v 1.15.6.2 2001/06/09 15:14:17 kai Exp $ +/* $Id: hfc_2bds0.c,v 1.15.6.3 2001/09/23 22:24:47 kai Exp $ * - * specific routines for CCD's HFC 2BDS0 + * specific routines for CCD's HFC 2BDS0 * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #define __NO_VERSION__ #include <linux/init.h> #include "hisax.h" diff --git a/drivers/isdn/hisax/hfc_2bds0.h b/drivers/isdn/hisax/hfc_2bds0.h index 7bb8f4dee209..15a4e370ab93 100644 --- a/drivers/isdn/hisax/hfc_2bds0.h +++ b/drivers/isdn/hisax/hfc_2bds0.h @@ -1,10 +1,12 @@ -/* $Id: hfc_2bds0.h,v 1.4.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: hfc_2bds0.h,v 1.4.6.2 2001/09/23 22:24:47 kai Exp $ * - * specific defines for CCD's HFC 2BDS0 + * specific defines for CCD's HFC 2BDS0 * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c index bd3167f4d569..e329f0480d0f 100644 --- a/drivers/isdn/hisax/hfc_2bs0.c +++ b/drivers/isdn/hisax/hfc_2bs0.c @@ -1,10 +1,12 @@ -/* $Id: hfc_2bs0.c,v 1.17.6.2 2001/06/09 15:14:17 kai Exp $ +/* $Id: hfc_2bs0.c,v 1.17.6.3 2001/09/23 22:24:47 kai Exp $ * - * specific routines for CCD's HFC 2BS0 + * specific routines for CCD's HFC 2BS0 * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/hfc_2bs0.h b/drivers/isdn/hisax/hfc_2bs0.h index f8f6391f3285..34513adcacd4 100644 --- a/drivers/isdn/hisax/hfc_2bs0.h +++ b/drivers/isdn/hisax/hfc_2bs0.h @@ -1,10 +1,12 @@ -/* $Id: hfc_2bs0.h,v 1.3.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: hfc_2bs0.h,v 1.3.6.2 2001/09/23 22:24:47 kai Exp $ * - * specific defines for CCD's HFC 2BS0 + * specific defines for CCD's HFC 2BS0 * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 9a7c82103620..eb5cf7de2d69 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -1,27 +1,17 @@ -/* $Id: hfc_pci.c,v 1.34.6.7 2001/07/27 09:08:27 kai Exp $ - - * hfc_pci.c low level driver for CCD´s hfc-pci based cards - * - * Author Werner Cornelius (werner@isdn4linux.de) - * based on existing driver for CCD hfc ISA cards - * type approval valid for HFC-S PCI A based card - * - * Copyright 1999 by Werner Cornelius (werner@isdn-development.de) - * Copyright 1999 by Karsten Keil (keil@isdn4linux.de) +/* $Id: hfc_pci.c,v 1.34.6.8 2001/09/23 22:24:47 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * low level driver for CCD´s hfc-pci based cards * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius + * based on existing driver for CCD hfc ISA cards + * Copyright by Werner Cornelius <werner@isdn4linux.de> + * by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * */ @@ -36,7 +26,7 @@ extern const char *CardType[]; -static const char *hfcpci_revision = "$Revision: 1.34.6.7 $"; +static const char *hfcpci_revision = "$Revision: 1.34.6.8 $"; /* table entry in the PCI devices list */ typedef struct { @@ -84,7 +74,7 @@ static const PCI_ENTRY id_list[] = void release_io_hfcpci(struct IsdnCardState *cs) { - long flags; + unsigned long flags; save_flags(flags); cli(); @@ -299,7 +289,7 @@ hfcpci_empty_fifo(struct BCState *bcs, bzfifo_type * bz, u_char * bdata, int cou u_char *ptr, *ptr1, new_f2; struct sk_buff *skb; struct IsdnCardState *cs = bcs->cs; - long flags; + unsigned long flags; int total, maxlen, new_z2; z_type *zp; @@ -634,7 +624,7 @@ static void hfcpci_fill_fifo(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; - long flags; + unsigned long flags; int maxlen, fcnt; int count, new_z1; bzfifo_type *bz; @@ -812,7 +802,7 @@ dch_nt_l2l1(struct PStack *st, int pr, void *arg) static int hfcpci_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic) { - long flags; + unsigned long flags; int i = *(unsigned int *) ic->parm.num; if ((ic->arg == 98) && @@ -1162,7 +1152,7 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; - long flags; + unsigned long flags; switch (pr) { case (PH_DATA | REQUEST): @@ -1316,7 +1306,7 @@ void mode_hfcpci(struct BCState *bcs, int mode, int bc) { struct IsdnCardState *cs = bcs->cs; - long flags; + unsigned long flags; int fifo2; if (cs->debug & L1_DEB_HSCX) @@ -1551,7 +1541,7 @@ setstack_2b(struct PStack *st, struct BCState *bcs) static void hfcpci_bh(struct IsdnCardState *cs) { - long flags; + unsigned long flags; /* struct PStack *stptr; */ if (!cs) diff --git a/drivers/isdn/hisax/hfc_pci.h b/drivers/isdn/hisax/hfc_pci.h index 136eb20517aa..32e59e31028f 100644 --- a/drivers/isdn/hisax/hfc_pci.h +++ b/drivers/isdn/hisax/hfc_pci.h @@ -1,24 +1,12 @@ -/* $Id: hfc_pci.h,v 1.8.6.1 2001/04/08 19:32:26 kai Exp $ +/* $Id: hfc_pci.h,v 1.8.6.2 2001/09/23 22:24:48 kai Exp $ * - * specific defines for CCD's HFC 2BDS0 PCI chips + * specific defines for CCD's HFC 2BDS0 PCI chips * - * Author Werner Cornelius (werner@isdn4linux.de) - * - * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Author Werner Cornelius + * Copyright by Werner Cornelius <werner@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index aecbb7398457..ad9690ff010e 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -1,25 +1,13 @@ -/* $Id: hfc_sx.c,v 1.9.6.2 2001/07/18 16:25:12 kai Exp $ - - * hfc_sx.c low level driver for CCD´s hfc-s+/sp based cards - * - * Author Werner Cornelius (werner@isdn4linux.de) - * based on existing driver for CCD HFC PCI cards - * - * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) +/* $Id: hfc_sx.c,v 1.9.6.3 2001/09/23 22:24:48 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * level driver for CCD´s hfc-s+/sp based cards * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Author Werner Cornelius + * based on existing driver for CCD HFC PCI cards + * Copyright by Werner Cornelius <werner@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -32,7 +20,7 @@ extern const char *CardType[]; -static const char *hfcsx_revision = "$Revision: 1.9.6.2 $"; +static const char *hfcsx_revision = "$Revision: 1.9.6.3 $"; /***************************************/ /* IRQ-table for CCDs demo board */ @@ -73,7 +61,7 @@ static u_char ccd_sp_irqtab[16] = { /******************************/ static inline void Write_hfc(struct IsdnCardState *cs, u_char regnum, u_char val) -{ long flags; +{ unsigned long flags; save_flags(flags); cli(); @@ -84,7 +72,7 @@ Write_hfc(struct IsdnCardState *cs, u_char regnum, u_char val) static inline u_char Read_hfc(struct IsdnCardState *cs, u_char regnum) -{ long flags; +{ unsigned long flags; u_char ret; save_flags(flags); @@ -101,7 +89,7 @@ Read_hfc(struct IsdnCardState *cs, u_char regnum) /**************************************************/ static void fifo_select(struct IsdnCardState *cs, u_char fifo) -{ long flags; +{ unsigned long flags; if (fifo == cs->hw.hfcsx.last_fifo) return; /* still valid */ @@ -123,7 +111,7 @@ fifo_select(struct IsdnCardState *cs, u_char fifo) /******************************************/ static void reset_fifo(struct IsdnCardState *cs, u_char fifo) -{ long flags; +{ unsigned long flags; save_flags(flags); cli(); @@ -337,7 +325,7 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max) void release_io_hfcsx(struct IsdnCardState *cs) { - long flags; + unsigned long flags; save_flags(flags); cli(); @@ -599,7 +587,7 @@ static void hfcsx_fill_fifo(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; - long flags; + unsigned long flags; if (!bcs->tx_skb) return; @@ -670,7 +658,7 @@ dch_nt_l2l1(struct PStack *st, int pr, void *arg) static int hfcsx_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic) { - long flags; + unsigned long flags; int i = *(unsigned int *) ic->parm.num; if ((ic->arg == 98) && @@ -729,7 +717,7 @@ hfcsx_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic) static void receive_emsg(struct IsdnCardState *cs) { - long flags; + unsigned long flags; int count = 5; u_char *ptr; struct sk_buff *skb; @@ -961,7 +949,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; - long flags; + unsigned long flags; switch (pr) { case (PH_DATA | REQUEST): @@ -1115,7 +1103,7 @@ void mode_hfcsx(struct BCState *bcs, int mode, int bc) { struct IsdnCardState *cs = bcs->cs; - long flags; + unsigned long flags; int fifo2; if (cs->debug & L1_DEB_HSCX) @@ -1339,7 +1327,7 @@ setstack_2b(struct PStack *st, struct BCState *bcs) static void hfcsx_bh(struct IsdnCardState *cs) { - long flags; + unsigned long flags; /* struct PStack *stptr; */ if (!cs) @@ -1479,7 +1467,7 @@ setup_hfcsx(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; char tmp[64]; - long flags; + unsigned long flags; strcpy(tmp, hfcsx_revision); printk(KERN_INFO "HiSax: HFC-SX driver Rev. %s\n", HiSax_getrev(tmp)); diff --git a/drivers/isdn/hisax/hfc_sx.h b/drivers/isdn/hisax/hfc_sx.h index 41c8056bcbfd..12f54159344a 100644 --- a/drivers/isdn/hisax/hfc_sx.h +++ b/drivers/isdn/hisax/hfc_sx.h @@ -1,24 +1,13 @@ -/* $Id: hfc_sx.h,v 1.2 2000/06/26 08:59:13 keil Exp $ +/* $Id: hfc_sx.h,v 1.2.6.1 2001/09/23 22:24:48 kai Exp $ * - * specific defines for CCD's HFC 2BDS0 S+,SP chips + * specific defines for CCD's HFC 2BDS0 S+,SP chips * - * Author Werner Cornelius (werner@isdn4linux.de) - * - * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Author Werner Cornelius + * based on existing driver for CCD HFC PCI cards + * Copyright by Werner Cornelius <werner@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c index e98557cc4502..65ab7b4bb3c7 100644 --- a/drivers/isdn/hisax/hfcscard.c +++ b/drivers/isdn/hisax/hfcscard.c @@ -1,10 +1,12 @@ -/* $Id: hfcscard.c,v 1.8.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: hfcscard.c,v 1.8.6.2 2001/09/23 22:24:48 kai Exp $ * - * hfcscard.c low level stuff for hfcs based cards (Teles3c, ACER P10) + * low level stuff for hfcs based cards (Teles3c, ACER P10) * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -16,7 +18,7 @@ extern const char *CardType[]; -static const char *hfcs_revision = "$Revision: 1.8.6.1 $"; +static const char *hfcs_revision = "$Revision: 1.8.6.2 $"; static void hfcs_interrupt(int intno, void *dev_id, struct pt_regs *regs) diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 38251b34ded9..fdab825761aa 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -1,13 +1,12 @@ -/* $Id: hisax.h,v 2.52.6.8 2001/08/23 19:44:23 kai Exp $ +/* $Id: hisax.h,v 2.52.6.9 2001/09/23 22:24:48 kai Exp $ * - * Basic declarations, defines and prototypes + * Basic declarations, defines and prototypes * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ #include <linux/config.h> -#include <linux/module.h> -#include <linux/version.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/major.h> diff --git a/drivers/isdn/hisax/hisax_debug.h b/drivers/isdn/hisax/hisax_debug.h index 0c94449ac562..c5b37d18800a 100644 --- a/drivers/isdn/hisax/hisax_debug.h +++ b/drivers/isdn/hisax/hisax_debug.h @@ -3,13 +3,11 @@ * * Author Frode Isaksen * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> + * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * - */ - -/* * How to use: * * Before including this file, you need to @@ -18,11 +16,14 @@ * determines the debug bitmask. * * If CONFIG_HISAX_DEBUG is not set, all macros evaluate to nothing + * */ #ifndef __HISAX_DEBUG_H__ #define __HISAX_DEBUG_H__ +#include <linux/config.h> + #ifdef CONFIG_HISAX_DEBUG #define DBG(level, format, arg...) do { \ diff --git a/drivers/isdn/hisax/hisax_if.h b/drivers/isdn/hisax/hisax_if.h index 49a856a84ec8..4898fce2d509 100644 --- a/drivers/isdn/hisax/hisax_if.h +++ b/drivers/isdn/hisax/hisax_if.h @@ -1,3 +1,15 @@ +/* + * Interface between low level (hardware) drivers and + * HiSax protocol stack + * + * Author Kai Germaschewski + * Copyright 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ + #ifndef __HISAX_IF_H__ #define __HISAX_IF_H__ diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c index d527d804c079..6a261e0befa1 100644 --- a/drivers/isdn/hisax/hscx.c +++ b/drivers/isdn/hisax/hscx.c @@ -1,10 +1,12 @@ -/* $Id: hscx.c,v 1.21.6.2 2001/06/09 15:14:17 kai Exp $ +/* $Id: hscx.c,v 1.21.6.3 2001/09/23 22:24:48 kai Exp $ * - * hscx.c HSCX specific routines + * HSCX specific routines * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/hscx.h b/drivers/isdn/hisax/hscx.h index bb1fd004d475..c9f6cbaa745b 100644 --- a/drivers/isdn/hisax/hscx.h +++ b/drivers/isdn/hisax/hscx.h @@ -1,10 +1,12 @@ -/* $Id: hscx.h,v 1.6.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: hscx.h,v 1.6.6.2 2001/09/23 22:24:48 kai Exp $ * - * hscx.h HSCX specific defines + * HSCX specific defines * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/hscx_irq.c b/drivers/isdn/hisax/hscx_irq.c index 3824f4337c2a..a90af53a979c 100644 --- a/drivers/isdn/hisax/hscx_irq.c +++ b/drivers/isdn/hisax/hscx_irq.c @@ -1,13 +1,15 @@ -/* $Id: hscx_irq.c,v 1.16.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: hscx_irq.c,v 1.16.6.2 2001/09/23 22:24:48 kai Exp $ * - * hscx_irq.c low level b-channel stuff for Siemens HSCX + * low level b-channel stuff for Siemens HSCX * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * * This is an include file for fast inline IRQ stuff * - * This file is (c) under GNU General Public License - * */ diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c index 609f626d5794..2f224215638a 100644 --- a/drivers/isdn/hisax/icc.c +++ b/drivers/isdn/hisax/icc.c @@ -1,18 +1,18 @@ -// $Id: icc.c,v 1.5.6.3 2001/06/09 15:14:17 kai Exp $ -//----------------------------------------------------------------------------- -// -// ICC specific routines -// -// Author Matt Henderson & Guy Ellis - Traverse Tecnologies Pty Ltd -// www.traverse.com.au -// -// 1999.6.25 Initial implementation of routines for Siemens ISDN -// Communication Controller PEB 2070 based on the ISAC routines -// written by Karsten Keil. -// -// This file is (c) under GNU General Public License -// -//----------------------------------------------------------------------------- +/* $Id: icc.c,v 1.5.6.4 2001/09/23 22:24:48 kai Exp $ + * + * ICC specific routines + * + * Author Matt Henderson & Guy Ellis + * Copyright by Traverse Technologies Pty Ltd, www.travers.com.au + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * 1999.6.25 Initial implementation of routines for Siemens ISDN + * Communication Controller PEB 2070 based on the ISAC routines + * written by Karsten Keil. + * + */ #define __NO_VERSION__ #include <linux/init.h> diff --git a/drivers/isdn/hisax/icc.h b/drivers/isdn/hisax/icc.h index f624a63ab6a6..90feb9064202 100644 --- a/drivers/isdn/hisax/icc.h +++ b/drivers/isdn/hisax/icc.h @@ -1,19 +1,17 @@ -// $Id: icc.h,v 1.2.6.2 2001/03/13 16:17:08 kai Exp $ -//----------------------------------------------------------------------------- -// -// ICC specific routines -// -// Author Matt Henderson & Guy Ellis - Traverse Tecnologies Pty Ltd -// www.traverse.com.au -// -// 1999.7.14 Initial implementation of routines for Siemens ISDN -// Communication Controller PEB 2070 based on the ISAC routines -// written by Karsten Keil. -// -// This file is (c) under GNU General Public License -// -//----------------------------------------------------------------------------- - +/* $Id: icc.h,v 1.2.6.3 2001/09/23 22:24:48 kai Exp $ + * + * ICC specific routines + * + * Author Matt Henderson & Guy Ellis + * Copyright by Traverse Technologies Pty Ltd, www.travers.com.au + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * 1999.7.14 Initial implementation of routines for Siemens ISDN + * Communication Controller PEB 2070 based on the ISAC routines + * written by Karsten Keil. + */ /* All Registers original Siemens Spec */ diff --git a/drivers/isdn/hisax/ipac.h b/drivers/isdn/hisax/ipac.h index a46840be6677..76bc1f21c332 100644 --- a/drivers/isdn/hisax/ipac.h +++ b/drivers/isdn/hisax/ipac.h @@ -1,14 +1,15 @@ -/* $Id: ipac.h,v 1.5.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: ipac.h,v 1.5.6.2 2001/09/23 22:24:49 kai Exp $ * - * ipac.h IPAC specific defines + * IPAC specific defines * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - /* All Registers original Siemens Spec */ #define IPAC_CONF 0xC0 diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c index b581c28724cf..61a0fff4278e 100644 --- a/drivers/isdn/hisax/isac.c +++ b/drivers/isdn/hisax/isac.c @@ -1,12 +1,16 @@ -/* $Id: isac.c,v 1.28.6.2 2001/06/09 15:14:17 kai Exp $ +/* $Id: isac.c,v 1.28.6.3 2001/09/23 22:24:49 kai Exp $ * - * isac.c ISAC specific routines + * ISAC specific routines * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert */ #define __NO_VERSION__ diff --git a/drivers/isdn/hisax/isac.h b/drivers/isdn/hisax/isac.h index 928439f815ea..3d69027427fd 100644 --- a/drivers/isdn/hisax/isac.h +++ b/drivers/isdn/hisax/isac.h @@ -1,14 +1,15 @@ -/* $Id: isac.h,v 1.7.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: isac.h,v 1.7.6.2 2001/09/23 22:24:49 kai Exp $ * - * isac.h ISAC specific defines + * ISAC specific defines * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ - /* All Registers original Siemens Spec */ #define ISAC_MASK 0x20 diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index c36164745290..01986d8ed454 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -1,4 +1,4 @@ -/* $Id: isar.c,v 1.17.6.4 2001/08/17 12:34:26 kai Exp $ +/* $Id: isar.c,v 1.17.6.5 2001/09/23 11:51:33 keil Exp $ * * isar.c ISAR (Siemens PSB 7110) specific routines * @@ -270,9 +270,10 @@ isar_load_firmware(struct IsdnCardState *cs, u_char *buf) ret = 1;goto reterror; } while (left>0) { - noc = left; - if (noc > 126) + if (left > 126) noc = 126; + else + noc = left; nom = 2*noc; mp = msg; *mp++ = sadr / 256; @@ -288,8 +289,8 @@ isar_load_firmware(struct IsdnCardState *cs, u_char *buf) nom += 3; sp = (u_short *)tmpmsg; #if DBG_LOADFIRM - printk(KERN_DEBUG"isar: load %3d words at %04x\n", - noc, sadr); + printk(KERN_DEBUG"isar: load %3d words at %04x left %d\n", + noc, sadr, left); #endif sadr += noc; while(noc) { diff --git a/drivers/isdn/hisax/isar.h b/drivers/isdn/hisax/isar.h index 509652784df0..fb929c218ec1 100644 --- a/drivers/isdn/hisax/isar.h +++ b/drivers/isdn/hisax/isar.h @@ -1,10 +1,12 @@ -/* $Id: isar.h,v 1.9.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: isar.h,v 1.9.6.2 2001/09/23 22:24:49 kai Exp $ * - * isar.h ISAR (Siemens PSB 7110) specific defines + * ISAR (Siemens PSB 7110) specific defines * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c index 0a4ba9193048..35b36bb14d90 100644 --- a/drivers/isdn/hisax/isdnl1.c +++ b/drivers/isdn/hisax/isdnl1.c @@ -1,13 +1,16 @@ -/* $Id: isdnl1.c,v 2.41.6.4 2001/08/23 19:44:23 kai Exp $ +/* $Id: isdnl1.c,v 2.41.6.5 2001/09/23 22:24:49 kai Exp $ * - * isdnl1.c common low level stuff for Siemens Chipsetbased isdn cards - * based on the teles driver from Jan den Ouden + * common low level stuff for Siemens Chipsetbased isdn cards * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * based on the teles driver from Jan den Ouden + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert @@ -15,7 +18,7 @@ * */ -const char *l1_revision = "$Revision: 2.41.6.4 $"; +const char *l1_revision = "$Revision: 2.41.6.5 $"; #define __NO_VERSION__ #include <linux/init.h> diff --git a/drivers/isdn/hisax/isdnl1.h b/drivers/isdn/hisax/isdnl1.h index 988dfe5751d1..0d7111b3c087 100644 --- a/drivers/isdn/hisax/isdnl1.h +++ b/drivers/isdn/hisax/isdnl1.h @@ -1,8 +1,9 @@ -/* $Id: isdnl1.h,v 2.9.6.2 2001/08/23 19:44:23 kai Exp $ +/* $Id: isdnl1.h,v 2.9.6.3 2001/09/23 22:24:49 kai Exp $ * * Layer 1 defines * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index 18683236802f..4b2a31196e19 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c @@ -1,22 +1,26 @@ -/* $Id: isdnl2.c,v 2.25.6.3 2001/06/09 15:14:17 kai Exp $ +/* $Id: isdnl2.c,v 2.25.6.4 2001/09/23 22:24:49 kai Exp $ * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil * based on the teles driver from Jan den Ouden + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert * */ + #define __NO_VERSION__ #include <linux/init.h> #include "hisax.h" #include "isdnl2.h" -const char *l2_revision = "$Revision: 2.25.6.3 $"; +const char *l2_revision = "$Revision: 2.25.6.4 $"; static void l2m_debug(struct FsmInst *fi, char *fmt, ...); diff --git a/drivers/isdn/hisax/isdnl2.h b/drivers/isdn/hisax/isdnl2.h index 6a73943f65df..7e447fb8ed1d 100644 --- a/drivers/isdn/hisax/isdnl2.h +++ b/drivers/isdn/hisax/isdnl2.h @@ -1,8 +1,9 @@ -/* $Id: isdnl2.h,v 1.3.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: isdnl2.h,v 1.3.6.2 2001/09/23 22:24:49 kai Exp $ * * Layer 2 defines * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c index 5eaa9bfad15b..02d23b8b7778 100644 --- a/drivers/isdn/hisax/isdnl3.c +++ b/drivers/isdn/hisax/isdnl3.c @@ -1,11 +1,14 @@ -/* $Id: isdnl3.c,v 2.17.6.4 2001/06/09 15:14:17 kai Exp $ +/* $Id: isdnl3.c,v 2.17.6.5 2001/09/23 22:24:49 kai Exp $ * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil * based on the teles driver from Jan den Ouden + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert @@ -18,7 +21,7 @@ #include "isdnl3.h" #include <linux/config.h> -const char *l3_revision = "$Revision: 2.17.6.4 $"; +const char *l3_revision = "$Revision: 2.17.6.5 $"; static struct Fsm l3fsm; diff --git a/drivers/isdn/hisax/isdnl3.h b/drivers/isdn/hisax/isdnl3.h index be25d32ba809..2cb76fef5a3c 100644 --- a/drivers/isdn/hisax/isdnl3.h +++ b/drivers/isdn/hisax/isdnl3.h @@ -1,6 +1,7 @@ -/* $Id: isdnl3.h,v 2.6.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: isdnl3.h,v 2.6.6.2 2001/09/23 22:24:49 kai Exp $ * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c index 1b986d0b37e5..c3c51edc3a1b 100644 --- a/drivers/isdn/hisax/isurf.c +++ b/drivers/isdn/hisax/isurf.c @@ -1,10 +1,12 @@ -/* $Id: isurf.c,v 1.10.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: isurf.c,v 1.10.6.2 2001/09/23 22:24:49 kai Exp $ * - * isurf.c low level stuff for Siemens I-Surf/I-Talk cards + * low level stuff for Siemens I-Surf/I-Talk cards * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -17,7 +19,7 @@ extern const char *CardType[]; -static const char *ISurf_revision = "$Revision: 1.10.6.1 $"; +static const char *ISurf_revision = "$Revision: 1.10.6.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c index 770b94268522..84fb2005d682 100644 --- a/drivers/isdn/hisax/ix1_micro.c +++ b/drivers/isdn/hisax/ix1_micro.c @@ -1,47 +1,22 @@ -/* $Id: ix1_micro.c,v 2.10.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: ix1_micro.c,v 2.10.6.2 2001/09/23 22:24:49 kai Exp $ * - * ix1_micro.c low level stuff for ITK ix1-micro Rev.2 isdn cards - * derived from the original file teles3.c from Karsten Keil + * low level stuff for ITK ix1-micro Rev.2 isdn cards + * derived from the original file teles3.c from Karsten Keil * - * Copyright (C) 1997 Klaus-Peter Nischke (ITK AG) (for the modifications to - * the original file teles.c) - * - * Thanks to Jan den Ouden - * Fritz Elfert - * Beat Doebeli + * Author Klaus-Peter Nischke + * Copyright by Klaus-Peter Nischke, ITK AG + * <klaus@nischke.do.eunet.de> + * by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * + * Klaus-Peter Nischke + * Deusener Str. 287 + * 44369 Dortmund + * Germany */ -/* - For the modification done by the author the following terms and conditions - apply (GNU General Public License) - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - - You may contact Klaus-Peter Nischke by email: klaus@nischke.do.eunet.de - or by conventional mail: - - Klaus-Peter Nischke - Deusener Str. 287 - 44369 Dortmund - Germany - */ - - #define __NO_VERSION__ #include <linux/init.h> #include "hisax.h" @@ -50,7 +25,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *ix1_revision = "$Revision: 2.10.6.1 $"; +const char *ix1_revision = "$Revision: 2.10.6.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c index 8b53fcc09160..d866dd277730 100644 --- a/drivers/isdn/hisax/jade.c +++ b/drivers/isdn/hisax/jade.c @@ -1,10 +1,12 @@ -/* $Id: jade.c,v 1.6.6.2 2001/06/09 15:14:18 kai Exp $ +/* $Id: jade.c,v 1.6.6.3 2001/09/23 22:24:49 kai Exp $ * - * jade.c JADE stuff (derived from original hscx.c) + * JADE stuff (derived from original hscx.c) * - * Author Roland Klabunde (R.Klabunde@Berkom.de) - * - * This file is (c) under GNU General Public License + * Author Roland Klabunde + * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/jade.h b/drivers/isdn/hisax/jade.h index 81eb8ddf2582..1a6ce2ac4dfe 100644 --- a/drivers/isdn/hisax/jade.h +++ b/drivers/isdn/hisax/jade.h @@ -1,9 +1,12 @@ -/* $Id: jade.h,v 1.3.6.1 2001/02/16 16:43:27 kai Exp $ - * jade.h JADE specific defines +/* $Id: jade.h,v 1.3.6.2 2001/09/23 22:24:49 kai Exp $ * - * Author Roland Klabunde (R.Klabunde@Berkom.de) + * JADE specific defines * - * This file is (c) under GNU General Public License + * Author Roland Klabunde + * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/jade_irq.c b/drivers/isdn/hisax/jade_irq.c index 4969669b92b8..e81547acf36f 100644 --- a/drivers/isdn/hisax/jade_irq.c +++ b/drivers/isdn/hisax/jade_irq.c @@ -1,10 +1,12 @@ -/* $Id: jade_irq.c,v 1.5.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: jade_irq.c,v 1.5.6.2 2001/09/23 22:24:49 kai Exp $ * - * jade_irq.c Low level JADE IRQ stuff (derived from original hscx_irq.c) + * Low level JADE IRQ stuff (derived from original hscx_irq.c) * - * Author Roland Klabunde (R.Klabunde@Berkom.de) - * - * This file is (c) under GNU General Public License + * Author Roland Klabunde + * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c index 6e05b5a60bc9..4cb998d2792f 100644 --- a/drivers/isdn/hisax/l3_1tr6.c +++ b/drivers/isdn/hisax/l3_1tr6.c @@ -1,12 +1,15 @@ -/* $Id: l3_1tr6.c,v 2.13.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: l3_1tr6.c,v 2.13.6.2 2001/09/23 22:24:49 kai Exp $ * - * German 1TR6 D-channel protocol + * German 1TR6 D-channel protocol * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * */ @@ -17,7 +20,7 @@ #include <linux/ctype.h> extern char *HiSax_getrev(const char *revision); -const char *l3_1tr6_revision = "$Revision: 2.13.6.1 $"; +const char *l3_1tr6_revision = "$Revision: 2.13.6.2 $"; #define MsgHead(ptr, cref, mty, dis) \ *ptr++ = dis; \ diff --git a/drivers/isdn/hisax/l3_1tr6.h b/drivers/isdn/hisax/l3_1tr6.h index cfb6d7326d9d..43215c00cada 100644 --- a/drivers/isdn/hisax/l3_1tr6.h +++ b/drivers/isdn/hisax/l3_1tr6.h @@ -1,10 +1,12 @@ -/* $Id: l3_1tr6.h,v 2.2.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: l3_1tr6.h,v 2.2.6.2 2001/09/23 22:24:49 kai Exp $ * - * German 1TR6 D-channel protocol defines + * German 1TR6 D-channel protocol defines * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #ifndef l3_1tr6 #define l3_1tr6 diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c index d9dff796fb6c..2f13dd3cf8b4 100644 --- a/drivers/isdn/hisax/l3dss1.c +++ b/drivers/isdn/hisax/l3dss1.c @@ -1,13 +1,18 @@ -/* $Id: l3dss1.c,v 2.30.6.1 2001/02/16 16:43:27 kai Exp $ +/* $Id: l3dss1.c,v 2.30.6.2 2001/09/23 22:24:49 kai Exp $ * * EURO/DSS1 D-channel protocol * - * Author Karsten Keil (keil@isdn4linux.de) + * German 1TR6 D-channel protocol + * + * Author Karsten Keil * based on the teles driver from Jan den Ouden + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert @@ -22,7 +27,7 @@ #include <linux/config.h> extern char *HiSax_getrev(const char *revision); -const char *dss1_revision = "$Revision: 2.30.6.1 $"; +const char *dss1_revision = "$Revision: 2.30.6.2 $"; #define EXT_BEARER_CAPS 1 @@ -44,7 +49,7 @@ const char *dss1_revision = "$Revision: 2.30.6.1 $"; static unsigned char new_invoke_id(struct PStack *p) { unsigned char retval; - long flags; + unsigned long flags; int i; i = 32; /* maximum search depth */ @@ -73,7 +78,7 @@ static unsigned char new_invoke_id(struct PStack *p) /* free a used invoke id */ /*************************/ static void free_invoke_id(struct PStack *p, unsigned char id) -{ long flags; +{ unsigned long flags; if (!id) return; /* 0 = invalid value */ diff --git a/drivers/isdn/hisax/l3dss1.h b/drivers/isdn/hisax/l3dss1.h index 76207660c010..7a18c26d3535 100644 --- a/drivers/isdn/hisax/l3dss1.h +++ b/drivers/isdn/hisax/l3dss1.h @@ -1,8 +1,9 @@ -/* $Id: l3dss1.h,v 1.10.6.1 2001/02/16 16:43:28 kai Exp $ +/* $Id: l3dss1.h,v 1.10.6.2 2001/09/23 22:24:50 kai Exp $ * - * DSS1 (Euro) D-channel protocol defines + * DSS1 (Euro) D-channel protocol defines * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c index 25f25c24c123..8811f3ca15c6 100644 --- a/drivers/isdn/hisax/l3ni1.c +++ b/drivers/isdn/hisax/l3ni1.c @@ -1,24 +1,23 @@ -// $Id: l3ni1.c,v 2.5.6.2 2001/02/16 16:43:28 kai Exp $ -// -//----------------------------------------------------------------------------- -// -// NI1 D-channel protocol -// -// Authors: -// Matt Henderson & Guy Ellis - Traverse Tecnologies Pty Ltd -// www.traverse.com.au -// -// 2000.6.6 Initial implementation of routines for US NI1 -// Layer 3 protocol based on the EURO/DSS1 D-channel protocol -// driver written by Karsten Keil et al. -// NI-1 Hall of Fame - Thanks to.... -// Ragnar Paulson - for some handy code fragments -// Will Scales - beta tester extraordinaire -// Brett Whittacre - beta tester and remote devel system in Vegas -// -// This file is (c) under GNU General Public License -// -//----------------------------------------------------------------------------- +/* $Id: l3ni1.c,v 2.5.6.3 2001/09/23 22:24:50 kai Exp $ + * + * NI1 D-channel protocol + * + * Author Matt Henderson & Guy Ellis + * Copyright by Traverse Technologies Pty Ltd, www.travers.com.au + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * 2000.6.6 Initial implementation of routines for US NI1 + * Layer 3 protocol based on the EURO/DSS1 D-channel protocol + * driver written by Karsten Keil et al. + * NI-1 Hall of Fame - Thanks to.... + * Ragnar Paulson - for some handy code fragments + * Will Scales - beta tester extraordinaire + * Brett Whittacre - beta tester and remote devel system in Vegas + * + */ + #define __NO_VERSION__ #include "hisax.h" #include "isdnl3.h" @@ -26,7 +25,7 @@ #include <linux/ctype.h> extern char *HiSax_getrev(const char *revision); -const char *ni1_revision = "$Revision: 2.5.6.2 $"; +const char *ni1_revision = "$Revision: 2.5.6.3 $"; #define EXT_BEARER_CAPS 1 @@ -48,7 +47,7 @@ const char *ni1_revision = "$Revision: 2.5.6.2 $"; static unsigned char new_invoke_id(struct PStack *p) { unsigned char retval; - long flags; + unsigned long flags; int i; i = 32; /* maximum search depth */ @@ -77,7 +76,7 @@ static unsigned char new_invoke_id(struct PStack *p) /* free a used invoke id */ /*************************/ static void free_invoke_id(struct PStack *p, unsigned char id) -{ long flags; +{ unsigned long flags; if (!id) return; /* 0 = invalid value */ diff --git a/drivers/isdn/hisax/l3ni1.h b/drivers/isdn/hisax/l3ni1.h index 57410c1514a5..4a0357b0c94d 100644 --- a/drivers/isdn/hisax/l3ni1.h +++ b/drivers/isdn/hisax/l3ni1.h @@ -1,20 +1,19 @@ -// $Id: l3ni1.h,v 2.3.6.1 2001/02/16 16:43:28 kai Exp $ -//----------------------------------------------------------------------------- -// -// NI1 D-channel protocol -// -// Author Matt Henderson & Guy Ellis - Traverse Tecnologies Pty Ltd -// www.traverse.com.au -// -// 2000.6.6 Initial implementation of routines for US NI1 -// Layer 3 protocol based on the EURO/DSS1 D-channel protocol -// driver written by Karsten Keil et al. Thanks also for the -// code provided by Ragnar Paulson. -// -// -// This file is (c) under GNU General Public License -// -//----------------------------------------------------------------------------- +/* $Id: l3ni1.h,v 2.3.6.2 2001/09/23 22:24:50 kai Exp $ + * + * NI1 D-channel protocol + * + * Author Matt Henderson & Guy Ellis + * Copyright by Traverse Technologies Pty Ltd, www.travers.com.au + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * 2000.6.6 Initial implementation of routines for US NI1 + * Layer 3 protocol based on the EURO/DSS1 D-channel protocol + * driver written by Karsten Keil et al. Thanks also for the + * code provided by Ragnar Paulson. + * + */ #ifndef l3ni1_process diff --git a/drivers/isdn/hisax/lmgr.c b/drivers/isdn/hisax/lmgr.c index c261ba6cdffe..855fda5bd7e0 100644 --- a/drivers/isdn/hisax/lmgr.c +++ b/drivers/isdn/hisax/lmgr.c @@ -1,10 +1,12 @@ -/* $Id: lmgr.c,v 1.7.6.1 2001/02/16 16:43:28 kai Exp $ +/* $Id: lmgr.c,v 1.7.6.2 2001/09/23 22:24:50 kai Exp $ * - * Author Karsten Keil (keil@isdn4linux.de) + * Layermanagement module * - * Layermanagement module - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c index b38235d41168..e7e03ebb7bd0 100644 --- a/drivers/isdn/hisax/mic.c +++ b/drivers/isdn/hisax/mic.c @@ -1,12 +1,12 @@ -/* $Id: mic.c,v 1.10.6.1 2001/02/16 16:43:28 kai Exp $ +/* $Id: mic.c,v 1.10.6.2 2001/09/23 22:24:50 kai Exp $ * - * mic.c low level stuff for mic cards + * low level stuff for mic cards * - * Copyright (C) 1997 - * - * Author Stephan von Krawczynski <skraw@ithnet.com> - * - * This file is (c) under GNU General Public License + * Author Stephan von Krawczynski + * Copyright by Stephan von Krawczynski <skraw@ithnet.com> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -19,7 +19,7 @@ extern const char *CardType[]; -const char *mic_revision = "$Revision: 1.10.6.1 $"; +const char *mic_revision = "$Revision: 1.10.6.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index d94bccd4eb45..7482de0f6d1e 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c @@ -1,12 +1,14 @@ -/* $Id: netjet.c,v 1.24.6.5 2001/06/09 15:14:18 kai Exp $ +/* $Id: netjet.c,v 1.24.6.6 2001/09/23 22:24:50 kai Exp $ * - * netjet.c low level stuff for Traverse Technologie NETJet ISDN cards + * low level stuff for Traverse Technologie NETJet ISDN cards * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * Thanks to Traverse Technologie Australia for documents and informations - * - * This file is (c) under GNU General Public License + * Thanks to Traverse Technologie Australia for documents and information * */ @@ -22,7 +24,7 @@ #include <asm/io.h> #include "netjet.h" -const char *NETjet_revision = "$Revision: 1.24.6.5 $"; +const char *NETjet_revision = "$Revision: 1.24.6.6 $"; /* Interface functions */ diff --git a/drivers/isdn/hisax/netjet.h b/drivers/isdn/hisax/netjet.h index f24f6992bf21..7269d1c226a6 100644 --- a/drivers/isdn/hisax/netjet.h +++ b/drivers/isdn/hisax/netjet.h @@ -1,14 +1,16 @@ -// $Id: netjet.h,v 2.5.6.2 2001/02/16 16:43:28 kai Exp $ -//----------------------------------------------------------------------------- -// -// NETjet common header file -// -// Author Kerstern Keil repackaged by -// Matt Henderson - Traverse Technologies P/L www.traverse.com.au -// -// This file is (c) under GNU General Public License -// -//----------------------------------------------------------------------------- +/* $Id: netjet.h,v 2.5.6.3 2001/09/23 22:24:50 kai Exp $ + * + * NETjet common header file + * + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * by Matt Henderson, + * Traverse Technologies P/L www.traverse.com.au + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ extern const char *CardType[]; diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c index dba2a6d86f11..386bfa3b5ff2 100644 --- a/drivers/isdn/hisax/niccy.c +++ b/drivers/isdn/hisax/niccy.c @@ -1,13 +1,15 @@ -/* $Id: niccy.c,v 1.15.6.4 2001/02/16 16:43:28 kai Exp $ +/* $Id: niccy.c,v 1.15.6.5 2001/09/23 22:24:50 kai Exp $ * - * niccy.c low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and - * compatible (SAGEM cybermodem) + * low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and + * compatible (SAGEM cybermodem) * - * Author Karsten Keil + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> * - * Thanks to Dr. Neuhaus and SAGEM for informations - * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * Thanks to Dr. Neuhaus and SAGEM for information * */ @@ -22,7 +24,7 @@ #include <linux/pci.h> extern const char *CardType[]; -const char *niccy_revision = "$Revision: 1.15.6.4 $"; +const char *niccy_revision = "$Revision: 1.15.6.5 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c index 9f9786fbf111..c12a3c24712c 100644 --- a/drivers/isdn/hisax/nj_s.c +++ b/drivers/isdn/hisax/nj_s.c @@ -1,7 +1,9 @@ -// $Id: nj_s.c,v 2.7.6.5 2001/07/18 16:25:12 kai Exp $ -// -// This file is (c) under GNU General Public License -// +/* $Id: nj_s.c,v 2.7.6.6 2001/09/23 22:24:50 kai Exp $ + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ #define __NO_VERSION__ #include <linux/config.h> @@ -14,7 +16,7 @@ #include <linux/ppp_defs.h> #include "netjet.h" -const char *NETjet_S_revision = "$Revision: 2.7.6.5 $"; +const char *NETjet_S_revision = "$Revision: 2.7.6.6 $"; static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) { diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c index 454cd1a71f3f..52fd4a5d81bc 100644 --- a/drivers/isdn/hisax/nj_u.c +++ b/drivers/isdn/hisax/nj_u.c @@ -1,6 +1,7 @@ -/* $Id: nj_u.c,v 2.8.6.5 2001/07/18 16:25:12 kai Exp $ +/* $Id: nj_u.c,v 2.8.6.6 2001/09/23 22:24:50 kai Exp $ * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -15,7 +16,7 @@ #include <linux/ppp_defs.h> #include "netjet.h" -const char *NETjet_U_revision = "$Revision: 2.8.6.5 $"; +const char *NETjet_U_revision = "$Revision: 2.8.6.6 $"; static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) { diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c index 2f68e3224776..727c1ea0641c 100644 --- a/drivers/isdn/hisax/q931.c +++ b/drivers/isdn/hisax/q931.c @@ -1,17 +1,17 @@ -/* $Id: q931.c,v 1.10.6.2 2001/03/13 16:17:08 kai Exp $ +/* $Id: q931.c,v 1.10.6.3 2001/09/23 22:24:50 kai Exp $ * - * q931.c code to decode ITU Q.931 call control messages + * code to decode ITU Q.931 call control messages * * Author Jan den Ouden + * Copyright by Jan den Ouden * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * Changelog + * Changelog: * * Pauline Middelink general improvements - * * Beat Doebeli cause texts, display information element - * * Karsten Keil cause texts, display information element for 1TR6 * */ diff --git a/drivers/isdn/hisax/rawhdlc.c b/drivers/isdn/hisax/rawhdlc.c index 09e05f67718c..6e9bb81d38e3 100644 --- a/drivers/isdn/hisax/rawhdlc.c +++ b/drivers/isdn/hisax/rawhdlc.c @@ -1,11 +1,14 @@ -/* $Id: rawhdlc.c,v 1.5.6.1 2001/02/16 16:43:28 kai Exp $ +/* $Id: rawhdlc.c,v 1.5.6.2 2001/09/23 22:24:51 kai Exp $ * - * rawhdlc.c support routines for cards that don't support HDLC + * support routines for cards that don't support HDLC * - * Author Karsten Keil (keil@isdn4linux.de) - * Brent Baccala <baccala@FreeSoft.org> + * Author Brent Baccala + * Copyright by Karsten Keil <keil@isdn4linux.de> + * by Brent Baccala <baccala@FreeSoft.org> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License * * Some passive ISDN cards, such as the Traverse NETJet and the AMD 7930, * don't perform HDLC encapsulation over the B channel. Drivers for diff --git a/drivers/isdn/hisax/rawhdlc.h b/drivers/isdn/hisax/rawhdlc.h index 1ba38a51f527..9b9fd8191df3 100644 --- a/drivers/isdn/hisax/rawhdlc.h +++ b/drivers/isdn/hisax/rawhdlc.h @@ -1,10 +1,10 @@ -/* $Id: rawhdlc.h,v 1.3.6.1 2001/02/16 16:43:29 kai Exp $ +/* $Id: rawhdlc.h,v 1.3.6.2 2001/09/23 22:24:51 kai Exp $ * - * rawhdlc.h support routines for cards that don't support HDLC + * Author Brent Baccala + * Copyright by Brent Baccala <baccala@FreeSoft.org> * - * Author Brent Baccala <baccala@FreeSoft.org> - * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c index fa965fe87c50..ee0924241ad9 100644 --- a/drivers/isdn/hisax/s0box.c +++ b/drivers/isdn/hisax/s0box.c @@ -1,12 +1,15 @@ -/* $Id: s0box.c,v 2.4.6.1 2001/02/16 16:43:29 kai Exp $ +/* $Id: s0box.c,v 2.4.6.2 2001/09/23 22:24:51 kai Exp $ * - * s0box.c low level stuff for Creatix S0BOX + * low level stuff for Creatix S0BOX * - * Author S0BOX specific stuff: Enrik Berkhan (enrik@starfleet.inka.de) + * Author Enrik Berkhan + * Copyright by Enrik Berkhan <enrik@starfleet.inka.de> * - * This file is (c) under GNU General Public License + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #define __NO_VERSION__ #include <linux/init.h> #include "hisax.h" @@ -15,7 +18,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *s0box_revision = "$Revision: 2.4.6.1 $"; +const char *s0box_revision = "$Revision: 2.4.6.2 $"; static inline void writereg(unsigned int padr, signed int addr, u_char off, u_char val) { diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c index c243cef3b11b..1a029e5a6ac0 100644 --- a/drivers/isdn/hisax/saphir.c +++ b/drivers/isdn/hisax/saphir.c @@ -1,16 +1,17 @@ -/* $Id: saphir.c,v 1.8.6.1 2001/02/16 16:43:29 kai Exp $ +/* $Id: saphir.c,v 1.8.6.2 2001/09/23 22:24:51 kai Exp $ * - * saphir.c low level stuff for HST Saphir 1 + * low level stuff for HST Saphir 1 * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * * Thanks to HST High Soft Tech GmbH * - * This file is (c) under GNU General Public License - * */ - #define __NO_VERSION__ #include <linux/init.h> #include "hisax.h" @@ -19,7 +20,7 @@ #include "isdnl1.h" extern const char *CardType[]; -static char *saphir_rev = "$Revision: 1.8.6.1 $"; +static char *saphir_rev = "$Revision: 1.8.6.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c index 20d91baf02b1..5ebb038c5bd7 100644 --- a/drivers/isdn/hisax/sedlbauer.c +++ b/drivers/isdn/hisax/sedlbauer.c @@ -1,23 +1,22 @@ -/* $Id: sedlbauer.c,v 1.25.6.5 2001/07/13 09:20:12 kai Exp $ +/* $Id: sedlbauer.c,v 1.25.6.6 2001/09/23 22:24:51 kai Exp $ * - * sedlbauer.c low level stuff for Sedlbauer cards - * includes support for the Sedlbauer speed star (speed star II), - * support for the Sedlbauer speed fax+, - * support for the Sedlbauer ISDN-Controller PC/104 and - * support for the Sedlbauer speed pci - * derived from the original file asuscom.c from Karsten Keil + * low level stuff for Sedlbauer cards + * includes support for the Sedlbauer speed star (speed star II), + * support for the Sedlbauer speed fax+, + * support for the Sedlbauer ISDN-Controller PC/104 and + * support for the Sedlbauer speed pci + * derived from the original file asuscom.c from Karsten Keil * - * Copyright (C) 1997,1998 Marcus Niemann (for the modifications to - * the original file asuscom.c) - * - * Author Marcus Niemann (niemann@www-bib.fh-bielefeld.de) + * Author Marcus Niemann + * Copyright by Marcus Niemann <niemann@www-bib.fh-bielefeld.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * * Thanks to Karsten Keil * Sedlbauer AG for informations * Edgar Toernig * - * This file is (c) under GNU General Public License - * */ /* Supported cards: @@ -52,7 +51,7 @@ extern const char *CardType[]; -const char *Sedlbauer_revision = "$Revision: 1.25.6.5 $"; +const char *Sedlbauer_revision = "$Revision: 1.25.6.6 $"; const char *Sedlbauer_Types[] = {"None", "speed card/win", "speed star", "speed fax+", diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 5be7d160a633..b13b13ea477f 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -5,8 +5,6 @@ This driver is for the Sedlbauer Speed Star and Speed Star II, which are ISDN PCMCIA Cards. - sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 - The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of @@ -57,6 +55,10 @@ #include <pcmcia/ds.h> #include <pcmcia/bus_ops.h> +MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards"); +MODULE_AUTHOR("Marcus Niemann"); +MODULE_LICENSE("Dual MPL/GPL"); + /* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If you do not define PCMCIA_DEBUG at all, all the debug code will be diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c index 01877caa3c73..fcb82e3f561f 100644 --- a/drivers/isdn/hisax/sportster.c +++ b/drivers/isdn/hisax/sportster.c @@ -1,12 +1,15 @@ -/* $Id: sportster.c,v 1.14.6.1 2001/02/16 16:43:29 kai Exp $ +/* $Id: sportster.c,v 1.14.6.2 2001/09/23 22:24:51 kai Exp $ * - * sportster.c low level stuff for USR Sportster internal TA + * low level stuff for USR Sportster internal TA * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * * Thanks to Christian "naddy" Weisgerber (3Com, US Robotics) for documentation * - * This file is (c) under GNU General Public License * */ #define __NO_VERSION__ @@ -17,7 +20,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *sportster_revision = "$Revision: 1.14.6.1 $"; +const char *sportster_revision = "$Revision: 1.14.6.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h index 333de24cb157..48498c6f85d2 100644 --- a/drivers/isdn/hisax/st5481.h +++ b/drivers/isdn/hisax/st5481.h @@ -13,6 +13,8 @@ #ifndef _ST5481_H_ #define _ST5481_H_ +#include <linux/config.h> + // USB IDs, the Product Id is in the range 0x4810-0x481F #define ST_VENDOR_ID 0x0483 diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c index 17b2a21f878a..17b2a4325c3f 100644 --- a/drivers/isdn/hisax/st5481_b.c +++ b/drivers/isdn/hisax/st5481_b.c @@ -10,8 +10,6 @@ * */ -#include <linux/version.h> -#include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> #include <linux/slab.h> diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c index 78c4e4961368..3a9faf2e7a76 100644 --- a/drivers/isdn/hisax/st5481_d.c +++ b/drivers/isdn/hisax/st5481_d.c @@ -10,8 +10,6 @@ * */ -#include <linux/version.h> -#include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> #include <linux/slab.h> diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c index 6e299ba936eb..28ea25bf56a3 100644 --- a/drivers/isdn/hisax/st5481_init.c +++ b/drivers/isdn/hisax/st5481_init.c @@ -25,6 +25,7 @@ * clean up debug */ +#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/init.h> @@ -32,8 +33,9 @@ #include <linux/slab.h> #include "st5481.h" -MODULE_AUTHOR("Frode Isaksen <fisaksen@bewan.com>"); -MODULE_DESCRIPTION("ST5481 USB ISDN modem driver"); +MODULE_DESCRIPTION("ISDN4Linux: driver for ST5481 USB ISDN adapter"); +MODULE_AUTHOR("Frode Isaksen"); +MODULE_LICENSE("GPL"); static int protocol = 2; /* EURO-ISDN Default */ MODULE_PARM(protocol, "i"); diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index 9908094c41fc..7c108a8d4bee 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c @@ -10,8 +10,6 @@ * */ -#include <linux/version.h> -#include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> #include <linux/slab.h> diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c index b40cb12a2275..e08446d44abd 100644 --- a/drivers/isdn/hisax/tei.c +++ b/drivers/isdn/hisax/tei.c @@ -1,23 +1,27 @@ -/* $Id: tei.c,v 2.17.6.2 2001/05/26 15:19:57 kai Exp $ +/* $Id: tei.c,v 2.17.6.3 2001/09/23 22:24:51 kai Exp $ * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil * based on the teles driver from Jan den Ouden + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This file is (c) under GNU General Public License - * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert * */ + #define __NO_VERSION__ #include "hisax.h" #include "isdnl2.h" #include <linux/init.h> #include <linux/random.h> -const char *tei_revision = "$Revision: 2.17.6.2 $"; +const char *tei_revision = "$Revision: 2.17.6.3 $"; #define ID_REQUEST 1 #define ID_ASSIGNED 2 diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c index dc42b6d5c175..e3137ed984fa 100644 --- a/drivers/isdn/hisax/teleint.c +++ b/drivers/isdn/hisax/teleint.c @@ -1,10 +1,12 @@ -/* $Id: teleint.c,v 1.14.6.1 2001/02/16 16:43:29 kai Exp $ +/* $Id: teleint.c,v 1.14.6.2 2001/09/23 22:24:52 kai Exp $ * - * teleint.c low level stuff for TeleInt isdn cards + * low level stuff for TeleInt isdn cards * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -17,7 +19,7 @@ extern const char *CardType[]; -const char *TeleInt_revision = "$Revision: 1.14.6.1 $"; +const char *TeleInt_revision = "$Revision: 1.14.6.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c index 643790e7a2ea..e61abf7e4db5 100644 --- a/drivers/isdn/hisax/teles0.c +++ b/drivers/isdn/hisax/teles0.c @@ -1,17 +1,20 @@ -/* $Id: teles0.c,v 2.13.6.1 2001/02/16 16:43:29 kai Exp $ +/* $Id: teles0.c,v 2.13.6.2 2001/09/23 22:24:52 kai Exp $ * - * teles0.c low level stuff for Teles Memory IO isdn cards - * based on the teles driver from Jan den Ouden + * low level stuff for Teles Memory IO isdn cards * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * based on the teles driver from Jan den Ouden + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * * Thanks to Jan den Ouden * Fritz Elfert * Beat Doebeli * - * This file is (c) under GNU General Public License - * */ + #define __NO_VERSION__ #include <linux/init.h> #include "hisax.h" @@ -21,7 +24,7 @@ extern const char *CardType[]; -const char *teles0_revision = "$Revision: 2.13.6.1 $"; +const char *teles0_revision = "$Revision: 2.13.6.2 $"; #define TELES_IOMEM_SIZE 0x400 #define byteout(addr,val) outb(val,addr) diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c index 6686f493b193..ee1574bd81fa 100644 --- a/drivers/isdn/hisax/teles3.c +++ b/drivers/isdn/hisax/teles3.c @@ -1,17 +1,17 @@ -/* $Id: teles3.c,v 2.17.6.1 2001/02/16 16:43:29 kai Exp $ +/* $Id: teles3.c,v 2.17.6.2 2001/09/23 22:24:52 kai Exp $ * - * teles3.c low level stuff for Teles 16.3 & PNP isdn cards + * low level stuff for Teles 16.3 & PNP isdn cards * - * based on the teles driver from Jan den Ouden - * - * Author Karsten Keil (keil@isdn4linux.de) + * Author Karsten Keil + * Copyright by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * * Thanks to Jan den Ouden * Fritz Elfert * Beat Doebeli * - * This file is (c) under GNU General Public License - * */ #define __NO_VERSION__ #include <linux/init.h> @@ -21,7 +21,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *teles3_revision = "$Revision: 2.17.6.1 $"; +const char *teles3_revision = "$Revision: 2.17.6.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index 36c165c5f8b1..f37a2702d169 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c @@ -1,13 +1,17 @@ -/* $Id: telespci.c,v 2.16.6.4 2001/02/16 16:43:29 kai Exp $ +/* $Id: telespci.c,v 2.16.6.5 2001/09/23 22:24:52 kai Exp $ * - * telespci.c low level stuff for Teles PCI isdn cards + * low level stuff for Teles PCI isdn cards * - * Author Ton van Rosmalen - * Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License + * Author Ton van Rosmalen + * Karsten Keil + * Copyright by Ton van Rosmalen + * by Karsten Keil <keil@isdn4linux.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #define __NO_VERSION__ #include <linux/init.h> #include <linux/config.h> @@ -18,7 +22,7 @@ #include <linux/pci.h> extern const char *CardType[]; -const char *telespci_revision = "$Revision: 2.16.6.4 $"; +const char *telespci_revision = "$Revision: 2.16.6.5 $"; #define ZORAN_PO_RQ_PEN 0x02000000 #define ZORAN_PO_WR 0x00800000 diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c index ae719d50fea9..d8e82616c30a 100644 --- a/drivers/isdn/hisax/w6692.c +++ b/drivers/isdn/hisax/w6692.c @@ -1,11 +1,12 @@ -/* $Id: w6692.c,v 1.12.6.5 2001/06/09 15:14:18 kai Exp $ +/* $Id: w6692.c,v 1.12.6.6 2001/09/23 22:24:52 kai Exp $ * - * w6692.c Winbond W6692 specific routines + * Winbond W6692 specific routines * - * Author Petr Novak <petr.novak@i.cz> - * (based on HiSax driver by Karsten Keil) - * - * This file is (c) under GNU General Public License + * Author Petr Novak + * Copyright by Petr Novak <petr.novak@i.cz> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -35,7 +36,7 @@ static const PCI_ENTRY id_list[] = extern const char *CardType[]; -const char *w6692_revision = "$Revision: 1.12.6.5 $"; +const char *w6692_revision = "$Revision: 1.12.6.6 $"; #define DBUSY_TIMER_VALUE 80 diff --git a/drivers/isdn/hisax/w6692.h b/drivers/isdn/hisax/w6692.h index 977ae341d2d9..9d4617418d79 100644 --- a/drivers/isdn/hisax/w6692.h +++ b/drivers/isdn/hisax/w6692.h @@ -1,10 +1,12 @@ -/* $Id: w6692.h,v 1.2.6.1 2001/02/16 16:43:29 kai Exp $ +/* $Id: w6692.h,v 1.2.6.2 2001/09/23 22:24:52 kai Exp $ * - * w6692.h Winbond W6692 specific defines + * Winbond W6692 specific defines * - * Author Petr Novak <petr.novak@i.cz> - * - * This file is (c) under GNU General Public License + * Author Petr Novak + * Copyright by Petr Novak <petr.novak@i.cz> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c index d95f98231edd..653349abc471 100644 --- a/drivers/isdn/hysdn/boardergo.c +++ b/drivers/isdn/hysdn/boardergo.c @@ -1,41 +1,27 @@ -/* $Id: boardergo.c,v 1.5.6.5 2001/07/18 16:02:16 kai Exp $ - +/* $Id: boardergo.c,v 1.5.6.6 2001/09/23 22:24:54 kai Exp $ + * * Linux driver for HYSDN cards, specific routines for ergo type boards. * + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * * As all Linux supported cards Champ2, Ergo and Metro2/4 use the same * DPRAM interface and layout with only minor differences all related * stuff is done here, not in separate modules. * - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH - * - * Copyright 1999 by Werner Cornelius (werner@titro.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * */ -#define __NO_VERSION__ #include <linux/config.h> -#include <linux/module.h> -#include <linux/version.h> -#include <asm/io.h> +#include <linux/sched.h> #include <linux/signal.h> #include <linux/kernel.h> #include <linux/ioport.h> #include <linux/interrupt.h> #include <linux/vmalloc.h> +#include <asm/io.h> #include "hysdn_defs.h" #include "boardergo.h" diff --git a/drivers/isdn/hysdn/boardergo.h b/drivers/isdn/hysdn/boardergo.h index 224d1823aa6d..b56ff0889ead 100644 --- a/drivers/isdn/hysdn/boardergo.h +++ b/drivers/isdn/hysdn/boardergo.h @@ -1,23 +1,12 @@ -/* $Id: boardergo.h,v 1.2 2000/11/13 22:51:47 kai Exp $ - - * Linux driver for HYSDN cards, definitions for ergo type boards (buffers..). - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH +/* $Id: boardergo.h,v 1.2.6.1 2001/09/23 22:24:54 kai Exp $ * - * Copyright 1999 by Werner Cornelius (werner@titro.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Linux driver for HYSDN cards, definitions for ergo type boards (buffers..). * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index 9c2e3f4ca4ee..9f5d35444f69 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c @@ -1,27 +1,15 @@ -/* $Id: hycapi.c,v 1.8.6.3 2001/05/26 15:19:58 kai Exp $ +/* $Id: hycapi.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $ * * Linux driver for HYSDN cards, CAPI2.0-Interface. - * written by Ulrich Albrecht (u.albrecht@hypercope.de) for Hypercope GmbH * + * Author Ulrich Albrecht <u.albrecht@hypercope.de> for Hypercope GmbH * Copyright 2000 by Hypercope GmbH * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ -#define __NO_VERSION__ #include <linux/module.h> #include <linux/version.h> #include <linux/signal.h> @@ -41,7 +29,7 @@ #include "hysdn_defs.h" #include <linux/kernelcapi.h> -static char hycapi_revision[]="$Revision: 1.8.6.3 $"; +static char hycapi_revision[]="$Revision: 1.8.6.4 $"; unsigned int hycapi_enable = 0xffffffff; MODULE_PARM(hycapi_enable, "i"); diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c index 8c5517e2195a..25e4fe68fa3f 100644 --- a/drivers/isdn/hysdn/hysdn_boot.c +++ b/drivers/isdn/hysdn/hysdn_boot.c @@ -1,30 +1,16 @@ -/* $Id: hysdn_boot.c,v 1.4.6.3 2001/03/13 16:17:09 kai Exp $ - - * Linux driver for HYSDN cards, specific routines for booting and pof handling. - * - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH - * - * Copyright 1999 by Werner Cornelius (werner@titro.de) +/* $Id: hysdn_boot.c,v 1.4.6.4 2001/09/23 22:24:54 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Linux driver for HYSDN cards + * specific routines for booting and pof handling * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ -#define __NO_VERSION__ -#include <linux/module.h> -#include <linux/version.h> #include <linux/vmalloc.h> #include <linux/slab.h> #include <asm/uaccess.h> diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h index 27bc620913bf..13eb45f56792 100644 --- a/drivers/isdn/hysdn/hysdn_defs.h +++ b/drivers/isdn/hysdn/hysdn_defs.h @@ -1,23 +1,13 @@ -/* $Id: hysdn_defs.h,v 1.5.6.2 2001/04/20 02:42:00 keil Exp $ - - * Linux driver for HYSDN cards, global definitions and exported vars and functions. - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH - * - * Copyright 1999 by Werner Cornelius (werner@titro.de) +/* $Id: hysdn_defs.h,v 1.5.6.3 2001/09/23 22:24:54 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Linux driver for HYSDN cards + * global definitions and exported vars and functions. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c index a676bfdd3e4d..5f8012b9ac83 100644 --- a/drivers/isdn/hysdn/hysdn_init.c +++ b/drivers/isdn/hysdn/hysdn_init.c @@ -1,23 +1,12 @@ -/* $Id: hysdn_init.c,v 1.6.6.5 2001/02/16 16:43:30 kai Exp $ - - * Linux driver for HYSDN cards, init functions. - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH - * - * Copyright 1999 by Werner Cornelius (werner@titro.de) +/* $Id: hysdn_init.c,v 1.6.6.6 2001/09/23 22:24:54 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Linux driver for HYSDN cards, init functions. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -32,7 +21,19 @@ #include "hysdn_defs.h" -static char *hysdn_init_revision = "$Revision: 1.6.6.5 $"; +static struct pci_device_id hysdn_pci_tbl[] __initdata = { + {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO}, + {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2}, + {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO}, + {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO}, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(pci, hysdn_pci_tbl); +MODULE_DESCRIPTION("ISDN4Linux: Driver for HYSDN cards"); +MODULE_AUTHOR("Werner Cornelius"); +MODULE_LICENSE("GPL"); + +static char *hysdn_init_revision = "$Revision: 1.6.6.6 $"; int cardmax; /* number of found cards */ hysdn_card *card_root = NULL; /* pointer to first card */ @@ -62,14 +63,6 @@ static struct { } /* terminating entry */ }; -static struct pci_device_id hysdn_pci_tbl[] __initdata = { - {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO}, - {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2}, - {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO}, - {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO}, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(pci, hysdn_pci_tbl); /*********************************************************************/ /* search_cards searches for available cards in the pci config data. */ diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c index 5f1783b9bbb1..8437a6323922 100644 --- a/drivers/isdn/hysdn/hysdn_net.c +++ b/drivers/isdn/hysdn/hysdn_net.c @@ -1,28 +1,16 @@ -/* $Id: hysdn_net.c,v 1.8.6.3 2001/06/05 19:45:37 kai Exp $ - +/* $Id: hysdn_net.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $ + * * Linux driver for HYSDN cards, net (ethernet type) handling routines. * - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * Copyright 1999 by Werner Cornelius (werner@titro.de) + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * * This net module has been inspired by the skeleton driver from * Donald Becker (becker@CESDIS.gsfc.nasa.gov) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * */ #define __NO_VERSION__ @@ -41,7 +29,7 @@ unsigned int hynet_enable = 0xffffffff; MODULE_PARM(hynet_enable, "i"); /* store the actual version for log reporting */ -char *hysdn_net_revision = "$Revision: 1.8.6.3 $"; +char *hysdn_net_revision = "$Revision: 1.8.6.4 $"; #define MAX_SKB_BUFFERS 20 /* number of buffers for keeping TX-data */ diff --git a/drivers/isdn/hysdn/hysdn_pof.h b/drivers/isdn/hysdn/hysdn_pof.h index 524b7a0ae9c5..6cd81b9b08bc 100644 --- a/drivers/isdn/hysdn/hysdn_pof.h +++ b/drivers/isdn/hysdn/hysdn_pof.h @@ -1,23 +1,12 @@ -/* $Id: hysdn_pof.h,v 1.2 2000/11/13 22:51:47 kai Exp $ - - * Linux driver for HYSDN cards, definitions used for handling pof-files. - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH +/* $Id: hysdn_pof.h,v 1.2.6.1 2001/09/23 22:24:54 kai Exp $ * - * Copyright 1999 by Werner Cornelius (werner@titro.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Linux driver for HYSDN cards, definitions used for handling pof-files. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index eae62dfd2489..e1d80ec18371 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c @@ -1,23 +1,13 @@ -/* $Id: hysdn_procconf.c,v 1.8.6.3 2001/08/13 07:46:15 kai Exp $ - +/* $Id: hysdn_procconf.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $ + * * Linux driver for HYSDN cards, /proc/net filesystem dir and conf functions. + * * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH * * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -31,7 +21,7 @@ #include "hysdn_defs.h" -static char *hysdn_procconf_revision = "$Revision: 1.8.6.3 $"; +static char *hysdn_procconf_revision = "$Revision: 1.8.6.4 $"; #define INFO_OUT_LEN 80 /* length of info line including lf */ @@ -456,4 +446,4 @@ hysdn_procconf_release(void) } remove_proc_entry(PROC_SUBDIR_NAME, proc_net); -} /* hysdn_procfs_release */ +} diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index af1c50a9ed42..b97d3201d4be 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -1,23 +1,12 @@ -/* $Id: hysdn_proclog.c,v 1.9.6.2 2001/08/13 07:46:15 kai Exp $ - - * Linux driver for HYSDN cards, /proc/net filesystem log functions. - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH +/* $Id: hysdn_proclog.c,v 1.9.6.3 2001/09/23 22:24:54 kai Exp $ * - * Copyright 1999 by Werner Cornelius (werner@titro.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Linux driver for HYSDN cards, /proc/net filesystem log functions. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c index c6066bb85390..d823b0f07f48 100644 --- a/drivers/isdn/hysdn/hysdn_sched.c +++ b/drivers/isdn/hysdn/hysdn_sched.c @@ -1,36 +1,23 @@ -/* $Id: hysdn_sched.c,v 1.5.6.2 2001/04/20 02:42:00 keil Exp $ - - * Linux driver for HYSDN cards, scheduler routines for handling exchange card <-> pc. - * - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH - * - * Copyright 1999 by Werner Cornelius (werner@titro.de) +/* $Id: hysdn_sched.c,v 1.5.6.3 2001/09/23 22:24:54 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Linux driver for HYSDN cards + * scheduler routines for handling exchange card <-> pc. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ -#define __NO_VERSION__ #include <linux/config.h> -#include <linux/module.h> -#include <linux/version.h> -#include <asm/io.h> +#include <linux/sched.h> #include <linux/signal.h> #include <linux/kernel.h> #include <linux/ioport.h> #include <linux/interrupt.h> +#include <asm/io.h> #include "hysdn_defs.h" diff --git a/drivers/isdn/hysdn/ince1pc.h b/drivers/isdn/hysdn/ince1pc.h index 9f9d3104dd28..4a115a87c782 100644 --- a/drivers/isdn/hysdn/ince1pc.h +++ b/drivers/isdn/hysdn/ince1pc.h @@ -1,18 +1,20 @@ +/* + * Linux driver for HYSDN cards + * common definitions for both sides of the bus: + * - conventions both spoolers must know + * - channel numbers agreed upon + * + * Author M. Steinkopf + * Copyright 1999 by M. Steinkopf + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ + #ifndef __INCE1PC_H__ #define __INCE1PC_H__ -/**************************************************************************** - - FILE: ince1pc.h - - AUTHOR: M.Steinkopf - - PURPOSE: common definitions for both sides of the bus: - - conventions both spoolers must know - - channel numbers agreed upon - -*****************************************************************************/ - /* basic scalar definitions have same meanning, * but their declaration location depends on environment */ diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index d64b9cf7c2e1..22061b2f6925 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c @@ -1,28 +1,35 @@ -/* $Id: icn.c,v 1.65.6.7 2001/08/17 12:34:27 kai Exp $ - +/* $Id: icn.c,v 1.65.6.8 2001/09/23 22:24:55 kai Exp $ + * * ISDN low-level module for the ICN active ISDN-Card. * * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ #include "icn.h" +#include <linux/module.h> #include <linux/init.h> +static int portbase = ICN_BASEADDR; +static unsigned long membase = ICN_MEMADDR; +static char *icn_id = "\0"; +static char *icn_id2 = "\0"; + +MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card"); +MODULE_AUTHOR("Fritz Elfert"); +MODULE_LICENSE("GPL"); +MODULE_PARM(portbase, "i"); +MODULE_PARM_DESC(portbase, "Port address of first card"); +MODULE_PARM(membase, "l"); +MODULE_PARM_DESC(membase, "Shared memory address of all cards"); +MODULE_PARM(icn_id, "s"); +MODULE_PARM_DESC(icn_id, "ID-String of first card"); +MODULE_PARM(icn_id2, "s"); +MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)"); + /* * Verbose bootcode- and protocol-downloading. */ @@ -34,7 +41,7 @@ #undef MAP_DEBUG static char -*revision = "$Revision: 1.65.6.7 $"; +*revision = "$Revision: 1.65.6.8 $"; static int icn_addcard(int, char *, char *); @@ -607,7 +614,7 @@ icn_polldchan(unsigned long data) int left; u_char c; int ch; - long flags; + unsigned long flags; int i; u_char *p; isdn_ctrl cmd; diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h index 281b85735dc7..82234568cb3a 100644 --- a/drivers/isdn/icn/icn.h +++ b/drivers/isdn/icn/icn.h @@ -1,22 +1,11 @@ -/* $Id: icn.h,v 1.30.6.4 2001/08/17 12:34:27 kai Exp $ - +/* $Id: icn.h,v 1.30.6.5 2001/09/23 22:24:55 kai Exp $ + * * ISDN lowlevel-module for the ICN active ISDN-Card. * * Copyright 1994 by Fritz Elfert (fritz@isdn4linux.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -46,7 +35,6 @@ typedef struct icn_cdef { #ifdef __KERNEL__ /* Kernel includes */ -#include <linux/module.h> #include <linux/version.h> #include <linux/errno.h> #include <linux/fs.h> @@ -206,27 +194,6 @@ static u_char chan2bank[] = static icn_dev dev; -/* With modutils >= 1.1.67 Integers can be changed while loading a - * module. For this reason define the Port-Base an Shmem-Base as - * integers. - */ -static int portbase = ICN_BASEADDR; -static unsigned long membase = ICN_MEMADDR; -static char *icn_id = "\0"; -static char *icn_id2 = "\0"; - -#ifdef MODULE -MODULE_AUTHOR("Fritz Elfert"); -MODULE_PARM(portbase, "i"); -MODULE_PARM_DESC(portbase, "Port address of first card"); -MODULE_PARM(membase, "l"); -MODULE_PARM_DESC(membase, "Shared memory address of all cards"); -MODULE_PARM(icn_id, "s"); -MODULE_PARM_DESC(icn_id, "ID-String of first card"); -MODULE_PARM(icn_id2, "s"); -MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)"); -#endif - #endif /* __KERNEL__ */ /* Utility-Macros */ diff --git a/drivers/isdn/isdn_audio.c b/drivers/isdn/isdn_audio.c index d5f05e029b0c..164d3a160468 100644 --- a/drivers/isdn/isdn_audio.c +++ b/drivers/isdn/isdn_audio.c @@ -1,34 +1,21 @@ -/* $Id: isdn_audio.c,v 1.21.6.1 2001/08/17 12:34:25 kai Exp $ - +/* $Id: isdn_audio.c,v 1.21.6.2 2001/09/23 22:24:31 kai Exp $ + * * Linux ISDN subsystem, audio conversion and compression (linklevel). * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * DTMF code (c) 1996 by Christian Mock (cm@kukuruz.ping.at) * Silence detection (c) 1998 by Armin Schindler (mac@gismo.telekom.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ -#define __NO_VERSION__ -#include <linux/module.h> #include <linux/isdn.h> #include "isdn_audio.h" #include "isdn_common.h" -char *isdn_audio_revision = "$Revision: 1.21.6.1 $"; +char *isdn_audio_revision = "$Revision: 1.21.6.2 $"; /* * Misc. lookup-tables. diff --git a/drivers/isdn/isdn_audio.h b/drivers/isdn/isdn_audio.h index 09c1651b1b13..e60c980c953a 100644 --- a/drivers/isdn/isdn_audio.h +++ b/drivers/isdn/isdn_audio.h @@ -1,22 +1,11 @@ -/* $Id: isdn_audio.h,v 1.9 2000/05/11 22:29:20 kai Exp $ - +/* $Id: isdn_audio.h,v 1.9.6.1 2001/09/23 22:24:31 kai Exp $ + * * Linux ISDN subsystem, audio conversion and compression (linklevel). * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/isdn_bsdcomp.c b/drivers/isdn/isdn_bsdcomp.c index 7e40a3d3def4..5daac5e35983 100644 --- a/drivers/isdn/isdn_bsdcomp.c +++ b/drivers/isdn/isdn_bsdcomp.c @@ -4,8 +4,14 @@ * Patched version for ISDN syncPPP written 1997/1998 by Michael Hipp * The whole module is now SKB based. * - * Compile with: - * gcc -O2 -I/usr/src/linux/include -D__KERNEL__ -DMODULE -c isdn_bsdcomp.c + */ + +/* + * Update: The Berkeley copyright was changed, and the change + * is retroactive to all "true" BSD software (ie everything + * from UCB as opposed to other peoples code that just carried + * the same license). The new copyright doesn't clash with the + * GPL, so the module-only restriction has been removed.. */ /* @@ -82,7 +88,6 @@ #include <linux/isdn.h> #include <linux/isdn_ppp.h> -/* #include <linux/netprotocol.h> */ #include <linux/ip.h> #include <linux/tcp.h> #include <linux/if_arp.h> @@ -90,6 +95,9 @@ #include "isdn_ppp.h" +MODULE_DESCRIPTION("ISDN4Linux: BSD Compression for PPP over ISDN"); +MODULE_LICENSE("Dual BSD/GPL"); + #define BSD_VERSION(x) ((x) >> 5) #define BSD_NBITS(x) ((x) & 0x1F) diff --git a/drivers/isdn/isdn_common.c b/drivers/isdn/isdn_common.c index e7d1ae1188e5..130710926447 100644 --- a/drivers/isdn/isdn_common.c +++ b/drivers/isdn/isdn_common.c @@ -1,24 +1,13 @@ -/* $Id: isdn_common.c,v 1.114.6.14 2001/08/17 12:34:25 kai Exp $ - +/* $Id: isdn_common.c,v 1.114.6.15 2001/09/23 22:24:31 kai Exp $ + * * Linux ISDN subsystem, common used functions (linklevel). * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -49,9 +38,13 @@ /* Debugflags */ #undef ISDN_DEBUG_STATCALLB +MODULE_DESCRIPTION("ISDN4Linux: link layer"); +MODULE_AUTHOR("Fritz Elfert"); +MODULE_LICENSE("GPL"); + isdn_dev *dev; -static char *isdn_revision = "$Revision: 1.114.6.14 $"; +static char *isdn_revision = "$Revision: 1.114.6.15 $"; extern char *isdn_net_revision; extern char *isdn_tty_revision; @@ -280,7 +273,7 @@ isdn_timer_funct(ulong dummy) } if (tf) { - long flags; + unsigned long flags; save_flags(flags); cli(); @@ -292,7 +285,7 @@ isdn_timer_funct(ulong dummy) void isdn_timer_ctrl(int tf, int onoff) { - long flags; + unsigned long flags; int old_tflags; save_flags(flags); @@ -2397,7 +2390,7 @@ static int __init isdn_init(void) */ static void __exit isdn_exit(void) { - long flags; + unsigned long flags; int i; #ifdef CONFIG_ISDN_PPP diff --git a/drivers/isdn/isdn_common.h b/drivers/isdn/isdn_common.h index 3ee69282447b..2565366ffeab 100644 --- a/drivers/isdn/isdn_common.h +++ b/drivers/isdn/isdn_common.h @@ -1,24 +1,14 @@ -/* $Id: isdn_common.h,v 1.21 2000/11/25 17:00:59 kai Exp $ - - * header for Linux ISDN subsystem, common used functions and debugging-switches (linklevel). +/* $Id: isdn_common.h,v 1.21.6.1 2001/09/23 22:24:31 kai Exp $ + * + * header for Linux ISDN subsystem + * common used functions and debugging-switches (linklevel). * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/isdn_concap.c b/drivers/isdn/isdn_concap.c index 73d18629fd50..03004194cbbd 100644 --- a/drivers/isdn/isdn_concap.c +++ b/drivers/isdn/isdn_concap.c @@ -1,20 +1,9 @@ -/* $Id: isdn_concap.c,v 1.8 2000/05/11 22:29:20 kai Exp $ - +/* $Id: isdn_concap.c,v 1.8.6.1 2001/09/23 22:24:31 kai Exp $ + * * Linux ISDN subsystem, protocol encapsulation * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/isdn_concap.h b/drivers/isdn/isdn_concap.h index 507b05e4226f..d4e9d936945a 100644 --- a/drivers/isdn/isdn_concap.h +++ b/drivers/isdn/isdn_concap.h @@ -1,20 +1,9 @@ -/* $Id: isdn_concap.h,v 1.3 2000/05/11 22:29:20 kai Exp $ +/* $Id: isdn_concap.h,v 1.3.6.1 2001/09/23 22:24:31 kai Exp $ * * Linux ISDN subsystem, protocol encapsulation * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/isdn_net.c b/drivers/isdn/isdn_net.c index 4cebdc5b7612..2d1e30e9340d 100644 --- a/drivers/isdn/isdn_net.c +++ b/drivers/isdn/isdn_net.c @@ -1,35 +1,20 @@ -/* $Id: isdn_net.c,v 1.140.6.8 2001/08/14 14:04:21 kai Exp $ - +/* $Id: isdn_net.c,v 1.140.6.10 2001/09/28 08:05:29 kai Exp $ + * * Linux ISDN subsystem, network interfaces and related functions (linklevel). * * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* Jan 2001: fix CISCO HDLC Bjoern A. Zeeb <i4l@zabbadoz.net> + * Jan 2001: fix CISCO HDLC Bjoern A. Zeeb <i4l@zabbadoz.net> * for info on the protocol, see * http://i4l.zabbadoz.net/i4l/cisco-hdlc.txt */ #include <linux/config.h> -#define __NO_VERSION__ -#include <linux/module.h> #include <linux/isdn.h> #include <net/arp.h> #include <net/dst.h> @@ -190,7 +175,7 @@ static int isdn_net_start_xmit(struct sk_buff *, struct net_device *); static void isdn_net_ciscohdlck_connected(isdn_net_local *lp); static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp); -char *isdn_net_revision = "$Revision: 1.140.6.8 $"; +char *isdn_net_revision = "$Revision: 1.140.6.10 $"; /* * Code for raw-networking over ISDN @@ -583,7 +568,7 @@ isdn_net_dial(void) isdn_net_dev *p = dev->netdev; int anymore = 0; int i; - ulong flags; + unsigned long flags; isdn_ctrl cmd; while (p) { @@ -1673,10 +1658,11 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb) { unsigned char *p; int period; - __u32 code; - __u32 my_seq, addr; - __u32 your_seq, mask; - __u16 unused; + u32 code; + u32 my_seq, addr; + u32 your_seq, mask; + u32 local; + u16 unused; if (skb->len < 14) return; @@ -1690,14 +1676,27 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb) isdn_net_ciscohdlck_slarp_send_reply(lp); break; case CISCO_SLARP_REPLY: - /* Ignore replies - at least for now */ - if (lp->cisco_debserint) { - p += get_u32(p, &addr); - p += get_u32(p, &mask); - p += get_u16(p, &unused); - printk(KERN_DEBUG "%s: got slarp reply (%ul/%ul) - " - "ignored\n", lp->name, addr, mask); - } + addr = ntohl(*(u32 *)p); + mask = ntohl(*(u32 *)(p+4)); + if (mask != 0xfffffffc) + goto slarp_reply_out; + if ((addr & 3) == 0 || (addr & 3) == 3) + goto slarp_reply_out; + local = addr ^ 3; + printk(KERN_INFO "%s: got slarp reply: " + "remote ip: %d.%d.%d.%d, " + "local ip: %d.%d.%d.%d " + "mask: %d.%d.%d.%d\n", + lp->name, + HIPQUAD(addr), + HIPQUAD(local), + HIPQUAD(mask)); + break; + slarp_reply_out: + printk(KERN_INFO "%s: got invalid slarp " + "reply (%d.%d.%d.%d/%d.%d.%d.%d) " + "- ignored\n", lp->name, + HIPQUAD(addr), HIPQUAD(mask)); break; case CISCO_SLARP_KEEPALIVE: period = (int)((jiffies - lp->cisco_last_slarp_in @@ -1723,9 +1722,9 @@ static void isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb) { unsigned char *p; - __u8 addr; - __u8 ctrl; - __u16 type; + u8 addr; + u8 ctrl; + u16 type; if (skb->len < 4) goto out_free; @@ -2792,7 +2791,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg) chidx = lp->pre_channel; } if (cfg->exclusive > 0) { - ulong flags; + unsigned long flags; /* If binding is exclusive, try to grab the channel */ save_flags(flags); @@ -3048,7 +3047,7 @@ isdn_net_delphone(isdn_net_ioctl_phone * phone) int inout = phone->outgoing & 1; isdn_net_phone *n; isdn_net_phone *m; - ulong flags; + unsigned long flags; if (p) { save_flags(flags); @@ -3084,7 +3083,7 @@ isdn_net_rmallphone(isdn_net_dev * p) { isdn_net_phone *n; isdn_net_phone *m; - ulong flags; + unsigned long flags; int i; save_flags(flags); @@ -3133,7 +3132,7 @@ isdn_net_force_hangup(char *name) static int isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q) { - ulong flags; + unsigned long flags; save_flags(flags); cli(); @@ -3219,7 +3218,7 @@ isdn_net_rm(char *name) int isdn_net_rmall(void) { - ulong flags; + unsigned long flags; int ret; /* Walk through netdev-chain */ diff --git a/drivers/isdn/isdn_net.h b/drivers/isdn/isdn_net.h index 7b4a25baeb98..016d304c7174 100644 --- a/drivers/isdn/isdn_net.h +++ b/drivers/isdn/isdn_net.h @@ -1,24 +1,13 @@ -/* $Id: isdn_net.h,v 1.19.6.2 2001/08/14 14:04:21 kai Exp $ - +/* $Id: isdn_net.h,v 1.19.6.4 2001/09/28 08:05:29 kai Exp $ + * * header for Linux ISDN subsystem, network related functions (linklevel). * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -39,8 +28,8 @@ #define CISCO_TYPE_CDP 0x2000 #define CISCO_TYPE_INET 0x0800 #define CISCO_TYPE_SLARP 0x8035 -#define CISCO_SLARP_REPLY 0 -#define CISCO_SLARP_REQUEST 1 +#define CISCO_SLARP_REQUEST 0 +#define CISCO_SLARP_REPLY 1 #define CISCO_SLARP_KEEPALIVE 2 extern char *isdn_net_new(char *, struct net_device *); @@ -147,48 +136,44 @@ static __inline__ void isdn_net_rm_from_bundle(isdn_net_local *lp) } static inline int -put_u8(unsigned char *p, __u8 x) +put_u8(unsigned char *p, u8 x) { - p[0] = x; + *p = x; return 1; } static inline int -put_u16(unsigned char *p, __u16 x) +put_u16(unsigned char *p, u16 x) { - p[0] = x >> 8; - p[1] = x; + *((u16 *)p) = htons(x); return 2; } static inline int -put_u32(unsigned char *p, __u32 x) +put_u32(unsigned char *p, u32 x) { - p[0] = x >> 24; - p[1] = x >> 16; - p[2] = x >> 8; - p[3] = x; + *((u32 *)p) = htonl(x); return 4; } static inline int -get_u8(unsigned char *p, __u8 *x) +get_u8(unsigned char *p, u8 *x) { - *x = p[0]; + *x = *p; return 1; } static inline int -get_u16(unsigned char *p, __u16 *x) +get_u16(unsigned char *p, u16 *x) { - *x = (p[0] << 8) + p[1]; + *x = ntohs(*((u16 *)p)); return 2; } static inline int -get_u32(unsigned char *p, __u32 *x) +get_u32(unsigned char *p, u32 *x) { - *x = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; + *x = ntohl(*((u32 *)p)); return 4; } diff --git a/drivers/isdn/isdn_ppp.c b/drivers/isdn/isdn_ppp.c index fcdcc616af78..663a8db7e7fe 100644 --- a/drivers/isdn/isdn_ppp.c +++ b/drivers/isdn/isdn_ppp.c @@ -1,31 +1,17 @@ -/* $Id: isdn_ppp.c,v 1.85.6.6 2001/07/27 09:08:27 kai Exp $ +/* $Id: isdn_ppp.c,v 1.85.6.7 2001/09/23 22:24:31 kai Exp $ * * Linux ISDN subsystem, functions for synchronous PPP (linklevel). * * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ #include <linux/config.h> -#define __NO_VERSION__ -#include <linux/module.h> -#include <linux/version.h> -#include <linux/poll.h> #include <linux/isdn.h> +#include <linux/poll.h> #include <linux/ppp-comp.h> #include "isdn_common.h" @@ -83,7 +69,7 @@ static void isdn_ppp_mp_cleanup( isdn_net_local * lp ); static int isdn_ppp_bundle(struct ippp_struct *, int unit); #endif /* CONFIG_ISDN_MPP */ -char *isdn_ppp_revision = "$Revision: 1.85.6.6 $"; +char *isdn_ppp_revision = "$Revision: 1.85.6.7 $"; static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS]; diff --git a/drivers/isdn/isdn_ppp.h b/drivers/isdn/isdn_ppp.h index 6587cf84a567..4495b079f8cf 100644 --- a/drivers/isdn/isdn_ppp.h +++ b/drivers/isdn/isdn_ppp.h @@ -1,27 +1,17 @@ -/* $Id: isdn_ppp.h,v 1.17 2000/08/10 22:52:46 kai Exp $ - +/* $Id: isdn_ppp.h,v 1.17.6.1 2001/09/23 22:24:32 kai Exp $ + * * header for Linux ISDN subsystem, functions for synchronous PPP (linklevel). * * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ #include <linux/ppp_defs.h> /* for PPP_PROTOCOL */ #include <linux/isdn_ppp.h> /* for isdn_ppp info */ + extern int isdn_ppp_read(int, struct file *, char *, int); extern int isdn_ppp_write(int, struct file *, const char *, int); extern int isdn_ppp_open(int, struct file *); diff --git a/drivers/isdn/isdn_tty.c b/drivers/isdn/isdn_tty.c index a1e6d1b4180a..adc7377d8dc8 100644 --- a/drivers/isdn/isdn_tty.c +++ b/drivers/isdn/isdn_tty.c @@ -1,30 +1,17 @@ -/* $Id: isdn_tty.c,v 1.94.6.7 2001/08/27 22:19:04 kai Exp $ - +/* $Id: isdn_tty.c,v 1.94.6.8 2001/09/23 22:24:32 kai Exp $ + * * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel). * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ #undef ISDN_TTY_STAT_DEBUG -#define __NO_VERSION__ #include <linux/config.h> -#include <linux/module.h> #include <linux/isdn.h> #include "isdn_common.h" #include "isdn_tty.h" @@ -66,7 +53,7 @@ static int bit2si[8] = static int si2bit[8] = {4, 1, 4, 4, 4, 4, 4, 4}; -char *isdn_tty_revision = "$Revision: 1.94.6.7 $"; +char *isdn_tty_revision = "$Revision: 1.94.6.8 $"; /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb() diff --git a/drivers/isdn/isdn_tty.h b/drivers/isdn/isdn_tty.h index e2ce92c38d18..8cfdad6d7b89 100644 --- a/drivers/isdn/isdn_tty.h +++ b/drivers/isdn/isdn_tty.h @@ -1,23 +1,12 @@ -/* $Id: isdn_tty.h,v 1.22.6.1 2001/08/14 14:12:18 kai Exp $ - +/* $Id: isdn_tty.h,v 1.22.6.2 2001/09/23 22:24:32 kai Exp $ + * * header for Linux ISDN subsystem, tty related functions (linklevel). * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/isdn_ttyfax.c b/drivers/isdn/isdn_ttyfax.c index 0e6b9a35908f..26657d8c0e33 100644 --- a/drivers/isdn/isdn_ttyfax.c +++ b/drivers/isdn/isdn_ttyfax.c @@ -1,39 +1,26 @@ -/* $Id: isdn_ttyfax.c,v 1.7.6.1 2001/08/14 14:12:18 kai Exp $ - +/* $Id: isdn_ttyfax.c,v 1.7.6.2 2001/09/23 22:24:32 kai Exp $ + * * Linux ISDN subsystem, tty_fax AT-command emulator (linklevel). * * Copyright 1999 by Armin Schindler (mac@melware.de) * Copyright 1999 by Ralf Spachmann (mel@melware.de) * Copyright 1999 by Cytronics & Melware * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ #undef ISDN_TTY_FAX_STAT_DEBUG #undef ISDN_TTY_FAX_CMD_DEBUG -#define __NO_VERSION__ -#include <linux/module.h> #include <linux/isdn.h> #include "isdn_common.h" #include "isdn_tty.h" #include "isdn_ttyfax.h" -static char *isdn_tty_fax_revision = "$Revision: 1.7.6.1 $"; +static char *isdn_tty_fax_revision = "$Revision: 1.7.6.2 $"; #define PARSE_ERROR1 { isdn_tty_fax_modem_result(1, info); return 1; } diff --git a/drivers/isdn/isdn_ttyfax.h b/drivers/isdn/isdn_ttyfax.h index 6390eee2ccbc..244ada3ca127 100644 --- a/drivers/isdn/isdn_ttyfax.h +++ b/drivers/isdn/isdn_ttyfax.h @@ -1,24 +1,13 @@ -/* $Id: isdn_ttyfax.h,v 1.2 2000/05/11 22:29:21 kai Exp $ - +/* $Id: isdn_ttyfax.h,v 1.2.6.1 2001/09/23 22:24:32 kai Exp $ + * * header for Linux ISDN subsystem, tty_fax related functions (linklevel). * * Copyright 1999 by Armin Schindler (mac@melware.de) * Copyright 1999 by Ralf Spachmann (mel@melware.de) * Copyright 1999 by Cytronics & Melware * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/isdn_v110.c b/drivers/isdn/isdn_v110.c index bb897f8c0899..1c34adf9c448 100644 --- a/drivers/isdn/isdn_v110.c +++ b/drivers/isdn/isdn_v110.c @@ -1,22 +1,11 @@ -/* $Id: isdn_v110.c,v 1.5.6.3 2001/02/16 16:43:23 kai Exp $ - +/* $Id: isdn_v110.c,v 1.5.6.4 2001/09/23 22:24:32 kai Exp $ + * * Linux ISDN subsystem, V.110 related functions (linklevel). * * Copyright by Thomas Pfeiffer (pfeiffer@pds.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -30,7 +19,7 @@ #undef ISDN_V110_DEBUG -char *isdn_v110_revision = "$Revision: 1.5.6.3 $"; +char *isdn_v110_revision = "$Revision: 1.5.6.4 $"; #define V110_38400 255 #define V110_19200 15 diff --git a/drivers/isdn/isdn_v110.h b/drivers/isdn/isdn_v110.h index 553ba86ab5cf..d557a769021d 100644 --- a/drivers/isdn/isdn_v110.h +++ b/drivers/isdn/isdn_v110.h @@ -1,24 +1,14 @@ -/* $Id: isdn_v110.h,v 1.4 2000/05/11 22:29:21 kai Exp $ - +/* $Id: isdn_v110.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $ + * * Linux ISDN subsystem, V.110 related functions (linklevel). * * Copyright by Thomas Pfeiffer (pfeiffer@pds.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ + #ifndef _isdn_v110_h_ #define _isdn_v110_h_ diff --git a/drivers/isdn/isdn_x25iface.c b/drivers/isdn/isdn_x25iface.c index 591608915aa0..edbf4eed016d 100644 --- a/drivers/isdn/isdn_x25iface.c +++ b/drivers/isdn/isdn_x25iface.c @@ -1,22 +1,9 @@ -/* $Id: isdn_x25iface.c,v 1.9 2000/05/16 20:52:10 keil Exp $ - +/* $Id: isdn_x25iface.c,v 1.9.6.1 2001/09/23 22:24:32 kai Exp $ * * Linux ISDN subsystem, X.25 related functions * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * * stuff needed to support the Linux X.25 PLP code on top of devices that * can provide a lab_b service using the concap_proto mechanism. diff --git a/drivers/isdn/isdn_x25iface.h b/drivers/isdn/isdn_x25iface.h index 97024e261457..ef69d3af9628 100644 --- a/drivers/isdn/isdn_x25iface.h +++ b/drivers/isdn/isdn_x25iface.h @@ -1,20 +1,9 @@ -/* $Id: isdn_x25iface.h,v 1.3 2000/05/11 22:29:21 kai Exp $ - - * header for Linux ISDN subsystem, x.25 related functions +/* $Id: isdn_x25iface.h,v 1.3.6.1 2001/09/23 22:24:32 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * header for Linux ISDN subsystem, x.25 related functions * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index f541fb653d0f..18f9d10e8073 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c @@ -1,22 +1,11 @@ -/* $Id: isdnloop.c,v 1.11.6.5 2001/08/17 12:34:27 kai Exp $ - +/* $Id: isdnloop.c,v 1.11.6.6 2001/09/23 22:24:56 kai Exp $ + * * ISDN low-level module implementing a dummy loop driver. * * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -25,8 +14,14 @@ #include <linux/init.h> #include "isdnloop.h" -static char -*revision = "$Revision: 1.11.6.5 $"; +static char *revision = "$Revision: 1.11.6.6 $"; +static char *isdnloop_id; + +MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card"); +MODULE_AUTHOR("Fritz Elfert"); +MODULE_LICENSE("GPL"); +MODULE_PARM(isdnloop_id, "s"); +MODULE_PARM_DESC(isdnloop_id, "ID-String of first card"); static int isdnloop_addcard(char *); diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h index 1a59ba57dc87..138e4cae6ef2 100644 --- a/drivers/isdn/isdnloop/isdnloop.h +++ b/drivers/isdn/isdnloop/isdnloop.h @@ -1,22 +1,11 @@ -/* $Id: isdnloop.h,v 1.5.6.2 2001/08/17 12:34:27 kai Exp $ - +/* $Id: isdnloop.h,v 1.5.6.3 2001/09/23 22:24:56 kai Exp $ + * * Loopback lowlevel module for testing of linklevel. * * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ @@ -44,7 +33,6 @@ typedef struct isdnloop_sdef { #ifdef __KERNEL__ /* Kernel includes */ -#include <linux/module.h> #include <linux/version.h> #include <linux/errno.h> #include <linux/fs.h> @@ -115,14 +103,6 @@ typedef struct isdnloop_card { */ #ifdef __KERNEL__ static isdnloop_card *cards = (isdnloop_card *) 0; -static char *isdnloop_id = "\0"; - -#ifdef MODULE -MODULE_AUTHOR("Fritz Elfert"); -MODULE_PARM(isdnloop_id, "s"); -MODULE_PARM_DESC(isdnloop_id, "ID-String of first card"); -#endif - #endif /* __KERNEL__ */ /* Utility-Macros */ diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c index ab67ae3f2253..92a48172bea6 100644 --- a/drivers/isdn/pcbit/callbacks.c +++ b/drivers/isdn/pcbit/callbacks.c @@ -1,4 +1,6 @@ /* + * Callbacks for the FSM + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -7,21 +9,12 @@ * the GNU General Public License, incorporated herein by reference. */ -/* - * callbacks for the FSM - */ - /* * Fix: 19981230 - Carlos Morgado <chbm@techie.com> * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN * NULL pointer dereference in cb_in_1 (originally fixed in 2.0) */ - -#define __NO_VERSION__ - -#include <linux/module.h> - #include <linux/sched.h> #include <linux/string.h> #include <linux/kernel.h> diff --git a/drivers/isdn/pcbit/callbacks.h b/drivers/isdn/pcbit/callbacks.h index 559b812e093b..f510dc56b57e 100644 --- a/drivers/isdn/pcbit/callbacks.h +++ b/drivers/isdn/pcbit/callbacks.h @@ -1,4 +1,6 @@ /* + * Callbacks prototypes for FSM + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -7,11 +9,6 @@ * the GNU General Public License, incorporated herein by reference. */ -/* - * Callbacks prototypes for FSM - * - */ - #ifndef CALLBACKS_H #define CALLBACKS_H diff --git a/drivers/isdn/pcbit/capi.c b/drivers/isdn/pcbit/capi.c index 60057c9bdb9b..2c882600787a 100644 --- a/drivers/isdn/pcbit/capi.c +++ b/drivers/isdn/pcbit/capi.c @@ -1,17 +1,16 @@ /* + * CAPI encoder/decoder for + * Portugal Telecom CAPI 2.0 + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) * * This software may be used and distributed according to the terms of * the GNU General Public License, incorporated herein by reference. - */ - -/* - * CAPI encoder/decoder for - * Portugal Telecom CAPI 2.0 * - * Not compatible with the AVM Gmbh. CAPI 2.0 + * Not compatible with the AVM Gmbh. CAPI 2.0 + * */ /* @@ -28,10 +27,6 @@ * encode our number in CallerPN and ConnectedPN */ -#define __NO_VERSION__ - -#include <linux/module.h> - #include <linux/sched.h> #include <linux/string.h> #include <linux/kernel.h> diff --git a/drivers/isdn/pcbit/capi.h b/drivers/isdn/pcbit/capi.h index 0d960f83a16c..a71cabad9727 100644 --- a/drivers/isdn/pcbit/capi.h +++ b/drivers/isdn/pcbit/capi.h @@ -1,4 +1,6 @@ /* + * CAPI encode/decode prototypes and defines + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -7,10 +9,6 @@ * the GNU General Public License, incorporated herein by reference. */ -/* - * CAPI encode/decode prototypes and defines - */ - #ifndef CAPI_H #define CAPI_H diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c index 13912b59d455..4bf81515e9e2 100644 --- a/drivers/isdn/pcbit/drv.c +++ b/drivers/isdn/pcbit/drv.c @@ -1,4 +1,6 @@ /* + * PCBIT-D interface with isdn4linux + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -7,10 +9,6 @@ * the GNU General Public License, incorporated herein by reference. */ -/* - * PCBIT-D interface with isdn4linux - */ - /* * Fixes: * diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c index e005341fc3df..088e679ecd86 100644 --- a/drivers/isdn/pcbit/edss1.c +++ b/drivers/isdn/pcbit/edss1.c @@ -1,4 +1,7 @@ /* + * DSS.1 Finite State Machine + * base: ITU-T Rec Q.931 + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -7,20 +10,11 @@ * the GNU General Public License, incorporated herein by reference. */ -/* - * DSS.1 Finite State Machine - * base: ITU-T Rec Q.931 - */ - /* * TODO: complete the FSM * move state/event descriptions to a user space logger */ -#define __NO_VERSION__ - -#include <linux/module.h> - #include <linux/sched.h> #include <linux/string.h> #include <linux/kernel.h> diff --git a/drivers/isdn/pcbit/edss1.h b/drivers/isdn/pcbit/edss1.h index 22befde381a0..6bb587005b86 100644 --- a/drivers/isdn/pcbit/edss1.h +++ b/drivers/isdn/pcbit/edss1.h @@ -1,4 +1,6 @@ /* + * DSS.1 module definitions + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -7,10 +9,6 @@ * the GNU General Public License, incorporated herein by reference. */ -/* - * DSS.1 module definitions - */ - #ifndef EDSS1_H #define EDSS1_H diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c index 7b0ac469a687..de23be7edd6c 100644 --- a/drivers/isdn/pcbit/layer2.c +++ b/drivers/isdn/pcbit/layer2.c @@ -1,4 +1,6 @@ /* + * PCBIT-D low-layer interface + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -13,10 +15,6 @@ */ /* - * PCBIT-D low-layer interface - */ - -/* * Based on documentation provided by Inesc: * - "Interface com bus do PC para o PCBIT e PCBIT-D", Inesc, Jan 93 */ @@ -26,16 +24,6 @@ * re-write/remove debug printks */ -#define __NO_VERSION__ - - -#ifdef MODULE -#define INCLUDE_INLINE_FUNCS -#endif - - -#include <linux/module.h> - #include <linux/sched.h> #include <linux/string.h> #include <linux/kernel.h> diff --git a/drivers/isdn/pcbit/layer2.h b/drivers/isdn/pcbit/layer2.h index 69e24ce9413a..d9b1487be1bc 100644 --- a/drivers/isdn/pcbit/layer2.h +++ b/drivers/isdn/pcbit/layer2.h @@ -1,4 +1,6 @@ /* + * PCBIT-D low-layer interface definitions + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -12,10 +14,6 @@ * Hacked to compile with egcs and run with current version of isdn modules */ -/* - * PCBIT-D low-layer interface definitions - */ - #ifndef LAYER2_H #define LAYER2_H diff --git a/drivers/isdn/pcbit/module.c b/drivers/isdn/pcbit/module.c index 88226f954f3e..8698ac192138 100644 --- a/drivers/isdn/pcbit/module.c +++ b/drivers/isdn/pcbit/module.c @@ -1,4 +1,6 @@ /* + * PCBIT-D module support + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -7,10 +9,6 @@ * the GNU General Public License, incorporated herein by reference. */ -/* - * PCBIT-D module support - */ - #include <linux/module.h> #include <linux/init.h> #include <linux/sched.h> @@ -22,6 +20,12 @@ #include <linux/isdnif.h> #include "pcbit.h" +MODULE_DESCRIPTION("ISDN4Linux: Driver for PCBIT-T card"); +MODULE_AUTHOR("Pedro Roque Marques"); +MODULE_LICENSE("GPL"); +MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i"); + static int mem[MAX_PCBIT_CARDS] = {0, }; static int irq[MAX_PCBIT_CARDS] = {0, }; @@ -119,9 +123,6 @@ static int __init pcbit_setup(char *line) __setup("pcbit=", pcbit_setup); #endif -MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i"); -MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i"); - module_init(pcbit_init); module_exit(pcbit_exit); diff --git a/drivers/isdn/pcbit/pcbit.h b/drivers/isdn/pcbit/pcbit.h index 8ce921f07730..223a32279f86 100644 --- a/drivers/isdn/pcbit/pcbit.h +++ b/drivers/isdn/pcbit/pcbit.h @@ -1,4 +1,6 @@ /* + * PCBIT-D device driver definitions + * * Copyright (C) 1996 Universidade de Lisboa * * Written by Pedro Roque Marques (roque@di.fc.ul.pt) @@ -7,10 +9,6 @@ * the GNU General Public License, incorporated herein by reference. */ -/* - * PCBIT-D device driver definitions - */ - #ifndef PCBIT_H #define PCBIT_H diff --git a/drivers/isdn/sc/card.h b/drivers/isdn/sc/card.h index 3e5370f347d1..48d7cad5249b 100644 --- a/drivers/isdn/sc/card.h +++ b/drivers/isdn/sc/card.h @@ -1,24 +1,13 @@ -/* - * $Id: card.h,v 1.1 1996/11/07 13:07:40 fritz Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. - * - * card.h - Driver parameters for SpellCaster ISA ISDN adapters +/* $Id: card.h,v 1.1.10.1 2001/09/23 22:24:59 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Driver parameters for SpellCaster ISA ISDN adapters * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c index 28accdc0fbf7..9c905f54f6ac 100644 --- a/drivers/isdn/sc/command.c +++ b/drivers/isdn/sc/command.c @@ -1,22 +1,11 @@ -/* - * $Id: command.c,v 1.4 1997/03/30 16:51:34 calle Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. +/* $Id: command.c,v 1.4.10.1 2001/09/23 22:24:59 kai Exp $ * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 @@ -27,6 +16,7 @@ */ #define __NO_VERSION__ +#include <linux/module.h> #include "includes.h" /* This must be first */ #include "hardware.h" #include "message.h" diff --git a/drivers/isdn/sc/debug.c b/drivers/isdn/sc/debug.c index 2f600c06e6d3..1a992a75868b 100644 --- a/drivers/isdn/sc/debug.c +++ b/drivers/isdn/sc/debug.c @@ -1,22 +1,11 @@ -/* - * $Id: debug.c,v 1.5 2000/11/12 15:29:37 kai Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. +/* $Id: debug.c,v 1.5.6.1 2001/09/23 22:24:59 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 @@ -25,6 +14,7 @@ * +1 (416) 297-8565 * +1 (416) 297-6433 Facsimile */ + #include <linux/kernel.h> #include <linux/string.h> diff --git a/drivers/isdn/sc/debug.h b/drivers/isdn/sc/debug.h index ba100543d36f..e9db96ede4b2 100644 --- a/drivers/isdn/sc/debug.h +++ b/drivers/isdn/sc/debug.h @@ -1,22 +1,11 @@ -/* - * $Id: debug.h,v 1.2 2000/02/26 01:00:53 keil Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. +/* $Id: debug.h,v 1.2.8.1 2001/09/23 22:24:59 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 diff --git a/drivers/isdn/sc/event.c b/drivers/isdn/sc/event.c index 23cd53f07f37..6488eb282e6b 100644 --- a/drivers/isdn/sc/event.c +++ b/drivers/isdn/sc/event.c @@ -1,22 +1,11 @@ -/* - * $Id: event.c,v 1.4 1997/10/09 22:30:58 fritz Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. +/* $Id: event.c,v 1.4.8.1 2001/09/23 22:24:59 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 diff --git a/drivers/isdn/sc/hardware.h b/drivers/isdn/sc/hardware.h index b0f07ac3c9cd..d46416e588b0 100644 --- a/drivers/isdn/sc/hardware.h +++ b/drivers/isdn/sc/hardware.h @@ -1,5 +1,9 @@ /* * Hardware specific macros, defines and structures + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #ifndef HARDWARE_H @@ -12,15 +16,7 @@ */ #define MAX_CARDS 4 /* The maximum number of cards to - control or probe for. If you change - this, you must also change the number - of elements in io, irq, and ram to - match. Initialized in init.c */ -/* -extern unsigned int io[]; -extern unsigned char irq[]; -extern unsigned long ram[]; -*/ + control or probe for. */ #define SIGNATURE 0x87654321 /* Board reset signature */ #define SIG_OFFSET 0x1004 /* Where to find signature in shared RAM */ diff --git a/drivers/isdn/sc/includes.h b/drivers/isdn/sc/includes.h index 840dfc0976fd..c33bf6de3e54 100644 --- a/drivers/isdn/sc/includes.h +++ b/drivers/isdn/sc/includes.h @@ -1,4 +1,9 @@ -#include <linux/module.h> +/* + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ + #include <linux/version.h> #include <linux/errno.h> #include <asm/segment.h> diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c index df7756435061..88a18c099797 100644 --- a/drivers/isdn/sc/init.c +++ b/drivers/isdn/sc/init.c @@ -1,9 +1,23 @@ +/* + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ + #include <linux/module.h> #include <linux/init.h> #include "includes.h" #include "hardware.h" #include "card.h" +MODULE_DESCRIPTION("ISDN4Linux: Driver for Spellcaster card"); +MODULE_AUTHOR("Spellcaster Telecommunications Inc."); +MODULE_LICENSE("GPL"); +MODULE_PARM( io, "1-" __MODULE_STRING(MAX_CARDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i"); +MODULE_PARM(ram, "1-" __MODULE_STRING(MAX_CARDS) "i"); +MODULE_PARM(do_reset, "i"); + board *adapter[MAX_CARDS]; int cinst; @@ -39,11 +53,6 @@ int irq_supported(int irq_x) return 0; } -MODULE_PARM(io, "1-4i"); -MODULE_PARM(irq, "1-4i"); -MODULE_PARM(ram, "1-4i"); -MODULE_PARM(do_reset, "i"); - static int __init sc_init(void) { int b = -1; diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c index e0697710dd9e..7e32c5a6880e 100644 --- a/drivers/isdn/sc/interrupt.c +++ b/drivers/isdn/sc/interrupt.c @@ -1,22 +1,11 @@ -/* - * $Id: interrupt.c,v 1.4.8.2 2001/04/08 17:51:43 kai Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. +/* $Id: interrupt.c,v 1.4.8.3 2001/09/23 22:24:59 kai Exp $ * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index 141d5254dbea..807d85d36c69 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c @@ -1,3 +1,11 @@ +/* + * Copyright (C) 1996 SpellCaster Telecommunications Inc. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ + #define __NO_VERSION__ #include "includes.h" #include "hardware.h" diff --git a/drivers/isdn/sc/message.c b/drivers/isdn/sc/message.c index 205eeb9a5c13..04ceff7d70f5 100644 --- a/drivers/isdn/sc/message.c +++ b/drivers/isdn/sc/message.c @@ -1,24 +1,13 @@ -/* - * $Id: message.c,v 1.5.8.1 2001/04/08 17:51:43 kai Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. - * - * message.c - functions for sending and receiving control messages +/* $Id: message.c,v 1.5.8.2 2001/09/23 22:24:59 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * functions for sending and receiving control messages * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 diff --git a/drivers/isdn/sc/message.h b/drivers/isdn/sc/message.h index 9b8bcb025a13..8eb15e7306b2 100644 --- a/drivers/isdn/sc/message.h +++ b/drivers/isdn/sc/message.h @@ -1,25 +1,14 @@ -/* - * $Id: message.h,v 1.1 1996/11/07 13:07:47 fritz Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. - * - * message.h - structures, macros and defines useful for sending - * messages to the adapter +/* $Id: message.h,v 1.1.10.1 2001/09/23 22:24:59 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * structures, macros and defines useful for sending + * messages to the adapter * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 diff --git a/drivers/isdn/sc/packet.c b/drivers/isdn/sc/packet.c index 31e562c57b04..38644225b2a1 100644 --- a/drivers/isdn/sc/packet.c +++ b/drivers/isdn/sc/packet.c @@ -1,22 +1,11 @@ -/* - * $Id: packet.c,v 1.5 1999/08/31 11:20:41 paul Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. +/* $Id: packet.c,v 1.5.8.1 2001/09/23 22:24:59 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 diff --git a/drivers/isdn/sc/scioc.h b/drivers/isdn/sc/scioc.h index 19db0b7c1175..c3dd551ecc3c 100644 --- a/drivers/isdn/sc/scioc.h +++ b/drivers/isdn/sc/scioc.h @@ -1,3 +1,7 @@ +/* + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ /* * IOCTL Command Codes diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c index 6ff0812746b2..94f7730ce858 100644 --- a/drivers/isdn/sc/shmem.c +++ b/drivers/isdn/sc/shmem.c @@ -1,24 +1,13 @@ -/* - * $Id: shmem.c,v 1.2 1996/11/20 17:49:56 fritz Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. - * - * card.c - Card functions implementing ISDN4Linux functionality +/* $Id: shmem.c,v 1.2.10.1 2001/09/23 22:24:59 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Card functions implementing ISDN4Linux functionality * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c index 1c355dc28ef8..e6c649f9dc32 100644 --- a/drivers/isdn/sc/timer.c +++ b/drivers/isdn/sc/timer.c @@ -1,22 +1,11 @@ -/* - * $Id: timer.c,v 1.3 2000/05/06 00:52:39 kai Exp $ - * Copyright (C) 1996 SpellCaster Telecommunications Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. +/* $Id: timer.c,v 1.3.6.1 2001/09/23 22:24:59 kai Exp $ * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (C) 1996 SpellCaster Telecommunications Inc. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * For more information, please contact gpl-info@spellcast.com or write: + * For more information, please contact gpl-info@spellcast.com or write: * * SpellCaster Telecommunications Inc. * 5621 Finch Avenue East, Unit #3 diff --git a/drivers/isdn/tpam/tpam.h b/drivers/isdn/tpam/tpam.h index 82c78b90025f..3b6a2aa5a54b 100644 --- a/drivers/isdn/tpam/tpam.h +++ b/drivers/isdn/tpam/tpam.h @@ -1,31 +1,19 @@ -/* $Id: tpam.h,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $ +/* $Id: tpam.h,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver) * * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve * - * For all support questions please contact: <support@auvertech.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * For all support questions please contact: <support@auvertech.fr> * */ #ifndef _TPAM_PRIV_H_ #define _TPAM_PRIV_H_ -#include <linux/module.h> #include <linux/isdnif.h> #include <linux/init.h> diff --git a/drivers/isdn/tpam/tpam_commands.c b/drivers/isdn/tpam/tpam_commands.c index 43a1d37b6936..8d9d9b50b0a8 100644 --- a/drivers/isdn/tpam/tpam_commands.c +++ b/drivers/isdn/tpam/tpam_commands.c @@ -1,27 +1,16 @@ -/* $Id: tpam_commands.c,v 1.1.2.2 2001/06/08 08:23:46 kai Exp $ +/* $Id: tpam_commands.c,v 1.1.2.3 2001/09/23 22:25:03 kai Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - ISDN commands) * * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve * - * For all support questions please contact: <support@auvertech.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * For all support questions please contact: <support@auvertech.fr> * */ -#include <linux/config.h> + #include <linux/module.h> #include <linux/pci.h> #include <linux/sched.h> diff --git a/drivers/isdn/tpam/tpam_crcpc.c b/drivers/isdn/tpam/tpam_crcpc.c index f2dcf2daf3b9..762a82575e1b 100644 --- a/drivers/isdn/tpam/tpam_crcpc.c +++ b/drivers/isdn/tpam/tpam_crcpc.c @@ -1,25 +1,14 @@ -/* $Id: tpam_crcpc.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $ +/* $Id: tpam_crcpc.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - CRC encoding) * * Copyright 1998-2000 AUVERTECH Télécom * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve * - * For all support questions please contact: <support@auvertech.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * For all support questions please contact: <support@auvertech.fr> * */ diff --git a/drivers/isdn/tpam/tpam_hdlc.c b/drivers/isdn/tpam/tpam_hdlc.c index 0337535d7915..4c1d0971fb99 100644 --- a/drivers/isdn/tpam/tpam_hdlc.c +++ b/drivers/isdn/tpam/tpam_hdlc.c @@ -1,25 +1,14 @@ -/* $Id: tpam_hdlc.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $ +/* $Id: tpam_hdlc.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - HDLC encoding) * * Copyright 1998-2000 AUVERTECH Télécom * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve * - * For all support questions please contact: <support@auvertech.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * For all support questions please contact: <support@auvertech.fr> * */ diff --git a/drivers/isdn/tpam/tpam_main.c b/drivers/isdn/tpam/tpam_main.c index bf6691bf4ea2..9a000b3d1f63 100644 --- a/drivers/isdn/tpam/tpam_main.c +++ b/drivers/isdn/tpam/tpam_main.c @@ -1,27 +1,16 @@ -/* $Id: tpam_main.c,v 1.1.2.2 2001/07/11 12:22:59 kai Exp $ +/* $Id: tpam_main.c,v 1.1.2.3 2001/09/23 22:25:03 kai Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - main routines) * * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve * - * For all support questions please contact: <support@auvertech.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * For all support questions please contact: <support@auvertech.fr> * */ -#include <linux/config.h> + #include <linux/module.h> #include <linux/pci.h> #include <linux/sched.h> @@ -46,9 +35,9 @@ static int cards_num; /* Configurable id of the driver */ static char *id = "tpam\0\0\0\0\0\0\0\0\0\0\0\0"; -MODULE_DESCRIPTION("Driver for TurboPAM cards"); -MODULE_AUTHOR("Stelian Pop, Alcove"); -MODULE_SUPPORTED_DEVICE("ISDN subsystem"); +MODULE_DESCRIPTION("ISDN4Linux: Driver for TurboPAM ISDN cards"); +MODULE_AUTHOR("Stelian Pop"); +MODULE_LICENSE("GPL"); MODULE_PARM_DESC(id,"ID-String of the driver"); MODULE_PARM(id,"s"); diff --git a/drivers/isdn/tpam/tpam_memory.c b/drivers/isdn/tpam/tpam_memory.c index 253ebfb82eae..fe70c08b5477 100644 --- a/drivers/isdn/tpam/tpam_memory.c +++ b/drivers/isdn/tpam/tpam_memory.c @@ -1,27 +1,16 @@ -/* $Id: tpam_memory.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $ +/* $Id: tpam_memory.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - Board Memory Access) * * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve * - * For all support questions please contact: <support@auvertech.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * For all support questions please contact: <support@auvertech.fr> * */ -#include <linux/config.h> + #include <linux/pci.h> #include <asm/io.h> diff --git a/drivers/isdn/tpam/tpam_nco.c b/drivers/isdn/tpam/tpam_nco.c index 20dc732ee206..96468ef8ec79 100644 --- a/drivers/isdn/tpam/tpam_nco.c +++ b/drivers/isdn/tpam/tpam_nco.c @@ -1,27 +1,17 @@ -/* $Id: tpam_nco.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $ +/* $Id: tpam_nco.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $ * - * Turbo PAM ISDN driver for Linux. (Kernel Driver - Low Level NCO Manipulation) + * Turbo PAM ISDN driver for Linux. + * (Kernel Driver - Low Level NCO Manipulation) * * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve * - * For all support questions please contact: <support@auvertech.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * For all support questions please contact: <support@auvertech.fr> * */ -#include <linux/config.h> + #include <linux/pci.h> #include <linux/sched.h> #include <linux/tqueue.h> diff --git a/drivers/isdn/tpam/tpam_queues.c b/drivers/isdn/tpam/tpam_queues.c index 15ec08a357e5..97dfe0286b8a 100644 --- a/drivers/isdn/tpam/tpam_queues.c +++ b/drivers/isdn/tpam/tpam_queues.c @@ -1,28 +1,16 @@ -/* $Id: tpam_queues.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $ +/* $Id: tpam_queues.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver) * * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve * - * For all support questions please contact: <support@auvertech.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * For all support questions please contact: <support@auvertech.fr> * */ -#include <linux/config.h> -#include <linux/module.h> + #include <linux/pci.h> #include <linux/sched.h> #include <linux/tqueue.h> diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 52583645fdf7..6f0a7923547b 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -203,3 +203,4 @@ static void linear_exit (void) module_init(linear_init); module_exit(linear_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index f4f3a9f0eda0..58baccf787a7 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -1258,4 +1258,4 @@ static void multipath_exit (void) module_init(multipath_init); module_exit(multipath_exit); - +MODULE_LICENSE("GPL"); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index d78d0f7fc8b8..fed885b57846 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -347,5 +347,4 @@ static void raid0_exit (void) module_init(raid0_init); module_exit(raid0_exit); - - +MODULE_LICENSE("GPL"); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 41fb53ca07c2..e4d0577e3e11 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1826,4 +1826,4 @@ static void raid1_exit (void) module_init(raid1_init); module_exit(raid1_exit); - +MODULE_LICENSE("GPL"); diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c63f68c47291..e4c7fd38d83e 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2026,4 +2026,4 @@ static void raid5_exit (void) module_init(raid5_init); module_exit(raid5_exit); - +MODULE_LICENSE("GPL"); diff --git a/drivers/md/xor.c b/drivers/md/xor.c index f0b76d4663c2..454ee9c135ce 100644 --- a/drivers/md/xor.c +++ b/drivers/md/xor.c @@ -137,5 +137,6 @@ calibrate_xor_block(void) } MD_EXPORT_SYMBOL(xor_block); +MODULE_LICENSE("GPL"); module_init(calibrate_xor_block); diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c index d4670b0889f5..0898e6930e16 100644 --- a/drivers/media/radio/miropcm20-radio.c +++ b/drivers/media/radio/miropcm20-radio.c @@ -273,6 +273,7 @@ static int __init pcm20_init(void) MODULE_AUTHOR("Ruurd Reitsma"); MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card."); +MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; diff --git a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c index 4cc0db1db958..d125f1b19db7 100644 --- a/drivers/media/radio/miropcm20-rds-core.c +++ b/drivers/media/radio/miropcm20-rds-core.c @@ -208,3 +208,4 @@ int __init attach_aci_rds(void) void __exit unload_aci_rds(void) { } +MODULE_LICENSE("GPL"); diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c index 661fae7e597a..ef4da4705d5c 100644 --- a/drivers/media/radio/miropcm20-rds.c +++ b/drivers/media/radio/miropcm20-rds.c @@ -138,3 +138,4 @@ static void __exit miropcm20_rds_cleanup(void) module_init(miropcm20_rds_init); module_exit(miropcm20_rds_cleanup); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index a7b03cd1a262..6bbe86bdac52 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -370,6 +370,8 @@ static int __init rtrack_init(void) MODULE_AUTHOR("M.Kirkwood"); MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card."); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)"); MODULE_PARM(radio_nr, "i"); diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 29f8756b2fab..f97483a6c54b 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -312,6 +312,8 @@ static int __init aztech_init(void) MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); MODULE_DESCRIPTION("A driver for the Aztech radio card."); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM(radio_nr, "i"); MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)"); diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 00dd37ca7dc5..f6ba7f942dff 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -629,6 +629,8 @@ static int __init cadet_init(void) MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card."); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)"); MODULE_PARM(radio_nr, "i"); diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 895ad4adbba7..68f612caa530 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -439,6 +439,8 @@ static void __exit gemtek_pci_cleanup_module( void ) MODULE_AUTHOR( "Vladimir Shebordaev <vshebordaev@mail.ru>" ); MODULE_DESCRIPTION( "The video4linux driver for the Gemtek PCI Radio Card" ); +MODULE_LICENSE("GPL"); + MODULE_PARM( mx, "b" ); MODULE_PARM_DESC( mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not" ); MODULE_PARM( nr_radio, "i"); diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 3d534599348d..ce35baa19ca0 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -294,6 +294,8 @@ static int __init gemtek_init(void) MODULE_AUTHOR("Jonas Munsin"); MODULE_DESCRIPTION("A driver for the GemTek Radio Card"); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c (0x20c or 0x248 have been reported to work for the combined sound/radiocard))."); MODULE_PARM(radio_nr, "i"); diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index f38dc8a2cd78..47d541b687bf 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c @@ -298,6 +298,7 @@ inline static __u16 radio_install(struct pci_dev *pcidev); MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl"); MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio."); +MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 1b0755697541..1368ff2ed012 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -316,6 +316,8 @@ static void radio_close(struct video_device *dev) MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net"); MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio."); +MODULE_LICENSE("GPL"); + EXPORT_NO_SYMBOLS; diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index ed5f81716243..6b9a676d9f65 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -256,6 +256,8 @@ static int __init rtrack2_init(void) MODULE_AUTHOR("Ben Pfaff"); MODULE_DESCRIPTION("A driver for the RadioTrack II radio card."); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)"); MODULE_PARM(radio_nr, "i"); diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 4d7be7f211f3..a4c643ce92f8 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -352,6 +352,8 @@ static int __init fmi_init(void) MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); MODULE_DESCRIPTION("A driver for the SF16MI radio."); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)"); MODULE_PARM(radio_nr, "i"); diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index 6b8710078831..d331dd65b6a8 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -338,6 +338,7 @@ static int __init terratec_init(void) MODULE_AUTHOR("R.OFFERMANNS & others"); MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card."); +MODULE_LICENSE("GPL"); MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)"); MODULE_PARM(radio_nr, "i"); diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index ebfcf0e8c4a2..be8cd7bdf0f3 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c @@ -331,6 +331,8 @@ static int __init trust_init(void) MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); MODULE_DESCRIPTION("A driver for the Trust FM Radio card."); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)"); MODULE_PARM(radio_nr, "i"); diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 06b41cc3e0c9..f3eb85bf4e31 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -317,6 +317,8 @@ static int typhoon_get_info(char *buf, char **start, off_t offset, int len) MODULE_AUTHOR("Dr. Henrik Seidel"); MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio)."); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)"); MODULE_PARM(mutefreq, "i"); diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 6e12d5614283..a302e1161d46 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -393,6 +393,8 @@ static int __init zoltrix_init(void) MODULE_AUTHOR("C.van Schaik"); MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus."); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)"); MODULE_PARM(radio_nr, "i"); diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index f65dfe0d79f6..32063589f0c5 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -476,3 +476,4 @@ static void adv7175_exit(void) module_init(adv7175_init); module_exit(adv7175_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index ecb3cc56f0e9..042ba8f1bc82 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -494,3 +494,4 @@ static void bt819_exit(void) module_init(bt819_setup); module_exit(bt819_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index cd38c6215c92..7b5d7d7bd37d 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c @@ -301,3 +301,4 @@ static void bt856_exit(void) module_init(bt856_init); module_exit(bt856_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 6a41c644f9f7..45d5b8de55ea 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c @@ -83,6 +83,7 @@ MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default MODULE_PARM(gpiomask,"i"); MODULE_PARM(audioall,"i"); MODULE_PARM(audiomux,"1-5i"); +MODULE_LICENSE("GPL"); /* kernel args */ #ifndef MODULE diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 0d78394d5825..06f7e4d01375 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -105,6 +105,7 @@ MODULE_PARM(vbi_nr,"i"); MODULE_DESCRIPTION("bttv - v4l driver module for bt848/878 based cards"); MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr"); +MODULE_LICENSE("GPL"); /* kernel args */ #ifndef MODULE diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c index fee0d40744fd..3e8d84ebf8f0 100644 --- a/drivers/media/video/bttv-if.c +++ b/drivers/media/video/bttv-if.c @@ -351,6 +351,7 @@ int __devinit init_bttv_i2c(struct bttv *btv) btv->i2c_rc = i2c_bit_add_bus(&btv->i2c_adap); return btv->i2c_rc; } +MODULE_LICENSE("GPL"); /* * Local variables: diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 635ff98dffad..56f1ceafcebe 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -1051,3 +1051,4 @@ int __init init_bw_qcams(struct video_init *unused) return 0; } #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 9da6cbf51da9..6ca1f83dc402 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -876,6 +876,8 @@ static void __exit cqcam_cleanup (void) MODULE_AUTHOR("Philip Blundell <philb@gnu.org>"); MODULE_DESCRIPTION(BANNER); +MODULE_LICENSE("GPL"); + MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\ probe=<0|1|2> for camera detection method\n\ force_rgb=<0|1> for RGB data format (default BGR)"); diff --git a/drivers/media/video/i2c-old.c b/drivers/media/video/i2c-old.c index efe733ae2178..52dc8ebb17d5 100644 --- a/drivers/media/video/i2c-old.c +++ b/drivers/media/video/i2c-old.c @@ -448,3 +448,4 @@ void cleanup_module(void) { } #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/i2c-parport.c b/drivers/media/video/i2c-parport.c index b315d66ac845..f0fd64c68d2b 100644 --- a/drivers/media/video/i2c-parport.c +++ b/drivers/media/video/i2c-parport.c @@ -149,3 +149,4 @@ void cleanup_module(void) parport_unregister_driver(&parport_i2c_driver); } #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 5a3b656f6b5e..0e30125c683f 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1480,6 +1480,8 @@ static void __exit meye_cleanup_module(void) { MODULE_AUTHOR("Stelian Pop <stelian.pop@fr.alcove.com>"); MODULE_DESCRIPTION("video4linux driver for the MotionEye camera"); +MODULE_LICENSE("GPL"); + MODULE_PARM(gbuffers,"i"); MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (32 max)"); diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index b3d9887b1693..25b95895e804 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -131,6 +131,8 @@ MODULE_PARM(debug,"i"); MODULE_PARM(simple,"i"); MODULE_PARM(amsound,"i"); MODULE_PARM(dolby,"i"); +MODULE_LICENSE("GPL"); + /* ---------------------------------------------------------------------- */ diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c index 6563cd44008c..c148ba785221 100644 --- a/drivers/media/video/planb.c +++ b/drivers/media/video/planb.c @@ -75,6 +75,8 @@ static int video_nr = -1; MODULE_PARM(def_norm, "i"); MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)"); MODULE_PARM(video_nr,"i"); +MODULE_LICENSE("GPL"); + /* ------------------ PlanB Exported Functions ------------------ */ static long planb_write(struct video_device *, const char *, unsigned long, int); diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index caab942d2a23..f1bda140dd68 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -1058,6 +1058,8 @@ static int __init init_pms_cards(void) MODULE_PARM(io_port,"i"); MODULE_PARM(mem_base,"i"); MODULE_PARM(video_nr,"i"); +MODULE_LICENSE("GPL"); + static void __exit shutdown_mediavision(void) { diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 22be539c7426..8d4bd9cc1c55 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -694,3 +694,4 @@ static struct video_device saa_template = ioctl: saa5249_ioctl, }; +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index a14a13e697d6..5e0a680ebaff 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c @@ -426,3 +426,4 @@ static void saa7110_exit(void) module_init(saa7110_init); module_exit(saa7110_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index 2b5b0481b38e..974ade4058cb 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -448,3 +448,4 @@ static void saa7111_exit(void) module_init(saa7111_init); module_exit(saa7111_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index d9a3bcd95cc1..778f29d74265 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c @@ -406,3 +406,4 @@ static void saa7185_exit(void) module_init(saa7185_init); module_exit(saa7185_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 141cbea39304..9b099f57966d 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -65,6 +65,8 @@ static int saa_num = 0; /* number of SAA7146s in use */ static int video_nr = -1; MODULE_PARM(video_nr,"i"); +MODULE_LICENSE("GPL"); + #define nDebNormal 0x00480000 #define nDebNoInc 0x00480000 diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 97e2be2b0409..dc5a5e35cc82 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -50,6 +50,8 @@ MODULE_AUTHOR("Eric Sandeen <eric_sandeen@bigfoot.com>"); MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip"); +MODULE_LICENSE("GPL"); + MODULE_PARM(debug,"i"); MODULE_PARM(loudness,"i"); diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 61a840f4832c..e9dcdac77a5b 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -34,6 +34,8 @@ #include "id.h" MODULE_PARM(debug,"i"); +MODULE_LICENSE("GPL"); + static int debug = 0; /* insmod parameter */ diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c index cfa0882fab04..26f403059c83 100644 --- a/drivers/media/video/tuner-3036.c +++ b/drivers/media/video/tuner-3036.c @@ -220,6 +220,8 @@ tuner3036_exit(void) MODULE_DESCRIPTION("SAB3036 tuner driver"); MODULE_AUTHOR("Philip Blundell <philb@gnu.org>"); +MODULE_LICENSE("GPL"); + MODULE_PARM(debug,"i"); MODULE_PARM_DESC(debug,"Enable debugging output"); diff --git a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c index c26dd99fd848..4bd6f17b574d 100644 --- a/drivers/media/video/tuner.c +++ b/drivers/media/video/tuner.c @@ -47,6 +47,7 @@ MODULE_PARM(addr,"i"); MODULE_PARM(tv_range,"2i"); MODULE_PARM(radio_range,"2i"); MODULE_PARM(pal,"s"); +MODULE_LICENSE("GPL"); struct tuner { diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 5cd813d0bff6..8984e6772090 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1168,6 +1168,7 @@ void audiochip_cleanup_module(void) module_init(audiochip_init_module); module_exit(audiochip_cleanup_module); +MODULE_LICENSE("GPL"); /* * Local variables: diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index be1684a694e7..0e7e71ae6160 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c @@ -355,3 +355,4 @@ module_exit(tvmixer_cleanup_module); * c-basic-offset: 8 * End: */ +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 0f444b7c8112..c556d031f26d 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -592,6 +592,8 @@ EXPORT_SYMBOL(video_unregister_device); MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("Device registrar for Video4Linux drivers"); +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index ce160c3851d3..c5e67b48c7bb 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -119,6 +119,8 @@ struct w9966_dev { MODULE_AUTHOR("Jakob Kemi <jakob.kemi@post.utfors.se>"); MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)"); +MODULE_LICENSE("GPL"); + #ifdef MODULE static const char* pardev[] = {[0 ... W9966_MAXCAMS] = ""}; diff --git a/drivers/media/video/zr36067.c b/drivers/media/video/zr36067.c index 1cf403df7fdf..8a666285b4c2 100644 --- a/drivers/media/video/zr36067.c +++ b/drivers/media/video/zr36067.c @@ -4901,3 +4901,4 @@ static void unload_dc10_cards(void) module_init(init_dc10_cards); module_exit(unload_dc10_cards); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c index ce1bb92fe7b6..6490af3d2949 100644 --- a/drivers/media/video/zr36120.c +++ b/drivers/media/video/zr36120.c @@ -62,6 +62,8 @@ static int vbi_nr = -1; MODULE_AUTHOR("Pauline Middelink <middelin@polyware.nl>"); MODULE_DESCRIPTION("Zoran ZR36120 based framegrabber"); +MODULE_LICENSE("GPL"); + MODULE_PARM(triton1,"i"); MODULE_PARM(cardtype,"1-" __MODULE_STRING(ZORAN_MAX) "i"); MODULE_PARM(video_nr,"i"); diff --git a/drivers/media/video/zr36120_mem.c b/drivers/media/video/zr36120_mem.c index b4c6078d3777..008fb7e5ab68 100644 --- a/drivers/media/video/zr36120_mem.c +++ b/drivers/media/video/zr36120_mem.c @@ -23,6 +23,7 @@ #include <linux/pci.h> #include <linux/wrapper.h> #include <linux/slab.h> +#include <linux/module.h> #include <asm/io.h> #ifdef CONFIG_BIGPHYS_AREA #include <linux/bigphysarea.h> @@ -75,3 +76,5 @@ void bfree(void* mem, unsigned long size) #endif } } + +MODULE_LICENSE("GPL"); diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 0e3cd3fb4ee3..fd7b1515ac3b 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -42,7 +42,7 @@ * Originally By: Steven J. Ralston * (mailto:Steve.Ralston@lsil.com) * - * $Id: mptbase.c,v 1.53.4.1 2001/08/24 20:07:05 sralston Exp $ + * $Id: mptbase.c,v 1.53.4.3 2001/09/18 03:54:54 sralston Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -108,6 +108,8 @@ MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); +MODULE_LICENSE("GPL"); + /* * cmd line parameters @@ -1435,10 +1437,14 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup) { if (this != NULL) { int sz; + u32 state; /* Disable the FW */ - if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) != 0) - (void) KickStart(this, 1); + state = GetIocState(this, 1); + if (state == MPI_IOC_STATE_OPERATIONAL) { + if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) != 0) + (void) KickStart(this, 1); + } /* Disable adapter interrupts! */ CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF); diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index d19402a58f15..b0f988a238da 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -12,7 +12,7 @@ * Originally By: Steven J. Ralston * (mailto:Steve.Ralston@lsil.com) * - * $Id: mptbase.h,v 1.46.2.2.2.1 2001/08/24 20:07:05 sralston Exp $ + * $Id: mptbase.h,v 1.46.2.2.2.2 2001/09/18 03:22:29 sralston Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -77,8 +77,8 @@ #define COPYRIGHT "Copyright (c) 1999-2001 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "1.02.01" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-1.02.01" +#define MPT_LINUX_VERSION_COMMON "1.02.02" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-1.02.02" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 5809cee210cf..372583a05c21 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -93,6 +93,8 @@ EXPORT_NO_SYMBOLS; MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); +MODULE_LICENSE("GPL"); + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 542ac00eb1e5..c0831d6a3b1f 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -1508,6 +1508,8 @@ void __init mpt_lan_exit(void) MODULE_PARM(tx_max_out_p, "i"); MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME! +MODULE_LICENSE("GPL"); + module_init(mpt_lan_init); module_exit(mpt_lan_exit); diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 74a76bc75c31..1e7c77b395af 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -19,7 +19,7 @@ * Original author: Steven J. Ralston * (mailto:Steve.Ralston@lsil.com) * - * $Id: mptscsih.c,v 1.29 2001/06/18 18:59:05 sralston Exp $ + * $Id: mptscsih.c,v 1.29.4.1 2001/09/18 03:22:30 sralston Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -81,6 +81,8 @@ MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); +MODULE_LICENSE("GPL"); + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -324,14 +326,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r) dprintk((KERN_NOTICE MYNAM ": SET sc->resid=%02xh\n", sc->resid)); #endif -#if 0 - if (sc->underflow && (le32_to_cpu(pScsiReply->TransferCount) < sc->underflow)) { - sc->result = DID_ERROR << 16; - sc->resid = sc->request_bufflen - le32_to_cpu(pScsiReply->TransferCount); - } else { - sc->result = 0; + if (pScsiReq->CDB[0] == INQUIRY) { + sc->result = (DID_OK << 16); + break; } -#endif /* workaround attempts... */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index ea06d383a564..13a272d5f7e8 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -980,6 +980,8 @@ void cleanup_module(void) } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index bc2a162b7ab2..c1768a1d078a 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -667,6 +667,8 @@ cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index 4ce3e811430e..7f91256e65ab 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -1673,3 +1673,4 @@ void cleanup_module(void) } #endif /* MODULE */ +MODULE_LICENSE("GPL"); diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index f97ad039d42e..df46dbbebfd5 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -126,6 +126,7 @@ struct net_local { ushort tx_head; ushort tx_cmd_link; ushort tx_reap; + ushort tx_pkts_in_ring; spinlock_t lock; }; @@ -194,7 +195,7 @@ struct net_local { #define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */ #define TX_BUF_START 0x0100 -#define NUM_TX_BUFS 4 +#define NUM_TX_BUFS 5 #define TX_BUF_SIZE (1518+14+20+16) /* packet+header+TBD */ #define RX_BUF_START 0x2000 @@ -463,6 +464,7 @@ static void el16_tx_timeout (struct net_device *dev) printk ("Resetting board.\n"); /* Completely reset the adaptor. */ init_82586_mem (dev); + lp->tx_pkts_in_ring = 0; } else { /* Issue the channel attention signal and hope it "gets better". */ if (net_debug > 1) @@ -538,30 +540,34 @@ static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) outb(0x80, ioaddr + MISC_CTRL); /* Reap the Tx packet buffers. */ - while (lp->tx_reap != lp->tx_head) { + while (lp->tx_pkts_in_ring) { unsigned short tx_status = isa_readw(shmem+lp->tx_reap); - - if (tx_status == 0) { - if (net_debug > 5) printk("Couldn't reap %#x.\n", lp->tx_reap); + if (!(tx_status & 0x8000)) { + if (net_debug > 5) + printk("Tx command incomplete (%#x).\n", lp->tx_reap); break; } - if (tx_status & 0x2000) { - lp->stats.tx_packets++; - lp->stats.collisions += tx_status & 0xf; - netif_wake_queue(dev); - } else { + /* Tx unsuccessful or some interesting status bit set. */ + if (!(tx_status & 0x2000) || (tx_status & 0x0f3f)) { lp->stats.tx_errors++; if (tx_status & 0x0600) lp->stats.tx_carrier_errors++; if (tx_status & 0x0100) lp->stats.tx_fifo_errors++; if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++; if (tx_status & 0x0020) lp->stats.tx_aborted_errors++; + lp->stats.collisions += tx_status & 0xf; } + lp->stats.tx_packets++; if (net_debug > 5) printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status); lp->tx_reap += TX_BUF_SIZE; if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE) lp->tx_reap = TX_BUF_START; - if (++boguscount > 4) + + lp->tx_pkts_in_ring--; + /* There is always more space in the Tx ring buffer now. */ + netif_wake_queue(dev); + + if (++boguscount > 10) break; } @@ -782,7 +788,8 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length dev->name, ioaddr, length, tx_block, lp->tx_head); } - if (lp->tx_head != lp->tx_reap) + /* Grimly block further packets if there has been insufficient reaping. */ + if (++lp->tx_pkts_in_ring < NUM_TX_BUFS) netif_wake_queue(dev); } @@ -892,6 +899,8 @@ cleanup_module(void) release_region(dev_3c507.base_addr, EL16_IO_EXTENT); } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index c9d14503ffd5..8b392f29f55b 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -202,6 +202,8 @@ static struct isapnp_device_id el3_isapnp_adapters[] __initdata = { }; MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters); +MODULE_LICENSE("GPL"); + static u16 el3_isapnp_phys_addr[8][3]; #endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */ diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 4159fae8a8c4..be9a92d2fed6 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -82,14 +82,14 @@ static int max_interrupt_work = 20; MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(debug, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i"); MODULE_PARM(rx_copybreak, "i"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM_DESC(debug, "3c515 debug level (0-6)"); MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering"); -MODULE_PARM_DESC(full_duplex, "(ignored)"); MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames"); MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt"); diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 578f530ee25b..32899ae207c4 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -267,6 +267,8 @@ DRV_NAME ": Donald Becker and others. www.scyld.com/network/vortex.html\n"; MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver " DRV_VERSION " " DRV_RELDATE); +MODULE_LICENSE("GPL"); + MODULE_PARM(debug, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(8) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i"); diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 815eed82e0da..68b3035ff289 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -592,6 +592,8 @@ struct rtl8139_private { MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>"); MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM (multicast_filter_limit, "i"); MODULE_PARM (max_interrupt_work, "i"); MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i"); @@ -825,6 +827,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev, #ifdef USE_IO_OPS ioaddr = (void *) pio_start; dev->base_addr = pio_start; + tp->mmio_addr = ioaddr; #else /* ioremap MMIO region */ ioaddr = ioremap (mmio_start, mmio_len); diff --git a/drivers/net/82596.c b/drivers/net/82596.c index bd7d379ed1d5..99b8c2901348 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -150,6 +150,8 @@ static int i596_debug = (DEB_SERIOUS|DEB_PROBE); MODULE_AUTHOR("Richard Hirst"); MODULE_DESCRIPTION("i82596 driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(i596_debug, "i"); MODULE_PARM_DESC(i596_debug, "i82596 debug mask"); diff --git a/drivers/net/8390.c b/drivers/net/8390.c index 380e4e664094..67064058e218 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -1156,6 +1156,8 @@ void cleanup_module(void) } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 46cb71b2455b..2daff418971b 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -395,6 +395,8 @@ cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 1fb3c1785c7a..ca08e724a535 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -747,6 +747,8 @@ int __devinit acenic_probe (ACE_PROBE_ARG) #ifdef MODULE MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>"); MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(link, "1-" __MODULE_STRING(8) "i"); MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i"); MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i"); diff --git a/drivers/net/aironet4500_card.c b/drivers/net/aironet4500_card.c index 596a946661d4..5f5a4f84137c 100644 --- a/drivers/net/aironet4500_card.c +++ b/drivers/net/aironet4500_card.c @@ -38,6 +38,7 @@ static const char *awc_version = #include <linux/if_arp.h> #include <linux/ioport.h> #include <linux/delay.h> +#include <linux/init.h> #include "aironet4500.h" @@ -66,6 +67,8 @@ static struct pci_device_id aironet4500_card_pci_tbl[] __devinitdata = { { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(pci, aironet4500_card_pci_tbl); +MODULE_LICENSE("GPL"); + static int reverse_probe; diff --git a/drivers/net/aironet4500_core.c b/drivers/net/aironet4500_core.c index 9a07d2f02665..a04c7e0f5957 100644 --- a/drivers/net/aironet4500_core.c +++ b/drivers/net/aironet4500_core.c @@ -2582,6 +2582,8 @@ MODULE_PARM_DESC(master,"Aironet is Adhoc master (creates network sync) (0-1)"); MODULE_PARM_DESC(slave,"Aironet is Adhoc slave (0-1)"); MODULE_PARM_DESC(max_mtu,"Aironet MTU limit (256-2312)"); #endif +MODULE_LICENSE("GPL"); + /*EXPORT_SYMBOL(tx_queue_len); EXPORT_SYMBOL(awc_debug); diff --git a/drivers/net/aironet4500_proc.c b/drivers/net/aironet4500_proc.c index 56a951e1d72a..1946e9c7a849 100644 --- a/drivers/net/aironet4500_proc.c +++ b/drivers/net/aironet4500_proc.c @@ -604,3 +604,4 @@ module_init(aironet_proc_init); module_exit(aironet_proc_exit); #endif // whole proc system styff +MODULE_LICENSE("GPL"); diff --git a/drivers/net/arlan-proc.c b/drivers/net/arlan-proc.c index 2583736ad9a5..5ae3c12f1dec 100644 --- a/drivers/net/arlan-proc.c +++ b/drivers/net/arlan-proc.c @@ -1068,3 +1068,4 @@ void cleanup_module(void) }; #endif // MODULE +MODULE_LICENSE("GPL"); diff --git a/drivers/net/arlan.c b/drivers/net/arlan.c index beef2128909c..2f8c50e4c38f 100644 --- a/drivers/net/arlan.c +++ b/drivers/net/arlan.c @@ -2079,3 +2079,4 @@ void cleanup_module(void) #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index d028df1e0dc7..b9171a449cee 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -918,6 +918,8 @@ cleanup_module(void) release_region(dev_at1700.base_addr, AT1700_IO_EXTENT); } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/atp.c b/drivers/net/atp.c index 31a337ee4d20..62d7ceaeaad0 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -151,6 +151,8 @@ static int xcvr[NUM_UNITS]; /* The data transfer mode. */ MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("RealTek RTL8002/8012 parallel port Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(debug, "i"); MODULE_PARM(io, "1-" __MODULE_STRING(NUM_UNITS) "i"); diff --git a/drivers/net/bonding.c b/drivers/net/bonding.c index 2442de9dcbae..f67756b700af 100644 --- a/drivers/net/bonding.c +++ b/drivers/net/bonding.c @@ -299,6 +299,7 @@ static void __exit bonding_exit(void) module_init(bonding_init); module_exit(bonding_exit); +MODULE_LICENSE("GPL"); /* * Local variables: diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c index a35ead1ef5f1..401671513982 100644 --- a/drivers/net/bsd_comp.c +++ b/drivers/net/bsd_comp.c @@ -1173,3 +1173,4 @@ void __exit bsdcomp_cleanup(void) module_init(bsdcomp_init); module_exit(bsdcomp_cleanup); +MODULE_LICENSE("BSD without advertising clause"); diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 42969a787451..b21549c65ca0 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -1628,6 +1628,8 @@ MODULE_PARM_DESC(use_dma , "(ignored)"); #endif MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>"); +MODULE_LICENSE("GPL"); + EXPORT_NO_SYMBOLS; diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c index 7e30cde0db19..2b5cff2b930c 100644 --- a/drivers/net/de4x5.c +++ b/drivers/net/de4x5.c @@ -1047,6 +1047,8 @@ MODULE_PARM(args, "s"); MODULE_PARM_DESC(de4x5_debug, "de4x5 debug mask"); MODULE_PARM_DESC(dec_only, "de4x5 probe only for Digital boards (0-1)"); MODULE_PARM_DESC(args, "de4x5 full duplex and media type settings; see de4x5.c for details"); +MODULE_LICENSE("GPL"); + # else static int loading_module; #endif /* MODULE */ diff --git a/drivers/net/de600.c b/drivers/net/de600.c index 22314569e65c..b9e5282bfba1 100644 --- a/drivers/net/de600.c +++ b/drivers/net/de600.c @@ -841,6 +841,9 @@ cleanup_module(void) release_region(DE600_IO, 3); } #endif /* MODULE */ + +MODULE_LICENSE("GPL"); + /* * Local variables: * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c" diff --git a/drivers/net/de620.c b/drivers/net/de620.c index 080586930593..98d821621501 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -1008,6 +1008,8 @@ void cleanup_module(void) release_region(de620_dev.base_addr, 3); } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * (add '-DMODULE' when compiling as loadable module) diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c index ff3864a962e9..177dbed4ee1b 100644 --- a/drivers/net/defxx.c +++ b/drivers/net/defxx.c @@ -3413,6 +3413,7 @@ static void __exit dfx_cleanup(void) module_init(dfx_init); module_exit(dfx_cleanup); +MODULE_LICENSE("GPL"); /* diff --git a/drivers/net/depca.c b/drivers/net/depca.c index ac218822da1d..e6f061bedbc6 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -2076,6 +2076,7 @@ cleanup_module(void) release_region(thisDepca.base_addr, DEPCA_TOTAL_SIZE); } #endif /* MODULE */ +MODULE_LICENSE("GPL"); /* diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c index a3422c810244..06e8f427c93e 100644 --- a/drivers/net/dgrs.c +++ b/drivers/net/dgrs.c @@ -126,6 +126,8 @@ static struct pci_device_id dgrs_pci_tbl[] __initdata = { { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(pci, dgrs_pci_tbl); +MODULE_LICENSE("GPL"); + /* * Firmware. Compiled separately for local compilation, diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 66c12f38bb6d..4ca0cf5d8e06 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -34,6 +34,8 @@ static int int_timeout; /* Rx DMA wait time in 64ns increments */ MODULE_AUTHOR ("Edward Peng"); MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter"); +MODULE_LICENSE("GPL"); + MODULE_PARM (mtu, "1-" __MODULE_STRING (MAX_UNITS) "i"); MODULE_PARM (media, "1-" __MODULE_STRING (MAX_UNITS) "s"); MODULE_PARM (vlan, "1-" __MODULE_STRING (MAX_UNITS) "i"); diff --git a/drivers/net/dmfe.c b/drivers/net/dmfe.c index 16e1d97b403d..fba554e9ea22 100644 --- a/drivers/net/dmfe.c +++ b/drivers/net/dmfe.c @@ -2000,6 +2000,7 @@ static struct pci_device_id dmfe_pci_tbl[] __devinitdata = { }; MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl); + static struct pci_driver dmfe_driver = { name: "dmfe", id_table: dmfe_pci_tbl, @@ -2009,6 +2010,8 @@ static struct pci_driver dmfe_driver = { MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw"); MODULE_DESCRIPTION("Davicom DM910X fast ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(debug, "i"); MODULE_PARM(mode, "i"); MODULE_PARM(cr6set, "i"); diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index ac9aab20555c..bd9c573c7362 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -122,3 +122,4 @@ static void __exit dummy_cleanup_module(void) module_init(dummy_init_module); module_exit(dummy_cleanup_module); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c index 1224763df143..cdab71f225b6 100644 --- a/drivers/net/e2100.c +++ b/drivers/net/e2100.c @@ -440,6 +440,8 @@ cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index b35983103396..c12c00c59b0b 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -1767,6 +1767,8 @@ static int n_eepro; MODULE_AUTHOR("Pascal Dupuis <dupuis@lei.ucl.ac.be> for the 2.1 stuff (locking,...)"); MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EEPRO) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i"); MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i"); diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 18f60b762cd0..74a014ceef85 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -43,7 +43,8 @@ static int rxdmacount /* = 0 */; /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method. Lower values use more memory, but are faster. */ -#if defined(__alpha__) || defined(__sparc__) || defined(__arm__) +#if defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \ + defined(__arm__) static int rx_copybreak = 1518; #else static int rx_copybreak = 200; @@ -103,6 +104,7 @@ static int debug = -1; /* The debug level */ #include <linux/spinlock.h> #include <linux/init.h> #include <linux/mii.h> +#include <linux/delay.h> #include <asm/bitops.h> #include <asm/io.h> @@ -114,6 +116,7 @@ static int debug = -1; /* The debug level */ MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>"); MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver"); +MODULE_LICENSE("GPL"); MODULE_PARM(debug, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(8) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i"); @@ -165,7 +168,7 @@ static inline int null_set_power_state(struct pci_dev *dev, int state) #endif -int speedo_debug = 1; +static int speedo_debug = 1; /* Theory of Operation @@ -319,7 +322,7 @@ static inline void io_outw(unsigned int val, unsigned long port) static inline void wait_for_cmd_done(long cmd_ioaddr) { int wait = 1000; - do ; + do udelay(1) ; while(inb(cmd_ioaddr) && --wait >= 0); #ifndef final_version if (wait < 0) @@ -1332,57 +1335,64 @@ speedo_start_xmit(struct sk_buff *skb, struct net_device *dev) long ioaddr = dev->base_addr; int entry; - { /* Prevent interrupts from changing the Tx ring from underneath us. */ - unsigned long flags; - - spin_lock_irqsave(&sp->lock, flags); + /* Prevent interrupts from changing the Tx ring from underneath us. */ + unsigned long flags; - /* Check if there are enough space. */ - if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) { - printk(KERN_ERR "%s: incorrect tbusy state, fixed.\n", dev->name); - netif_stop_queue(dev); - sp->tx_full = 1; - spin_unlock_irqrestore(&sp->lock, flags); - return 1; - } + spin_lock_irqsave(&sp->lock, flags); - /* Calculate the Tx descriptor entry. */ - entry = sp->cur_tx++ % TX_RING_SIZE; + /* Check if there are enough space. */ + if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) { + printk(KERN_ERR "%s: incorrect tbusy state, fixed.\n", dev->name); + netif_stop_queue(dev); + sp->tx_full = 1; + spin_unlock_irqrestore(&sp->lock, flags); + return 1; + } - sp->tx_skbuff[entry] = skb; - sp->tx_ring[entry].status = - cpu_to_le32(CmdSuspend | CmdTx | CmdTxFlex); - if (!(entry & ((TX_RING_SIZE>>2)-1))) - sp->tx_ring[entry].status |= cpu_to_le32(CmdIntr); - sp->tx_ring[entry].link = - cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE)); - sp->tx_ring[entry].tx_desc_addr = - cpu_to_le32(TX_RING_ELEM_DMA(sp, entry) + TX_DESCR_BUF_OFFSET); - /* The data region is always in one buffer descriptor. */ - sp->tx_ring[entry].count = cpu_to_le32(sp->tx_threshold); - sp->tx_ring[entry].tx_buf_addr0 = - cpu_to_le32(pci_map_single(sp->pdev, skb->data, - skb->len, PCI_DMA_TODEVICE)); - sp->tx_ring[entry].tx_buf_size0 = cpu_to_le32(skb->len); - /* Trigger the command unit resume. */ + /* Calculate the Tx descriptor entry. */ + entry = sp->cur_tx++ % TX_RING_SIZE; + + sp->tx_skbuff[entry] = skb; + sp->tx_ring[entry].status = + cpu_to_le32(CmdSuspend | CmdTx | CmdTxFlex); + if (!(entry & ((TX_RING_SIZE>>2)-1))) + sp->tx_ring[entry].status |= cpu_to_le32(CmdIntr); + sp->tx_ring[entry].link = + cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE)); + sp->tx_ring[entry].tx_desc_addr = + cpu_to_le32(TX_RING_ELEM_DMA(sp, entry) + TX_DESCR_BUF_OFFSET); + /* The data region is always in one buffer descriptor. */ + sp->tx_ring[entry].count = cpu_to_le32(sp->tx_threshold); + sp->tx_ring[entry].tx_buf_addr0 = + cpu_to_le32(pci_map_single(sp->pdev, skb->data, + skb->len, PCI_DMA_TODEVICE)); + sp->tx_ring[entry].tx_buf_size0 = cpu_to_le32(skb->len); + + /* workaround for hardware bug on 10 mbit half duplex */ + + if ((sp->partner==0) && (sp->chip_id==1)) { wait_for_cmd_done(ioaddr + SCBCmd); - clear_suspend(sp->last_cmd); - /* We want the time window between clearing suspend flag on the previous - command and resuming CU to be as small as possible. - Interrupts in between are very undesired. --SAW */ - outb(CUResume, ioaddr + SCBCmd); - sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; - - /* Leave room for set_rx_mode(). If there is no more space than reserved - for multicast filter mark the ring as full. */ - if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) { - netif_stop_queue(dev); - sp->tx_full = 1; - } + outb(0 , ioaddr + SCBCmd); + } - spin_unlock_irqrestore(&sp->lock, flags); + /* Trigger the command unit resume. */ + wait_for_cmd_done(ioaddr + SCBCmd); + clear_suspend(sp->last_cmd); + /* We want the time window between clearing suspend flag on the previous + command and resuming CU to be as small as possible. + Interrupts in between are very undesired. --SAW */ + outb(CUResume, ioaddr + SCBCmd); + sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; + + /* Leave room for set_rx_mode(). If there is no more space than reserved + for multicast filter mark the ring as full. */ + if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) { + netif_stop_queue(dev); + sp->tx_full = 1; } + spin_unlock_irqrestore(&sp->lock, flags); + dev->trans_start = jiffies; return 0; @@ -2205,12 +2215,15 @@ static void __devexit eepro100_remove_one (struct pci_dev *pdev) pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD) + sizeof(struct speedo_stats), sp->tx_ring, sp->tx_ring_dma); + pci_disable_device(pdev); kfree(dev); } static struct pci_device_id eepro100_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562ET, + PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029, diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 514dd7e4e2f7..a039bfc504d8 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -1634,6 +1634,8 @@ MODULE_PARM(io, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i"); MODULE_PARM_DESC(io, "EtherExpress 16 I/O base address(es)"); MODULE_PARM_DESC(irq, "EtherExpress 16 IRQ number(s)"); +MODULE_LICENSE("GPL"); + /* Ideally the user would give us io=, irq= for every card. If any parameters * are specified, we verify and then use them. If no parameters are given, we diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index f1c9d7e039a5..468c675b4ba0 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -138,6 +138,8 @@ static char version3[] __devinitdata = MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("SMC 83c170 EPIC series Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(debug, "i"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(rx_copybreak, "i"); diff --git a/drivers/net/eql.c b/drivers/net/eql.c index aa3861ff3028..300f28d51b36 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -1016,6 +1016,7 @@ static void __exit eql_cleanup_module(void) module_init(eql_init_module); module_exit(eql_cleanup_module); +MODULE_LICENSE("GPL"); /* * Local Variables: diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c index 7d89be9c5079..e9cd5bc553e9 100644 --- a/drivers/net/es3210.c +++ b/drivers/net/es3210.c @@ -429,3 +429,5 @@ cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index 469960cb1762..fc546e8b3e89 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -1405,6 +1405,8 @@ static int debug = -1; #if (LINUX_VERSION_CODE >= 0x20115) MODULE_AUTHOR("Mika Kuoppala <miku@iki.fi>"); MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i"); MODULE_PARM_DESC(io, "eth16i I/O base address(es)"); diff --git a/drivers/net/ethertap.c b/drivers/net/ethertap.c index f02363ad6462..6bb635be09c9 100644 --- a/drivers/net/ethertap.c +++ b/drivers/net/ethertap.c @@ -374,3 +374,5 @@ void cleanup_module(void) } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index ce3911e7ed20..4b9319011880 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -1876,6 +1876,8 @@ void cleanup_module(void) release_region(thisEthwrk.base_addr, EWRK3_TOTAL_SIZE); } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* diff --git a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c index 8d91da5067ed..4b7f58f9afcb 100644 --- a/drivers/net/fc/iph5526.c +++ b/drivers/net/fc/iph5526.c @@ -1932,7 +1932,7 @@ u_int tachyon_status; fi->g.name_server = FALSE; fi->g.alpa_list_index = 0; fi->g.ox_id = NOT_SCSI_XID; - fi->g.my_mtu = FRAME_SIZE; + fi->g.my_mtu = TACH_FRAME_SIZE; /* Implicitly LOGO with all logged-in nodes. */ @@ -2811,7 +2811,7 @@ int i; else if (logi == ELS_FLOGI) fi->g.login.common_features = htons(FLOGI_C_F); - fi->g.login.recv_data_field_size = htons(FRAME_SIZE); + fi->g.login.recv_data_field_size = htons(TACH_FRAME_SIZE); fi->g.login.n_port_total_conc_seq = htons(CONCURRENT_SEQUENCES); fi->g.login.rel_off_by_info_cat = htons(RO_INFO_CATEGORY); fi->g.login.ED_TOV = htonl(E_D_TOV); @@ -2847,7 +2847,7 @@ int i; fi->g.login.c_of_s[2].service_options = htons(SERVICE_VALID); fi->g.login.c_of_s[2].initiator_ctl = htons(0); fi->g.login.c_of_s[2].recipient_ctl = htons(0); - fi->g.login.c_of_s[2].recv_data_field_size = htons(FRAME_SIZE); + fi->g.login.c_of_s[2].recv_data_field_size = htons(TACH_FRAME_SIZE); fi->g.login.c_of_s[2].concurrent_sequences = htons(CLASS3_CONCURRENT_SEQUENCE); fi->g.login.c_of_s[2].n_port_end_to_end_credit = htons(0); fi->g.login.c_of_s[2].open_seq_per_exchange = htons(CLASS3_OPEN_SEQUENCE); diff --git a/drivers/net/fc/tach.h b/drivers/net/fc/tach.h index 741812c5f554..3e90ec06786e 100644 --- a/drivers/net/fc/tach.h +++ b/drivers/net/fc/tach.h @@ -94,9 +94,9 @@ /* Size of the various buffers. */ -#define FRAME_SIZE 2048 -#define MFS_BUFFER_SIZE FRAME_SIZE -#define SFS_BUFFER_SIZE (FRAME_SIZE + TACHYON_HEADER_LEN) +#define TACH_FRAME_SIZE 2048 +#define MFS_BUFFER_SIZE TACH_FRAME_SIZE +#define SFS_BUFFER_SIZE (TACH_FRAME_SIZE + TACHYON_HEADER_LEN) #define SEST_BUFFER_SIZE 512 #define TACH_HEADER_SIZE 64 #define NO_OF_TACH_HEADERS ((MY_PAGE_SIZE)/TACH_HEADER_SIZE) diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 26cbf35279c3..c84b81dd1c50 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -521,6 +521,8 @@ struct hamachi_private { MODULE_AUTHOR("Donald Becker <becker@scyld.com>, Eric Kasten <kasten@nscl.msu.edu>, Keith Underwood <keithu@parl.clemson.edu>"); MODULE_DESCRIPTION("Packet Engines 'Hamachi' GNIC-II Gigabit Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(mtu, "i"); MODULE_PARM(debug, "i"); diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 3bf52f8465e4..5a871a8cbc84 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -35,6 +35,9 @@ * 0.6 F6FBB 25.08.98 Added 1200Bds format * 0.7 F6FBB 12.09.98 Added to the kernel configuration * 0.8 F6FBB 14.10.98 Fixed slottime/persistance timing bug + * OK1ZIA 2.09.01 Fixed "kfree_skb on hard IRQ" + * using dev_kfree_skb_any(). (important in 2.4 kernel) + * */ /*****************************************************************************/ @@ -649,16 +652,16 @@ static void yam_tx_byte(struct net_device *dev, struct yam_port *yp) yp->tx_state = TX_DATA; if (skb->data[0] != 0) { /* do_kiss_params(s, skb->data, skb->len); */ - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); break; } yp->tx_len = skb->len - 1; /* strip KISS byte */ if (yp->tx_len >= YAM_MAX_FRAME || yp->tx_len < 2) { - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); break; } memcpy(yp->tx_buf, skb->data + 1, yp->tx_len); - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); yp->tx_count = 0; yp->tx_crcl = 0x21; yp->tx_crch = 0xf3; @@ -858,7 +861,7 @@ static int yam_open(struct net_device *dev) return -EIO; } outb(0, IER(dev->base_addr)); - if (request_irq(dev->irq, yam_interrupt, SA_INTERRUPT | SA_SHIRQ, dev->name, NULL)) { + if (request_irq(dev->irq, yam_interrupt, SA_INTERRUPT | SA_SHIRQ, dev->name, dev)) { printk(KERN_ERR "%s: irq %d busy\n", dev->name, dev->irq); return -EBUSY; } @@ -896,7 +899,7 @@ static int yam_close(struct net_device *dev) outb(0, IER(dev->base_addr)); outb(1, MCR(dev->base_addr)); /* Remove IRQ handler if last */ - free_irq(dev->irq, NULL); + free_irq(dev->irq,dev); release_region(dev->base_addr, YAM_EXTENT); netif_stop_queue(dev); while ((skb = skb_dequeue(&yp->send_queue))) diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index a5af15996251..f3d056d8a7f9 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -457,6 +457,8 @@ cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/hp.c b/drivers/net/hp.c index 8c309f8643ec..1799981670b6 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -429,6 +429,8 @@ cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 36479e42df3e..0b25e65b9cca 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -2,7 +2,7 @@ ** hp100.c ** HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters ** -** $Id: hp100.c,v 1.57 1998/04/10 16:27:23 perex Exp perex $ +** $Id: hp100.c,v 1.58 2001/09/24 18:03:01 perex Exp perex $ ** ** Based on the HP100 driver written by Jaroslav Kysela <perex@jcu.cz> ** Extended for new busmaster capable chipsets by @@ -45,6 +45,11 @@ ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** +** 1.57c -> 1.58 +** - used indent to change coding-style +** - added KTI DP-200 EISA ID +** - ioremap is also used for low (<1MB) memory (multi-architecture support) +** ** 1.57b -> 1.57c - Arnaldo Carvalho de Melo <acme@conectiva.com.br> ** - release resources on failure in init_module ** @@ -78,18 +83,18 @@ ** */ -#define HP100_DEFAULT_PRIORITY_TX 0 +#define HP100_DEFAULT_PRIORITY_TX 0 #undef HP100_DEBUG -#undef HP100_DEBUG_B /* Trace */ -#undef HP100_DEBUG_BM /* Debug busmaster code (PDL stuff) */ +#undef HP100_DEBUG_B /* Trace */ +#undef HP100_DEBUG_BM /* Debug busmaster code (PDL stuff) */ -#undef HP100_DEBUG_TRAINING /* Debug login-to-hub procedure */ -#undef HP100_DEBUG_TX -#undef HP100_DEBUG_IRQ -#undef HP100_DEBUG_RX +#undef HP100_DEBUG_TRAINING /* Debug login-to-hub procedure */ +#undef HP100_DEBUG_TX +#undef HP100_DEBUG_IRQ +#undef HP100_DEBUG_RX -#undef HP100_MULTICAST_FILTER /* Need to be debugged... */ +#undef HP100_MULTICAST_FILTER /* Need to be debugged... */ #include <linux/version.h> #include <linux/module.h> @@ -110,7 +115,7 @@ #include <linux/skbuff.h> #include <linux/types.h> -#include <linux/config.h> /* for CONFIG_PCI */ +#include <linux/config.h> /* for CONFIG_PCI */ #include <linux/delay.h> #include <linux/init.h> @@ -144,7 +149,7 @@ EXPORT_NO_SYMBOLS; #define PCI_DEVICE_ID_COMPEX2_100VG 0x0005 #endif -#define HP100_REGION_SIZE 0x20 /* for ioports */ +#define HP100_REGION_SIZE 0x20 /* for ioports */ #define HP100_MAX_PACKET_SIZE (1536+4) #define HP100_MIN_PACKET_SIZE 60 @@ -164,51 +169,51 @@ EXPORT_NO_SYMBOLS; */ struct hp100_eisa_id { - u_int id; - const char *name; - u_char bus; + u_int id; + const char *name; + u_char bus; }; struct hp100_pci_id { - u_short vendor; - u_short device; + u_short vendor; + u_short device; }; struct hp100_private { - struct hp100_eisa_id *id; - spinlock_t lock; - u_short chip; - u_short soft_model; - u_int memory_size; - u_int virt_memory_size; - u_short rx_ratio; /* 1 - 99 */ - u_short priority_tx; /* != 0 - priority tx */ - u_short mode; /* PIO, Shared Mem or Busmaster */ - u_char bus; - struct pci_dev *pci_dev; - short mem_mapped; /* memory mapped access */ - void *mem_ptr_virt; /* virtual memory mapped area, maybe NULL */ - unsigned long mem_ptr_phys; /* physical memory mapped area */ - short lan_type; /* 10Mb/s, 100Mb/s or -1 (error) */ - int hub_status; /* was login to hub successful? */ - u_char mac1_mode; - u_char mac2_mode; - u_char hash_bytes[ 8 ]; - hp100_stats_t stats; - - /* Rings for busmaster mode: */ - hp100_ring_t *rxrhead; /* Head (oldest) index into rxring */ - hp100_ring_t *rxrtail; /* Tail (newest) index into rxring */ - hp100_ring_t *txrhead; /* Head (oldest) index into txring */ - hp100_ring_t *txrtail; /* Tail (newest) index into txring */ - - hp100_ring_t rxring[ MAX_RX_PDL ]; - hp100_ring_t txring[ MAX_TX_PDL ]; - - u_int *page_vaddr; /* Virtual address of allocated page */ - u_int *page_vaddr_algn; /* Aligned virtual address of allocated page */ - int rxrcommit; /* # Rx PDLs commited to adapter */ - int txrcommit; /* # Tx PDLs commited to adapter */ + struct hp100_eisa_id *id; + spinlock_t lock; + u_short chip; + u_short soft_model; + u_int memory_size; + u_int virt_memory_size; + u_short rx_ratio; /* 1 - 99 */ + u_short priority_tx; /* != 0 - priority tx */ + u_short mode; /* PIO, Shared Mem or Busmaster */ + u_char bus; + struct pci_dev *pci_dev; + short mem_mapped; /* memory mapped access */ + void *mem_ptr_virt; /* virtual memory mapped area, maybe NULL */ + unsigned long mem_ptr_phys; /* physical memory mapped area */ + short lan_type; /* 10Mb/s, 100Mb/s or -1 (error) */ + int hub_status; /* was login to hub successful? */ + u_char mac1_mode; + u_char mac2_mode; + u_char hash_bytes[8]; + hp100_stats_t stats; + + /* Rings for busmaster mode: */ + hp100_ring_t *rxrhead; /* Head (oldest) index into rxring */ + hp100_ring_t *rxrtail; /* Tail (newest) index into rxring */ + hp100_ring_t *txrhead; /* Head (oldest) index into txring */ + hp100_ring_t *txrtail; /* Tail (newest) index into txring */ + + hp100_ring_t rxring[MAX_RX_PDL]; + hp100_ring_t txring[MAX_TX_PDL]; + + u_int *page_vaddr; /* Virtual address of allocated page */ + u_int *page_vaddr_algn; /* Aligned virtual address of allocated page */ + int rxrcommit; /* # Rx PDLs commited to adapter */ + int txrcommit; /* # Tx PDLs commited to adapter */ }; /* @@ -217,62 +222,64 @@ struct hp100_private { static struct hp100_eisa_id hp100_eisa_ids[] = { - /* 10/100 EISA card with revision A Cascade chip */ - { 0x80F1F022, "HP J2577 rev A", HP100_BUS_EISA }, + /* 10/100 EISA card with revision A Cascade chip */ + {0x80F1F022, "HP J2577 rev A", HP100_BUS_EISA}, - /* 10/100 ISA card with revision A Cascade chip */ - { 0x50F1F022, "HP J2573 rev A", HP100_BUS_ISA }, + /* 10/100 ISA card with revision A Cascade chip */ + {0x50F1F022, "HP J2573 rev A", HP100_BUS_ISA}, - /* 10 only EISA card with Cascade chip */ - { 0x2019F022, "HP 27248B", HP100_BUS_EISA }, + /* 10 only EISA card with Cascade chip */ + {0x2019F022, "HP 27248B", HP100_BUS_EISA}, - /* 10/100 EISA card with Cascade chip */ - { 0x4019F022, "HP J2577", HP100_BUS_EISA }, + /* 10/100 EISA card with Cascade chip */ + {0x4019F022, "HP J2577", HP100_BUS_EISA}, - /* 10/100 ISA card with Cascade chip */ - { 0x5019F022, "HP J2573", HP100_BUS_ISA }, + /* 10/100 ISA card with Cascade chip */ + {0x5019F022, "HP J2573", HP100_BUS_ISA}, - /* 10/100 PCI card - old J2585A */ - { 0x1030103c, "HP J2585A", HP100_BUS_PCI }, + /* 10/100 PCI card - old J2585A */ + {0x1030103c, "HP J2585A", HP100_BUS_PCI}, - /* 10/100 PCI card - new J2585B - master capable */ - { 0x1041103c, "HP J2585B", HP100_BUS_PCI }, + /* 10/100 PCI card - new J2585B - master capable */ + {0x1041103c, "HP J2585B", HP100_BUS_PCI}, - /* 10 Mbit Combo Adapter */ - { 0x1042103c, "HP J2970", HP100_BUS_PCI }, + /* 10 Mbit Combo Adapter */ + {0x1042103c, "HP J2970", HP100_BUS_PCI}, - /* 10 Mbit 10baseT Adapter */ - { 0x1040103c, "HP J2973", HP100_BUS_PCI }, + /* 10 Mbit 10baseT Adapter */ + {0x1040103c, "HP J2973", HP100_BUS_PCI}, - /* 10/100 EISA card from Compex */ - { 0x0103180e, "ReadyLink ENET100-VG4", HP100_BUS_EISA }, + /* 10/100 EISA card from Compex */ + {0x0103180e, "ReadyLink ENET100-VG4", HP100_BUS_EISA}, - /* 10/100 EISA card from Compex - FreedomLine (sq5bpf) */ - /* Note: plhbrod@mbox.vol.cz reported that same ID have ISA */ - /* version of adapter, too... */ - { 0x0104180e, "FreedomLine 100/VG", HP100_BUS_EISA }, + /* 10/100 EISA card from Compex - FreedomLine (sq5bpf) */ + /* Note: plhbrod@mbox.vol.cz reported that same ID have ISA */ + /* version of adapter, too... */ + {0x0104180e, "FreedomLine 100/VG", HP100_BUS_EISA}, - /* 10/100 PCI card from Compex - FreedomLine - * - * I think this card doesn't like aic7178 scsi controller, but - * I haven't tested this much. It works fine on diskless machines. - * Jacek Lipkowski <sq5bpf@acid.ch.pw.edu.pl> - */ - { 0x021211f6, "FreedomLine 100/VG", HP100_BUS_PCI }, - - /* 10/100 PCI card from Compex (J2585A compatible) */ - { 0x011211f6, "ReadyLink ENET100-VG4", HP100_BUS_PCI } + /* 10/100 PCI card from Compex - FreedomLine + * + * I think this card doesn't like aic7178 scsi controller, but + * I haven't tested this much. It works fine on diskless machines. + * Jacek Lipkowski <sq5bpf@acid.ch.pw.edu.pl> + */ + {0x021211f6, "FreedomLine 100/VG", HP100_BUS_PCI}, + /* 10/100 PCI card from Compex (J2585A compatible) */ + {0x011211f6, "ReadyLink ENET100-VG4", HP100_BUS_PCI}, + + /* 10/100 PCI card from KTI */ + {0x40008e2e, "KTI DP-200", HP100_BUS_PCI } }; #define HP100_EISA_IDS_SIZE (sizeof(hp100_eisa_ids)/sizeof(struct hp100_eisa_id)) #ifdef CONFIG_PCI static struct hp100_pci_id hp100_pci_ids[] = { - { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A }, - { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B }, - { PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4 }, - { PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG } + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B}, + {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4}, + {PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG} }; #endif @@ -280,62 +287,71 @@ static struct hp100_pci_id hp100_pci_ids[] = { #if LINUX_VERSION_CODE >= 0x20400 static struct pci_device_id hp100_pci_tbl[] __initdata = { - { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4, PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG, PCI_ANY_ID, PCI_ANY_ID, }, - { } /* Terminating entry */ + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,}, + {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4, PCI_ANY_ID, PCI_ANY_ID,}, + {PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG, PCI_ANY_ID, PCI_ANY_ID,}, + {} /* Terminating entry */ }; MODULE_DEVICE_TABLE(pci, hp100_pci_tbl); -#endif /* LINUX_VERSION_CODE >= 0x20400 */ +#endif /* LINUX_VERSION_CODE >= 0x20400 */ static int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO; static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX; static int hp100_mode = 1; -MODULE_PARM( hp100_rx_ratio, "1i" ); -MODULE_PARM( hp100_priority_tx, "1i" ); -MODULE_PARM( hp100_mode, "1i" ); +MODULE_PARM(hp100_rx_ratio, "1i"); +MODULE_PARM(hp100_priority_tx, "1i"); +MODULE_PARM(hp100_mode, "1i"); /* * prototypes */ -static int hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ); -static int hp100_open( struct net_device *dev ); -static int hp100_close( struct net_device *dev ); -static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ); -static int hp100_start_xmit_bm (struct sk_buff *skb, struct net_device *dev ); -static void hp100_rx( struct net_device *dev ); -static hp100_stats_t *hp100_get_stats( struct net_device *dev ); -static void hp100_misc_interrupt( struct net_device *dev ); -static void hp100_update_stats( struct net_device *dev ); -static void hp100_clear_stats( struct hp100_private *lp, int ioaddr ); -static void hp100_set_multicast_list( struct net_device *dev); -static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs ); -static void hp100_start_interface( struct net_device *dev ); -static void hp100_stop_interface( struct net_device *dev ); -static void hp100_load_eeprom( struct net_device *dev, u_short ioaddr ); -static int hp100_sense_lan( struct net_device *dev ); -static int hp100_login_to_vg_hub( struct net_device *dev, u_short force_relogin ); -static int hp100_down_vg_link( struct net_device *dev ); -static void hp100_cascade_reset( struct net_device *dev, u_short enable ); -static void hp100_BM_shutdown( struct net_device *dev ); -static void hp100_mmuinit( struct net_device *dev ); -static void hp100_init_pdls( struct net_device *dev ); -static int hp100_init_rxpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); -static int hp100_init_txpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); -static void hp100_rxfill( struct net_device *dev ); -static void hp100_hwinit( struct net_device *dev ); -static void hp100_clean_txring( struct net_device *dev ); +static int hp100_probe1(struct net_device *dev, int ioaddr, u_char bus, + struct pci_dev *pci_dev); + + +static int hp100_open(struct net_device *dev); +static int hp100_close(struct net_device *dev); +static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int hp100_start_xmit_bm(struct sk_buff *skb, + struct net_device *dev); +static void hp100_rx(struct net_device *dev); +static hp100_stats_t *hp100_get_stats(struct net_device *dev); +static void hp100_misc_interrupt(struct net_device *dev); +static void hp100_update_stats(struct net_device *dev); +static void hp100_clear_stats(struct hp100_private *lp, int ioaddr); +static void hp100_set_multicast_list(struct net_device *dev); +static void hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static void hp100_start_interface(struct net_device *dev); +static void hp100_stop_interface(struct net_device *dev); +static void hp100_load_eeprom(struct net_device *dev, u_short ioaddr); +static int hp100_sense_lan(struct net_device *dev); +static int hp100_login_to_vg_hub(struct net_device *dev, + u_short force_relogin); +static int hp100_down_vg_link(struct net_device *dev); +static void hp100_cascade_reset(struct net_device *dev, u_short enable); +static void hp100_BM_shutdown(struct net_device *dev); +static void hp100_mmuinit(struct net_device *dev); +static void hp100_init_pdls(struct net_device *dev); +static int hp100_init_rxpdl(struct net_device *dev, + register hp100_ring_t * ringptr, + register u_int * pdlptr); +static int hp100_init_txpdl(struct net_device *dev, + register hp100_ring_t * ringptr, + register u_int * pdlptr); +static void hp100_rxfill(struct net_device *dev); +static void hp100_hwinit(struct net_device *dev); +static void hp100_clean_txring(struct net_device *dev); #ifdef HP100_DEBUG -static void hp100_RegisterDump( struct net_device *dev ); +static void hp100_RegisterDump(struct net_device *dev); #endif /* TODO: This function should not really be needed in a good design... */ -static void wait( void ) +static void wait(void) { - mdelay(1); + mdelay(1); } /* @@ -343,977 +359,923 @@ static void wait( void ) * These functions should - if possible - avoid doing write operations * since this could cause problems when the card is not installed. */ - -int __init hp100_probe( struct net_device *dev ) + +int __init hp100_probe(struct net_device *dev) { - int base_addr = dev ? dev -> base_addr : 0; - int ioaddr = 0; + int base_addr = dev ? dev->base_addr : 0; + int ioaddr = 0; #ifdef CONFIG_PCI - int pci_start_index = 0; + int pci_start_index = 0; #endif #ifdef HP100_DEBUG_B - hp100_outw( 0x4200, TRACE ); - printk( "hp100: %s: probe\n", dev->name ); -#endif - - if ( base_addr > 0xff ) /* Check a single specified location. */ - { - if ( check_region( base_addr, HP100_REGION_SIZE ) ) return -EINVAL; - if ( base_addr < 0x400 ) - return hp100_probe1( dev, base_addr, HP100_BUS_ISA, NULL ); - if ( EISA_bus && base_addr >= 0x1c38 && ( (base_addr - 0x1c38) & 0x3ff ) == 0 ) - return hp100_probe1( dev, base_addr, HP100_BUS_EISA, NULL ); + hp100_outw(0x4200, TRACE); + printk("hp100: %s: probe\n", dev->name); +#endif + + if (base_addr > 0xff) { /* Check a single specified location. */ + if (check_region(base_addr, HP100_REGION_SIZE)) + return -EINVAL; + if (base_addr < 0x400) + return hp100_probe1(dev, base_addr, HP100_BUS_ISA, + NULL); + if (EISA_bus && base_addr >= 0x1c38 && ((base_addr - 0x1c38) & 0x3ff) == 0) + return hp100_probe1(dev, base_addr, HP100_BUS_EISA, NULL); #ifdef CONFIG_PCI - printk( "hp100: %s: You must specify card # in i/o address parameter for PCI bus...", dev->name ); + printk("hp100: %s: You must specify card # in i/o address parameter for PCI bus...", dev->name); #else - return -ENODEV; + return -ENODEV; #endif - } - else + } else #ifdef CONFIG_PCI - if ( base_addr > 0 && base_addr < 8 + 1 ) - pci_start_index = 0x100 | ( base_addr - 1 ); - else + if (base_addr > 0 && base_addr < 8 + 1) + pci_start_index = 0x100 | (base_addr - 1); + else #endif - if ( base_addr != 0 ) return -ENXIO; + if (base_addr != 0) + return -ENXIO; - /* at first - scan PCI bus(es) */ + /* First: scan PCI bus(es) */ #ifdef CONFIG_PCI - if ( pcibios_present() ) - { - int pci_index; - struct pci_dev *pci_dev = NULL; - int pci_id_index; - u_short pci_command; + if (pcibios_present()) { + int pci_index; + struct pci_dev *pci_dev = NULL; + int pci_id_index; + u_short pci_command; #ifdef HP100_DEBUG_PCI - printk( "hp100: %s: PCI BIOS is present, checking for devices..\n", dev->name ); -#endif - pci_index = 0; - for ( pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE; pci_id_index++ ) { - while ( (pci_dev = pci_find_device( hp100_pci_ids[ pci_id_index ].vendor, - hp100_pci_ids[ pci_id_index ].device, - pci_dev )) != NULL ) { - if ( pci_index < (pci_start_index & 7) ) { - pci_index++; - continue; - } - if (pci_enable_device(pci_dev)) - continue; - /* found... */ - ioaddr = pci_resource_start (pci_dev, 0); - if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue; - pci_read_config_word( pci_dev, PCI_COMMAND, &pci_command ); - if ( !( pci_command & PCI_COMMAND_IO ) ) { + printk("hp100: %s: PCI BIOS is present, checking for devices..\n", dev->name); +#endif + pci_index = 0; + for (pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE; + pci_id_index++) { + while ((pci_dev = pci_find_device(hp100_pci_ids[pci_id_index].vendor, + hp100_pci_ids[pci_id_index].device, + pci_dev)) != NULL) { + if (pci_index < (pci_start_index & 7)) { + pci_index++; + continue; + } + if (pci_enable_device(pci_dev)) + continue; + /* found... */ + ioaddr = pci_resource_start(pci_dev, 0); + if (check_region(ioaddr, HP100_REGION_SIZE)) + continue; + pci_read_config_word(pci_dev, PCI_COMMAND, &pci_command); + if (!(pci_command & PCI_COMMAND_IO)) { #ifdef HP100_DEBUG - printk( "hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name ); + printk("hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name); #endif - pci_command |= PCI_COMMAND_IO; - pci_write_config_word( pci_dev, PCI_COMMAND, pci_command ); - } - if ( !( pci_command & PCI_COMMAND_MASTER ) ) { + pci_command |= PCI_COMMAND_IO; + pci_write_config_word(pci_dev, PCI_COMMAND, pci_command); + } + if (!(pci_command & PCI_COMMAND_MASTER)) { #ifdef HP100_DEBUG - printk( "hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name ); + printk("hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name); #endif - pci_command |= PCI_COMMAND_MASTER; - pci_write_config_word( pci_dev, PCI_COMMAND, pci_command ); - } + pci_command |= PCI_COMMAND_MASTER; + pci_write_config_word(pci_dev, PCI_COMMAND, pci_command); + } #ifdef HP100_DEBUG - printk( "hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr ); -#endif - if ( hp100_probe1( dev, ioaddr, HP100_BUS_PCI, pci_dev ) == 0 ) - return 0; - } - } - } - if ( pci_start_index > 0 ) return -ENODEV; + printk("hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr); +#endif + if (hp100_probe1(dev, ioaddr, HP100_BUS_PCI, pci_dev) == 0) + return 0; + } + } + } + if (pci_start_index > 0) + return -ENODEV; #endif /* CONFIG_PCI */ - /* Second: Probe all EISA possible port regions (if EISA bus present) */ - for ( ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400 ) - { - if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue; - if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA, NULL ) == 0 ) return 0; - } - - /* Third Probe all ISA possible port regions */ - for ( ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20 ) - { - if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue; - if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA, NULL ) == 0 ) return 0; - } - - return -ENODEV; + /* Second: Probe all EISA possible port regions (if EISA bus present) */ + for (ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400) { + if (check_region(ioaddr, HP100_REGION_SIZE)) + continue; + if (hp100_probe1(dev, ioaddr, HP100_BUS_EISA, NULL) == 0) + return 0; + } + + /* Third: Probe all ISA possible port regions */ + for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) { + if (check_region(ioaddr, HP100_REGION_SIZE)) + continue; + if (hp100_probe1(dev, ioaddr, HP100_BUS_ISA, NULL) == 0) + return 0; + } + + return -ENODEV; } - -static int __init hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ) +static int __init hp100_probe1(struct net_device *dev, int ioaddr, + u_char bus, struct pci_dev *pci_dev) { - int i; - - u_char uc, uc_1; - u_int eisa_id; - u_int chip; - u_int memory_size = 0, virt_memory_size = 0; - u_short local_mode, lsw; - short mem_mapped; - unsigned long mem_ptr_phys; - void **mem_ptr_virt; - struct hp100_private *lp; - struct hp100_eisa_id *eid; + int i; + + u_char uc, uc_1; + u_int eisa_id; + u_int chip; + u_int memory_size = 0, virt_memory_size = 0; + u_short local_mode, lsw; + short mem_mapped; + unsigned long mem_ptr_phys; + void **mem_ptr_virt; + struct hp100_private *lp; + struct hp100_eisa_id *eid; #ifdef HP100_DEBUG_B - hp100_outw( 0x4201, TRACE ); - printk("hp100: %s: probe1\n",dev->name); + hp100_outw(0x4201, TRACE); + printk("hp100: %s: probe1\n", dev->name); #endif - if ( dev == NULL ) - { + if (dev == NULL) { #ifdef HP100_DEBUG - printk( "hp100_probe1: %s: dev == NULL ?\n", dev->name ); -#endif - return -EIO; - } - - if ( hp100_inw( HW_ID ) != HP100_HW_ID_CASCADE ) - { - return -ENODEV; - } - else - { - chip = hp100_inw( PAGING ) & HP100_CHIPID_MASK; + printk("hp100_probe1: %s: dev == NULL ?\n", dev->name); +#endif + return -EIO; + } + + if (hp100_inw(HW_ID) != HP100_HW_ID_CASCADE) { + return -ENODEV; + } else { + chip = hp100_inw(PAGING) & HP100_CHIPID_MASK; #ifdef HP100_DEBUG - if ( chip == HP100_CHIPID_SHASTA ) - printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name); - else if ( chip == HP100_CHIPID_RAINIER ) - printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name); - else if ( chip == HP100_CHIPID_LASSEN ) - printk("hp100: %s: Lassen Chip detected.\n", dev->name); - else - printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n",dev->name,chip); -#endif - } - - dev->base_addr = ioaddr; - - hp100_page( ID_MAC_ADDR ); - for ( i = uc = eisa_id = 0; i < 4; i++ ) - { - eisa_id >>= 8; - uc_1 = hp100_inb( BOARD_ID + i ); - eisa_id |= uc_1 << 24; - uc += uc_1; - } - uc += hp100_inb( BOARD_ID + 4 ); - - if ( uc != 0xff ) /* bad checksum? */ - { - printk("hp100_probe: %s: bad EISA ID checksum at base port 0x%x\n", dev->name, ioaddr ); - return -ENODEV; - } - - for ( i=0; i < HP100_EISA_IDS_SIZE; i++) - if ( hp100_eisa_ids[ i ].id == eisa_id ) - break; - if ( i >= HP100_EISA_IDS_SIZE ) { - for ( i = 0; i < HP100_EISA_IDS_SIZE; i++) - if ( ( hp100_eisa_ids[ i ].id & 0xf0ffffff ) == ( eisa_id & 0xf0ffffff ) ) - break; - if ( i >= HP100_EISA_IDS_SIZE ) { - printk( "hp100_probe: %s: card at port 0x%x isn't known (id = 0x%x)\n", dev -> name, ioaddr, eisa_id ); - return -ENODEV; - } - } - eid = &hp100_eisa_ids[ i ]; - if ( ( eid->id & 0x0f000000 ) < ( eisa_id & 0x0f000000 ) ) - { - printk( "hp100_probe: %s: newer version of card %s at port 0x%x - unsupported\n", - dev->name, eid->name, ioaddr ); - return -ENODEV; - } - - for ( i = uc = 0; i < 7; i++ ) - uc += hp100_inb( LAN_ADDR + i ); - if ( uc != 0xff ) - { - printk("hp100_probe: %s: bad lan address checksum (card %s at port 0x%x)\n", - dev->name, eid->name, ioaddr ); - return -EIO; - } - - /* Make sure, that all registers are correctly updated... */ - - hp100_load_eeprom( dev, ioaddr ); - wait(); - - /* - * Determine driver operation mode - * - * Use the variable "hp100_mode" upon insmod or as kernel parameter to - * force driver modes: - * hp100_mode=1 -> default, use busmaster mode if configured. - * hp100_mode=2 -> enable shared memory mode - * hp100_mode=3 -> force use of i/o mapped mode. - * hp100_mode=4 -> same as 1, but re-set the enable bit on the card. - */ - - /* - * LSW values: - * 0x2278 -> J2585B, PnP shared memory mode - * 0x2270 -> J2585B, shared memory mode, 0xdc000 - * 0xa23c -> J2585B, I/O mapped mode - * 0x2240 -> EISA COMPEX, BusMaster (Shasta Chip) - * 0x2220 -> EISA HP, I/O (Shasta Chip) - * 0x2260 -> EISA HP, BusMaster (Shasta Chip) - */ + if (chip == HP100_CHIPID_SHASTA) + printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name); + else if (chip == HP100_CHIPID_RAINIER) + printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name); + else if (chip == HP100_CHIPID_LASSEN) + printk("hp100: %s: Lassen Chip detected.\n", dev->name); + else + printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n", dev->name, chip); +#endif + } + + dev->base_addr = ioaddr; + + hp100_page(ID_MAC_ADDR); + for (i = uc = eisa_id = 0; i < 4; i++) { + eisa_id >>= 8; + uc_1 = hp100_inb(BOARD_ID + i); + eisa_id |= uc_1 << 24; + uc += uc_1; + } + uc += hp100_inb(BOARD_ID + 4); + + if (uc != 0xff) { /* bad checksum? */ + printk("hp100_probe: %s: bad EISA ID checksum at base port 0x%x\n", dev->name, ioaddr); + return -ENODEV; + } + + for (i = 0; i < HP100_EISA_IDS_SIZE; i++) + if (hp100_eisa_ids[i].id == eisa_id) + break; + if (i >= HP100_EISA_IDS_SIZE) { + for (i = 0; i < HP100_EISA_IDS_SIZE; i++) + if ((hp100_eisa_ids[i].id & 0xf0ffffff) == (eisa_id & 0xf0ffffff)) + break; + if (i >= HP100_EISA_IDS_SIZE) { + printk ("hp100_probe: %s: card at port 0x%x isn't known (id = 0x%x)\n", dev->name, ioaddr, eisa_id); + return -ENODEV; + } + } + eid = &hp100_eisa_ids[i]; + if ((eid->id & 0x0f000000) < (eisa_id & 0x0f000000)) { + printk("hp100_probe: %s: newer version of card %s at port 0x%x - unsupported\n", dev->name, eid->name, ioaddr); + return -ENODEV; + } + + for (i = uc = 0; i < 7; i++) + uc += hp100_inb(LAN_ADDR + i); + if (uc != 0xff) { + printk("hp100_probe: %s: bad lan address checksum (card %s at port 0x%x)\n", dev->name, eid->name, ioaddr); + return -EIO; + } + + /* Make sure, that all registers are correctly updated... */ + + hp100_load_eeprom(dev, ioaddr); + wait(); + + /* + * Determine driver operation mode + * + * Use the variable "hp100_mode" upon insmod or as kernel parameter to + * force driver modes: + * hp100_mode=1 -> default, use busmaster mode if configured. + * hp100_mode=2 -> enable shared memory mode + * hp100_mode=3 -> force use of i/o mapped mode. + * hp100_mode=4 -> same as 1, but re-set the enable bit on the card. + */ + + /* + * LSW values: + * 0x2278 -> J2585B, PnP shared memory mode + * 0x2270 -> J2585B, shared memory mode, 0xdc000 + * 0xa23c -> J2585B, I/O mapped mode + * 0x2240 -> EISA COMPEX, BusMaster (Shasta Chip) + * 0x2220 -> EISA HP, I/O (Shasta Chip) + * 0x2260 -> EISA HP, BusMaster (Shasta Chip) + */ #if 0 - local_mode = 0x2270; - hp100_outw(0xfefe,OPTION_LSW); - hp100_outw(local_mode|HP100_SET_LB|HP100_SET_HB,OPTION_LSW); + local_mode = 0x2270; + hp100_outw(0xfefe, OPTION_LSW); + hp100_outw(local_mode | HP100_SET_LB | HP100_SET_HB, OPTION_LSW); #endif - /* hp100_mode value maybe used in future by another card */ - local_mode=hp100_mode; - if ( local_mode < 1 || local_mode > 4 ) - local_mode = 1; /* default */ + /* hp100_mode value maybe used in future by another card */ + local_mode = hp100_mode; + if (local_mode < 1 || local_mode > 4) + local_mode = 1; /* default */ #ifdef HP100_DEBUG - printk( "hp100: %s: original LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW) ); -#endif - - if(local_mode==3) - { - hp100_outw(HP100_MEM_EN|HP100_RESET_LB, OPTION_LSW); - hp100_outw(HP100_IO_EN|HP100_SET_LB, OPTION_LSW); - hp100_outw(HP100_BM_WRITE|HP100_BM_READ|HP100_RESET_HB, OPTION_LSW); - printk("hp100: %s: IO mapped mode forced.\n", dev->name); - } - else if(local_mode==2) - { - hp100_outw(HP100_MEM_EN|HP100_SET_LB, OPTION_LSW); - hp100_outw(HP100_IO_EN |HP100_SET_LB, OPTION_LSW); - hp100_outw(HP100_BM_WRITE|HP100_BM_READ|HP100_RESET_HB, OPTION_LSW); - printk("hp100: %s: Shared memory mode requested.\n", dev->name); - } - else if(local_mode==4) - { - if(chip==HP100_CHIPID_LASSEN) - { - hp100_outw(HP100_BM_WRITE| - HP100_BM_READ | HP100_SET_HB, OPTION_LSW); - hp100_outw(HP100_IO_EN | - HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW); - printk("hp100: %s: Busmaster mode requested.\n",dev->name); + printk("hp100: %s: original LSW = 0x%x\n", dev->name, + hp100_inw(OPTION_LSW)); +#endif + + if (local_mode == 3) { + hp100_outw(HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW); + hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW); + hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW); + printk("hp100: %s: IO mapped mode forced.\n", dev->name); + } else if (local_mode == 2) { + hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW); + hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW); + hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW); + printk("hp100: %s: Shared memory mode requested.\n", dev->name); + } else if (local_mode == 4) { + if (chip == HP100_CHIPID_LASSEN) { + hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_SET_HB, OPTION_LSW); + hp100_outw(HP100_IO_EN | HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW); + printk("hp100: %s: Busmaster mode requested.\n", dev->name); + } + local_mode = 1; } - local_mode=1; - } - - if(local_mode==1) /* default behaviour */ - { - lsw = hp100_inw(OPTION_LSW); - - if ( (lsw & HP100_IO_EN) && - (~lsw & HP100_MEM_EN) && - (~lsw & (HP100_BM_WRITE|HP100_BM_READ)) ) - { + + if (local_mode == 1) { /* default behaviour */ + lsw = hp100_inw(OPTION_LSW); + + if ((lsw & HP100_IO_EN) && (~lsw & HP100_MEM_EN) && + (~lsw & (HP100_BM_WRITE | HP100_BM_READ))) { #ifdef HP100_DEBUG - printk("hp100: %s: IO_EN bit is set on card.\n",dev->name); -#endif - local_mode=3; - } - else if ( chip == HP100_CHIPID_LASSEN && - ( lsw & (HP100_BM_WRITE|HP100_BM_READ) ) == - (HP100_BM_WRITE|HP100_BM_READ) ) - { - printk("hp100: %s: Busmaster mode enabled.\n",dev->name); - hp100_outw(HP100_MEM_EN|HP100_IO_EN|HP100_RESET_LB, OPTION_LSW); - } - else - { + printk("hp100: %s: IO_EN bit is set on card.\n", dev->name); +#endif + local_mode = 3; + } else if (chip == HP100_CHIPID_LASSEN && + (lsw & (HP100_BM_WRITE | HP100_BM_READ)) == (HP100_BM_WRITE | HP100_BM_READ)) { + printk("hp100: %s: Busmaster mode enabled.\n", dev->name); + hp100_outw(HP100_MEM_EN | HP100_IO_EN | HP100_RESET_LB, OPTION_LSW); + } else { #ifdef HP100_DEBUG - printk("hp100: %s: Card not configured for BM or BM not supported with this card.\n", dev->name ); - printk("hp100: %s: Trying shared memory mode.\n", dev->name); + printk("hp100: %s: Card not configured for BM or BM not supported with this card.\n", dev->name); + printk("hp100: %s: Trying shared memory mode.\n", dev->name); #endif - /* In this case, try shared memory mode */ - local_mode=2; - hp100_outw(HP100_MEM_EN|HP100_SET_LB, OPTION_LSW); - /* hp100_outw(HP100_IO_EN|HP100_RESET_LB, OPTION_LSW); */ + /* In this case, try shared memory mode */ + local_mode = 2; + hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW); + /* hp100_outw(HP100_IO_EN|HP100_RESET_LB, OPTION_LSW); */ + } } - } - #ifdef HP100_DEBUG - printk( "hp100: %s: new LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW) ); -#endif - - /* Check for shared memory on the card, eventually remap it */ - hp100_page( HW_MAP ); - mem_mapped = (( hp100_inw( OPTION_LSW ) & ( HP100_MEM_EN ) ) != 0); - mem_ptr_phys = 0UL; - mem_ptr_virt = NULL; - memory_size = (8192<<( (hp100_inb(SRAM)>>5)&0x07)); - virt_memory_size = 0; - - /* For memory mapped or busmaster mode, we want the memory address */ - if ( mem_mapped || (local_mode==1)) - { - mem_ptr_phys = ( hp100_inw( MEM_MAP_LSW ) | - ( hp100_inw( MEM_MAP_MSW ) << 16 ) ); - mem_ptr_phys &= ~0x1fff; /* 8k alignment */ - - if ( bus == HP100_BUS_ISA && (mem_ptr_phys & ~0xfffff ) != 0 ) - { - printk("hp100: %s: Can only use programmed i/o mode.\n", dev->name); - mem_ptr_phys = 0; - mem_mapped = 0; - local_mode=3; /* Use programmed i/o */ - } - - /* We do not need access to shared memory in busmaster mode */ - /* However in slave mode we need to remap high (>1GB) card memory */ - if(local_mode!=1) /* = not busmaster */ - { - if ( bus == HP100_BUS_PCI && mem_ptr_phys >= 0x100000 ) - { - /* We try with smaller memory sizes, if ioremap fails */ - for(virt_memory_size = memory_size; virt_memory_size>16383; virt_memory_size>>=1) - { - if((mem_ptr_virt=ioremap((u_long)mem_ptr_phys,virt_memory_size))==NULL) - { + printk("hp100: %s: new LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW)); +#endif + + /* Check for shared memory on the card, eventually remap it */ + hp100_page(HW_MAP); + mem_mapped = ((hp100_inw(OPTION_LSW) & (HP100_MEM_EN)) != 0); + mem_ptr_phys = 0UL; + mem_ptr_virt = NULL; + memory_size = (8192 << ((hp100_inb(SRAM) >> 5) & 0x07)); + virt_memory_size = 0; + + /* For memory mapped or busmaster mode, we want the memory address */ + if (mem_mapped || (local_mode == 1)) { + mem_ptr_phys = (hp100_inw(MEM_MAP_LSW) | (hp100_inw(MEM_MAP_MSW) << 16)); + mem_ptr_phys &= ~0x1fff; /* 8k alignment */ + + if (bus == HP100_BUS_ISA && (mem_ptr_phys & ~0xfffff) != 0) { + printk("hp100: %s: Can only use programmed i/o mode.\n", dev->name); + mem_ptr_phys = 0; + mem_mapped = 0; + local_mode = 3; /* Use programmed i/o */ + } + + /* We do not need access to shared memory in busmaster mode */ + /* However in slave mode we need to remap high (>1GB) card memory */ + if (local_mode != 1) { /* = not busmaster */ + /* We try with smaller memory sizes, if ioremap fails */ + for (virt_memory_size = memory_size; virt_memory_size > 16383; virt_memory_size >>= 1) { + if ((mem_ptr_virt = ioremap((u_long) mem_ptr_phys, virt_memory_size)) == NULL) { #ifdef HP100_DEBUG - printk( "hp100: %s: ioremap for 0x%x bytes high PCI memory at 0x%lx failed\n", dev->name, virt_memory_size, mem_ptr_phys ); + printk("hp100: %s: ioremap for 0x%x bytes high PCI memory at 0x%lx failed\n", dev->name, virt_memory_size, mem_ptr_phys); #endif - } - else - { + } else { #ifdef HP100_DEBUG - printk( "hp100: %s: remapped 0x%x bytes high PCI memory at 0x%lx to %p.\n", dev->name, virt_memory_size, mem_ptr_phys, mem_ptr_virt); + printk("hp100: %s: remapped 0x%x bytes high PCI memory at 0x%lx to %p.\n", dev->name, virt_memory_size, mem_ptr_phys, mem_ptr_virt); #endif - break; - } - } - - if(mem_ptr_virt==NULL) /* all ioremap tries failed */ - { - printk("hp100: %s: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n", dev->name); - local_mode=3; - virt_memory_size = 0; + break; + } + } + + if (mem_ptr_virt == NULL) { /* all ioremap tries failed */ + printk("hp100: %s: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n", dev->name); + local_mode = 3; + virt_memory_size = 0; + } } - } } - - } - - if(local_mode==3) /* io mapped forced */ - { - mem_mapped = 0; - mem_ptr_phys = 0; - mem_ptr_virt = NULL; - printk("hp100: %s: Using (slow) programmed i/o mode.\n", dev->name); - } - - /* Initialise the "private" data structure for this card. */ - if ( (dev->priv=kmalloc(sizeof(struct hp100_private), GFP_KERNEL)) == NULL) - return -ENOMEM; - - lp = (struct hp100_private *)dev->priv; - memset( lp, 0, sizeof( struct hp100_private ) ); - spin_lock_init(&lp->lock); - lp->id = eid; - lp->chip = chip; - lp->mode = local_mode; - lp->bus = bus; - lp->pci_dev = pci_dev; - lp->priority_tx = hp100_priority_tx; - lp->rx_ratio = hp100_rx_ratio; - lp->mem_ptr_phys = mem_ptr_phys; - lp->mem_ptr_virt = mem_ptr_virt; - hp100_page( ID_MAC_ADDR ); - lp->soft_model = hp100_inb( SOFT_MODEL ); - lp->mac1_mode = HP100_MAC1MODE3; - lp->mac2_mode = HP100_MAC2MODE3; - memset( &lp->hash_bytes, 0x00, 8 ); - - dev->base_addr = ioaddr; - - lp->memory_size = memory_size; - lp->virt_memory_size = virt_memory_size; - lp->rx_ratio = hp100_rx_ratio; /* can be conf'd with insmod */ - - /* memory region for programmed i/o */ - request_region( dev->base_addr, HP100_REGION_SIZE, eid->name ); - - dev->open = hp100_open; - dev->stop = hp100_close; - - if (lp->mode==1) /* busmaster */ - dev->hard_start_xmit = hp100_start_xmit_bm; - else - dev->hard_start_xmit = hp100_start_xmit; - - dev->get_stats = hp100_get_stats; - dev->set_multicast_list = &hp100_set_multicast_list; - - /* Ask the card for which IRQ line it is configured */ - if ( bus == HP100_BUS_PCI ) { - dev->irq = pci_dev->irq; - } else { - hp100_page( HW_MAP ); - dev->irq = hp100_inb( IRQ_CHANNEL ) & HP100_IRQMASK; - if ( dev->irq == 2 ) - dev->irq = 9; - } - - if(lp->mode==1) /* busmaster */ - dev->dma=4; - - /* Ask the card for its MAC address and store it for later use. */ - hp100_page( ID_MAC_ADDR ); - for ( i = uc = 0; i < 6; i++ ) - dev->dev_addr[ i ] = hp100_inb( LAN_ADDR + i ); - - /* Reset statistics (counters) */ - hp100_clear_stats( lp, ioaddr ); - - SET_MODULE_OWNER(dev); - ether_setup( dev ); - - /* If busmaster mode is wanted, a dma-capable memory area is needed for - * the rx and tx PDLs - * PCI cards can access the whole PC memory. Therefore GFP_DMA is not - * needed for the allocation of the memory area. - */ - - /* TODO: We do not need this with old cards, where PDLs are stored - * in the cards shared memory area. But currently, busmaster has been - * implemented/tested only with the lassen chip anyway... */ - if(lp->mode==1) /* busmaster */ - { - /* Get physically continous memory for TX & RX PDLs */ - if ( (lp->page_vaddr=kmalloc(MAX_RINGSIZE+0x0f,GFP_KERNEL) ) == NULL) - return -ENOMEM; - lp->page_vaddr_algn=((u_int *) ( ((u_int)(lp->page_vaddr)+0x0f) &~0x0f)); - memset(lp->page_vaddr, 0, MAX_RINGSIZE+0x0f); + + if (local_mode == 3) { /* io mapped forced */ + mem_mapped = 0; + mem_ptr_phys = 0; + mem_ptr_virt = NULL; + printk("hp100: %s: Using (slow) programmed i/o mode.\n", dev->name); + } + + /* Initialise the "private" data structure for this card. */ + if ((dev->priv = kmalloc(sizeof(struct hp100_private), GFP_KERNEL)) == NULL) + return -ENOMEM; + + lp = (struct hp100_private *) dev->priv; + memset(lp, 0, sizeof(struct hp100_private)); + spin_lock_init(&lp->lock); + lp->id = eid; + lp->chip = chip; + lp->mode = local_mode; + lp->bus = bus; + lp->pci_dev = pci_dev; + lp->priority_tx = hp100_priority_tx; + lp->rx_ratio = hp100_rx_ratio; + lp->mem_ptr_phys = mem_ptr_phys; + lp->mem_ptr_virt = mem_ptr_virt; + hp100_page(ID_MAC_ADDR); + lp->soft_model = hp100_inb(SOFT_MODEL); + lp->mac1_mode = HP100_MAC1MODE3; + lp->mac2_mode = HP100_MAC2MODE3; + memset(&lp->hash_bytes, 0x00, 8); + + dev->base_addr = ioaddr; + + lp->memory_size = memory_size; + lp->virt_memory_size = virt_memory_size; + lp->rx_ratio = hp100_rx_ratio; /* can be conf'd with insmod */ + + /* memory region for programmed i/o */ + request_region(dev->base_addr, HP100_REGION_SIZE, eid->name); + + dev->open = hp100_open; + dev->stop = hp100_close; + + if (lp->mode == 1) /* busmaster */ + dev->hard_start_xmit = hp100_start_xmit_bm; + else + dev->hard_start_xmit = hp100_start_xmit; + + dev->get_stats = hp100_get_stats; + dev->set_multicast_list = &hp100_set_multicast_list; + + /* Ask the card for which IRQ line it is configured */ + if (bus == HP100_BUS_PCI) { + dev->irq = pci_dev->irq; + } else { + hp100_page(HW_MAP); + dev->irq = hp100_inb(IRQ_CHANNEL) & HP100_IRQMASK; + if (dev->irq == 2) + dev->irq = 9; + } + + if (lp->mode == 1) /* busmaster */ + dev->dma = 4; + + /* Ask the card for its MAC address and store it for later use. */ + hp100_page(ID_MAC_ADDR); + for (i = uc = 0; i < 6; i++) + dev->dev_addr[i] = hp100_inb(LAN_ADDR + i); + + /* Reset statistics (counters) */ + hp100_clear_stats(lp, ioaddr); + + SET_MODULE_OWNER(dev); + ether_setup(dev); + + /* If busmaster mode is wanted, a dma-capable memory area is needed for + * the rx and tx PDLs + * PCI cards can access the whole PC memory. Therefore GFP_DMA is not + * needed for the allocation of the memory area. + */ + + /* TODO: We do not need this with old cards, where PDLs are stored + * in the cards shared memory area. But currently, busmaster has been + * implemented/tested only with the lassen chip anyway... */ + if (lp->mode == 1) { /* busmaster */ + /* Get physically continous memory for TX & RX PDLs */ + if ((lp->page_vaddr = kmalloc(MAX_RINGSIZE + 0x0f, GFP_KERNEL)) == NULL) + return -ENOMEM; + lp->page_vaddr_algn = ((u_int *) (((u_int) (lp->page_vaddr) + 0x0f) & ~0x0f)); + memset(lp->page_vaddr, 0, MAX_RINGSIZE + 0x0f); #ifdef HP100_DEBUG_BM - printk("hp100: %s: Reserved DMA memory from 0x%x to 0x%x\n", - dev->name, - (u_int)lp->page_vaddr_algn, - (u_int)lp->page_vaddr_algn+MAX_RINGSIZE); -#endif - lp->rxrcommit = lp->txrcommit = 0; - lp->rxrhead = lp->rxrtail = &(lp->rxring[0]); - lp->txrhead = lp->txrtail = &(lp->txring[0]); - } - - /* Initialise the card. */ - /* (I'm not really sure if it's a good idea to do this during probing, but - * like this it's assured that the lan connection type can be sensed - * correctly) - */ - hp100_hwinit( dev ); - - /* Try to find out which kind of LAN the card is connected to. */ - lp->lan_type = hp100_sense_lan( dev ); - - /* Print out a message what about what we think we have probed. */ - printk( "hp100: %s: %s at 0x%x, IRQ %d, ", - dev->name, lp->id->name, ioaddr, dev->irq ); - switch ( bus ) { - case HP100_BUS_EISA: printk( "EISA" ); break; - case HP100_BUS_PCI: printk( "PCI" ); break; - default: printk( "ISA" ); break; - } - printk( " bus, %dk SRAM (rx/tx %d%%).\n", - lp->memory_size >> 10, lp->rx_ratio ); - - if ( lp->mode==2 ) /* memory mapped */ - { - printk( "hp100: %s: Memory area at 0x%lx-0x%lx", - dev->name,mem_ptr_phys, - (mem_ptr_phys+(mem_ptr_phys>0x100000?(u_long)lp->memory_size:16*1024))-1 ); - if ( mem_ptr_virt ) - printk( " (virtual base %p)", mem_ptr_virt ); - printk( ".\n" ); - - /* Set for info when doing ifconfig */ - dev->mem_start = mem_ptr_phys; - dev->mem_end = mem_ptr_phys+lp->memory_size; - } - printk( "hp100: %s: ", dev->name ); - if ( lp->lan_type != HP100_LAN_ERR ) - printk( "Adapter is attached to " ); - switch ( lp->lan_type ) { - case HP100_LAN_100: - printk( "100Mb/s Voice Grade AnyLAN network.\n" ); - break; - case HP100_LAN_10: - printk( "10Mb/s network.\n" ); - break; - default: - printk( "Warning! Link down.\n" ); - } - - return 0; + printk("hp100: %s: Reserved DMA memory from 0x%x to 0x%x\n", dev->name, (u_int) lp->page_vaddr_algn, (u_int) lp->page_vaddr_algn + MAX_RINGSIZE); +#endif + lp->rxrcommit = lp->txrcommit = 0; + lp->rxrhead = lp->rxrtail = &(lp->rxring[0]); + lp->txrhead = lp->txrtail = &(lp->txring[0]); + } + + /* Initialise the card. */ + /* (I'm not really sure if it's a good idea to do this during probing, but + * like this it's assured that the lan connection type can be sensed + * correctly) + */ + hp100_hwinit(dev); + + /* Try to find out which kind of LAN the card is connected to. */ + lp->lan_type = hp100_sense_lan(dev); + + /* Print out a message what about what we think we have probed. */ + printk("hp100: %s: %s at 0x%x, IRQ %d, ", dev->name, lp->id->name, ioaddr, dev->irq); + switch (bus) { + case HP100_BUS_EISA: + printk("EISA"); + break; + case HP100_BUS_PCI: + printk("PCI"); + break; + default: + printk("ISA"); + break; + } + printk(" bus, %dk SRAM (rx/tx %d%%).\n", lp->memory_size >> 10, lp->rx_ratio); + + if (lp->mode == 2) { /* memory mapped */ + printk("hp100: %s: Memory area at 0x%lx-0x%lx", dev->name, mem_ptr_phys, + (mem_ptr_phys + (mem_ptr_phys > 0x100000 ? (u_long) lp->memory_size : 16 * 1024)) - 1); + if (mem_ptr_virt) + printk(" (virtual base %p)", mem_ptr_virt); + printk(".\n"); + + /* Set for info when doing ifconfig */ + dev->mem_start = mem_ptr_phys; + dev->mem_end = mem_ptr_phys + lp->memory_size; + } + printk("hp100: %s: ", dev->name); + if (lp->lan_type != HP100_LAN_ERR) + printk("Adapter is attached to "); + switch (lp->lan_type) { + case HP100_LAN_100: + printk("100Mb/s Voice Grade AnyLAN network.\n"); + break; + case HP100_LAN_10: + printk("10Mb/s network.\n"); + break; + default: + printk("Warning! Link down.\n"); + } + + return 0; } - /* This procedure puts the card into a stable init state */ -static void hp100_hwinit( struct net_device *dev ) +static void hp100_hwinit(struct net_device *dev) { - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4202, TRACE ); - printk("hp100: %s: hwinit\n", dev->name); -#endif - - /* Initialise the card. -------------------------------------------- */ - - /* Clear all pending Ints and disable Ints */ - hp100_page( PERFORMANCE ); - hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all ints */ - hp100_outw( 0xffff, IRQ_STATUS ); /* clear all pending ints */ - - hp100_outw( HP100_INT_EN | HP100_RESET_LB, OPTION_LSW ); - hp100_outw( HP100_TRI_INT | HP100_SET_HB, OPTION_LSW ); - - if(lp->mode==1) - { - hp100_BM_shutdown( dev ); /* disables BM, puts cascade in reset */ - wait(); - } - else - { - hp100_outw( HP100_INT_EN | HP100_RESET_LB, OPTION_LSW ); - hp100_cascade_reset( dev, TRUE ); - hp100_page( MAC_CTRL ); - hp100_andb( ~(HP100_RX_EN|HP100_TX_EN), MAC_CFG_1); - } - - /* Initiate EEPROM reload */ - hp100_load_eeprom( dev, 0 ); - - wait(); - - /* Go into reset again. */ - hp100_cascade_reset( dev, TRUE ); - - /* Set Option Registers to a safe state */ - hp100_outw( HP100_DEBUG_EN | - HP100_RX_HDR | - HP100_EE_EN | - HP100_BM_WRITE | - HP100_BM_READ | HP100_RESET_HB | - HP100_FAKE_INT | - HP100_INT_EN | - HP100_MEM_EN | - HP100_IO_EN | HP100_RESET_LB, OPTION_LSW); - - hp100_outw( HP100_TRI_INT | - HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW ); - - hp100_outb( HP100_PRIORITY_TX | - HP100_ADV_NXT_PKT | - HP100_TX_CMD | HP100_RESET_LB, OPTION_MSW ); - - /* TODO: Configure MMU for Ram Test. */ - /* TODO: Ram Test. */ - - /* Re-check if adapter is still at same i/o location */ - /* (If the base i/o in eeprom has been changed but the */ - /* registers had not been changed, a reload of the eeprom */ - /* would move the adapter to the address stored in eeprom */ - - /* TODO: Code to implement. */ - - /* Until here it was code from HWdiscover procedure. */ - /* Next comes code from mmuinit procedure of SCO BM driver which is - * called from HWconfigure in the SCO driver. */ - - /* Initialise MMU, eventually switch on Busmaster Mode, initialise - * multicast filter... - */ - hp100_mmuinit( dev ); - - /* We don't turn the interrupts on here - this is done by start_interface. */ - wait(); /* TODO: Do we really need this? */ - - /* Enable Hardware (e.g. unreset) */ - hp100_cascade_reset( dev, FALSE ); - - /* ------- initialisation complete ----------- */ - - /* Finally try to log in the Hub if there may be a VG connection. */ - if( lp->lan_type != HP100_LAN_10 ) - hp100_login_to_vg_hub( dev, FALSE ); /* relogin */ -} + hp100_outw(0x4202, TRACE); + printk("hp100: %s: hwinit\n", dev->name); +#endif + + /* Initialise the card. -------------------------------------------- */ + + /* Clear all pending Ints and disable Ints */ + hp100_page(PERFORMANCE); + hp100_outw(0xfefe, IRQ_MASK); /* mask off all ints */ + hp100_outw(0xffff, IRQ_STATUS); /* clear all pending ints */ + + hp100_outw(HP100_INT_EN | HP100_RESET_LB, OPTION_LSW); + hp100_outw(HP100_TRI_INT | HP100_SET_HB, OPTION_LSW); + + if (lp->mode == 1) { + hp100_BM_shutdown(dev); /* disables BM, puts cascade in reset */ + wait(); + } else { + hp100_outw(HP100_INT_EN | HP100_RESET_LB, OPTION_LSW); + hp100_cascade_reset(dev, TRUE); + hp100_page(MAC_CTRL); + hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1); + } + + /* Initiate EEPROM reload */ + hp100_load_eeprom(dev, 0); + + wait(); + + /* Go into reset again. */ + hp100_cascade_reset(dev, TRUE); + + /* Set Option Registers to a safe state */ + hp100_outw(HP100_DEBUG_EN | + HP100_RX_HDR | + HP100_EE_EN | + HP100_BM_WRITE | + HP100_BM_READ | HP100_RESET_HB | + HP100_FAKE_INT | + HP100_INT_EN | + HP100_MEM_EN | + HP100_IO_EN | HP100_RESET_LB, OPTION_LSW); + + hp100_outw(HP100_TRI_INT | + HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW); + hp100_outb(HP100_PRIORITY_TX | + HP100_ADV_NXT_PKT | + HP100_TX_CMD | HP100_RESET_LB, OPTION_MSW); + + /* TODO: Configure MMU for Ram Test. */ + /* TODO: Ram Test. */ + + /* Re-check if adapter is still at same i/o location */ + /* (If the base i/o in eeprom has been changed but the */ + /* registers had not been changed, a reload of the eeprom */ + /* would move the adapter to the address stored in eeprom */ + + /* TODO: Code to implement. */ + + /* Until here it was code from HWdiscover procedure. */ + /* Next comes code from mmuinit procedure of SCO BM driver which is + * called from HWconfigure in the SCO driver. */ + + /* Initialise MMU, eventually switch on Busmaster Mode, initialise + * multicast filter... + */ + hp100_mmuinit(dev); + + /* We don't turn the interrupts on here - this is done by start_interface. */ + wait(); /* TODO: Do we really need this? */ + + /* Enable Hardware (e.g. unreset) */ + hp100_cascade_reset(dev, FALSE); + + /* ------- initialisation complete ----------- */ + + /* Finally try to log in the Hub if there may be a VG connection. */ + if (lp->lan_type != HP100_LAN_10) + hp100_login_to_vg_hub(dev, FALSE); /* relogin */ +} + /* * mmuinit - Reinitialise Cascade MMU and MAC settings. * Note: Must already be in reset and leaves card in reset. */ -static void hp100_mmuinit( struct net_device *dev ) +static void hp100_mmuinit(struct net_device *dev) { - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; - int i; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + int i; #ifdef HP100_DEBUG_B - hp100_outw( 0x4203, TRACE ); - printk("hp100: %s: mmuinit\n",dev->name); + hp100_outw(0x4203, TRACE); + printk("hp100: %s: mmuinit\n", dev->name); #endif #ifdef HP100_DEBUG - if( 0!=(hp100_inw(OPTION_LSW)&HP100_HW_RST) ) - { - printk("hp100: %s: Not in reset when entering mmuinit. Fix me.\n",dev->name); - return; - } -#endif - - /* Make sure IRQs are masked off and ack'ed. */ - hp100_page( PERFORMANCE ); - hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all ints */ - hp100_outw( 0xffff, IRQ_STATUS ); /* ack IRQ */ - - /* - * Enable Hardware - * - Clear Debug En, Rx Hdr Pipe, EE En, I/O En, Fake Int and Intr En - * - Set Tri-State Int, Bus Master Rd/Wr, and Mem Map Disable - * - Clear Priority, Advance Pkt and Xmit Cmd - */ - - hp100_outw( HP100_DEBUG_EN | - HP100_RX_HDR | - HP100_EE_EN | HP100_RESET_HB | - HP100_IO_EN | - HP100_FAKE_INT | - HP100_INT_EN | HP100_RESET_LB, OPTION_LSW ); - - hp100_outw( HP100_TRI_INT | HP100_SET_HB, OPTION_LSW); - - if(lp->mode==1) /* busmaster */ - { - hp100_outw( HP100_BM_WRITE | - HP100_BM_READ | - HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW ); - } - else if(lp->mode==2) /* memory mapped */ - { - hp100_outw( HP100_BM_WRITE | - HP100_BM_READ | HP100_RESET_HB, OPTION_LSW ); - hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW ); - hp100_outw( HP100_MEM_EN | HP100_SET_LB, OPTION_LSW ); - hp100_outw( HP100_IO_EN | HP100_SET_LB, OPTION_LSW ); - } - else if( lp->mode==3 ) /* i/o mapped mode */ - { - hp100_outw( HP100_MMAP_DIS | HP100_SET_HB | - HP100_IO_EN | HP100_SET_LB, OPTION_LSW ); - } - - hp100_page( HW_MAP ); - hp100_outb( 0, EARLYRXCFG ); - hp100_outw( 0, EARLYTXCFG ); - - /* - * Enable Bus Master mode - */ - if(lp->mode==1) /* busmaster */ - { - /* Experimental: Set some PCI configuration bits */ - hp100_page( HW_MAP ); - hp100_andb( ~HP100_PDL_USE3, MODECTRL1 ); /* BM engine read maximum */ - hp100_andb( ~HP100_TX_DUALQ, MODECTRL1 ); /* No Queue for Priority TX */ - - /* PCI Bus failures should result in a Misc. Interrupt */ - hp100_orb( HP100_EN_BUS_FAIL, MODECTRL2); - - hp100_outw( HP100_BM_READ | HP100_BM_WRITE | HP100_SET_HB, OPTION_LSW ); - hp100_page( HW_MAP ); - /* Use Burst Mode and switch on PAGE_CK */ - hp100_orb( HP100_BM_BURST_RD | - HP100_BM_BURST_WR, BM); - if((lp->chip==HP100_CHIPID_RAINIER)||(lp->chip==HP100_CHIPID_SHASTA)) - hp100_orb( HP100_BM_PAGE_CK, BM ); - hp100_orb( HP100_BM_MASTER, BM ); - } - else /* not busmaster */ - { - hp100_page(HW_MAP); - hp100_andb(~HP100_BM_MASTER, BM ); - } - - /* - * Divide card memory into regions for Rx, Tx and, if non-ETR chip, PDLs - */ - hp100_page( MMU_CFG ); - if(lp->mode==1) /* only needed for Busmaster */ - { - int xmit_stop, recv_stop; - - if((lp->chip==HP100_CHIPID_RAINIER)||(lp->chip==HP100_CHIPID_SHASTA)) - { - int pdl_stop; - - /* - * Each pdl is 508 bytes long. (63 frags * 4 bytes for address and - * 4 bytes for header). We will leave NUM_RXPDLS * 508 (rounded - * to the next higher 1k boundary) bytes for the rx-pdl's - * Note: For non-etr chips the transmit stop register must be - * programmed on a 1k boundary, i.e. bits 9:0 must be zero. - */ - pdl_stop = lp->memory_size; - xmit_stop = ( pdl_stop-508*(MAX_RX_PDL)-16 )& ~(0x03ff); - recv_stop = ( xmit_stop * (lp->rx_ratio)/100 ) &~(0x03ff); - hp100_outw( (pdl_stop>>4)-1, PDL_MEM_STOP ); + if (0 != (hp100_inw(OPTION_LSW) & HP100_HW_RST)) { + printk("hp100: %s: Not in reset when entering mmuinit. Fix me.\n", dev->name); + return; + } +#endif + + /* Make sure IRQs are masked off and ack'ed. */ + hp100_page(PERFORMANCE); + hp100_outw(0xfefe, IRQ_MASK); /* mask off all ints */ + hp100_outw(0xffff, IRQ_STATUS); /* ack IRQ */ + + /* + * Enable Hardware + * - Clear Debug En, Rx Hdr Pipe, EE En, I/O En, Fake Int and Intr En + * - Set Tri-State Int, Bus Master Rd/Wr, and Mem Map Disable + * - Clear Priority, Advance Pkt and Xmit Cmd + */ + + hp100_outw(HP100_DEBUG_EN | + HP100_RX_HDR | + HP100_EE_EN | HP100_RESET_HB | + HP100_IO_EN | + HP100_FAKE_INT | + HP100_INT_EN | HP100_RESET_LB, OPTION_LSW); + + hp100_outw(HP100_TRI_INT | HP100_SET_HB, OPTION_LSW); + + if (lp->mode == 1) { /* busmaster */ + hp100_outw(HP100_BM_WRITE | + HP100_BM_READ | + HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW); + } else if (lp->mode == 2) { /* memory mapped */ + hp100_outw(HP100_BM_WRITE | + HP100_BM_READ | HP100_RESET_HB, OPTION_LSW); + hp100_outw(HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW); + hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW); + hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW); + } else if (lp->mode == 3) { /* i/o mapped mode */ + hp100_outw(HP100_MMAP_DIS | HP100_SET_HB | + HP100_IO_EN | HP100_SET_LB, OPTION_LSW); + } + + hp100_page(HW_MAP); + hp100_outb(0, EARLYRXCFG); + hp100_outw(0, EARLYTXCFG); + + /* + * Enable Bus Master mode + */ + if (lp->mode == 1) { /* busmaster */ + /* Experimental: Set some PCI configuration bits */ + hp100_page(HW_MAP); + hp100_andb(~HP100_PDL_USE3, MODECTRL1); /* BM engine read maximum */ + hp100_andb(~HP100_TX_DUALQ, MODECTRL1); /* No Queue for Priority TX */ + + /* PCI Bus failures should result in a Misc. Interrupt */ + hp100_orb(HP100_EN_BUS_FAIL, MODECTRL2); + + hp100_outw(HP100_BM_READ | HP100_BM_WRITE | HP100_SET_HB, OPTION_LSW); + hp100_page(HW_MAP); + /* Use Burst Mode and switch on PAGE_CK */ + hp100_orb(HP100_BM_BURST_RD | HP100_BM_BURST_WR, BM); + if ((lp->chip == HP100_CHIPID_RAINIER) || (lp->chip == HP100_CHIPID_SHASTA)) + hp100_orb(HP100_BM_PAGE_CK, BM); + hp100_orb(HP100_BM_MASTER, BM); + } else { /* not busmaster */ + + hp100_page(HW_MAP); + hp100_andb(~HP100_BM_MASTER, BM); + } + + /* + * Divide card memory into regions for Rx, Tx and, if non-ETR chip, PDLs + */ + hp100_page(MMU_CFG); + if (lp->mode == 1) { /* only needed for Busmaster */ + int xmit_stop, recv_stop; + + if ((lp->chip == HP100_CHIPID_RAINIER) + || (lp->chip == HP100_CHIPID_SHASTA)) { + int pdl_stop; + + /* + * Each pdl is 508 bytes long. (63 frags * 4 bytes for address and + * 4 bytes for header). We will leave NUM_RXPDLS * 508 (rounded + * to the next higher 1k boundary) bytes for the rx-pdl's + * Note: For non-etr chips the transmit stop register must be + * programmed on a 1k boundary, i.e. bits 9:0 must be zero. + */ + pdl_stop = lp->memory_size; + xmit_stop = (pdl_stop - 508 * (MAX_RX_PDL) - 16) & ~(0x03ff); + recv_stop = (xmit_stop * (lp->rx_ratio) / 100) & ~(0x03ff); + hp100_outw((pdl_stop >> 4) - 1, PDL_MEM_STOP); #ifdef HP100_DEBUG_BM - printk("hp100: %s: PDL_STOP = 0x%x\n", dev->name, pdl_stop); + printk("hp100: %s: PDL_STOP = 0x%x\n", dev->name, pdl_stop); #endif - } - else /* ETR chip (Lassen) in busmaster mode */ - { - xmit_stop = ( lp->memory_size ) - 1; - recv_stop = ( ( lp->memory_size * lp->rx_ratio ) / 100 ) & ~(0x03ff); - } + } else { + /* ETR chip (Lassen) in busmaster mode */ + xmit_stop = (lp->memory_size) - 1; + recv_stop = ((lp->memory_size * lp->rx_ratio) / 100) & ~(0x03ff); + } - hp100_outw( xmit_stop>>4 , TX_MEM_STOP ); - hp100_outw( recv_stop>>4 , RX_MEM_STOP ); + hp100_outw(xmit_stop >> 4, TX_MEM_STOP); + hp100_outw(recv_stop >> 4, RX_MEM_STOP); #ifdef HP100_DEBUG_BM - printk("hp100: %s: TX_STOP = 0x%x\n",dev->name,xmit_stop>>4); - printk("hp100: %s: RX_STOP = 0x%x\n",dev->name,recv_stop>>4); -#endif - } - else /* Slave modes (memory mapped and programmed io) */ - { - hp100_outw( (((lp->memory_size*lp->rx_ratio)/100)>>4), RX_MEM_STOP ); - hp100_outw( ((lp->memory_size - 1 )>>4), TX_MEM_STOP ); + printk("hp100: %s: TX_STOP = 0x%x\n", dev->name, xmit_stop >> 4); + printk("hp100: %s: RX_STOP = 0x%x\n", dev->name, recv_stop >> 4); +#endif + } else { + /* Slave modes (memory mapped and programmed io) */ + hp100_outw((((lp->memory_size * lp->rx_ratio) / 100) >> 4), RX_MEM_STOP); + hp100_outw(((lp->memory_size - 1) >> 4), TX_MEM_STOP); #ifdef HP100_DEBUG - printk("hp100: %s: TX_MEM_STOP: 0x%x\n", dev->name,hp100_inw(TX_MEM_STOP)); - printk("hp100: %s: RX_MEM_STOP: 0x%x\n", dev->name,hp100_inw(RX_MEM_STOP)); -#endif - } - - /* Write MAC address into page 1 */ - hp100_page( MAC_ADDRESS ); - for ( i = 0; i < 6; i++ ) - hp100_outb( dev->dev_addr[ i ], MAC_ADDR + i ); - - /* Zero the multicast hash registers */ - for ( i = 0; i < 8; i++ ) - hp100_outb( 0x0, HASH_BYTE0 + i ); - - /* Set up MAC defaults */ - hp100_page( MAC_CTRL ); - - /* Go to LAN Page and zero all filter bits */ - /* Zero accept error, accept multicast, accept broadcast and accept */ - /* all directed packet bits */ - hp100_andb( ~(HP100_RX_EN| - HP100_TX_EN| - HP100_ACC_ERRORED| - HP100_ACC_MC| - HP100_ACC_BC| - HP100_ACC_PHY), MAC_CFG_1 ); - - hp100_outb( 0x00, MAC_CFG_2 ); - - /* Zero the frame format bit. This works around a training bug in the */ - /* new hubs. */ - hp100_outb( 0x00, VG_LAN_CFG_2); /* (use 802.3) */ - - if(lp->priority_tx) - hp100_outb( HP100_PRIORITY_TX | HP100_SET_LB, OPTION_MSW ); - else - hp100_outb( HP100_PRIORITY_TX | HP100_RESET_LB, OPTION_MSW ); - - hp100_outb( HP100_ADV_NXT_PKT | - HP100_TX_CMD | HP100_RESET_LB, OPTION_MSW ); - - /* If busmaster, initialize the PDLs */ - if(lp->mode==1) - hp100_init_pdls( dev ); - - /* Go to performance page and initalize isr and imr registers */ - hp100_page( PERFORMANCE ); - hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all ints */ - hp100_outw( 0xffff, IRQ_STATUS ); /* ack IRQ */ + printk("hp100: %s: TX_MEM_STOP: 0x%x\n", dev->name, hp100_inw(TX_MEM_STOP)); + printk("hp100: %s: RX_MEM_STOP: 0x%x\n", dev->name, hp100_inw(RX_MEM_STOP)); +#endif + } + + /* Write MAC address into page 1 */ + hp100_page(MAC_ADDRESS); + for (i = 0; i < 6; i++) + hp100_outb(dev->dev_addr[i], MAC_ADDR + i); + + /* Zero the multicast hash registers */ + for (i = 0; i < 8; i++) + hp100_outb(0x0, HASH_BYTE0 + i); + + /* Set up MAC defaults */ + hp100_page(MAC_CTRL); + + /* Go to LAN Page and zero all filter bits */ + /* Zero accept error, accept multicast, accept broadcast and accept */ + /* all directed packet bits */ + hp100_andb(~(HP100_RX_EN | + HP100_TX_EN | + HP100_ACC_ERRORED | + HP100_ACC_MC | + HP100_ACC_BC | HP100_ACC_PHY), MAC_CFG_1); + + hp100_outb(0x00, MAC_CFG_2); + + /* Zero the frame format bit. This works around a training bug in the */ + /* new hubs. */ + hp100_outb(0x00, VG_LAN_CFG_2); /* (use 802.3) */ + + if (lp->priority_tx) + hp100_outb(HP100_PRIORITY_TX | HP100_SET_LB, OPTION_MSW); + else + hp100_outb(HP100_PRIORITY_TX | HP100_RESET_LB, OPTION_MSW); + + hp100_outb(HP100_ADV_NXT_PKT | + HP100_TX_CMD | HP100_RESET_LB, OPTION_MSW); + + /* If busmaster, initialize the PDLs */ + if (lp->mode == 1) + hp100_init_pdls(dev); + + /* Go to performance page and initalize isr and imr registers */ + hp100_page(PERFORMANCE); + hp100_outw(0xfefe, IRQ_MASK); /* mask off all ints */ + hp100_outw(0xffff, IRQ_STATUS); /* ack IRQ */ } - /* * open/close functions */ -static int hp100_open( struct net_device *dev ) +static int hp100_open(struct net_device *dev) { - struct hp100_private *lp = (struct hp100_private *)dev->priv; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - int ioaddr=dev->base_addr; + int ioaddr = dev->base_addr; #endif #ifdef HP100_DEBUG_B - hp100_outw( 0x4204, TRACE ); - printk("hp100: %s: open\n",dev->name); -#endif - - /* New: if bus is PCI or EISA, interrupts might be shared interrupts */ - if ( request_irq(dev->irq, hp100_interrupt, - lp->bus==HP100_BUS_PCI||lp->bus==HP100_BUS_EISA?SA_SHIRQ:SA_INTERRUPT, - lp->id->name, dev)) - { - printk( "hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq ); - return -EAGAIN; - } - - dev->trans_start = jiffies; - netif_start_queue(dev); - - lp->lan_type = hp100_sense_lan( dev ); - lp->mac1_mode = HP100_MAC1MODE3; - lp->mac2_mode = HP100_MAC2MODE3; - memset( &lp->hash_bytes, 0x00, 8 ); - - hp100_stop_interface( dev ); - - hp100_hwinit( dev ); - - hp100_start_interface( dev ); /* sets mac modes, enables interrupts */ - - return 0; + hp100_outw(0x4204, TRACE); + printk("hp100: %s: open\n", dev->name); +#endif + + /* New: if bus is PCI or EISA, interrupts might be shared interrupts */ + if (request_irq(dev->irq, hp100_interrupt, + lp->bus == HP100_BUS_PCI || lp->bus == + HP100_BUS_EISA ? SA_SHIRQ : SA_INTERRUPT, + lp->id->name, dev)) { + printk("hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq); + return -EAGAIN; + } + + dev->trans_start = jiffies; + netif_start_queue(dev); + + lp->lan_type = hp100_sense_lan(dev); + lp->mac1_mode = HP100_MAC1MODE3; + lp->mac2_mode = HP100_MAC2MODE3; + memset(&lp->hash_bytes, 0x00, 8); + + hp100_stop_interface(dev); + + hp100_hwinit(dev); + + hp100_start_interface(dev); /* sets mac modes, enables interrupts */ + + return 0; } - /* The close function is called when the interface is to be brought down */ -static int hp100_close( struct net_device *dev ) +static int hp100_close(struct net_device *dev) { - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4205, TRACE ); - printk("hp100: %s: close\n", dev->name); + hp100_outw(0x4205, TRACE); + printk("hp100: %s: close\n", dev->name); #endif - hp100_page( PERFORMANCE ); - hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all IRQs */ + hp100_page(PERFORMANCE); + hp100_outw(0xfefe, IRQ_MASK); /* mask off all IRQs */ - hp100_stop_interface( dev ); + hp100_stop_interface(dev); - if ( lp->lan_type == HP100_LAN_100 ) - lp->hub_status=hp100_login_to_vg_hub( dev, FALSE ); + if (lp->lan_type == HP100_LAN_100) + lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); - netif_stop_queue(dev); + netif_stop_queue(dev); - free_irq( dev->irq, dev ); + free_irq(dev->irq, dev); #ifdef HP100_DEBUG - printk( "hp100: %s: close LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW) ); + printk("hp100: %s: close LSW = 0x%x\n", dev->name, + hp100_inw(OPTION_LSW)); #endif - return 0; + return 0; } - + /* * Configure the PDL Rx rings and LAN */ -static void hp100_init_pdls( struct net_device *dev ) +static void hp100_init_pdls(struct net_device *dev) { - struct hp100_private *lp = (struct hp100_private *)dev->priv; - hp100_ring_t *ringptr; - u_int *pageptr; - int i; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + hp100_ring_t *ringptr; + u_int *pageptr; + int i; #ifdef HP100_DEBUG_B - int ioaddr = dev->base_addr; + int ioaddr = dev->base_addr; #endif #ifdef HP100_DEBUG_B - hp100_outw( 0x4206, TRACE ); - printk("hp100: %s: init pdls\n", dev->name); -#endif - - if(0==lp->page_vaddr_algn) - printk("hp100: %s: Warning: lp->page_vaddr_algn not initialised!\n",dev->name); - else - { - /* pageptr shall point into the DMA accessible memory region */ - /* we use this pointer to status the upper limit of allocated */ - /* memory in the allocated page. */ - /* note: align the pointers to the pci cache line size */ - memset(lp->page_vaddr_algn, 0, MAX_RINGSIZE); /* Zero Rx/Tx ring page */ - pageptr=lp->page_vaddr_algn; - - lp->rxrcommit =0; - ringptr = lp->rxrhead = lp-> rxrtail = &(lp->rxring[0]); - - /* Initialise Rx Ring */ - for (i=MAX_RX_PDL-1; i>=0; i--) - { - lp->rxring[i].next = ringptr; - ringptr=&(lp->rxring[i]); - pageptr+=hp100_init_rxpdl(dev, ringptr, pageptr); - } - - /* Initialise Tx Ring */ - lp->txrcommit = 0; - ringptr = lp->txrhead = lp->txrtail = &(lp->txring[0]); - for (i=MAX_TX_PDL-1; i>=0; i--) - { - lp->txring[i].next = ringptr; - ringptr=&(lp->txring[i]); - pageptr+=hp100_init_txpdl(dev, ringptr, pageptr); - } - } -} + hp100_outw(0x4206, TRACE); + printk("hp100: %s: init pdls\n", dev->name); +#endif + + if (0 == lp->page_vaddr_algn) + printk("hp100: %s: Warning: lp->page_vaddr_algn not initialised!\n", dev->name); + else { + /* pageptr shall point into the DMA accessible memory region */ + /* we use this pointer to status the upper limit of allocated */ + /* memory in the allocated page. */ + /* note: align the pointers to the pci cache line size */ + memset(lp->page_vaddr_algn, 0, MAX_RINGSIZE); /* Zero Rx/Tx ring page */ + pageptr = lp->page_vaddr_algn; + + lp->rxrcommit = 0; + ringptr = lp->rxrhead = lp->rxrtail = &(lp->rxring[0]); + + /* Initialise Rx Ring */ + for (i = MAX_RX_PDL - 1; i >= 0; i--) { + lp->rxring[i].next = ringptr; + ringptr = &(lp->rxring[i]); + pageptr += hp100_init_rxpdl(dev, ringptr, pageptr); + } + /* Initialise Tx Ring */ + lp->txrcommit = 0; + ringptr = lp->txrhead = lp->txrtail = &(lp->txring[0]); + for (i = MAX_TX_PDL - 1; i >= 0; i--) { + lp->txring[i].next = ringptr; + ringptr = &(lp->txring[i]); + pageptr += hp100_init_txpdl(dev, ringptr, pageptr); + } + } +} + /* These functions "format" the entries in the pdl structure */ /* They return how much memory the fragments need. */ -static int hp100_init_rxpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) +static int hp100_init_rxpdl(struct net_device *dev, + register hp100_ring_t * ringptr, + register u32 * pdlptr) { - /* pdlptr is starting address for this pdl */ + /* pdlptr is starting address for this pdl */ - if( 0!=( ((unsigned)pdlptr) & 0xf) ) - printk("hp100: %s: Init rxpdl: Unaligned pdlptr 0x%x.\n",dev->name,(unsigned)pdlptr); + if (0 != (((unsigned) pdlptr) & 0xf)) + printk("hp100: %s: Init rxpdl: Unaligned pdlptr 0x%x.\n", + dev->name, (unsigned) pdlptr); - ringptr->pdl = pdlptr+1; - ringptr->pdl_paddr = virt_to_bus(pdlptr+1); - ringptr->skb = (void *) NULL; + ringptr->pdl = pdlptr + 1; + ringptr->pdl_paddr = virt_to_bus(pdlptr + 1); + ringptr->skb = (void *) NULL; - /* - * Write address and length of first PDL Fragment (which is used for - * storing the RX-Header - * We use the 4 bytes _before_ the PDH in the pdl memory area to - * store this information. (PDH is at offset 0x04) - */ - /* Note that pdlptr+1 and not pdlptr is the pointer to the PDH */ + /* + * Write address and length of first PDL Fragment (which is used for + * storing the RX-Header + * We use the 4 bytes _before_ the PDH in the pdl memory area to + * store this information. (PDH is at offset 0x04) + */ + /* Note that pdlptr+1 and not pdlptr is the pointer to the PDH */ - *(pdlptr+2) =(u_int) virt_to_bus(pdlptr); /* Address Frag 1 */ - *(pdlptr+3) = 4; /* Length Frag 1 */ + *(pdlptr + 2) = (u_int) virt_to_bus(pdlptr); /* Address Frag 1 */ + *(pdlptr + 3) = 4; /* Length Frag 1 */ - return( ( ((MAX_RX_FRAG*2+2)+3) /4)*4 ); + return ((((MAX_RX_FRAG * 2 + 2) + 3) / 4) * 4); } -static int hp100_init_txpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) +static int hp100_init_txpdl(struct net_device *dev, + register hp100_ring_t * ringptr, + register u32 * pdlptr) { - if( 0!=( ((unsigned)pdlptr) & 0xf) ) - printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n",dev->name,(unsigned) pdlptr); - - ringptr->pdl = pdlptr; /* +1; */ - ringptr->pdl_paddr = virt_to_bus(pdlptr); /* +1 */ - ringptr->skb = (void *) NULL; - - return((((MAX_TX_FRAG*2+2)+3)/4)*4); + if (0 != (((unsigned) pdlptr) & 0xf)) + printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n", dev->name, (unsigned) pdlptr); + + ringptr->pdl = pdlptr; /* +1; */ + ringptr->pdl_paddr = virt_to_bus(pdlptr); /* +1 */ + ringptr->skb = (void *) NULL; + + return ((((MAX_TX_FRAG * 2 + 2) + 3) / 4) * 4); } - /* * hp100_build_rx_pdl allocates an skb_buff of maximum size plus two bytes * for possible odd word alignment rounding up to next dword and set PDL @@ -1321,80 +1283,76 @@ static int hp100_init_txpdl( struct net_device *dev, register hp100_ring_t *ring * Returns: 0 if unable to allocate skb_buff * 1 if successful */ -static int hp100_build_rx_pdl( hp100_ring_t *ringptr, struct net_device *dev ) +static int hp100_build_rx_pdl(hp100_ring_t * ringptr, + struct net_device *dev) { #ifdef HP100_DEBUG_B - int ioaddr = dev->base_addr; + int ioaddr = dev->base_addr; #endif #ifdef HP100_DEBUG_BM - u_int *p; + u_int *p; #endif #ifdef HP100_DEBUG_B - hp100_outw( 0x4207, TRACE ); - printk("hp100: %s: build rx pdl\n", dev->name); -#endif - - /* Allocate skb buffer of maximum size */ - /* Note: This depends on the alloc_skb functions allocating more - * space than requested, i.e. aligning to 16bytes */ - - ringptr->skb = dev_alloc_skb( ((MAX_ETHER_SIZE+2+3)/4)*4 ); - - if(NULL!=ringptr->skb) - { - /* - * Reserve 2 bytes at the head of the buffer to land the IP header - * on a long word boundary (According to the Network Driver section - * in the Linux KHG, this should help to increase performance.) - */ - skb_reserve(ringptr->skb, 2); - - ringptr->skb->dev=dev; - ringptr->skb->data=(u_char *)skb_put(ringptr->skb, MAX_ETHER_SIZE ); - - /* ringptr->pdl points to the beginning of the PDL, i.e. the PDH */ - /* Note: 1st Fragment is used for the 4 byte packet status - * (receive header). Its PDL entries are set up by init_rxpdl. So - * here we only have to set up the PDL fragment entries for the data - * part. Those 4 bytes will be stored in the DMA memory region - * directly before the PDL. - */ + hp100_outw(0x4207, TRACE); + printk("hp100: %s: build rx pdl\n", dev->name); +#endif + + /* Allocate skb buffer of maximum size */ + /* Note: This depends on the alloc_skb functions allocating more + * space than requested, i.e. aligning to 16bytes */ + + ringptr->skb = dev_alloc_skb(((MAX_ETHER_SIZE + 2 + 3) / 4) * 4); + + if (NULL != ringptr->skb) { + /* + * Reserve 2 bytes at the head of the buffer to land the IP header + * on a long word boundary (According to the Network Driver section + * in the Linux KHG, this should help to increase performance.) + */ + skb_reserve(ringptr->skb, 2); + + ringptr->skb->dev = dev; + ringptr->skb->data = (u_char *) skb_put(ringptr->skb, MAX_ETHER_SIZE); + + /* ringptr->pdl points to the beginning of the PDL, i.e. the PDH */ + /* Note: 1st Fragment is used for the 4 byte packet status + * (receive header). Its PDL entries are set up by init_rxpdl. So + * here we only have to set up the PDL fragment entries for the data + * part. Those 4 bytes will be stored in the DMA memory region + * directly before the PDL. + */ #ifdef HP100_DEBUG_BM - printk("hp100: %s: build_rx_pdl: PDH@0x%x, skb->data (len %d) at 0x%x\n", - dev->name, - (u_int) ringptr->pdl, - ((MAX_ETHER_SIZE+2+3)/4)*4, - (unsigned int) ringptr->skb->data); + printk("hp100: %s: build_rx_pdl: PDH@0x%x, skb->data (len %d) at 0x%x\n", + dev->name, (u_int) ringptr->pdl, + ((MAX_ETHER_SIZE + 2 + 3) / 4) * 4, + (unsigned int) ringptr->skb->data); #endif - ringptr->pdl[0] = 0x00020000; /* Write PDH */ - ringptr->pdl[3] = ((u_int)virt_to_bus(ringptr->skb->data)); - ringptr->pdl[4] = MAX_ETHER_SIZE; /* Length of Data */ - + ringptr->pdl[0] = 0x00020000; /* Write PDH */ + ringptr->pdl[3] = ((u_int) virt_to_bus(ringptr->skb->data)); + ringptr->pdl[4] = MAX_ETHER_SIZE; /* Length of Data */ + #ifdef HP100_DEBUG_BM - for(p=(ringptr->pdl); p<(ringptr->pdl+5); p++) - printk("hp100: %s: Adr 0x%.8x = 0x%.8x\n",dev->name,(u_int) p,(u_int) *p ); -#endif - return(1); - } - /* else: */ - /* alloc_skb failed (no memory) -> still can receive the header - * fragment into PDL memory. make PDL safe by clearing msgptr and - * making the PDL only 1 fragment (i.e. the 4 byte packet status) - */ + for (p = (ringptr->pdl); p < (ringptr->pdl + 5); p++) + printk("hp100: %s: Adr 0x%.8x = 0x%.8x\n", dev->name, (u_int) p, (u_int) * p); +#endif + return (1); + } + /* else: */ + /* alloc_skb failed (no memory) -> still can receive the header + * fragment into PDL memory. make PDL safe by clearing msgptr and + * making the PDL only 1 fragment (i.e. the 4 byte packet status) + */ #ifdef HP100_DEBUG_BM - printk("hp100: %s: build_rx_pdl: PDH@0x%x, No space for skb.\n", - dev->name, - (u_int) ringptr->pdl); + printk("hp100: %s: build_rx_pdl: PDH@0x%x, No space for skb.\n", dev->name, (u_int) ringptr->pdl); #endif - ringptr->pdl[0]=0x00010000; /* PDH: Count=1 Fragment */ + ringptr->pdl[0] = 0x00010000; /* PDH: Count=1 Fragment */ - return(0); + return (0); } - /* * hp100_rxfill - attempt to fill the Rx Ring will empty skb's * @@ -1405,275 +1363,250 @@ static int hp100_build_rx_pdl( hp100_ring_t *ringptr, struct net_device *dev ) * b. Put the physical address of the buffer into the PDL. * c. Output physical address of PDL to adapter. */ -static void hp100_rxfill( struct net_device *dev ) +static void hp100_rxfill(struct net_device *dev) { - int ioaddr=dev->base_addr; + int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; - hp100_ring_t *ringptr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + hp100_ring_t *ringptr; #ifdef HP100_DEBUG_B - hp100_outw( 0x4208, TRACE ); - printk("hp100: %s: rxfill\n",dev->name); -#endif - - hp100_page( PERFORMANCE ); - - while (lp->rxrcommit < MAX_RX_PDL) - { - /* - ** Attempt to get a buffer and build a Rx PDL. - */ - ringptr = lp->rxrtail; - if (0 == hp100_build_rx_pdl( ringptr, dev )) - { - return; /* None available, return */ - } - - /* Hand this PDL over to the card */ - /* Note: This needs performance page selected! */ + hp100_outw(0x4208, TRACE); + printk("hp100: %s: rxfill\n", dev->name); +#endif + + hp100_page(PERFORMANCE); + + while (lp->rxrcommit < MAX_RX_PDL) { + /* + ** Attempt to get a buffer and build a Rx PDL. + */ + ringptr = lp->rxrtail; + if (0 == hp100_build_rx_pdl(ringptr, dev)) { + return; /* None available, return */ + } + + /* Hand this PDL over to the card */ + /* Note: This needs performance page selected! */ #ifdef HP100_DEBUG_BM - printk("hp100: %s: rxfill: Hand to card: pdl #%d @0x%x phys:0x%x, buffer: 0x%x\n", - dev->name, - lp->rxrcommit, - (u_int)ringptr->pdl, - (u_int)ringptr->pdl_paddr, - (u_int)ringptr->pdl[3]); -#endif - - hp100_outl( (u32)ringptr->pdl_paddr, RX_PDA); - - lp->rxrcommit += 1; - lp->rxrtail = ringptr->next; - } + printk("hp100: %s: rxfill: Hand to card: pdl #%d @0x%x phys:0x%x, buffer: 0x%x\n", + dev->name, lp->rxrcommit, (u_int) ringptr->pdl, + (u_int) ringptr->pdl_paddr, (u_int) ringptr->pdl[3]); +#endif + + hp100_outl((u32) ringptr->pdl_paddr, RX_PDA); + + lp->rxrcommit += 1; + lp->rxrtail = ringptr->next; + } } - /* * BM_shutdown - shutdown bus mastering and leave chip in reset state */ -static void hp100_BM_shutdown( struct net_device *dev ) +static void hp100_BM_shutdown(struct net_device *dev) { - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; - unsigned long time; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + unsigned long time; #ifdef HP100_DEBUG_B - hp100_outw( 0x4209, TRACE ); - printk("hp100: %s: bm shutdown\n",dev->name); -#endif - - hp100_page( PERFORMANCE ); - hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all ints */ - hp100_outw( 0xffff, IRQ_STATUS ); /* Ack all ints */ - - /* Ensure Interrupts are off */ - hp100_outw( HP100_INT_EN | HP100_RESET_LB , OPTION_LSW ); - - /* Disable all MAC activity */ - hp100_page( MAC_CTRL ); - hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 ); /* stop rx/tx */ - - /* If cascade MMU is not already in reset */ - if (0 != (hp100_inw(OPTION_LSW)&HP100_HW_RST) ) - { - /* Wait 1.3ms (10Mb max packet time) to ensure MAC is idle so - * MMU pointers will not be reset out from underneath - */ - hp100_page( MAC_CTRL ); - for(time=0; time<5000; time++) - { - if( (hp100_inb(MAC_CFG_1)&(HP100_TX_IDLE|HP100_RX_IDLE))== - (HP100_TX_IDLE|HP100_RX_IDLE) ) break; - } - - /* Shutdown algorithm depends on the generation of Cascade */ - if( lp->chip==HP100_CHIPID_LASSEN ) - { /* ETR shutdown/reset */ - /* Disable Busmaster mode and wait for bit to go to zero. */ - hp100_page(HW_MAP); - hp100_andb( ~HP100_BM_MASTER, BM ); - /* 100 ms timeout */ - for(time=0; time<32000; time++) - { - if ( 0 == (hp100_inb( BM ) & HP100_BM_MASTER) ) break; - } - } - else - { /* Shasta or Rainier Shutdown/Reset */ - /* To ensure all bus master inloading activity has ceased, - * wait for no Rx PDAs or no Rx packets on card. - */ - hp100_page( PERFORMANCE ); - /* 100 ms timeout */ - for(time=0; time<10000; time++) - { - /* RX_PDL: PDLs not executed. */ - /* RX_PKT_CNT: RX'd packets on card. */ - if ( (hp100_inb( RX_PDL ) == 0) && - (hp100_inb( RX_PKT_CNT ) == 0) ) break; - } - - if(time>=10000) - printk("hp100: %s: BM shutdown error.\n", dev->name); - - /* To ensure all bus master outloading activity has ceased, - * wait until the Tx PDA count goes to zero or no more Tx space - * available in the Tx region of the card. - */ - /* 100 ms timeout */ - for(time=0; time<10000; time++) { - if ( (0 == hp100_inb( TX_PKT_CNT )) && - (0 != (hp100_inb( TX_MEM_FREE )&HP100_AUTO_COMPARE))) break; - } - - /* Disable Busmaster mode */ - hp100_page(HW_MAP); - hp100_andb( ~HP100_BM_MASTER, BM ); - } /* end of shutdown procedure for non-etr parts */ - - hp100_cascade_reset( dev, TRUE ); - } - hp100_page( PERFORMANCE ); - /* hp100_outw( HP100_BM_READ | HP100_BM_WRITE | HP100_RESET_HB, OPTION_LSW ); */ - /* Busmaster mode should be shut down now. */ -} + hp100_outw(0x4209, TRACE); + printk("hp100: %s: bm shutdown\n", dev->name); +#endif + + hp100_page(PERFORMANCE); + hp100_outw(0xfefe, IRQ_MASK); /* mask off all ints */ + hp100_outw(0xffff, IRQ_STATUS); /* Ack all ints */ + + /* Ensure Interrupts are off */ + hp100_outw(HP100_INT_EN | HP100_RESET_LB, OPTION_LSW); + + /* Disable all MAC activity */ + hp100_page(MAC_CTRL); + hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1); /* stop rx/tx */ + + /* If cascade MMU is not already in reset */ + if (0 != (hp100_inw(OPTION_LSW) & HP100_HW_RST)) { + /* Wait 1.3ms (10Mb max packet time) to ensure MAC is idle so + * MMU pointers will not be reset out from underneath + */ + hp100_page(MAC_CTRL); + for (time = 0; time < 5000; time++) { + if ((hp100_inb(MAC_CFG_1) & (HP100_TX_IDLE | HP100_RX_IDLE)) == (HP100_TX_IDLE | HP100_RX_IDLE)) + break; + } + /* Shutdown algorithm depends on the generation of Cascade */ + if (lp->chip == HP100_CHIPID_LASSEN) { /* ETR shutdown/reset */ + /* Disable Busmaster mode and wait for bit to go to zero. */ + hp100_page(HW_MAP); + hp100_andb(~HP100_BM_MASTER, BM); + /* 100 ms timeout */ + for (time = 0; time < 32000; time++) { + if (0 == (hp100_inb(BM) & HP100_BM_MASTER)) + break; + } + } else { /* Shasta or Rainier Shutdown/Reset */ + /* To ensure all bus master inloading activity has ceased, + * wait for no Rx PDAs or no Rx packets on card. + */ + hp100_page(PERFORMANCE); + /* 100 ms timeout */ + for (time = 0; time < 10000; time++) { + /* RX_PDL: PDLs not executed. */ + /* RX_PKT_CNT: RX'd packets on card. */ + if ((hp100_inb(RX_PDL) == 0) && (hp100_inb(RX_PKT_CNT) == 0)) + break; + } + + if (time >= 10000) + printk("hp100: %s: BM shutdown error.\n", dev->name); + + /* To ensure all bus master outloading activity has ceased, + * wait until the Tx PDA count goes to zero or no more Tx space + * available in the Tx region of the card. + */ + /* 100 ms timeout */ + for (time = 0; time < 10000; time++) { + if ((0 == hp100_inb(TX_PKT_CNT)) && + (0 != (hp100_inb(TX_MEM_FREE) & HP100_AUTO_COMPARE))) + break; + } + + /* Disable Busmaster mode */ + hp100_page(HW_MAP); + hp100_andb(~HP100_BM_MASTER, BM); + } /* end of shutdown procedure for non-etr parts */ + + hp100_cascade_reset(dev, TRUE); + } + hp100_page(PERFORMANCE); + /* hp100_outw( HP100_BM_READ | HP100_BM_WRITE | HP100_RESET_HB, OPTION_LSW ); */ + /* Busmaster mode should be shut down now. */ +} - /* * transmit functions */ /* tx function for busmaster mode */ -static int hp100_start_xmit_bm( struct sk_buff *skb, struct net_device *dev ) +static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev) { - unsigned long flags; - int i, ok_flag; - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; - hp100_ring_t *ringptr; + unsigned long flags; + int i, ok_flag; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + hp100_ring_t *ringptr; #ifdef HP100_DEBUG_B - hp100_outw( 0x4210, TRACE ); - printk("hp100: %s: start_xmit_bm\n",dev->name); + hp100_outw(0x4210, TRACE); + printk("hp100: %s: start_xmit_bm\n", dev->name); #endif - if ( skb==NULL ) - { - return 0; - } - - if ( skb->len <= 0 ) return 0; - - /* Get Tx ring tail pointer */ - if( lp->txrtail->next==lp->txrhead ) - { - /* No memory. */ -#ifdef HP100_DEBUG - printk("hp100: %s: start_xmit_bm: No TX PDL available.\n", dev->name); -#endif - /* not waited long enough since last tx? */ - if ( jiffies - dev->trans_start < HZ ) return -EAGAIN; - - if ( lp->lan_type < 0 ) /* no LAN type detected yet? */ - { - hp100_stop_interface( dev ); - if ( ( lp->lan_type = hp100_sense_lan( dev ) ) < 0 ) - { - printk( "hp100: %s: no connection found - check wire\n", dev->name ); - hp100_start_interface( dev ); /* 10Mb/s RX pkts maybe handled */ - return -EIO; - } - if ( lp->lan_type == HP100_LAN_100 ) - lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); /* relogin */ - hp100_start_interface( dev ); + if (skb == NULL) { + return 0; } - - if ( lp->lan_type == HP100_LAN_100 && lp->hub_status < 0 ) - /* we have a 100Mb/s adapter but it isn't connected to hub */ - { - printk( "hp100: %s: login to 100Mb/s hub retry\n", dev->name ); - hp100_stop_interface( dev ); - lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); - hp100_start_interface( dev ); + + if (skb->len <= 0) + return 0; + + /* Get Tx ring tail pointer */ + if (lp->txrtail->next == lp->txrhead) { + /* No memory. */ +#ifdef HP100_DEBUG + printk("hp100: %s: start_xmit_bm: No TX PDL available.\n", dev->name); +#endif + /* not waited long enough since last tx? */ + if (jiffies - dev->trans_start < HZ) + return -EAGAIN; + + if (lp->lan_type < 0) { /* no LAN type detected yet? */ + hp100_stop_interface(dev); + if ((lp->lan_type = hp100_sense_lan(dev)) < 0) { + printk("hp100: %s: no connection found - check wire\n", dev->name); + hp100_start_interface(dev); /* 10Mb/s RX pkts maybe handled */ + return -EIO; + } + if (lp->lan_type == HP100_LAN_100) + lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); /* relogin */ + hp100_start_interface(dev); + } + + if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) { + /* we have a 100Mb/s adapter but it isn't connected to hub */ + printk("hp100: %s: login to 100Mb/s hub retry\n", dev->name); + hp100_stop_interface(dev); + lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); + hp100_start_interface(dev); + } else { + spin_lock_irqsave(&lp->lock, flags); + hp100_ints_off(); /* Useful ? Jean II */ + i = hp100_sense_lan(dev); + hp100_ints_on(); + spin_unlock_irqrestore(&lp->lock, flags); + if (i == HP100_LAN_ERR) + printk("hp100: %s: link down detected\n", dev->name); + else if (lp->lan_type != i) { /* cable change! */ + /* it's very hard - all network setting must be changed!!! */ + printk("hp100: %s: cable change 10Mb/s <-> 100Mb/s detected\n", dev->name); + lp->lan_type = i; + hp100_stop_interface(dev); + if (lp->lan_type == HP100_LAN_100) + lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); + hp100_start_interface(dev); + } else { + printk("hp100: %s: interface reset\n", dev->name); + hp100_stop_interface(dev); + if (lp->lan_type == HP100_LAN_100) + lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); + hp100_start_interface(dev); + } + } + + dev->trans_start = jiffies; + return -EAGAIN; } - else - { - spin_lock_irqsave (&lp->lock, flags); - hp100_ints_off(); /* Useful ? Jean II */ - i = hp100_sense_lan( dev ); - hp100_ints_on(); - spin_unlock_irqrestore (&lp->lock, flags); - if ( i == HP100_LAN_ERR ) - printk( "hp100: %s: link down detected\n", dev->name ); - else - if ( lp->lan_type != i ) /* cable change! */ - { - /* it's very hard - all network setting must be changed!!! */ - printk( "hp100: %s: cable change 10Mb/s <-> 100Mb/s detected\n", dev->name ); - lp->lan_type = i; - hp100_stop_interface( dev ); - if ( lp->lan_type == HP100_LAN_100 ) - lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); - hp100_start_interface( dev ); - } - else - { - printk( "hp100: %s: interface reset\n", dev->name ); - hp100_stop_interface( dev ); - if ( lp->lan_type == HP100_LAN_100 ) - lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); - hp100_start_interface( dev ); - } + + /* + * we have to turn int's off before modifying this, otherwise + * a tx_pdl_cleanup could occur at the same time + */ + spin_lock_irqsave(&lp->lock, flags); + ringptr = lp->txrtail; + lp->txrtail = ringptr->next; + + /* Check whether packet has minimal packet size */ + ok_flag = skb->len >= HP100_MIN_PACKET_SIZE; + i = ok_flag ? skb->len : HP100_MIN_PACKET_SIZE; + + ringptr->skb = skb; + ringptr->pdl[0] = ((1 << 16) | i); /* PDH: 1 Fragment & length */ + ringptr->pdl[1] = (u32) virt_to_bus(skb->data); /* 1st Frag: Adr. of data */ + if (lp->chip == HP100_CHIPID_SHASTA) { + /* TODO:Could someone who has the EISA card please check if this works? */ + ringptr->pdl[2] = i; + } else { /* Lassen */ + /* In the PDL, don't use the padded size but the real packet size: */ + ringptr->pdl[2] = skb->len; /* 1st Frag: Length of frag */ } - dev->trans_start = jiffies; - return -EAGAIN; - } - - /* - * we have to turn int's off before modifying this, otherwise - * a tx_pdl_cleanup could occur at the same time - */ - spin_lock_irqsave (&lp->lock, flags); - ringptr=lp->txrtail; - lp->txrtail=ringptr->next; - - /* Check whether packet has minimal packet size */ - ok_flag = skb->len >= HP100_MIN_PACKET_SIZE; - i = ok_flag ? skb->len : HP100_MIN_PACKET_SIZE; - - ringptr->skb=skb; - ringptr->pdl[0]=((1<<16) | i); /* PDH: 1 Fragment & length */ - ringptr->pdl[1]=(u32)virt_to_bus(skb->data); /* 1st Frag: Adr. of data */ - if(lp->chip==HP100_CHIPID_SHASTA) - { - /* TODO:Could someone who has the EISA card please check if this works? */ - ringptr->pdl[2]=i; - } - else /* Lassen */ - { - /* In the PDL, don't use the padded size but the real packet size: */ - ringptr->pdl[2]=skb->len; /* 1st Frag: Length of frag */ - } - - /* Hand this PDL to the card. */ - hp100_outl( ringptr->pdl_paddr, TX_PDA_L ); /* Low Prio. Queue */ - - lp->txrcommit++; - spin_unlock_irqrestore (&lp->lock, flags); - - /* Update statistics */ - lp->stats.tx_packets++; - lp->stats.tx_bytes += skb->len; - dev->trans_start = jiffies; - - return 0; -} + /* Hand this PDL to the card. */ + hp100_outl(ringptr->pdl_paddr, TX_PDA_L); /* Low Prio. Queue */ + + lp->txrcommit++; + spin_unlock_irqrestore(&lp->lock, flags); + /* Update statistics */ + lp->stats.tx_packets++; + lp->stats.tx_bytes += skb->len; + dev->trans_start = jiffies; + + return 0; +} + /* clean_txring checks if packets have been sent by the card by reading * the TX_PDL register from the performance page and comparing it to the * number of commited packets. It then frees the skb's of the packets that @@ -1681,201 +1614,181 @@ static int hp100_start_xmit_bm( struct sk_buff *skb, struct net_device *dev ) * * Needs the PERFORMANCE page selected. */ -static void hp100_clean_txring( struct net_device *dev ) +static void hp100_clean_txring(struct net_device *dev) { - struct hp100_private *lp = (struct hp100_private *)dev->priv; - int ioaddr = dev->base_addr; - int donecount; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + int ioaddr = dev->base_addr; + int donecount; #ifdef HP100_DEBUG_B - hp100_outw( 0x4211, TRACE ); - printk("hp100: %s: clean txring\n", dev->name); + hp100_outw(0x4211, TRACE); + printk("hp100: %s: clean txring\n", dev->name); #endif - /* How many PDLs have been transmitted? */ - donecount=(lp->txrcommit)-hp100_inb(TX_PDL); + /* How many PDLs have been transmitted? */ + donecount = (lp->txrcommit) - hp100_inb(TX_PDL); #ifdef HP100_DEBUG - if(donecount>MAX_TX_PDL) - printk("hp100: %s: Warning: More PDLs transmitted than commited to card???\n",dev->name); + if (donecount > MAX_TX_PDL) + printk("hp100: %s: Warning: More PDLs transmitted than commited to card???\n", dev->name); #endif - for( ; 0!=donecount; donecount-- ) - { + for (; 0 != donecount; donecount--) { #ifdef HP100_DEBUG_BM - printk("hp100: %s: Free skb: data @0x%.8x txrcommit=0x%x TXPDL=0x%x, done=0x%x\n", - dev->name, - (u_int) lp->txrhead->skb->data, - lp->txrcommit, - hp100_inb(TX_PDL), - donecount); -#endif - dev_kfree_skb_any( lp->txrhead->skb ); - lp->txrhead->skb=(void *)NULL; - lp->txrhead=lp->txrhead->next; - lp->txrcommit--; - } + printk("hp100: %s: Free skb: data @0x%.8x txrcommit=0x%x TXPDL=0x%x, done=0x%x\n", + dev->name, (u_int) lp->txrhead->skb->data, + lp->txrcommit, hp100_inb(TX_PDL), donecount); +#endif + dev_kfree_skb_any(lp->txrhead->skb); + lp->txrhead->skb = (void *) NULL; + lp->txrhead = lp->txrhead->next; + lp->txrcommit--; + } } - /* tx function for slave modes */ -static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ) +static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) { - unsigned long flags; - int i, ok_flag; - int ioaddr = dev->base_addr; - u_short val; - struct hp100_private *lp = (struct hp100_private *)dev->priv; + unsigned long flags; + int i, ok_flag; + int ioaddr = dev->base_addr; + u_short val; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4212, TRACE ); - printk("hp100: %s: start_xmit\n", dev->name); + hp100_outw(0x4212, TRACE); + printk("hp100: %s: start_xmit\n", dev->name); #endif - if ( skb==NULL ) - { - return 0; - } - - if ( skb->len <= 0 ) return 0; - - if ( lp->lan_type < 0 ) /* no LAN type detected yet? */ - { - hp100_stop_interface( dev ); - if ( ( lp->lan_type = hp100_sense_lan( dev ) ) < 0 ) - { - printk( "hp100: %s: no connection found - check wire\n", dev->name ); - hp100_start_interface( dev ); /* 10Mb/s RX packets maybe handled */ - return -EIO; - } - if ( lp->lan_type == HP100_LAN_100 ) - lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); /* relogin */ - hp100_start_interface( dev ); - } - - /* If there is not enough free memory on the card... */ - i=hp100_inl(TX_MEM_FREE)&0x7fffffff; - if ( !(((i/2)-539)>(skb->len+16) && (hp100_inb(TX_PKT_CNT)<255)) ) - { + if (skb == NULL) { + return 0; + } + + if (skb->len <= 0) + return 0; + + if (lp->lan_type < 0) { /* no LAN type detected yet? */ + hp100_stop_interface(dev); + if ((lp->lan_type = hp100_sense_lan(dev)) < 0) { + printk("hp100: %s: no connection found - check wire\n", dev->name); + hp100_start_interface(dev); /* 10Mb/s RX packets maybe handled */ + return -EIO; + } + if (lp->lan_type == HP100_LAN_100) + lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); /* relogin */ + hp100_start_interface(dev); + } + + /* If there is not enough free memory on the card... */ + i = hp100_inl(TX_MEM_FREE) & 0x7fffffff; + if (!(((i / 2) - 539) > (skb->len + 16) && (hp100_inb(TX_PKT_CNT) < 255))) { #ifdef HP100_DEBUG - printk( "hp100: %s: start_xmit: tx free mem = 0x%x\n", dev->name, i ); + printk("hp100: %s: start_xmit: tx free mem = 0x%x\n", dev->name, i); #endif - /* not waited long enough since last failed tx try? */ - if ( jiffies - dev->trans_start < HZ ) - { + /* not waited long enough since last failed tx try? */ + if (jiffies - dev->trans_start < HZ) { #ifdef HP100_DEBUG - printk("hp100: %s: trans_start timing problem\n", dev->name); + printk("hp100: %s: trans_start timing problem\n", + dev->name); #endif - return -EAGAIN; + return -EAGAIN; + } + if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) { + /* we have a 100Mb/s adapter but it isn't connected to hub */ + printk("hp100: %s: login to 100Mb/s hub retry\n", dev->name); + hp100_stop_interface(dev); + lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); + hp100_start_interface(dev); + } else { + spin_lock_irqsave(&lp->lock, flags); + hp100_ints_off(); /* Useful ? Jean II */ + i = hp100_sense_lan(dev); + hp100_ints_on(); + spin_unlock_irqrestore(&lp->lock, flags); + if (i == HP100_LAN_ERR) + printk("hp100: %s: link down detected\n", dev->name); + else if (lp->lan_type != i) { /* cable change! */ + /* it's very hard - all network setting must be changed!!! */ + printk("hp100: %s: cable change 10Mb/s <-> 100Mb/s detected\n", dev->name); + lp->lan_type = i; + hp100_stop_interface(dev); + if (lp->lan_type == HP100_LAN_100) + lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); + hp100_start_interface(dev); + } else { + printk("hp100: %s: interface reset\n", dev->name); + hp100_stop_interface(dev); + if (lp->lan_type == HP100_LAN_100) + lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); + hp100_start_interface(dev); + mdelay(1); + } + } + dev->trans_start = jiffies; + return -EAGAIN; } - if ( lp->lan_type == HP100_LAN_100 && lp->hub_status < 0 ) - /* we have a 100Mb/s adapter but it isn't connected to hub */ - { - printk( "hp100: %s: login to 100Mb/s hub retry\n", dev->name ); - hp100_stop_interface( dev ); - lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); - hp100_start_interface( dev ); - } - else - { - spin_lock_irqsave (&lp->lock, flags); - hp100_ints_off(); /* Useful ? Jean II */ - i = hp100_sense_lan( dev ); - hp100_ints_on(); - spin_unlock_irqrestore (&lp->lock, flags); - if ( i == HP100_LAN_ERR ) - printk( "hp100: %s: link down detected\n", dev->name ); - else - if ( lp->lan_type != i ) /* cable change! */ - { - /* it's very hard - all network setting must be changed!!! */ - printk( "hp100: %s: cable change 10Mb/s <-> 100Mb/s detected\n", dev->name ); - lp->lan_type = i; - hp100_stop_interface( dev ); - if ( lp->lan_type == HP100_LAN_100 ) - lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); - hp100_start_interface( dev ); - } - else - { - printk( "hp100: %s: interface reset\n", dev->name ); - hp100_stop_interface( dev ); - if ( lp->lan_type == HP100_LAN_100 ) - lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); - hp100_start_interface( dev ); - mdelay(1); - } - } - dev->trans_start = jiffies; - return -EAGAIN; - } - - for ( i=0; i<6000 && ( hp100_inb( OPTION_MSW ) & HP100_TX_CMD ); i++ ) - { + + for (i = 0; i < 6000 && (hp100_inb(OPTION_MSW) & HP100_TX_CMD); i++) { #ifdef HP100_DEBUG_TX - printk( "hp100: %s: start_xmit: busy\n", dev->name ); + printk("hp100: %s: start_xmit: busy\n", dev->name); #endif - } - - spin_lock_irqsave (&lp->lock, flags); - hp100_ints_off(); - val = hp100_inw( IRQ_STATUS ); - /* Ack / clear the interrupt TX_COMPLETE interrupt - this interrupt is set - * when the current packet being transmitted on the wire is completed. */ - hp100_outw( HP100_TX_COMPLETE, IRQ_STATUS ); + } + + spin_lock_irqsave(&lp->lock, flags); + hp100_ints_off(); + val = hp100_inw(IRQ_STATUS); + /* Ack / clear the interrupt TX_COMPLETE interrupt - this interrupt is set + * when the current packet being transmitted on the wire is completed. */ + hp100_outw(HP100_TX_COMPLETE, IRQ_STATUS); #ifdef HP100_DEBUG_TX - printk("hp100: %s: start_xmit: irq_status=0x%.4x, irqmask=0x%.4x, len=%d\n",dev->name,val,hp100_inw(IRQ_MASK),(int)skb->len ); -#endif + printk("hp100: %s: start_xmit: irq_status=0x%.4x, irqmask=0x%.4x, len=%d\n", + dev->name, val, hp100_inw(IRQ_MASK), (int) skb->len); +#endif + + ok_flag = skb->len >= HP100_MIN_PACKET_SIZE; + i = ok_flag ? skb->len : HP100_MIN_PACKET_SIZE; + + hp100_outw(i, DATA32); /* tell card the total packet length */ + hp100_outw(i, FRAGMENT_LEN); /* and first/only fragment length */ + + if (lp->mode == 2) { /* memory mapped */ + if (lp->mem_ptr_virt) { /* high pci memory was remapped */ + /* Note: The J2585B needs alignment to 32bits here! */ + memcpy_toio(lp->mem_ptr_virt, skb->data, (skb->len + 3) & ~3); + if (!ok_flag) + memset_io(lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len); + } else { + /* Note: The J2585B needs alignment to 32bits here! */ + isa_memcpy_toio(lp->mem_ptr_phys, skb->data, (skb->len + 3) & ~3); + if (!ok_flag) + isa_memset_io(lp->mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb->len); + } + } else { /* programmed i/o */ + outsl(ioaddr + HP100_REG_DATA32, skb->data, + (skb->len + 3) >> 2); + if (!ok_flag) + for (i = (skb->len + 3) & ~3; i < HP100_MIN_PACKET_SIZE; i += 4) + hp100_outl(0, DATA32); + } - ok_flag = skb->len >= HP100_MIN_PACKET_SIZE; - i = ok_flag ? skb->len : HP100_MIN_PACKET_SIZE; + hp100_outb(HP100_TX_CMD | HP100_SET_LB, OPTION_MSW); /* send packet */ + + lp->stats.tx_packets++; + lp->stats.tx_bytes += skb->len; + dev->trans_start = jiffies; + hp100_ints_on(); + spin_unlock_irqrestore(&lp->lock, flags); + + dev_kfree_skb_any(skb); - hp100_outw( i, DATA32 ); /* tell card the total packet length */ - hp100_outw( i, FRAGMENT_LEN ); /* and first/only fragment length */ - - if ( lp->mode==2 ) /* memory mapped */ - { - if ( lp->mem_ptr_virt ) /* high pci memory was remapped */ - { - /* Note: The J2585B needs alignment to 32bits here! */ - memcpy_toio( lp->mem_ptr_virt, skb->data, ( skb->len + 3 ) & ~3 ); - if ( !ok_flag ) - memset_io( lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len ); - } - else - { - /* Note: The J2585B needs alignment to 32bits here! */ - isa_memcpy_toio( lp->mem_ptr_phys, skb->data, (skb->len + 3) & ~3 ); - if ( !ok_flag ) - isa_memset_io( lp->mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb->len ); - } - } - else /* programmed i/o */ - { - outsl( ioaddr + HP100_REG_DATA32, skb->data, ( skb->len + 3 ) >> 2 ); - if ( !ok_flag ) - for ( i = ( skb->len + 3 ) & ~3; i < HP100_MIN_PACKET_SIZE; i += 4 ) - hp100_outl( 0, DATA32 ); - } - - hp100_outb( HP100_TX_CMD | HP100_SET_LB, OPTION_MSW ); /* send packet */ - - lp->stats.tx_packets++; - lp->stats.tx_bytes += skb->len; - dev->trans_start=jiffies; - hp100_ints_on(); - spin_unlock_irqrestore (&lp->lock, flags); - - dev_kfree_skb_any( skb ); - #ifdef HP100_DEBUG_TX - printk( "hp100: %s: start_xmit: end\n", dev->name ); + printk("hp100: %s: start_xmit: end\n", dev->name); #endif - - return 0; -} + return 0; +} + /* * Receive Function (Non-Busmaster mode) * Called when an "Receive Packet" interrupt occurs, i.e. the receive @@ -1885,323 +1798,295 @@ static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ) * and netif_rx. */ -static void hp100_rx( struct net_device *dev ) +static void hp100_rx(struct net_device *dev) { - int packets, pkt_len; - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; - u_int header; - struct sk_buff *skb; + int packets, pkt_len; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + u_int header; + struct sk_buff *skb; #ifdef DEBUG_B - hp100_outw( 0x4213, TRACE ); - printk("hp100: %s: rx\n", dev->name); + hp100_outw(0x4213, TRACE); + printk("hp100: %s: rx\n", dev->name); #endif - /* First get indication of received lan packet */ - /* RX_PKT_CND indicates the number of packets which have been fully */ - /* received onto the card but have not been fully transferred of the card */ - packets = hp100_inb( RX_PKT_CNT ); + /* First get indication of received lan packet */ + /* RX_PKT_CND indicates the number of packets which have been fully */ + /* received onto the card but have not been fully transferred of the card */ + packets = hp100_inb(RX_PKT_CNT); #ifdef HP100_DEBUG_RX - if ( packets > 1 ) - printk( "hp100: %s: rx: waiting packets = %d\n", dev->name,packets ); + if (packets > 1) + printk("hp100: %s: rx: waiting packets = %d\n", dev->name, packets); #endif - while ( packets-- > 0 ) - { - /* If ADV_NXT_PKT is still set, we have to wait until the card has */ - /* really advanced to the next packet. */ - for (pkt_len=0; pkt_len<6000 &&(hp100_inb(OPTION_MSW)&HP100_ADV_NXT_PKT); - pkt_len++ ) - { + while (packets-- > 0) { + /* If ADV_NXT_PKT is still set, we have to wait until the card has */ + /* really advanced to the next packet. */ + for (pkt_len = 0; pkt_len < 6000 && (hp100_inb(OPTION_MSW) & HP100_ADV_NXT_PKT); pkt_len++) { #ifdef HP100_DEBUG_RX - printk( "hp100: %s: rx: busy, remaining packets = %d\n", dev->name, packets ); -#endif - } - - /* First we get the header, which contains information about the */ - /* actual length of the received packet. */ - if( lp->mode==2 ) /* memory mapped mode */ - { - if ( lp->mem_ptr_virt ) /* if memory was remapped */ - header = readl(lp->mem_ptr_virt); - else - header = isa_readl( lp->mem_ptr_phys ); - } - else /* programmed i/o */ - header = hp100_inl( DATA32 ); - - pkt_len = ((header & HP100_PKT_LEN_MASK) + 3) & ~3; + printk ("hp100: %s: rx: busy, remaining packets = %d\n", dev->name, packets); +#endif + } + + /* First we get the header, which contains information about the */ + /* actual length of the received packet. */ + if (lp->mode == 2) { /* memory mapped mode */ + if (lp->mem_ptr_virt) /* if memory was remapped */ + header = readl(lp->mem_ptr_virt); + else + header = isa_readl(lp->mem_ptr_phys); + } else /* programmed i/o */ + header = hp100_inl(DATA32); + + pkt_len = ((header & HP100_PKT_LEN_MASK) + 3) & ~3; #ifdef HP100_DEBUG_RX - printk( "hp100: %s: rx: new packet - length=%d, errors=0x%x, dest=0x%x\n", - dev->name, - header & HP100_PKT_LEN_MASK, (header>>16)&0xfff8, - (header>>16)&7); -#endif - - /* Now we allocate the skb and transfer the data into it. */ - skb = dev_alloc_skb( pkt_len ); - if ( skb == NULL ) /* Not enough memory->drop packet */ - { + printk("hp100: %s: rx: new packet - length=%d, errors=0x%x, dest=0x%x\n", + dev->name, header & HP100_PKT_LEN_MASK, + (header >> 16) & 0xfff8, (header >> 16) & 7); +#endif + + /* Now we allocate the skb and transfer the data into it. */ + skb = dev_alloc_skb(pkt_len); + if (skb == NULL) { /* Not enough memory->drop packet */ #ifdef HP100_DEBUG - printk( "hp100: %s: rx: couldn't allocate a sk_buff of size %d\n", dev->name, pkt_len ); + printk("hp100: %s: rx: couldn't allocate a sk_buff of size %d\n", + dev->name, pkt_len); #endif - lp->stats.rx_dropped++; - } - else /* skb successfully allocated */ - { - u_char *ptr; - - skb->dev = dev; - - /* ptr to start of the sk_buff data area */ - ptr = (u_char *)skb_put( skb, pkt_len ); - - /* Now transfer the data from the card into that area */ - if ( lp->mode==2 ) - { - if ( lp->mem_ptr_virt ) - memcpy_fromio( ptr, lp->mem_ptr_virt, pkt_len ); - /* Note alignment to 32bit transfers */ - else - isa_memcpy_fromio( ptr, lp->mem_ptr_phys, pkt_len ); - } - else /* io mapped */ - insl( ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2 ); - - skb->protocol = eth_type_trans( skb, dev ); - + lp->stats.rx_dropped++; + } else { /* skb successfully allocated */ + + u_char *ptr; + + skb->dev = dev; + + /* ptr to start of the sk_buff data area */ + ptr = (u_char *) skb_put(skb, pkt_len); + + /* Now transfer the data from the card into that area */ + if (lp->mode == 2) { + if (lp->mem_ptr_virt) + memcpy_fromio(ptr, lp->mem_ptr_virt,pkt_len); + /* Note alignment to 32bit transfers */ + else + isa_memcpy_fromio(ptr, lp->mem_ptr_phys, pkt_len); + } else /* io mapped */ + insl(ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2); + + skb->protocol = eth_type_trans(skb, dev); + #ifdef HP100_DEBUG_RX - printk( "hp100: %s: rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - dev->name, - ptr[ 0 ], ptr[ 1 ], ptr[ 2 ], ptr[ 3 ], ptr[ 4 ], ptr[ 5 ], - ptr[ 6 ], ptr[ 7 ], ptr[ 8 ], ptr[ 9 ], ptr[ 10 ], ptr[ 11 ] ); -#endif - netif_rx( skb ); - dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; - } - - /* Indicate the card that we have got the packet */ - hp100_outb( HP100_ADV_NXT_PKT | HP100_SET_LB, OPTION_MSW ); - - switch ( header & 0x00070000 ) { - case (HP100_MULTI_ADDR_HASH<<16): - case (HP100_MULTI_ADDR_NO_HASH<<16): - lp->stats.multicast++; break; - } - } /* end of while(there are packets) loop */ + printk("hp100: %s: rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + dev->name, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], + ptr[9], ptr[10], ptr[11]); +#endif + netif_rx(skb); + dev->last_rx = jiffies; + lp->stats.rx_packets++; + lp->stats.rx_bytes += pkt_len; + } + + /* Indicate the card that we have got the packet */ + hp100_outb(HP100_ADV_NXT_PKT | HP100_SET_LB, OPTION_MSW); + + switch (header & 0x00070000) { + case (HP100_MULTI_ADDR_HASH << 16): + case (HP100_MULTI_ADDR_NO_HASH << 16): + lp->stats.multicast++; + break; + } + } /* end of while(there are packets) loop */ #ifdef HP100_DEBUG_RX - printk( "hp100_rx: %s: end\n", dev->name ); + printk("hp100_rx: %s: end\n", dev->name); #endif } - /* * Receive Function for Busmaster Mode */ -static void hp100_rx_bm( struct net_device *dev ) +static void hp100_rx_bm(struct net_device *dev) { - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; - hp100_ring_t *ptr; - u_int header; - int pkt_len; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + hp100_ring_t *ptr; + u_int header; + int pkt_len; #ifdef HP100_DEBUG_B - hp100_outw( 0x4214, TRACE ); - printk("hp100: %s: rx_bm\n", dev->name); + hp100_outw(0x4214, TRACE); + printk("hp100: %s: rx_bm\n", dev->name); #endif #ifdef HP100_DEBUG - if(0==lp->rxrcommit) - { - printk("hp100: %s: rx_bm called although no PDLs were committed to adapter?\n", dev->name); - return; - } - else - - /* RX_PKT_CNT states how many PDLs are currently formatted and available to - * the cards BM engine */ - if( (hp100_inw(RX_PKT_CNT)&0x00ff) >= lp->rxrcommit) - { - printk("hp100: %s: More packets received than commited? RX_PKT_CNT=0x%x, commit=0x%x\n", dev->name, hp100_inw(RX_PKT_CNT)&0x00ff, lp->rxrcommit); - return; - } -#endif - - while( (lp->rxrcommit > hp100_inb(RX_PDL)) ) - { - /* - * The packet was received into the pdl pointed to by lp->rxrhead ( - * the oldest pdl in the ring - */ - - /* First we get the header, which contains information about the */ - /* actual length of the received packet. */ - - ptr=lp->rxrhead; - - header = *(ptr->pdl-1); - pkt_len = (header & HP100_PKT_LEN_MASK); + if (0 == lp->rxrcommit) { + printk("hp100: %s: rx_bm called although no PDLs were committed to adapter?\n", dev->name); + return; + } else + /* RX_PKT_CNT states how many PDLs are currently formatted and available to + * the cards BM engine */ + if ((hp100_inw(RX_PKT_CNT) & 0x00ff) >= lp->rxrcommit) { + printk("hp100: %s: More packets received than commited? RX_PKT_CNT=0x%x, commit=0x%x\n", + dev->name, hp100_inw(RX_PKT_CNT) & 0x00ff, + lp->rxrcommit); + return; + } +#endif + + while ((lp->rxrcommit > hp100_inb(RX_PDL))) { + /* + * The packet was received into the pdl pointed to by lp->rxrhead ( + * the oldest pdl in the ring + */ + + /* First we get the header, which contains information about the */ + /* actual length of the received packet. */ + + ptr = lp->rxrhead; + + header = *(ptr->pdl - 1); + pkt_len = (header & HP100_PKT_LEN_MASK); #ifdef HP100_DEBUG_BM - printk( "hp100: %s: rx_bm: header@0x%x=0x%x length=%d, errors=0x%x, dest=0x%x\n", - dev->name, - (u_int) (ptr->pdl-1),(u_int) header, - pkt_len, - (header>>16)&0xfff8, - (header>>16)&7); - printk( "hp100: %s: RX_PDL_COUNT:0x%x TX_PDL_COUNT:0x%x, RX_PKT_CNT=0x%x PDH=0x%x, Data@0x%x len=0x%x\n", - dev->name, - hp100_inb( RX_PDL ), - hp100_inb( TX_PDL ), - hp100_inb( RX_PKT_CNT ), - (u_int) *(ptr->pdl), - (u_int) *(ptr->pdl+3), - (u_int) *(ptr->pdl+4)); -#endif - - if( (pkt_len>=MIN_ETHER_SIZE) && - (pkt_len<=MAX_ETHER_SIZE) ) - { - if(ptr->skb==NULL) - { - printk("hp100: %s: rx_bm: skb null\n", dev->name); - /* can happen if we only allocated room for the pdh due to memory shortage. */ - lp->stats.rx_dropped++; - } - else - { - skb_trim( ptr->skb, pkt_len ); /* Shorten it */ - ptr->skb->protocol = eth_type_trans( ptr->skb, dev ); - - netif_rx( ptr->skb ); /* Up and away... */ - - dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; - } - - switch ( header & 0x00070000 ) { - case (HP100_MULTI_ADDR_HASH<<16): - case (HP100_MULTI_ADDR_NO_HASH<<16): - lp->stats.multicast++; break; - } - } - else - { + printk("hp100: %s: rx_bm: header@0x%x=0x%x length=%d, errors=0x%x, dest=0x%x\n", + dev->name, (u_int) (ptr->pdl - 1), (u_int) header, + pkt_len, (header >> 16) & 0xfff8, (header >> 16) & 7); + printk("hp100: %s: RX_PDL_COUNT:0x%x TX_PDL_COUNT:0x%x, RX_PKT_CNT=0x%x PDH=0x%x, Data@0x%x len=0x%x\n", + dev->name, hp100_inb(RX_PDL), hp100_inb(TX_PDL), + hp100_inb(RX_PKT_CNT), (u_int) * (ptr->pdl), + (u_int) * (ptr->pdl + 3), (u_int) * (ptr->pdl + 4)); +#endif + + if ((pkt_len >= MIN_ETHER_SIZE) && + (pkt_len <= MAX_ETHER_SIZE)) { + if (ptr->skb == NULL) { + printk("hp100: %s: rx_bm: skb null\n", dev->name); + /* can happen if we only allocated room for the pdh due to memory shortage. */ + lp->stats.rx_dropped++; + } else { + skb_trim(ptr->skb, pkt_len); /* Shorten it */ + ptr->skb->protocol = + eth_type_trans(ptr->skb, dev); + + netif_rx(ptr->skb); /* Up and away... */ + + dev->last_rx = jiffies; + lp->stats.rx_packets++; + lp->stats.rx_bytes += pkt_len; + } + + switch (header & 0x00070000) { + case (HP100_MULTI_ADDR_HASH << 16): + case (HP100_MULTI_ADDR_NO_HASH << 16): + lp->stats.multicast++; + break; + } + } else { #ifdef HP100_DEBUG - printk("hp100: %s: rx_bm: Received bad packet (length=%d)\n",dev->name,pkt_len); -#endif - if(ptr->skb!=NULL) - dev_kfree_skb_any( ptr->skb ); - lp->stats.rx_errors++; - } - - lp->rxrhead=lp->rxrhead->next; - - /* Allocate a new rx PDL (so lp->rxrcommit stays the same) */ - if (0 == hp100_build_rx_pdl( lp->rxrtail, dev )) - { - /* No space for skb, header can still be received. */ + printk("hp100: %s: rx_bm: Received bad packet (length=%d)\n", dev->name, pkt_len); +#endif + if (ptr->skb != NULL) + dev_kfree_skb_any(ptr->skb); + lp->stats.rx_errors++; + } + + lp->rxrhead = lp->rxrhead->next; + + /* Allocate a new rx PDL (so lp->rxrcommit stays the same) */ + if (0 == hp100_build_rx_pdl(lp->rxrtail, dev)) { + /* No space for skb, header can still be received. */ #ifdef HP100_DEBUG - printk("hp100: %s: rx_bm: No space for new PDL.\n", dev->name); -#endif - return; - } - else - { /* successfully allocated new PDL - put it in ringlist at tail. */ - hp100_outl((u32)lp->rxrtail->pdl_paddr, RX_PDA); - lp->rxrtail=lp->rxrtail->next; + printk("hp100: %s: rx_bm: No space for new PDL.\n", dev->name); +#endif + return; + } else { /* successfully allocated new PDL - put it in ringlist at tail. */ + hp100_outl((u32) lp->rxrtail->pdl_paddr, RX_PDA); + lp->rxrtail = lp->rxrtail->next; + } + } - - } } - - /* * statistics */ -static hp100_stats_t *hp100_get_stats( struct net_device *dev ) +static hp100_stats_t *hp100_get_stats(struct net_device *dev) { - unsigned long flags; - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; + unsigned long flags; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4215, TRACE ); + hp100_outw(0x4215, TRACE); #endif - spin_lock_irqsave (&lp->lock, flags); - hp100_ints_off(); /* Useful ? Jean II */ - hp100_update_stats( dev ); - hp100_ints_on(); - spin_unlock_irqrestore (&lp->lock, flags); - return &(lp->stats); + spin_lock_irqsave(&lp->lock, flags); + hp100_ints_off(); /* Useful ? Jean II */ + hp100_update_stats(dev); + hp100_ints_on(); + spin_unlock_irqrestore(&lp->lock, flags); + return &(lp->stats); } -static void hp100_update_stats( struct net_device *dev ) +static void hp100_update_stats(struct net_device *dev) { - int ioaddr = dev->base_addr; - u_short val; - struct hp100_private *lp = (struct hp100_private *)dev->priv; + int ioaddr = dev->base_addr; + u_short val; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4216, TRACE ); - printk("hp100: %s: update-stats\n", dev->name); -#endif - - /* Note: Statistics counters clear when read. */ - hp100_page( MAC_CTRL ); - val = hp100_inw( DROPPED ) & 0x0fff; - lp->stats.rx_errors += val; - lp->stats.rx_over_errors += val; - val = hp100_inb( CRC ); - lp->stats.rx_errors += val; - lp->stats.rx_crc_errors += val; - val = hp100_inb( ABORT ); - lp->stats.tx_errors += val; - lp->stats.tx_aborted_errors += val; - hp100_page( PERFORMANCE ); + hp100_outw(0x4216, TRACE); + printk("hp100: %s: update-stats\n", dev->name); +#endif + + /* Note: Statistics counters clear when read. */ + hp100_page(MAC_CTRL); + val = hp100_inw(DROPPED) & 0x0fff; + lp->stats.rx_errors += val; + lp->stats.rx_over_errors += val; + val = hp100_inb(CRC); + lp->stats.rx_errors += val; + lp->stats.rx_crc_errors += val; + val = hp100_inb(ABORT); + lp->stats.tx_errors += val; + lp->stats.tx_aborted_errors += val; + hp100_page(PERFORMANCE); } -static void hp100_misc_interrupt( struct net_device *dev ) +static void hp100_misc_interrupt(struct net_device *dev) { - struct hp100_private *lp = (struct hp100_private *)dev->priv; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4216, TRACE ); - printk("hp100: %s: misc_interrupt\n", dev->name); + hp100_outw(0x4216, TRACE); + printk("hp100: %s: misc_interrupt\n", dev->name); #endif - /* Note: Statistics counters clear when read. */ - lp->stats.rx_errors++; - lp->stats.tx_errors++; + /* Note: Statistics counters clear when read. */ + lp->stats.rx_errors++; + lp->stats.tx_errors++; } -static void hp100_clear_stats( struct hp100_private *lp, int ioaddr ) +static void hp100_clear_stats(struct hp100_private *lp, int ioaddr) { - unsigned long flags; + unsigned long flags; #ifdef HP100_DEBUG_B - hp100_outw( 0x4217, TRACE ); - printk("hp100: %s: clear_stats\n", dev->name); + hp100_outw(0x4217, TRACE); + printk("hp100: %s: clear_stats\n", dev->name); #endif - spin_lock_irqsave (&lp->lock, flags); - hp100_page( MAC_CTRL ); /* get all statistics bytes */ - hp100_inw( DROPPED ); - hp100_inb( CRC ); - hp100_inb( ABORT ); - hp100_page( PERFORMANCE ); - spin_unlock_irqrestore (&lp->lock, flags); + spin_lock_irqsave(&lp->lock, flags); + hp100_page(MAC_CTRL); /* get all statistics bytes */ + hp100_inw(DROPPED); + hp100_inb(CRC); + hp100_inb(ABORT); + hp100_page(PERFORMANCE); + spin_unlock_irqrestore(&lp->lock, flags); } - + /* * multicast setup */ @@ -2209,838 +2094,821 @@ static void hp100_clear_stats( struct hp100_private *lp, int ioaddr ) /* * Set or clear the multicast filter for this adapter. */ - -static void hp100_set_multicast_list( struct net_device *dev ) + +static void hp100_set_multicast_list(struct net_device *dev) { - unsigned long flags; - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; + unsigned long flags; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4218, TRACE ); - printk("hp100: %s: set_mc_list\n", dev->name); -#endif - - spin_lock_irqsave (&lp->lock, flags); - hp100_ints_off(); - hp100_page( MAC_CTRL ); - hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 ); /* stop rx/tx */ - - if ( dev->flags & IFF_PROMISC ) - { - lp->mac2_mode = HP100_MAC2MODE6; /* promiscuous mode = get all good */ - lp->mac1_mode = HP100_MAC1MODE6; /* packets on the net */ - memset( &lp->hash_bytes, 0xff, 8 ); - } - else if ( dev->mc_count || (dev->flags&IFF_ALLMULTI) ) - { - lp->mac2_mode = HP100_MAC2MODE5; /* multicast mode = get packets for */ - lp->mac1_mode = HP100_MAC1MODE5; /* me, broadcasts and all multicasts */ -#ifdef HP100_MULTICAST_FILTER /* doesn't work!!! */ - if ( dev -> flags & IFF_ALLMULTI ) - { - /* set hash filter to receive all multicast packets */ - memset( &lp->hash_bytes, 0xff, 8 ); - } - else - { - int i, j, idx; - u_char *addrs; - struct dev_mc_list *dmi; - - memset( &lp->hash_bytes, 0x00, 8 ); + hp100_outw(0x4218, TRACE); + printk("hp100: %s: set_mc_list\n", dev->name); +#endif + + spin_lock_irqsave(&lp->lock, flags); + hp100_ints_off(); + hp100_page(MAC_CTRL); + hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1); /* stop rx/tx */ + + if (dev->flags & IFF_PROMISC) { + lp->mac2_mode = HP100_MAC2MODE6; /* promiscuous mode = get all good */ + lp->mac1_mode = HP100_MAC1MODE6; /* packets on the net */ + memset(&lp->hash_bytes, 0xff, 8); + } else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) { + lp->mac2_mode = HP100_MAC2MODE5; /* multicast mode = get packets for */ + lp->mac1_mode = HP100_MAC1MODE5; /* me, broadcasts and all multicasts */ +#ifdef HP100_MULTICAST_FILTER /* doesn't work!!! */ + if (dev->flags & IFF_ALLMULTI) { + /* set hash filter to receive all multicast packets */ + memset(&lp->hash_bytes, 0xff, 8); + } else { + int i, j, idx; + u_char *addrs; + struct dev_mc_list *dmi; + + memset(&lp->hash_bytes, 0x00, 8); #ifdef HP100_DEBUG - printk("hp100: %s: computing hash filter - mc_count = %i\n", dev -> name, dev -> mc_count ); -#endif - for ( i = 0, dmi = dev -> mc_list; i < dev -> mc_count; i++, dmi = dmi -> next ) - { - addrs = dmi -> dmi_addr; - if ( ( *addrs & 0x01 ) == 0x01 ) /* multicast address? */ - { + printk("hp100: %s: computing hash filter - mc_count = %i\n", dev->name, dev->mc_count); +#endif + for (i = 0, dmi = dev->mc_list; i < dev->mc_count; i++, dmi = dmi->next) { + addrs = dmi->dmi_addr; + if ((*addrs & 0x01) == 0x01) { /* multicast address? */ #ifdef HP100_DEBUG - printk("hp100: %s: multicast = %02x:%02x:%02x:%02x:%02x:%02x, ", - dev -> name, - addrs[ 0 ], addrs[ 1 ], addrs[ 2 ], - addrs[ 3 ], addrs[ 4 ], addrs[ 5 ] ); -#endif - for ( j = idx = 0; j < 6; j++ ) - { - idx ^= *addrs++ & 0x3f; - printk( ":%02x:", idx ); - } + printk("hp100: %s: multicast = %02x:%02x:%02x:%02x:%02x:%02x, ", + dev->name, addrs[0], addrs[1], addrs[2], + addrs[3], addrs[4], addrs[5]); +#endif + for (j = idx = 0; j < 6; j++) { + idx ^= *addrs++ & 0x3f; + printk(":%02x:", idx); + } #ifdef HP100_DEBUG - printk("idx = %i\n", idx ); + printk("idx = %i\n", idx); #endif - lp->hash_bytes[ idx >> 3 ] |= ( 1 << ( idx & 7 ) ); - } - } - } + lp->hash_bytes[idx >> 3] |= (1 << (idx & 7)); + } + } + } #else - memset( &lp->hash_bytes, 0xff, 8 ); -#endif - } - else - { - lp->mac2_mode = HP100_MAC2MODE3; /* normal mode = get packets for me */ - lp->mac1_mode = HP100_MAC1MODE3; /* and broadcasts */ - memset( &lp->hash_bytes, 0x00, 8 ); - } - - if ( ( (hp100_inb(MAC_CFG_1) & 0x0f)!=lp->mac1_mode ) || - ( hp100_inb(MAC_CFG_2)!=lp->mac2_mode ) ) - { - int i; - - hp100_outb( lp->mac2_mode, MAC_CFG_2 ); - hp100_andb( HP100_MAC1MODEMASK, MAC_CFG_1 ); /* clear mac1 mode bits */ - hp100_orb( lp->mac1_mode, MAC_CFG_1 ); /* and set the new mode */ - - hp100_page( MAC_ADDRESS ); - for ( i = 0; i < 8; i++ ) - hp100_outb( lp->hash_bytes[ i ], HASH_BYTE0 + i ); + memset(&lp->hash_bytes, 0xff, 8); +#endif + } else { + lp->mac2_mode = HP100_MAC2MODE3; /* normal mode = get packets for me */ + lp->mac1_mode = HP100_MAC1MODE3; /* and broadcasts */ + memset(&lp->hash_bytes, 0x00, 8); + } + + if (((hp100_inb(MAC_CFG_1) & 0x0f) != lp->mac1_mode) || + (hp100_inb(MAC_CFG_2) != lp->mac2_mode)) { + int i; + + hp100_outb(lp->mac2_mode, MAC_CFG_2); + hp100_andb(HP100_MAC1MODEMASK, MAC_CFG_1); /* clear mac1 mode bits */ + hp100_orb(lp->mac1_mode, MAC_CFG_1); /* and set the new mode */ + + hp100_page(MAC_ADDRESS); + for (i = 0; i < 8; i++) + hp100_outb(lp->hash_bytes[i], HASH_BYTE0 + i); #ifdef HP100_DEBUG - printk("hp100: %s: mac1 = 0x%x, mac2 = 0x%x, multicast hash = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, lp->mac1_mode, lp->mac2_mode, - lp->hash_bytes[ 0 ], lp->hash_bytes[ 1 ], - lp->hash_bytes[ 2 ], lp->hash_bytes[ 3 ], - lp->hash_bytes[ 4 ], lp->hash_bytes[ 5 ], - lp->hash_bytes[ 6 ], lp->hash_bytes[ 7 ] - ); -#endif - - if(lp->lan_type==HP100_LAN_100) - { + printk("hp100: %s: mac1 = 0x%x, mac2 = 0x%x, multicast hash = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + dev->name, lp->mac1_mode, lp->mac2_mode, + lp->hash_bytes[0], lp->hash_bytes[1], + lp->hash_bytes[2], lp->hash_bytes[3], + lp->hash_bytes[4], lp->hash_bytes[5], + lp->hash_bytes[6], lp->hash_bytes[7]); +#endif + + if (lp->lan_type == HP100_LAN_100) { #ifdef HP100_DEBUG - printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name); -#endif - lp->hub_status=hp100_login_to_vg_hub( dev, TRUE ); /* force a relogin to the hub */ - } - } - else - { - int i; - u_char old_hash_bytes[ 8 ]; - - hp100_page( MAC_ADDRESS ); - for ( i = 0; i < 8; i++ ) - old_hash_bytes[ i ] = hp100_inb( HASH_BYTE0 + i ); - if ( memcmp( old_hash_bytes, &lp->hash_bytes, 8 ) ) - { - for ( i = 0; i < 8; i++ ) - hp100_outb( lp->hash_bytes[ i ], HASH_BYTE0 + i ); + printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name); +#endif + lp->hub_status = hp100_login_to_vg_hub(dev, TRUE); /* force a relogin to the hub */ + } + } else { + int i; + u_char old_hash_bytes[8]; + + hp100_page(MAC_ADDRESS); + for (i = 0; i < 8; i++) + old_hash_bytes[i] = hp100_inb(HASH_BYTE0 + i); + if (memcmp(old_hash_bytes, &lp->hash_bytes, 8)) { + for (i = 0; i < 8; i++) + hp100_outb(lp->hash_bytes[i], HASH_BYTE0 + i); #ifdef HP100_DEBUG - printk("hp100: %s: multicast hash = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, - lp->hash_bytes[ 0 ], lp->hash_bytes[ 1 ], - lp->hash_bytes[ 2 ], lp->hash_bytes[ 3 ], - lp->hash_bytes[ 4 ], lp->hash_bytes[ 5 ], - lp->hash_bytes[ 6 ], lp->hash_bytes[ 7 ] - ); -#endif - - if(lp->lan_type==HP100_LAN_100) - { + printk("hp100: %s: multicast hash = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + dev->name, lp->hash_bytes[0], + lp->hash_bytes[1], lp->hash_bytes[2], + lp->hash_bytes[3], lp->hash_bytes[4], + lp->hash_bytes[5], lp->hash_bytes[6], + lp->hash_bytes[7]); +#endif + + if (lp->lan_type == HP100_LAN_100) { #ifdef HP100_DEBUG - printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name); -#endif - lp->hub_status=hp100_login_to_vg_hub( dev, TRUE ); /* force a relogin to the hub */ - } - } - } - - hp100_page( MAC_CTRL ); - hp100_orb( HP100_RX_EN | HP100_RX_IDLE | /* enable rx */ - HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1 ); /* enable tx */ - - hp100_page( PERFORMANCE ); - hp100_ints_on(); - spin_unlock_irqrestore (&lp->lock, flags); + printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name); +#endif + lp->hub_status = hp100_login_to_vg_hub(dev, TRUE); /* force a relogin to the hub */ + } + } + } + + hp100_page(MAC_CTRL); + hp100_orb(HP100_RX_EN | HP100_RX_IDLE | /* enable rx */ + HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1); /* enable tx */ + + hp100_page(PERFORMANCE); + hp100_ints_on(); + spin_unlock_irqrestore(&lp->lock, flags); } - /* * hardware interrupt handling */ -static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs ) +static void hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = (struct net_device *)dev_id; - struct hp100_private *lp = (struct hp100_private *)dev->priv; + struct net_device *dev = (struct net_device *) dev_id; + struct hp100_private *lp = (struct hp100_private *) dev->priv; - int ioaddr; - u_int val; + int ioaddr; + u_int val; - if ( dev == NULL ) return; - ioaddr = dev->base_addr; - - spin_lock (&lp->lock); + if (dev == NULL) + return; + ioaddr = dev->base_addr; - hp100_ints_off(); + spin_lock(&lp->lock); + + hp100_ints_off(); #ifdef HP100_DEBUG_B - hp100_outw( 0x4219, TRACE ); + hp100_outw(0x4219, TRACE); #endif - /* hp100_page( PERFORMANCE ); */ - val = hp100_inw( IRQ_STATUS ); + /* hp100_page( PERFORMANCE ); */ + val = hp100_inw(IRQ_STATUS); #ifdef HP100_DEBUG_IRQ - printk( "hp100: %s: mode=%x,IRQ_STAT=0x%.4x,RXPKTCNT=0x%.2x RXPDL=0x%.2x TXPKTCNT=0x%.2x TXPDL=0x%.2x\n", - dev->name, - lp->mode, - (u_int)val, - hp100_inb( RX_PKT_CNT ), - hp100_inb( RX_PDL ), - hp100_inb( TX_PKT_CNT ), - hp100_inb( TX_PDL ) - ); -#endif - - if(val==0) /* might be a shared interrupt */ - { - spin_unlock (&lp->lock); - hp100_ints_on(); - return; - } - /* We're only interested in those interrupts we really enabled. */ - /* val &= hp100_inw( IRQ_MASK ); */ - - /* - * RX_PDL_FILL_COMPL is set whenever a RX_PDL has been executed. A RX_PDL - * is considered executed whenever the RX_PDL data structure is no longer - * needed. - */ - if ( val & HP100_RX_PDL_FILL_COMPL ) - { - if(lp->mode==1) - hp100_rx_bm( dev ); - else - { - printk("hp100: %s: rx_pdl_fill_compl interrupt although not busmaster?\n", dev->name); + printk("hp100: %s: mode=%x,IRQ_STAT=0x%.4x,RXPKTCNT=0x%.2x RXPDL=0x%.2x TXPKTCNT=0x%.2x TXPDL=0x%.2x\n", + dev->name, lp->mode, (u_int) val, hp100_inb(RX_PKT_CNT), + hp100_inb(RX_PDL), hp100_inb(TX_PKT_CNT), hp100_inb(TX_PDL)); +#endif + + if (val == 0) { /* might be a shared interrupt */ + spin_unlock(&lp->lock); + hp100_ints_on(); + return; + } + /* We're only interested in those interrupts we really enabled. */ + /* val &= hp100_inw( IRQ_MASK ); */ + + /* + * RX_PDL_FILL_COMPL is set whenever a RX_PDL has been executed. A RX_PDL + * is considered executed whenever the RX_PDL data structure is no longer + * needed. + */ + if (val & HP100_RX_PDL_FILL_COMPL) { + if (lp->mode == 1) + hp100_rx_bm(dev); + else { + printk("hp100: %s: rx_pdl_fill_compl interrupt although not busmaster?\n", dev->name); + } } - } - - /* - * The RX_PACKET interrupt is set, when the receive packet counter is - * non zero. We use this interrupt for receiving in slave mode. In - * busmaster mode, we use it to make sure we did not miss any rx_pdl_fill - * interrupts. If rx_pdl_fill_compl is not set and rx_packet is set, then - * we somehow have missed a rx_pdl_fill_compl interrupt. - */ - - if ( val & HP100_RX_PACKET ) /* Receive Packet Counter is non zero */ - { - if(lp->mode!=1) /* non busmaster */ - hp100_rx( dev ); - else if ( !(val & HP100_RX_PDL_FILL_COMPL )) - { - /* Shouldnt happen - maybe we missed a RX_PDL_FILL Interrupt? */ - hp100_rx_bm( dev ); + + /* + * The RX_PACKET interrupt is set, when the receive packet counter is + * non zero. We use this interrupt for receiving in slave mode. In + * busmaster mode, we use it to make sure we did not miss any rx_pdl_fill + * interrupts. If rx_pdl_fill_compl is not set and rx_packet is set, then + * we somehow have missed a rx_pdl_fill_compl interrupt. + */ + + if (val & HP100_RX_PACKET) { /* Receive Packet Counter is non zero */ + if (lp->mode != 1) /* non busmaster */ + hp100_rx(dev); + else if (!(val & HP100_RX_PDL_FILL_COMPL)) { + /* Shouldnt happen - maybe we missed a RX_PDL_FILL Interrupt? */ + hp100_rx_bm(dev); + } } - } - - /* - * Ack. that we have noticed the interrupt and thereby allow next one. - * Note that this is now done after the slave rx function, since first - * acknowledging and then setting ADV_NXT_PKT caused an extra interrupt - * on the J2573. - */ - hp100_outw( val, IRQ_STATUS ); - - /* - * RX_ERROR is set when a packet is dropped due to no memory resources on - * the card or when a RCV_ERR occurs. - * TX_ERROR is set when a TX_ABORT condition occurs in the MAC->exists - * only in the 802.3 MAC and happens when 16 collisions occur during a TX - */ - if ( val & ( HP100_TX_ERROR | HP100_RX_ERROR ) ) - { + + /* + * Ack. that we have noticed the interrupt and thereby allow next one. + * Note that this is now done after the slave rx function, since first + * acknowledging and then setting ADV_NXT_PKT caused an extra interrupt + * on the J2573. + */ + hp100_outw(val, IRQ_STATUS); + + /* + * RX_ERROR is set when a packet is dropped due to no memory resources on + * the card or when a RCV_ERR occurs. + * TX_ERROR is set when a TX_ABORT condition occurs in the MAC->exists + * only in the 802.3 MAC and happens when 16 collisions occur during a TX + */ + if (val & (HP100_TX_ERROR | HP100_RX_ERROR)) { #ifdef HP100_DEBUG_IRQ - printk("hp100: %s: TX/RX Error IRQ\n", dev->name); + printk("hp100: %s: TX/RX Error IRQ\n", dev->name); #endif - hp100_update_stats( dev ); - if(lp->mode==1) - { - hp100_rxfill( dev ); - hp100_clean_txring( dev ); + hp100_update_stats(dev); + if (lp->mode == 1) { + hp100_rxfill(dev); + hp100_clean_txring(dev); + } } - } - - /* - * RX_PDA_ZERO is set when the PDA count goes from non-zero to zero. - */ - if ( (lp->mode==1)&&(val &(HP100_RX_PDA_ZERO)) ) - hp100_rxfill( dev ); - - /* - * HP100_TX_COMPLETE interrupt occurs when packet transmitted on wire - * is completed - */ - if ( (lp->mode==1) && ( val & ( HP100_TX_COMPLETE )) ) - hp100_clean_txring( dev ); - - /* - * MISC_ERROR is set when either the LAN link goes down or a detected - * bus error occurs. - */ - if ( val & HP100_MISC_ERROR ) /* New for J2585B */ - { + + /* + * RX_PDA_ZERO is set when the PDA count goes from non-zero to zero. + */ + if ((lp->mode == 1) && (val & (HP100_RX_PDA_ZERO))) + hp100_rxfill(dev); + + /* + * HP100_TX_COMPLETE interrupt occurs when packet transmitted on wire + * is completed + */ + if ((lp->mode == 1) && (val & (HP100_TX_COMPLETE))) + hp100_clean_txring(dev); + + /* + * MISC_ERROR is set when either the LAN link goes down or a detected + * bus error occurs. + */ + if (val & HP100_MISC_ERROR) { /* New for J2585B */ #ifdef HP100_DEBUG_IRQ - printk("hp100: %s: Misc. Error Interrupt - Check cabling.\n", dev->name); + printk + ("hp100: %s: Misc. Error Interrupt - Check cabling.\n", + dev->name); #endif - if(lp->mode==1) - { - hp100_clean_txring( dev ); - hp100_rxfill( dev ); + if (lp->mode == 1) { + hp100_clean_txring(dev); + hp100_rxfill(dev); + } + hp100_misc_interrupt(dev); } - hp100_misc_interrupt( dev ); - } - spin_unlock (&lp->lock); - hp100_ints_on(); + spin_unlock(&lp->lock); + hp100_ints_on(); } - /* * some misc functions */ -static void hp100_start_interface( struct net_device *dev ) +static void hp100_start_interface(struct net_device *dev) { - unsigned long flags; - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; + unsigned long flags; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4220, TRACE ); - printk("hp100: %s: hp100_start_interface\n",dev->name); -#endif - - spin_lock_irqsave (&lp->lock, flags); - - /* Ensure the adapter does not want to request an interrupt when */ - /* enabling the IRQ line to be active on the bus (i.e. not tri-stated) */ - hp100_page( PERFORMANCE ); - hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all ints */ - hp100_outw( 0xffff, IRQ_STATUS ); /* ack all IRQs */ - hp100_outw( HP100_FAKE_INT|HP100_INT_EN|HP100_RESET_LB, OPTION_LSW); - /* Un Tri-state int. TODO: Check if shared interrupts can be realised? */ - hp100_outw( HP100_TRI_INT | HP100_RESET_HB, OPTION_LSW ); - - if(lp->mode==1) - { - /* Make sure BM bit is set... */ - hp100_page(HW_MAP); - hp100_orb( HP100_BM_MASTER, BM ); - hp100_rxfill( dev ); - } - else if(lp->mode==2) - { - /* Enable memory mapping. Note: Don't do this when busmaster. */ - hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW ); - } - - hp100_page(PERFORMANCE); - hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all ints */ - hp100_outw( 0xffff, IRQ_STATUS ); /* ack IRQ */ - - /* enable a few interrupts: */ - if(lp->mode==1) /* busmaster mode */ - { - hp100_outw( HP100_RX_PDL_FILL_COMPL | - HP100_RX_PDA_ZERO | - HP100_RX_ERROR | - /* HP100_RX_PACKET | */ - /* HP100_RX_EARLY_INT | */ HP100_SET_HB | - /* HP100_TX_PDA_ZERO | */ - HP100_TX_COMPLETE | - /* HP100_MISC_ERROR | */ - HP100_TX_ERROR | HP100_SET_LB, IRQ_MASK ); - } - else - { - hp100_outw( HP100_RX_PACKET | - HP100_RX_ERROR | HP100_SET_HB | - HP100_TX_ERROR | HP100_SET_LB , IRQ_MASK ); - } - - /* Note : before hp100_set_multicast_list(), because it will play with - * spinlock itself... Jean II */ - spin_unlock_irqrestore (&lp->lock, flags); + hp100_outw(0x4220, TRACE); + printk("hp100: %s: hp100_start_interface\n", dev->name); +#endif + + spin_lock_irqsave(&lp->lock, flags); + + /* Ensure the adapter does not want to request an interrupt when */ + /* enabling the IRQ line to be active on the bus (i.e. not tri-stated) */ + hp100_page(PERFORMANCE); + hp100_outw(0xfefe, IRQ_MASK); /* mask off all ints */ + hp100_outw(0xffff, IRQ_STATUS); /* ack all IRQs */ + hp100_outw(HP100_FAKE_INT | HP100_INT_EN | HP100_RESET_LB, + OPTION_LSW); + /* Un Tri-state int. TODO: Check if shared interrupts can be realised? */ + hp100_outw(HP100_TRI_INT | HP100_RESET_HB, OPTION_LSW); + + if (lp->mode == 1) { + /* Make sure BM bit is set... */ + hp100_page(HW_MAP); + hp100_orb(HP100_BM_MASTER, BM); + hp100_rxfill(dev); + } else if (lp->mode == 2) { + /* Enable memory mapping. Note: Don't do this when busmaster. */ + hp100_outw(HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW); + } + + hp100_page(PERFORMANCE); + hp100_outw(0xfefe, IRQ_MASK); /* mask off all ints */ + hp100_outw(0xffff, IRQ_STATUS); /* ack IRQ */ + + /* enable a few interrupts: */ + if (lp->mode == 1) { /* busmaster mode */ + hp100_outw(HP100_RX_PDL_FILL_COMPL | + HP100_RX_PDA_ZERO | HP100_RX_ERROR | + /* HP100_RX_PACKET | */ + /* HP100_RX_EARLY_INT | */ HP100_SET_HB | + /* HP100_TX_PDA_ZERO | */ + HP100_TX_COMPLETE | + /* HP100_MISC_ERROR | */ + HP100_TX_ERROR | HP100_SET_LB, IRQ_MASK); + } else { + hp100_outw(HP100_RX_PACKET | + HP100_RX_ERROR | HP100_SET_HB | + HP100_TX_ERROR | HP100_SET_LB, IRQ_MASK); + } - /* Enable MAC Tx and RX, set MAC modes, ... */ - hp100_set_multicast_list( dev ); + /* Note : before hp100_set_multicast_list(), because it will play with + * spinlock itself... Jean II */ + spin_unlock_irqrestore(&lp->lock, flags); + + /* Enable MAC Tx and RX, set MAC modes, ... */ + hp100_set_multicast_list(dev); } - -static void hp100_stop_interface( struct net_device *dev ) +static void hp100_stop_interface(struct net_device *dev) { - struct hp100_private *lp = (struct hp100_private *)dev->priv; - int ioaddr = dev->base_addr; - u_int val; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + int ioaddr = dev->base_addr; + u_int val; #ifdef HP100_DEBUG_B - printk("hp100: %s: hp100_stop_interface\n",dev->name); - hp100_outw( 0x4221, TRACE ); -#endif - - if (lp->mode==1) - hp100_BM_shutdown( dev ); - else - { - /* Note: MMAP_DIS will be reenabled by start_interface */ - hp100_outw( HP100_INT_EN | HP100_RESET_LB | - HP100_TRI_INT | HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW ); - val = hp100_inw( OPTION_LSW ); - - hp100_page( MAC_CTRL ); - hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 ); - - if ( !(val & HP100_HW_RST) ) return; /* If reset, imm. return ... */ - /* ... else: busy wait until idle */ - for ( val = 0; val < 6000; val++ ) - if ( ( hp100_inb( MAC_CFG_1 ) & (HP100_TX_IDLE | HP100_RX_IDLE) ) == - (HP100_TX_IDLE | HP100_RX_IDLE) ) - { - hp100_page(PERFORMANCE); - return; - } - printk( "hp100: %s: hp100_stop_interface - timeout\n", dev->name ); - hp100_page(PERFORMANCE); - } + printk("hp100: %s: hp100_stop_interface\n", dev->name); + hp100_outw(0x4221, TRACE); +#endif + + if (lp->mode == 1) + hp100_BM_shutdown(dev); + else { + /* Note: MMAP_DIS will be reenabled by start_interface */ + hp100_outw(HP100_INT_EN | HP100_RESET_LB | + HP100_TRI_INT | HP100_MMAP_DIS | HP100_SET_HB, + OPTION_LSW); + val = hp100_inw(OPTION_LSW); + + hp100_page(MAC_CTRL); + hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1); + + if (!(val & HP100_HW_RST)) + return; /* If reset, imm. return ... */ + /* ... else: busy wait until idle */ + for (val = 0; val < 6000; val++) + if ((hp100_inb(MAC_CFG_1) & (HP100_TX_IDLE | HP100_RX_IDLE)) == (HP100_TX_IDLE | HP100_RX_IDLE)) { + hp100_page(PERFORMANCE); + return; + } + printk("hp100: %s: hp100_stop_interface - timeout\n", dev->name); + hp100_page(PERFORMANCE); + } } - -static void hp100_load_eeprom( struct net_device *dev, u_short probe_ioaddr ) +static void hp100_load_eeprom(struct net_device *dev, u_short probe_ioaddr) { - int i; - int ioaddr = probe_ioaddr > 0 ? probe_ioaddr : dev->base_addr; + int i; + int ioaddr = probe_ioaddr > 0 ? probe_ioaddr : dev->base_addr; #ifdef HP100_DEBUG_B - hp100_outw( 0x4222, TRACE ); + hp100_outw(0x4222, TRACE); #endif - hp100_page( EEPROM_CTRL ); - hp100_andw( ~HP100_EEPROM_LOAD, EEPROM_CTRL ); - hp100_orw( HP100_EEPROM_LOAD, EEPROM_CTRL ); - for ( i = 0; i < 10000; i++ ) - if ( !( hp100_inb( OPTION_MSW ) & HP100_EE_LOAD ) ) return; - printk( "hp100: %s: hp100_load_eeprom - timeout\n", dev->name ); + hp100_page(EEPROM_CTRL); + hp100_andw(~HP100_EEPROM_LOAD, EEPROM_CTRL); + hp100_orw(HP100_EEPROM_LOAD, EEPROM_CTRL); + for (i = 0; i < 10000; i++) + if (!(hp100_inb(OPTION_MSW) & HP100_EE_LOAD)) + return; + printk("hp100: %s: hp100_load_eeprom - timeout\n", dev->name); } - /* Sense connection status. * return values: LAN_10 - Connected to 10Mbit/s network * LAN_100 - Connected to 100Mbit/s network * LAN_ERR - not connected or 100Mbit/s Hub down */ -static int hp100_sense_lan( struct net_device *dev ) +static int hp100_sense_lan(struct net_device *dev) { - int ioaddr = dev->base_addr; - u_short val_VG, val_10; - struct hp100_private *lp = (struct hp100_private *)dev->priv; + int ioaddr = dev->base_addr; + u_short val_VG, val_10; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4223, TRACE ); + hp100_outw(0x4223, TRACE); #endif - hp100_page( MAC_CTRL ); - val_10 = hp100_inb( 10_LAN_CFG_1 ); - val_VG = hp100_inb( VG_LAN_CFG_1 ); - hp100_page( PERFORMANCE ); + hp100_page(MAC_CTRL); + val_10 = hp100_inb(10_LAN_CFG_1); + val_VG = hp100_inb(VG_LAN_CFG_1); + hp100_page(PERFORMANCE); #ifdef HP100_DEBUG - printk( "hp100: %s: sense_lan: val_VG = 0x%04x, val_10 = 0x%04x\n", dev->name, val_VG, val_10 ); + printk("hp100: %s: sense_lan: val_VG = 0x%04x, val_10 = 0x%04x\n", + dev->name, val_VG, val_10); #endif - if ( val_10 & HP100_LINK_BEAT_ST ) /* 10Mb connection is active */ - return HP100_LAN_10; + if (val_10 & HP100_LINK_BEAT_ST) /* 10Mb connection is active */ + return HP100_LAN_10; - if ( val_10 & HP100_AUI_ST ) /* have we BNC or AUI onboard? */ - { - val_10 |= HP100_AUI_SEL | HP100_LOW_TH; - hp100_page( MAC_CTRL ); - hp100_outb( val_10, 10_LAN_CFG_1 ); - hp100_page( PERFORMANCE ); - return HP100_LAN_10; - } + if (val_10 & HP100_AUI_ST) { /* have we BNC or AUI onboard? */ + val_10 |= HP100_AUI_SEL | HP100_LOW_TH; + hp100_page(MAC_CTRL); + hp100_outb(val_10, 10_LAN_CFG_1); + hp100_page(PERFORMANCE); + return HP100_LAN_10; + } - if ( (lp->id->id == 0x02019F022) || - (lp->id->id == 0x01042103c) || - (lp->id->id == 0x01040103c) ) - return HP100_LAN_ERR; /* Those cards don't have a 100 Mbit connector */ + if ((lp->id->id == 0x02019F022) || + (lp->id->id == 0x01042103c) || (lp->id->id == 0x01040103c)) + return HP100_LAN_ERR; /* Those cards don't have a 100 Mbit connector */ - if ( val_VG & HP100_LINK_CABLE_ST ) /* Can hear the HUBs tone. */ - return HP100_LAN_100; - return HP100_LAN_ERR; + if (val_VG & HP100_LINK_CABLE_ST) /* Can hear the HUBs tone. */ + return HP100_LAN_100; + return HP100_LAN_ERR; } - - -static int hp100_down_vg_link( struct net_device *dev ) +static int hp100_down_vg_link(struct net_device *dev) { - struct hp100_private *lp = (struct hp100_private *)dev->priv; - int ioaddr = dev->base_addr; - unsigned long time; - long savelan, newlan; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + int ioaddr = dev->base_addr; + unsigned long time; + long savelan, newlan; #ifdef HP100_DEBUG_B - hp100_outw( 0x4224, TRACE ); - printk("hp100: %s: down_vg_link\n", dev->name); -#endif - - hp100_page( MAC_CTRL ); - time=jiffies+(HZ/4); - do{ - if ( hp100_inb( VG_LAN_CFG_1 ) & HP100_LINK_CABLE_ST ) break; - } while (time_after(time, jiffies)); + hp100_outw(0x4224, TRACE); + printk("hp100: %s: down_vg_link\n", dev->name); +#endif + + hp100_page(MAC_CTRL); + time = jiffies + (HZ / 4); + do { + if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) + break; + if (!in_interrupt()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + } while (time_after(time, jiffies)); - if ( time_after_eq(jiffies, time) ) /* no signal->no logout */ - return 0; + if (time_after_eq(jiffies, time)) /* no signal->no logout */ + return 0; - /* Drop the VG Link by clearing the link up cmd and load addr.*/ + /* Drop the VG Link by clearing the link up cmd and load addr. */ - hp100_andb( ~( HP100_LOAD_ADDR| HP100_LINK_CMD), VG_LAN_CFG_1); - hp100_orb( HP100_VG_SEL, VG_LAN_CFG_1); + hp100_andb(~(HP100_LOAD_ADDR | HP100_LINK_CMD), VG_LAN_CFG_1); + hp100_orb(HP100_VG_SEL, VG_LAN_CFG_1); - /* Conditionally stall for >250ms on Link-Up Status (to go down) */ - time=jiffies+(HZ/2); - do{ - if ( !(hp100_inb( VG_LAN_CFG_1) & HP100_LINK_UP_ST) ) break; - } while(time_after(time, jiffies)); + /* Conditionally stall for >250ms on Link-Up Status (to go down) */ + time = jiffies + (HZ / 2); + do { + if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST)) + break; + if (!in_interrupt()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + } while (time_after(time, jiffies)); #ifdef HP100_DEBUG - if (time_after_eq(jiffies, time)) - printk("hp100: %s: down_vg_link: Link does not go down?\n", dev->name); -#endif - - /* To prevent condition where Rev 1 VG MAC and old hubs do not complete */ - /* logout under traffic (even though all the status bits are cleared), */ - /* do this workaround to get the Rev 1 MAC in its idle state */ - if ( lp->chip==HP100_CHIPID_LASSEN ) - { - /* Reset VG MAC to insure it leaves the logoff state even if */ - /* the Hub is still emitting tones */ - hp100_andb(~HP100_VG_RESET, VG_LAN_CFG_1); - udelay(1500); /* wait for >1ms */ - hp100_orb(HP100_VG_RESET, VG_LAN_CFG_1); /* Release Reset */ - udelay(1500); - } - - /* New: For lassen, switch to 10 Mbps mac briefly to clear training ACK */ - /* to get the VG mac to full reset. This is not req.d with later chips */ - /* Note: It will take the between 1 and 2 seconds for the VG mac to be */ - /* selected again! This will be left to the connect hub function to */ - /* perform if desired. */ - if (lp->chip==HP100_CHIPID_LASSEN) - { - /* Have to write to 10 and 100VG control registers simultaneously */ - savelan=newlan=hp100_inl(10_LAN_CFG_1); /* read 10+100 LAN_CFG regs */ - newlan &= ~(HP100_VG_SEL<<16); - newlan |= (HP100_DOT3_MAC)<<8; - hp100_andb( ~HP100_AUTO_MODE, MAC_CFG_3); /* Autosel off */ - hp100_outl(newlan, 10_LAN_CFG_1); - - /* Conditionally stall for 5sec on VG selected. */ - time=jiffies+(HZ*5); - do{ - if( !(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST) ) break; - } while(time_after(time, jiffies)); - - hp100_orb( HP100_AUTO_MODE, MAC_CFG_3); /* Autosel back on */ - hp100_outl(savelan, 10_LAN_CFG_1); - } - - time=jiffies+(3*HZ); /* Timeout 3s */ - do { - if ( (hp100_inb( VG_LAN_CFG_1 )&HP100_LINK_CABLE_ST) == 0) break; - } while (time_after(time, jiffies)); - - if(time_before_eq(time, jiffies)) - { + if (time_after_eq(jiffies, time)) + printk("hp100: %s: down_vg_link: Link does not go down?\n", dev->name); +#endif + + /* To prevent condition where Rev 1 VG MAC and old hubs do not complete */ + /* logout under traffic (even though all the status bits are cleared), */ + /* do this workaround to get the Rev 1 MAC in its idle state */ + if (lp->chip == HP100_CHIPID_LASSEN) { + /* Reset VG MAC to insure it leaves the logoff state even if */ + /* the Hub is still emitting tones */ + hp100_andb(~HP100_VG_RESET, VG_LAN_CFG_1); + udelay(1500); /* wait for >1ms */ + hp100_orb(HP100_VG_RESET, VG_LAN_CFG_1); /* Release Reset */ + udelay(1500); + } + + /* New: For lassen, switch to 10 Mbps mac briefly to clear training ACK */ + /* to get the VG mac to full reset. This is not req.d with later chips */ + /* Note: It will take the between 1 and 2 seconds for the VG mac to be */ + /* selected again! This will be left to the connect hub function to */ + /* perform if desired. */ + if (lp->chip == HP100_CHIPID_LASSEN) { + /* Have to write to 10 and 100VG control registers simultaneously */ + savelan = newlan = hp100_inl(10_LAN_CFG_1); /* read 10+100 LAN_CFG regs */ + newlan &= ~(HP100_VG_SEL << 16); + newlan |= (HP100_DOT3_MAC) << 8; + hp100_andb(~HP100_AUTO_MODE, MAC_CFG_3); /* Autosel off */ + hp100_outl(newlan, 10_LAN_CFG_1); + + /* Conditionally stall for 5sec on VG selected. */ + time = jiffies + (HZ * 5); + do { + if (!(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST)) + break; + if (!in_interrupt()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + } while (time_after(time, jiffies)); + + hp100_orb(HP100_AUTO_MODE, MAC_CFG_3); /* Autosel back on */ + hp100_outl(savelan, 10_LAN_CFG_1); + } + + time = jiffies + (3 * HZ); /* Timeout 3s */ + do { + if ((hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) == 0) + break; + if (!in_interrupt()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + } while (time_after(time, jiffies)); + + if (time_before_eq(time, jiffies)) { #ifdef HP100_DEBUG - printk( "hp100: %s: down_vg_link: timeout\n", dev->name ); -#endif - return -EIO; - } - - time=jiffies+(2*HZ); /* This seems to take a while.... */ - do {} while (time_after(time, jiffies)); - - return 0; + printk("hp100: %s: down_vg_link: timeout\n", dev->name); +#endif + return -EIO; + } + + time = jiffies + (2 * HZ); /* This seems to take a while.... */ + do { + if (!in_interrupt()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + } while (time_after(time, jiffies)); + + return 0; } - -static int hp100_login_to_vg_hub( struct net_device *dev, u_short force_relogin ) +static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin) { - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; - u_short val=0; - unsigned long time; - int startst; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; + u_short val = 0; + unsigned long time; + int startst; #ifdef HP100_DEBUG_B - hp100_outw( 0x4225, TRACE ); - printk("hp100: %s: login_to_vg_hub\n", dev->name); -#endif - - /* Initiate a login sequence iff VG MAC is enabled and either Load Address - * bit is zero or the force relogin flag is set (e.g. due to MAC address or - * promiscuous mode change) - */ - hp100_page( MAC_CTRL ); - startst=hp100_inb( VG_LAN_CFG_1 ); - if((force_relogin==TRUE)||(hp100_inb( MAC_CFG_4 )&HP100_MAC_SEL_ST)) - { -#ifdef HP100_DEBUG_TRAINING - printk("hp100: %s: Start training\n", dev->name); + hp100_outw(0x4225, TRACE); + printk("hp100: %s: login_to_vg_hub\n", dev->name); #endif - /* Ensure VG Reset bit is 1 (i.e., do not reset)*/ - hp100_orb( HP100_VG_RESET , VG_LAN_CFG_1 ); - - /* If Lassen AND auto-select-mode AND VG tones were sensed on */ - /* entry then temporarily put them into force 100Mbit mode */ - if((lp->chip==HP100_CHIPID_LASSEN)&&( startst & HP100_LINK_CABLE_ST ) ) - hp100_andb( ~HP100_DOT3_MAC, 10_LAN_CFG_2 ); - - /* Drop the VG link by zeroing Link Up Command and Load Address */ - hp100_andb( ~(HP100_LINK_CMD/* |HP100_LOAD_ADDR */), VG_LAN_CFG_1); - + /* Initiate a login sequence iff VG MAC is enabled and either Load Address + * bit is zero or the force relogin flag is set (e.g. due to MAC address or + * promiscuous mode change) + */ + hp100_page(MAC_CTRL); + startst = hp100_inb(VG_LAN_CFG_1); + if ((force_relogin == TRUE) || (hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST)) { #ifdef HP100_DEBUG_TRAINING - printk("hp100: %s: Bring down the link\n", dev->name); + printk("hp100: %s: Start training\n", dev->name); #endif - /* Wait for link to drop */ - time = jiffies + (HZ/10); - do { - if (~(hp100_inb( VG_LAN_CFG_1 )& HP100_LINK_UP_ST) ) break; - } while (time_after(time, jiffies)); + /* Ensure VG Reset bit is 1 (i.e., do not reset) */ + hp100_orb(HP100_VG_RESET, VG_LAN_CFG_1); - /* Start an addressed training and optionally request promiscuous port */ - if ( (dev->flags) & IFF_PROMISC ) - { - hp100_orb( HP100_PROM_MODE, VG_LAN_CFG_2); - if(lp->chip==HP100_CHIPID_LASSEN) - hp100_orw( HP100_MACRQ_PROMSC, TRAIN_REQUEST ); - } - else - { - hp100_andb( ~HP100_PROM_MODE, VG_LAN_CFG_2); - /* For ETR parts we need to reset the prom. bit in the training - * register, otherwise promiscious mode won't be disabled. - */ - if(lp->chip==HP100_CHIPID_LASSEN) - { - hp100_andw( ~HP100_MACRQ_PROMSC, TRAIN_REQUEST ); - } - } + /* If Lassen AND auto-select-mode AND VG tones were sensed on */ + /* entry then temporarily put them into force 100Mbit mode */ + if ((lp->chip == HP100_CHIPID_LASSEN) && (startst & HP100_LINK_CABLE_ST)) + hp100_andb(~HP100_DOT3_MAC, 10_LAN_CFG_2); + + /* Drop the VG link by zeroing Link Up Command and Load Address */ + hp100_andb(~(HP100_LINK_CMD /* |HP100_LOAD_ADDR */ ), VG_LAN_CFG_1); - /* With ETR parts, frame format request bits can be set. */ - if(lp->chip==HP100_CHIPID_LASSEN) - hp100_orb( HP100_MACRQ_FRAMEFMT_EITHER, TRAIN_REQUEST); - - hp100_orb( HP100_LINK_CMD|HP100_LOAD_ADDR|HP100_VG_RESET, VG_LAN_CFG_1); - - /* Note: Next wait could be omitted for Hood and earlier chips under */ - /* certain circumstances */ - /* TODO: check if hood/earlier and skip wait. */ - - /* Wait for either short timeout for VG tones or long for login */ - /* Wait for the card hardware to signalise link cable status ok... */ - hp100_page( MAC_CTRL ); - time = jiffies + ( 1*HZ ); /* 1 sec timeout for cable st */ - do { - if ( hp100_inb( VG_LAN_CFG_1 ) & HP100_LINK_CABLE_ST ) break; - } while ( time_before(jiffies, time) ); - - if ( time_after_eq(jiffies, time) ) - { #ifdef HP100_DEBUG_TRAINING - printk( "hp100: %s: Link cable status not ok? Training aborted.\n", dev->name ); -#endif - } - else - { + printk("hp100: %s: Bring down the link\n", dev->name); +#endif + + /* Wait for link to drop */ + time = jiffies + (HZ / 10); + do { + if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST)) + break; + if (!in_interrupt()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + } while (time_after(time, jiffies)); + + /* Start an addressed training and optionally request promiscuous port */ + if ((dev->flags) & IFF_PROMISC) { + hp100_orb(HP100_PROM_MODE, VG_LAN_CFG_2); + if (lp->chip == HP100_CHIPID_LASSEN) + hp100_orw(HP100_MACRQ_PROMSC, TRAIN_REQUEST); + } else { + hp100_andb(~HP100_PROM_MODE, VG_LAN_CFG_2); + /* For ETR parts we need to reset the prom. bit in the training + * register, otherwise promiscious mode won't be disabled. + */ + if (lp->chip == HP100_CHIPID_LASSEN) { + hp100_andw(~HP100_MACRQ_PROMSC, TRAIN_REQUEST); + } + } + + /* With ETR parts, frame format request bits can be set. */ + if (lp->chip == HP100_CHIPID_LASSEN) + hp100_orb(HP100_MACRQ_FRAMEFMT_EITHER, TRAIN_REQUEST); + + hp100_orb(HP100_LINK_CMD | HP100_LOAD_ADDR | HP100_VG_RESET, VG_LAN_CFG_1); + + /* Note: Next wait could be omitted for Hood and earlier chips under */ + /* certain circumstances */ + /* TODO: check if hood/earlier and skip wait. */ + + /* Wait for either short timeout for VG tones or long for login */ + /* Wait for the card hardware to signalise link cable status ok... */ + hp100_page(MAC_CTRL); + time = jiffies + (1 * HZ); /* 1 sec timeout for cable st */ + do { + if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) + break; + if (!in_interrupt()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + } while (time_before(jiffies, time)); + + if (time_after_eq(jiffies, time)) { #ifdef HP100_DEBUG_TRAINING - printk( "hp100: %s: HUB tones detected. Trying to train.\n", dev->name); + printk("hp100: %s: Link cable status not ok? Training aborted.\n", dev->name); #endif - - time = jiffies + ( 2*HZ ); /* again a timeout */ - do { - val = hp100_inb( VG_LAN_CFG_1 ); - if ( (val & ( HP100_LINK_UP_ST )) ) - { + } else { #ifdef HP100_DEBUG_TRAINING - printk( "hp100: %s: Passed training.\n", dev->name); + printk + ("hp100: %s: HUB tones detected. Trying to train.\n", + dev->name); #endif - break; - } - } while ( time_after(time, jiffies) ); - } - - /* If LINK_UP_ST is set, then we are logged into the hub. */ - if ( time_before_eq(jiffies, time) && (val & HP100_LINK_UP_ST) ) - { + + time = jiffies + (2 * HZ); /* again a timeout */ + do { + val = hp100_inb(VG_LAN_CFG_1); + if ((val & (HP100_LINK_UP_ST))) { #ifdef HP100_DEBUG_TRAINING - printk( "hp100: %s: Successfully logged into the HUB.\n", dev->name); - if(lp->chip==HP100_CHIPID_LASSEN) - { - val = hp100_inw(TRAIN_ALLOW); - printk( "hp100: %s: Card supports 100VG MAC Version \"%s\" ", - dev->name,(hp100_inw(TRAIN_REQUEST)&HP100_CARD_MACVER) ? "802.12" : "Pre"); - printk( "Driver will use MAC Version \"%s\"\n", - ( val & HP100_HUB_MACVER) ? "802.12" : "Pre" ); - printk( "hp100: %s: Frame format is %s.\n",dev->name,(val&HP100_MALLOW_FRAMEFMT)?"802.5":"802.3"); - } -#endif - } - else - { - /* If LINK_UP_ST is not set, login was not successful */ - printk("hp100: %s: Problem logging into the HUB.\n",dev->name); - if(lp->chip==HP100_CHIPID_LASSEN) - { - /* Check allowed Register to find out why there is a problem. */ - val = hp100_inw( TRAIN_ALLOW ); /* wont work on non-ETR card */ + printk("hp100: %s: Passed training.\n", dev->name); +#endif + break; + } + if (!in_interrupt()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + } while (time_after(time, jiffies)); + } + + /* If LINK_UP_ST is set, then we are logged into the hub. */ + if (time_before_eq(jiffies, time) && (val & HP100_LINK_UP_ST)) { +#ifdef HP100_DEBUG_TRAINING + printk("hp100: %s: Successfully logged into the HUB.\n", dev->name); + if (lp->chip == HP100_CHIPID_LASSEN) { + val = hp100_inw(TRAIN_ALLOW); + printk("hp100: %s: Card supports 100VG MAC Version \"%s\" ", + dev->name, (hp100_inw(TRAIN_REQUEST) & HP100_CARD_MACVER) ? "802.12" : "Pre"); + printk("Driver will use MAC Version \"%s\"\n", (val & HP100_HUB_MACVER) ? "802.12" : "Pre"); + printk("hp100: %s: Frame format is %s.\n", dev->name, (val & HP100_MALLOW_FRAMEFMT) ? "802.5" : "802.3"); + } +#endif + } else { + /* If LINK_UP_ST is not set, login was not successful */ + printk("hp100: %s: Problem logging into the HUB.\n", dev->name); + if (lp->chip == HP100_CHIPID_LASSEN) { + /* Check allowed Register to find out why there is a problem. */ + val = hp100_inw(TRAIN_ALLOW); /* wont work on non-ETR card */ #ifdef HP100_DEBUG_TRAINING - printk("hp100: %s: MAC Configuration requested: 0x%04x, HUB allowed: 0x%04x\n", dev->name, hp100_inw(TRAIN_REQUEST), val); -#endif - if ( val & HP100_MALLOW_ACCDENIED ) - printk("hp100: %s: HUB access denied.\n", dev->name); - if ( val & HP100_MALLOW_CONFIGURE ) - printk("hp100: %s: MAC Configuration is incompatible with the Network.\n", dev->name); - if ( val & HP100_MALLOW_DUPADDR ) - printk("hp100: %s: Duplicate MAC Address on the Network.\n", dev->name); - } - } - - /* If we have put the chip into forced 100 Mbit mode earlier, go back */ - /* to auto-select mode */ - - if( (lp->chip==HP100_CHIPID_LASSEN)&&(startst & HP100_LINK_CABLE_ST) ) - { - hp100_page( MAC_CTRL ); - hp100_orb( HP100_DOT3_MAC, 10_LAN_CFG_2 ); - } - - val=hp100_inb(VG_LAN_CFG_1); - - /* Clear the MISC_ERROR Interrupt, which might be generated when doing the relogin */ - hp100_page(PERFORMANCE); - hp100_outw( HP100_MISC_ERROR, IRQ_STATUS); - - if (val&HP100_LINK_UP_ST) - return(0); /* login was ok */ - else - { - printk("hp100: %s: Training failed.\n", dev->name); - hp100_down_vg_link( dev ); - return -EIO; - } - } - /* no forced relogin & already link there->no training. */ - return -EIO; + printk("hp100: %s: MAC Configuration requested: 0x%04x, HUB allowed: 0x%04x\n", dev->name, hp100_inw(TRAIN_REQUEST), val); +#endif + if (val & HP100_MALLOW_ACCDENIED) + printk("hp100: %s: HUB access denied.\n", dev->name); + if (val & HP100_MALLOW_CONFIGURE) + printk("hp100: %s: MAC Configuration is incompatible with the Network.\n", dev->name); + if (val & HP100_MALLOW_DUPADDR) + printk("hp100: %s: Duplicate MAC Address on the Network.\n", dev->name); + } + } + + /* If we have put the chip into forced 100 Mbit mode earlier, go back */ + /* to auto-select mode */ + + if ((lp->chip == HP100_CHIPID_LASSEN) && (startst & HP100_LINK_CABLE_ST)) { + hp100_page(MAC_CTRL); + hp100_orb(HP100_DOT3_MAC, 10_LAN_CFG_2); + } + + val = hp100_inb(VG_LAN_CFG_1); + + /* Clear the MISC_ERROR Interrupt, which might be generated when doing the relogin */ + hp100_page(PERFORMANCE); + hp100_outw(HP100_MISC_ERROR, IRQ_STATUS); + + if (val & HP100_LINK_UP_ST) + return (0); /* login was ok */ + else { + printk("hp100: %s: Training failed.\n", dev->name); + hp100_down_vg_link(dev); + return -EIO; + } + } + /* no forced relogin & already link there->no training. */ + return -EIO; } - -static void hp100_cascade_reset( struct net_device *dev, u_short enable ) +static void hp100_cascade_reset(struct net_device *dev, u_short enable) { - int ioaddr = dev->base_addr; - struct hp100_private *lp = (struct hp100_private *)dev->priv; - int i; + int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B - hp100_outw( 0x4226, TRACE ); - printk("hp100: %s: cascade_reset\n", dev->name); -#endif - - if (enable==TRUE) - { - hp100_outw( HP100_HW_RST | HP100_RESET_LB, OPTION_LSW ); - if(lp->chip==HP100_CHIPID_LASSEN) - { - /* Lassen requires a PCI transmit fifo reset */ - hp100_page( HW_MAP ); - hp100_andb( ~HP100_PCI_RESET, PCICTRL2 ); - hp100_orb( HP100_PCI_RESET, PCICTRL2 ); - /* Wait for min. 300 ns */ - /* we cant use jiffies here, because it may be */ - /* that we have disabled the timer... */ - for (i=0; i<0xffff; i++); - hp100_andb( ~HP100_PCI_RESET, PCICTRL2 ); - hp100_page( PERFORMANCE ); - } - } - else - { /* bring out of reset */ - hp100_outw(HP100_HW_RST|HP100_SET_LB, OPTION_LSW); - for (i=0; i<0xffff; i++ ); - hp100_page(PERFORMANCE); - } + hp100_outw(0x4226, TRACE); + printk("hp100: %s: cascade_reset\n", dev->name); +#endif + + if (enable == TRUE) { + hp100_outw(HP100_HW_RST | HP100_RESET_LB, OPTION_LSW); + if (lp->chip == HP100_CHIPID_LASSEN) { + /* Lassen requires a PCI transmit fifo reset */ + hp100_page(HW_MAP); + hp100_andb(~HP100_PCI_RESET, PCICTRL2); + hp100_orb(HP100_PCI_RESET, PCICTRL2); + /* Wait for min. 300 ns */ + /* we cant use jiffies here, because it may be */ + /* that we have disabled the timer... */ + udelay(400); + hp100_andb(~HP100_PCI_RESET, PCICTRL2); + hp100_page(PERFORMANCE); + } + } else { /* bring out of reset */ + hp100_outw(HP100_HW_RST | HP100_SET_LB, OPTION_LSW); + udelay(400); + hp100_page(PERFORMANCE); + } } -#ifdef HP100_DEBUG -void hp100_RegisterDump( struct net_device *dev ) +#ifdef HP100_DEBUG +void hp100_RegisterDump(struct net_device *dev) { - int ioaddr=dev->base_addr; - int Page; - int Register; - - /* Dump common registers */ - printk("hp100: %s: Cascade Register Dump\n", dev->name); - printk("hardware id #1: 0x%.2x\n",hp100_inb(HW_ID)); - printk("hardware id #2/paging: 0x%.2x\n",hp100_inb(PAGING)); - printk("option #1: 0x%.4x\n",hp100_inw(OPTION_LSW)); - printk("option #2: 0x%.4x\n",hp100_inw(OPTION_MSW)); - - /* Dump paged registers */ - for (Page = 0; Page < 8; Page++) - { - /* Dump registers */ - printk("page: 0x%.2x\n",Page); - outw( Page, ioaddr+0x02); - for (Register = 0x8; Register < 0x22; Register += 2) - { - /* Display Register contents except data port */ - if (((Register != 0x10) && (Register != 0x12)) || (Page > 0)) - { - printk("0x%.2x = 0x%.4x\n",Register,inw(ioaddr+Register)); - } + int ioaddr = dev->base_addr; + int Page; + int Register; + + /* Dump common registers */ + printk("hp100: %s: Cascade Register Dump\n", dev->name); + printk("hardware id #1: 0x%.2x\n", hp100_inb(HW_ID)); + printk("hardware id #2/paging: 0x%.2x\n", hp100_inb(PAGING)); + printk("option #1: 0x%.4x\n", hp100_inw(OPTION_LSW)); + printk("option #2: 0x%.4x\n", hp100_inw(OPTION_MSW)); + + /* Dump paged registers */ + for (Page = 0; Page < 8; Page++) { + /* Dump registers */ + printk("page: 0x%.2x\n", Page); + outw(Page, ioaddr + 0x02); + for (Register = 0x8; Register < 0x22; Register += 2) { + /* Display Register contents except data port */ + if (((Register != 0x10) && (Register != 0x12)) || (Page > 0)) { + printk("0x%.2x = 0x%.4x\n", Register, inw(ioaddr + Register)); + } + } } - } - hp100_page(PERFORMANCE); + hp100_page(PERFORMANCE); } #endif - /* * module section */ - + #ifdef MODULE +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, " + "Siegfried \"Frieder\" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>"); +MODULE_DESCRIPTION("HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters"); + +/* + * Note: if you have more than five 100vg cards in your pc, feel free to + * increase this value + */ + +#define HP100_DEVICES 5 + +/* + * Note: to register three eisa or pci devices, use: + * option hp100 hp100_port=0,0,0 + * to register one card at io 0x280 as eth239, use: + * option hp100 hp100_port=0x280 hp100_name=eth239 + */ + /* Parameters set by insmod */ -static int hp100_port[5] = { 0, -1, -1, -1, -1 }; -MODULE_PARM(hp100_port, "1-5i"); +static int hp100_port[HP100_DEVICES] = { 0, [1 ... (HP100_DEVICES-1)] = -1 }; +MODULE_PARM(hp100_port, "1-" __MODULE_STRING(HP100_DEVICES) "i"); -/* Allocate 5 string of length IFNAMSIZ, one string for each device */ -static char hp100_name[5][IFNAMSIZ] = { "", "", "", "", "" }; -/* Allow insmod to write those 5 strings individually */ -MODULE_PARM(hp100_name, "1-5c" __MODULE_STRING(IFNAMSIZ)); +/* Allocate HP100_DEVICES strings of length IFNAMSIZ, one string for each device */ +static char hp100_name[HP100_DEVICES][IFNAMSIZ] = { "", "", "", "", "" }; +/* Allow insmod to write those HP100_DEVICES strings individually */ +MODULE_PARM(hp100_name, "1-" __MODULE_STRING(HP100_DEVICES) "c" __MODULE_STRING(IFNAMSIZ)); /* List of devices */ -static struct net_device *hp100_devlist[5]; +static struct net_device *hp100_devlist[HP100_DEVICES]; static void release_dev(int i) { struct net_device *d = hp100_devlist[i]; - struct hp100_private *p = (struct hp100_private *)d->priv; + struct hp100_private *p = (struct hp100_private *) d->priv; unregister_netdev(d); release_region(d->base_addr, HP100_REGION_SIZE); - if (p->mode == 1) /* busmaster */ - kfree(p->page_vaddr); + if (p->mode == 1) /* busmaster */ + kfree(p->page_vaddr); if (p->mem_ptr_virt) iounmap(p->mem_ptr_virt); kfree(d->priv); @@ -3049,78 +2917,66 @@ static void release_dev(int i) hp100_devlist[i] = NULL; } -/* - * Note: if you have more than five 100vg cards in your pc, feel free to - * increase this value - */ - -/* - * Note: to register three eisa or pci devices, use: - * option hp100 hp100_port=0,0,0 - * to register one card at io 0x280 as eth239, use: - * option hp100 hp100_port=0x280 hp100_name=eth239 - */ - -int init_module( void ) +static int __init hp100_module_init(void) { - int i, cards; - - if (hp100_port == 0 && !EISA_bus && !pcibios_present()) - printk("hp100: You should not use auto-probing with insmod!\n"); - - /* Loop on all possible base addresses */ - i = -1; cards = 0; - while((hp100_port[++i] != -1) && (i < 5)) - { - /* Create device and set basics args */ - hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL); - if (!hp100_devlist[i]) - goto fail; - memset(hp100_devlist[i], 0x00, sizeof(struct net_device)); + int i, cards; + + if (hp100_port == 0 && !EISA_bus && !pcibios_present()) + printk("hp100: You should not use auto-probing with insmod!\n"); + + /* Loop on all possible base addresses */ + i = -1; + cards = 0; + while ((hp100_port[++i] != -1) && (i < HP100_DEVICES)) { + /* Create device and set basics args */ + hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL); + if (!hp100_devlist[i]) + goto fail; + memset(hp100_devlist[i], 0x00, sizeof(struct net_device)); #if LINUX_VERSION_CODE >= 0x020362 /* 2.3.99-pre7 */ - memcpy(hp100_devlist[i]->name, hp100_name[i], IFNAMSIZ); /* Copy name */ + memcpy(hp100_devlist[i]->name, hp100_name[i], IFNAMSIZ); /* Copy name */ #else - hp100_devlist[i]->name = hp100_name[i]; -#endif /* LINUX_VERSION_CODE >= 0x020362 */ - hp100_devlist[i]->base_addr = hp100_port[i]; - hp100_devlist[i]->init = &hp100_probe; - - /* Try to create the device */ - if(register_netdev(hp100_devlist[i]) != 0) - { - /* DeAllocate everything */ - /* Note: if dev->priv is mallocated, there is no way to fail */ - kfree(hp100_devlist[i]); - hp100_devlist[i] = (struct net_device *) NULL; - } - else - cards++; - } /* Loop over all devices */ - - return cards > 0 ? 0 : -ENODEV; - fail: - while (cards && --i) - if (hp100_devlist[i]) { - release_dev(i); - --cards; - } - return -ENOMEM; + hp100_devlist[i]->name = hp100_name[i]; +#endif /* LINUX_VERSION_CODE >= 0x020362 */ + hp100_devlist[i]->base_addr = hp100_port[i]; + hp100_devlist[i]->init = &hp100_probe; + + /* Try to create the device */ + if (register_netdev(hp100_devlist[i]) != 0) { + /* DeAllocate everything */ + /* Note: if dev->priv is mallocated, there is no way to fail */ + kfree(hp100_devlist[i]); + hp100_devlist[i] = (struct net_device *) NULL; + } else + cards++; + } /* Loop over all devices */ + + return cards > 0 ? 0 : -ENODEV; + fail: + while (cards && --i) + if (hp100_devlist[i]) { + release_dev(i); + --cards; + } + return -ENOMEM; } -void cleanup_module( void ) +static void __exit hp100_module_exit(void) { - int i; + int i; - /* TODO: Check if all skb's are released/freed. */ - for(i = 0; i < 5; i++) - if(hp100_devlist[i] != (struct net_device *) NULL) - release_dev(i); + /* TODO: Check if all skb's are released/freed. */ + for (i = 0; i < HP100_DEVICES; i++) + if (hp100_devlist[i] != (struct net_device *) NULL) + release_dev(i); } -#endif /* MODULE */ +module_init(hp100_module_init) +module_exit(hp100_module_exit) + +#endif /* MODULE */ - /* * Local variables: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c hp100.c" diff --git a/drivers/net/irda/actisys.c b/drivers/net/irda/actisys.c index e7cf517f48d9..cde9f41b2a2a 100644 --- a/drivers/net/irda/actisys.c +++ b/drivers/net/irda/actisys.c @@ -272,6 +272,8 @@ static int actisys_reset(struct irda_task *task) #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no> - Jean Tourrilhes <jt@hpl.hp.com>"); MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver"); +MODULE_LICENSE("GPL"); + /* * Function init_module (void) diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index 3db8ecf8575d..4aaef91ab021 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -2290,6 +2290,8 @@ static void FIR2SIR(int iobase) #ifdef MODULE MODULE_AUTHOR("Benjamin Kong <benjamin_kong@ali.com.tw>"); MODULE_DESCRIPTION("ALi FIR Controller Driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "1-4i"); MODULE_PARM_DESC(io, "Base I/O addresses"); diff --git a/drivers/net/irda/esi.c b/drivers/net/irda/esi.c index 100b0772db13..d39642a8e267 100644 --- a/drivers/net/irda/esi.c +++ b/drivers/net/irda/esi.c @@ -136,6 +136,7 @@ static int esi_reset(struct irda_task *task) #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Extended Systems JetEye PC dongle driver"); +MODULE_LICENSE("GPL"); /* * Function init_module (void) diff --git a/drivers/net/irda/girbil.c b/drivers/net/irda/girbil.c index 37d0291c8f43..23e1e4f23c47 100644 --- a/drivers/net/irda/girbil.c +++ b/drivers/net/irda/girbil.c @@ -234,6 +234,8 @@ static int girbil_reset(struct irda_task *task) #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver"); +MODULE_LICENSE("GPL"); + /* * Function init_module (void) diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 3effbc2067ab..53c1c27c4fca 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -1035,6 +1035,8 @@ MODULE_PARM_DESC(irq, "IRQ lines"); MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode"); +MODULE_LICENSE("GPL"); + void cleanup_module(void) { diff --git a/drivers/net/irda/irtty.c b/drivers/net/irda/irtty.c index dce8561435bc..7452310e8119 100644 --- a/drivers/net/irda/irtty.c +++ b/drivers/net/irda/irtty.c @@ -1049,6 +1049,8 @@ static struct net_device_stats *irtty_net_get_stats(struct net_device *dev) MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("IrDA TTY device driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(qos_mtt_bits, "i"); MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); diff --git a/drivers/net/irda/litelink.c b/drivers/net/irda/litelink.c index 7120b5647063..f2c6d85d8361 100644 --- a/drivers/net/irda/litelink.c +++ b/drivers/net/irda/litelink.c @@ -166,6 +166,8 @@ static int litelink_reset(struct irda_task *task) #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Parallax Litelink dongle driver"); +MODULE_LICENSE("GPL"); + /* * Function init_module (void) diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index a51489955334..308b64bccf02 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -2042,6 +2042,8 @@ static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data) #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("NSC IrDA Device Driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(qos_mtt_bits, "i"); MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); diff --git a/drivers/net/irda/old_belkin.c b/drivers/net/irda/old_belkin.c index dbbaa50a1d69..96a3c781aba0 100644 --- a/drivers/net/irda/old_belkin.c +++ b/drivers/net/irda/old_belkin.c @@ -152,6 +152,8 @@ static int old_belkin_reset(struct irda_task *task) #ifdef MODULE MODULE_AUTHOR("Jean Tourrilhes <jt@hpl.hp.com>"); MODULE_DESCRIPTION("Belkin (old) SmartBeam dongle driver"); +MODULE_LICENSE("GPL"); + /* * Function init_module (void) diff --git a/drivers/net/irda/smc-ircc.c b/drivers/net/irda/smc-ircc.c index 14b2af4325fa..33c86a4172a8 100644 --- a/drivers/net/irda/smc-ircc.c +++ b/drivers/net/irda/smc-ircc.c @@ -99,7 +99,7 @@ static int ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data); #define SERx4 8 /* SuperIO Chip supports 115,2 KBaud * 4=460,8 KBaud */ /* These are the currently known SMC SuperIO chipsets */ -static const smc_chip_t __init fdc_chips_flat[]= +static smc_chip_t __initdata fdc_chips_flat[]= { /* Base address 0x3f0 or 0x370 */ { "37C44", KEY55_1|NoIRDA, 0x00, 0x00 }, /* This chip can not detected */ @@ -113,7 +113,7 @@ static const smc_chip_t __init fdc_chips_flat[]= { NULL } }; -static const smc_chip_t __init fdc_chips_paged[]= +static smc_chip_t __initdata fdc_chips_paged[]= { /* Base address 0x3f0 or 0x370 */ { "37B72X", KEY55_1|SIR|SERx4, 0x4c, 0x00 }, @@ -132,7 +132,7 @@ static const smc_chip_t __init fdc_chips_paged[]= { NULL } }; -static const smc_chip_t __init lpc_chips_flat[]= +static smc_chip_t __initdata lpc_chips_flat[]= { /* Base address 0x2E or 0x4E */ { "47N227", KEY55_1|FIR|SERx4, 0x5a, 0x00 }, @@ -140,7 +140,7 @@ static const smc_chip_t __init lpc_chips_flat[]= { NULL } }; -static const smc_chip_t __init lpc_chips_paged[]= +static smc_chip_t __initdata lpc_chips_paged[]= { /* Base address 0x2E or 0x4E */ { "47B27X", KEY55_1|SIR|SERx4, 0x51, 0x00 }, @@ -1219,6 +1219,8 @@ module_exit(smc_cleanup); MODULE_AUTHOR("Thomas Davis <tadavis@jps.net>"); MODULE_DESCRIPTION("SMC IrCC controller driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(ircc_dma, "1i"); MODULE_PARM_DESC(ircc_dma, "DMA channel"); MODULE_PARM(ircc_irq, "1i"); diff --git a/drivers/net/irda/tekram.c b/drivers/net/irda/tekram.c index c6aa648c0195..10f53f887350 100644 --- a/drivers/net/irda/tekram.c +++ b/drivers/net/irda/tekram.c @@ -267,6 +267,7 @@ int tekram_reset(struct irda_task *task) #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver"); +MODULE_LICENSE("GPL"); /* * Function init_module (void) diff --git a/drivers/net/irda/toshoboe.c b/drivers/net/irda/toshoboe.c index c01376a24905..8e0a750aeca5 100644 --- a/drivers/net/irda/toshoboe.c +++ b/drivers/net/irda/toshoboe.c @@ -643,6 +643,8 @@ out: MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver"); MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>"); +MODULE_LICENSE("GPL"); + MODULE_PARM (max_baud, "i"); MODULE_PARM_DESC(max_baus, "Maximum baud rate"); diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 06dcec26009c..3ee231377b4d 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -46,6 +46,8 @@ MODULE_DESCRIPTION("IrDA SIR/MIR/FIR driver for VLSI 82C147"); MODULE_AUTHOR("Martin Diehl <info@mdiehl.de>"); +MODULE_LICENSE("GPL"); + static /* const */ char drivername[] = "vlsi_ir"; diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 1c980075f283..52f19ed6b094 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -1378,6 +1378,8 @@ static struct net_device_stats *w83977af_net_get_stats(struct net_device *dev) MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Winbond W83977AF IrDA Device Driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(qos_mtt_bits, "i"); MODULE_PARM_DESC(qos_mtt_bits, "Mimimum Turn Time"); diff --git a/drivers/net/lance.c b/drivers/net/lance.c index 81995bbfadb3..ac7a07cb5ebb 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -347,6 +347,8 @@ void cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* Starting in v2.1.*, the LANCE/PCnet probe is now similar to the other board probes now that kmalloc() can allocate ISA DMA-able regions. diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c index dbdb691ff37d..b80f239169ac 100644 --- a/drivers/net/lne390.c +++ b/drivers/net/lne390.c @@ -384,6 +384,7 @@ MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i"); MODULE_PARM_DESC(io, "LNE390 I/O base address(es)"); MODULE_PARM_DESC(irq, "LNE390 IRQ number(s)"); MODULE_PARM_DESC(mem, "LNE390 memory base address(es)"); +MODULE_LICENSE("GPL"); int init_module(void) { diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c index 0255fbeaf4ac..85c5c63d781e 100644 --- a/drivers/net/lp486e.c +++ b/drivers/net/lp486e.c @@ -1324,6 +1324,8 @@ static void set_multicast_list(struct net_device *dev) { MODULE_AUTHOR("Ard van Breemen <ard@cstmel.nl.eu.org>"); MODULE_DESCRIPTION("Intel Panther onboard i82596 driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(debug, "i"); //MODULE_PARM(max_interrupt_work, "i"); //MODULE_PARM(reverse_probe, "i"); diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index ccd882e9bb04..ec0912034773 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c @@ -524,7 +524,7 @@ net_rx(struct net_device *dev) lp->stats.rx_dropped++; return; } - skb->len = length; + skb_put(skb, length); skb->dev = dev; memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length); diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 71e9f8c956b5..422894612d64 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -171,6 +171,8 @@ KERN_INFO " (unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDA MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(mtu, "i"); MODULE_PARM(debug, "i"); diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 2d98d16aab74..43b12a6f33aa 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -788,6 +788,8 @@ void cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index dfc29027ce97..0189756a64bb 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -77,6 +77,8 @@ KERN_INFO " http://www.scyld.com/network/ne2k-pci.html\n"; MODULE_AUTHOR("Donald Becker / Paul Gortmaker"); MODULE_DESCRIPTION("PCI NE2000 clone driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(debug, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c index bc1e08a1921b..6b408b118cd1 100644 --- a/drivers/net/ne3210.c +++ b/drivers/net/ne3210.c @@ -415,5 +415,7 @@ void cleanup_module(void) } } } +MODULE_LICENSE("GPL"); + #endif /* MODULE */ diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c index ed6cd16d2cc8..0974671fcfd3 100644 --- a/drivers/net/ni5010.c +++ b/drivers/net/ni5010.c @@ -783,6 +783,7 @@ cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); /* * Local variables: diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c index f4ad2222b0f9..d222d5480bf8 100644 --- a/drivers/net/ni52.c +++ b/drivers/net/ni52.c @@ -1362,6 +1362,7 @@ void ni52_dump(struct net_device *dev,void *ptr) printk("\n"); } #endif +MODULE_LICENSE("GPL"); /* * END: linux/drivers/net/ni52.c diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c index d568458e5b38..84f5a31ae71d 100644 --- a/drivers/net/ni65.c +++ b/drivers/net/ni65.c @@ -1214,6 +1214,7 @@ void cleanup_module(void) dev_ni65.priv = NULL; } #endif /* MODULE */ +MODULE_LICENSE("GPL"); /* * END of ni65.c diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 8f0ebf5a38cc..f0639d32c53a 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1,7 +1,7 @@ -#define VERSION "0.11" +#define VERSION "0.12" /* ns83820.c by Benjamin LaHaise <bcrl@redhat.com> * - * $Revision: 1.34.2.2 $ + * $Revision: 1.34.2.8 $ * * Copyright 2001 Benjamin LaHaise. * Copyright 2001 Red Hat. @@ -41,7 +41,9 @@ * 20010827 0.10 - fix ia64 unaligned access. * 20010906 0.11 - accept all packets with checksum errors as * otherwise fragments get lost - - fix >> 32 bugs + * - fix >> 32 bugs + * 0.12 - add statistics counters + * - add allmulti/promisc support * * Driver Overview * =============== @@ -61,7 +63,9 @@ * Cameo SOHO-GA2000T SOHO-GA2500T * D-Link DGE-500T * PureData PDP8023Z-TG - * SMC SMC9462TX + * SMC SMC9452TX SMC9462TX + * + * Special thanks to SMC for providing hardware to test this driver on. * * Reports of success or failure would be greatly appreciated. */ @@ -366,6 +370,7 @@ struct rx_info { struct ns83820 { struct net_device net_dev; + struct net_device_stats stats; u8 *base; struct pci_dev *pci_dev; @@ -732,39 +737,22 @@ static void rx_irq(struct ns83820 *dev) kfree_skb(skb); skb = tmp; #endif + if (cmdsts & CMDSTS_DEST_MULTI) + dev->stats.multicast ++; + dev->stats.rx_packets ++; + dev->stats.rx_bytes += len; if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) { skb->ip_summed = CHECKSUM_UNNECESSARY; } else { skb->ip_summed = CHECKSUM_NONE; } skb->protocol = eth_type_trans(skb, &dev->net_dev); - switch (netif_rx(skb)) { - case NET_RX_SUCCESS: - dev->ihr = 3; - break; - case NET_RX_CN_LOW: - dev->ihr = 3; - break; - case NET_RX_CN_MOD: - dev->ihr = dev->ihr + 1; - break; - case NET_RX_CN_HIGH: - dev->ihr += dev->ihr/2 + 1; - break; - case NET_RX_DROP: - dev->ihr = 255; - break; - } - if (dev->ihr > 255) - dev->ihr = 255; + if (NET_RX_DROP == netif_rx(skb)) + dev->stats.rx_dropped ++; #ifndef __i386__ done:; #endif } else { - static int err; - if (err++ < 20) { - Dprintk("error packet: cmdsts: %08x extsts: %08x\n", cmdsts, extsts); - } kfree_skb(skb); } @@ -807,6 +795,13 @@ static void do_tx_done(struct ns83820 *dev) !(CMDSTS_OWN & (cmdsts = desc[CMDSTS])) ) { struct sk_buff *skb; + if (cmdsts & CMDSTS_ERR) + dev->stats.tx_errors ++; + if (cmdsts & CMDSTS_OK) + dev->stats.tx_packets ++; + if (cmdsts & CMDSTS_OK) + dev->stats.tx_bytes += cmdsts & 0xffff; + dprintk("tx_done_idx=%d free_idx=%d cmdsts=%08x\n", tx_done_idx, dev->tx_free_idx, desc[CMDSTS]); skb = dev->tx_skbs[tx_done_idx]; @@ -985,6 +980,35 @@ again: return 0; } +static void ns83820_update_stats(struct ns83820 *dev) +{ + u8 *base = dev->base; + + dev->stats.rx_errors += readl(base + 0x60) & 0xffff; + dev->stats.rx_crc_errors += readl(base + 0x64) & 0xffff; + dev->stats.rx_missed_errors += readl(base + 0x68) & 0xffff; + dev->stats.rx_frame_errors += readl(base + 0x6c) & 0xffff; + /*dev->stats.rx_symbol_errors +=*/ readl(base + 0x70); + dev->stats.rx_length_errors += readl(base + 0x74) & 0xffff; + dev->stats.rx_length_errors += readl(base + 0x78) & 0xffff; + /*dev->stats.rx_badopcode_errors += */ readl(base + 0x7c); + /*dev->stats.rx_pause_count += */ readl(base + 0x80); + /*dev->stats.tx_pause_count += */ readl(base + 0x84); + dev->stats.tx_carrier_errors += readl(base + 0x88) & 0xff; +} + +static struct net_device_stats *ns83820_get_stats(struct net_device *_dev) +{ + struct ns83820 *dev = (void *)_dev; + + /* somewhat overkill */ + spin_lock_irq(&dev->misc_lock); + ns83820_update_stats(dev); + spin_unlock_irq(&dev->misc_lock); + + return &dev->stats; +} + static void ns83820_irq(int foo, void *data, struct pt_regs *regs) { struct ns83820 *dev = data; @@ -1060,6 +1084,12 @@ static void ns83820_irq(int foo, void *data, struct pt_regs *regs) if ((ISR_TXDESC | ISR_TXIDLE) & isr) do_tx_done(dev); + if (ISR_MIB & isr) { + spin_lock(&dev->misc_lock); + ns83820_update_stats(dev); + spin_unlock(&dev->misc_lock); + } + if (ISR_PHY & isr) phy_intr(dev); } @@ -1178,6 +1208,28 @@ static int ns83820_change_mtu(struct net_device *_dev, int new_mtu) return 0; } +static void ns83820_set_multicast(struct net_device *_dev) +{ + struct ns83820 *dev = (void *)_dev; + u8 *rfcr = dev->base + RFCR; + u32 and_mask = 0xffffffff; + u32 or_mask = 0; + + if (dev->net_dev.flags & IFF_PROMISC) + or_mask |= RFCR_AAU | RFCR_AAM; + else + and_mask &= ~(RFCR_AAU | RFCR_AAM); + + if (dev->net_dev.flags & IFF_ALLMULTI) + or_mask |= RFCR_AAM; + else + and_mask &= ~RFCR_AAM; + + spin_lock_irq(&dev->misc_lock); + writel((readl(rfcr) & and_mask) | or_mask, rfcr); + spin_unlock_irq(&dev->misc_lock); +} + static int ns83820_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) { struct ns83820 *dev; @@ -1241,6 +1293,9 @@ static int ns83820_probe(struct pci_dev *pci_dev, const struct pci_device_id *id dev->net_dev.stop = ns83820_stop; dev->net_dev.hard_start_xmit = ns83820_hard_start_xmit; dev->net_dev.change_mtu = ns83820_change_mtu; + dev->net_dev.get_stats = ns83820_get_stats; + dev->net_dev.change_mtu = ns83820_change_mtu; + dev->net_dev.set_multicast_list = ns83820_set_multicast; //FIXME: dev->net_dev.tx_timeout = ns83820_tx_timeout; lock_kernel(); @@ -1423,6 +1478,9 @@ static void ns83820_exit(void) MODULE_AUTHOR("Benjamin LaHaise <bcrl@redhat.com>"); MODULE_DESCRIPTION("National Semiconductor DP83820 10/100/1000 driver"); +MODULE_LICENSE("GPL"); + MODULE_DEVICE_TABLE(pci, pci_device_id); + module_init(ns83820_init); module_exit(ns83820_exit); diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index da91816e379f..d1986a2ccafb 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -1312,6 +1312,7 @@ static void __exit exit_3c574_cs(void) module_init(init_3c574_cs); module_exit(exit_3c574_cs); +MODULE_LICENSE("GPL"); /* * Local variables: diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index a35f51d2dc0b..1deb93034180 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -1097,3 +1097,4 @@ static void __exit exit_3c589_cs(void) module_init(init_3c589_cs); module_exit(exit_3c589_cs); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/pcmcia/aironet4500_cs.c b/drivers/net/pcmcia/aironet4500_cs.c index 1dfe16146396..4c26b7f48f37 100644 --- a/drivers/net/pcmcia/aironet4500_cs.c +++ b/drivers/net/pcmcia/aironet4500_cs.c @@ -644,4 +644,4 @@ static void __exit aironet_cs_exit(void) module_init(aironet_cs_init); module_exit(aironet_cs_exit); - +MODULE_LICENSE("GPL"); diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 4c43040868c8..73908f868a7e 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -1257,3 +1257,4 @@ static void set_rx_mode(struct net_device *dev) } restore_flags(flags); } +MODULE_LICENSE("GPL"); diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index fb4bf2e13aa9..24d20fb7824e 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -107,6 +107,7 @@ MODULE_PARM(mmiobase, "i"); MODULE_PARM(srambase, "i"); MODULE_PARM(sramsize, "i"); MODULE_PARM(ringspeed, "i"); +MODULE_LICENSE("GPL"); /*====================================================================*/ diff --git a/drivers/net/pcmcia/netwave_cs.c b/drivers/net/pcmcia/netwave_cs.c index 3bf0c6aaf6cf..2c6a50af1d74 100644 --- a/drivers/net/pcmcia/netwave_cs.c +++ b/drivers/net/pcmcia/netwave_cs.c @@ -1590,3 +1590,4 @@ static void set_multicast_list(struct net_device *dev) writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1); writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2); } +MODULE_LICENSE("GPL"); diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 239dc0239608..62a62bc50036 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -409,6 +409,8 @@ static int irq_list[4] = { -1 }; MODULE_PARM(if_port, "i"); MODULE_PARM(irq_mask, "i"); MODULE_PARM(irq_list, "1-4i"); +MODULE_LICENSE("GPL"); + /* ---------------------------------------------------------------------------- Function Prototypes diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 484e08384a43..e22fa262d5ed 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1522,3 +1522,4 @@ static void __exit exit_pcnet_cs(void) module_init(init_pcnet_cs); module_exit(exit_pcnet_cs); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/pcmcia/ray_cs.c b/drivers/net/pcmcia/ray_cs.c index 3655a3fc2356..f39af0ea8b52 100644 --- a/drivers/net/pcmcia/ray_cs.c +++ b/drivers/net/pcmcia/ray_cs.c @@ -221,6 +221,8 @@ static unsigned int ray_mem_speed = 500; MODULE_AUTHOR("Corey Thomas <corey@world.std.com>"); MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(irq_mask,"i"); MODULE_PARM(net_type,"i"); MODULE_PARM(hop_dwell,"i"); diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 8c3ef835999f..90eaf258b31e 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -85,6 +85,7 @@ static int irq_list[4] = { -1 }; MODULE_PARM(if_port, "i"); MODULE_PARM(irq_mask, "i"); MODULE_PARM(irq_list, "1-4i"); +MODULE_LICENSE("GPL"); /* Operational parameter that usually are not changed. */ diff --git a/drivers/net/pcmcia/wavelan_cs.c b/drivers/net/pcmcia/wavelan_cs.c index aa0ac3fb9c21..b41536ce3f26 100644 --- a/drivers/net/pcmcia/wavelan_cs.c +++ b/drivers/net/pcmcia/wavelan_cs.c @@ -4832,3 +4832,4 @@ exit_wavelan_cs(void) module_init(init_wavelan_cs); module_exit(exit_wavelan_cs); +MODULE_LICENSE("BSD without advertisement clause"); diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index ac3355aa097c..757ff555d235 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -2090,3 +2090,4 @@ static int __init setup_xirc2ps_cs(char *str) __setup("xirc2ps_cs=", setup_xirc2ps_cs); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/net/pcmcia/xircom_cb.c b/drivers/net/pcmcia/xircom_cb.c index a256a5b68484..47ed54e36a55 100644 --- a/drivers/net/pcmcia/xircom_cb.c +++ b/drivers/net/pcmcia/xircom_cb.c @@ -37,6 +37,7 @@ MODULE_DESCRIPTION("Xircom Cardbus ethernet driver"); MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/pcmcia/xircom_tulip_cb.c b/drivers/net/pcmcia/xircom_tulip_cb.c index b229607541c8..4b95b3d7b126 100644 --- a/drivers/net/pcmcia/xircom_tulip_cb.c +++ b/drivers/net/pcmcia/xircom_tulip_cb.c @@ -106,6 +106,8 @@ static int csr0 = 0x00A00000 | 0x4800; MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(debug, "i"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(rx_copybreak, "i"); diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 37d965573a5f..2356639d600b 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1538,6 +1538,7 @@ MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_AUTHOR("Thomas Bogendoerfer"); MODULE_DESCRIPTION("Driver for PCnet32 and PCnetPCI based ethercards"); +MODULE_LICENSE("GPL"); /* An additional parameter that may be passed in... */ static int debug = -1; diff --git a/drivers/net/plip.c b/drivers/net/plip.c index a2de0f408469..864d9b833043 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -1432,6 +1432,7 @@ static int __init plip_init (void) module_init(plip_init); module_exit(plip_cleanup_module); +MODULE_LICENSE("GPL"); /* * Local variables: diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 16d9ab300549..5177c8bee290 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -81,6 +81,8 @@ struct asyncppp { static int flag_time = HZ; MODULE_PARM(flag_time, "i"); MODULE_PARM_DESC(flag_time, "ppp_async: interval between flagged packets (in clock ticks)"); +MODULE_LICENSE("GPL"); + /* * Prototypes. diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c index e1d4768972bf..0092f7b6c830 100644 --- a/drivers/net/ppp_deflate.c +++ b/drivers/net/ppp_deflate.c @@ -657,3 +657,4 @@ void __exit deflate_cleanup(void) module_init(deflate_init); module_exit(deflate_cleanup); +MODULE_LICENSE("BSD without advertisement clause"); diff --git a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c index 3768ed0548d5..0b5bcdcc1eaa 100644 --- a/drivers/net/rcpci45.c +++ b/drivers/net/rcpci45.c @@ -111,6 +111,7 @@ static struct pci_device_id rcpci45_pci_table[] __devinitdata = { {} }; MODULE_DEVICE_TABLE (pci, rcpci45_pci_table); +MODULE_LICENSE("GPL"); static void __exit rcpci45_remove_one (struct pci_dev *pdev) diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c index e469f46cfe56..ac5ca33b2980 100644 --- a/drivers/net/sb1000.c +++ b/drivers/net/sb1000.c @@ -1209,6 +1209,8 @@ static int sb1000_close(struct net_device *dev) #ifdef MODULE MODULE_AUTHOR("Franco Venturi <fventuri@mediaone.net>"); MODULE_DESCRIPTION("General Instruments SB1000 driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "1-2i"); MODULE_PARM(irq, "i"); MODULE_PARM_DESC(io, "SB1000 I/O base addresses"); diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index ad2c001a3b97..9e1e2e30a26c 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -743,4 +743,5 @@ static void __exit shaper_exit (void) module_init(shaper_init); module_exit(shaper_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index a65b3b097c2b..694d44e2f5b4 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -161,6 +161,8 @@ struct sis900_private { MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>, Ollie Lho <ollie@sis.com.tw>"); MODULE_DESCRIPTION("SiS 900 PCI Fast Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(multicast_filter_limit, "i"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(debug, "i"); diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c index 463d815529ec..a2708e7e8a6d 100644 --- a/drivers/net/sk98lin/skge.c +++ b/drivers/net/sk98lin/skge.c @@ -591,6 +591,7 @@ SK_AC *pAC; MODULE_AUTHOR("Christoph Goos <cgoos@syskonnect.de>"); MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver"); +MODULE_LICENSE("GPL"); MODULE_PARM(AutoNeg_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(AutoNeg_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(DupCap_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index cb81e98cf00d..e748b5c9aa4c 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -187,6 +187,7 @@ static struct pci_device_id skfddi_pci_tbl[] __initdata = { { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(pci, skfddi_pci_tbl); +MODULE_LICENSE("GPL"); // Define module-wide (static) variables diff --git a/drivers/net/slhc.c b/drivers/net/slhc.c index 3112a4d661b7..d83aeffb391c 100644 --- a/drivers/net/slhc.c +++ b/drivers/net/slhc.c @@ -797,3 +797,4 @@ EXPORT_SYMBOL(slhc_uncompress); EXPORT_SYMBOL(slhc_toss); #endif /* CONFIG_INET */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/drivers/net/slip.c b/drivers/net/slip.c index e8201924d01f..ebac2929faaa 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -1516,3 +1516,4 @@ out: } #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index 269be5c5a8e4..f2807a6447d9 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -557,6 +557,8 @@ cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + /* diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c index 1a2b9b8c8f6a..1b27198e434b 100644 --- a/drivers/net/smc-ultra32.c +++ b/drivers/net/smc-ultra32.c @@ -415,3 +415,5 @@ void cleanup_module(void) } } #endif /* MODULE */ +MODULE_LICENSE("GPL"); + diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 09b396cf3298..0fec2bcce2c3 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -250,6 +250,8 @@ KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELD MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(mtu, "i"); MODULE_PARM(debug, "i"); diff --git a/drivers/net/strip.c b/drivers/net/strip.c index 2d1164fb3da7..e78d5b991df0 100644 --- a/drivers/net/strip.c +++ b/drivers/net/strip.c @@ -2871,5 +2871,7 @@ module_exit(strip_exit_driver); MODULE_AUTHOR("Stuart Cheshire <cheshire@cs.stanford.edu>"); MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver"); +MODULE_LICENSE("BSD without advertisement clause"); + MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem"); diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 0266076e179b..cf21b0181630 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -108,6 +108,8 @@ KERN_INFO " http://www.scyld.com/network/sundance.html\n"; MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("Sundance Alta Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(mtu, "i"); MODULE_PARM(debug, "i"); diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 1f4c1a2a560a..08653abefba8 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -48,6 +48,8 @@ static char version[] __devinitdata = MODULE_AUTHOR("David S. Miller (davem@redhat.com)"); MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(gem_debug, "i"); MODULE_PARM_DESC(gem_debug, "(ignored)"); diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 654e2db9256c..a029bc9a88f0 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -190,6 +190,8 @@ struct pci_device_id happymeal_pci_ids[] __initdata = { }; MODULE_DEVICE_TABLE(pci, happymeal_pci_ids); +MODULE_LICENSE("GPL"); + #endif /* NOTE: In the descriptor writes one _must_ write the address diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index dbba4a020fb9..57632c10efb2 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -190,6 +190,8 @@ static int boards_found; MODULE_AUTHOR("Maintainer: Torben Mathiasen <torben.mathiasen@compaq.com>"); MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters"); +MODULE_LICENSE("GPL"); + MODULE_PARM(aui, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i"); MODULE_PARM(duplex, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i"); MODULE_PARM(speed, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i"); @@ -452,7 +454,7 @@ static int __init tlan_probe(void) /* Use new style PCI probing. Now the kernel will do most of this for us */ - pci_module_init(&tlan_driver); + pci_register_driver(&tlan_driver); TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n"); TLan_EisaProbe(); @@ -462,6 +464,7 @@ static int __init tlan_probe(void) tlan_have_pci, tlan_have_eisa); if (TLanDevicesInstalled == 0) { + pci_unregister_driver(&tlan_driver); kfree(TLanPadBuffer); return -ENODEV; } @@ -643,8 +646,7 @@ static void TLan_Eisa_Cleanup(void) static void __exit tlan_exit(void) { - if (tlan_have_pci) - pci_unregister_driver(&tlan_driver); + pci_unregister_driver(&tlan_driver); if (tlan_have_eisa) TLan_Eisa_Cleanup(); diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index cae4ad98e0e8..8dc7c621f67f 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c @@ -1825,3 +1825,4 @@ static void __exit streamer_cleanup_module(void) { module_init(streamer_init_module); module_exit(streamer_cleanup_module); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 1a39a109aaf3..f130784958ff 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -101,6 +101,7 @@ static int csr0 = 0x00A00000 | 0x4800; MODULE_AUTHOR("The Linux Kernel Team"); MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver"); +MODULE_LICENSE("GPL"); MODULE_PARM(tulip_debug, "i"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(rx_copybreak, "i"); @@ -1466,8 +1467,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, goto err_out_free_res; #endif - pci_set_master(pdev); - pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev); /* @@ -1512,6 +1511,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, /* Stop the chip's Tx and Rx processes. */ tulip_stop_rxtx(tp); + pci_set_master(pdev); + /* Clear the missed-packet counter. */ inl(ioaddr + CSR8); diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a7f262577394..fc552d28d810 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -581,3 +581,4 @@ void tun_cleanup(void) module_init(tun_init); module_exit(tun_cleanup); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index dc7a5c13d1e0..fba2430f5ba6 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -184,6 +184,8 @@ static char shortname[] __devinitdata = "via-rhine"; MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(debug, "i"); MODULE_PARM(rx_copybreak, "i"); diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c index a588bb6ec1da..9034148c3a38 100644 --- a/drivers/net/wan/cycx_drv.c +++ b/drivers/net/wan/cycx_drv.c @@ -64,6 +64,8 @@ MODULE_AUTHOR("Arnaldo Carvalho de Melo"); MODULE_DESCRIPTION("Cyclom 2x Sync Card Driver"); +MODULE_LICENSE("GPL"); + /* Function Prototypes */ /* Module entry points. These are called by the OS and must be public. */ diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index f43e33a9ab0d..f46c7e9c82ad 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -1,5 +1,3 @@ -#define LINUX_21 - /* * Comtrol SV11 card driver * @@ -186,7 +184,6 @@ static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d) return z8530_queue_xmit(&sv11->sync.chanA, skb); } -#ifdef LINUX_21 static int hostess_neigh_setup(struct neighbour *n) { if (n->nud_state == NUD_NONE) { @@ -206,15 +203,6 @@ static int hostess_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p return 0; } -#else - -static int return_0(struct net_device *d) -{ - return 0; -} - -#endif - /* * Description block for a Comtrol Hostess SV11 card */ @@ -345,11 +333,7 @@ static struct sv11_device *sv11_init(int iobase, int irq) d->get_stats = hostess_get_stats; d->set_multicast_list = NULL; d->do_ioctl = hostess_ioctl; -#ifdef LINUX_21 d->neigh_setup = hostess_neigh_setup_dev; -#else - d->init = return_0; -#endif d->set_mac_address = NULL; if(register_netdev(d)==-1) @@ -416,7 +400,7 @@ static struct sv11_device *sv11_unit; int init_module(void) { printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.02.\n"); - printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n"); + printk(KERN_INFO "(c) Copyright 2001, Red Hat Inc.\n"); if((sv11_unit=sv11_init(io,irq))==NULL) return -ENODEV; return 0; diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 8bc2e120a1fd..6e3fd01c259b 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -1,5 +1,3 @@ -#define LINUX_21 - /* * Sealevel Systems 4021 driver. * @@ -8,8 +6,8 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * (c) Copyright 1999 Building Number Three Ltd - * (c) Copyright 2001 Alan Cox. + * (c) Copyright 1999, 2001 Alan Cox + * (c) Copyright 2001 Red Hat Inc. * */ @@ -185,7 +183,6 @@ static int sealevel_queue_xmit(struct sk_buff *skb, struct net_device *d) return z8530_queue_xmit(slvl->chan, skb); } -#ifdef LINUX_21 static int sealevel_neigh_setup(struct neighbour *n) { if (n->nud_state == NUD_NONE) { @@ -205,15 +202,6 @@ static int sealevel_neigh_setup_dev(struct net_device *dev, struct neigh_parms * return 0; } -#else - -static int return_0(struct net_device *d) -{ - return 0; -} - -#endif - /* * Description block for a Comtrol Hostess SV11 card */ @@ -374,11 +362,7 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i d->get_stats = sealevel_get_stats; d->set_multicast_list = NULL; d->do_ioctl = sealevel_ioctl; -#ifdef LINUX_21 d->neigh_setup = sealevel_neigh_setup_dev; -#else - d->init = return_0; -#endif d->set_mac_address = NULL; if(register_netdev(d)==-1) @@ -444,7 +428,6 @@ static int rxdma=3; static int irq=5; static int slow=0; -#ifdef LINUX_21 MODULE_PARM(io,"i"); MODULE_PARM_DESC(io, "The I/O base of the Sealevel card"); MODULE_PARM(txdma,"i"); @@ -459,7 +442,6 @@ MODULE_PARM_DESC(slow, "Set this for an older Sealevel card such as the 4012"); MODULE_AUTHOR("Alan Cox"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Modular driver for the SeaLevel 4021"); -#endif static struct slvl_board *slvl_unit; diff --git a/drivers/net/wavelan.c b/drivers/net/wavelan.c index 409c1d5eb4aa..7868bee37067 100644 --- a/drivers/net/wavelan.c +++ b/drivers/net/wavelan.c @@ -1545,8 +1545,7 @@ static inline int wv_set_frequency(unsigned long ioaddr, /* I/O port of the card /* Setting by channel (same as wfreqsel) */ /* Warning: each channel is 22 MHz wide, so some of the channels * will interfere. */ - if ((frequency->e == 0) && - (frequency->m >= 0) && (frequency->m < BAND_NUM)) { + if ((frequency->e == 0) && (frequency->m < BAND_NUM)) { /* Get frequency offset. */ freq = channel_bands[frequency->m] >> 1; } @@ -4292,6 +4291,7 @@ void cleanup_module(void) #endif } #endif /* MODULE */ +MODULE_LICENSE("GPL"); /* * This software may only be used and distributed diff --git a/drivers/net/wd.c b/drivers/net/wd.c index efd3c350ae53..c053c1c53320 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -454,6 +454,7 @@ MODULE_PARM_DESC(io, "WD80x3 I/O base address(es)"); MODULE_PARM_DESC(irq, "WD80x3 IRQ number(s) (ignored for PureData boards)"); MODULE_PARM_DESC(mem, "WD80x3 memory base address(es)(ignored for PureData boards)"); MODULE_PARM_DESC(mem_end, "WD80x3 memory end address(es)"); +MODULE_LICENSE("GPL"); /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ diff --git a/drivers/net/winbond-840.c b/drivers/net/winbond-840.c index 25ec43b93afe..c1aa90d3d8f9 100644 --- a/drivers/net/winbond-840.c +++ b/drivers/net/winbond-840.c @@ -149,6 +149,8 @@ KERN_INFO " http://www.scyld.com/network/drivers.html\n"; MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(debug, "i"); MODULE_PARM(rx_copybreak, "i"); diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 5338a70a2179..0f955e76db72 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -150,6 +150,8 @@ KERN_INFO " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n"; #endif /* !USE_IO_OPS */ MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(mtu, "i"); MODULE_PARM(debug, "i"); diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index ac9e8275f3e5..e90aa13c78e8 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -480,3 +480,4 @@ static void __exit exit_parport_cs(void) module_init(init_parport_cs); module_exit(exit_parport_cs); +MODULE_LICENSE("Dual MPL/GPL"); diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 4a3172950469..e0e047209c37 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -357,6 +357,7 @@ static void __exit parport_serial_exit (void) MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>"); MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards"); +MODULE_LICENSE("GPL"); module_init(parport_serial_init); module_exit(parport_serial_exit); diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 82913b6b723f..591cd28ba368 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -18,6 +18,7 @@ #undef PARPORT_DEBUG_SHARING /* undef for production */ #include <linux/config.h> +#include <linux/module.h> #include <linux/string.h> #include <linux/threads.h> #include <linux/parport.h> @@ -1140,3 +1141,4 @@ int parport_parse_dmas(int nports, const char *dmastr[], int dmaval[]) return parport_parse_params (nports, dmastr, dmaval, PARPORT_DMA_AUTO, PARPORT_DMA_NONE, PARPORT_DMA_NOFIFO); } +MODULE_LICENSE("GPL"); diff --git a/drivers/pcmcia/cb_enabler.c b/drivers/pcmcia/cb_enabler.c index 56d7289230f6..ca074012e8cc 100644 --- a/drivers/pcmcia/cb_enabler.c +++ b/drivers/pcmcia/cb_enabler.c @@ -65,6 +65,7 @@ static char *version = MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>"); MODULE_DESCRIPTION("CardBus stub enabler module"); +MODULE_LICENSE("Dual MPL/GPL"); /*====================================================================*/ diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 93391a2d4a33..c9d8b5313fc4 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -96,6 +96,7 @@ static const char *options = "options: " OPTIONS; MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>"); MODULE_DESCRIPTION("Linux Kernel Card Services " CS_RELEASE "\n options:" OPTIONS); +MODULE_LICENSE("Dual MPL/GPL"); /*====================================================================*/ diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 0627c455f116..cf1e8228c99a 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -68,6 +68,8 @@ static const char *version = MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>"); MODULE_DESCRIPTION("PCMCIA Driver Services " CS_RELEASE); +MODULE_LICENSE("Dual MPL/GPL"); + /*====================================================================*/ @@ -415,7 +417,10 @@ static int bind_request(int i, bind_info_t *bind_info) driver->use_count++; b = kmalloc(sizeof(socket_bind_t), GFP_KERNEL); if (!b) - return -ENOMEM; + { + driver->use_count--; + return -ENOMEM; + } b->driver = driver; b->function = bind_info->function; b->instance = NULL; diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index fe39d9878e55..3ac564e3b4ec 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -1660,5 +1660,5 @@ static void __exit exit_i82365(void) module_init(init_i82365); module_exit(exit_i82365); - +MODULE_LICENSE("Dual MPL/GPL"); /*====================================================================*/ diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 03c7a9d053ad..7c5aba638e85 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -69,6 +69,7 @@ static const char *version = MODULE_AUTHOR("David Hinds <dhinds@pcmcia.sourceforge.org>"); MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver"); +MODULE_LICENSE("Dual MPL/GPL"); /*====================================================================*/ diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c index c72c4ca43b0f..b61a3724b53b 100644 --- a/drivers/pcmcia/yenta.c +++ b/drivers/pcmcia/yenta.c @@ -895,3 +895,4 @@ struct pci_socket_ops yenta_operations = { yenta_proc_setup }; EXPORT_SYMBOL(yenta_operations); +MODULE_LICENSE("GPL"); diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index a27159bae3bd..241bb3bea959 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -135,7 +135,9 @@ static void dasd_disable_ranges (dasd_range_t *, dasd_discipline_t *, int, int); static void dasd_enable_single_device ( unsigned long); static inline int dasd_state_init_to_ready(dasd_device_t*); static inline void dasd_setup_partitions ( dasd_device_t *); +static inline void dasd_destroy_partitions ( dasd_device_t *); static inline int dasd_setup_blkdev(dasd_device_t*); +static void dasd_deactivate_queue (dasd_device_t *); static inline int dasd_disable_blkdev(dasd_device_t*); static void dasd_flush_chanq ( dasd_device_t * device, int destroy ); static void dasd_flush_request_queues ( dasd_device_t * device, int destroy ); @@ -205,12 +207,20 @@ dasd_create_range (int from, int to, int features) int i; if ( from > to ) { - printk (KERN_WARNING PRINTK_HEADER "Adding device range %04X-%04X: range invalid, ignoring.\n",from,to); + printk (KERN_WARNING PRINTK_HEADER + "Adding device range %04x-%04x: range invalid, ignoring.\n", + from, + to); + return NULL; } for (i=from;i<=to;i++) { if (dasd_device_from_devno(i)) { - printk (KERN_WARNING PRINTK_HEADER "device range %04X-%04X: device %04X is already in a range.\n",from,to,i); + printk (KERN_WARNING PRINTK_HEADER + "device range %04x-%04x: device %04x is already in a range.\n", + from, + to, + i); } } range = (dasd_range_t *) kmalloc (sizeof (dasd_range_t), GFP_KERNEL); @@ -501,8 +511,15 @@ dasd_strtoul (char *str, char **stra, int* features) } /* copy device no to buffer and convert to decimal */ - for (i=0;isxdigit(temp[i]);i++) - buffer[i]=temp[i]; + for (i=0; temp[i]!='\0' && temp[i]!='(' && + temp[i]!='-' && temp[i]!=' '; i++){ + if (isxdigit(temp[i])) { + buffer[i]=temp[i]; + } else { + return -EINVAL; + } + } + buffer[i]='\0'; val = simple_strtoul (buffer, &buffer, 16); @@ -524,10 +541,12 @@ dasd_strtoul (char *str, char **stra, int* features) break; } printk (KERN_WARNING PRINTK_HEADER - "unsupported feature: %s, ignoring setting",buffer); + "unsupported feature: %s, ignoring setting", + buffer); } } } + *stra = temp+i; return val; } @@ -537,12 +556,13 @@ dasd_strtoul (char *str, char **stra, int* features) * examines the strings given in the string array str and * creates and adds the ranges to the apropriate lists */ -static inline void +static int dasd_parse (char **str) { char *temp; int from, to; int features = 0; + int rc = 0; if (*str) { /* turn off probeonly mode, if any dasd parameter is present */ @@ -570,10 +590,18 @@ dasd_parse (char **str) temp++; to = dasd_strtoul (temp, &temp, &features); } - dasd_add_range (from, to ,features); - } + if (from == -EINVAL || + to == -EINVAL ) { + rc = -EINVAL; + break; + } else { + dasd_add_range (from, to ,features); + } + } str++; } + + return rc; } /* SECTION: Dealing with devices registered to multiple major numbers */ @@ -648,7 +676,9 @@ dasd_register_major (major_info_t * major_info) rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations); if (rc < 0) { printk (KERN_WARNING PRINTK_HEADER - "Cannot register to major no %d, rc = %d\n", major, rc); + "Cannot register to major no %d, rc = %d\n", + major, + rc); goto out_reg_blkdev; } else { major_info->flags |= DASD_MAJOR_INFO_REGISTERED; @@ -751,7 +781,8 @@ dasd_register_major (major_info_t * major_info) rc = devfs_unregister_blkdev (major, DASD_NAME); if (rc < 0) { printk (KERN_WARNING PRINTK_HEADER - "Unable to unregister from major no %d, rc = %d\n", major, + "Unable to unregister from major no %d, rc = %d\n", + major, rc); } else { major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED; @@ -800,7 +831,8 @@ dasd_unregister_major (major_info_t * major_info) rc = devfs_unregister_blkdev (major, DASD_NAME); if (rc < 0) { printk (KERN_WARNING PRINTK_HEADER - "Cannot unregister from major no %d, rc = %d\n", major, + "Cannot unregister from major no %d, rc = %d\n", + major, rc); return rc; } else { @@ -1051,8 +1083,6 @@ ccw_req_t * dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* device) { ccw_req_t *rv = NULL; - int i; - unsigned long flags; if ((rv = ccw_alloc_request (magic, cplength, datasize)) != NULL) { return rv; @@ -1062,7 +1092,9 @@ dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* devi BUG (); } if (device->lowmem_cqr==NULL) { - DASD_MESSAGE (KERN_WARNING, device, "Low memory! Using emergency request %p",device->lowmem_ccws); + DASD_MESSAGE (KERN_WARNING, device, + "Low memory! Using emergency request %p", + device->lowmem_ccws); device->lowmem_cqr=device->lowmem_ccws; rv = device->lowmem_ccws; memset (rv, 0, PAGE_SIZE); @@ -1073,7 +1105,10 @@ dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* devi rv->data = (void *) ((long) rv + PAGE_SIZE - datasize); rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t)); } else { - DASD_MESSAGE (KERN_WARNING, device,"Refusing emergency mem for request NULL, already in use at %p.",device->lowmem_ccws); + DASD_MESSAGE (KERN_WARNING, device, + "Refusing emergency mem for request " + "NULL, already in use at %p.", + device->lowmem_ccws); } return rv; } @@ -1086,47 +1121,61 @@ void dasd_free_request (ccw_req_t * request, dasd_device_t* device) { #ifdef CONFIG_ARCH_S390X - ccw1_t* ccw; - /* clear any idals used for chain */ - ccw=request->cpaddr-1; - do { - ccw++; - if ((ccw->cda < (unsigned long) device->lowmem_idals) || (ccw->cda >= (unsigned long) device->lowmem_idals+PAGE_SIZE)) - clear_normalized_cda (ccw); - else { - if (device->lowmem_idal_ptr != device->lowmem_idals) - DASD_MESSAGE (KERN_WARNING, device, "Freeing emergency idals from request at %p.",request); - device->lowmem_idal_ptr = device->lowmem_idals; - device->lowmem_cqr=NULL; - } - } while ((ccw->flags & CCW_FLAG_CC) || (ccw->flags & CCW_FLAG_DC)); + ccw1_t* ccw; + /* clear any idals used for chain */ + ccw=request->cpaddr-1; + do { + ccw++; + if ((ccw->cda < (unsigned long) device->lowmem_idals ) || + (ccw->cda >= (unsigned long) device->lowmem_idals+PAGE_SIZE) ) + clear_normalized_cda (ccw); + else { + if (device->lowmem_idal_ptr != device->lowmem_idals) + DASD_MESSAGE (KERN_WARNING, device, + "Freeing emergency idals from request at %p.", + request); + device->lowmem_idal_ptr = device->lowmem_idals; + device->lowmem_cqr=NULL; + } + } while ((ccw->flags & CCW_FLAG_CC) || + (ccw->flags & CCW_FLAG_DC) ); #endif - if (request != device->lowmem_ccws) { /* compare to lowmem_ccws to protect usage of lowmem_cqr for IDAL only ! */ + if (request != device->lowmem_ccws) { + /* compare to lowmem_ccws to protect usage of lowmem_cqr for IDAL only ! */ ccw_free_request (request); - } else { - DASD_MESSAGE (KERN_WARNING, device, "Freeing emergency request at %p",request); - device->lowmem_cqr=NULL; + } else { + DASD_MESSAGE (KERN_WARNING, device, + "Freeing emergency request at %p", + request); + device->lowmem_cqr=NULL; } } int -dasd_set_normalized_cda ( ccw1_t * cp, unsigned long address, ccw_req_t* request, dasd_device_t* device ) +dasd_set_normalized_cda (ccw1_t * cp, unsigned long address, + ccw_req_t* request, dasd_device_t* device ) { #ifdef CONFIG_ARCH_S390X int nridaws; int count = cp->count; if (set_normalized_cda (cp, address)!=-ENOMEM) { - return 0; + return 0; } if ((device->lowmem_cqr!=NULL) && (device->lowmem_cqr!=request)) { - DASD_MESSAGE (KERN_WARNING, device, "Refusing emergency idals for request %p, memory is already in use for request %p",request,device->lowmem_cqr); - return -ENOMEM; + DASD_MESSAGE (KERN_WARNING, device, + "Refusing emergency idals for request %p, memory" + " is already in use for request %p", + request, + device->lowmem_cqr); + return -ENOMEM; } device->lowmem_cqr=request; if (device->lowmem_idal_ptr == device->lowmem_idals) { - DASD_MESSAGE (KERN_WARNING,device, "Low memory! Using emergency IDALs for request %p.\n",request); + DASD_MESSAGE (KERN_WARNING,device, + "Low memory! Using emergency IDALs for request %p.\n", + request); } nridaws = ((address & (IDA_BLOCK_SIZE-1)) + count + (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG; @@ -1165,7 +1214,27 @@ dasd_chanq_enq (dasd_chanq_t * q, ccw_req_t * cqr) q->head = cqr; cqr->next = NULL; q->tail = cqr; - check_then_set (&cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED); + check_then_set (&cqr->status, + CQR_STATUS_FILLED, + CQR_STATUS_QUEUED); + + + /* save profile information for non erp cqr */ + if (cqr->refers == NULL) { + unsigned int counter = 0; + ccw_req_t *ptr; + dasd_device_t *device = cqr->device; + + /* count the length of the chanq for statistics */ + for (ptr = q->head; + ptr->next != NULL && counter <=31; + ptr = ptr->next) { + counter++; + } + + dasd_global_profile.dasd_io_nr_req[counter]++; + device->profile.dasd_io_nr_req[counter]++; + } } /* @@ -1217,8 +1286,11 @@ dasd_chanq_deq (dasd_chanq_t * q, ccw_req_t * cqr) /* SECTION: Managing the device queues etc. */ /* - * function dasd_start_IO - * attempts to start the IO and returns an appropriate return code + * DASD_TERM_IO + * + * attempts to terminate the the current IO and set it to failed if termination + * was successful. + * returns an appropriate return code */ int dasd_term_IO (ccw_req_t * cqr) @@ -1234,49 +1306,54 @@ dasd_term_IO (ccw_req_t * cqr) irq = device->devinfo.irq; if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) { DASD_MESSAGE (KERN_WARNING, device, - " ccw_req_t 0x%08X magic doesn't match" - " discipline 0x%08X\n", + " ccw_req_t 0x%08x magic doesn't match" + " discipline 0x%08x\n", cqr->magic, *(unsigned int *) device->discipline->name); return -EINVAL; } + + while ((retries < 5 ) && + (cqr->status == CQR_STATUS_IN_IO) ) { - while ( retries < 5 ) { - if ( retries < 2 ) - rc = halt_IO(irq, (long)cqr, - cqr->options | DOIO_WAIT_FOR_INTERRUPT); - else - rc = clear_IO(irq, (long)cqr, - cqr->options | DOIO_WAIT_FOR_INTERRUPT); - switch (rc) { - case 0: - break; - case -ENODEV: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "device gone, retry\n"); - break; - case -EIO: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "I/O error, retry\n"); - break; - case -EBUSY: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "device busy, retry later\n"); - break; - default: - DASD_MESSAGE (KERN_ERR, device, - "line %d unknown RC=%d, please report" - " to linux390@de.ibm.com\n", __LINE__, rc); - BUG (); - break; - } - if (rc == 0) { - check_then_set (&cqr->status, - CQR_STATUS_IN_IO, CQR_STATUS_FAILED); - asm volatile ("STCK %0":"=m" (cqr->stopclk)); - break; - } - retries ++; + if ( retries < 2 ) + rc = halt_IO(irq, (long)cqr, + cqr->options | DOIO_WAIT_FOR_INTERRUPT); + else + rc = clear_IO(irq, (long)cqr, + cqr->options | DOIO_WAIT_FOR_INTERRUPT); + + switch (rc) { + case 0: /* termination successful */ + check_then_set (&cqr->status, + CQR_STATUS_IN_IO, + CQR_STATUS_FAILED); + + asm volatile ("STCK %0":"=m" (cqr->stopclk)); + break; + case -ENODEV: + DASD_MESSAGE (KERN_WARNING, device, "%s", + "device gone, retry\n"); + break; + case -EIO: + DASD_MESSAGE (KERN_WARNING, device, "%s", + "I/O error, retry\n"); + break; + case -EBUSY: + DASD_MESSAGE (KERN_WARNING, device, "%s", + "device busy, retry later\n"); + break; + default: + DASD_MESSAGE (KERN_ERR, device, + "line %d unknown RC=%d, please report" + " to linux390@de.ibm.com\n", + __LINE__, + rc); + BUG (); + break; + } + + retries ++; } return rc; } @@ -1299,30 +1376,54 @@ dasd_start_IO (ccw_req_t * cqr) irq = device->devinfo.irq; if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) { DASD_MESSAGE (KERN_WARNING, device, - " ccw_req_t 0x%08X magic doesn't match" - " discipline 0x%08X\n", + " ccw_req_t 0x%08x magic doesn't match" + " discipline 0x%08x\n", cqr->magic, *(unsigned int *) device->discipline->name); return -EINVAL; } asm volatile ("STCK %0":"=m" (now)); + cqr->startclk = now; + rc = do_IO (irq, cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options); + switch (rc) { case 0: - break; - case -ENODEV: - check_then_set (&cqr->status, - CQR_STATUS_QUEUED, CQR_STATUS_FAILED); - break; - case -EIO: - check_then_set (&cqr->status, - CQR_STATUS_QUEUED, CQR_STATUS_FAILED); + if (cqr->options & DOIO_WAIT_FOR_INTERRUPT) { + /* request already finished (synchronous IO) */ + DASD_MESSAGE (KERN_ERR, device, "%s", + " do_IO finished request... " + "DOIO_WAIT_FOR_INTERRUPT was set"); + check_then_set (&cqr->status, + CQR_STATUS_QUEUED, + CQR_STATUS_DONE); + + cqr->stopclk = now; + dasd_schedule_bh (device); + + } else { + check_then_set (&cqr->status, + CQR_STATUS_QUEUED, + CQR_STATUS_IN_IO); + } break; case -EBUSY: DASD_MESSAGE (KERN_WARNING, device, "%s", "device busy, retry later\n"); break; + case -ETIMEDOUT: + DASD_MESSAGE (KERN_WARNING, device, "%s", + "request timeout - terminated\n"); + case -ENODEV: + case -EIO: + check_then_set (&cqr->status, + CQR_STATUS_QUEUED, + CQR_STATUS_FAILED); + + cqr->stopclk = now; + dasd_schedule_bh (device); + break; default: DASD_MESSAGE (KERN_ERR, device, "line %d unknown RC=%d, please report" @@ -1330,11 +1431,7 @@ dasd_start_IO (ccw_req_t * cqr) BUG (); break; } - if (rc == 0) { - check_then_set (&cqr->status, - CQR_STATUS_QUEUED, CQR_STATUS_IN_IO); - cqr->startclk = now; - } + return rc; } @@ -1410,7 +1507,7 @@ dasd_get_queue (kdev_t kdev) /* * function dasd_check_expire_time * check the request given as argument for expiration - * and returns 0 if not yet expired, nonzero else + * and returns 0 if not yet expired, EIO else */ static inline int dasd_check_expire_time (ccw_req_t * cqr) @@ -1425,6 +1522,7 @@ dasd_check_expire_time (ccw_req_t * cqr) (long) (cqr->expires >> 44), (long) (cqr->expires >> 12), cqr); cqr->expires <<= 1; + rc = -EIO; } return rc; } @@ -1502,6 +1600,8 @@ dasd_process_queues (dasd_device_t * device) CQR_STATUS_ERROR, CQR_STATUS_FAILED); + asm volatile ("STCK %0":"=m" (qp->head->stopclk)); + } else if ((device->discipline->erp_action == NULL ) || ((erp_action = device->discipline->erp_action (qp->head)) == NULL) ) { @@ -1628,7 +1728,8 @@ dasd_process_queues (dasd_device_t * device) } } s390irq_spin_unlock_irqrestore (irq, flags); -} + +} /* end dasd_process_queues */ /* * function dasd_run_bh @@ -1703,28 +1804,30 @@ dasd_handle_state_change_pending (devstat_t * stat) printk (KERN_DEBUG PRINTK_HEADER "unable to find device for state change pending " - "interrupt: devno%04X\n", stat->devno); - } else { - /* re-activate first request in queue */ - cqr = (*device_addr)->queue.head; - - if (cqr->status == CQR_STATUS_PENDING) { - - DASD_MESSAGE (KERN_DEBUG, (*device_addr), - "%s", - "device request queue restarted by " - "state change pending interrupt\n"); - - del_timer (&(*device_addr)->timer); - - check_then_set (&cqr->status, - CQR_STATUS_PENDING, CQR_STATUS_QUEUED); + "interrupt: devno%04x\n", + stat->devno); + return; + } - dasd_schedule_bh (*device_addr); + /* re-activate first request in queue */ + cqr = (*device_addr)->queue.head; + + if (cqr->status == CQR_STATUS_PENDING) { + + DASD_MESSAGE (KERN_DEBUG, (*device_addr), "%s", + "device request queue restarted by " + "state change pending interrupt\n"); + + del_timer (&(*device_addr)->timer); + + check_then_set (&cqr->status, + CQR_STATUS_PENDING, CQR_STATUS_QUEUED); + + dasd_schedule_bh (*device_addr); + + } - } - } -} /* end dasd_handle_state_change_pending */ +} /* end dasd_handle_state_change_pending */ /* * function dasd_int_handler @@ -1740,44 +1843,66 @@ dasd_int_handler (int irq, void *ds, struct pt_regs *regs) dasd_era_t era = dasd_era_none; /* default is everything is okay */ devstat_t *stat = (devstat_t *)ds; - DASD_DRIVER_DEBUG_EVENT (4, dasd_int_handler, - "Interrupt: IRQ 0x%x",irq); + DASD_DRIVER_DEBUG_EVENT (6, dasd_int_handler, + "Interrupt: IRQ %02x, stat %02x, devno %04x", + irq, + stat->dstat, + stat->devno); asm volatile ("STCK %0":"=m" (now)); if (stat == NULL) { BUG(); } /* first of all check for state change pending interrupt */ - if (stat->dstat & (DEV_STAT_ATTENTION | - DEV_STAT_DEV_END | - DEV_STAT_UNIT_EXCEP )) { + if ((stat->dstat & DEV_STAT_ATTENTION ) && + (stat->dstat & DEV_STAT_DEV_END ) && + (stat->dstat & DEV_STAT_UNIT_EXCEP) ) { DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler, - "State change Interrupt: %04X", + "State change Interrupt: %04x", stat->devno); dasd_handle_state_change_pending (stat); - //return; /* TBD */ + return; } ip = stat->intparm; if (!ip) { /* no intparm: unsolicited interrupt */ DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler, - "Unsolicited Interrupt: %04X", + "Unsolicited Interrupt: %04x", stat->devno); printk (KERN_DEBUG PRINTK_HEADER - "unsolicited interrupt: irq0x%x devno%04X\n", - irq,stat->devno); + "unsolicited interrupt: irq 0x%x devno %04x\n", + irq, + stat->devno); return; } if (ip & 0x80000001) { DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler, - "spurious Interrupt: %04X", + "spurious Interrupt: %04x", stat->devno); printk (KERN_DEBUG PRINTK_HEADER - "spurious interrupt: irq0x%x devno%04X, parm %08x\n", - irq,stat->devno,ip); + "spurious interrupt: irq 0x%x devno %04x, parm %08x\n", + irq, + stat->devno,ip); return; } + cqr = (ccw_req_t *)(long)ip; + + /* check status - the request might have been killed because of dyn dettach */ + if (cqr->status != CQR_STATUS_IN_IO) { + DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler, + "invalid status %02x on device %04x", + cqr->status, + stat->devno); + + printk (KERN_DEBUG PRINTK_HEADER + "invalid status: irq 0x%x devno %04x, status %02x\n", + irq, + stat->devno, + cqr->status); + return; + } + device = (dasd_device_t *) cqr->device; if (device == NULL || device != ds-offsetof(dasd_device_t,dev_status)) { @@ -1789,46 +1914,11 @@ dasd_int_handler (int irq, void *ds, struct pt_regs *regs) if (strncmp (device->discipline->ebcname, (char *) &cqr->magic, 4)) { BUG(); } -#ifdef ERP_FAKE - { - static int counter = 0; - static int fake_count = 0; - if ((++counter % 937 >= 0) && - ( counter % 937 <= 10) && - ( counter < 5000) && - ( counter > 2000) ) { - - char *sense = stat->ii.sense.data; - - printk (KERN_INFO PRINTK_HEADER - "***********************************************\n"); - printk (KERN_INFO PRINTK_HEADER - "Faking I/O error to recover from; cntr=%i / %02X\n", - counter, ++fake_count); - printk (KERN_INFO PRINTK_HEADER - "***********************************************\n"); - - era = dasd_era_recover; - stat->flag |= DEVSTAT_FLAG_SENSE_AVAIL; - stat->dstat |= 0x02; - memset(sense,0,32); - - /* 32 byte sense (byte 27 bit 1 = 0)*/ - sense[25] = 0x1D; -// sense [25] = (fake_count % 256); //0x1B; - - /* 24 byte sense (byte 27 bit 1 = 1)*/ -// sense [0] = (counter % 0xFF); //0x1B; -// sense [1] = ((counter * 7) % 0xFF); //0x1B; -// sense [2] = (fake_count % 0xFF); //0x1B; -// sense [27] = 0x80; - } - } -#endif /* ERP_FAKE */ /* first of all lets try to find out the appropriate era_action */ - DASD_DEVICE_DEBUG_EVENT (4, device," Int: CS/DS 0x%04X", + DASD_DEVICE_DEBUG_EVENT (4, device," Int: CS/DS 0x%04x", ((stat->cstat<<8)|stat->dstat)); + /* first of all lets try to find out the appropriate era_action */ if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL || stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) { @@ -1844,7 +1934,9 @@ dasd_int_handler (int irq, void *ds, struct pt_regs *regs) } if ( era == dasd_era_none ) { check_then_set(&cqr->status, - CQR_STATUS_IN_IO, CQR_STATUS_DONE); + CQR_STATUS_IN_IO, + CQR_STATUS_DONE); + cqr->stopclk=now; /* start the next queued request if possible -> fast_io */ if (cqr->next && @@ -1875,11 +1967,15 @@ dasd_int_handler (int irq, void *ds, struct pt_regs *regs) switch (era) { case dasd_era_fatal: - check_then_set (&cqr->status, CQR_STATUS_IN_IO, + check_then_set (&cqr->status, + CQR_STATUS_IN_IO, CQR_STATUS_FAILED); + + cqr->stopclk = now; break; case dasd_era_recover: - check_then_set (&cqr->status, CQR_STATUS_IN_IO, + check_then_set (&cqr->status, + CQR_STATUS_IN_IO, CQR_STATUS_ERROR); break; default: @@ -1894,7 +1990,8 @@ dasd_int_handler (int irq, void *ds, struct pt_regs *regs) wake_up (&dasd_init_waitq); } dasd_schedule_bh (device); -} + +} /* end dasd_int_handler */ /* SECTION: Some stuff related to error recovery */ @@ -1929,13 +2026,15 @@ dasd_default_erp_action (ccw_req_t * cqr) CQR_STATUS_ERROR, CQR_STATUS_FAILED); + asm volatile ("STCK %0":"=m" (cqr->stopclk)); + return cqr; } erp->cpaddr->cmd_code = CCW_CMD_TIC; erp->cpaddr->cda = (__u32) (void *) cqr->cpaddr; erp->function = dasd_default_erp_action; - erp->refers = (unsigned int) (unsigned long) cqr; + erp->refers = cqr; erp->device = cqr->device; erp->magic = cqr->magic; erp->retries = 16; @@ -1946,7 +2045,8 @@ dasd_default_erp_action (ccw_req_t * cqr) erp); return erp; -} + +} /* end dasd_default_erp_action */ /* * DEFAULT_ERP_POSTACTION @@ -2012,6 +2112,8 @@ dasd_default_erp_postaction (ccw_req_t *erp) check_then_set (&cqr->status, CQR_STATUS_ERROR, CQR_STATUS_FAILED); + + asm volatile ("STCK %0":"=m" (cqr->stopclk)); } return cqr; @@ -2040,8 +2142,10 @@ dasd_format (dasd_device_t * device, format_data_t * fdata) } DASD_MESSAGE (KERN_INFO, device, "formatting units %d to %d (%d B blocks) flags %d", - fdata->start_unit, fdata->stop_unit, - fdata->blksize, fdata->intensity); + fdata->start_unit, + fdata->stop_unit, + fdata->blksize, + fdata->intensity); while ((!rc) && (fdata->start_unit <= fdata->stop_unit)) { ccw_req_t *req; dasd_format_fn_t ffn = device->discipline->format_device; @@ -2060,8 +2164,10 @@ dasd_format (dasd_device_t * device, format_data_t * fdata) break; } dasd_free_request (req, device); /* request is no longer used */ - if ( signal_pending(current) ) + if ( signal_pending(current) ) { + rc = -ERESTARTSYS; break; + } fdata->start_unit++; } return rc; @@ -2126,7 +2232,13 @@ dasd_revalidate (dasd_device_t * device) } for (i = (1 << DASD_PARTN_BITS) - 1; i >= 0; i--) { int major = device->major_info->gendisk.major; - invalidate_device(MKDEV (major, start+i), 1); + int minor = start + i; + kdev_t devi = MKDEV (major, minor); + struct super_block *sb = get_super (devi); + //sync_dev (devi); + if (sb) + invalidate_inodes (sb); + invalidate_buffers (devi); } dasd_destroy_partitions(device); dasd_setup_partitions(device); @@ -2143,7 +2255,8 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) if (!device) { printk (KERN_WARNING PRINTK_HEADER "No device registered as device (%d:%d)\n", - MAJOR (inp->i_rdev), MINOR (inp->i_rdev)); + MAJOR (inp->i_rdev), + MINOR (inp->i_rdev)); return -EINVAL; } if ((_IOC_DIR (no) != _IOC_NONE) && (data == 0)) { @@ -2154,15 +2267,21 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) #if 0 printk (KERN_DEBUG PRINTK_HEADER "ioctl 0x%08x %s'0x%x'%d(%d) on /dev/%s (%d:%d," - " devno 0x%04X on irq %d) with data %8lx\n", + " devno 0x%04x on irq %d) with data %8lx\n", no, _IOC_DIR (no) == _IOC_NONE ? "0" : _IOC_DIR (no) == _IOC_READ ? "r" : _IOC_DIR (no) == _IOC_WRITE ? "w" : _IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u", - _IOC_TYPE (no), _IOC_NR (no), _IOC_SIZE (no), - device->name, MAJOR (inp->i_rdev), MINOR (inp->i_rdev), - device->devinfo.devno, device->devinfo.irq, data); + _IOC_TYPE (no), + _IOC_NR (no), + _IOC_SIZE (no), + device->name, + MAJOR (inp->i_rdev), + MINOR (inp->i_rdev), + device->devinfo.devno, + device->devinfo.irq, + data); #endif switch (no) { case DASDAPIVER: { @@ -2175,13 +2294,11 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) case BLKGETSIZE:{ /* Return device size */ long blocks = major_info->gendisk.sizes [MINOR (inp->i_rdev)] << 1; - rc = put_user(blocks, (long *)arg); - break; - } - case BLKGETSIZE64:{ - u64 blocks = major_info->gendisk.sizes - [MINOR (inp->i_rdev)]; - rc = put_user(blocks << 10, (u64 *)arg); + rc = + copy_to_user ((long *) data, &blocks, + sizeof (long)); + if (rc) + rc = -EFAULT; break; } case BLKRRPART:{ @@ -2210,6 +2327,7 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) break; } if ( device->level > DASD_STATE_ACCEPT) { + dasd_deactivate_queue(device); if ( device->request_queue) dasd_flush_request_queues(device,0); dasd_flush_chanq(device,0); @@ -2264,7 +2382,7 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) rc = dasd_format (device, &fdata); break; } - case BIODASDPRRST:{ + case BIODASDPRRST:{ /* reset device profile information */ if (!capable (CAP_SYS_ADMIN)) { rc = -EACCES; break; @@ -2273,7 +2391,7 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) sizeof (dasd_profile_info_t)); break; } - case BIODASDPRRD:{ + case BIODASDPRRD:{ /* retrun device profile information */ rc = copy_to_user((long *)data, (long *)&device->profile, sizeof(dasd_profile_info_t)); @@ -2281,7 +2399,7 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) rc = -EFAULT; break; } - case BIODASDRSRV:{ + case BIODASDRSRV:{ /* reserve */ ccw_req_t *req; if (!capable (CAP_SYS_ADMIN)) { rc = -EACCES; @@ -2292,7 +2410,7 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) dasd_free_request (req, device); break; } - case BIODASDRLSE:{ + case BIODASDRLSE:{ /* release */ ccw_req_t *req; if (!capable (CAP_SYS_ADMIN)) { rc = -EACCES; @@ -2303,9 +2421,15 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) dasd_free_request (req, device); break; } - case BIODASDSLCK:{ - printk (KERN_WARNING PRINTK_HEADER - "Unsupported ioctl BIODASDSLCK\n"); + case BIODASDSLCK:{ /* steal lock - unconditional reserve */ + ccw_req_t *req; + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + req = device->discipline->steal_lock (device); + rc = dasd_sleep_on_req (req); + dasd_free_request (req, device); break; } case BIODASDINFO:{ @@ -2398,11 +2522,12 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) no, _IOC_DIR (no) == _IOC_NONE ? "0" : _IOC_DIR (no) == _IOC_READ ? "r" : - _IOC_DIR (no) == - _IOC_WRITE ? "w" : _IOC_DIR (no) - == (_IOC_READ | _IOC_WRITE) ? "rw" - : "u", _IOC_TYPE (no), - _IOC_NR (no), _IOC_SIZE (no), + _IOC_DIR (no) == _IOC_WRITE ? "w" : + _IOC_DIR (no) == + (_IOC_READ | _IOC_WRITE) ? "rw" : "u", + _IOC_TYPE (no), + _IOC_NR (no), + _IOC_SIZE (no), data); rc = -ENOTTY; } @@ -2441,7 +2566,8 @@ dasd_open (struct inode *inp, struct file *filp) if (dasd_probeonly) { printk ("\n" KERN_INFO PRINTK_HEADER "No access to device (%d:%d) due to probeonly mode\n", - MAJOR (inp->i_rdev), MINOR (inp->i_rdev)); + MAJOR (inp->i_rdev), + MINOR (inp->i_rdev)); rc = -EPERM; goto fail; } @@ -2450,13 +2576,14 @@ dasd_open (struct inode *inp, struct file *filp) if (device == NULL ) { printk (KERN_WARNING PRINTK_HEADER "No device registered as (%d:%d)\n", - MAJOR (inp->i_rdev), MINOR (inp->i_rdev)); + MAJOR (inp->i_rdev), + MINOR (inp->i_rdev)); rc = -ENODEV; goto unlock; } - if (device->level < DASD_STATE_ACCEPT ) { - DASD_MESSAGE (KERN_WARNING, device, - " %s", " Cannot open unrecognized device\n"); + if (device->level <= DASD_STATE_ACCEPT ) { + DASD_MESSAGE (KERN_WARNING, device, " %s", + " Cannot open unrecognized device\n"); rc = -ENODEV; goto unlock; } @@ -2473,6 +2600,11 @@ dasd_open (struct inode *inp, struct file *filp) return rc; } +/* + * DASD_RELEASE + * + * DESCRIPTION + */ static int dasd_release (struct inode *inp, struct file *filp) { @@ -2488,17 +2620,19 @@ dasd_release (struct inode *inp, struct file *filp) if (device == NULL) { printk (KERN_WARNING PRINTK_HEADER "No device registered as %d:%d\n", - MAJOR (inp->i_rdev), MINOR (inp->i_rdev)); + MAJOR (inp->i_rdev), + MINOR (inp->i_rdev)); rc = -EINVAL; goto out; } if (device->level < DASD_STATE_ACCEPT ) { - DASD_MESSAGE (KERN_WARNING, device, - " %s", " Cannot release unrecognized device\n"); + DASD_MESSAGE (KERN_WARNING, device, " %s", + " Cannot release unrecognized device\n"); rc = -ENODEV; goto out; } + // fsync_dev (inp->i_rdev); /* sync the device */ count = atomic_dec_return (&device->open_count); if ( count == 0) { invalidate_buffers (inp->i_rdev); @@ -2604,11 +2738,14 @@ dasd_flush_chanq ( dasd_device_t * device, int destroy ) s390irq_spin_lock_irqsave (device->devinfo.irq, flags); cqr = device->queue.head; while ( cqr != NULL ) { - if ( cqr -> status == CQR_STATUS_IN_IO ) + if ( cqr->status == CQR_STATUS_IN_IO ) device->discipline->term_IO (cqr); if ( cqr->status != CQR_STATUS_DONE || cqr->status != CQR_STATUS_FAILED ) { + cqr->status = CQR_STATUS_FAILED; + asm volatile ("STCK %0":"=m" (cqr->stopclk)); + } dasd_schedule_bh(device); cqr = cqr->next; @@ -2638,29 +2775,26 @@ dasd_disable_volume ( dasd_device_t * device, int force ) int rc = 0; int target = DASD_STATE_KNOWN; int count = atomic_read (&device->open_count); - int part; if ( count ) { DASD_MESSAGE (KERN_EMERG, device, "%s", "device has vanished although it was open!"); } if ( force ) { + dasd_deactivate_queue(device); dasd_flush_chanq(device,force); dasd_flush_request_queues(device,force); dasd_disable_blkdev(device); target = DASD_STATE_DEL; } -#if 0 - /* unregister devfs entries */ - for (part = 0; part < (1 << DASD_PARTN_BITS); part++) { - devfs_unregister(device->major_info->gendisk.part[MINOR(device->kdev)+part].de); - device->major_info->gendisk.part[MINOR(device->kdev)+part].de = NULL; - } -#endif + /* unregister partitions ('ungrok_partitions') */ + devfs_register_partitions(&device->major_info->gendisk, + MINOR(device->kdev),1); DASD_MESSAGE (KERN_WARNING, device, - "disabling device, target state:%d",target); + "disabling device, target state: %d",target); + dasd_set_device_level (device->devinfo.devno, device->discipline, target); @@ -2777,9 +2911,14 @@ dasd_enable_ranges (dasd_range_t *range, dasd_discipline_t *d, int all ) device->level >= DASD_STATE_READY && device->request_queue == NULL ) { if (dasd_features_from_devno(j)&DASD_FEATURE_READONLY) { - for (tempdev=device->kdev;tempdev<(device->kdev +(1 << DASD_PARTN_BITS));tempdev++) - set_device_ro (tempdev, 1); - printk (KERN_WARNING PRINTK_HEADER "setting read-only mode for device /dev/%s\n",device->name); + for (tempdev=device->kdev; + tempdev<(device->kdev +(1 << DASD_PARTN_BITS)); + tempdev++) + set_device_ro (tempdev, 1); + + printk (KERN_WARNING PRINTK_HEADER + "setting read-only mode for device /dev/%s\n", + device->name); } dasd_setup_blkdev(device); dasd_setup_partitions(device); @@ -2790,6 +2929,12 @@ dasd_enable_ranges (dasd_range_t *range, dasd_discipline_t *d, int all ) } #ifdef CONFIG_DASD_DYNAMIC +/* + * DASD_NOT_OPER_HANDLER + * + * DESCRIPTION + * handles leaving devices + */ static void dasd_not_oper_handler (int irq, int status) { @@ -2811,14 +2956,26 @@ dasd_not_oper_handler (int irq, int status) if (devno != -ENODEV) break; } + + DASD_DRIVER_DEBUG_EVENT (5, dasd_not_oper_handler, + "called for devno %04x", + devno); + if (devno < 0) { printk (KERN_WARNING PRINTK_HEADER - "not_oper_handler called on irq %d no devno!\n", irq); + "not_oper_handler called on irq 0x%04x no devno!\n", + irq); return; } - dasd_disable_volume(device, 0); + dasd_disable_volume(device, 1); } +/* + * DASD_OPER_HANDLER + * + * DESCRIPTION + * called by the machine check handler to make an device operational + */ int dasd_oper_handler (int irq, devreg_t * devreg) { @@ -2835,7 +2992,12 @@ dasd_oper_handler (int irq, devreg_t * devreg) rc = -ENODEV; goto out; } - /* find out devno of leaving device: CIO has already deleted this information ! */ + + DASD_DRIVER_DEBUG_EVENT (5, dasd_oper_handler, + "called for devno %04x", + devno); + + /* find out devno of device */ list_for_each (l, &dasd_major_info[0].list) { major_info = list_entry (l, major_info_t, list); for (i = 0; i < DASD_PER_MAJOR; i++) { @@ -2881,10 +3043,11 @@ dasd_find_device_addr ( int devno ) dasd_device_t **device_addr; DASD_DRIVER_DEBUG_EVENT (1, dasd_find_device_addr, - "devno %04X", devno); + "devno %04x", + devno); if ( dasd_devindex_from_devno (devno) < 0 ) { DASD_DRIVER_DEBUG_EXCEPTION (1, dasd_find_device_addr, - "no dasd: devno %04X", + "no dasd: devno %04x", devno); return NULL; } @@ -2996,6 +3159,13 @@ dasd_state_new_to_known (dasd_device_t **dptr, int devno, dasd_discipline_t *dis if ( rc ) { goto out; } + + DASD_DRIVER_DEBUG_EVENT (5, dasd_state_new_to_known, + "got devinfo CU-type %04x and dev-type %04x", + device->devinfo.sid_data.cu_type, + device->devinfo.sid_data.dev_type); + + if ( devno != device->devinfo.devno ) BUG(); device->discipline = dasd_find_disc (device, disc); @@ -3003,7 +3173,8 @@ dasd_state_new_to_known (dasd_device_t **dptr, int devno, dasd_discipline_t *dis rc = -ENODEV; goto out; } - sprintf (buffer, "%04x", device->devinfo.devno); + sprintf (buffer, "%04x", + device->devinfo.devno); dir = devfs_mk_dir (dasd_devfs_handle, buffer, device); device->major_info->gendisk.de_arr[MINOR(device->kdev) >> DASD_PARTN_BITS] = dir; @@ -3039,7 +3210,8 @@ dasd_state_known_to_accept (dasd_device_t *device) 3 * sizeof (long)); debug_register_view (device->debug_area, &debug_sprintf_view); debug_register_view (device->debug_area, &debug_hex_ascii_view); - DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area created",device); + DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area created", + device); if (device->discipline->int_handler) { rc = s390_request_irq_special (device->devinfo.irq, @@ -3065,7 +3237,8 @@ dasd_state_accept_to_known (dasd_device_t *device ) if (device->discipline->int_handler) { free_irq (device->devinfo.irq, &device->dev_status); } - DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area deleted",device); + DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area deleted", + device); if ( device->debug_area != NULL ) debug_unregister (device->debug_area); device->discipline = NULL; @@ -3080,6 +3253,10 @@ dasd_state_accept_to_init (dasd_device_t *device) int rc = 0; unsigned long flags; + printk (KERN_ERR PRINTK_HEADER + "called dasd_state_accept_to_init for device %02x\n", + device->devinfo.devno); + if ( device->discipline->init_analysis ) { device->init_cqr=device->discipline->init_analysis (device); if ( device->init_cqr != NULL ) { @@ -3197,6 +3374,18 @@ dasd_setup_blkdev (dasd_device_t *device ) return rc; } +static void +dasd_deactivate_queue (dasd_device_t *device) +{ + int i; + int major = MAJOR(device->kdev); + int minor = MINOR(device->kdev); + + for (i = 0; i < (1 << DASD_PARTN_BITS); i++) { + device->major_info->gendisk.sizes[minor + i] = 0; + } +} + static inline int dasd_disable_blkdev (dasd_device_t *device ) { @@ -3238,7 +3427,6 @@ static inline void dasd_destroy_partitions ( dasd_device_t * device ) { int i; - int major = MAJOR(device->kdev); int minor = MINOR(device->kdev); for (i = 0; i < (1 << DASD_PARTN_BITS); i++) { @@ -3285,6 +3473,12 @@ dasd_set_device_level (unsigned int devno, from_state = device->level; } + DASD_DRIVER_DEBUG_EVENT (3, dasd_set_device_level, + "devno %04x; from %i to %i", + devno, + from_state, + to_state); + if ( from_state == to_state ) goto out; @@ -3340,8 +3534,12 @@ dasd_set_device_level (unsigned int devno, bringup_fail: /* revert changes */ #if 0 printk (KERN_DEBUG PRINTK_HEADER - "failed to set device from state %d to %d at level %d rc %d. Reverting...\n", - from_state,to_state,device->level,rc); + "failed to set device from state %d to %d at " + "level %d rc %d. Reverting...\n", + from_state, + to_state, + device->level, + rc); #endif to_state = from_state; from_state = device->level; @@ -3352,18 +3550,22 @@ dasd_set_device_level (unsigned int devno, to_state <= DASD_STATE_READY ) if (dasd_state_online_to_ready(device)) BUG(); + if ( from_state >= DASD_STATE_READY && - to_state <= DASD_STATE_ACCEPT ) + to_state <= DASD_STATE_ACCEPT ) if ( dasd_state_ready_to_accept(device)) BUG(); + if ( from_state >= DASD_STATE_ACCEPT && to_state <= DASD_STATE_KNOWN ) if ( dasd_state_accept_to_known(device)) BUG(); + if ( from_state >= DASD_STATE_KNOWN && to_state <= DASD_STATE_NEW ) if ( dasd_state_known_to_new(device)) BUG(); + if ( from_state >= DASD_STATE_NEW && to_state <= DASD_STATE_DEL) if (dasd_state_new_to_del(device_addr)) @@ -3420,7 +3622,8 @@ dasd_devices_open (struct inode *inode, struct file *file) } info->data = (char *) vmalloc (size); DASD_DRIVER_DEBUG_EVENT (1, dasd_devices_open, "area: %p, size 0x%x", - info->data, size); + info->data, + size); if (size && info->data == NULL) { printk (KERN_WARNING "No memory available for data\n"); vfree (info); @@ -3437,7 +3640,7 @@ dasd_devices_open (struct inode *inode, struct file *file) device = temp->dasd_device[i]; if (device) { len += sprintf (info->data + len, - "%04X(%s) at (%3d:%3d) is %7s:", + "%04x(%s) at (%3d:%3d) is %7s:", device->devinfo.devno, device->discipline ? device-> @@ -3506,7 +3709,7 @@ dasd_devices_open (struct inode *inode, struct file *file) "none"); } else { len += sprintf (info->data + len, - "%04X",devno); + "%04x",devno); } len += sprintf (info->data + len, "(none) at (%3d:%3d) is %7s: unknown", @@ -3591,22 +3794,31 @@ dasd_devices_write (struct file *file, const char *user_buf, range.to = dasd_strtoul (temp, &temp, &features); } - off = (long) temp - (long) buffer; - if (!strncmp (buffer, "add", strlen ("add"))) { - dasd_add_range (range.from, range.to, features); - dasd_enable_ranges (&range, NULL, 0); - } else { - while (buffer[off] && !isalnum (buffer[off])) - off++; - if (!strncmp (buffer + off, "on", strlen ("on"))) { - dasd_enable_ranges (&range, NULL, 0); - } else if (!strncmp (buffer + off, "off", strlen ("off"))) { - dasd_disable_ranges (&range, NULL, 0, 1); - } else { - printk (KERN_WARNING PRINTK_HEADER - "/proc/dasd/devices: parse error in '%s'", buffer); - } - } + if (range.from == -EINVAL || + range.to == -EINVAL ) { + + printk (KERN_WARNING PRINTK_HEADER + "/proc/dasd/devices: parse error in '%s'", + buffer); + } else { + off = (long) temp - (long) buffer; + if (!strncmp (buffer, "add", strlen ("add"))) { + dasd_add_range (range.from, range.to, features); + dasd_enable_ranges (&range, NULL, 0); + } else { + while (buffer[off] && !isalnum (buffer[off])) + off++; + if (!strncmp (buffer + off, "on", strlen ("on"))) { + dasd_enable_ranges (&range, NULL, 0); + } else if (!strncmp (buffer + off, "off", strlen ("off"))) { + dasd_disable_ranges (&range, NULL, 0, 1); + } else { + printk (KERN_WARNING PRINTK_HEADER + "/proc/dasd/devices: parse error in '%s'", buffer); + } + } + } + vfree (buffer); return user_len; } @@ -3660,112 +3872,124 @@ dasd_statistics_open (struct inode *inode, struct file *file) MOD_DEC_USE_COUNT; return -ENOMEM; } + + /* prevent couter 'ouverflow' on output */ for (shift = 0, help = dasd_global_profile.dasd_io_reqs; - help > 8192; help = help >> 1, shift++) ; - len = - sprintf (info->data, "%d dasd I/O requests\n", - dasd_global_profile.dasd_io_reqs); - len += - sprintf (info->data + len, "with %d sectors(512B each)\n", - dasd_global_profile.dasd_io_sects); - len += - sprintf (info->data + len, - "__<4 ___8 __16 __32 __64 _128 _256 _512 __1k __2k __4k __8k _16k _32k _64k 128k\n"); - len += - sprintf (info->data + len, - "_256 _512 __1M __2M __4M __8M _16M _32M _64M 128M 256M 512M __1G __2G __4G _>4G\n"); + help > 9999999; help = help >> 1, shift++) ; + + len = sprintf (info->data, "%d dasd I/O requests\n", + dasd_global_profile.dasd_io_reqs); + len += sprintf (info->data + len, "with %d sectors(512B each)\n", + dasd_global_profile.dasd_io_sects); + + len += sprintf (info->data + len, + " __<4 ___8 __16 __32 __64 " + " _128 _256 _512 __1k __2k " + " __4k __8k _16k _32k _64k " + " 128k\n"); + + len += sprintf (info->data + len, + " _256 _512 __1M __2M __4M " + " __8M _16M _32M _64M 128M " + " 256M 512M __1G __2G __4G " + " _>4G\n"); + len += sprintf (info->data + len, "Histogram of sizes (512B secs)\n"); for (i = 0; i < 16; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_secs[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_secs[i] >> shift); } len += sprintf (info->data + len, "\n"); + len += sprintf (info->data + len, "Histogram of I/O times\n"); for (i = 0; i < 16; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_times[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_times[i] >> shift); } len += sprintf (info->data + len, "\n"); for (; i < 32; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_times[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_times[i] >> shift); } len += sprintf (info->data + len, "\n"); - len += - sprintf (info->data + len, "Histogram of I/O times per sector\n"); + + len += sprintf (info->data + len, "Histogram of I/O times per sector\n"); for (i = 0; i < 16; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_timps[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_timps[i] >> shift); } len += sprintf (info->data + len, "\n"); for (; i < 32; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_timps[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_timps[i] >> shift); } len += sprintf (info->data + len, "\n"); + len += sprintf (info->data + len, "Histogram of I/O time till ssch\n"); for (i = 0; i < 16; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_time1[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_time1[i] >> shift); } len += sprintf (info->data + len, "\n"); for (; i < 32; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_time1[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_time1[i] >> shift); } len += sprintf (info->data + len, "\n"); - len += - sprintf (info->data + len, - "Histogram of I/O time between ssch and irq\n"); + + len += sprintf (info->data + len, + "Histogram of I/O time between ssch and irq\n"); for (i = 0; i < 16; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_time2[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_time2[i] >> shift); } len += sprintf (info->data + len, "\n"); for (; i < 32; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_time2[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_time2[i] >> shift); } len += sprintf (info->data + len, "\n"); - len += - sprintf (info->data + len, - "Histogram of I/O time between ssch and irq per sector\n"); + + len += sprintf (info->data + len, + "Histogram of I/O time between ssch and irq per sector\n"); for (i = 0; i < 16; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_time2ps[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_time2ps[i] >> shift); } len += sprintf (info->data + len, "\n"); for (; i < 32; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_time2ps[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_time2ps[i] >> shift); } len += sprintf (info->data + len, "\n"); - len += - sprintf (info->data + len, - "Histogram of I/O time between irq and end\n"); + + len += sprintf (info->data + len, + "Histogram of I/O time between irq and end\n"); for (i = 0; i < 16; i++) { len += - sprintf (info->data + len, "%4d ", + sprintf (info->data + len, "%7d ", dasd_global_profile.dasd_io_time3[i] >> shift); } len += sprintf (info->data + len, "\n"); for (; i < 32; i++) { - len += - sprintf (info->data + len, "%4d ", - dasd_global_profile.dasd_io_time3[i] >> shift); + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_time3[i] >> shift); + } + len += sprintf (info->data + len, "\n"); + + len += sprintf (info->data + len, + "# of req in chanq at enqueuing (1..32) \n"); + for (i = 0; i < 16; i++) { + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_nr_req[i] >> shift); } len += sprintf (info->data + len, "\n"); + for (; i < 32; i++) { + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_nr_req[i] >> shift); + } + len += sprintf (info->data + len, "\n"); + info->len = len; return rc; } @@ -3838,7 +4062,9 @@ dasd_request_module ( void *name ) { } while ( (rc=request_module(name)) != 0 ) { DECLARE_WAIT_QUEUE_HEAD(wait); - printk ( KERN_INFO "request_module returned %d for %s\n",rc,(char*)name); + printk ( KERN_INFO "request_module returned %d for %s\n", + rc, + (char*)name); sleep_on_timeout(&wait,5* HZ); /* wait in steps of 5 seconds */ } return rc; @@ -3855,7 +4081,7 @@ dasd_init (void) struct list_head *l; printk (KERN_INFO PRINTK_HEADER "initializing...\n"); - dasd_debug_area = debug_register (DASD_NAME, 0, 2, 4 * sizeof (long)); + dasd_debug_area = debug_register (DASD_NAME, 0, 2, 5 * sizeof (long)); debug_register_view (dasd_debug_area, &debug_sprintf_view); debug_register_view (dasd_debug_area, &debug_hex_ascii_view); @@ -3864,10 +4090,12 @@ dasd_init (void) if (dasd_debug_area == NULL) { goto failed; } - DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s", "ENTRY"); + DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s", + "ENTRY"); dasd_devfs_handle = devfs_mk_dir (NULL, DASD_NAME, NULL); if (dasd_devfs_handle < 0) { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", "no devfs"); + DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", + "no devfs"); goto failed; } list_for_each (l, &dasd_major_info[0].list) { @@ -3893,7 +4121,12 @@ dasd_init (void) #ifndef MODULE dasd_split_parm_string (dasd_parm_string); #endif /* ! MODULE */ - dasd_parse (dasd); + rc = dasd_parse (dasd); + if (rc) { + DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", + "invalid range found"); + goto failed; + } rc = dasd_proc_init (); if (rc) { @@ -3909,7 +4142,7 @@ dasd_init (void) int index = dasd_devindex_from_devno (devno); if (index == -ENODEV) { /* not included in ranges */ DASD_DRIVER_DEBUG_EVENT (2, dasd_init, - "add %04X to range", + "add %04x to range", devno); dasd_add_range (devno, devno, DASD_DEFAULT_FEATURES); } diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index c589c022c56f..4ba50f2f68e9 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -1724,8 +1724,16 @@ dasd_3990_erp_env_data (ccw_req_t *erp, dasd_3990_handle_env_data (erp, sense); - erp = dasd_3990_erp_action_4 (erp, - sense); + /* don't retry on disabled interface */ + if (sense[7] != 0x0F) { + + erp = dasd_3990_erp_action_4 (erp, + sense); + } else { + + erp = dasd_3990_erp_cleanup (erp, + CQR_STATUS_IN_IO); + } return erp; diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index be5ac9e8be84..c203c15273ab 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -158,9 +158,6 @@ dasd_start_diag (ccw_req_t * cqr) CQR_STATUS_QUEUED, CQR_STATUS_DONE); dasd_schedule_bh (device); } else { - if (cqr->expires) { - cqr->expires += cqr->startclk; - } check_then_set (&cqr->status, CQR_STATUS_QUEUED, CQR_STATUS_IN_IO); rc = 0; @@ -178,6 +175,8 @@ dasd_ext_handler (struct pt_regs *regs, __u16 code) dasd_device_t *device; int done_fast_io = 0; int devno; + unsigned long flags; + irq_enter(cpu, -1); @@ -195,6 +194,7 @@ dasd_ext_handler (struct pt_regs *regs, __u16 code) } cqr = (ccw_req_t *) ip; device = (dasd_device_t *) cqr->device; + devno = device->devinfo.devno; if (device == NULL) { printk (KERN_WARNING PRINTK_HEADER @@ -214,7 +214,13 @@ dasd_ext_handler (struct pt_regs *regs, __u16 code) irq_exit(cpu, -1); return; } + + /* get irq lock to modify request queue */ + s390irq_spin_lock_irqsave (device->devinfo.irq, + flags); + asm volatile ("STCK %0":"=m" (cqr->stopclk)); + switch (status) { case 0x00: check_then_set (&cqr->status, @@ -233,9 +239,14 @@ dasd_ext_handler (struct pt_regs *regs, __u16 code) CQR_STATUS_IN_IO, CQR_STATUS_FAILED); break; } + + s390irq_spin_unlock_irqrestore (device->devinfo.irq, + flags); + wake_up (&device->wait_q); dasd_schedule_bh (device); irq_exit(cpu, -1); + } static int diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 844e8b969806..416597a99b3b 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -209,7 +209,7 @@ define_extent (ccw1_t * de_ccw, memset (de_ccw, 0, sizeof (ccw1_t)); de_ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT; de_ccw->count = 16; - if (rc=dasd_set_normalized_cda (de_ccw, __pa (data), cqr, device)) + if ((rc=dasd_set_normalized_cda (de_ccw, __pa (data), cqr, device))) return rc; memset (data, 0, sizeof (DE_eckd_data_t)); @@ -283,7 +283,7 @@ locate_record (ccw1_t * lo_ccw, memset (lo_ccw, 0, sizeof (ccw1_t)); lo_ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD; lo_ccw->count = 16; - if (rc=dasd_set_normalized_cda (lo_ccw, __pa (data), cqr, device)) + if ((rc=dasd_set_normalized_cda (lo_ccw, __pa (data), cqr, device))) return rc; memset (data, 0, sizeof (LO_eckd_data_t)); @@ -1157,6 +1157,16 @@ dasd_eckd_cleanup_request (ccw_req_t * cqr) return ret; } #endif + +/* + * DASD_ECKD_RESERVE + * + * DESCRIPTION + * Buils a channel programm to reserve a device. + * Options are set to 'synchronous wait for interrupt' and + * 'timeout the request'. This leads to an terminate IO if + * the interrupt is outstanding for a certain time. + */ ccw_req_t * dasd_eckd_reserve (struct dasd_device_t * device) { @@ -1168,12 +1178,21 @@ dasd_eckd_reserve (struct dasd_device_t * device) return NULL; } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE; - cqr->device = device; + cqr->device = device; cqr->retries = 0; - cqr->status = CQR_STATUS_FILLED; - return cqr; + cqr->expires = 10 * TOD_SEC; + cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */ + cqr->status = CQR_STATUS_FILLED; + return cqr; } +/* + * DASD_ECKD_RELEASE + * + * DESCRIPTION + * Buils a channel programm to releases a prior reserved + * (see dasd_eckd_reserve) device. + */ ccw_req_t * dasd_eckd_release (struct dasd_device_t * device) { @@ -1185,13 +1204,41 @@ dasd_eckd_release (struct dasd_device_t * device) return NULL; } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE; - cqr->device = device; + cqr->device = device; cqr->retries = 0; - cqr->status = CQR_STATUS_FILLED; + cqr->expires = 10 * TOD_SEC; + cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */ + cqr->status = CQR_STATUS_FILLED; return cqr; } +/* + * DASD_ECKD_STEAL_LOCK + * + * DESCRIPTION + * Buils a channel programm to break a device's reservation. + * (unconditional reserve) + */ +ccw_req_t * +dasd_eckd_steal_lock (struct dasd_device_t * device) +{ + ccw_req_t *cqr = + dasd_alloc_request (dasd_eckd_discipline.name, 1 + 1, 0, device); + if (cqr == NULL) { + printk (KERN_WARNING PRINTK_HEADER + "No memory to allocate initialization request\n"); + return NULL; + } + cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK; + cqr->device = device; + cqr->retries = 0; + cqr->expires = 10 * TOD_SEC; + cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */ + cqr->status = CQR_STATUS_FILLED; + return cqr; +} + static inline ccw1_t * dasd_eckd_find_cmd (ccw_req_t * cqr, int cmd) { @@ -1335,6 +1382,7 @@ dasd_discipline_t dasd_eckd_discipline = { int_handler:dasd_int_handler, reserve:dasd_eckd_reserve, release:dasd_eckd_release, + steal_lock:dasd_eckd_steal_lock, merge_cp:dasd_eckd_merge_cp, fill_info:dasd_eckd_fill_info, }; diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h index b2b564104d4e..6ec10b4a8f71 100644 --- a/drivers/s390/block/dasd_eckd.h +++ b/drivers/s390/block/dasd_eckd.h @@ -26,6 +26,7 @@ #define DASD_ECKD_CCW_READ_CKD_MT 0x9e #define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d #define DASD_ECKD_CCW_RESERVE 0xB4 +#define DASD_ECKD_CCW_SLCK 0x14 /* steal lock - unconditional reserve */ typedef struct eckd_count_t { diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index d55de1aad2a9..f39fdcef9817 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -71,7 +71,7 @@ define_extent (ccw1_t * ccw, DE_fba_data_t * DE_data, int rw, memset (DE_data, 0, sizeof (DE_fba_data_t)); ccw->cmd_code = DASD_FBA_CCW_DEFINE_EXTENT; ccw->count = 16; - if (rc=dasd_set_normalized_cda (ccw, __pa (DE_data), cqr, device)) + if ((rc=dasd_set_normalized_cda (ccw, __pa (DE_data), cqr, device))) return rc; if (rw == WRITE) (DE_data->mask).perm = 0x0; diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index df0d3f83e26a..6224a23897ad 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -254,6 +254,7 @@ typedef ccw_req_t *(*dasd_cp_builder_fn_t)(struct dasd_device_t *,struct request typedef char *(*dasd_dump_sense_fn_t)(struct dasd_device_t *,ccw_req_t *); typedef ccw_req_t *(*dasd_reserve_fn_t)(struct dasd_device_t *); typedef ccw_req_t *(*dasd_release_fn_t)(struct dasd_device_t *); +typedef ccw_req_t *(*dasd_steal_lock_fn_t)(struct dasd_device_t *); typedef ccw_req_t *(*dasd_merge_cp_fn_t)(struct dasd_device_t *); typedef int (*dasd_info_fn_t) (struct dasd_device_t *, dasd_information_t *); typedef int (*dasd_use_count_fn_t) (int); @@ -286,6 +287,7 @@ typedef struct dasd_discipline_t { dasd_int_handler_fn_t int_handler; dasd_reserve_fn_t reserve; dasd_release_fn_t release; + dasd_steal_lock_fn_t steal_lock; dasd_merge_cp_fn_t merge_cp; dasd_info_fn_t fill_info; struct list_head list; /* used for list of disciplines */ diff --git a/drivers/s390/char/ctrlchar.c b/drivers/s390/char/ctrlchar.c index f2d3492d8e50..46b2dbeebfda 100644 --- a/drivers/s390/char/ctrlchar.c +++ b/drivers/s390/char/ctrlchar.c @@ -38,7 +38,7 @@ void ctrlchar_init(void) { return; INIT_LIST_HEAD(&ctrlchar_tq.list); ctrlchar_tq.sync = 0; - ctrlchar_tq.routine = ctrlchar_handle_sysrq; + ctrlchar_tq.routine = (void (*)(void *)) ctrlchar_handle_sysrq; #endif } diff --git a/drivers/s390/char/hwc_cpi.c b/drivers/s390/char/hwc_cpi.c index 404830c97e97..80eeb58e7366 100644 --- a/drivers/s390/char/hwc_cpi.c +++ b/drivers/s390/char/hwc_cpi.c @@ -16,6 +16,9 @@ #include "hwc_rw.h" #include "hwc.h" +#define CPI_RETRIES 3 +#define CPI_SLEEP_TICKS 50 + #define CPI_LENGTH_SYSTEM_TYPE 8 #define CPI_LENGTH_SYSTEM_NAME 8 #define CPI_LENGTH_SYSPLEX_NAME 8 @@ -84,6 +87,7 @@ cpi_module_init (void) int system_type_length; int system_name_length; int sysplex_name_length = 0; + int retries; if (!MACHINE_HAS_HWC) { printk ("cpi: bug: hardware console not present\n"); @@ -163,22 +167,30 @@ cpi_module_init (void) cpi_request.word = HWC_CMDW_WRITEDATA; cpi_request.callback = cpi_callback; - retval = hwc_send (&cpi_request); - if (retval) { - printk ("cpi: failed (%i)\n", retval); - goto free; - } - down (&sem); - - switch (cpi_hwcb->response_code) { - case 0x0020: - printk ("cpi: succeeded\n"); - break; - default: - printk ("cpi: failed with response code 0x%x\n", - cpi_hwcb->response_code); + for (retries = CPI_RETRIES; retries; retries--) { + retval = hwc_send (&cpi_request); + if (retval) { + + set_current_state (TASK_INTERRUPTIBLE); + schedule_timeout (CPI_SLEEP_TICKS); + } else { + + down (&sem); + + switch (cpi_hwcb->response_code) { + case 0x0020: + printk ("cpi: succeeded\n"); + break; + default: + printk ("cpi: failed with response code 0x%x\n", + cpi_hwcb->response_code); + } + goto free; + } } + printk ("cpi: failed (%i)\n", retval); + free: kfree (cpi_hwcb); diff --git a/drivers/s390/char/hwc_rw.c b/drivers/s390/char/hwc_rw.c index 37994da92f6f..63ce296c33f8 100644 --- a/drivers/s390/char/hwc_rw.c +++ b/drivers/s390/char/hwc_rw.c @@ -238,17 +238,18 @@ static signed int do_hwc_write (int from_user, unsigned char *, unsigned int, unsigned char); +unsigned char hwc_ip_buf[512]; + static asmlinkage int internal_print (char write_time, char *fmt,...) { va_list args; int i; - unsigned char buf[512]; va_start (args, fmt); - i = vsprintf (buf, fmt, args); + i = vsprintf (hwc_ip_buf, fmt, args); va_end (args); - return do_hwc_write (0, buf, i, write_time); + return do_hwc_write (0, hwc_ip_buf, i, write_time); } int @@ -256,15 +257,14 @@ hwc_printk (const char *fmt,...) { va_list args; int i; - unsigned char buf[512]; unsigned long flags; int retval; spin_lock_irqsave (&hwc_data.lock, flags); - i = vsprintf (buf, fmt, args); + i = vsprintf (hwc_ip_buf, fmt, args); va_end (args); - retval = do_hwc_write (0, buf, i, IMMEDIATE_WRITE); + retval = do_hwc_write (0, hwc_ip_buf, i, IMMEDIATE_WRITE); spin_unlock_irqrestore (&hwc_data.lock, flags); @@ -2098,10 +2098,10 @@ hwc_send (hwc_request_t * req) retval = -ENOTSUPP; goto unlock; } - hwc_data.request = req; cc = service_call (req->word, req->block); switch (cc) { case 0: + hwc_data.request = req; hwc_data.current_servc = req->word; hwc_data.current_hwcb = req->block; retval = 0; diff --git a/drivers/s390/misc/chandev.c b/drivers/s390/misc/chandev.c index 12d759963823..86bc96031d3e 100644 --- a/drivers/s390/misc/chandev.c +++ b/drivers/s390/misc/chandev.c @@ -599,9 +599,6 @@ static int chandev_exec_start_script(void *unused) chandev_unlock(); Fail2: - /* We don't really need to report /sbin/hotplug not existing */ - if(retval!=-ENOENT) - printk("chandev_exec_start_script failed retval=%d\n",retval); return(retval); } @@ -1140,6 +1137,7 @@ void chandev_reset(void) #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0) chandev_use_devno_names=FALSE; #endif + chandev_persistent=0; chandev_unlock(); } @@ -2225,7 +2223,7 @@ static char *argstrs[]= "unregister_probe_by_chan_type", "read_conf", "dont_read_conf", - "persistent" + "persist" }; typedef enum @@ -2262,7 +2260,7 @@ typedef enum unregister_probe_by_chan_type_stridx, read_conf_stridx, dont_read_conf_stridx, - persistent_stridx, + persist_stridx, last_stridx, } chandev_str_enum; @@ -2388,7 +2386,7 @@ static int chandev_get_string(char **instr,char **outstr) -static int chandev_setup(char *instr,char *errstr,int lineno) +static int chandev_setup(int in_read_conf,char *instr,char *errstr,int lineno) { chandev_strval val=isnull; chandev_str_enum stridx; @@ -2676,12 +2674,17 @@ static int chandev_setup(char *instr,char *errstr,int lineno) chandev_unregister_probe_by_chan_type((chandev_type)ints[1]); break; case read_conf_stridx*stridx_mult: + if(in_read_conf) + { + printk("attempt to recursively call read_conf\n"); + goto BadArgs; + } chandev_read_conf(); break; case dont_read_conf_stridx*stridx_mult: atomic_set(&chandev_conf_read,TRUE); break; - case (persistent_stridx*stridx_mult)|iscomma: + case (persist_stridx*stridx_mult)|iscomma: if(ints[0]==1) chandev_persistent=ints[1]; else @@ -2729,7 +2732,7 @@ static int chandev_setup_bootargs(char *str,int paramno) copystr=alloca(len+1); strncpy(copystr,str,len); copystr[len]=0; - if(chandev_setup(copystr,"at "CHANDEV_KEYWORD" bootparam no",paramno)==0) + if(chandev_setup(FALSE,copystr,"at "CHANDEV_KEYWORD" bootparam no",paramno)==0) return(0); return(len); @@ -2758,7 +2761,7 @@ static void __init chandev_parse_args(void) } } -int chandev_do_setup(char *buff,int size) +int chandev_do_setup(int in_read_conf,char *buff,int size) { int curr,comment=FALSE,newline=FALSE,oldnewline=TRUE; char *startline=NULL,*endbuff=&buff[size]; @@ -2787,7 +2790,7 @@ int chandev_do_setup(char *buff,int size) startline=buff; if(startline&&(buff>startline)&&(oldnewline==FALSE)&&(newline==TRUE)) { - if((chandev_setup(startline," on line no",lineno))==0) + if((chandev_setup(in_read_conf,startline," on line no",lineno))==0) return(-EINVAL); startline=NULL; } @@ -2835,7 +2838,7 @@ static void chandev_read_conf(void) close(fd); } set_fs(USER_DS); - chandev_do_setup(buff,statbuf.st_size); + chandev_do_setup(TRUE,buff,statbuf.st_size); vfree(buff); } } @@ -2898,7 +2901,7 @@ static int chandev_read_proc(char *page, char **start, off_t offset, chandev_printf(chan_exit,"\n%s\n" "*'s for cu/dev type/models indicate don't cares\n",chandev_keydescript); chandev_printf(chan_exit,"\ncautious_auto_detect: %s\n",chandev_cautious_auto_detect ? "on":"off"); - chandev_printf(chan_exit,"\nchandev_persistent = 0x%02x\n",chandev_persistent); + chandev_printf(chan_exit,"\npersist = 0x%02x\n",chandev_persistent); #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0) chandev_printf(chan_exit,"\nuse_devno_names: %s\n\n",chandev_use_devno_names ? "on":"off"); #endif @@ -3151,7 +3154,7 @@ static int chandev_write_proc(struct file *file, const char *buffer, rc = copy_from_user(buff,buffer,count); if (rc) goto chandev_write_exit; - chandev_do_setup(buff,count); + chandev_do_setup(FALSE,buff,count); rc=count; chandev_write_exit: vfree(buff); @@ -3212,13 +3215,25 @@ int chandev_register_and_probe(chandev_probefunc probefunc, chandev_msck_notification_func msck_notfunc, chandev_type chan_type) { - chandev_probelist *new_probe; + chandev_probelist *new_probe,*curr_probe; /* Avoid chicked & egg situations where we may be called before we */ /* are initialised. */ chandev_interrupt_check(); if(!atomic_compare_and_swap(FALSE,TRUE,&chandev_initialised)) chandev_init(); + chandev_lock(); + for_each(curr_probe,chandev_probelist_head) + { + if(curr_probe->probefunc==probefunc) + { + chandev_unlock(); + printk("chandev_register_and_probe detected duplicate probefunc %p" + " for chan_type 0x%02x \n",probefunc,chan_type); + return (-EPERM); + } + } + chandev_unlock(); if((new_probe=chandev_alloc(sizeof(chandev_probelist)))) { new_probe->probefunc=probefunc; @@ -3229,12 +3244,12 @@ int chandev_register_and_probe(chandev_probefunc probefunc, chandev_add_to_list((list **)&chandev_probelist_head,new_probe); chandev_probe(); } - return(new_probe ? new_probe->devices_found:0); + return(new_probe ? new_probe->devices_found:-ENOMEM); } void chandev_unregister(chandev_probefunc probefunc,int call_shutdown) { - chandev_probelist *curr_probe=NULL; + chandev_probelist *curr_probe; chandev_activelist *curr_device,*next_device; chandev_interrupt_check(); diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index f14c4a486cbe..d1a1cb3c7161 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c @@ -1,5 +1,5 @@ /* - * $Id: ctcmain.c,v 1.46 2001/07/05 17:36:41 felfert Exp $ + * $Id: ctcmain.c,v 1.49 2001/08/31 14:50:05 felfert Exp $ * * CTC / ESCON network driver * @@ -35,7 +35,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.46 $ + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.49 $ * */ @@ -43,7 +43,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/slab.h> +#include <linux/malloc.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -80,7 +80,7 @@ #if LINUX_VERSION_CODE >= 0x020213 # include <asm/idals.h> #else -# define set_normalized_cda(ccw, addr) ((ccw)->cda = (addr)) +# define set_normalized_cda(ccw, addr) ((ccw)->cda = (addr),0) # define clear_normalized_cda(ccw) #endif #if LINUX_VERSION_CODE < 0x020400 @@ -382,7 +382,7 @@ static __inline__ int ctc_test_and_set_busy(net_device *dev) */ static void print_banner(void) { static int printed = 0; - char vbuf[] = "$Revision: 1.46 $"; + char vbuf[] = "$Revision: 1.49 $"; char *version = vbuf; if (printed) @@ -925,6 +925,7 @@ static __inline__ int ctc_checkalloc_buffer(channel *ch, int warn) { (ch->flags & CHANNEL_FLAGS_BUFSIZE_CHANGED)) { if (ch->trans_skb != NULL) dev_kfree_skb(ch->trans_skb); + clear_normalized_cda(&ch->ccw[1]); ch->trans_skb = dev_alloc_skb(ch->max_bufsize); if (ch->trans_skb == NULL) { if (warn) @@ -935,9 +936,9 @@ static __inline__ int ctc_checkalloc_buffer(channel *ch, int warn) { "RX" : "TX"); return -ENOMEM; } - set_normalized_cda(&ch->ccw[1], - virt_to_phys(ch->trans_skb->data)); - if (ch->ccw[1].cda == 0) { + ch->ccw[1].count = ch->max_bufsize; + if (set_normalized_cda(&ch->ccw[1], + virt_to_phys(ch->trans_skb->data))) { dev_kfree_skb(ch->trans_skb); ch->trans_skb = NULL; if (warn) @@ -949,6 +950,7 @@ static __inline__ int ctc_checkalloc_buffer(channel *ch, int warn) { "RX" : "TX"); return -ENOMEM; } + ch->ccw[1].count = 0; ch->flags &= ~CHANNEL_FLAGS_BUFSIZE_CHANGED; } return 0; @@ -1330,6 +1332,15 @@ static void ch_action_start(fsm_instance *fi, int event, void *arg) dev_kfree_skb(ch->trans_skb); ch->trans_skb = NULL; } + if (CHANNEL_DIRECTION(ch->flags) == READ) { + ch->ccw[1].cmd_code = CCW_CMD_READ; + ch->ccw[1].flags = CCW_FLAG_SLI; + ch->ccw[1].count = 0; + } else { + ch->ccw[1].cmd_code = CCW_CMD_WRITE; + ch->ccw[1].flags = CCW_FLAG_SLI | CCW_FLAG_CC; + ch->ccw[1].count = 0; + } if (ctc_checkalloc_buffer(ch, 0)) printk(KERN_NOTICE "%s: Could not allocate %s trans_skb, delaying " @@ -1350,21 +1361,13 @@ static void ch_action_start(fsm_instance *fi, int event, void *arg) ch->ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[0].count = 0; ch->ccw[0].cda = 0; - if (CHANNEL_DIRECTION(ch->flags) == READ) { - ch->ccw[1].cmd_code = CCW_CMD_READ; - ch->ccw[1].flags = CCW_FLAG_SLI; - ch->ccw[1].count = 0; - } else { - ch->ccw[1].cmd_code = CCW_CMD_WRITE; - ch->ccw[1].flags = CCW_FLAG_SLI | CCW_FLAG_CC; - ch->ccw[1].count = 0; - } ch->ccw[2].cmd_code = CCW_CMD_NOOP; /* jointed CE + DE */ ch->ccw[2].flags = CCW_FLAG_SLI; ch->ccw[2].count = 0; ch->ccw[2].cda = 0; memcpy(&ch->ccw[3], &ch->ccw[0], sizeof(ccw1_t) * 3); ch->ccw[4].cda = 0; + ch->ccw[4].flags &= ~CCW_FLAG_IDA; fsm_newstate(fi, CH_STATE_STARTWAIT); fsm_addtimer(&ch->timer, 1000, CH_EVENT_TIMER, ch); @@ -1696,9 +1699,10 @@ static void ch_action_txretry(fsm_instance *fi, int event, void *arg) if ((skb = skb_peek(&ch->io_queue))) { int rc = 0; - set_normalized_cda(&ch->ccw[4], - virt_to_phys(skb->data)); - if (ch->ccw[4].cda == 0) { + clear_normalized_cda(&ch->ccw[4]); + ch->ccw[4].count = skb->len; + if (set_normalized_cda(&ch->ccw[4], + virt_to_phys(skb->data))) { printk(KERN_DEBUG "%s: IDAL alloc failed, " "restarting channel\n", dev->name); fsm_event(((ctc_priv *)dev->priv)->fsm, @@ -1709,7 +1713,6 @@ static void ch_action_txretry(fsm_instance *fi, int event, void *arg) fsm_addtimer(&ch->timer, 1000, CH_EVENT_TIMER, ch); if (event == CH_EVENT_TIMER) s390irq_spin_lock_irqsave(ch->irq, saveflags); - ch->ccw[4].count = skb->len; #ifdef DEBUG printk(KERN_DEBUG "ccw[4].cda = %08x\n", ch->ccw[4].cda); #endif @@ -2488,8 +2491,8 @@ static int transmit_skb(channel *ch, struct sk_buff *skb) { LL_HEADER_LENGTH); block_len = skb->len + 2; *((__u16 *)skb_push(skb, 2)) = block_len; - set_normalized_cda(&ch->ccw[4], virt_to_phys(skb->data)); - if (ch->ccw[4].cda == 0) { + ch->ccw[4].count = block_len; + if (set_normalized_cda(&ch->ccw[4], virt_to_phys(skb->data))) { /** * idal allocation failed, try via copying to * trans_skb. trans_skb usually has a pre-allocated @@ -2513,7 +2516,6 @@ static int transmit_skb(channel *ch, struct sk_buff *skb) { dev_kfree_skb_irq(skb); ccw_idx = 0; } else { - ch->ccw[4].count = block_len; skb_queue_tail(&ch->io_queue, skb); ccw_idx = 3; } diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c index 26ea68ce650d..9346f10fa4f6 100644 --- a/drivers/s390/net/iucv.c +++ b/drivers/s390/net/iucv.c @@ -1,30 +1,41 @@ -/* - * drivers/s390/net/iucv.c - * Support for VM IUCV functions for use by other part of the - * kernel or loadable modules. +/* + * $Id$ * - * S390 version - * Copyright (C) 2000 IBM Corporation - * Author(s): Alan Altmark (Alan_Altmark@us.ibm.com) - * Xenia Tkatschow (xenia@us.ibm.com) - * Functionality: - * To explore any of the IUCV functions, one must first register - * their program using iucv_register(). Once your program has - * successfully completed a register, it can use the other functions. - * For furthur reference on all IUCV functionality, refer to the - * CP Programming Services book, also available on the web - * thru www.ibm.com/s390/vm/pubs , manual # SC24-5760. - * - * Definition of Return Codes - * -All positive return codes including zero are reflected back - * from CP and the definition can be found in CP Programming - * Services book. - * - (-ENOMEM) Out of memory - * - (-EINVAL) Invalid value -*/ -/* #define DEBUG 1 */ + * IUCV network driver + * + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): + * Original source: + * Alan Altmark (Alan_Altmark@us.ibm.com) Sept. 2000 + * Xenia Tkatschow (xenia@us.ibm.com) + * 2Gb awareness and general cleanup: + * Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) + * + * Documentation used: + * The original source + * CP Programming Service, IBM document # SC24-5760 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * RELEASE-TAG: IUCV lowlevel driver $Revision$ + * + */ + #include <linux/module.h> #include <linux/config.h> + #include <linux/version.h> #include <linux/spinlock.h> #include <linux/kernel.h> @@ -32,6 +43,7 @@ #include <linux/init.h> #include <linux/tqueue.h> #include <linux/interrupt.h> +#include <linux/list.h> #include <asm/atomic.h> #include "iucv.h" #include <asm/io.h> @@ -39,20 +51,11 @@ #include <asm/s390_ext.h> #include <asm/ebcdic.h> -#ifdef DEBUG -#undef KERN_INFO -#undef KERN_DEBUG -#define KERN_INFO KERN_EMERG -#define KERN_DEBUG KERN_EMERG -#endif - -#undef NULL -#define NULL 0 +#undef DEBUG -#define PRRTY_PRMTD 0x01 /* priority permitted */ -#define RPY_RQRD 0x01 /* reply required */ -#define ADDED_STOR 64 /* ADDITIONAL STORAGE FOR PATHID @'S */ -#define BUFFER_SIZE 40 /* Size of 31-bit iparml */ +#ifndef min +#define min(a,b) (((a)<(b))?(a):(b)) +#endif /* FLAGS: * All flags are defined in the field IPFLAGS1 of each function @@ -74,55 +77,43 @@ #define IPANSLST 0x08 #define IPBUFLST 0x40 -static uchar iucv_external_int_buffer[40]; - -/* Spin Lock declaration */ -struct tq_struct short_task; /* automatically initialized to zero */ -static spinlock_t iucv_lock = SPIN_LOCK_UNLOCKED; - /* General IUCV interrupt structure */ typedef struct { - u16 ippathid; - uchar res1; - uchar iptype; - u32 res2; - uchar ipvmid[8]; - uchar res3[24]; + __u16 ippathid; + __u8 res1; + __u8 iptype; + __u32 res2; + __u8 ipvmid[8]; + __u8 res3[24]; } iucv_GeneralInterrupt; -/***************INTERRUPT HANDLING DEFINITIONS***************/ -typedef struct _iucv_packet { - struct _iucv_packet *next; - uchar data[40]; -} iucv_packet; -struct tq_struct short_task; - -static spinlock_t iucv_packets_lock = SPIN_LOCK_UNLOCKED; - -iucv_packet *iucv_packets_head, *iucv_packets_tail; +static iucv_GeneralInterrupt *iucv_external_int_buffer; -static atomic_t bh_scheduled = ATOMIC_INIT (0); - -/* - *Internal function prototypes - */ +/* Spin Lock declaration */ -static ulong iucv_vmsize (void); +static spinlock_t iucv_lock = SPIN_LOCK_UNLOCKED; -int iucv_declare_buffer (void); +/***************INTERRUPT HANDLING ***************/ -int iucv_retrieve_buffer (void); +typedef struct { + struct list_head queue; + iucv_GeneralInterrupt data; +} iucv_irqdata; -static int iucv_add_pathid (u16 pathid, iucv_handle_t handle, void *pgm_data); +struct list_head iucv_irq_queue; +static spinlock_t iucv_irq_queue_lock = SPIN_LOCK_UNLOCKED; -static void iucv_remove_pathid (u16 pathid); +struct tq_struct iucv_tq; -void bottom_half_interrupt (void); +static atomic_t iucv_bh_scheduled = ATOMIC_INIT (0); -static void do_int (iucv_GeneralInterrupt *); +/* + *Internal function prototypes + */ +static void iucv_bh_handler(void); +static void iucv_irq_handler(struct pt_regs *, __u16); -inline void top_half_interrupt (struct pt_regs *regs, __u16 code); -/************FUNCTION ID'S****************************/ +/************ FUNCTION ID'S ****************************/ #define ACCEPT 10 #define CONNECT 11 @@ -139,1180 +130,1066 @@ inline void top_half_interrupt (struct pt_regs *regs, __u16 code); #define SETMASK 16 #define SEVER 15 -/* - * Structure: handler - * members: next - is a pointer to next handler on chain - * prev - is a pointer to prev handler on chain - * structure: id - * vmid - 8 char array of machine identification - * user_data - 16 char array for user identification - * mask - 24 char array used to compare the 2 previous - * interrupt_table - vector of interrupt functions. - * pathid_head - pointer to start of user_pathid_table - * pathid_tail - pointer to end of user_pathid_table - * entries - ulong, size of user_pathid_table - * pgm_data - ulong, application data that is passed - * to the interrupt handlers +/** + * Structure: handler + * members: list - list management. + * structure: id + * userid - 8 char array of machine identification + * user_data - 16 char array for user identification + * mask - 24 char array used to compare the 2 previous + * interrupt_table - vector of interrupt functions. + * pgm_data - ulong, application data that is passed + * to the interrupt handlers */ -typedef struct { - ulong *next; - ulong *prev; +typedef struct handler_t { + struct list_head list; struct { - uchar userid[8]; - uchar user_data[16]; - uchar mask[24]; - } id; + __u8 userid[8]; + __u8 user_data[16]; + __u8 mask[24]; + } id; iucv_interrupt_ops_t *interrupt_table; - ulong *pathid_head; - ulong *pathid_tail; - ulong entries; - void *pgm_data; + void *pgm_data; } handler; -/* - * Structure: handler_table_entry - * members: addrs - pointer to a handler - * pathid - ushort containing path identification - * pgm_data - ulong, application data that is - * passed to the interrupt handlers - * ops - pointer to iucv interrupt vector +/** + * iucv_handler_table: List of registered handlers. */ +static struct list_head iucv_handler_table; -typedef struct { - handler *addrs; - u16 pathid; - void *pgm_data; - iucv_interrupt_ops_t *ops; -} handler_table_entry; - -/* - * Internal function prototypes +/** + * iucv_pathid_table: an array of *handler pointing into + * iucv_handler_table for fast indexing by pathid; */ +static handler **iucv_pathid_table; -static int iucv_add_handler (handler * new_handler); - -static void iucv_remove_handler (handler * users_handler); - -/* handler_anchor: points to first handler on chain */ -/* handler_tail: points to last handler on chain */ -/* handler_table_anchor: points to beginning of handler_table_entries*/ - -static handler *handler_anchor = NULL; - -static handler *handler_tail = NULL; +static unsigned long max_connections; -static handler_table_entry *handler_table_anchor = NULL; - -/* declare_flag: is 0 when iucv_declare_buffer has not been called */ - -static ulong declare_flag = 0; +/** + * declare_flag: is 0 when iucv_declare_buffer has not been called + */ +static int declare_flag; /****************FIVE 40-BYTE PARAMETER STRUCTURES******************/ -/* Data struct 1: iparml_control - * Used for iucv_accept - * iucv_connect - * iucv_quiesce - * iucv_resume - * iucv_sever - * iucv_retrieve_buffer - * Data struct 2: iparml_dpl (data in parameter list) - * Used for iucv_send_prmmsg - * iucv_send2way_prmmsg - * iucv_send2way_prmmsg_array - * iucv_reply_prmmsg - * Data struct 3: iparml_db (data in a buffer) - * Used for iucv_receive - * iucv_receive_array - * iucv_reject - * iucv_reply - * iucv_reply_array - * iucv_send - * iucv_send_array - * iucv_send2way - * iucv_send2way_array - * iucv_declare_buffer - * Data struct 4: iparml_purge - * Used for iucv_purge - * iucv_query - * Data struct 5: iparml_set_mask - * Used for iucv_set_mask -*/ +/* Data struct 1: iparml_control + * Used for iucv_accept + * iucv_connect + * iucv_quiesce + * iucv_resume + * iucv_sever + * iucv_retrieve_buffer + * Data struct 2: iparml_dpl (data in parameter list) + * Used for iucv_send_prmmsg + * iucv_send2way_prmmsg + * iucv_send2way_prmmsg_array + * iucv_reply_prmmsg + * Data struct 3: iparml_db (data in a buffer) + * Used for iucv_receive + * iucv_receive_array + * iucv_reject + * iucv_reply + * iucv_reply_array + * iucv_send + * iucv_send_array + * iucv_send2way + * iucv_send2way_array + * iucv_declare_buffer + * Data struct 4: iparml_purge + * Used for iucv_purge + * iucv_query + * Data struct 5: iparml_set_mask + * Used for iucv_set_mask + */ typedef struct { - u16 ippathid; - uchar ipflags1; - uchar iprcode; - u16 ipmsglim; - u16 res1; - uchar ipvmid[8]; - uchar ipuser[16]; - uchar iptarget[8]; + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u16 ipmsglim; + __u16 res1; + __u8 ipvmid[8]; + __u8 ipuser[16]; + __u8 iptarget[8]; } iparml_control; typedef struct { - u16 ippathid; - uchar ipflags1; - uchar iprcode; - u32 ipmsgid; - u32 iptrgcls; - uchar iprmmsg[8]; - u32 ipsrccls; - u32 ipmsgtag; - u32 ipbfadr2; - u32 ipbfln2f; - u32 res; + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u32 ipmsgid; + __u32 iptrgcls; + __u8 iprmmsg[8]; + __u32 ipsrccls; + __u32 ipmsgtag; + __u32 ipbfadr2; + __u32 ipbfln2f; + __u32 res; } iparml_dpl; typedef struct { - u16 ippathid; - uchar ipflags1; - uchar iprcode; - u32 ipmsgid; - u32 iptrgcls; - u32 ipbfadr1; - u32 ipbfln1f; - u32 ipsrccls; - u32 ipmsgtag; - u32 ipbfadr2; - u32 ipbfln2f; - u32 res; + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u32 ipmsgid; + __u32 iptrgcls; + __u32 ipbfadr1; + __u32 ipbfln1f; + __u32 ipsrccls; + __u32 ipmsgtag; + __u32 ipbfadr2; + __u32 ipbfln2f; + __u32 res; } iparml_db; typedef struct { - u16 ippathid; - uchar ipflags1; - uchar iprcode; - u32 ipmsgid; - uchar ipaudit[3]; - uchar res1[5]; - u32 res2; - u32 ipsrccls; - u32 ipmsgtag; - u32 res3[3]; + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u32 ipmsgid; + __u8 ipaudit[3]; + __u8 res1[5]; + __u32 res2; + __u32 ipsrccls; + __u32 ipmsgtag; + __u32 res3[3]; } iparml_purge; typedef struct { - uchar ipmask; - uchar res1[2]; - uchar iprcode; - u32 res2[9]; + __u8 ipmask; + __u8 res1[2]; + __u8 iprcode; + __u32 res2[9]; } iparml_set_mask; -/*********************INTERNAL FUNCTIONS*****************************/ - -static ulong -iucv_vmsize (void) -{ - extern unsigned long memory_size; - return memory_size; -} +typedef struct { + union { + iparml_control p_ctrl; + iparml_dpl p_dpl; + iparml_db p_db; + iparml_purge p_purge; + iparml_set_mask p_set_mask; + } param; + atomic_t in_use; +} __attribute__ ((aligned(8))) iucv_param; +#define PARAM_POOL_SIZE (PAGE_SIZE / sizeof(iucv_param)) + +static iucv_param * iucv_param_pool; /* - * Name: dumpit - * Purpose: print to the console buffers of a given length - * Input: buf - (* uchar) - pointer to buffer to be printed - * len - int - length of buffer being printed - * Output: void - */ - + * Debugging stuff + *******************************************************************************/ + #ifdef DEBUG static void -iucv_dumpit (uchar * buf, int len) +iucv_dumpit(void *buf, int len) { int i; + __u8 *p = (__u8 *)buf; + + printk(KERN_DEBUG " "); for (i = 0; i < len; i++) { if (!(i % 16) && i != 0) - printk ("\n"); + printk ("\n "); else if (!(i % 4) && i != 0) printk (" "); - printk ("%02X", buf[i]); + printk ("%02X", *p++); } if (len % 16) printk ("\n"); return; } +#define iucv_debug(fmt, args...) \ +printk(KERN_DEBUG __FUNCTION__ ": " fmt "\n" , ## args); #else -static void -iucv_dumpit (uchar * buf, int len) -{ -} + +#define iucv_debug(fmt, args...) +#define iucv_dumpit(buf, len) #endif /* - * Name iucv_add_handler - * Purpose: Place new handle on handler_anchor chain, if identical handler is not - * found. Handlers are ordered with largest mask integer value first. - * Input: new_handler - handle that is being entered into chain - * Return: int - * 0 - handler added - * 1 - identical handler found, handler not added to chain -*/ -int -iucv_add_handler (handler * new_handler) + * Internal functions + *******************************************************************************/ + +/** + * iucv_init - Initialization + * + * Allocates and initializes various data structures. + */ +static int +iucv_init(void) +{ + if (iucv_external_int_buffer) + return 0; + + /* Note: GFP_DMA used used to get memory below 2G */ + iucv_external_int_buffer = kmalloc(sizeof(iucv_GeneralInterrupt), + GFP_KERNEL|GFP_DMA); + if (!iucv_external_int_buffer) { + printk(KERN_WARNING + "%s: Could not allocate external interrupt buffer\n", + __FUNCTION__); + return -ENOMEM; + } + memset(iucv_external_int_buffer, 0, sizeof(iucv_GeneralInterrupt)); + + /* Initialize parameter pool */ + iucv_param_pool = kmalloc(sizeof(iucv_param) * PARAM_POOL_SIZE, + GFP_KERNEL|GFP_DMA); + if (!iucv_param_pool) { + printk(KERN_WARNING "%s: Could not allocate param pool\n", + __FUNCTION__); + kfree(iucv_external_int_buffer); + iucv_external_int_buffer = NULL; + return -ENOMEM; + } + memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE); + + /* Initialize task queue */ + INIT_LIST_HEAD(&iucv_tq.list); + iucv_tq.sync = 0; + iucv_tq.routine = (void *)iucv_bh_handler; + + /* Initialize irq queue */ + INIT_LIST_HEAD(&iucv_irq_queue); + + /* Initialize handler table */ + INIT_LIST_HEAD(&iucv_handler_table); + + return 0; +} + +/** + * grab_param: - Get a parameter buffer from the pre-allocated pool. + * + * This function searches for an unused element in the the pre-allocated pool + * of parameter buffers. If one is found, it marks it "in use" and returns + * a pointer to it. The calling function is responsible for releasing it + * when it has finished its usage. + * + * Returns: A pointer to iucv_param. + */ +static __inline__ iucv_param * +grab_param(void) +{ + iucv_param *ret; + static int i = 0; + + while (atomic_compare_and_swap(0, 1, &iucv_param_pool[i].in_use)) { + i++; + if (i >= PARAM_POOL_SIZE) + i = 0; + } + ret = &iucv_param_pool[i]; + memset(&ret->param, 0, sizeof(ret->param)); + return ret; +} + +/** + * release_param - Release a parameter buffer. + * @p: A pointer to a struct iucv_param, previously obtained by calling + * grab_param(). + * + * This function marks the specified parameter buffer "unused". + */ +static __inline__ void +release_param(void *p) +{ + atomic_set(&((iucv_param *)p)->in_use, 0); +} + +/** + * iucv_add_handler: - Add a new handler + * @new_handler: handle that is being entered into chain. + * + * Places new handle on iucv_handler_table, if identical handler is not + * found. + * + * Returns: 0 on success, !0 on failure (handler already in chain). + */ +static int +iucv_add_handler (handler *new) { - handler *R = new_handler; - int rc = 1, comp = 0; /* return code (rc = 1 not added) or (rc = 0 added) */ ulong flags; - pr_debug ("iucv_add_handler: entering\n"); - iucv_dumpit ((uchar *) new_handler, sizeof (handler)); + + iucv_debug("entering"); + iucv_dumpit(new, sizeof(handler)); + spin_lock_irqsave (&iucv_lock, flags); - if (handler_anchor == NULL) { - /* add to beginning of chain */ - handler_anchor = handler_tail = new_handler; - rc = 0; - } else - for (R = handler_anchor; R != NULL; R = (handler *) R->next) { - comp = memcmp ((void *) &(new_handler->id), - (void *) &(R->id), sizeof (R->id)); - pr_debug ("comp = %d\n", comp); - if (comp == 0) /* identicle handler found */ - break; /* break out of for loop */ - else if (comp > 0) { /* new_handler > R */ - pr_debug - ("iucv_add_handler: Found a place to add," - "R is\n"); - iucv_dumpit ((uchar *) R, sizeof (handler)); - if ((R->prev != NULL)) { - /* add to middle of chain */ - pr_debug - ("iucv_add_handler: added to middle\n"); - new_handler->prev = R->prev; - new_handler->next = (ulong *) R; - ((handler *) (R->prev))->next = - (ulong *) new_handler; - R->prev = (ulong *) new_handler; - rc = 0; - break; /* break out of FOR loop */ - } else { /* R->prev == NULL */ - /* add to start of chain; */ - pr_debug ("iucv_add_handler:" - "added to beginning\n"); - R->prev = (ulong *) new_handler; - new_handler->next = (ulong *) R; - handler_anchor = new_handler; - rc = 0; - break; /* break out of FOR loop */ - } - } /* end of else if */ - } /* end of for loop */ - if (R == NULL) { - /* add to end of chain */ - pr_debug ("iucv_add_handler: added to end\n"); - handler_tail->next = (ulong *) new_handler; - new_handler->prev = (ulong *) handler_tail; - handler_tail = new_handler; - rc = 0; + if (!list_empty(&iucv_handler_table)) { + struct list_head *lh; + + /** + * Search list for handler with identical id. If one + * is found, the new handler is _not_ added. + */ + list_for_each(lh, &iucv_handler_table) { + handler *h = list_entry(lh, handler, list); + if (memcmp(&new->id, &h->id, sizeof(h->id)) == 0) { + iucv_debug("ret 1"); + spin_unlock_irqrestore (&iucv_lock, flags); + return 1; + } + } } + /** + * If we get here, no handler was found. + */ + INIT_LIST_HEAD(&new->list); + list_add(&new->list, &iucv_handler_table); spin_unlock_irqrestore (&iucv_lock, flags); - pr_debug ("Current Chain of handlers is\n"); - for (R = handler_anchor; R != NULL; R = (handler *) R->next) - iucv_dumpit ((uchar *) R, (int) sizeof (handler)); - - pr_debug ("iucv_add_handler: exiting\n"); - return rc; + iucv_debug("exiting"); + return 0; } -/* - * Name: iucv_remove_handler - * Purpose: Remove handler when application unregisters. - * Input: users_handler - handler to be removed - * Output: void -*/ -void -iucv_remove_handler (handler * users_handler) +/** + * iucv_remove_handler: + * @users_handler: handler to be removed + * + * Remove handler when application unregisters. + */ +static void +iucv_remove_handler(handler *handler) { - handler *R; /* used for Debugging */ - pr_debug ("iucv_remove_handler: entering\n"); - if ((users_handler->next != NULL) & (users_handler->prev != NULL)) { - /* remove from middle of chain */ - ((handler *) (users_handler->next))->prev = - (ulong *) users_handler->prev; - ((handler *) (users_handler->prev))->next = - (ulong *) users_handler->next; - } else if ((users_handler->next != NULL) & - (users_handler->prev == NULL)) { - /* remove from start of chain */ - ((handler *) (users_handler->next))->prev = NULL; - handler_anchor = (handler *) users_handler->next; - } else if ((users_handler->next == NULL) & - (users_handler->prev != NULL)) { - /* remove from end of chain */ - ((handler *) (users_handler->prev))->next = NULL; - handler_tail = (handler *) users_handler->prev; - } else { - handler_anchor = NULL; - handler_tail = NULL; - } + unsigned long flags; + + if ((!iucv_pathid_table) || (!handler)) + return; - pr_debug ("Current Chain of handlers is\n"); - for (R = handler_anchor; R != NULL; R = (handler *) R->next) - iucv_dumpit ((uchar *) R, (int) sizeof (handler)); + iucv_debug("entering"); - pr_debug ("iucv_remove_handler: exiting\n"); + spin_lock_irqsave (&iucv_lock, flags); + list_del(&handler->list); + spin_unlock_irqrestore (&iucv_lock, flags); + + iucv_debug("exiting"); return; } -/* - * Name: b2f0 - * Purpose: This function calls CP to execute IUCV commands. - * Input: code - identifier of IUCV call to CP. - * parm - pointer to 40 byte iparml area - * passed to CP - * Output: iprcode- return code from CP's IUCV call - * NOTE: Assembler code performing IUCV call -*/ -inline ulong -b2f0 (u32 code, void *parm) +/** + * b2f0: + * @code: identifier of IUCV call to CP. + * @parm: pointer to 40 byte iparml area passed to CP + * + * Calls CP to execute IUCV commands. + * + * Returns: return code from CP's IUCV call + */ +static __inline__ ulong +b2f0(__u32 code, void *parm) { - uchar *iprcode; - pr_debug ("iparml before b2f0 call\n"); - iucv_dumpit ((uchar *) parm, (int) BUFFER_SIZE); - asm volatile ("LRA 1,0(%1)\n\t" - "LR 0,%0\n\t" - ".long 0xb2f01000"::"d" (code), "a" (parm):"0", "1"); - pr_debug ("iparml after b2f0 call\n"); - iucv_dumpit ((uchar *) parm, (int) BUFFER_SIZE); - iprcode = (uchar *) (parm + 3); - return (ulong) (*iprcode); + iucv_debug("iparml before b2f0 call:"); + iucv_dumpit(parm, sizeof(iucv_param.param)); + + asm volatile ( + "LRA 1,0(%1)\n\t" + "LR 0,%0\n\t" + ".long 0xb2f01000" + : + : "d" (code), "a" (parm) + : "0", "1" + ); + + iucv_debug("iparml after b2f0 call:"); + iucv_dumpit(parm, sizeof(iucv_param.param)); + + return (unsigned long)*((__u8 *)(parm + 3)); } /* - * Name: iucv_add_pathid - * Purpose: Adds a path id to the system. - * Input: pathid - pathid that is going to be entered into system + * Name: iucv_add_pathid + * Purpose: Adds a path id to the system. + * Input: pathid - pathid that is going to be entered into system * handle - address of handler that the pathid will be associated * with. - * pgm_data - token passed in by application. + * pgm_data - token passed in by application. * Output: 0: successful addition of pathid * - EINVAL - pathid entry is being used by another application - * - ENOMEM - storage allocation for a new pathid table failed + * - ENOMEM - storage allocation for a new pathid table failed */ -int -iucv_add_pathid (u16 pathid, iucv_handle_t handle, void *pgm_data) +static int +iucv_add_pathid(__u16 pathid, handler *handler) { - ulong add_flag = 0; - ulong old_size = 0, new_size = 0; ulong flags; - uchar *to, *from; /* pointer for copying the table */ - handler_table_entry *P = 0; /*P is a pointer to the users H_T_E */ - handler *users_handler = 0; - ulong *X = 0; /* Points to array of pointers to H-T_E */ - pr_debug ("iucv_add_pathid: entering\n"); + iucv_debug("entering"); - users_handler = (handler *) handle; + iucv_debug("handler is pointing to %p", handler); - pr_debug ("iucv_add_pathid: users_handler is pointing to %p ", - users_handler); + if (pathid > (max_connections - 1)) + return -EINVAL; spin_lock_irqsave (&iucv_lock, flags); - - /* - * P points to the users handler table entry (H_T_E) in which all entries in - * that structure should be NULL. If they're not NULL, then there - * is a bad pointer and it will return(-EINVAL) immediately, otherwise users - * data will be entered into H_T_E. - */ - - P = handler_table_anchor + pathid; /* index into users handler table */ - - pr_debug ("handler_table_anchor is %p\n", handler_table_anchor); - pr_debug ("P=handler_table_anchor+pathid = %p\n", P); - - if (P->addrs) { - pr_debug ("iucv_add_pathid: P = %p \n", P); - pr_debug ("iucv_add_pathid: P->addrs is %p \n", P->addrs); + if (iucv_pathid_table[pathid]) { spin_unlock_irqrestore (&iucv_lock, flags); - /* This message should be sent to syslog */ - printk (KERN_WARNING "iucv_add_pathid: Pathid being used," - "error.\n"); - return (-EINVAL); + iucv_debug("pathid entry is %p", iucv_pathid_table[pathid]); + printk(KERN_WARNING + "%s: Pathid being used, error.\n", __FUNCTION__); + return -EINVAL; } + iucv_pathid_table[pathid] = handler; + spin_unlock_irqrestore (&iucv_lock, flags); - P->addrs = handle; - P->pathid = pathid; - - /* - * pgm_data provided in iucv_register may be overwritten on a connect, accept. - */ - - if (pgm_data) - P->pgm_data = pgm_data; - else - P->pgm_data = users_handler->pgm_data; - - /* - * Address of pathid's iucv_interrupt_ops is taken from the associated handler - * and added here for quicker access to the interrupt tables during interrupt - * handling. - */ - - P->ops = (P->addrs)->interrupt_table; - - pr_debug ("Complete users H_T_E is\n"); - iucv_dumpit ((uchar *) P, sizeof (handler_table_entry)); - - /* - * Step thru the table of addresses of pathid's to find the first - * available entry (NULL). If an entry is found, add the pathid, - * unlock and exit. If an available entry is not found, allocate a - * new, larger table, copy over the old table to the new table. De-allocate the - * old table and enter the new pathid. - */ - - pr_debug ("iucv_add_pathid: address of handle is %p\n", handle); - pr_debug ("iucv_add_pathid: &(users_handler->pathid_head) is %p\n", - &(users_handler->pathid_head)); - pr_debug ("iucv_add_pathid: &(users_handler->pathid_tail) is %p\n", - &(users_handler->pathid_tail)); - pr_debug ("iucv_add_pathid: start of pathid table is %p\n", - (users_handler->pathid_head)); - pr_debug ("iucv_add_pathid: end of pathid table is %p\n", - (users_handler->pathid_tail)); - iucv_dumpit ((uchar *) users_handler->pathid_head, - (int) (users_handler->pathid_tail - - users_handler->pathid_head)); - - for (X = (users_handler->pathid_head); - X < - (users_handler->pathid_head + - users_handler->entries * sizeof (ulong)); X++) - if (*X == NULL) { - pr_debug ("adding pathid, %p = P\n", P); - *X = (ulong) P; - add_flag = 1; - break; /* breaks out of for loop */ - } - - pr_debug ("Addresses of HTE's are\n"); - iucv_dumpit ((uchar *) users_handler->pathid_head, - users_handler->entries * sizeof (ulong)); + iucv_debug("exiting"); + return 0; +} /* end of add_pathid function */ - if (add_flag == 0) { /* element not added to list: must get a new table */ - X = users_handler->pathid_head; - old_size = users_handler->entries; - new_size = old_size + ADDED_STOR; /*number of entries of new table */ - from = (uchar *) (users_handler->pathid_head); /*address of old table */ - users_handler->pathid_head = - kmalloc (new_size * sizeof (ulong), GFP_ATOMIC); +static void +iucv_remove_pathid(__u16 pathid) +{ + ulong flags; - if (users_handler->pathid_head == NULL) { - users_handler->pathid_head = X; /*setting old condition */ - spin_unlock_irqrestore (&iucv_lock, flags); - printk (KERN_WARNING - "iucv_add_pathid: storage allocation" - "failed for new pathid table \n "); - memset (P, 0, sizeof (handler_table_entry)); - return -ENOMEM; - } + if (pathid > (max_connections - 1)) + return; - memset (users_handler->pathid_head, 0, - new_size * sizeof (ulong)); - to = (uchar *) (users_handler->pathid_head); /* address of new table */ - /* copy old table to new */ - memcpy (to, from, old_size * (sizeof (ulong))); - - pr_debug ("iucv: add_pathid: Getting a new pathid table\n"); - pr_debug ("iucv: add_pathid: to is %p \n", to); - pr_debug ("iucv: add_pathid: from is %p \n", from); - - users_handler->entries = new_size; /* storing new size of table */ - users_handler->pathid_tail = - (users_handler->pathid_head) + (users_handler->entries); - X = users_handler->pathid_head + old_size; - *X = (ulong) P; /* adding element to new table */ - - pr_debug ("iucv: add_pathid: users_handler->entries is %u \n", - (int) (users_handler->entries)); - pr_debug - ("iucv: add_pathid: users_handler->pathid_tail is %p\n", - users_handler->pathid_tail); - pr_debug ("users_handler->pathid_head is %p \n", - users_handler->pathid_head); - pr_debug ("iucv: add_pathid: X is %p \n", X); - pr_debug ("iucv: add_pathid: *X is %u \n", (int) (*X)); - pr_debug ("Addresses of HTE's after getting new table is\n"); - iucv_dumpit ((uchar *) users_handler->pathid_head, - users_handler->entries * sizeof (ulong)); - pr_debug ("New handler is\n"); - iucv_dumpit ((uchar *) users_handler, sizeof (handler)); - - kfree (from); /* free old table */ - } + spin_lock_irqsave (&iucv_lock, flags); + iucv_pathid_table[pathid] = NULL; spin_unlock_irqrestore (&iucv_lock, flags); - pr_debug ("iucv_dd_pathid: exiting\n"); - return (0); -} /* end of add_pathid function */ +} /* - * Name: iucv_declare_buffer - * Purpose: Specifies the guests real address of an external - * interrupt. - * Input: void - * Output: iprcode - return code from b2f0 call + * Name: iucv_declare_buffer + * Purpose: Specifies the guests real address of an external + * interrupt. + * Input: void + * Output: iprcode - return code from b2f0 call */ int iucv_declare_buffer (void) { - iparml_db parm; ulong b2f0_result; - pr_debug ("iucv_declare_buffer: entering\n"); - memset (&parm, 0, sizeof (parm)); - parm.ipbfadr1 = virt_to_phys ((uchar *) iucv_external_int_buffer); - b2f0_result = b2f0 (DECLARE_BUFFER, &parm); - pr_debug ("iucv_declare_buffer: Address of EIB = %p\n", - iucv_external_int_buffer); - pr_debug ("iucv_declare_buffer: exiting\n"); + iparml_db *parm = (iparml_db *)grab_param(); + + parm->ipbfadr1 = virt_to_phys(iucv_external_int_buffer); + b2f0_result = b2f0(DECLARE_BUFFER, parm); + release_param(parm); + iucv_debug("Address of EIB = %p", iucv_external_int_buffer); + iucv_debug("exiting"); return b2f0_result; } -/* - * Name: iucv_retrieve_buffer - * Purpose: Terminates all use of IUCV. - * Input: void - * Output: - * b2f0_result: return code from CP -*/ +/** + * iucv_retrieve_buffer: + * + * Terminates all use of IUCV. + * Returns: return code from CP + */ int iucv_retrieve_buffer (void) { - iparml_control parm; ulong b2f0_result = 0; - pr_debug ("iucv_retrieve_buffer: entering\n"); - memset (&parm, 0, sizeof (parm)); - b2f0_result = b2f0 (RETRIEVE_BUFFER, &parm); - if (b2f0_result == NULL) { - kfree (handler_table_anchor); - handler_table_anchor = NULL; + iparml_control *parm = (iparml_control *)grab_param(); + + iucv_debug("entering"); + + b2f0_result = b2f0(RETRIEVE_BUFFER, parm); + release_param(parm); + if (b2f0_result == 0) { + kfree(iucv_pathid_table); + iucv_pathid_table = NULL; declare_flag = 0; } - pr_debug ("iucv_retrieve_buffer: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } -/* - * Name: iucv_register_program - * Purpose: Registers an application with IUCV. - * Input: prmname - user identification - * userid - machine identification - * pgmmask - indicates which bits in the prmname and userid combined will be used - * to determine who is given control - * ops - address of vector of interrupt handlers - * pgm_data- application data passed to interrupt handlers - * Output: NA - * Return: type: iucv_handle_t - * address of handler - * (0) - registration failed - * - Machine size > 2GB - * - new_handler kmalloc failed - * - pgmname was not provided - * - pathid_table kmalloc failed - * - application with identical pgmname, userid, and pgmmask is registered - * - iucv_declare_buffer failed - * NOTE: pgmmask - * When pgmname, userid, pgmmask is provided, mask is entered into the handler - * as is. - * When pgmname, userid is provided, pgmmask is all 0xff's - * When pgmname, pgmmask is provided, the first 8 bytes = 0x00 and the last 16 - * bytes are as provided by pgmmask. - * When pgmname is provided is provided, the first 8 bytes = 0x00 and the last - * 16 bytes are 0xff. -*/ +/** + * iucv_register_program: + * @pgmname: user identification + * @userid: machine identification + * @pgmmask: Indicates which bits in the pgmname and userid combined will be + * used to determine who is given control. + * @ops: Address of interrupt handler table. + * @pgm_data: Application data to be passed to interrupt handlers. + * + * Registers an application with IUCV. + * Returns: + * The address of handler, or NULL on failure. + * NOTE on pgmmask: + * If pgmname, userid and pgmmask are provided, pgmmask is entered into the + * handler as is. + * If pgmmask is NULL, the internal mask is set to all 0xff's + * When userid is NULL, the first 8 bytes of the internal mask are forced + * to 0x00. + * If pgmmask and userid are NULL, the first 8 bytes of the internal mask + * are forced to 0x00 and the last 16 bytes to 0xff. + */ iucv_handle_t -iucv_register_program (uchar pgmname[16], - uchar userid[8], - uchar pgmmask[24], +iucv_register_program (__u8 pgmname[16], + __u8 userid[8], + __u8 pgmmask[24], iucv_interrupt_ops_t * ops, void *pgm_data) { ulong rc = 0; /* return code from function calls */ - ulong machine_size = 0; /* size of virtual machine */ - static u32 maxconn1; - handler *new_handler = NULL; + handler *new_handler; - pr_debug ("iucv_register_program:entering\n"); + iucv_debug("entering"); if (ops == NULL) { /* interrupt table is not defined */ - printk (KERN_WARNING "iucv_register_program:" - "Interrupt table is not defined, exiting\n"); + printk(KERN_WARNING "%s: Interrupt table is not defined, " + "exiting\n", __FUNCTION__); + return NULL; + } + if (!pgmname) { + printk(KERN_WARNING "%s: pgmname not provided\n", __FUNCTION__); return NULL; } - if (declare_flag == 0) { - /* check size of virtual machine */ - if ((machine_size = iucv_vmsize ()) > 0x100000000) { /* 2GB */ - printk (KERN_WARNING "iucv_register_progam: Virtual" - "storage = %lx hex," "exiting\n", machine_size); + /* Allocate handler entry */ + new_handler = (handler *)kmalloc(sizeof(handler), GFP_KERNEL); + if (new_handler == NULL) { + printk(KERN_WARNING "%s: storage allocation for new handler " + "failed.\n", __FUNCTION__); + return NULL; + } + + if (!iucv_pathid_table) { + if (iucv_init()) { + kfree(new_handler); return NULL; } - pr_debug ("machine_size is %lx\n", machine_size); - - maxconn1 = iucv_query_maxconn (); - handler_table_anchor = kmalloc (maxconn1 * sizeof - (handler_table_entry), - GFP_KERNEL); - - if (handler_table_anchor == NULL) { - printk (KERN_WARNING "iucv_register_program:" - "handler_table_anchor" - "storage allocation failed\n"); + max_connections = iucv_query_maxconn(); + iucv_pathid_table = kmalloc(max_connections * sizeof(handler *), + GFP_KERNEL); + if (iucv_pathid_table == NULL) { + printk(KERN_WARNING "%s: iucv_pathid_table storage " + "allocation failed\n", __FUNCTION__); return NULL; } - - memset (handler_table_anchor, 0, - maxconn1 * sizeof (handler_table_entry)); - - } - /* Allocate handler table */ - new_handler = (handler *) kmalloc (sizeof (handler), GFP_KERNEL); - if (new_handler == NULL) { - printk (KERN_WARNING "iucv_register_program: storage allocation" - "for new handler failed. \n "); - return NULL; + memset (iucv_pathid_table, 0, max_connections * sizeof(handler *)); } - memset (new_handler, 0, sizeof (handler)); - if (pgmname) { - memcpy (new_handler->id.user_data, pgmname, - sizeof (new_handler->id.user_data)); - if (userid) { - memcpy (new_handler->id.userid, userid, - sizeof (new_handler->id.userid)); - ASCEBC (new_handler->id.userid, - sizeof (new_handler->id.userid)); - EBC_TOUPPER (new_handler->id.userid, - sizeof (new_handler->id.userid)); - - if (pgmmask) { - memcpy (new_handler->id.mask, pgmmask, - sizeof (new_handler->id.mask)); - } else { - memset (new_handler->id.mask, 0xFF, - sizeof (new_handler->id.mask)); - } + memset(new_handler, 0, sizeof (handler)); + memcpy(new_handler->id.user_data, pgmname, + sizeof (new_handler->id.user_data)); + if (userid) { + memcpy (new_handler->id.userid, userid, + sizeof (new_handler->id.userid)); + ASCEBC (new_handler->id.userid, + sizeof (new_handler->id.userid)); + EBC_TOUPPER (new_handler->id.userid, + sizeof (new_handler->id.userid)); + + if (pgmmask) { + memcpy (new_handler->id.mask, pgmmask, + sizeof (new_handler->id.mask)); } else { - if (pgmmask) { - memcpy (new_handler->id.mask, pgmmask, - sizeof (new_handler->id.mask)); - } else { - memset (new_handler->id.mask, 0xFF, - sizeof (new_handler->id.mask)); - } - memset (new_handler->id.mask, 0x00, - sizeof (new_handler->id.userid)); + memset (new_handler->id.mask, 0xFF, + sizeof (new_handler->id.mask)); } } else { - kfree (new_handler); - printk (KERN_WARNING "iucv_register_program: pgmname not" - "provided\n"); - return NULL; + if (pgmmask) { + memcpy (new_handler->id.mask, pgmmask, + sizeof (new_handler->id.mask)); + } else { + memset (new_handler->id.mask, 0xFF, + sizeof (new_handler->id.mask)); + } + memset (new_handler->id.mask, 0x00, + sizeof (new_handler->id.userid)); } /* fill in the rest of handler */ new_handler->pgm_data = pgm_data; new_handler->interrupt_table = ops; - new_handler->entries = ADDED_STOR; - /* Allocate storage for pathid table */ - new_handler->pathid_head = - kmalloc (new_handler->entries * sizeof (ulong), GFP_KERNEL); - if (new_handler->pathid_head == NULL) { - printk (KERN_WARNING "iucv_register_program: storage allocation" - "failed\n"); - kfree (new_handler); - return NULL; - } - memset (new_handler->pathid_head, 0, - new_handler->entries * sizeof (ulong)); - new_handler->pathid_tail = - new_handler->pathid_head + new_handler->entries; - /* - * Check if someone else is registered with same pgmname, userid, and mask. - * If someone is already registered with same pgmname, userid, and mask - * registration will fail and NULL will be returned to the application. + /* + * Check if someone else is registered with same pgmname, userid + * and mask. If someone is already registered with same pgmname, + * userid and mask, registration will fail and NULL will be returned + * to the application. * If identical handler not found, then handler is added to list. */ - rc = iucv_add_handler (new_handler); + rc = iucv_add_handler(new_handler); if (rc) { - printk (KERN_WARNING "iucv_register_program: Someone already" - "registered with same pgmname, userid, pgmmask\n"); - kfree (new_handler->pathid_head); + printk(KERN_WARNING "%s: Someone already registered with same " + "pgmname, userid, pgmmask\n", __FUNCTION__); kfree (new_handler); return NULL; } if (declare_flag == 0) { - rc = iucv_declare_buffer (); + rc = iucv_declare_buffer(); if (rc) { - kfree (handler_table_anchor); - kfree (new_handler->pathid_head); - kfree (new_handler); - handler_table_anchor = NULL; - printk (KERN_WARNING "iucv_register_program: rc from" - "iucv_declare_buffer is:% ld \n ", rc); + iucv_remove_handler(new_handler); + kfree(new_handler); + printk(KERN_WARNING "%s: iucv_declare_buffer " + "returned %ld\n", __FUNCTION__, rc); return NULL; } /* request the 0x4000 external interrupt */ - rc = register_external_interrupt (0x4000, top_half_interrupt); + rc = register_external_interrupt (0x4000, iucv_irq_handler); if (rc) { - iucv_retrieve_buffer (); - kfree (new_handler->pathid_head); + iucv_remove_handler(new_handler); + iucv_retrieve_buffer(); kfree (new_handler); - printk (KERN_WARNING "iucv_register_program: rc from" - "register_external_interrupt is:% ld \n ", rc); + printk(KERN_WARNING "%s: " + "register_external_interrupt returned %ld\n", + __FUNCTION__, rc); return NULL; } declare_flag = 1; } - pr_debug ("iucv_register_program: exiting\n"); + iucv_debug("exiting"); return new_handler; } /* end of register function */ -/* - * Name: iucv_unregister_program - * Purpose: Unregister application with IUCV. - * Input: handle address of handler - * Output: NA - * Return: (0) - Normal return - * (-EINVAL)- Matching handler was not found -*/ +/** + * iucv_unregister_program: + * @handle: address of handler + * + * Unregister application with IUCV. + * Returns: + * Always 0 + */ int iucv_unregister_program (iucv_handle_t handle) { - handler *users_handler = 0, *R; - handler_table_entry *H_T_E = 0; - ulong *S = 0; /*points to the beginning of block of h_t_e's */ + handler *h = (handler *)handle; + int i; ulong flags; - u16 pathid_sever = 0; - pr_debug ("iucv_unregister_program: entering\n"); - pr_debug ("iucv_unregister_program: address of handle is %p\n", handle); - spin_lock_irqsave (&iucv_lock, flags); - users_handler = (handler *) handle; - /* - * Checking if handle is still registered: if yes, continue - * if not registered, return. + + iucv_debug("entering"); + iucv_debug("address of handler is %p", h); + + /** + * First, walk thru iucv_pathid_table and sever any pathid which is + * still pointing to the handler to be removed. */ - for (R = handler_anchor; R != NULL; R = (handler *) R->next) - if (users_handler == R) { - pr_debug ("iucv_unregister_program: found a matching" - "handler\n"); - break; - } - if (!R) { - pr_debug ("You are not registered\n"); - spin_unlock_irqrestore (&iucv_lock, flags); - return (0); - } - S = users_handler->pathid_head; - while (S < (users_handler->pathid_tail)) { /* index thru table */ - if (*S) { - H_T_E = (handler_table_entry *) (*S); - - pr_debug ("iucv_unregister_program: pointer to H_T_E is" - "%p\n", H_T_E); - pr_debug - ("iucv_unregister_program: address of handle in" - "H_T_E is %p", (H_T_E->addrs)); - pathid_sever = H_T_E->pathid; + spin_lock_irqsave (&iucv_lock, flags); + for (i = 0; i < max_connections; i++) + if (iucv_pathid_table[i] == h) { spin_unlock_irqrestore (&iucv_lock, flags); - iucv_sever (pathid_sever, users_handler->id.user_data); - spin_lock_irqsave (&iucv_lock, flags); + iucv_sever(i, h->id.user_data); + spin_lock_irqsave(&iucv_lock, flags); } + spin_unlock_irqrestore (&iucv_lock, flags); - S++; /* index by address */ - } + iucv_remove_handler(h); + kfree(h); - kfree (users_handler->pathid_head); - iucv_remove_handler (users_handler); - spin_unlock_irqrestore (&iucv_lock, flags); - kfree (handle); - pr_debug ("iucv_unregister_program: exiting\n"); + iucv_debug("exiting"); return 0; } -/* - * Name: iucv_accept - * Purpose: This function is issued after the user receives a Connection Pending external - * interrupt and now wishes to complete the IUCV communication path. - * Input: pathid - u16 , path identification number - * msglim_reqstd - u16, The number of outstanding messages requested. - * user_data - uchar[16], Data specified by the iucv_connect function. - * flags1 - int, Contains options for this path. - * -IPPRTY - 0x20- Specifies if you want to send priority message. - * -IPRMDATA - 0x80, Specifies whether your program can handle a message - * in the parameter list. - * -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being - * established. - * handle - iucv_handle_t, Address of handler. - * pgm_data - ulong, Application data passed to interrupt handlers. - * flags1_out - int *, Options for path. - * IPPRTY - 0x20 - Indicates you may send a priority message. - * priority_permitted -uchar *, Indicates you may send priority messages. - * msglim - *u16, Number of outstanding messages. - * Output: b2f0_result - return code from CP -*/ +/** + * iucv_accept: + * @pathid: Path identification number + * @msglim_reqstd: The number of outstanding messages requested. + * @user_data: Data specified by the iucv_connect function. + * @flags1: Contains options for this path. + * - IPPRTY (0x20) Specifies if you want to send priority message. + * - IPRMDATA (0x80) Specifies whether your program can handle a message + * in the parameter list. + * - IPQUSCE (0x40) Specifies whether you want to quiesce the path being + * established. + * @handle: Address of handler. + * @pgm_data: Application data passed to interrupt handlers. + * @flags1_out: Pointer to an int. If not NULL, on return the options for + * the path are stored at the given location: + * - IPPRTY (0x20) Indicates you may send a priority message. + * @msglim: Pointer to an __u16. If not NULL, on return the maximum + * number of outstanding messages is stored at the given + * location. + * + * This function is issued after the user receives a Connection Pending external + * interrupt and now wishes to complete the IUCV communication path. + * Returns: + * return code from CP + */ int -iucv_accept (u16 pathid, u16 msglim_reqstd, - uchar user_data[16], int flags1, +iucv_accept(__u16 pathid, __u16 msglim_reqstd, + __u8 user_data[16], int flags1, iucv_handle_t handle, void *pgm_data, - int *flags1_out, u16 * msglim) + int *flags1_out, __u16 * msglim) { - iparml_control parm; ulong b2f0_result = 0; ulong flags; - handler *R = NULL; - pr_debug ("iucv_accept: entering \n"); - pr_debug ("iucv_accept: pathid = %d\n", pathid); + struct list_head *lh; + handler *h = NULL; + iparml_control *parm; + + iucv_debug("entering"); + iucv_debug("pathid = %d", pathid); /* Checking if handle is valid */ spin_lock_irqsave (&iucv_lock, flags); - - for (R = handler_anchor; R != NULL; R = (handler *) R->next) - if (R == handle) + list_for_each(lh, &iucv_handler_table) { + if ((handler *)handle == list_entry(lh, handler, list)) { + h = (handler *)handle; break; - + } + } spin_unlock_irqrestore (&iucv_lock, flags); - if (R == NULL) { - printk (KERN_WARNING "iucv_connect: NULL handle passed by" - "application\n"); + + if (!h) { + printk(KERN_WARNING "%s: NULL handle passed by application " + "or handler not found in iucv_handler_table\n", + __FUNCTION__); return -EINVAL; } - memset (&parm, 0, sizeof (parm)); - parm.ippathid = pathid; - parm.ipmsglim = msglim_reqstd; + parm = (iparml_control *)grab_param(); + + parm->ippathid = pathid; + parm->ipmsglim = msglim_reqstd; if (user_data) - memcpy (parm.ipuser, user_data, sizeof (parm.ipuser)); - parm.ipflags1 = (uchar) flags1; - b2f0_result = b2f0 (ACCEPT, &parm); + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + + parm->ipflags1 = (__u8)flags1; + b2f0_result = b2f0(ACCEPT, parm); if (b2f0_result == 0) { if (pgm_data) - (handler_table_anchor + pathid)->pgm_data = pgm_data; - if (parm.ipflags1 & IPPRTY) - if (flags1_out) { - pr_debug ("*flags1_out = %d\n", *flags1_out); - *flags1_out = 0; - *flags1_out |= IPPRTY; - pr_debug (" *flags1_out = %d\n", *flags1_out); - } + h->pgm_data = pgm_data; + if (flags1_out) + *flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0; } + release_param(parm); - pr_debug ("iucv_accept: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } -/* - * Name: iucv_connect - * Purpose: This function establishes an IUCV path. Although the connect may complete - * successfully, you are not able to use the path until you receive an IUCV - * Connection Complete external interrupt. - * Input: pathid - u16 *, path identification number - * msglim_reqstd - u16, number of outstanding messages requested - * user_data - uchar[16], 16-byte user data - * userid - uchar[8], 8-byte of user identification - * system_name - uchar[8], 8-byte identifying the system name - * flags1 - int, Contains options for this path. - * -IPPRTY - 0x20- Specifies if you want to send priority message. - * -IPRMDATA - 0x80, Specifies whether your program can handle a message - * in the parameter list. - * -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being - * established. - * -IPLOCAL - 0X01, allows an application to force the partner to be on the - * local system. If local is specified then target class cannot be - * specified. - * flags1_out - int *, Options for path. - * IPPRTY - 0x20 - Indicates you may send a priority message. - * msglim - * u16, number of outstanding messages - * handle - iucv_handle_t, address of handler - * pgm_data - *void, application data passed to interrupt handlers - * Output: b2f0_result - return code from CP - * -ENOMEM - * rc - return code from iucv_declare_buffer - * -EINVAL - invalid handle passed by application - * -EINVAL - pathid address is NULL - * -ENOMEM - pathid table storage allocation failed - * add_pathid_result - return code from internal function add_pathid -*/ +/** + * iucv_connect: + * @pathid: Path identification number + * @msglim_reqstd: Number of outstanding messages requested + * @user_data: 16-byte user data + * @userid: 8-byte of user identification + * @system_name: 8-byte identifying the system name + * @flags1: Specifies options for this path: + * - IPPRTY (0x20) Specifies if you want to send priority message. + * - IPRMDATA (0x80) Specifies whether your program can handle a message + * in the parameter list. + * - IPQUSCE (0x40) Specifies whether you want to quiesce the path being + * established. + * - IPLOCAL (0x01) Allows an application to force the partner to be on the + * local system. If local is specified then target class + * cannot be specified. + * @flags1_out: Pointer to an int. If not NULL, on return the options for + * the path are stored at the given location: + * - IPPRTY (0x20) Indicates you may send a priority message. + * @msglim: Pointer to an __u16. If not NULL, on return the maximum + * number of outstanding messages is stored at the given + * location. + * @handle: Address of handler. + * @pgm_data: Application data to be passed to interrupt handlers. + * + * This function establishes an IUCV path. Although the connect may complete + * successfully, you are not able to use the path until you receive an IUCV + * Connection Complete external interrupt. + * Returns: return code from CP, or one of the following + * - ENOMEM + * - return code from iucv_declare_buffer + * - EINVAL - invalid handle passed by application + * - EINVAL - pathid address is NULL + * - ENOMEM - pathid table storage allocation failed + * - return code from internal function add_pathid + */ int -iucv_connect (u16 * pathid, u16 msglim_reqstd, - uchar user_data[16], uchar userid[8], - uchar system_name[8], int flags1, - int *flags1_out, u16 * msglim, +iucv_connect (__u16 *pathid, __u16 msglim_reqstd, + __u8 user_data[16], __u8 userid[8], + __u8 system_name[8], int flags1, + int *flags1_out, __u16 * msglim, iucv_handle_t handle, void *pgm_data) { - iparml_control parm; + iparml_control *parm; + struct list_head *lh; ulong b2f0_result = 0; ulong flags; int add_pathid_result = 0; - handler *R = NULL; - uchar no_memory[16] = "NO MEMORY"; + handler *h = NULL; + __u8 no_memory[16] = "NO MEMORY"; - pr_debug ("iucv_connect: entering \n"); + iucv_debug("entering"); /* Checking if handle is valid */ spin_lock_irqsave (&iucv_lock, flags); - - for (R = handler_anchor; R != NULL; R = (handler *) R->next) - if (R == handle) + list_for_each(lh, &iucv_handler_table) { + if ((handler *)handle == list_entry(lh, handler, list)) { + h = (handler *)handle; break; - + } + } spin_unlock_irqrestore (&iucv_lock, flags); - if (R == NULL) { - printk (KERN_WARNING "iucv_connect: NULL handle passed by" - "application\n"); + if (!h) { + printk(KERN_WARNING "%s: NULL handle passed by application " + "or handler not found in iucv_handler_table\n", + __FUNCTION__); return -EINVAL; } if (pathid == NULL) { - printk (KERN_WARNING "iucv_connect: NULL pathid pointer\n"); + printk(KERN_WARNING "%s: NULL pathid pointer\n", + __FUNCTION__); return -EINVAL; } - memset (&parm, 0, sizeof (iparml_control)); - parm.ipmsglim = msglim_reqstd; + + parm = (iparml_control *)grab_param(); + + parm->ipmsglim = msglim_reqstd; if (user_data) - memcpy (parm.ipuser, user_data, sizeof (parm.ipuser)); + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); if (userid) { - memcpy (parm.ipvmid, userid, sizeof (parm.ipvmid)); - ASCEBC (parm.ipvmid, sizeof (parm.ipvmid)); - EBC_TOUPPER (parm.ipvmid, sizeof (parm.ipvmid)); + memcpy(parm->ipvmid, userid, sizeof(parm->ipvmid)); + ASCEBC(parm->ipvmid, sizeof(parm->ipvmid)); + EBC_TOUPPER(parm->ipvmid, sizeof(parm->ipvmid)); } if (system_name) { - memcpy (parm.iptarget, system_name, sizeof (parm.iptarget)); - ASCEBC (parm.iptarget, sizeof (parm.iptarget)); - EBC_TOUPPER (parm.iptarget, sizeof (parm.iptarget)); + memcpy(parm->iptarget, system_name, sizeof(parm->iptarget)); + ASCEBC(parm->iptarget, sizeof(parm->iptarget)); + EBC_TOUPPER(parm->iptarget, sizeof(parm->iptarget)); } - parm.ipflags1 = (uchar) flags1; - b2f0_result = b2f0 (CONNECT, &parm); - if (b2f0_result) - return b2f0_result; + parm->ipflags1 = (__u8)flags1; + b2f0_result = b2f0(CONNECT, parm); - add_pathid_result = iucv_add_pathid (parm.ippathid, handle, pgm_data); - if (add_pathid_result) { - - iucv_sever (parm.ippathid, no_memory); - printk (KERN_WARNING "iucv_connect: add_pathid failed with rc =" - "%d\n", add_pathid_result); - return (add_pathid_result); + if (b2f0_result) { + release_param(parm); + return b2f0_result; } - *pathid = parm.ippathid; + add_pathid_result = iucv_add_pathid(parm->ippathid, h); + *pathid = parm->ippathid; if (msglim) - *msglim = parm.ipmsglim; + *msglim = parm->ipmsglim; + if (flags1_out) + *flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0; - if (parm.ipflags1 & IPPRTY) - if (flags1_out) { - *flags1_out = 0; - *flags1_out |= IPPRTY; - } + if (add_pathid_result) { + iucv_sever(parm->ippathid, no_memory); + printk(KERN_WARNING "%s: add_pathid failed with rc =" + " %d\n", __FUNCTION__, add_pathid_result); + return(add_pathid_result); + } - pr_debug ("iucv_connect: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } -/* - * Name: iucv_purge - * Purpose: Cancels a message you have sent. - * Input: pathid - address of pathid - * msgid - address of message identification - * srccls - address of source message class - * audit - contains information about - * asynchronous error that may have affected - * the normal completion of this message. - * Output:b2f0_result - return code from CP -*/ +/** + * iucv_purge: + * @pathid: Path identification number + * @msgid: Message ID of message to purge. + * @srccls: Message class of the message to purge. + * @audit: Pointer to an __u32. If not NULL, on return, information about + * asynchronous errors that may have affected the normal completion + * of this message ist stored at the given location. + * + * Cancels a message you have sent. + * Returns: return code from CP + */ int -iucv_purge (u16 pathid, u32 msgid, u32 srccls, uchar audit[3]) +iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit) { - iparml_purge parm; + iparml_purge *parm; ulong b2f0_result = 0; - pr_debug ("iucv_purge: entering\n"); - pr_debug ("iucv_purge: pathid = %d \n", pathid); - memset (&parm, 0, sizeof (parm)); - parm.ipmsgid = msgid; - parm.ippathid = pathid; - parm.ipsrccls = srccls; - parm.ipflags1 |= (IPSRCCLS | IPFGMID | IPFGPID); - b2f0_result = b2f0 (PURGE, &parm); - - if ((b2f0_result == 0) && (audit)) - memcpy (audit, parm.ipaudit, sizeof (parm.ipaudit)); - - pr_debug ("iucv_purge: b2f0_result = %ld \n", b2f0_result); - pr_debug ("iucv_purge: exiting\n"); - return b2f0_result; -} -/* - * Name: iucv_query_maxconn - * Purpose: Determines the maximum number of connections thay may be established. - * Output: maxconn - ulong: Maximum number of connections that can be. -*/ -ulong -iucv_query_maxconn (void) -{ - iparml_purge parm; /* DOESN'T MATTER WHICH IPARML IS USED */ - static u32 maxconn1, bufsize1; + iucv_debug("entering"); + iucv_debug("pathid = %d", pathid); - pr_debug ("iucv_query_maxconn: entering\n"); + parm = (iparml_purge *)grab_param(); - memset (&parm, 0, sizeof (parm)); + parm->ipmsgid = msgid; + parm->ippathid = pathid; + parm->ipsrccls = srccls; + parm->ipflags1 |= (IPSRCCLS | IPFGMID | IPFGPID); + b2f0_result = b2f0(PURGE, parm); - /* Assembler instruction calling b2f0 and storing R0 and R1 */ - asm volatile ("LRA 1,0(%3)\n\t" - "LR 0,%2\n\t" - ".long 0xb2f01000\n\t" - "ST 0,%0\n\t" - "ST 1,%1\n\t":"=m" (bufsize1), - "=m" (maxconn1):"d" (QUERY), "a" (&parm):"0", "1"); - - pr_debug (" bufsize1 = %d and maxconn1 = %d \n", bufsize1, maxconn1); - pr_debug ("iucv_query_maxconn: exiting\n"); + if ((b2f0_result == 0) && audit) { + memcpy(audit, parm->ipaudit, sizeof(parm->ipaudit)); + /* parm->ipaudit has only 3 bytes */ + *audit >>= 8; + } + + release_param(parm); - return maxconn1; + iucv_debug("b2f0_result = %ld", b2f0_result); + iucv_debug("exiting"); + return b2f0_result; } -/* - * Name: iucv_query_bufsize - * Purpose: Determines the size of the external interrupt buffer. - * Output: bufsize - ulong: Size of external interrupt buffer. +/** + * iucv_query_generic: + * @want_maxconn: Flag, describing which value is to be returned. + * + * Helper function for iucv_query_maxconn() and iucv_query_bufsize(). + * + * Returns: The buffersize, if want_maxconn is 0; the maximum number of + * connections, if want_maxconn is 1 or an error-code < 0 on failure. */ -ulong -iucv_query_bufsize (void) +static int +iucv_query_generic(int want_maxconn) { - iparml_purge parm; /* DOESN'T MATTER WHICH IPARML IS USED */ - static u32 maxconn1, bufsize1; - - pr_debug ("iucv_query_bufsize: entering\n"); - pr_debug ("iucv_query_maxconn: entering\n"); + iparml_purge *parm = (iparml_purge *)grab_param(); + int bufsize, maxconn; + int ccode; - memset (&parm, 0, sizeof (parm)); - - /* Assembler instruction calling b2f0 and storing R0 and R1 */ - asm volatile ("LRA 1,0(%3)\n\t" - "LR 0,%2\n\t" - ".long 0xb2f01000\n\t" - "ST 0,%0\n\t" - "ST 1,%1\n\t":"=m" (bufsize1), - "=m" (maxconn1):"d" (QUERY), "a" (&parm):"0", "1"); + /** + * Call b2f0 and store R0 (max buffer size), + * R1 (max connections) and CC. + */ + asm volatile ( + "LRA 1,0(%4)\n\t" + "LR 0,%3\n\t" + ".long 0xb2f01000\n\t" + "IPM %0\n\t" + "SRL %0,28\n\t" + "ST 0,%1\n\t" + "ST 1,%2\n\t" + : "=d" (ccode), "=m" (bufsize), "=m" (maxconn) + : "d" (QUERY), "a" (parm) + : "0", "1", "cc" + ); + release_param(parm); + + if (ccode) + return -EPERM; + if (want_maxconn) + return maxconn; + return bufsize; +} - pr_debug (" bufsize1 = %d and maxconn1 = %d \n", bufsize1, maxconn1); - pr_debug ("iucv_query_bufsize: exiting\n"); +/** + * iucv_query_maxconn: + * + * Determines the maximum number of connections thay may be established. + * + * Returns: Maximum number of connections that can be. + */ +ulong +iucv_query_maxconn(void) +{ + return iucv_query_generic(1); +} - return bufsize1; +/** + * iucv_query_bufsize: + * + * Determines the size of the external interrupt buffer. + * + * Returns: Size of external interrupt buffer. + */ +ulong +iucv_query_bufsize (void) +{ + return iucv_query_generic(0); } -/* - * Name: iucv_quiesce - * Purpose: temporarily suspends incoming messages on an IUCV path. - * You can later reactivate the path by invoking the iucv_resume function - * Input: pathid - u16, path identification number - * user_data - uchar[16], 16-byte user data - * Output: b2f0_result - return code from CP +/** + * iucv_quiesce: + * @pathid: Path identification number + * @user_data: 16-byte user data + * + * Temporarily suspends incoming messages on an IUCV path. + * You can later reactivate the path by invoking the iucv_resume function. + * Returns: return code from CP */ int -iucv_quiesce (u16 pathid, uchar user_data[16]) +iucv_quiesce (__u16 pathid, __u8 user_data[16]) { - iparml_control parm; + iparml_control *parm; ulong b2f0_result = 0; - pr_debug ("iucv_quiesce: entering \n"); - pr_debug ("iucv_quiesce: pathid = %d\n", pathid); + iucv_debug("entering"); + iucv_debug("pathid = %d", pathid); - memset (&parm, 0, sizeof (parm)); - memcpy (parm.ipuser, user_data, sizeof (parm.ipuser)); - parm.ippathid = pathid; + parm = (iparml_control *)grab_param(); - b2f0_result = b2f0 (QUIESCE, &parm); + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + parm->ippathid = pathid; - pr_debug ("iucv_quiesce: b2f0_result = %ld\n", b2f0_result); - pr_debug ("iucv_quiesce: exiting\n"); + b2f0_result = b2f0(QUIESCE, parm); + release_param(parm); + + iucv_debug("b2f0_result = %ld", b2f0_result); + iucv_debug("exiting"); return b2f0_result; } -/* - * Name: iucv_receive - * Purpose: This function receives messages that are being sent to you - * over established paths. - * Input: - * pathid - path identification number - * buffer - address of buffer to receive - * buflen - length of buffer to receive - * msgid - specifies the message ID. - * trgcls - specifies target class - * Output: - * flags1_out: Options for path. - * IPNORPY - 0x10 specifies whether a reply is required - * IPPRTY - 0x20 specifies if you want to send priority message - * IPRMDATA - 0x80 specifies the data is contained in the parameter list - * residual_buffer - address of buffer updated by the number - * of bytes you have received. - * residual_length - - * Contains one of the following values, if the receive buffer is: - * The same length as the message, this field is zero. - * Longer than the message, this field contains the number of - * bytes remaining in the buffer. - * Shorter than the message, this field contains the residual - * count (that is, the number of bytes remaining in the - * message that does not fit into the buffer. In this - * case b2f0_result = 5. - * Return: b2f0_result - return code from CP IUCV call. - * (-EINVAL) - buffer address is pointing to NULL +/** + * iucv_receive: + * @pathid: Path identification number. + * @buffer: Address of buffer to receive. Must be below 2G. + * @buflen: Length of buffer to receive. + * @msgid: Specifies the message ID. + * @trgcls: Specifies target class. + * @flags1_out: Receives options for path on return. + * - IPNORPY (0x10) Specifies whether a reply is required + * - IPPRTY (0x20) Specifies if you want to send priority message + * - IPRMDATA (0x80) Specifies the data is contained in the parameter list + * @residual_buffer: Receives the address of buffer updated by the number + * of bytes you have received on return. + * @residual_length: On return, receives one of the following values: + * - 0 If the receive buffer is the same length as + * the message. + * - Remaining bytes in buffer If the receive buffer is longer than the + * message. + * - Remaining bytes in message If the receive buffer is shorter than the + * message. + * + * This function receives messages that are being sent to you over established + * paths. + * Returns: return code from CP IUCV call; If the receive buffer is shorter + * than the message, always 5 + * -EINVAL - buffer address is pointing to NULL */ int -iucv_receive (u16 pathid, u32 msgid, u32 trgcls, +iucv_receive (__u16 pathid, __u32 msgid, __u32 trgcls, void *buffer, ulong buflen, int *flags1_out, ulong * residual_buffer, ulong * residual_length) { - iparml_db parm; + iparml_db *parm; ulong b2f0_result; - int moved = 0; /* number of bytes moved from parmlist to buffer */ - pr_debug ("iucv_receive: entering\n"); + int moved = 0; /* number of bytes moved from parmlist to buffer */ + + iucv_debug("entering"); if (!buffer) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ipbfadr1 = (u32) buffer; - parm.ipbfln1f = (u32) ((ulong) buflen); - parm.ipmsgid = msgid; - parm.ippathid = pathid; - parm.iptrgcls = trgcls; - parm.ipflags1 = (IPFGPID | IPFGMID | IPFGMCL); + parm = (iparml_db *)grab_param(); + + parm->ipbfadr1 = (__u32) buffer; + parm->ipbfln1f = (__u32) ((ulong) buflen); + parm->ipmsgid = msgid; + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPFGPID | IPFGMID | IPFGMCL); - b2f0_result = b2f0 (RECEIVE, &parm); + b2f0_result = b2f0(RECEIVE, parm); if (b2f0_result == 0 || b2f0_result == 5) { if (flags1_out) { - pr_debug ("*flags1_out = %d\n", *flags1_out); - *flags1_out = (parm.ipflags1 & (~0x07)); - pr_debug ("*flags1_out = %d\n", *flags1_out); + iucv_debug("*flags1_out = %d", *flags1_out); + *flags1_out = (parm->ipflags1 & (~0x07)); + iucv_debug("*flags1_out = %d", *flags1_out); } - if (!(parm.ipflags1 & IPRMDATA)) { /*msg not in parmlist */ + if (!(parm->ipflags1 & IPRMDATA)) { /*msg not in parmlist */ if (residual_length) - *residual_length = parm.ipbfln1f; + *residual_length = parm->ipbfln1f; if (residual_buffer) - *residual_buffer = parm.ipbfadr1; + *residual_buffer = parm->ipbfadr1; } else { - moved = min_t(unsigned int, buflen, 8); + moved = min (buflen, 8); memcpy ((char *) buffer, - (char *) &parm.ipbfadr1, moved); + (char *) &parm->ipbfadr1, moved); if (buflen < 8) b2f0_result = 5; @@ -1324,14 +1201,16 @@ iucv_receive (u16 pathid, u32 msgid, u32 trgcls, *residual_buffer = (ulong) (buffer + moved); } } - pr_debug ("iucv_receive: exiting \n"); + release_param(parm); + + iucv_debug("exiting"); return b2f0_result; } /* * Name: iucv_receive_array * Purpose: This function receives messages that are being sent to you - * over established paths. + * over established paths. * Input: pathid - path identification number * buffer - address of array of buffers * buflen - total length of buffers @@ -1357,64 +1236,65 @@ iucv_receive (u16 pathid, u32 msgid, u32 trgcls, * (-EINVAL) - buffer address is NULL */ int -iucv_receive_array (u16 pathid, - u32 msgid, u32 trgcls, +iucv_receive_array (__u16 pathid, + __u32 msgid, __u32 trgcls, iucv_array_t * buffer, ulong buflen, int *flags1_out, ulong * residual_buffer, ulong * residual_length) { - iparml_db parm; + iparml_db *parm; ulong b2f0_result; int i = 0, moved = 0, need_to_move = 8, dyn_len; - pr_debug ("iucv_receive_array: entering\n"); + + iucv_debug("entering"); if (!buffer) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ipbfadr1 = (u32) ((ulong) buffer); - parm.ipbfln1f = (u32) buflen; - parm.ipmsgid = msgid; - parm.ippathid = pathid; - parm.iptrgcls = trgcls; - parm.ipflags1 = (IPBUFLST | IPFGPID | IPFGMID | IPFGMCL); + parm = (iparml_db *)grab_param(); - b2f0_result = b2f0 (RECEIVE, &parm); + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; + parm->ipmsgid = msgid; + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPBUFLST | IPFGPID | IPFGMID | IPFGMCL); + + b2f0_result = b2f0(RECEIVE, parm); if (b2f0_result == 0 || b2f0_result == 5) { if (flags1_out) { - pr_debug ("*flags1_out = %d\n", *flags1_out); - *flags1_out = (parm.ipflags1 & (~0x07)); - pr_debug ("*flags1_out = %d\n", *flags1_out); + iucv_debug("*flags1_out = %d", *flags1_out); + *flags1_out = (parm->ipflags1 & (~0x07)); + iucv_debug("*flags1_out = %d", *flags1_out); } - if (!(parm.ipflags1 & IPRMDATA)) { /*msg not in parmlist */ + if (!(parm->ipflags1 & IPRMDATA)) { /*msg not in parmlist */ if (residual_length) - *residual_length = parm.ipbfln1f; + *residual_length = parm->ipbfln1f; if (residual_buffer) - *residual_buffer = parm.ipbfadr1; + *residual_buffer = parm->ipbfadr1; } else { /* copy msg from parmlist to users array. */ while ((moved < 8) && (moved < buflen)) { dyn_len = - min_t(unsigned int, - (buffer + i)->length, need_to_move); + min ((buffer + i)->length, need_to_move); memcpy ((char *)((ulong)((buffer + i)->address)), - ((char *) &parm.ipbfadr1) + moved, + ((char *) &parm->ipbfadr1) + moved, dyn_len); moved += dyn_len; need_to_move -= dyn_len; (buffer + i)->address = - (u32) - ((ulong)(uchar *) ((ulong)(buffer + i)->address) + (__u32) + ((ulong)(__u8 *) ((ulong)(buffer + i)->address) + dyn_len); (buffer + i)->length -= dyn_len; @@ -1437,52 +1317,55 @@ iucv_receive_array (u16 pathid, } } + release_param(parm); - pr_debug ("iucv_receive_array: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } -/* - * Name: iucv_reject - * Purpose: Refuses a specified message. Between the time you are notified of a - * message and the time that you complete the message, the message may - * be rejected. - * Input: pathid - u16, path identification number. - * msgid - u32, specifies the message ID. - * trgcls - u32, specifies target class. - * Output: b2f0_result - return code from CP - * NOTE: see b2f0 output list -*/ +/** + * iucv_reject: + * @pathid: Path identification number. + * @msgid: Message ID of the message to reject. + * @trgcls: Target class of the message to reject. + * Returns: return code from CP + * + * Refuses a specified message. Between the time you are notified of a + * message and the time that you complete the message, the message may + * be rejected. + */ int -iucv_reject (u16 pathid, u32 msgid, u32 trgcls) +iucv_reject (__u16 pathid, __u32 msgid, __u32 trgcls) { - iparml_db parm; + iparml_db *parm; ulong b2f0_result = 0; - pr_debug ("iucv_reject: entering \n"); - pr_debug ("iucv_reject: pathid = %d\n", pathid); + iucv_debug("entering"); + iucv_debug("pathid = %d", pathid); - memset (&parm, 0, sizeof (parm)); - parm.ippathid = pathid; - parm.ipmsgid = msgid; - parm.iptrgcls = trgcls; - parm.ipflags1 = (IPFGMCL | IPFGMID | IPFGPID); + parm = (iparml_db *)grab_param(); - b2f0_result = b2f0 (REJECT, &parm); + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPFGMCL | IPFGMID | IPFGPID); - pr_debug ("iucv_reject: b2f0_result = %ld\n", b2f0_result); - pr_debug ("iucv_reject: exiting\n"); + b2f0_result = b2f0(REJECT, parm); + release_param(parm); + + iucv_debug("b2f0_result = %ld", b2f0_result); + iucv_debug("exiting"); return b2f0_result; } -/* +/* * Name: iucv_reply * Purpose: This function responds to the two-way messages that you * receive. You must identify completely the message to * which you wish to reply. ie, pathid, msgid, and trgcls. * Input: pathid - path identification number - * msgid - specifies the message ID. + * msgid - specifies the message ID. * trgcls - specifies target class * flags1 - option for path * IPPRTY- 0x20 - specifies if you want to send priority message @@ -1503,37 +1386,39 @@ iucv_reject (u16 pathid, u32 msgid, u32 trgcls) * (-EINVAL) - buffer address is NULL */ int -iucv_reply (u16 pathid, - u32 msgid, u32 trgcls, +iucv_reply (__u16 pathid, + __u32 msgid, __u32 trgcls, int flags1, void *buffer, ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f) { - iparml_db parm; + iparml_db *parm; ulong b2f0_result; - pr_debug ("iucv_reply: entering\n"); + iucv_debug("entering"); if (!buffer) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ipbfadr2 = (u32) ((ulong) buffer); - parm.ipbfln2f = (u32) buflen; /* length of message */ - parm.ippathid = pathid; - parm.ipmsgid = msgid; - parm.iptrgcls = trgcls; - parm.ipflags1 = (uchar) flags1; /* priority message */ + parm = (iparml_db *)grab_param(); - b2f0_result = b2f0 (REPLY, &parm); + parm->ipbfadr2 = (__u32) ((ulong) buffer); + parm->ipbfln2f = (__u32) buflen; /* length of message */ + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (__u8) flags1; /* priority message */ + + b2f0_result = b2f0(REPLY, parm); if ((b2f0_result == 0) || (b2f0_result == 5)) { if (ipbfadr2) - *ipbfadr2 = parm.ipbfadr2; + *ipbfadr2 = parm->ipbfadr2; if (ipbfln2f) - *ipbfln2f = parm.ipbfln2f; + *ipbfln2f = parm->ipbfln2f; } + release_param(parm); - pr_debug ("iucv_reply: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } @@ -1541,13 +1426,13 @@ iucv_reply (u16 pathid, /* * Name: iucv_reply_array * Purpose: This function responds to the two-way messages that you - * receive. You must identify completely the message to + * receive. You must identify completely the message to * which you wish to reply. ie, pathid, msgid, and trgcls. * The array identifies a list of addresses and lengths of * discontiguous buffers that contains the reply data. * Input: pathid - path identification number - * msgid - specifies the message ID. - * trgcls - specifies target class + * msgid - specifies the message ID. + * trgcls - specifies target class * flags1 - option for path * IPPRTY- specifies if you want to send priority message * buffer - address of array of reply buffers @@ -1566,39 +1451,41 @@ iucv_reply (u16 pathid, * (-EINVAL) - buffer address is NULL */ int -iucv_reply_array (u16 pathid, - u32 msgid, u32 trgcls, +iucv_reply_array (__u16 pathid, + __u32 msgid, __u32 trgcls, int flags1, iucv_array_t * buffer, ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f) { - iparml_db parm; + iparml_db *parm; ulong b2f0_result; - pr_debug ("iucv_reply_array: entering\n"); + iucv_debug("entering"); if (!buffer) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ipbfadr2 = (u32) ((ulong) buffer); - parm.ipbfln2f = buflen; /* length of message */ - parm.ippathid = pathid; - parm.ipmsgid = msgid; - parm.iptrgcls = trgcls; - parm.ipflags1 = (IPANSLST | flags1); + parm = (iparml_db *)grab_param(); + + parm->ipbfadr2 = (__u32) ((ulong) buffer); + parm->ipbfln2f = buflen; /* length of message */ + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPANSLST | flags1); - b2f0_result = b2f0 (REPLY, &parm); + b2f0_result = b2f0(REPLY, parm); if ((b2f0_result == 0) || (b2f0_result == 5)) { if (ipbfadr2) - *ipbfadr2 = parm.ipbfadr2; + *ipbfadr2 = parm->ipbfadr2; if (ipbfln2f) - *ipbfln2f = parm.ipbfln2f; + *ipbfln2f = parm->ipbfln2f; } + release_param(parm); - pr_debug ("iucv_reply_array: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } @@ -1611,7 +1498,7 @@ iucv_reply_array (u16 pathid, * Prmmsg signifies the data is moved into the * parameter list. * Input: pathid - path identification number - * msgid - specifies the message ID. + * msgid - specifies the message ID. * trgcls - specifies target class * flags1 - option for path * IPPRTY- specifies if you want to send priority message @@ -1621,98 +1508,105 @@ iucv_reply_array (u16 pathid, * Return: b2f0_result - return code from CP */ int -iucv_reply_prmmsg (u16 pathid, - u32 msgid, u32 trgcls, int flags1, uchar prmmsg[8]) +iucv_reply_prmmsg (__u16 pathid, + __u32 msgid, __u32 trgcls, int flags1, __u8 prmmsg[8]) { - iparml_dpl parm; + iparml_dpl *parm; ulong b2f0_result; - pr_debug ("iucv_reply_prmmsg: entering\n"); + iucv_debug("entering"); + + parm = (iparml_dpl *)grab_param(); - memset (&parm, 0, sizeof (parm)); - parm.ippathid = pathid; - parm.ipmsgid = msgid; - parm.iptrgcls = trgcls; - memcpy (parm.iprmmsg, prmmsg, sizeof (parm.iprmmsg)); - parm.ipflags1 = (IPRMDATA | flags1); + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + memcpy(parm->iprmmsg, prmmsg, sizeof (parm->iprmmsg)); + parm->ipflags1 = (IPRMDATA | flags1); - b2f0_result = b2f0 (REPLY, &parm); + b2f0_result = b2f0(REPLY, parm); + release_param(parm); - pr_debug ("iucv_reply_prmmsg: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } -/* - * Name: iucv_resume - * Purpose: This function restores communication over a quiesced path. - * Input: pathid - u16, path identification number - * user_data - uchar[16], 16-byte of user data - * Output: b2f0_result - return code from CP +/** + * iucv_resume: + * @pathid: Path identification number + * @user_data: 16-byte of user data + * + * This function restores communication over a quiesced path. + * Returns: return code from CP */ int -iucv_resume (u16 pathid, uchar user_data[16]) +iucv_resume (__u16 pathid, __u8 user_data[16]) { - iparml_control parm; + iparml_control *parm; ulong b2f0_result = 0; - pr_debug ("iucv_resume: entering\n"); - pr_debug ("iucv_resume: pathid = %d\n", pathid); + iucv_debug("entering"); + iucv_debug("pathid = %d", pathid); + + parm = (iparml_control *)grab_param(); - memset (&parm, 0, sizeof (parm)); - memcpy (parm.ipuser, user_data, sizeof (*user_data)); - parm.ippathid = pathid; + memcpy (parm->ipuser, user_data, sizeof (*user_data)); + parm->ippathid = pathid; - b2f0_result = b2f0 (RESUME, &parm); + b2f0_result = b2f0(RESUME, parm); + release_param(parm); - pr_debug ("iucv_resume: exiting \n"); + iucv_debug("exiting"); return b2f0_result; } /* - * Name: iucv_send - * Purpose: sends messages - * Input: pathid - ushort, pathid - * msgid - ulong *, id of message returned to caller - * trgcls - ulong, target message class - * srccls - ulong, source message class - * msgtag - ulong, message tag + * Name: iucv_send + * Purpose: sends messages + * Input: pathid - ushort, pathid + * msgid - ulong *, id of message returned to caller + * trgcls - ulong, target message class + * srccls - ulong, source message class + * msgtag - ulong, message tag * flags1 - Contains options for this path. * IPPRTY - Ox20 - specifies if you want to send a priority message. - * buffer - pointer to buffer - * buflen - ulong, length of buffer - * Output: b2f0_result - return code from b2f0 call - * msgid - returns message id + * buffer - pointer to buffer + * buflen - ulong, length of buffer + * Output: b2f0_result - return code from b2f0 call + * msgid - returns message id */ int -iucv_send (u16 pathid, u32 * msgid, - u32 trgcls, u32 srccls, - u32 msgtag, int flags1, void *buffer, ulong buflen) +iucv_send (__u16 pathid, __u32 * msgid, + __u32 trgcls, __u32 srccls, + __u32 msgtag, int flags1, void *buffer, ulong buflen) { - iparml_db parm; + iparml_db *parm; ulong b2f0_result; - pr_debug ("iucv_send: entering\n"); + iucv_debug("entering"); if (!buffer) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ipbfadr1 = (u32) ((ulong) buffer); - parm.ippathid = pathid; - parm.iptrgcls = trgcls; - parm.ipbfln1f = (u32) buflen; /* length of message */ - parm.ipsrccls = srccls; - parm.ipmsgtag = msgtag; - parm.ipflags1 = (IPNORPY | flags1); /* one way priority message */ + parm = (iparml_db *)grab_param(); - b2f0_result = b2f0 (SEND, &parm); + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPNORPY | flags1); /* one way priority message */ + + b2f0_result = b2f0(SEND, parm); if ((b2f0_result == 0) && (msgid)) - *msgid = parm.ipmsgid; + *msgid = parm->ipmsgid; + release_param(parm); - pr_debug ("iucv_send: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } @@ -1733,43 +1627,46 @@ iucv_send (u16 pathid, u32 * msgid, * buffer - address of array of send buffers * buflen - total length of send buffers * Output: msgid - specifies the message ID. - * Return: b2f0_result - return code from CP + * Return: b2f0_result - return code from CP * (-EINVAL) - buffer address is NULL */ int -iucv_send_array (u16 pathid, - u32 * msgid, - u32 trgcls, - u32 srccls, - u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen) +iucv_send_array (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen) { - iparml_db parm; + iparml_db *parm; ulong b2f0_result; - pr_debug ("iucv_send_array: entering\n"); + iucv_debug("entering"); if (!buffer) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ippathid = pathid; - parm.iptrgcls = trgcls; - parm.ipbfadr1 = (u32) ((ulong) buffer); - parm.ipbfln1f = (u32) buflen; /* length of message */ - parm.ipsrccls = srccls; - parm.ipmsgtag = msgtag; - parm.ipflags1 = (IPNORPY | IPBUFLST | flags1); - b2f0_result = b2f0 (SEND, &parm); + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPNORPY | IPBUFLST | flags1); + b2f0_result = b2f0(SEND, parm); if ((b2f0_result == 0) && (msgid)) - *msgid = parm.ipmsgid; - pr_debug ("iucv_send_array: exiting\n"); + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug("exiting"); return b2f0_result; } /* * Name: iucv_send_prmmsg - * Purpose: This function transmits data to another application. + * Purpose: This function transmits data to another application. * Prmmsg specifies that the 8-bytes of data are to be moved * into the parameter list. This is a one-way message and the * receiver will not reply to the message. @@ -1780,34 +1677,37 @@ iucv_send_array (u16 pathid, * flags1 - option for path * IPPRTY- specifies if you want to send priority message * prmmsg - 8-bytes of data to be placed into parameter list - * Output: msgid - specifies the message ID. + * Output: msgid - specifies the message ID. * Return: b2f0_result - return code from CP */ int -iucv_send_prmmsg (u16 pathid, - u32 * msgid, - u32 trgcls, - u32 srccls, u32 msgtag, int flags1, uchar prmmsg[8]) +iucv_send_prmmsg (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, __u32 msgtag, int flags1, __u8 prmmsg[8]) { - iparml_dpl parm; + iparml_dpl *parm; ulong b2f0_result; - pr_debug ("iucv_send_prmmsg: entering\n"); + iucv_debug("entering"); - memset (&parm, 0, sizeof (parm)); - parm.ippathid = pathid; - parm.iptrgcls = trgcls; - parm.ipsrccls = srccls; - parm.ipmsgtag = msgtag; - parm.ipflags1 = (IPRMDATA | IPNORPY | flags1); - memcpy (parm.iprmmsg, prmmsg, sizeof (parm.iprmmsg)); + parm = (iparml_dpl *)grab_param(); - b2f0_result = b2f0 (SEND, &parm); + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPRMDATA | IPNORPY | flags1); + memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); + + b2f0_result = b2f0(SEND, parm); if ((b2f0_result == 0) && (msgid)) - *msgid = parm.ipmsgid; + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug("exiting"); - pr_debug ("iucv_send_prmmsg: exiting\n"); return b2f0_result; } @@ -1816,7 +1716,7 @@ iucv_send_prmmsg (u16 pathid, * Purpose: This function transmits data to another application. * Data to be transmitted is in a buffer. The receiver * of the send is expected to reply to the message and - * a buffer is provided into which IUCV moves the reply + * a buffer is provided into which IUCV moves the reply * to this message. * Input: pathid - path identification number * trgcls - specifies target class @@ -1833,38 +1733,41 @@ iucv_send_prmmsg (u16 pathid, * (-EINVAL) - buffer or ansbuf address is NULL */ int -iucv_send2way (u16 pathid, - u32 * msgid, - u32 trgcls, - u32 srccls, - u32 msgtag, +iucv_send2way (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, int flags1, void *buffer, ulong buflen, void *ansbuf, ulong anslen) { - iparml_db parm; + iparml_db *parm; ulong b2f0_result; - pr_debug ("iucv_send2way: entering\n"); + + iucv_debug("entering"); if (!buffer || !ansbuf) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ippathid = pathid; - parm.iptrgcls = trgcls; - parm.ipbfadr1 = (u32) ((ulong) buffer); - parm.ipbfln1f = (u32) buflen; /* length of message */ - parm.ipbfadr2 = (u32) ((ulong) ansbuf); - parm.ipbfln2f = (u32) anslen; - parm.ipsrccls = srccls; - parm.ipmsgtag = msgtag; - parm.ipflags1 = flags1; /* priority message */ + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = flags1; /* priority message */ - b2f0_result = b2f0 (SEND, &parm); + b2f0_result = b2f0(SEND, parm); if ((b2f0_result == 0) && (msgid)) - *msgid = parm.ipmsgid; + *msgid = parm->ipmsgid; + release_param(parm); - pr_debug ("iucv_send2way: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } @@ -1885,44 +1788,47 @@ iucv_send2way (u16 pathid, * IPPRTY- specifies if you want to send priority message * buffer - address of array of send buffers * buflen - total length of send buffers - * ansbuf - address of buffer to reply with - * anslen - length of buffer to reply with + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with * Output: msgid - specifies the message ID. * Return: b2f0_result - return code from CP * (-EINVAL) - buffer address is NULL */ int -iucv_send2way_array (u16 pathid, - u32 * msgid, - u32 trgcls, - u32 srccls, - u32 msgtag, +iucv_send2way_array (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen, iucv_array_t * ansbuf, ulong anslen) { - iparml_db parm; + iparml_db *parm; ulong b2f0_result; - pr_debug ("iucv_send2way_array: entering\n"); + iucv_debug("entering"); if (!buffer || !ansbuf) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ippathid = pathid; - parm.iptrgcls = trgcls; - parm.ipbfadr1 = (u32) ((ulong) buffer); - parm.ipbfln1f = (u32) buflen; /* length of message */ - parm.ipbfadr2 = (u32) ((ulong) ansbuf); - parm.ipbfln2f = (u32) anslen; - parm.ipsrccls = srccls; - parm.ipmsgtag = msgtag; - parm.ipflags1 = (IPBUFLST | IPANSLST | flags1); - b2f0_result = b2f0 (SEND, &parm); + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPBUFLST | IPANSLST | flags1); + b2f0_result = b2f0(SEND, parm); if ((b2f0_result == 0) && (msgid)) - *msgid = parm.ipmsgid; - pr_debug ("iucv_send2way_array: exiting\n"); + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug("exiting"); return b2f0_result; } @@ -1934,50 +1840,53 @@ iucv_send2way_array (u16 pathid, * receiver of the message is expected to reply. A buffer * is provided into which IUCV moves the reply to this * message. - * Input: pathid - path identification number + * Input: pathid - path identification number * trgcls - specifies target class * srccls - specifies the source message class * msgtag - specifies a tag to be associated with the message * flags1 - option for path * IPPRTY- specifies if you want to send priority message * prmmsg - 8-bytes of data to be placed in parameter list - * ansbuf - address of buffer to reply with - * anslen - length of buffer to reply with + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with * Output: msgid - specifies the message ID. * Return: b2f0_result - return code from CP * (-EINVAL) - buffer address is NULL */ int -iucv_send2way_prmmsg (u16 pathid, - u32 * msgid, - u32 trgcls, - u32 srccls, - u32 msgtag, - ulong flags1, uchar prmmsg[8], void *ansbuf, ulong anslen) +iucv_send2way_prmmsg (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, + ulong flags1, __u8 prmmsg[8], void *ansbuf, ulong anslen) { - iparml_dpl parm; + iparml_dpl *parm; ulong b2f0_result; - pr_debug ("iucv_send2way_prmmsg: entering\n"); + + iucv_debug("entering"); if (!ansbuf) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ippathid = pathid; - parm.iptrgcls = trgcls; - parm.ipsrccls = srccls; - parm.ipmsgtag = msgtag; - parm.ipbfadr2 = (u32) ((ulong) ansbuf); - parm.ipbfln2f = (u32) anslen; - parm.ipflags1 = (IPRMDATA | flags1); /* message in prmlist */ - memcpy (parm.iprmmsg, prmmsg, sizeof (parm.iprmmsg)); + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipflags1 = (IPRMDATA | flags1); /* message in prmlist */ + memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); - b2f0_result = b2f0 (SEND, &parm); + b2f0_result = b2f0(SEND, parm); if ((b2f0_result == 0) && (msgid)) - *msgid = parm.ipmsgid; + *msgid = parm->ipmsgid; + release_param(parm); - pr_debug ("iucv_send2way_prmmsg: exiting\n"); + iucv_debug("exiting"); return b2f0_result; } @@ -1994,54 +1903,57 @@ iucv_send2way_prmmsg (u16 pathid, * that contain the reply. * Input: pathid - path identification number * trgcls - specifies target class - * srccls - specifies the source message class + * srccls - specifies the source message class * msgtag - specifies a tag to be associated with the message * flags1 - option for path * IPPRTY- specifies if you want to send priority message * prmmsg - 8-bytes of data to be placed into the parameter list - * ansbuf - address of buffer to reply with - * anslen - length of buffer to reply with + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with * Output: msgid - specifies the message ID. * Return: b2f0_result - return code from CP * (-EINVAL) - ansbuf address is NULL */ int -iucv_send2way_prmmsg_array (u16 pathid, - u32 * msgid, - u32 trgcls, - u32 srccls, - u32 msgtag, +iucv_send2way_prmmsg_array (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, int flags1, - uchar prmmsg[8], + __u8 prmmsg[8], iucv_array_t * ansbuf, ulong anslen) { - iparml_dpl parm; + iparml_dpl *parm; ulong b2f0_result; - pr_debug ("iucv_send2way_prmmsg_array: entering\n"); + iucv_debug("entering"); if (!ansbuf) return -EINVAL; - memset (&parm, 0, sizeof (parm)); - parm.ippathid = pathid; - parm.iptrgcls = trgcls; - parm.ipsrccls = srccls; - parm.ipmsgtag = msgtag; - parm.ipbfadr2 = (u32) ((ulong) ansbuf); - parm.ipbfln2f = (u32) anslen; - parm.ipflags1 = (IPRMDATA | IPANSLST | flags1); - memcpy (parm.iprmmsg, prmmsg, sizeof (parm.iprmmsg)); - b2f0_result = b2f0 (SEND, &parm); + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipflags1 = (IPRMDATA | IPANSLST | flags1); + memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); + b2f0_result = b2f0(SEND, parm); if ((b2f0_result == 0) && (msgid)) - *msgid = parm.ipmsgid; - pr_debug ("iucv_send2way_prmmsg_array: exiting\n"); + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug("exiting"); return b2f0_result; } /* * Name: iucv_setmask - * Purpose: This function enables or disables the following IUCV + * Purpose: This function enables or disables the following IUCV * external interruptions: Nonpriority and priority message * interrupts, nonpriority and priority reply interrupts. * Input: SetMaskFlag - options for interrupts @@ -2055,358 +1967,301 @@ iucv_send2way_prmmsg_array (u16 pathid, int iucv_setmask (int SetMaskFlag) { - iparml_set_mask parm; + iparml_set_mask *parm; ulong b2f0_result = 0; - pr_debug ("iucv_setmask: entering \n"); - memset (&parm, 0, sizeof (parm)); - parm.ipmask = (uchar) SetMaskFlag; + iucv_debug("entering"); + + parm = (iparml_set_mask *)grab_param(); - b2f0_result = b2f0 (SETMASK, &parm); + parm->ipmask = (__u8)SetMaskFlag; - pr_debug ("iucv_setmask: b2f0_result = %ld\n", b2f0_result); - pr_debug ("iucv_setmask: exiting\n"); + b2f0_result = b2f0(SETMASK, parm); + release_param(parm); + + iucv_debug("b2f0_result = %ld", b2f0_result); + iucv_debug("exiting"); return b2f0_result; } -/* - * Name: iucv_sever - * Purpose: This function terminates an iucv path - * Input: pathid - u16, path identification number - * user_data - uchar[16], 16-byte of user data - * Output: b2f0_result - return code from CP - * -EINVAL - NULL address found for handler +/** + * iucv_sever: + * @pathid: Path identification number + * @user_data: 16-byte of user data + * + * This function terminates an iucv path. + * Returns: return code from CP */ int -iucv_sever (u16 pathid, uchar user_data[16]) +iucv_sever(__u16 pathid, __u8 user_data[16]) { - iparml_control parm; + iparml_control *parm; ulong b2f0_result = 0; - pr_debug ("iucv_sever: entering\n"); - memset (&parm, 0, sizeof (parm)); - memcpy (parm.ipuser, user_data, sizeof (parm.ipuser)); - parm.ippathid = pathid; - b2f0_result = b2f0 (SEVER, &parm); + iucv_debug("entering"); + parm = (iparml_control *)grab_param(); - if (!b2f0_result) - iucv_remove_pathid (pathid); + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + parm->ippathid = pathid; - pr_debug ("iucv_sever: exiting \n"); - return b2f0_result; -} + b2f0_result = b2f0(SEVER, parm); -static void -iucv_remove_pathid (u16 pathid) -{ - handler_table_entry *users_hte = NULL; /*users handler_table_entry */ - handler *users_handler = NULL; - ulong *users_pathid = NULL; - ulong flags; - spin_lock_irqsave (&iucv_lock, flags); - users_hte = handler_table_anchor + (int) pathid; - - if ((users_hte->addrs) == NULL) { - spin_unlock_irqrestore (&iucv_lock, flags); - return; /* wild pointer has been found */ - } - - users_handler = users_hte->addrs; - - pr_debug ("iucv_sever: pathid is %d\n", pathid); - pr_debug ("iucv_sever: H_T_E is %p\n", users_hte); - pr_debug ("iucv_sever: address of handler is %p\n", users_handler); - pr_debug ("iucv_sever: below is pathid table\n"); - iucv_dumpit ((uchar *) users_handler->pathid_head, - (int) users_handler->entries * sizeof (ulong)); - -/* - * Searching the pathid address table for matching address, once - * found, NULL the handler_table_entry field and then zero the H_T_E fields. - */ - - for (users_pathid = (users_handler->pathid_head); - users_pathid < (users_handler->pathid_tail); users_pathid++) - - if (*users_pathid == (ulong) users_hte) { - pr_debug ("iucv_sever: found a path to remove from" - "table\n"); - pr_debug ("iucv_sever: removing %d \n", - (int) (*users_pathid)); *users_pathid = NULL; + if (!b2f0_result) + iucv_remove_pathid(pathid); + release_param(parm); - memset (users_hte, 0, sizeof (handler_table_entry)); - } - spin_unlock_irqrestore (&iucv_lock, flags); - return; + iucv_debug("exiting"); + return b2f0_result; } /* - * Interrupt Handling Functions - * top_half_interrupt - * bottom_half_interrupt - * do_int - */ + * Interrupt Handlers + *******************************************************************************/ -/* - * Name: top_half_interrupt - * Purpose: Handles interrupts coming in from CP. Places the interrupt on a queue and - * calls bottom_half_interrupt - * Input: external interrupt buffer - * Output: void +/** + * iucv_irq_handler: + * @regs: Current registers + * @code: irq code + * + * Handles external interrupts coming in from CP. + * Places the interrupt buffer on a queue and schedules iucv_bh_handler(). */ - -inline void -top_half_interrupt (struct pt_regs *regs, __u16 code) +static void +iucv_irq_handler(struct pt_regs *regs, __u16 code) { - iucv_packet *pkt; - int cpu = smp_processor_id(); + iucv_irqdata *irqdata; + int cpu = smp_processor_id(); irq_enter(cpu, 0x4000); - pkt = (iucv_packet *) kmalloc (sizeof (iucv_packet), GFP_ATOMIC); - if (pkt == NULL) { - printk (KERN_WARNING - "iucv:top_half_interrupt: out of memory\n"); + irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC); + if (!irqdata) { + printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); irq_exit(cpu, 0x4000); return; } - memcpy (pkt->data, iucv_external_int_buffer, BUFFER_SIZE); + memcpy(&irqdata->data, iucv_external_int_buffer, + sizeof(iucv_GeneralInterrupt)); - pr_debug ("TH: Got INT: %08x\n", *(int *) (pkt->data + 4)); + spin_lock(&iucv_irq_queue_lock); + list_add_tail(&irqdata->queue, &iucv_irq_queue); + spin_unlock(&iucv_irq_queue_lock); - /* put new packet on the list */ - spin_lock (&iucv_packets_lock); - pkt->next = NULL; - - if (iucv_packets_tail != NULL) - iucv_packets_tail->next = pkt; - else - iucv_packets_head = pkt; - - iucv_packets_tail = pkt; - spin_unlock (&iucv_packets_lock); - - if (atomic_compare_and_swap (0, 1, &bh_scheduled) == 0) { - short_task.routine = (void *) bottom_half_interrupt; - queue_task (&short_task, &tq_immediate); - mark_bh (IMMEDIATE_BH); + if (atomic_compare_and_swap (0, 1, &iucv_bh_scheduled) == 0) { + queue_task (&iucv_tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); } - irq_exit(cpu, 0x4000); - return; -} -/* - * Name: bottom_half_interrupt - * Purpose: Handle interrupt at a more safer time - * Input: void - * Output: void - */ -void -bottom_half_interrupt (void) -{ - iucv_packet *iucv_packet_list; - iucv_packet *tmp; - ulong flags; - atomic_set (&bh_scheduled, 0); - - spin_lock_irqsave (&iucv_packets_lock, flags); - iucv_packet_list = iucv_packets_head; - iucv_packets_head = iucv_packets_tail = NULL; - spin_unlock_irqrestore (&iucv_packets_lock, flags); - - /* now process all the request in the iucv_packet_list */ - pr_debug ("BH: Process all packets\n"); - while (iucv_packet_list != NULL) { - pr_debug ("BH:> %08x\n", - *(int *) (iucv_packet_list->data + 4)); - - do_int ((iucv_GeneralInterrupt *) iucv_packet_list->data); - - pr_debug ("BH:< %08x\n", - *(int *) (iucv_packet_list->data + 4)); - tmp = iucv_packet_list; - iucv_packet_list = iucv_packet_list->next; - kfree (tmp); - } - pr_debug ("BH: Done\n"); + irq_exit(cpu, 0x4000); return; } -/* - * Name: do_int - * Purpose: Handles the interrupts in a more safe environment - * Input: int_buf - pointer to copy of external interrupt buffer - * Output: void +/** + * iucv_do_int: + * @int_buf: Pointer to copy of external interrupt buffer + * + * The workhorse for handling interrupts queued by iucv_irq_handler(). + * This function is called from the bottom half iucv_bh_handler(). */ -void -do_int (iucv_GeneralInterrupt * int_buf) +static void +iucv_do_int(iucv_GeneralInterrupt * int_buf) { - handler_table_entry *P = 0; + handler *h = NULL; + struct list_head *lh; ulong flags; - handler *Q = 0, *R; - iucv_interrupt_ops_t *interrupt = 0; /* interrupt addresses */ - uchar temp_buff1[24], temp_buff2[24]; /* masked handler id. */ - int add_pathid_result = 0, j = 0; - uchar no_listener[16] = "NO LISTENER"; + iucv_interrupt_ops_t *interrupt = NULL; /* interrupt addresses */ + __u8 temp_buff1[24], temp_buff2[24]; /* masked handler id. */ + int rc = 0, j = 0; + __u8 no_listener[16] = "NO LISTENER"; - pr_debug ("IUCV: BHI: - Entered do_int " - "pathid %d, type %02X\n", int_buf->ippathid, int_buf->iptype); - pr_debug ("BHI:External Interrupt Buffer\n"); - iucv_dumpit ((uchar *) int_buf, sizeof (iucv_GeneralInterrupt)); + iucv_debug("entering, pathid %d, type %02X", + int_buf->ippathid, int_buf->iptype); + iucv_debug("External Interrupt Buffer:"); + iucv_dumpit(int_buf, sizeof(iucv_GeneralInterrupt)); ASCEBC (no_listener, 16); + if (int_buf->iptype != 01) { - spin_lock_irqsave (&iucv_lock, flags); - P = handler_table_anchor + int_buf->ippathid; - Q = P->addrs; - interrupt = P->ops; /* interrupt functions */ + if ((int_buf->ippathid) > (max_connections - 1)) { + printk(KERN_WARNING "%s: Got interrupt with pathid %d" + " > max_connections (%ld)\n", __FUNCTION__, + int_buf->ippathid, max_connections - 1); + } else { + h = iucv_pathid_table[int_buf->ippathid]; + interrupt = h->interrupt_table; - pr_debug ("iucv: do_int: Handler\n"); - iucv_dumpit ((uchar *) Q, sizeof (handler)); - spin_unlock_irqrestore (&iucv_lock, flags); + iucv_debug("Handler:"); + iucv_dumpit(h, sizeof(handler)); + } } + /* end of if statement */ switch (int_buf->iptype) { - case 0x01: /* connection pending */ - spin_lock_irqsave (&iucv_lock, flags); - for (R = handler_anchor; R != NULL; R = (handler *) R->next) { - memcpy (temp_buff1, &(int_buf->ipvmid), 24); - memcpy (temp_buff2, &(R->id.userid), 24); - for (j = 0; j < 24; j++) { - temp_buff1[j] = - (temp_buff1[j]) & (R->id.mask)[j]; - temp_buff2[j] = - (temp_buff2[j]) & (R->id.mask)[j]; - } - - pr_debug ("iucv:do_int: temp_buff1\n"); - iucv_dumpit (temp_buff1, sizeof (temp_buff1)); - pr_debug ("iucv:do_int: temp_buff2\n"); - iucv_dumpit (temp_buff2, sizeof (temp_buff2)); - - if (memcmp ((void *) temp_buff1, - (void *) temp_buff2, 24) == 0) { - - pr_debug - ("iucv:do_int: found a matching handler\n"); - break; + case 0x01: /* connection pending */ + spin_lock_irqsave(&iucv_lock, flags); + list_for_each(lh, &iucv_handler_table) { + h = list_entry(lh, handler, list); + memcpy(temp_buff1, &(int_buf->ipvmid), 24); + memcpy(temp_buff2, &(h->id.userid), 24); + for (j = 0; j < 24; j++) { + temp_buff1[j] &= (h->id.mask)[j]; + temp_buff2[j] &= (h->id.mask)[j]; + } + + iucv_debug("temp_buff1:"); + iucv_dumpit(temp_buff1, sizeof(temp_buff1)); + iucv_debug("temp_buff2"); + iucv_dumpit(temp_buff2, sizeof(temp_buff2)); + + if (memcmp (temp_buff1, temp_buff2, 24) == 0) { + + iucv_debug("found a matching handler"); + break; + } } - } - spin_unlock_irqrestore (&iucv_lock, flags); - - if (R) { - /* ADD PATH TO PATHID TABLE */ - add_pathid_result = iucv_add_pathid (int_buf->ippathid, - R, R->pgm_data); - if (add_pathid_result == NULL) { - interrupt = R->interrupt_table; - if (interrupt->ConnectionPending) { - - EBCASC (int_buf->ipvmid, 8); - - (interrupt->ConnectionPending) - ((iucv_ConnectionPending *) int_buf, - (R->pgm_data)); - } else { + spin_unlock_irqrestore (&iucv_lock, flags); + if (h) { + /* ADD PATH TO PATHID TABLE */ + rc = iucv_add_pathid(int_buf->ippathid, h); + if (rc) { iucv_sever (int_buf->ippathid, no_listener); + iucv_debug("add_pathid failed, rc = %d", + (int)add_pathid_result); + } else { + interrupt = h->interrupt_table; + if (interrupt->ConnectionPending) { + EBCASC (int_buf->ipvmid, 8); + interrupt->ConnectionPending( + (iucv_ConnectionPending *)int_buf, + h->pgm_data); + } else + iucv_sever(int_buf->ippathid, + no_listener); } - } /* end of if(add_p...... */ - else { - iucv_sever (int_buf->ippathid, no_listener); - pr_debug ("iucv:do_int:add_pathid failed" - "with rc = %d\n", - (int) add_pathid_result); + } else + iucv_sever(int_buf->ippathid, no_listener); + break; + + case 0x02: /*connection complete */ + if (h) { + if (interrupt->ConnectionComplete) + interrupt->ConnectionComplete( + (iucv_ConnectionComplete *)int_buf, + h->pgm_data); + else + iucv_debug("ConnectionComplete not called"); } - } else - iucv_sever (int_buf->ippathid, no_listener); - break; - - case 0x02: /*connection complete */ - if (Q) { - if (interrupt->ConnectionComplete) - (interrupt->ConnectionComplete) - ((iucv_ConnectionComplete *) int_buf, (P->pgm_data)); - else - pr_debug ("iucv:do_int:" - "ConnectionComplete not called\n"); - } - - break; - - case 0x03: /* connection severed */ - if (Q) { - if (interrupt->ConnectionSevered) - (interrupt->ConnectionSevered) - ((iucv_ConnectionSevered *) int_buf, - (P->pgm_data)); - - else - iucv_sever (int_buf->ippathid, no_listener); - } else - iucv_sever (int_buf->ippathid, no_listener); - break; - - case 0x04: /* connection quiesced */ - if (Q) { - if (interrupt->ConnectionQuiesced) - (interrupt->ConnectionQuiesced) - ((iucv_ConnectionQuiesced *) int_buf, - (P->pgm_data)); - else - pr_debug ("iucv:do_int:" - "ConnectionQuiesced not called\n"); - } - break; - - case 0x05: /* connection resumed */ - if (Q) { - if (interrupt->ConnectionResumed) - (interrupt->ConnectionResumed) - ((iucv_ConnectionResumed *) int_buf, (P->pgm_data)); - else - pr_debug ("iucv:do_int:" - "ConnectionResumed not called\n"); - } - break; - - case 0x06: /* priority message complete */ - case 0x07: /* nonpriority message complete */ - if (Q) { - if (interrupt->MessageComplete) - (interrupt->MessageComplete) - ((iucv_MessageComplete *) int_buf, (P->pgm_data)); - else - pr_debug ("iucv:do_int:" - "MessageComplete not called\n"); - } - break; - - case 0x08: /* priority message pending */ - case 0x09: /* nonpriority message pending */ - if (Q) { - if (interrupt->MessagePending) - (interrupt->MessagePending) - ((iucv_MessagePending *) int_buf, (P->pgm_data)); - else - pr_debug ("iucv:do_int:" - "MessagePending not called\n"); - } - break; - default: /* unknown iucv type */ - printk (KERN_WARNING "iucv:do_int: unknown iucv interrupt \n"); - break; + + break; + + case 0x03: /* connection severed */ + if (h) { + if (interrupt->ConnectionSevered) + interrupt->ConnectionSevered( + (iucv_ConnectionSevered *)int_buf, + h->pgm_data); + + else + iucv_sever (int_buf->ippathid, no_listener); + } else + iucv_sever(int_buf->ippathid, no_listener); + break; + + case 0x04: /* connection quiesced */ + if (h) { + if (interrupt->ConnectionQuiesced) + interrupt->ConnectionQuiesced( + (iucv_ConnectionQuiesced *)int_buf, + h->pgm_data); + else + iucv_debug("ConnectionQuiesced not called"); + } + break; + + case 0x05: /* connection resumed */ + if (h) { + if (interrupt->ConnectionResumed) + interrupt->ConnectionResumed( + (iucv_ConnectionResumed *)int_buf, + h->pgm_data); + else + iucv_debug("ConnectionResumed not called"); + } + break; + + case 0x06: /* priority message complete */ + case 0x07: /* nonpriority message complete */ + if (h) { + if (interrupt->MessageComplete) + interrupt->MessageComplete( + (iucv_MessageComplete *)int_buf, + h->pgm_data); + else + iucv_debug("MessageComplete not called"); + } + break; + + case 0x08: /* priority message pending */ + case 0x09: /* nonpriority message pending */ + if (h) { + if (interrupt->MessagePending) + interrupt->MessagePending( + (iucv_MessagePending *) int_buf, + h->pgm_data); + else + iucv_debug("MessagePending not called"); + } + break; + default: /* unknown iucv type */ + printk(KERN_WARNING "%s: unknown iucv interrupt\n", + __FUNCTION__); + break; } /* end switch */ + + iucv_debug("exiting pathid %d, type %02X", + int_buf->ippathid, int_buf->iptype); - pr_debug ("BH:- Exiting do_int " - "pathid %d, type %02X\n", int_buf->ippathid, int_buf->iptype); + return; +} + +/** + * iucv_bh_handler: + * + * This function loops over the queue of irq buffers and runs iucv_do_int() + * on every queue element. + */ +static void +iucv_bh_handler(void) +{ + struct list_head head; + struct list_head *next; + ulong flags; + + atomic_set(&iucv_bh_scheduled, 0); + + spin_lock_irqsave(&iucv_irq_queue_lock, flags); + list_add(&head, &iucv_irq_queue); + list_del_init(&iucv_irq_queue); + spin_unlock_irqrestore (&iucv_irq_queue_lock, flags); + + next = head.next; + while (next != &head) { + iucv_irqdata *p = list_entry(next, iucv_irqdata, queue); + + next = next->next; + iucv_do_int(&p->data); + kfree(p); + } return; } -/* end of function call */ +/** + * Export all public stuff + */ EXPORT_SYMBOL (iucv_accept); EXPORT_SYMBOL (iucv_connect); EXPORT_SYMBOL (iucv_purge); diff --git a/drivers/s390/net/iucv.h b/drivers/s390/net/iucv.h index 5ab30c4ad630..acdf3af3b772 100644 --- a/drivers/s390/net/iucv.h +++ b/drivers/s390/net/iucv.h @@ -8,8 +8,6 @@ * Xenia Tkatschow (xenia@us.ibm.com) * * - * Linux Kernel IUCV will not support a machine with storage > 2 GB. - * * Functionality: * To explore any of the IUCV functions, one must first register * their program using iucv_register_program(). Once your program has @@ -314,7 +312,7 @@ int * of this message. * Return: Return code from CP IUCV call. */ -int iucv_purge (u16 pathid, u32 msgid, u32 srccls, uchar audit[3]); +int iucv_purge (u16 pathid, u32 msgid, u32 srccls, __u32 *audit); /* * Name: iucv_query_maxconn * Purpose: This function determines the maximum number of communication paths you diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 7ea2bf79f691..f93e6813cfe7 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -1,974 +1,2121 @@ /* - * drivers/s390/net/netiucv.c - * Network driver for VM using iucv + * $Id: netiucv.c,v 1.11 2001/07/16 17:00:02 felfert Exp $ * - * S/390 version - * Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Stefan Hegewald <hegewald@de.ibm.com> - * Hartmut Penner <hpenner@de.ibm.com> + * IUCV network driver * + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) * - * 2.3 Updates Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) - * Martin Schwidefsky (schwidefsky@de.ibm.com) + * Documentation used: + * the source of the original IUCV driver by: + * Stefan Hegewald <hegewald@de.ibm.com> + * Hartmut Penner <hpenner@de.ibm.com> + * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) + * Martin Schwidefsky (schwidefsky@de.ibm.com) + * Alan Altmark (Alan_Altmark@us.ibm.com) Sept. 2000 * - * Re-write: Alan Altmark (Alan_Altmark@us.ibm.com) Sept. 2000 - * Uses iucv.c kernel module for IUCV services. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. * - * 2.4 Updates Alan Altmark (Alan_Altmark@us.ibm.com) June 2001 - * Update to use changed IUCV (iucv.c) interface. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * -------------------------------------------------------------------------- - * An IUCV frame consists of one or more packets preceded by a 16-bit - * header. The header contains the offset to the next packet header, - * measured from the beginning of the _frame_. If zero, there are no more - * packets in the frame. Consider a frame which contains a 10-byte packet - * followed by a 20-byte packet: - * +-----+----------------+--------------------------------+-----+ - * |h'12'| 10-byte packet |h'34'| 20-byte packet |h'00'| - * +-----+----------------+-----+--------------------------+-----+ - * Offset: 0 2 12 14 34 + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * This means that each header will always have a larger value than the - * previous one (except for the final zero header, of course). - * - * For outbound packets, we send ONE frame per packet. So, our frame is: - * AL2(packet length+2), packet, AL2(0) - * The maximum packet size is the MTU, so the maximum IUCV frame we send - * is MTU+4 bytes. + * RELEASE-TAG: IUCV network driver $Revision: 1.11 $ * - * For inbound frames, we don't care how long the frame is. We tear apart - * the frame, processing packets up to MTU size in length, until no more - * packets remain in the frame. - * - * -------------------------------------------------------------------------- - * The code uses the 2.3.43 network driver interfaces. If compiled on an - * an older level of the kernel, the module provides its own macros. - * Doc is in Linux Weekly News (lwn.net) memo from David Miller, 9 Feb 2000. - * There are a few other places with 2.3-specific enhancements. - * - * -------------------------------------------------------------------------- -*/ -//#define DEBUG 1 -//#define DEBUG2 1 -//#define IPDEBUG 1 -#define LEVEL "1.1" - -/* If MAX_DEVICES increased, add initialization data to iucv_netdev[] array */ -/* (See bottom of program.) */ -#define MAX_DEVICES 20 /* Allows "iucv0" to "iucv19" */ -#define MAX_VM_MTU 32764 /* 32K IUCV buffer, minus 4 */ -#define MAX_TX_Q 50 /* Maximum pending TX */ - + */ + #include <linux/version.h> +#include <linux/module.h> +#include <linux/init.h> #include <linux/kernel.h> +#include <linux/malloc.h> +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/timer.h> +#include <linux/sched.h> + +#include <linux/signal.h> +#include <linux/string.h> +#include <linux/proc_fs.h> + +#include <linux/ip.h> +#include <linux/if_arp.h> +#include <linux/tcp.h> +#include <linux/skbuff.h> +#include <linux/ctype.h> +#include <net/dst.h> + +#include <asm/io.h> +#include <asm/bitops.h> +#include <asm/uaccess.h> + +#include "iucv.h" +#include "fsm.h" + +#undef DEBUG #ifdef MODULE -#include <linux/module.h> MODULE_AUTHOR - ("(C) 2000 IBM Corporation by Alan Altmark (Alan_Altmark@us.ibm.com)"); -MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver " LEVEL); -MODULE_PARM (iucv, "1-" __MODULE_STRING (MAX_DEVICES) "s"); + ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)"); +MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); +MODULE_PARM (iucv, "1s"); MODULE_PARM_DESC (iucv, - "Specify the userids associated with iucv0-iucv9:\n" - "iucv=userid1,userid2,...,userid10\n"); -#ifdef MODVERSIONS -#include <linux/modversions.h> + "Specify the initial remote userids for iucv0 .. iucvn:\n" + "iucv=userid0:userid1:...:useridN\n"); #endif -#else -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif - -#include <linux/sched.h> /* task queues */ -#include <linux/malloc.h> /* kmalloc() */ -#include <linux/errno.h> /* error codes */ -#include <linux/types.h> /* size_t */ -#include <linux/interrupt.h> /* mark_bh */ -#include <linux/netdevice.h> /* struct net_device, etc. */ -#include <linux/if_arp.h> /* ARPHRD_SLIP */ -#include <linux/ip.h> /* IP header */ -#include <linux/skbuff.h> /* skb */ -#include <linux/init.h> /* __setup() */ -#include <asm/string.h> /* memset, memcpy, etc. */ -#include "iucv.h" -#if defined( DEBUG ) -#undef KERN_INFO -#undef KERN_DEBUG -#undef KERN_NOTICE -#undef KERN_ERR -#define KERN_INFO KERN_EMERG -#define KERN_DEBUG KERN_EMERG -#define KERN_NOTICE KERN_EMERG -#define KERN_ERR KERN_EMERG -#endif +static char *iucv = ""; +/** + * compatibility stuff + */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) typedef struct net_device net_device; #else typedef struct device net_device; #endif -static __inline__ int -netif_is_busy (net_device * dev) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,45)) - return (dev->tbusy); -#else - return (test_bit (__LINK_STATE_XOFF, &dev->flags)); + +/** + * Per connection profiling data + */ +typedef struct connection_profile_t { + unsigned long maxmulti; + unsigned long maxcqueue; + unsigned long doios_single; + unsigned long doios_multi; + unsigned long txlen; + unsigned long tx_time; + struct timeval send_stamp; +} connection_profile; + +/** + * Representation of one iucv connection + */ +typedef struct iucv_connection_t { + struct iucv_connection_t *next; + iucv_handle_t handle; + __u16 pathid; + struct sk_buff *rx_buff; + struct sk_buff *tx_buff; + struct sk_buff_head collect_queue; + spinlock_t collect_lock; + int collect_len; + int max_buffsize; + int flags; + fsm_timer timer; + int retry; + fsm_instance *fsm; + net_device *netdev; + connection_profile prof; + char userid[9]; +} iucv_connection; + +#define CONN_FLAGS_BUFSIZE_CHANGED 1 + +/** + * Linked list of all connection structs. + */ +iucv_connection *connections; + +/** + * Representation of event-data for the + * connection state machine. + */ +typedef struct iucv_event_t { + iucv_connection *conn; + void *data; +} iucv_event; + +/** + * Private part of the network device structure + */ +typedef struct netiucv_priv_t { + struct net_device_stats stats; +#if LINUX_VERSION_CODE >= 0x02032D + unsigned long tbusy; #endif + fsm_instance *fsm; + iucv_connection *conn; + struct proc_dir_entry *proc_dentry; + struct proc_dir_entry *proc_stat_entry; + struct proc_dir_entry *proc_buffer_entry; + struct proc_dir_entry *proc_user_entry; + int proc_registered; +} netiucv_priv; + +/** + * Link level header for a packet. + */ +typedef struct ll_header_t { + __u16 next; +} ll_header; + +#define NETIUCV_HDRLEN (sizeof(ll_header)) +#define NETIUCV_BUFSIZE_MAX 32768 +#define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX +#define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN) +#define NETIUCV_MTU_DEFAULT 9216 +#define NETIUCV_QUEUELEN_DEFAULT 50 +#define NETIUCV_TIMEOUT_5SEC 5000 + +/** + * Compatibility macros for busy handling + * of network devices. + */ +#if LINUX_VERSION_CODE < 0x02032D +static __inline__ void netiucv_clear_busy(net_device *dev) +{ + clear_bit(0 ,(void *)&dev->tbusy); + mark_bh(NET_BH); } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,45)) - /* Provide our own 2.3.45 interfaces */ -#define netif_enter_interrupt(dev) dev->interrupt=1 -#define netif_exit_interrupt(dev) dev->interrupt=0 -#define netif_start(dev) dev->start=1 -#define netif_stop(dev) dev->start=0 - -static __inline__ void -netif_stop_queue (net_device * dev) +static __inline__ int netiucv_test_and_set_busy(net_device *dev) { - dev->tbusy = 1; + return(test_and_set_bit(0, (void *)&dev->tbusy)); } -static __inline__ void -netif_start_queue (net_device * dev) +#define SET_DEVICE_START(device, value) dev->start = value +#else +static __inline__ void netiucv_clear_busy(net_device *dev) { - dev->tbusy = 0; + clear_bit(0, &(((netiucv_priv *)dev->priv)->tbusy)); + netif_start_queue(dev); } -static __inline__ void -netif_wake_queue (net_device * dev) +static __inline__ int netiucv_test_and_set_busy(net_device *dev) { - dev->tbusy = 0; - mark_bh (NET_BH); + netif_stop_queue(dev); + return test_and_set_bit(0, &((netiucv_priv *)dev->priv)->tbusy); } -#else - /* As of 2.3.45, we don't do these things anymore */ -#define netif_enter_interrupt(dev) -#define netif_exit_interrupt(dev) -#define netif_start(dev) -#define netif_stop(dev) +#define SET_DEVICE_START(device, value) #endif -static int iucv_start (net_device *); -static int iucv_stop (net_device *); -static int iucv_change_mtu (net_device *, int); -static int iucv_init (net_device *); -static void iucv_rx (net_device *, u32, uchar *, int); -static int iucv_tx (struct sk_buff *, net_device *); +#if LINUX_VERSION_CODE < 0x020400 +# define dev_kfree_skb_irq(a) dev_kfree_skb(a) +#endif -static void connection_severed (iucv_ConnectionSevered *, void *); -static void connection_pending (iucv_ConnectionPending *, void *); -static void connection_complete (iucv_ConnectionComplete *, void *); -static void message_pending (iucv_MessagePending *, void *); -static void send_complete (iucv_MessageComplete *, void *); +__u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +__u8 iucvMagic[16] = { + 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 +}; -void register_iucv_dev (int, char *); +/** + * This mask means the 16-byte IUCV "magic" and the origin userid must + * match exactly as specified in order to give connection_pending() + * control. + */ +__u8 mask[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; -static iucv_interrupt_ops_t netiucv_ops = { - &connection_pending, - &connection_complete, - &connection_severed, - NULL, /* Quiesced */ - NULL, /* Resumed */ - &message_pending, /* Message pending */ - &send_complete /* Message complete */ +/** + * Convert an iucv userId to its printable + * form (strip whitespace at end). + * + * @param An iucv userId + * + * @returns The printable string (static data!!) + */ +static __inline__ char * +netiucv_printname(char *name) +{ + static char tmp[9]; + char *p = tmp; + memcpy(tmp, name, 8); + tmp[8] = '\0'; + while (*p && (!isspace(*p))) + p++; + *p = '\0'; + return tmp; +} + +/** + * States of the interface statemachine. + */ +enum dev_states { + DEV_STATE_STOPPED, + DEV_STATE_STARTWAIT, + DEV_STATE_STOPWAIT, + DEV_STATE_RUNNING, + /** + * MUST be always the last element!! + */ + NR_DEV_STATES }; -static char iucv_userid[MAX_DEVICES][8]; -net_device iucv_netdev[MAX_DEVICES]; +static const char *dev_state_names[] = { + "Stopped", + "StartWait", + "StopWait", + "Running", +}; -/* This structure is private to each device. It contains the */ -/* information necessary to do IUCV operations. */ -struct iucv_priv { - struct net_device_stats stats; - net_device *dev; - iucv_handle_t handle; - uchar userid[9]; /* Printable userid */ - uchar userid2[8]; /* Used for IUCV operations */ - - /* Note: atomic_compare_and_swap() return value is backwards */ - /* from what you might think: FALSE=0=OK, TRUE=1=FAIL */ - atomic_t state; -#define FREE 0 -#define CONNECTING 1 -#define CONNECTED 2 - u16 pathid; +/** + * Events of the interface statemachine. + */ +enum dev_events { + DEV_EVENT_START, + DEV_EVENT_STOP, + DEV_EVENT_CONUP, + DEV_EVENT_CONDOWN, + /** + * MUST be always the last element!! + */ + NR_DEV_EVENTS }; -uchar iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -uchar iucvMagic[16] = { 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 +static const char *dev_event_names[] = { + "Start", + "Stop", + "Connection up", + "Connection down", +}; + +/** + * Events of the connection statemachine + */ +enum conn_events { + /** + * Events, representing callbacks from + * lowlevel iucv layer) + */ + CONN_EVENT_CONN_REQ, + CONN_EVENT_CONN_ACK, + CONN_EVENT_CONN_REJ, + CONN_EVENT_CONN_SUS, + CONN_EVENT_CONN_RES, + CONN_EVENT_RX, + CONN_EVENT_TXDONE, + + /** + * Events, representing errors return codes from + * calls to lowlevel iucv layer + */ + + /** + * Event, representing timer expiry. + */ + CONN_EVENT_TIMER, + + /** + * Events, representing commands from upper levels. + */ + CONN_EVENT_START, + CONN_EVENT_STOP, + + /** + * MUST be always the last element!! + */ + NR_CONN_EVENTS, }; -/* This mask means the 16-byte IUCV "magic" and the origin userid must */ -/* match exactly as specified in order to give connection_pending() */ -/* control. */ -const char mask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +static const char *conn_event_names[] = { + "Remote connection request", + "Remote connection acknowledge", + "Remote connection reject", + "Connection suspended", + "Connection resumed", + "Data received", + "Data sent", + + "Timer", + + "Start", + "Stop", }; -#if defined( DEBUG2 ) || defined( IPDEBUG ) -/*--------------------------*/ -/* Dump buffer formatted */ -/*--------------------------*/ -static void -dumpit (char *buf, int len) -{ - int i; - printk (KERN_DEBUG); - for (i = 0; i < len; i++) { - if (!(i % 32) && i != 0) - printk ("\n"); - else if (!(i % 4) && i != 0) - printk (" "); - printk ("%02X", buf[i]); - } - if (len % 32) - printk ("\n"); -} -#endif - -/*-----------------------------------------------------------------*/ -/* Open a connection to another Linux or VM TCP/IP stack. */ -/* Called by kernel. */ -/* */ -/* 1. Register a handler. (Up to now, any attempt by another stack */ -/* has been rejected by the IUCV handler.) We give the handler */ -/* the net_device* so that we can locate the dev associated */ -/* with the partner userid if he tries to connect to us or */ -/* if the connection is broken. */ -/* */ -/* 2. Connect to remote stack. If we get a connection pending */ -/* interrupt while we're in the middle of connecting, don't */ -/* worry. VM will sever its and use ours, because the DEVICE */ -/* is defined to be: */ -/* DEVICE devname IUCV 0 0 linuxvm A */ -/* or DEVICE devname IUCV 0 0 linuxvm B */ -/* In EBCDIC, "0" (0xF0) is greater than "A" (0xC1) or "B", so */ -/* win all races. We will sever any connects that occur while */ -/* we are connecting. The "0 0" is where we get iucvMagic from.*/ -/* */ -/* FIXME: If two Linux machines get into this race condition, */ -/* both will sever. Manual intervention required. */ -/* Need a better IUCV "hello"-like function that permits */ -/* some negotiation. But can't do that until VM TCP/IP */ -/* would support it. */ -/* */ -/* 3. Return 0 to indicate device ok. Anything else is an error. */ -/*-----------------------------------------------------------------*/ -static int -iucv_start (net_device * dev) +/** + * States of the connection statemachine. + */ +enum conn_states { + /** + * Connection not assigned to any device, + * initial state, invalid + */ + CONN_STATE_INVALID, + + /** + * Userid assigned but not operating + */ + CONN_STATE_STOPPED, + + /** + * Connection registered, + * no connection request sent yet, + * no connection request received + */ + CONN_STATE_STARTWAIT, + + /** + * Connection registered and connection request sent, + * no acknowledge and no connection request received yet. + */ + CONN_STATE_SETUPWAIT, + + /** + * Connection up and running idle + */ + CONN_STATE_IDLE, + + /** + * Data sent, awaiting CONN_EVENT_TXDONE + */ + CONN_STATE_TX, + + /** + * Terminating + */ + CONN_STATE_TERM, + + /** + * Error during registration. + */ + CONN_STATE_REGERR, + + /** + * Error during registration. + */ + CONN_STATE_CONNERR, + + /** + * MUST be always the last element!! + */ + NR_CONN_STATES, +}; + +static const char *conn_state_names[] = { + "Invalid", + "Stopped", + "StartWait", + "SetupWait", + "Idle", + "TX", + "Terminating", + "Registration error", + "Connect error", +}; + + +/** + * Callback-wrappers, called from lowlevel iucv layer. + *****************************************************************************/ + +static void +netiucv_callback_rx(iucv_MessagePending *eib, void *pgm_data) { - int rc, i; - struct iucv_priv *p = (struct iucv_priv *) dev->priv; + iucv_connection *conn = (iucv_connection *)pgm_data; + iucv_event ev; - pr_debug ("iucv_start(%s)\n", dev->name); + ev.conn = conn; + ev.data = (void *)eib; - if (p == NULL) { - /* Allocate priv data */ - p = (struct iucv_priv *) kmalloc (sizeof (struct iucv_priv), - GFP_ATOMIC); - if (p == NULL) { - printk (KERN_CRIT "%s: no memory for dev->priv.\n", - dev->name); - return -ENOMEM; - } - memset (p, 0, sizeof (struct iucv_priv)); - dev->priv = p; - p->dev = dev; + fsm_event(conn->fsm, CONN_EVENT_RX, &ev); +} + +static void +netiucv_callback_txdone(iucv_MessageComplete *eib, void *pgm_data) +{ + iucv_connection *conn = (iucv_connection *)pgm_data; + iucv_event ev; - memcpy (p->userid, iucv_userid[dev - iucv_netdev], 8); /* Save userid */ - memcpy (p->userid2, p->userid, 8); /* Again, with feeling. */ + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev); +} - for (i = 0; i < 8; i++) { /* Change userid to printable form */ - if (p->userid[i] == ' ') { - p->userid[i] = '\0'; - break; - } +static void +netiucv_callback_connack(iucv_ConnectionComplete *eib, void *pgm_data) +{ + iucv_connection *conn = (iucv_connection *)pgm_data; + iucv_event ev; + + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, &ev); +} + +static void +netiucv_callback_connreq(iucv_ConnectionPending *eib, void *pgm_data) +{ + iucv_connection *conn = (iucv_connection *)pgm_data; + iucv_event ev; + + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev); +} + +static void +netiucv_callback_connrej(iucv_ConnectionSevered *eib, void *pgm_data) +{ + iucv_connection *conn = (iucv_connection *)pgm_data; + iucv_event ev; + + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, &ev); +} + +static void +netiucv_callback_connsusp(iucv_ConnectionQuiesced *eib, void *pgm_data) +{ + iucv_connection *conn = (iucv_connection *)pgm_data; + iucv_event ev; + + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, &ev); +} + +static void +netiucv_callback_connres(iucv_ConnectionResumed *eib, void *pgm_data) +{ + iucv_connection *conn = (iucv_connection *)pgm_data; + iucv_event ev; + + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_RES, &ev); +} + +static iucv_interrupt_ops_t netiucv_ops = { + ConnectionPending: netiucv_callback_connreq, + ConnectionComplete: netiucv_callback_connack, + ConnectionSevered: netiucv_callback_connrej, + ConnectionQuiesced: netiucv_callback_connsusp, + ConnectionResumed: netiucv_callback_connres, + MessagePending: netiucv_callback_rx, + MessageComplete: netiucv_callback_txdone +}; + +/** + * Dummy NOP action for all statemachines + */ +static void +fsm_action_nop(fsm_instance *fi, int event, void *arg) +{ +} + +/** + * Actions of the connection statemachine + *****************************************************************************/ + +/** + * Helper function for conn_action_rx() + * Unpack a just received skb and hand it over to + * upper layers. + * + * @param conn The connection where this skb has been received. + * @param pskb The received skb. + */ +//static __inline__ void +static void +netiucv_unpack_skb(iucv_connection *conn, struct sk_buff *pskb) +{ + net_device *dev = conn->netdev; + netiucv_priv *privptr = (netiucv_priv *)dev->priv; + __u16 offset = 0; + + skb_put(pskb, NETIUCV_HDRLEN); + pskb->dev = dev; + pskb->ip_summed = CHECKSUM_NONE; + pskb->protocol = ntohs(ETH_P_IP); + + while (1) { + struct sk_buff *skb; + ll_header *header = (ll_header *)pskb->data; + + if (header->next == 0) + break; + + skb_pull(pskb, NETIUCV_HDRLEN); + header->next -= offset; + offset += header->next; + header->next -= NETIUCV_HDRLEN; + if (skb_tailroom(pskb) < header->next) { + printk(KERN_WARNING + "%s: Ilegal next field in iucv header: %d > %d\n", + dev->name, header->next, skb_tailroom(pskb)); + return; } - p->userid[8] = '\0'; - atomic_set (&p->state, FREE); - p->handle = - iucv_register_program (iucvMagic, p->userid2, (char *) mask, - &netiucv_ops, (void *) dev); - if (p->handle <= 0) { - printk (KERN_ERR - "%s: iucv_register_program error, rc=%p\n", - dev->name, p->handle); - dev->priv = NULL; - kfree (p); - return -ENODEV; + skb_put(pskb, header->next); + pskb->mac.raw = pskb->data; + skb = dev_alloc_skb(pskb->len); + if (!skb) { + printk(KERN_WARNING + "%s Out of memory in netiucv_unpack_skb\n", + dev->name); + privptr->stats.rx_dropped++; + return; } - pr_debug ("state@ = %p\n", &p->state); - MOD_INC_USE_COUNT; - } - - if (atomic_compare_and_swap (FREE, CONNECTING, &p->state) != 0) { - pr_debug ("Other side connecting during start\n"); - return 0; + memcpy(skb_put(skb, pskb->len), pskb->data, pskb->len); + skb->mac.raw = skb->data; + skb->dev = pskb->dev; + skb->protocol = pskb->protocol; + pskb->ip_summed = CHECKSUM_UNNECESSARY; + netif_rx(skb); + privptr->stats.rx_packets++; + privptr->stats.rx_bytes += skb->len; + skb_pull(pskb, header->next); + skb_put(pskb, NETIUCV_HDRLEN); } +} - rc = - iucv_connect (&(p->pathid), MAX_TX_Q, iucvMagic, p->userid2, - iucv_host, 0, NULL, NULL, p->handle, p); +static void +conn_action_rx(fsm_instance *fi, int event, void *arg) +{ + iucv_event *ev = (iucv_event *)arg; + iucv_connection *conn = ev->conn; + iucv_MessagePending *eib = (iucv_MessagePending *)ev->data; + netiucv_priv *privptr = (netiucv_priv *)conn->netdev->priv; - /* Some errors are not fatal. In these cases we will report "OK". */ - switch (rc) { - case 0: /* Wait for connection to complete */ - pr_debug ("...waiting for connection to complete..."); - return 0; - case 11: /* Wait for parter to connect */ - printk (KERN_NOTICE "%s: " - "User %s is not available now.\n", - dev->name, p->userid); - atomic_set (&p->state, FREE); - return 0; - case 12: /* Wait for partner to connect */ - printk (KERN_NOTICE "%s: " - "User %s is not ready to talk now.\n", - dev->name, p->userid); - atomic_set (&p->state, FREE); - return 0; - case 13: /* Fatal */ - printk (KERN_ERR "%s: " - "You have too many IUCV connections." - "Check MAXCONN in CP directory.\n", dev->name); - break; - case 14: /* Fatal */ - printk (KERN_ERR "%s: " - "User %s has too many IUCV connections." - "Check MAXCONN in CP directory.\n", - dev->name, p->userid); - break; - case 15: /* Fatal */ - printk (KERN_ERR "%s: " - "No IUCV authorization found in CP directory.\n", - dev->name); - break; - default: /* Really fatal! Should not occur!! */ - printk (KERN_ERR "%s: " - "return code %i from iucv_connect()\n", dev->name, rc); - } - - rc = iucv_unregister_program (p->handle); - dev->priv = NULL; - kfree (p); - MOD_DEC_USE_COUNT; - return -ENODEV; -} /* end iucv_start() */ - -/*********************************************************************/ -/* Our connection TO another stack has been accepted. */ -/*********************************************************************/ -static void -connection_complete (iucv_ConnectionComplete * cci, void *pgm_data) -{ - struct iucv_priv *p = (struct iucv_priv *) pgm_data; - pr_debug ("...%s connection complete... txq=%u\n", - p->dev->name, cci->ipmsglim); - atomic_set (&p->state, CONNECTED); - p->pathid = cci->ippathid; - p->dev->tx_queue_len = cci->ipmsglim; - netif_start (p->dev); - netif_start_queue (p->dev); - printk (KERN_NOTICE "%s: Connection to user %s is up\n", - p->dev->name, p->userid); -} /* end connection_complete() */ - -/*********************************************************************/ -/* A connection FROM another stack is pending. If we are in the */ -/* middle of connecting, sever the new connection. */ -/* */ -/* We only get here if we've done an iucv_register(), so we know */ -/* the remote user is the correct user. */ -/*********************************************************************/ -static void -connection_pending (iucv_ConnectionPending * cpi, void *pgm_data) -{ - /* Only get this far if handler is set up, so we know userid is ok. */ - /* and the device is started. */ - /* pgm_data is different for this one. We get dev*, not priv*. */ - net_device *dev = (net_device *) pgm_data; - struct iucv_priv *p = (struct iucv_priv *) dev->priv; + __u16 msglen = eib->ln1msg2.ipbfln1f; int rc; - u16 msglimit; - uchar udata[16]; - /* If we're not waiting on a connect, reject the connection */ - if (atomic_compare_and_swap (FREE, CONNECTING, &p->state) != 0) { - iucv_sever (cpi->ippathid, udata); +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + if (!conn->netdev) { + /* FRITZ: How to tell iucv LL to drop the msg? */ + printk(KERN_WARNING + "Received data for unlinked connection\n"); + return; + } + if (msglen > conn->max_buffsize) { + /* FRITZ: How to tell iucv LL to drop the msg? */ + privptr->stats.rx_dropped++; return; } + conn->rx_buff->data = conn->rx_buff->tail = conn->rx_buff->head; + conn->rx_buff->len = 0; + rc = iucv_receive(conn->pathid, eib->ipmsgid, eib->iptrgcls, + conn->rx_buff->data, msglen, NULL, NULL, NULL); + if (rc != 0 || msglen < 5) { + privptr->stats.rx_errors++; + return; + } + netiucv_unpack_skb(conn, conn->rx_buff); +} - rc = iucv_accept (cpi->ippathid, /* Path id */ - MAX_TX_Q, /* desired IUCV msg limit */ - udata, /* user_Data */ - 0, /* No flags */ - p->handle, /* registration handle */ - p, /* private data */ - NULL, /* don't care about output flags */ - &msglimit); /* Actual IUCV msg limit */ - if (rc != 0) { - atomic_set (&p->state, FREE); - printk (KERN_ERR "%s: iucv accept failed rc=%i\n", - p->dev->name, rc); +static void +conn_action_txdone(fsm_instance *fi, int event, void *arg) +{ + iucv_event *ev = (iucv_event *)arg; + iucv_connection *conn = ev->conn; + iucv_MessageComplete *eib = (iucv_MessageComplete *)ev->data; + netiucv_priv *privptr = NULL; + struct sk_buff *skb = (struct sk_buff *)eib->ipmsgtag; + __u32 txbytes = 0; + __u32 txpackets = 0; + __u32 stat_maxcq = 0; + unsigned long saveflags; + ll_header header; + +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + fsm_deltimer(&conn->timer); + if (conn && conn->netdev && conn->netdev->priv) + privptr = (netiucv_priv *)conn->netdev->priv; + if (skb) { + if (privptr) { + privptr->stats.tx_packets++; + privptr->stats.tx_bytes += + (skb->len - NETIUCV_HDRLEN - NETIUCV_HDRLEN); + } + dev_kfree_skb_any(skb); } else { - atomic_set (&p->state, CONNECTED); - p->pathid = cpi->ippathid; - p->dev->tx_queue_len = (u32) msglimit; - netif_start (p->dev); - netif_start_queue (p->dev); - printk (KERN_NOTICE "%s: Connection to user %s is up\n", - p->dev->name, p->userid); + conn->tx_buff->data = conn->tx_buff->tail = conn->tx_buff->head; + conn->tx_buff->len = 0; + } + spin_lock_irqsave(&conn->collect_lock, saveflags); + while ((skb = skb_dequeue(&conn->collect_queue))) { + header.next = conn->tx_buff->len + skb->len + NETIUCV_HDRLEN; + memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, + NETIUCV_HDRLEN); + memcpy(skb_put(conn->tx_buff, skb->len), skb->data, skb->len); + txbytes += skb->len; + txpackets++; + stat_maxcq++; + atomic_dec(&skb->users); + dev_kfree_skb_any(skb); } -} /* end connection_pending() */ + if (conn->collect_len > conn->prof.maxmulti) + conn->prof.maxmulti = conn->collect_len; + conn->collect_len = 0; + spin_unlock_irqrestore(&conn->collect_lock, saveflags); + if (conn->tx_buff->len) { + int rc; + + header.next = 0; + memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, + NETIUCV_HDRLEN); + + fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, + CONN_EVENT_TIMER, conn); + conn->prof.send_stamp = xtime; + rc = iucv_send(conn->pathid, NULL, 0, 0, 0, 0, + conn->tx_buff->data, conn->tx_buff->len); + conn->prof.doios_multi++; + conn->prof.txlen += conn->tx_buff->len; + if (rc != 0) { + fsm_deltimer(&conn->timer); + fsm_newstate(fi, CONN_STATE_IDLE); + if (privptr) + privptr->stats.tx_errors += txpackets; + } else { + if (privptr) { + privptr->stats.tx_packets += txpackets; + privptr->stats.tx_bytes += txbytes; + } + if (stat_maxcq > conn->prof.maxcqueue) + conn->prof.maxcqueue = stat_maxcq; + } + } else + fsm_newstate(fi, CONN_STATE_IDLE); +} -/*********************************************************************/ -/* Our connection to another stack has been severed. */ -/*********************************************************************/ static void -connection_severed (iucv_ConnectionSevered * eib, void *pgm_data) +conn_action_connaccept(fsm_instance *fi, int event, void *arg) { - struct iucv_priv *p = (struct iucv_priv *) pgm_data; - - printk (KERN_INFO "%s: Connection to user %s is down\n", - p->dev->name, p->userid); + iucv_event *ev = (iucv_event *)arg; + iucv_connection *conn = ev->conn; + iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data; + net_device *netdev = conn->netdev; + netiucv_priv *privptr = (netiucv_priv *)netdev->priv; + int rc; + __u16 msglimit; + __u8 udata[16]; - /* FIXME: We can also get a severed interrupt while in - state CONNECTING! Fix the state machine ... */ -#if 0 - if (atomic_compare_and_swap (CONNECTED, FREE, &p->state) != 0) - return; /* In case reconnect in progress already */ -#else - atomic_set (&p->state, FREE); +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); #endif + rc = iucv_accept(eib->ippathid, NETIUCV_QUEUELEN_DEFAULT, udata, 0, + conn->handle, conn, NULL, &msglimit); + if (rc != 0) { + printk(KERN_WARNING + "%s: IUCV accept failed with error %d\n", + netdev->name, rc); + return; + } + fsm_newstate(fi, CONN_STATE_IDLE); + conn->pathid = eib->ippathid; + netdev->tx_queue_len = msglimit; + fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev); +} - netif_stop_queue (p->dev); - netif_stop (p->dev); -} /* end connection_severed() */ +static void +conn_action_connreject(fsm_instance *fi, int event, void *arg) +{ + iucv_event *ev = (iucv_event *)arg; + // iucv_connection *conn = ev->conn; + iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data; + __u8 udata[16]; -/*-----------------------------------------------------*/ -/* STOP device. Called by kernel. */ -/*-----------------------------------------------------*/ -static int -iucv_stop (net_device * dev) +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + iucv_sever(eib->ippathid, udata); +} + +static void +conn_action_connack(fsm_instance *fi, int event, void *arg) { - int rc = 0; - struct iucv_priv *p; - pr_debug ("%s: iucv_stop\n", dev->name); + iucv_event *ev = (iucv_event *)arg; + iucv_connection *conn = ev->conn; + iucv_ConnectionComplete *eib = (iucv_ConnectionComplete *)ev->data; + net_device *netdev = conn->netdev; + netiucv_priv *privptr = (netiucv_priv *)netdev->priv; - netif_stop_queue (dev); - netif_stop (dev); +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + fsm_newstate(fi, CONN_STATE_IDLE); + conn->pathid = eib->ippathid; + netdev->tx_queue_len = eib->ipmsglim; + fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev); +} - p = (struct iucv_priv *) (dev->priv); - if (p == NULL) - return 0; +static void +conn_action_connsever(fsm_instance *fi, int event, void *arg) +{ + iucv_event *ev = (iucv_event *)arg; + iucv_connection *conn = ev->conn; + // iucv_ConnectionSevered *eib = (iucv_ConnectionSevered *)ev->data; + net_device *netdev = conn->netdev; + netiucv_priv *privptr = (netiucv_priv *)netdev->priv; + int state = fsm_getstate(fi); - /* Unregister will sever associated connections */ - rc = iucv_unregister_program (p->handle); - dev->priv = NULL; - kfree (p); - MOD_DEC_USE_COUNT; - return 0; -} /* end iucv_stop() */ +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + switch (state) { + case CONN_STATE_IDLE: + case CONN_STATE_TX: + printk(KERN_INFO "%s: Remote dropped connection\n", + netdev->name); + iucv_unregister_program(conn->handle); + conn->handle = 0; + fsm_newstate(fi, CONN_STATE_STOPPED); + fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); + break; + } +} -/*---------------------------------------------------------------------*/ -/* Inbound packets from other host are ready for receipt. Receive */ -/* them (they arrive as a single transmission), break them up into */ -/* separate packets, and send them to the "generic" packet processor. */ -/*---------------------------------------------------------------------*/ static void -message_pending (iucv_MessagePending * mpi, void *pgm_data) +conn_action_start(fsm_instance *fi, int event, void *arg) { - struct iucv_priv *p = (struct iucv_priv *) pgm_data; - int rc; - u32 buffer_length; - u16 packet_offset, prev_offset = 0; - void *buffer; + iucv_event *ev = (iucv_event *)arg; + iucv_connection *conn = ev->conn; - buffer_length = mpi->ln1msg2.ipbfln1f; - pr_debug ("%s: MP id=%i Length=%u\n", - p->dev->name, mpi->ipmsgid, buffer_length); + int rc; - buffer = kmalloc (buffer_length, GFP_ATOMIC | GFP_DMA); - if (buffer == NULL) { - p->stats.rx_dropped++; - return; +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + if (conn->handle == 0) { + conn->handle = + iucv_register_program(iucvMagic, conn->userid, mask, + &netiucv_ops, conn); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + if (conn->handle <= 0) { + fsm_newstate(fi, CONN_STATE_REGERR); + conn->handle = 0; + return; + } +#ifdef DEBUG + printk(KERN_DEBUG "%s('%s'): registered successfully\n", + conn->netdev->name, conn->userid); +#endif } - rc = iucv_receive (p->pathid, mpi->ipmsgid, mpi->iptrgcls, - buffer, buffer_length, NULL, NULL, NULL); - - if (rc != 0 || buffer_length < 5) { - printk (KERN_INFO - "%s: IUCV rcv error. rc=%X ID=%i length=%u\n", - p->dev->name, rc, mpi->ipmsgid, buffer_length); - p->stats.rx_errors++; - kfree (buffer); - return; +#ifdef DEBUG + printk(KERN_DEBUG "%s('%s'): connecting ...\n", + conn->netdev->name, conn->userid); +#endif + rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic, + conn->userid, iucv_host, 0, NULL, NULL, conn->handle, + conn); + fsm_newstate(fi, CONN_STATE_SETUPWAIT); + switch (rc) { + case 0: + return; + case 11: + printk(KERN_NOTICE + "%s: User %s is currently not available.\n", + conn->netdev->name, + netiucv_printname(conn->userid)); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + return; + case 12: + printk(KERN_NOTICE + "%s: User %s is currently not ready.\n", + conn->netdev->name, + netiucv_printname(conn->userid)); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + return; + case 13: + printk(KERN_WARNING + "%s: Too many IUCV connections.\n", + conn->netdev->name); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; + case 14: + printk(KERN_WARNING + "%s: User %s has too many IUCV connections.\n", + conn->netdev->name, + netiucv_printname(conn->userid)); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; + case 15: + printk(KERN_WARNING + "%s: No IUCV authorization in CP directory.\n", + conn->netdev->name); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; + default: + printk(KERN_WARNING + "%s: iucv_connect returned error %d\n", + conn->netdev->name, rc); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; } + iucv_unregister_program(conn->handle); + conn->handle = 0; +} - packet_offset = *((u16 *) buffer); +static void +netiucv_purge_skb_queue(struct sk_buff_head *q) +{ + struct sk_buff *skb; - while (packet_offset != 0) { - if (packet_offset <= prev_offset - || packet_offset > buffer_length - 2) { - printk (KERN_INFO "%s: bad inbound packet offset %u, " - "prev %u, total %u\n", p->dev->name, - packet_offset, prev_offset, buffer_length); - p->stats.rx_errors++; - break; - } else { - /* Kick the packet upstairs */ - iucv_rx (p->dev, mpi->ipmsgid, - buffer + prev_offset + 2, - packet_offset - prev_offset - 2); - prev_offset = packet_offset; - packet_offset = *((u16 *) (buffer + packet_offset)); - } + while ((skb = skb_dequeue(q))) { + atomic_dec(&skb->users); + dev_kfree_skb_any(skb); } +} - kfree (buffer); - return; -} /* end message_pending() */ +static void +conn_action_stop(fsm_instance *fi, int event, void *arg) +{ + iucv_event *ev = (iucv_event *)arg; + iucv_connection *conn = ev->conn; + net_device *netdev = conn->netdev; + netiucv_priv *privptr = (netiucv_priv *)netdev->priv; + +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + fsm_newstate(fi, CONN_STATE_STOPPED); + netiucv_purge_skb_queue(&conn->collect_queue); + iucv_unregister_program(conn->handle); + conn->handle = 0; + fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); +} -/*-------------------------------------------------------------*/ -/* Add meta-data to packet and send upstairs. */ -/*-------------------------------------------------------------*/ static void -iucv_rx (net_device * dev, u32 msgid, uchar * buf, int len) +conn_action_inval(fsm_instance *fi, int event, void *arg) { - struct iucv_priv *p = (struct iucv_priv *) dev->priv; - struct sk_buff *skb; + iucv_event *ev = (iucv_event *)arg; + iucv_connection *conn = ev->conn; + net_device *netdev = conn->netdev; + + printk(KERN_WARNING + "%s: Cannot connect without username\n", + netdev->name); +} + +static const fsm_node conn_fsm[] = { + { CONN_STATE_INVALID, CONN_EVENT_START, conn_action_inval }, + { CONN_STATE_STOPPED, CONN_EVENT_START, conn_action_start }, + { CONN_STATE_STARTWAIT, CONN_EVENT_START, conn_action_start }, + + { CONN_STATE_STARTWAIT, CONN_EVENT_STOP, conn_action_stop }, + { CONN_STATE_SETUPWAIT, CONN_EVENT_STOP, conn_action_stop }, + { CONN_STATE_IDLE, CONN_EVENT_STOP, conn_action_stop }, + { CONN_STATE_TX, CONN_EVENT_STOP, conn_action_stop }, + { CONN_STATE_REGERR, CONN_EVENT_STOP, conn_action_stop }, + { CONN_STATE_CONNERR, CONN_EVENT_STOP, conn_action_stop }, + + { CONN_STATE_STOPPED, CONN_EVENT_CONN_REQ, conn_action_connreject }, + { CONN_STATE_STARTWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept }, + { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept }, + { CONN_STATE_IDLE, CONN_EVENT_CONN_REQ, conn_action_connreject }, + { CONN_STATE_TX, CONN_EVENT_CONN_REQ, conn_action_connreject }, + + { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_ACK, conn_action_connack }, + + { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REJ, conn_action_connsever }, + { CONN_STATE_IDLE, CONN_EVENT_CONN_REJ, conn_action_connsever }, + { CONN_STATE_TX, CONN_EVENT_CONN_REJ, conn_action_connsever }, + + { CONN_STATE_IDLE, CONN_EVENT_RX, conn_action_rx }, + { CONN_STATE_TX, CONN_EVENT_RX, conn_action_rx }, + + { CONN_STATE_TX, CONN_EVENT_TXDONE, conn_action_txdone }, +}; + +static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node); + + +/** + * Actions for interface - statemachine. + *****************************************************************************/ + +/** + * Startup connection by sending CONN_EVENT_START to it. + * + * @param fi An instance of an interface statemachine. + * @param event The event, just happened. + * @param arg Generic pointer, casted from net_device * upon call. + */ +static void +dev_action_start(fsm_instance *fi, int event, void *arg) +{ + net_device *dev = (net_device *)arg; + netiucv_priv *privptr = dev->priv; + iucv_event ev; -#ifdef IPDEBUG - printk (KERN_DEBUG "RX id=%i\n", msgid); - dumpit (buf, 20); - dumpit (buf + 20, 20); +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); #endif + ev.conn = privptr->conn; + fsm_newstate(fi, DEV_STATE_STARTWAIT); + fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev); +} - pr_debug ("%s: RX len=%u\n", p->dev->name, len); +/** + * Shutdown connection by sending CONN_EVENT_STOP to it. + * + * @param fi An instance of an interface statemachine. + * @param event The event, just happened. + * @param arg Generic pointer, casted from net_device * upon call. + */ +static void +dev_action_stop(fsm_instance *fi, int event, void *arg) +{ + net_device *dev = (net_device *)arg; + netiucv_priv *privptr = dev->priv; + iucv_event ev; - if (len > p->dev->mtu) { - printk (KERN_INFO - "%s: inbound packet id# %i length %u exceeds MTU %i\n", - p->dev->name, msgid, len, p->dev->mtu); - p->stats.rx_errors++; - return; +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + ev.conn = privptr->conn; + + fsm_newstate(fi, DEV_STATE_STOPWAIT); + fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev); +} + +/** + * Called from connection statemachine + * when a connection is up and running. + * + * @param fi An instance of an interface statemachine. + * @param event The event, just happened. + * @param arg Generic pointer, casted from net_device * upon call. + */ +static void +dev_action_connup(fsm_instance *fi, int event, void *arg) +{ + net_device *dev = (net_device *)arg; + +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + switch (fsm_getstate(fi)) { + case DEV_STATE_STARTWAIT: + fsm_newstate(fi, DEV_STATE_RUNNING); + printk(KERN_INFO + "%s: connected with remote side\n", + dev->name); + break; + case DEV_STATE_STOPWAIT: + printk(KERN_INFO + "%s: got connection UP event during shutdown!!\n", + dev->name); + break; } +} - skb = dev_alloc_skb (len); - if (!skb) { - p->stats.rx_dropped++; - return; +/** + * Called from connection statemachine + * when a connection has been shutdown. + * + * @param fi An instance of an interface statemachine. + * @param event The event, just happened. + * @param arg Generic pointer, casted from net_device * upon call. + */ +static void +dev_action_conndown(fsm_instance *fi, int event, void *arg) +{ + net_device *dev = (net_device *)arg; + netiucv_priv *privptr = dev->priv; + iucv_event ev; + +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + switch (fsm_getstate(fi)) { + case DEV_STATE_RUNNING: + fsm_newstate(fi, DEV_STATE_STARTWAIT); + ev.conn = privptr->conn; + fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev); + break; + case DEV_STATE_STARTWAIT: + break; + case DEV_STATE_STOPWAIT: + fsm_newstate(fi, DEV_STATE_STOPPED); + break; } +} - /* If not enough room, skb_put will panic */ - memcpy (skb_put (skb, len), buf, len); +static const fsm_node dev_fsm[] = { + { DEV_STATE_STOPPED, DEV_EVENT_START, dev_action_start }, - /* Write metadata, and then pass to the receive level. Since we */ - /* are not an Ethernet device, we have special fields to set. */ - /* This is all boilerplace, not to be messed with. */ - skb->dev = p->dev; /* Set device */ - skb->mac.raw = skb->data; /* Point to packet */ - skb->pkt_type = PACKET_HOST; /* ..for this host. */ - skb->protocol = htons (ETH_P_IP); /* IP packet */ - skb->ip_summed = CHECKSUM_UNNECESSARY; /* No checksum */ - p->stats.rx_packets++; - p->stats.rx_bytes += len; - netif_rx (skb); + { DEV_STATE_STOPWAIT, DEV_EVENT_START, dev_action_start }, + { DEV_STATE_STOPWAIT, DEV_EVENT_CONDOWN, dev_action_conndown }, - return; -} /* end iucv_rx() */ + { DEV_STATE_STARTWAIT, DEV_EVENT_STOP, dev_action_stop }, + { DEV_STATE_STARTWAIT, DEV_EVENT_CONUP, dev_action_connup }, + { DEV_STATE_STARTWAIT, DEV_EVENT_CONDOWN, dev_action_conndown }, -/*-------------------------------------------------------------*/ -/* TRANSMIT a packet. Called by kernel. */ -/* This function deals with hw details of packet transmission. */ -/*-------------------------------------------------------------*/ -static int -iucv_tx (struct sk_buff *skb, net_device * dev) -{ - int rc, pktlen; - u32 framelen, msgid; - void *frame; - struct iucv_priv *p = (struct iucv_priv *) dev->priv; + { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop }, + { DEV_STATE_RUNNING, DEV_EVENT_CONDOWN, dev_action_conndown }, + { DEV_STATE_RUNNING, DEV_EVENT_CONUP, fsm_action_nop }, +}; + +static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node); - if (skb == NULL) { /* Nothing to do */ - printk (KERN_WARNING "%s: TX Kernel passed null sk_buffer\n", - dev->name); - p->stats.tx_dropped++; - return -EIO; +/** + * Transmit a packet. + * This is a helper function for netiucv_tx(). + * + * @param conn Connection to be used for sending. + * @param skb Pointer to struct sk_buff of packet to send. + * The linklevel header has already been set up + * by netiucv_tx(). + * + * @return 0 on success, -ERRNO on failure. (Never fails.) + */ +static int +netiucv_transmit_skb(iucv_connection *conn, struct sk_buff *skb) { + unsigned long saveflags; + ll_header header; + int rc = 0; + + if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) { + int l = skb->len + NETIUCV_HDRLEN; + + spin_lock_irqsave(&conn->collect_lock, saveflags); + if (conn->collect_len + l > + (conn->max_buffsize - NETIUCV_HDRLEN)) + rc = -EBUSY; + else { + atomic_inc(&skb->users); + skb_queue_tail(&conn->collect_queue, skb); + conn->collect_len += l; + } + spin_unlock_irqrestore(&conn->collect_lock, saveflags); + } else { + struct sk_buff *nskb = skb; + /** + * Copy the skb to a new allocated skb in lowmem only if the + * data is located above 2G in memory or tailroom is < 2. + */ + unsigned long hi = + ((unsigned long)(skb->tail + NETIUCV_HDRLEN)) >> 31; + int copied = 0; + if (hi || (skb_tailroom(skb) < 2)) { + nskb = alloc_skb(skb->len + NETIUCV_HDRLEN + + NETIUCV_HDRLEN, GFP_ATOMIC | GFP_DMA); + if (!nskb) { + printk(KERN_WARNING + "%s: Could not allocate tx_skb\n", + conn->netdev->name); + rc = -ENOMEM; + } else { + skb_reserve(nskb, NETIUCV_HDRLEN); + memcpy(skb_put(nskb, skb->len), + skb->data, skb->len); + } + copied = 1; + } + /** + * skb now is below 2G and has enough room. Add headers. + */ + header.next = nskb->len + NETIUCV_HDRLEN; + memcpy(skb_push(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN); + header.next = 0; + memcpy(skb_put(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN); + + conn->retry = 0; + fsm_newstate(conn->fsm, CONN_STATE_TX); + fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, + CONN_EVENT_TIMER, conn); + conn->prof.send_stamp = xtime; + rc = iucv_send(conn->pathid, NULL, 0, 0, (__u32)nskb, 0, + nskb->data, nskb->len); + conn->prof.doios_single++; + conn->prof.txlen += skb->len; + if (rc != 0) { + fsm_deltimer(&conn->timer); + if (copied) + dev_kfree_skb(nskb); + else { + /** + * Remove our headers. They get added + * again on retransmit. + */ + skb_pull(skb, NETIUCV_HDRLEN); + skb_trim(skb, skb->len - NETIUCV_HDRLEN); + } + } else { + if (copied) + dev_kfree_skb(skb); + } } - if (netif_is_busy (dev)) - return -EBUSY; + return rc; +} + +/** + * Interface API for upper network layers + *****************************************************************************/ + +/** + * Open an interface. + * Called from generic network layer when ifconfig up is run. + * + * @param dev Pointer to interface struct. + * + * @return 0 on success, -ERRNO on failure. (Never fails.) + */ +static int +netiucv_open(net_device *dev) { + MOD_INC_USE_COUNT; + fsm_event(((netiucv_priv *)dev->priv)->fsm, DEV_EVENT_START, dev); + return 0; +} - dev->trans_start = jiffies; /* save the timestamp */ +/** + * Close an interface. + * Called from generic network layer when ifconfig down is run. + * + * @param dev Pointer to interface struct. + * + * @return 0 on success, -ERRNO on failure. (Never fails.) + */ +static int +netiucv_close(net_device *dev) { + SET_DEVICE_START(dev, 0); + fsm_event(((netiucv_priv *)dev->priv)->fsm, DEV_EVENT_STOP, dev); + MOD_DEC_USE_COUNT; + return 0; +} - /* IUCV frame will be released when MessageComplete */ - /* interrupt is received. */ - pktlen = skb->len; - framelen = pktlen + 4; +/** + * Start transmission of a packet. + * Called from generic network device layer. + * + * @param skb Pointer to buffer containing the packet. + * @param dev Pointer to interface struct. + * + * @return 0 if packet consumed, !0 if packet rejected. + * Note: If we return !0, then the packet is free'd by + * the generic network layer. + */ +static int netiucv_tx(struct sk_buff *skb, net_device *dev) +{ + int rc = 0; + netiucv_priv *privptr = (netiucv_priv *)dev->priv; + + /** + * Some sanity checks ... + */ + if (skb == NULL) { + printk(KERN_WARNING "%s: NULL sk_buff passed\n", dev->name); + privptr->stats.tx_dropped++; + return 0; + } + if (skb_headroom(skb) < (NETIUCV_HDRLEN)) { + printk(KERN_WARNING + "%s: Got sk_buff with head room < %ld bytes\n", + dev->name, NETIUCV_HDRLEN); + dev_kfree_skb(skb); + privptr->stats.tx_dropped++; + return 0; + } - frame = kmalloc (framelen, GFP_ATOMIC | GFP_DMA); - if (!frame) { - p->stats.tx_dropped++; - dev_kfree_skb (skb); + /** + * If connection is not running, try to restart it + * notify anybody about a link failure and throw + * away packet. + */ + if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { + fsm_event(privptr->fsm, DEV_EVENT_START, dev); + dst_link_failure(skb); + dev_kfree_skb(skb); + privptr->stats.tx_dropped++; + privptr->stats.tx_errors++; + privptr->stats.tx_carrier_errors++; return 0; } - netif_stop_queue (dev); /* transmission is busy */ + if (netiucv_test_and_set_busy(dev)) + return -EBUSY; - *(u16 *) frame = pktlen + 2; /* Set header */ - memcpy (frame + 2, skb->data, pktlen); /* Copy data */ - memset (frame + pktlen + 2, 0, 2); /* Set trailer */ + dev->trans_start = jiffies; + if (netiucv_transmit_skb(privptr->conn, skb) != 0) + rc = 1; + netiucv_clear_busy(dev); + return rc; +} - /* Ok, now the frame is ready for transmission: send it. */ - rc = iucv_send (p->pathid, &msgid, 0, 0, - (u32) frame, /* Msg tag */ - 0, /* No flags */ - frame, framelen); - if (rc == 0) { -#ifdef IPDEBUG - printk (KERN_DEBUG "TX id=%i\n", msgid); - dumpit (skb->data, 20); - dumpit (skb->data + 20, 20); -#endif - pr_debug ("%s: tx START %i.%i @=%p len=%i\n", - p->dev->name, p->pathid, msgid, frame, framelen); - p->stats.tx_packets++; - } else { - if (rc == 3) /* Exceeded MSGLIMIT */ - p->stats.tx_dropped++; - else { - p->stats.tx_errors++; - printk (KERN_INFO "%s: tx ERROR id=%i.%i rc=%i\n", - p->dev->name, p->pathid, msgid, rc); - } - /* We won't get interrupt. Free frame now. */ - kfree (frame); - } - dev_kfree_skb (skb); /* Finished with skb */ +/** + * Returns interface statistics of a device. + * + * @param dev Pointer to interface struct. + * + * @return Pointer to stats struct of this interface. + */ +static struct net_device_stats * +netiucv_stats (net_device * dev) +{ + return &((netiucv_priv *)dev->priv)->stats; +} - netif_wake_queue (p->dev); +/** + * Sets MTU of an interface. + * + * @param dev Pointer to interface struct. + * @param new_mtu The new MTU to use for this interface. + * + * @return 0 on success, -EINVAL if MTU is out of valid range. + * (valid range is 576 .. NETIUCV_MTU_MAX). + */ +static int +netiucv_change_mtu (net_device * dev, int new_mtu) +{ + if ((new_mtu < 576) || (new_mtu > NETIUCV_MTU_MAX)) + return -EINVAL; + dev->mtu = new_mtu; return 0; -} /* end iucv_tx() */ +} -/*-----------------------------------------------------------*/ -/* SEND COMPLETE Called by IUCV handler. */ -/* Free the IUCV frame that was used for this transmission. */ -/*-----------------------------------------------------------*/ + +/** + * procfs related structures and routines + *****************************************************************************/ + +static net_device * +find_netdev_by_ino(unsigned long ino) +{ + iucv_connection *conn = connections; + net_device *dev = NULL; + netiucv_priv *privptr; + + while (conn) { + if (conn->netdev != dev) { + dev = conn->netdev; + privptr = (netiucv_priv *)dev->priv; + + if ((privptr->proc_buffer_entry->low_ino == ino) || + (privptr->proc_user_entry->low_ino == ino) || + (privptr->proc_stat_entry->low_ino == ino) ) + return dev; + } + conn = conn->next; + } + return NULL; +} + +#if LINUX_VERSION_CODE < 0x020363 +/** + * Lock the module, if someone changes into + * our proc directory. + */ static void -send_complete (iucv_MessageComplete * mci, void *pgm_data) +netiucv_fill_inode(struct inode *inode, int fill) { - void *frame; -#ifdef DEBUG - struct iucv_priv *p = (struct iucv_priv *) pgm_data; + if (fill) { + MOD_INC_USE_COUNT; + } else + MOD_DEC_USE_COUNT; +} #endif - frame = (void *) (ulong) mci->ipmsgtag; - kfree (frame); - pr_debug ("%s: TX DONE %i.%i @=%p\n", - p->dev->name, mci->ippathid, mci->ipmsgid, frame); -} /* end send_complete() */ -/*-----------------------------------------------------------*/ -/* STATISTICS reporting. Called by kernel. */ -/*-----------------------------------------------------------*/ -static struct net_device_stats * -iucv_stats (net_device * dev) -{ - struct iucv_priv *p = (struct iucv_priv *) dev->priv; - return &p->stats; -} /* end iucv_stats() */ - -/*-----------------------------------------------------------*/ -/* MTU change . Called by kernel. */ -/* IUCV can handle mtu sizes from 576 (the IP architectural */ -/* minimum) up to maximum supported by VM. I don't think IP */ -/* pays attention to new mtu until device is restarted. */ -/*-----------------------------------------------------------*/ +#define CTRL_BUFSIZE 40 + static int -iucv_change_mtu (net_device * dev, int new_mtu) +netiucv_buffer_open(struct inode *inode, struct file *file) { - if ((new_mtu < 576) || (new_mtu > MAX_VM_MTU)) + file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL); + if (file->private_data == NULL) + return -ENOMEM; + MOD_INC_USE_COUNT; + return 0; +} + +static int +netiucv_buffer_close(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + MOD_DEC_USE_COUNT; + return 0; +} + +static ssize_t +netiucv_buffer_write(struct file *file, const char *buf, size_t count, + loff_t *off) +{ + unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; + net_device *dev; + netiucv_priv *privptr; + char *e; + int bs1; + char tmp[CTRL_BUFSIZE]; + + if (!(dev = find_netdev_by_ino(ino))) + return -ENODEV; + if (off != &file->f_pos) + return -ESPIPE; + + privptr = (netiucv_priv *)dev->priv; + + if (count >= 39) return -EINVAL; - dev->mtu = new_mtu; + + if (copy_from_user(tmp, buf, count)) + return -EFAULT; + tmp[count+1] = '\0'; + bs1 = simple_strtoul(tmp, &e, 0); + + if ((bs1 > NETIUCV_BUFSIZE_MAX) || + (e && (!isspace(*e)))) + return -EINVAL; + if ((dev->flags & IFF_RUNNING) && + (bs1 < (dev->mtu + NETIUCV_HDRLEN + 2))) + return -EINVAL; + if (bs1 < (576 + NETIUCV_HDRLEN + NETIUCV_HDRLEN)) + return -EINVAL; + + + privptr->conn->max_buffsize = bs1; + if (!(dev->flags & IFF_RUNNING)) + dev->mtu = bs1 - NETIUCV_HDRLEN - NETIUCV_HDRLEN; + privptr->conn->flags |= CONN_FLAGS_BUFSIZE_CHANGED; + + return count; +} + +static ssize_t +netiucv_buffer_read(struct file *file, char *buf, size_t count, loff_t *off) +{ + unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; + char *sbuf = (char *)file->private_data; + net_device *dev; + netiucv_priv *privptr; + ssize_t ret = 0; + char *p = sbuf; + int l; + + if (!(dev = find_netdev_by_ino(ino))) + return -ENODEV; + if (off != &file->f_pos) + return -ESPIPE; + + privptr = (netiucv_priv *)dev->priv; + + if (file->f_pos == 0) + sprintf(sbuf, "%d\n", privptr->conn->max_buffsize); + + l = strlen(sbuf); + p = sbuf; + if (file->f_pos < l) { + p += file->f_pos; + l = strlen(p); + ret = (count > l) ? l : count; + if (copy_to_user(buf, p, ret)) + return -EFAULT; + } + file->f_pos += ret; + return ret; +} + +static int +netiucv_user_open(struct inode *inode, struct file *file) +{ + file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL); + if (file->private_data == NULL) + return -ENOMEM; + MOD_INC_USE_COUNT; return 0; -} /* end iucv_change_mtu() */ +} -/*-----------------------------------------------------------*/ -/* INIT device. Called by kernel. */ -/* Called by register_netdev() in kernel. */ -/*-----------------------------------------------------------*/ static int -iucv_init (net_device * dev) -{ - dev->open = iucv_start; - dev->stop = iucv_stop; - dev->hard_start_xmit = iucv_tx; - dev->get_stats = iucv_stats; - dev->change_mtu = iucv_change_mtu; - dev->hard_header_len = 0; - dev->addr_len = 0; - dev->type = ARPHRD_SLIP; - dev->tx_queue_len = MAX_TX_Q; /* Default - updated based on IUCV */ - /* keep the default flags, just add NOARP and POINTOPOINT */ - dev->flags |= IFF_NOARP | IFF_POINTOPOINT; - dev->mtu = 9216; - - dev_init_buffers (dev); - pr_debug ("%s: iucv_init dev@=%p\n", dev->name, dev); +netiucv_user_close(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + MOD_DEC_USE_COUNT; return 0; } -#ifndef MODULE -/*-----------------------------------------------------------------*/ -/* Process iucv=userid1,...,useridn kernel parameter. */ -/* */ -/* Each user id provided will be associated with device 'iucvnn'. */ -/* iucv_init will be called to initialize each device. */ -/*-----------------------------------------------------------------*/ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) -#define init_return(a) return a -static int __init -iucv_setup (char *iucv) +static ssize_t +netiucv_user_write(struct file *file, const char *buf, size_t count, + loff_t *off) +{ + unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; + net_device *dev; + netiucv_priv *privptr; + int i; + char *p; + char tmp[CTRL_BUFSIZE]; + char user[9]; + + if (!(dev = find_netdev_by_ino(ino))) + return -ENODEV; + if (off != &file->f_pos) + return -ESPIPE; + + privptr = (netiucv_priv *)dev->priv; + + if (count >= 39) + return -EINVAL; + + if (copy_from_user(tmp, buf, count)) + return -EFAULT; + tmp[count+1] = '\0'; + + memset(user, ' ', sizeof(user)); + user[8] = '\0'; + for (p = tmp, i = 0; *p && (!isspace(*p)); p++) { + if (i > 7) + return -EINVAL; + user[i++] = *p; + } + + if (memcmp(user, privptr->conn->userid, 8) != 0) { + /* username changed */ + if (dev->flags & IFF_RUNNING) + return -EBUSY; + } + memcpy(privptr->conn->userid, user, 9); + return count; +} + +static ssize_t +netiucv_user_read(struct file *file, char *buf, size_t count, loff_t *off) +{ + unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; + char *sbuf = (char *)file->private_data; + net_device *dev; + netiucv_priv *privptr; + ssize_t ret = 0; + char *p = sbuf; + int l; + + if (!(dev = find_netdev_by_ino(ino))) + return -ENODEV; + if (off != &file->f_pos) + return -ESPIPE; + + privptr = (netiucv_priv *)dev->priv; + + + if (file->f_pos == 0) + sprintf(sbuf, "%s\n", + netiucv_printname(privptr->conn->userid)); + + l = strlen(sbuf); + p = sbuf; + if (file->f_pos < l) { + p += file->f_pos; + l = strlen(p); + ret = (count > l) ? l : count; + if (copy_to_user(buf, p, ret)) + return -EFAULT; + } + file->f_pos += ret; + return ret; +} + +#define STATS_BUFSIZE 2048 + +static int +netiucv_stat_open(struct inode *inode, struct file *file) +{ + file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL); + if (file->private_data == NULL) + return -ENOMEM; + MOD_INC_USE_COUNT; + return 0; +} + +static int +netiucv_stat_close(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + MOD_DEC_USE_COUNT; + return 0; +} + +static ssize_t +netiucv_stat_write(struct file *file, const char *buf, size_t count, loff_t *off) +{ + unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; + net_device *dev; + netiucv_priv *privptr; + + if (!(dev = find_netdev_by_ino(ino))) + return -ENODEV; + privptr = (netiucv_priv *)dev->priv; + privptr->conn->prof.maxmulti = 0; + privptr->conn->prof.maxcqueue = 0; + privptr->conn->prof.doios_single = 0; + privptr->conn->prof.doios_multi = 0; + privptr->conn->prof.txlen = 0; + privptr->conn->prof.tx_time = 0; + return count; +} + +static ssize_t +netiucv_stat_read(struct file *file, char *buf, size_t count, loff_t *off) +{ + unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; + char *sbuf = (char *)file->private_data; + net_device *dev; + netiucv_priv *privptr; + ssize_t ret = 0; + char *p = sbuf; + int l; + + if (!(dev = find_netdev_by_ino(ino))) + return -ENODEV; + if (off != &file->f_pos) + return -ESPIPE; + + privptr = (netiucv_priv *)dev->priv; + + if (file->f_pos == 0) { + p += sprintf(p, "Device FSM state: %s\n", + fsm_getstate_str(privptr->fsm)); + p += sprintf(p, "RX channel FSM state: %s\n", + fsm_getstate_str(privptr->conn->fsm)); + p += sprintf(p, "TX channel FSM state: %s\n", + fsm_getstate_str(privptr->conn->fsm)); + p += sprintf(p, "Max. TX buffer used: %ld\n", + privptr->conn->prof.maxmulti); + p += sprintf(p, "Max. chained SKBs: %ld\n", + privptr->conn->prof.maxcqueue); + p += sprintf(p, "TX single write ops: %ld\n", + privptr->conn->prof.doios_single); + p += sprintf(p, "TX multi write ops: %ld\n", + privptr->conn->prof.doios_multi); + p += sprintf(p, "Netto bytes written: %ld\n", + privptr->conn->prof.txlen); + p += sprintf(p, "Max. TX IO-time: %ld\n", + privptr->conn->prof.tx_time); + } + l = strlen(sbuf); + p = sbuf; + if (file->f_pos < l) { + p += file->f_pos; + l = strlen(p); + ret = (count > l) ? l : count; + if (copy_to_user(buf, p, ret)) + return -EFAULT; + } + file->f_pos += ret; + return ret; +} + +static struct file_operations netiucv_stat_fops = { + read: netiucv_stat_read, + write: netiucv_stat_write, + open: netiucv_stat_open, + release: netiucv_stat_close, +}; + +static struct file_operations netiucv_buffer_fops = { + read: netiucv_buffer_read, + write: netiucv_buffer_write, + open: netiucv_buffer_open, + release: netiucv_buffer_close, +}; + +static struct file_operations netiucv_user_fops = { + read: netiucv_user_read, + write: netiucv_user_write, + open: netiucv_user_open, + release: netiucv_user_close, +}; + +static struct inode_operations netiucv_stat_iops = { +#if LINUX_VERSION_CODE < 0x020363 + default_file_ops: &netiucv_stat_fops +#endif +}; +static struct inode_operations netiucv_buffer_iops = { +#if LINUX_VERSION_CODE < 0x020363 + default_file_ops: &netiucv_buffer_fops +#endif +}; + +static struct inode_operations netiucv_user_iops = { +#if LINUX_VERSION_CODE < 0x020363 + default_file_ops: &netiucv_user_fops +#endif +}; + +static struct proc_dir_entry stat_entry = { + 0, /* low_ino */ + 10, /* namelen */ + "statistics", /* name */ + S_IFREG | S_IRUGO | S_IWUSR, /* mode */ + 1, /* nlink */ + 0, /* uid */ + 0, /* gid */ + 0, /* size */ + &netiucv_stat_iops /* ops */ +}; + +static struct proc_dir_entry buffer_entry = { + 0, /* low_ino */ + 10, /* namelen */ + "buffersize", /* name */ + S_IFREG | S_IRUSR | S_IWUSR, /* mode */ + 1, /* nlink */ + 0, /* uid */ + 0, /* gid */ + 0, /* size */ + &netiucv_buffer_iops /* ops */ +}; + +static struct proc_dir_entry user_entry = { + 0, /* low_ino */ + 8, /* namelen */ + "username", /* name */ + S_IFREG | S_IRUSR | S_IWUSR, /* mode */ + 1, /* nlink */ + 0, /* uid */ + 0, /* gid */ + 0, /* size */ + &netiucv_user_iops /* ops */ +}; + +#if LINUX_VERSION_CODE < 0x020363 +static struct proc_dir_entry netiucv_dir = { + 0, /* low_ino */ + 4, /* namelen */ + "iucv", /* name */ + S_IFDIR | S_IRUGO | S_IXUGO, /* mode */ + 2, /* nlink */ + 0, /* uid */ + 0, /* gid */ + 0, /* size */ + 0, /* ops */ + 0, /* get_info */ + netiucv_fill_inode /* fill_ino (for locking) */ +}; + +static struct proc_dir_entry netiucv_template = +{ + 0, /* low_ino */ + 0, /* namelen */ + "", /* name */ + S_IFDIR | S_IRUGO | S_IXUGO, /* mode */ + 2, /* nlink */ + 0, /* uid */ + 0, /* gid */ + 0, /* size */ + 0, /* ops */ + 0, /* get_info */ + netiucv_fill_inode /* fill_ino (for locking) */ +}; #else -#define init_return(a) return -__initfunc (void iucv_setup (char *iucv, int *ints)) +static struct proc_dir_entry *netiucv_dir = NULL; +static struct proc_dir_entry *netiucv_template = NULL; #endif + +/** + * Create the driver's main directory /proc/net/iucv + */ +static void +netiucv_proc_create_main(void) { - int i, devnumber; - char *s; - char temp_userid[9]; + /** + * If not registered, register main proc dir-entry now + */ +#if LINUX_VERSION_CODE > 0x020362 + if (!netiucv_dir) + netiucv_dir = proc_mkdir("iucv", proc_net); +#else + if (netiucv_dir.low_ino == 0) + proc_net_register(&netiucv_dir); +#endif +} - i = devnumber = 0; - memset (temp_userid, ' ', 8); - temp_userid[8] = '\0'; - printk (KERN_NOTICE "netiucv: IUCV network driver " LEVEL "\n"); +#ifdef MODULE +/** + * Destroy /proc/net/iucv + */ +static void +netiucv_proc_destroy_main(void) +{ +#if LINUX_VERSION_CODE > 0x020362 + remove_proc_entry("iucv", proc_net); +#else + proc_net_unregister(netiucv_dir.low_ino); +#endif +} +#endif MODULE - if (!iucv) - init_return (0); +/** + * Create a device specific subdirectory in /proc/net/iucv/ with the + * same name like the device. In that directory, create 3 entries + * "statistics", "buffersize" and "username". + * + * @param dev The device for which the subdirectory should be created. + * + */ +static void +netiucv_proc_create_sub(net_device *dev) { + netiucv_priv *privptr = dev->priv; + +#if LINUX_VERSION_CODE > 0x020362 + privptr->proc_dentry = proc_mkdir(dev->name, netiucv_dir); + privptr->proc_stat_entry = + create_proc_entry("statistics", + S_IFREG | S_IRUSR | S_IWUSR, + privptr->proc_dentry); + privptr->proc_stat_entry->proc_fops = &netiucv_stat_fops; + privptr->proc_stat_entry->proc_iops = &netiucv_stat_iops; + privptr->proc_buffer_entry = + create_proc_entry("buffersize", + S_IFREG | S_IRUSR | S_IWUSR, + privptr->proc_dentry); + privptr->proc_buffer_entry->proc_fops = &netiucv_buffer_fops; + privptr->proc_buffer_entry->proc_iops = &netiucv_buffer_iops; + privptr->proc_user_entry = + create_proc_entry("username", + S_IFREG | S_IRUSR | S_IWUSR, + privptr->proc_dentry); + privptr->proc_user_entry->proc_fops = &netiucv_user_fops; + privptr->proc_user_entry->proc_iops = &netiucv_user_iops; +#else + privptr->proc_dentry->name = dev->name; + privptr->proc_dentry->namelen = strlen(dev->name); + proc_register(&netiucv_dir, privptr->proc_dentry); + proc_register(privptr->proc_dentry, privptr->proc_stat_entry); + proc_register(privptr->proc_dentry, privptr->proc_buffer_entry); + proc_register(privptr->proc_dentry, privptr->proc_user_entry); +#endif + privptr->proc_registered = 1; +} - for (s = iucv; *s != '\0'; s++) { - if (*s == ' ') /* Compress out blanks */ - continue; - if (devnumber >= MAX_DEVICES) { - printk (KERN_ERR "More than %i IUCV hosts specified\n", - MAX_DEVICES); - init_return (-ENODEV); +/** + * Destroy a device specific subdirectory. + * + * @param privptr Pointer to device private data. + */ +static void +netiucv_proc_destroy_sub(netiucv_priv *privptr) { + if (!privptr->proc_registered) + return; +#if LINUX_VERSION_CODE > 0x020362 + remove_proc_entry("statistics", privptr->proc_dentry); + remove_proc_entry("buffersize", privptr->proc_dentry); + remove_proc_entry("username", privptr->proc_dentry); + remove_proc_entry(privptr->proc_dentry->name, netiucv_dir); +#else + proc_unregister(privptr->proc_dentry, + privptr->proc_stat_entry->low_ino); + proc_unregister(privptr->proc_dentry, + privptr->proc_buffer_entry->low_ino); + proc_unregister(privptr->proc_dentry, + privptr->proc_user_entry->low_ino); + proc_unregister(&netiucv_dir, + privptr->proc_dentry->low_ino); +#endif + privptr->proc_registered = 0; +} + + +/** + * Allocate and initialize a new connection structure. + * Add it to the list of connections; + */ +static iucv_connection * +netiucv_new_connection(net_device *dev, char *username) +{ + iucv_connection **clist = &connections; + iucv_connection *conn = + (iucv_connection *)kmalloc(sizeof(iucv_connection), GFP_KERNEL); + if (conn) { + memset(conn, 0, sizeof(iucv_connection)); + skb_queue_head_init(&conn->collect_queue); + conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT; + conn->netdev = dev; + + conn->rx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA); + if (!conn->rx_buff) { + kfree(conn); + return NULL; + } + conn->tx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA); + if (!conn->tx_buff) { + kfree_skb(conn->rx_buff); + kfree(conn); + return NULL; + } + conn->fsm = init_fsm("netiucvconn", conn_state_names, + conn_event_names, NR_CONN_STATES, + NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN, + GFP_KERNEL); + if (!conn->fsm) { + kfree_skb(conn->tx_buff); + kfree_skb(conn->rx_buff); + kfree(conn); + return NULL; } + fsm_settimer(conn->fsm, &conn->timer); + fsm_newstate(conn->fsm, CONN_STATE_INVALID); - if (*s != ',') { - temp_userid[i++] = *s; + if (username) { + memcpy(conn->userid, username, 9); + fsm_newstate(conn->fsm, CONN_STATE_STOPPED); + } - if (i == 8 || *(s + 1) == ',' || *(s + 1) == '\0') { - register_iucv_dev (devnumber, temp_userid); - devnumber++; - i = 0; - memset (temp_userid, ' ', 8); - if (*(s + 1) != '\0') - *(s + 1) = ' '; + conn->next = *clist; + *clist = conn; + } + return conn; +} + +/** + * Release a connection structure and remove it from the + * list of connections. + */ +static void +netiucv_remove_connection(iucv_connection *conn) +{ + iucv_connection **clist = &connections; + + if (conn == NULL) + return; + while (*clist) { + if (*clist == conn) { + *clist = conn->next; + if (conn->handle != 0) { + iucv_unregister_program(conn->handle); + conn->handle = 0; } + fsm_deltimer(&conn->timer); + kfree_fsm(conn->fsm); + kfree_skb(conn->rx_buff); + kfree_skb(conn->tx_buff); + return; } - } /* while */ - - init_return (1); + clist = &((*clist)->next); + } } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) -__setup ("iucv=", iucv_setup); +/** + * Allocate and initialize everything of a net device. + */ +static net_device * +netiucv_init_netdevice(int ifno, char *username) +{ + netiucv_priv *privptr; + int priv_size; + + net_device *dev = kmalloc(sizeof(net_device) +#if LINUX_VERSION_CODE < 0x020300 + + 11 /* name + zero */ #endif -#else /* BUILT AS MODULE */ -/*-------------------------------------------------------------------*/ -/* Process iucv=userid1,...,useridn module paramter. */ -/* */ -/* insmod passes the module an array of string pointers, each of */ -/* which points to a userid. The commas are stripped out by insmod. */ -/* MODULE_PARM defines the name of the array. (See start of module.)*/ -/* */ -/* Each user id provided will be associated with device 'iucvnn'. */ -/* iucv_init will be called to initialize each device. */ -/*-------------------------------------------------------------------*/ -char *iucv[MAX_DEVICES] = { NULL }; -int -init_module (void) -{ - int i; - printk (KERN_NOTICE "netiucv: IUCV network driver " LEVEL "\n"); - for (i = 0; i < MAX_DEVICES; i++) { - if (iucv[i] == NULL) - break; - register_iucv_dev (i, iucv[i]); + , GFP_KERNEL); + if (!dev) + return NULL; + memset(dev, 0, sizeof(net_device)); +#if LINUX_VERSION_CODE < 0x020300 + dev->name = (char *)dev + sizeof(net_device); +#endif + sprintf(dev->name, "iucv%d", ifno); + + priv_size = sizeof(netiucv_priv) + sizeof(netiucv_template) + + sizeof(stat_entry) + sizeof(buffer_entry) + sizeof(user_entry); + dev->priv = kmalloc(priv_size, GFP_KERNEL); + if (dev->priv == NULL) { + kfree(dev); + return NULL; } - return 0; + memset(dev->priv, 0, priv_size); + privptr = (netiucv_priv *)dev->priv; + privptr->proc_dentry = (struct proc_dir_entry *) + (((char *)privptr) + sizeof(netiucv_priv)); + privptr->proc_stat_entry = (struct proc_dir_entry *) + (((char *)privptr) + sizeof(netiucv_priv) + + sizeof(netiucv_template)); + privptr->proc_buffer_entry = (struct proc_dir_entry *) + (((char *)privptr) + sizeof(netiucv_priv) + + sizeof(netiucv_template) + sizeof(stat_entry)); + privptr->proc_user_entry = (struct proc_dir_entry *) + (((char *)privptr) + sizeof(netiucv_priv) + + sizeof(netiucv_template) + sizeof(stat_entry) + + sizeof(buffer_entry)); + memcpy(privptr->proc_dentry, &netiucv_template, + sizeof(netiucv_template)); + memcpy(privptr->proc_stat_entry, &stat_entry, sizeof(stat_entry)); + memcpy(privptr->proc_buffer_entry, &buffer_entry, sizeof(buffer_entry)); + memcpy(privptr->proc_user_entry, &user_entry, sizeof(user_entry)); + privptr->fsm = init_fsm("netiucvdev", dev_state_names, + dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS, + dev_fsm, DEV_FSM_LEN, GFP_KERNEL); + if (privptr->fsm == NULL) { + kfree(privptr); + kfree(dev); + return NULL; + } + privptr->conn = netiucv_new_connection(dev, username); + if (!privptr->conn) { + kfree_fsm(privptr->fsm); + kfree(privptr); + kfree(dev); + return NULL; + } + + fsm_newstate(privptr->fsm, DEV_STATE_STOPPED); + dev->mtu = NETIUCV_MTU_DEFAULT; + dev->hard_start_xmit = netiucv_tx; + dev->open = netiucv_open; + dev->stop = netiucv_close; + dev->get_stats = netiucv_stats; + dev->change_mtu = netiucv_change_mtu; + dev->hard_header_len = NETIUCV_HDRLEN; + dev->addr_len = 0; + dev->type = ARPHRD_SLIP; + dev->tx_queue_len = NETIUCV_QUEUELEN_DEFAULT; + SET_DEVICE_START(dev, 1); + dev_init_buffers(dev); + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + return dev; } -void -cleanup_module (void) +/** + * Allocate and initialize everything of a net device. + */ +static void +netiucv_free_netdevice(net_device *dev) { - int i; - for (i = 0; i < MAX_DEVICES; i++) { - if (iucv[i]) - unregister_netdev (&iucv_netdev[i]); + netiucv_priv *privptr; + + if (!dev) + return; + + privptr = (netiucv_priv *)dev->priv; + if (privptr) { + if (privptr->conn) + netiucv_remove_connection(privptr->conn); + if (privptr->fsm) + kfree_fsm(privptr->fsm); + netiucv_proc_destroy_sub(privptr); + kfree(privptr); } - return; + kfree(dev); } -#endif /* MODULE */ -void -register_iucv_dev (int devnumber, char *userid) +static void +netiucv_banner(void) { - int rc; - net_device *dev; - - memset (iucv_userid[devnumber], ' ', 8); - memcpy (iucv_userid[devnumber], userid, - min_t(unsigned int, strlen(userid), 8)); - dev = &iucv_netdev[devnumber]; - sprintf (dev->name, "iucv%i", devnumber); + char vbuf[] = "$Revision: 1.11 $"; + char *version = vbuf; + + if ((version = strchr(version, ':'))) { + char *p = strchr(version + 1, '$'); + if (p) + *p = '\0'; + } else + version = " ??? "; + printk(KERN_INFO "NETIUCV driver Version%s initialized\n", version); +} - pr_debug ("netiucv: registering %s\n", dev->name); +#ifndef MODULE +# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) +# define init_return(a) return a +static int __init +iucv_setup(char *param) +# else +# define init_return(a) return +__initfunc (void iucv_setup(char *param, int *ints)) +# endif +{ + /** + * We do not parse parameters here because at the time of + * calling iucv_setup(), the kernel does not yet have + * memory management running. We delay this until probing + * is called. + */ + iucv = param; + init_return(1); +} - if ((rc = register_netdev (dev))) { - printk (KERN_ERR - "netiucv: register_netdev(%s) error %i\n", - dev->name, rc); +# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) +__setup ("iucv=", iucv_setup); +# endif +#else +static void +netiucv_exit(void) +{ + while (connections) { + net_device *dev = connections->netdev; + unregister_netdev(dev); + netiucv_free_netdevice(dev); } + netiucv_proc_destroy_main(); + + printk(KERN_INFO "NETIUCV driver unloaded\n"); return; } +#endif -/* These structures are static because setup() can be called very */ -/* early in kernel init if this module is built into the kernel. */ -/* Certainly no kmalloc() is available, probably no C runtime. */ -/* If support changed to be module only, this can all be done */ -/* dynamically. */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) -static char iucv_names[MAX_DEVICES][8]; /* Allows "iucvXXX" plus null */ -#endif -net_device iucv_netdev[MAX_DEVICES] = { - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[0][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[1][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[2][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[3][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[4][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[5][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[6][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[7][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[8][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[9][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[10][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[11][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[12][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[13][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[14][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[15][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[16][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[17][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[18][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, - { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) - name: &iucv_names[19][0], /* Name filled in at load time */ -#endif - init: iucv_init /* probe function */ - }, -}; +static int +netiucv_init(void) +{ + char *p = iucv; + int ifno = 0; + int i = 0; + char username[10]; + + netiucv_proc_create_main(); + while (p) { + if (isalnum(*p)) { + username[i++] = *p++; + username[i] = '\0'; + if (i > 8) { + printk(KERN_WARNING + "netiucv: Invalid user name '%s'\n", + username); + while (*p && (*p != ':') && (*p != ',')) + p++; + } + } else { + if (*p && (*p != ':') && (*p != ',')) { + printk(KERN_WARNING + "netiucv: Invalid delimiter '%c'\n", + *p); + while (*p && (*p != ':') && (*p != ',')) + p++; + } else { + if (i) { + net_device *dev; + + while (i < 9) + username[i++] = ' '; + username[9] = '\0'; + dev = netiucv_init_netdevice(ifno, + username); + if (!dev) + printk(KERN_WARNING + "netiucv: Could not allocate network device structure for user '%s'\n", netiucv_printname(username)); + else { + if (register_netdev(dev)) { + printk(KERN_WARNING + "netiucv: Could not register '%s'\n", dev->name); + netiucv_free_netdevice(dev); + } else { + printk(KERN_INFO "%s: '%s'\n", dev->name, netiucv_printname(username)); + netiucv_proc_create_sub(dev); + ifno++; + } + } + } + if (!(*p)) + break; + i = 0; + p++; + } + } + } + netiucv_banner(); + return 0; +} + +module_init(netiucv_init); +#ifdef MODULE +module_exit(netiucv_exit); +#endif diff --git a/drivers/s390/s390io.c b/drivers/s390/s390io.c index cfd2e3cd2500..a8c1543c8762 100644 --- a/drivers/s390/s390io.c +++ b/drivers/s390/s390io.c @@ -1,12 +1,13 @@ /* - * arch/s390/kernel/s390io.c + * drivers/s390/s390io.c * S/390 common I/O routines * * S390 version * Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH, * IBM Corporation * Author(s): Ingo Adlung (adlung@de.ibm.com) - * ChangeLog: 01/04/2001 Holger Smolinski (smolinsk@de.ibm.com) + * ChangeLog: 01/07/2001 Blacklist cleanup (djbarrow@de.ibm.com,barrow_dj@yahoo.com) + * 01/04/2001 Holger Smolinski (smolinsk@de.ibm.com) * Fixed lost interrupts and do_adapter_IO * xx/xx/xxxx nnn multiple changes not reflected * 03/12/2001 Ingo Adlung blacklist= - changed to cio_ignore= @@ -20,6 +21,9 @@ * 05/22/2001 Cornelia Huck added /proc/cio_ignore * un-ignore blacklisted devices by piping * to /proc/cio_ignore + * xx/xx/xxxx some bugfixes & cleanups + * 08/02/2001 Cornelia Huck not already known devices can be blacklisted + * by piping to /proc/cio_ignore */ #include <linux/module.h> @@ -29,7 +33,7 @@ #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> -#include <linux/slab.h> +#include <linux/malloc.h> #include <linux/string.h> #include <linux/smp.h> #include <linux/threads.h> @@ -50,17 +54,26 @@ #include <asm/lowcore.h> #include <asm/idals.h> #include <asm/uaccess.h> +#include <asm/cpcmd.h> #include <asm/s390io.h> #include <asm/s390dyn.h> #include <asm/s390mach.h> #include <asm/debug.h> +#include <asm/queue.h> #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif +#define SANITY_CHECK(irq) do { \ +if (irq > highest_subchannel || irq < 0) \ + return (-ENODEV); \ + if (ioinfo[irq] == INVALID_STORAGE_AREA) \ + return (-ENODEV); \ + } while(0) + #undef CONFIG_DEBUG_IO #define CONFIG_DEBUG_CRW @@ -129,6 +142,9 @@ int cio_notoper_msg = 1; int cio_proc_devinfo = 0; /* switch off the /proc/deviceinfo/ stuff by default until problems are dealt with */ +unsigned long s390_irq_count[NR_CPUS]; /* trace how many irqs have occured per cpu... */ +int cio_count_irqs = 1; /* toggle use here... */ + /* * "Blacklisting" of certain devices: * Device numbers given in the commandline as blacklist=... won't be known to Linux @@ -139,109 +155,39 @@ int cio_proc_devinfo = 0; /* switch off the /proc/deviceinfo/ stuff by default */ typedef struct dev_blacklist_range_t { + struct dev_blacklist_range_t *next; /* next range in list */ unsigned int from; /* beginning of range */ unsigned int to; /* end of range */ - struct dev_blacklist_range_t *next; /* next range in list */ + int kmalloced; + } dev_blacklist_range_t; static dev_blacklist_range_t *dev_blacklist_range_head = NULL; /* Anchor for list of ranges */ +static dev_blacklist_range_t *dev_blacklist_unused_head = NULL; + static spinlock_t blacklist_lock = SPIN_LOCK_UNLOCKED; static int nr_blacklisted_ranges = 0; /* Handling of the blacklist ranges */ -/* - * Function: blacklist_range_create - * Creates a range from the given parameters - */ -static inline dev_blacklist_range_t *blacklist_range_create( int from, int to) -{ - dev_blacklist_range_t *range = NULL; - - if (to && (from>to)) { - printk("Invalid blacklist range %x to %x, skipping\n", from, to); - return NULL; - } - if (init_IRQ_complete) { - range = ( dev_blacklist_range_t *) kmalloc( sizeof( dev_blacklist_range_t ), GFP_KERNEL); - } else { - range = ( dev_blacklist_range_t *) alloc_bootmem( sizeof( dev_blacklist_range_t ) ); - } - if (range == NULL) - return NULL; - memset( range, 0, sizeof( dev_blacklist_range_t )); - range->from = from; - if (to == 0) { /* only a single device is given */ - range->to = from; - } else { - range->to = to; - } - nr_blacklisted_ranges++; - return range; -} - -/* - * Function: blacklist_range_destroy - * Free the given range - */ - -static inline void blacklist_range_destroy( dev_blacklist_range_t *range ) +static inline void blacklist_range_destroy( dev_blacklist_range_t *range,int locked ) { - nr_blacklisted_ranges--; - /* - * FIXME: the memory was allocated as bootmem, - * how to get it free again ?! - */ - /* kfree( range ); */ + long flags; + + if(!locked) + spin_lock_irqsave( &blacklist_lock, flags ); + if(!remove_from_list((list **)&dev_blacklist_range_head,(list *)range)) + BUG(); + nr_blacklisted_ranges--; + if(range->kmalloced) + kfree(range); + else + add_to_list((list **)&dev_blacklist_unused_head,(list *)range); + if(!locked) + spin_unlock_irqrestore( &blacklist_lock, flags ); } -/* - * Function: blacklist_range_append - * Append a range to the list of blacklisted ranges anchored at dev_blacklist_range_head - */ -static inline void blacklist_range_append( dev_blacklist_range_t *range ) -{ - dev_blacklist_range_t *temp; - long flags; - - spin_lock_irqsave( &blacklist_lock, flags ); - if (dev_blacklist_range_head == NULL) { - dev_blacklist_range_head = range; - } else { - for ( temp = dev_blacklist_range_head; - temp && temp->next; - temp = temp->next ); - temp->next = range; - } - spin_unlock_irqrestore( &blacklist_lock, flags ); -} - -/* - * Function: blacklist_range_dechain - * Remove a range from the list of blacklisted ranges - */ - -static inline void blacklist_range_dechain( dev_blacklist_range_t *range ) -{ - dev_blacklist_range_t *temp, *prev = NULL; - long flags; - - spin_lock_irqsave( &blacklist_lock, flags ); - for ( temp = dev_blacklist_range_head; temp != NULL; temp = temp->next ) { - if ( temp == range ) - break; - prev = temp; - } - if (!temp) - BUG(); - if (prev) { - prev->next = range->next; - } else { - dev_blacklist_range_head = range->next; - } - spin_unlock_irqrestore( &blacklist_lock, flags ); -} /* * Function: blacklist_range_add @@ -249,15 +195,44 @@ static inline void blacklist_range_dechain( dev_blacklist_range_t *range ) * blacklisted devices */ -static inline dev_blacklist_range_t *blacklist_range_add( int from, int to ) +static inline dev_blacklist_range_t *blacklist_range_add( int from, int to,int locked) { - dev_blacklist_range_t *temp; + + dev_blacklist_range_t *range = NULL; + unsigned long flags; - temp = blacklist_range_create( from, to ); - if (!temp) - return NULL; - blacklist_range_append( temp ); - return temp; + if (to && (from>to)) { + printk(KERN_WARNING "Invalid blacklist range %x to %x, skipping\n", from, to); + return NULL; + } + if(!locked) + spin_lock_irqsave( &blacklist_lock, flags ); + if(dev_blacklist_unused_head) + range=(dev_blacklist_range_t *) + remove_listhead((list **)&dev_blacklist_unused_head); + else if (init_IRQ_complete) { + if((range = ( dev_blacklist_range_t *) + kmalloc( sizeof( dev_blacklist_range_t ), GFP_KERNEL))) + range->kmalloced=1; + } else { + if((range = ( dev_blacklist_range_t *) + alloc_bootmem( sizeof( dev_blacklist_range_t ) ))) + range->kmalloced=0; + } + if (range) + { + add_to_list((list **)&dev_blacklist_range_head,(list *)range); + range->from = from; + if (to == 0) { /* only a single device is given */ + range->to = from; + } else { + range->to = to; + } + nr_blacklisted_ranges++; + } + if(!locked) + spin_unlock_irqrestore( &blacklist_lock, flags ); + return range; } /* @@ -268,12 +243,14 @@ static inline dev_blacklist_range_t *blacklist_range_add( int from, int to ) static inline void blacklist_range_remove( int from, int to ) { dev_blacklist_range_t *temp; + long flags; + spin_lock_irqsave( &blacklist_lock, flags ); for ( temp = dev_blacklist_range_head; (temp->from != from) && (temp->to != to); temp = temp->next ); - blacklist_range_dechain( temp ); - blacklist_range_destroy( temp ); + blacklist_range_destroy( temp,1 ); + spin_unlock_irqrestore( &blacklist_lock, flags ); } /* Parsing the commandline for blacklist parameters */ @@ -361,7 +338,7 @@ static inline void blacklist_parse( char **str ) temp++; to = blacklist_strtoul( temp, &temp ); } - if (!blacklist_range_add( from, to )) { + if (!blacklist_range_add( from, to,0 )) { printk( KERN_WARNING "Blacklisting range from %X to %X failed!\n", from, to); } #ifdef CONFIG_DEBUG_IO @@ -430,20 +407,25 @@ __setup ("cio_ignore=", blacklist_call_setup); static inline int is_blacklisted( int devno ) { dev_blacklist_range_t *temp; + long flags; + int retval=0; if (dev_blacklist_range_head == NULL) { /* no blacklist */ return 0; } + spin_lock_irqsave( &blacklist_lock, flags ); temp = dev_blacklist_range_head; while (temp) { if ((temp->from <= devno) && (temp->to >= devno)) { - return 1; /* Deviceno is blacklisted */ + retval=1; /* Deviceno is blacklisted */ + break; } temp = temp->next; } - return 0; + spin_unlock_irqrestore( &blacklist_lock, flags ); + return retval; } /* @@ -454,12 +436,14 @@ static inline int is_blacklisted( int devno ) void blacklist_free_all_ranges(void) { dev_blacklist_range_t *tmp = dev_blacklist_range_head; + unsigned long flags; + spin_lock_irqsave( &blacklist_lock, flags ); while (tmp) { - blacklist_range_dechain(tmp); - blacklist_range_destroy(tmp); + blacklist_range_destroy(tmp,1); tmp = dev_blacklist_range_head; } + spin_unlock_irqrestore( &blacklist_lock, flags ); } /* @@ -477,6 +461,8 @@ void blacklist_parse_proc_parameters(char *buf) int to = 0; int changed = 0; dev_blacklist_range_t *range, *temp; + long flags; + int err = 0; tmp = buf; if (strstr(tmp, "free ")) { @@ -506,39 +492,97 @@ void blacklist_parse_proc_parameters(char *buf) } else { to = from; } + spin_lock_irqsave( &blacklist_lock, flags ); range = dev_blacklist_range_head; while (range != NULL) { temp = range->next; if ((from <= range->from) && (to >= range->to)) { - blacklist_range_dechain(range); - blacklist_range_destroy(range); + blacklist_range_destroy(range,1); changed = 1; } else if ((from <= range->from) && (to>=range->from) && (to < range->to)) { - blacklist_range_add(to+1, range->to); - blacklist_range_dechain(range); - blacklist_range_destroy(range); + blacklist_range_add(to+1, range->to,1); + blacklist_range_destroy(range,1); changed = 1; } else if ((from > range->from) && (from<=range->to) && (to >= range->to)) { - blacklist_range_add(range->from, from-1); - blacklist_range_dechain(range); - blacklist_range_destroy(range); + blacklist_range_add(range->from, from-1,1); + blacklist_range_destroy(range,1); changed = 1; } else if ((from > range->from) && (to < range->to)) { - blacklist_range_add(range->from, from-1); - blacklist_range_add(to+1, range->to); - blacklist_range_dechain(range); - blacklist_range_destroy(range); + blacklist_range_add(range->from, from-1,1); + blacklist_range_add(to+1, range->to,1); + blacklist_range_destroy(range,1); changed = 1; } range = temp; } + spin_unlock_irqrestore( &blacklist_lock, flags ); kfree(param); } if (changed) s390_redo_validation(); } + } else if (strstr(tmp, "add ")) { + for (i=0;i<4;i++){ + tmp++; + } + while (tmp != NULL) { + end = strchr(tmp, ','); + if (end == NULL) { + len = strlen(tmp) + 1; + } else { + len = (long)end - (long) tmp + 1; + *end = '\0'; + end++; + } + param = (char*) kmalloc(len * sizeof(char) + 1, GFP_KERNEL); + strncpy(param, (const char *) tmp, len); + tmp = end; + from = blacklist_strtoul(param, ¶m); + if (*param == '-') { + param++; + to = blacklist_strtoul(param, ¶m); + } else { + to = from; + } + spin_lock_irqsave( &blacklist_lock, flags ); + + /* + * Don't allow for already known devices to be + * blacklisted + * The criterion is a bit dumb, devices which once were + * there but are already gone are also caught... + */ + + err = 0; + for (i=0; i<=highest_subchannel; i++) { + if (ioinfo[i]!=INVALID_STORAGE_AREA) { + if ( (ioinfo[i]->schib.pmcw.dev >= from) + && (ioinfo[i]->schib.pmcw.dev <= to) ) { + printk(KERN_WARNING "cio_ignore: Won't blacklist " + "already known devices, skipping range " + "%x to %x\n", from, to); + err = 1; + break; + } + } + } + + /* + * Note: We allow for overlapping ranges here, + * since the user might specify overlapping ranges + * and we walk through all ranges when freeing anyway. + */ + + if (!err) + blacklist_range_add(from, to, 1); + + spin_unlock_irqrestore( &blacklist_lock, flags ); + kfree(param); + } + } else { printk("cio_ignore: Parse error; try using 'free all|<devno-range>,<devno-range>,...'\n"); + printk("or 'add <devno-range>,<devno-range>,...'\n"); } } @@ -571,17 +615,19 @@ void s390_displayhex2(char *str, void *ptr, s32 cnt, int level) { s32 cnt1, cnt2, maxcnt2; u32 *currptr = (__u32 *)ptr; + char buffer[cnt*12]; debug_sprintf_event(cio_debug_msg_id, level, "%s\n", str); for (cnt1 = 0; cnt1<cnt; cnt1+=16) { - debug_sprintf_event(cio_debug_msg_id, level, "%08lX ", (unsigned long)currptr); + sprintf(buffer, "%08lX ", (unsigned long)currptr); maxcnt2 = cnt - cnt1; if (maxcnt2 > 16) maxcnt2 = 16; for (cnt2 = 0; cnt2 < maxcnt2; cnt2 += 4) - debug_sprintf_event(cio_debug_msg_id, level, "%08X ", *currptr++); + sprintf(buffer, "%08X ", *currptr++); } + debug_sprintf_event(cio_debug_msg_id, level, "%s\n",buffer); } static int __init cio_setup( char *parm ) @@ -704,6 +750,10 @@ static inline void do_adapter_IO( __u32 intparm ) return; } +/* + * Note : internal use of irqflags SA_PROBE for NOT path grouping + * + */ int s390_request_irq_special( int irq, io_handler_func_t io_handler, not_oper_handler_func_t not_oper_handler, @@ -714,6 +764,7 @@ int s390_request_irq_special( int irq, int retval = 0; unsigned long flags; char dbf_txt[15]; + int retry; if (irq >= __MAX_SUBCHANNELS) return -EINVAL; @@ -738,12 +789,28 @@ int s390_request_irq_special( int irq, if ( !ioinfo[irq]->ui.flags.ready ) { + retry = 5; + ioinfo[irq]->irq_desc.handler = io_handler; ioinfo[irq]->irq_desc.name = devname; ioinfo[irq]->irq_desc.dev_id = dev_id; ioinfo[irq]->ui.flags.ready = 1; + + + do { + retval = enable_subchannel(irq); + if (retval) { + ioinfo[irq]->ui.flags.ready = 0; + break; + } + + stsch(irq,&ioinfo[irq]->schib); + if (ioinfo[irq]->schib.pmcw.ena) + retry = 0; + else + retry--; - enable_subchannel(irq); + } while (retry); } else { @@ -761,7 +828,8 @@ int s390_request_irq_special( int irq, if ( retval == 0 ) { - s390_DevicePathVerification( irq, 0 ); + if ( !(irqflags & SA_PROBE)) + s390_DevicePathVerification( irq, 0 ); ioinfo[irq]->ui.flags.newreq = 1; ioinfo[irq]->nopfunc = not_oper_handler; @@ -838,6 +906,15 @@ void s390_free_irq(unsigned int irq, void *dev_id) /* start deregister */ ioinfo[irq]->ui.flags.unready = 1; + /* + * Try to stop IO first... + * ... it seems disable_subchannel is sometimes + * successfully called with IO still pending. + */ + halt_IO( irq, + 0xC8C1D3E3, + DOIO_WAIT_FOR_INTERRUPT ); + do { ret = disable_subchannel( irq); @@ -888,23 +965,23 @@ void s390_free_irq(unsigned int irq, void *dev_id) } /* endif */ if ( count == 2 ) - { + { /* give it a very last try ... */ disable_subchannel( irq); if ( ioinfo[irq]->ui.flags.busy ) - { + { printk( KERN_CRIT"free_irq(%04X) " "- device %04X busy, retry " "count exceeded\n", - irq, - ioinfo[irq]->devstat.devno); + irq, + ioinfo[irq]->devstat.devno); if (cio_debug_initialized) debug_sprintf_event(cio_debug_msg_id, 0, "free_irq(%04X) - device %04X busy, retry count exceeded\n", irq, ioinfo[irq]->devstat.devno); - } /* endif */ + } /* endif */ break; /* sigh, let's give up ... */ @@ -957,8 +1034,7 @@ int disable_irq(unsigned int irq) int ret; char dbf_txt[15]; - if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - return( -ENODEV); + SANITY_CHECK(irq); if ( !ioinfo[irq]->ui.flags.ready ) return -ENODEV; @@ -984,8 +1060,7 @@ int enable_irq(unsigned int irq) int ret; char dbf_txt[15]; - if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - return( -ENODEV); + SANITY_CHECK(irq); if ( !ioinfo[irq]->ui.flags.ready ) return -ENODEV; @@ -1008,19 +1083,12 @@ int enable_irq(unsigned int irq) */ static int enable_subchannel( unsigned int irq) { - int ret; + int ret = 0; int ccode; int retry = 5; char dbf_txt[15]; - if ( irq > highest_subchannel || irq < 0 ) - { - return( -ENODEV ); - - } /* endif */ - - if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - return( -ENODEV); + SANITY_CHECK(irq); if (cio_debug_initialized) { debug_text_event(cio_debug_trace_id, 2, "ensch"); @@ -1064,19 +1132,12 @@ static int enable_subchannel( unsigned int irq) ccode = msch( irq, &(ioinfo[irq]->schib) ); switch (ccode) { - case 0: + case 0: /* ok */ ret = 0; + retry = 0; break; - case 1: - /* - * very bad, requires interrupt alike - * processing, where "rbh" is a dummy - * parameter for interface compatibility - * only. Bottom-half handling cannot be - * required as this must be an - * unsolicited interrupt (!busy). - */ + case 1: /* status pending */ ioinfo[irq]->ui.flags.s_pend = 1; s390_process_IRQ( irq ); @@ -1084,36 +1145,24 @@ static int enable_subchannel( unsigned int irq) ret = -EIO; /* might be overwritten */ /* ... on re-driving */ - /* ... the msch() */ + /* ... the msch() */ retry--; break; - case 2: + case 2: /* busy */ udelay(100); /* allow for recovery */ ret = -EBUSY; retry--; break; - case 3: + case 3: /* not oper */ ioinfo[irq]->ui.flags.oper = 0; + retry = 0; ret = -ENODEV; break; - - default: - printk( KERN_CRIT"enable_subchannel(%04X) " - " : ccode 2 on msch() for device " - "%04X received !\n", - irq, - ioinfo[irq]->devstat.devno); - if (cio_debug_initialized) - debug_sprintf_event(cio_debug_msg_id, 0, - "enable_subchannel(%04X) : ccode 2 on msch() for device %04X received !\n", - irq, ioinfo[irq]->devstat.devno); - - ret = -ENODEV; // never reached } - } while ( (ccode == 1) && retry ); + } while ( retry ); } /* endif */ @@ -1129,19 +1178,13 @@ static int enable_subchannel( unsigned int irq) static int disable_subchannel( unsigned int irq) { int cc; /* condition code */ - int ret; /* function return value */ + int ret = 0; /* function return value */ int retry = 5; char dbf_txt[15]; - if ( irq > highest_subchannel ) - { - ret = -ENODEV; - } - if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - } - else if ( ioinfo[irq]->ui.flags.busy ) + SANITY_CHECK(irq); + + if ( ioinfo[irq]->ui.flags.busy ) { /* * the disable function must not be called while there are @@ -1180,19 +1223,12 @@ static int disable_subchannel( unsigned int irq) cc = msch( irq, &(ioinfo[irq]->schib) ); switch (cc) { - case 0 : - ret = 0; /* done */ + case 0: /* ok */ + retry = 0; + ret = 0; break; - case 1 : - /* - * very bad, requires interrupt alike - * processing, where "rbh" is a dummy - * parm for interface compatibility - * only. Bottom-half handling cannot - * be required as this must be an - * unsolicited interrupt (!busy). - */ + case 1: /* status pending */ ioinfo[irq]->ui.flags.s_pend = 1; s390_process_IRQ( irq ); ioinfo[irq]->ui.flags.s_pend = 0; @@ -1203,45 +1239,36 @@ static int disable_subchannel( unsigned int irq) retry--; break; - case 2 : - /* - * *** must not occur ! *** - * *** *** - * *** indicates our internal *** - * *** interrupt accounting is out *** - * *** of sync ===> panic() *** - */ + case 2: /* busy; this should not happen! */ printk( KERN_CRIT"disable_subchannel(%04X) " "- unexpected busy condition for " - "device %04X received !\n", + "device %04X received !\n", irq, ioinfo[irq]->devstat.devno); if (cio_debug_initialized) debug_sprintf_event(cio_debug_msg_id, 0, "disable_subchannel(%04X) - unexpected busy condition for device %04X received !\n", irq, ioinfo[irq]->devstat.devno); + retry = 0; ret = -EBUSY; break; - case 3 : + case 3: /* not oper */ /* * should hardly occur ?! */ ioinfo[irq]->ui.flags.oper = 0; ioinfo[irq]->ui.flags.d_disable = 1; + retry = 0; ret = 0; /* if the device has gone we */ /* ... don't need to disable */ - /* ... it anymore ! */ - break; - - default : - ret = -ENODEV; // never reached ... + /* ... it anymore ! */ break; } /* endswitch */ - } while ( (cc == 1) && retry ); + } while ( retry ); } /* endif */ @@ -1282,6 +1309,12 @@ void s390_init_IRQ( void ) s390_process_subchannels(); + if (cio_count_irqs) { + int i; + for (i=0; i<NR_CPUS; i++) + s390_irq_count[i]=0; + } + /* * enable default I/O-interrupt sublass 3 */ @@ -1318,6 +1351,8 @@ int s390_start_IO( int irq, /* IRQ */ char buffer[80]; char dbf_txt[15]; + SANITY_CHECK(irq); + /* * The flag usage is mutal exclusive ... */ @@ -1804,16 +1839,7 @@ int do_IO( int irq, /* IRQ */ int ret = 0; char dbf_txt[15]; - if ( irq > highest_subchannel || irq < 0 ) - { - return( -ENODEV ); - - } /* endif */ - - if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - } + SANITY_CHECK(irq); /* handler registered ? or free_irq() in process already ? */ if ( !ioinfo[irq]->ui.flags.ready || ioinfo[irq]->ui.flags.unready ) @@ -1848,7 +1874,7 @@ int do_IO( int irq, /* IRQ */ * but its intparm must be returned (see halt_IO() processing) */ if ( ioinfo[irq]->ui.flags.w4final - && !ioinfo[irq]->ui.flags.doio_q ) + && !ioinfo[irq]->ui.flags.doio_q ) { ioinfo[irq]->qflag = flag; ioinfo[irq]->qcpa = cpa; @@ -1879,16 +1905,7 @@ int resume_IO( int irq) int ret = 0; char dbf_txt[15]; - if ( irq > highest_subchannel || irq < 0 ) - { - return( -ENODEV ); - - } /* endif */ - - if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - } + SANITY_CHECK(irq); if (cio_debug_initialized) { debug_text_event(cio_debug_trace_id, 4, "resIO"); @@ -1954,20 +1971,12 @@ int halt_IO( int irq, int ccode; char dbf_txt[15]; - if ( irq > highest_subchannel || irq < 0 ) - { - return -ENODEV; - } - - if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - } + SANITY_CHECK(irq); /* * we only allow for halt_IO if the device has an I/O handler associated */ - else if ( !ioinfo[irq]->ui.flags.ready ) + if ( !ioinfo[irq]->ui.flags.ready ) { ret = -ENODEV; } @@ -1979,6 +1988,7 @@ int halt_IO( int irq, { ret = 0; } +#if 0 /* * We don't allow for halt_io with a sync do_IO() requests pending. */ @@ -1987,6 +1997,7 @@ int halt_IO( int irq, { ret = -EBUSY; } +#endif else { if (cio_debug_initialized) { @@ -2141,7 +2152,7 @@ hio_wakeup: * Let the common interrupt handler process the pending * status. However, we must avoid calling the user * action handler, as it won't be prepared to handle - * a pending status during do_IO() processing inline. + * a pending status during do_IO() processing inline. * This also implies that s390_process_IRQ must * terminate synchronously - especially if device * sensing is required. @@ -2216,14 +2227,11 @@ int clear_IO( int irq, unsigned long user_intparm, unsigned long flag) /* possible DOIO_WAIT_FOR_INTERRUPT */ { - int ret; + int ret = 0; int ccode; char dbf_txt[15]; - if ( irq > highest_subchannel || irq < 0 ) - { - return -ENODEV; - } + SANITY_CHECK(irq); if ( ioinfo[irq] == INVALID_STORAGE_AREA ) { @@ -2231,22 +2239,23 @@ int clear_IO( int irq, } /* - * we only allow for halt_IO if the device has an I/O handler associated + * we only allow for clear_IO if the device has an I/O handler associated */ - else if ( !ioinfo[irq]->ui.flags.ready ) + if ( !ioinfo[irq]->ui.flags.ready ) { ret = -ENODEV; } /* - * we ignore the halt_io() request if ending_status was received but + * we ignore the clear_io() request if ending_status was received but * a SENSE operation is waiting for completion. */ else if ( ioinfo[irq]->ui.flags.w4sense ) { ret = 0; } +#if 0 /* - * We don't allow for halt_io with a sync do_IO() requests pending. + * We don't allow for clear_io with a sync do_IO() requests pending. * Concurrent I/O is possible in SMP environments only, but the * sync. I/O request can be gated to one CPU at a time only. */ @@ -2254,6 +2263,7 @@ int clear_IO( int irq, { ret = -EBUSY; } +#endif else { if (cio_debug_initialized) { @@ -2280,7 +2290,7 @@ int clear_IO( int irq, } /* endif */ /* - * Issue "Halt subchannel" and process condition code + * Issue "Clear subchannel" and process condition code */ ccode = csch( irq ); @@ -2361,7 +2371,7 @@ int clear_IO( int irq, | _PSW_IO_WAIT; break; default: - panic( "halt_IO() : unexpected " + panic( "clear_IO() : unexpected " "address-space-control %d\n", ccode); break; @@ -2394,65 +2404,13 @@ cio_wakeup: ret = 0; break; - case 1 : /* status pending */ - - ioinfo[irq]->devstat.flag |= DEVSTAT_STATUS_PENDING; - - /* - * initialize the device driver specific devstat irb area - */ - memset( &ioinfo[irq]->irq_desc.dev_id->ii.irb, - '\0', sizeof( irb_t) ); - - /* - * Let the common interrupt handler process the pending - * status. However, we must avoid calling the user - * action handler, as it won't be prepared to handle - * a pending status during do_IO() processing inline. - * This also implies that s390_process_IRQ must - * terminate synchronously - especially if device - * sensing is required. - */ - ioinfo[irq]->ui.flags.s_pend = 1; - ioinfo[irq]->ui.flags.busy = 1; - ioinfo[irq]->ui.flags.doio = 1; - - s390_process_IRQ( irq ); - - ioinfo[irq]->ui.flags.s_pend = 0; - ioinfo[irq]->ui.flags.busy = 0; - ioinfo[irq]->ui.flags.doio = 0; - ioinfo[irq]->ui.flags.repall = 0; - ioinfo[irq]->ui.flags.w4final = 0; - - ioinfo[irq]->devstat.flag |= DEVSTAT_FINAL_STATUS; - - /* - * In multipath mode a condition code 3 implies the last - * path has gone, except we have previously restricted - * the I/O to a particular path. A condition code 1 - * (0 won't occur) results in return code EIO as well - * as 3 with another path than the one used (i.e. path available mask is non-zero). - */ - if ( ioinfo[irq]->devstat.ii.irb.scsw.cc == 3 ) - { - ret = -ENODEV; - ioinfo[irq]->devstat.flag |= DEVSTAT_NOT_OPER; - ioinfo[irq]->ui.flags.oper = 0; - } - else - { - ret = -EIO; - ioinfo[irq]->devstat.flag &= ~DEVSTAT_NOT_OPER; - ioinfo[irq]->ui.flags.oper = 1; - - } /* endif */ - + case 1 : /* no status pending for csh */ + BUG(); break; - case 2 : /* busy */ - ret = -EBUSY; + case 2 : /* no busy for csh*/ + BUG(); break; default: /* device not operational */ @@ -2572,7 +2530,6 @@ int s390_process_IRQ( unsigned int irq ) unsigned int fctl; /* function control */ unsigned int stctl; /* status control */ unsigned int actl; /* activity control */ - struct pt_regs regs; /* for interface compatibility only */ int issense = 0; int ending_status = 0; @@ -2582,11 +2539,15 @@ int s390_process_IRQ( unsigned int irq ) devstat_t *udp; char dbf_txt[15]; -#if 0 - int cpu = smp_processor_id(); + char buffer[80]; - kstat.irqs[cpu][irq]++; -#endif + + if (cio_count_irqs) { + int cpu = smp_processor_id(); + s390_irq_count[cpu]++; + } + + if (cio_debug_initialized) { debug_text_event(cio_debug_trace_id, 3, "procIRQ"); @@ -2688,9 +2649,28 @@ int s390_process_IRQ( unsigned int irq ) * secondary status are presented with different interrupts. */ if ( dp->ii.irb.scsw.stctl - & ( SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_INTER_STATUS ) ) - { - dp->rescnt = dp->ii.irb.scsw.count; + & ( SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_INTER_STATUS ) ) { + + /* + * If the subchannel status shows status pending + * and we received a check condition, the count + * information is not meaningful. + */ + + if ( !( (dp->ii.irb.scsw.stctl & SCSW_STCTL_STATUS_PEND) + && ( dp->ii.irb.scsw.cstat + & ( SCHN_STAT_CHN_DATA_CHK + | SCHN_STAT_CHN_CTRL_CHK + | SCHN_STAT_INTF_CTRL_CHK + | SCHN_STAT_PROG_CHECK + | SCHN_STAT_PROT_CHECK + | SCHN_STAT_CHAIN_CHECK )))) { + + dp->rescnt = dp->ii.irb.scsw.count; + } else { + dp->rescnt = SENSE_MAX_COUNT; + } + dp->cpa = dp->ii.irb.scsw.cpa; #ifdef CONFIG_DEBUG_IO @@ -2743,13 +2723,13 @@ int s390_process_IRQ( unsigned int irq ) issense=0; } else if ( (dp->ii.irb.scsw.stctl == SCSW_STCTL_STATUS_PEND) - && (dp->ii.irb.scsw.eswf == 0 )) + && (dp->ii.irb.scsw.eswf == 0 )) { issense = 0; } - else if ( (dp->ii.irb.scsw.stctl == - (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_INTER_STATUS)) - && ((dp->ii.irb.scsw.actl & SCSW_ACTL_SUSPENDED) == 0)) + else if ( (dp->ii.irb.scsw.stctl == + (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_INTER_STATUS)) + && ((dp->ii.irb.scsw.actl & SCSW_ACTL_SUSPENDED) == 0) ) { issense = 0; } @@ -2797,8 +2777,6 @@ int s390_process_IRQ( unsigned int irq ) if ( chnchk ) { - char buffer[80]; - sprintf( buffer, "s390_process_IRQ(%04X) - irb for " "device %04X after channel check\n", irq, @@ -2824,8 +2802,8 @@ int s390_process_IRQ( unsigned int irq ) ending_status = ( stctl & SCSW_STCTL_SEC_STATUS ) || ( stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND) ) - || ( (fctl == SCSW_FCTL_HALT_FUNC) && (stctl == SCSW_STCTL_STATUS_PEND) ) - || ( (fctl == SCSW_FCTL_CLEAR_FUNC) && (stctl == SCSW_STCTL_STATUS_PEND) ); + || ( (fctl == SCSW_FCTL_HALT_FUNC) && (stctl == SCSW_STCTL_STATUS_PEND) ) + || ( (fctl == SCSW_FCTL_CLEAR_FUNC) && (stctl == SCSW_STCTL_STATUS_PEND) ); /* * Check for unsolicited interrupts - for debug purposes only @@ -2838,10 +2816,9 @@ int s390_process_IRQ( unsigned int irq ) * unsolicited interrupt applies to the console device * itself ! */ - if ( !( stctl & SCSW_STCTL_ALERT_STATUS ) - && ( ioinfo[irq]->ui.flags.busy == 0 ) ) + if ( !( stctl & SCSW_STCTL_ALERT_STATUS ) + && ( ioinfo[irq]->ui.flags.busy == 0 ) ) { - char buffer[80]; #ifdef CONFIG_DEBUG_IO if (irq != cons_dev) printk( "Unsolicited interrupt received for device %04X on subchannel %04X\n" @@ -2895,7 +2872,7 @@ int s390_process_IRQ( unsigned int irq ) * violates the ESA/390 architecture and doesn't present an * operand exception for virtual devices without concurrent * sense facility available/supported when enabling the - * concurrent sense facility. + * concurrent sense facility. */ if ( ( (dp->ii.irb.scsw.dstat & DEV_STAT_UNIT_CHECK ) && (!issense ) ) @@ -2992,8 +2969,8 @@ int s390_process_IRQ( unsigned int irq ) if ( allow4handler ) { allow4handler = ending_status - || ( ioinfo[irq]->ui.flags.repall ) - || ( stctl & SCSW_STCTL_INTER_STATUS ) + || ( ioinfo[irq]->ui.flags.repall ) + || ( stctl & SCSW_STCTL_INTER_STATUS ) || ( (ioinfo[irq]->ui.flags.fast ) && (stctl & SCSW_STCTL_PRIM_STATUS) ) || ( ioinfo[irq]->ui.flags.oper == 0 ); @@ -3041,20 +3018,10 @@ int s390_process_IRQ( unsigned int irq ) } else { -#if 1 panic( "s390_process_IRQ(%04x) encountered " "negative sense count\n", irq); -#else - printk( KERN_CRIT"s390_process_IRQ(%04x) encountered " - "negative sense count\n", - irq); - if (cio_debug_initialized) - debug_sprintf_event(cio_debug_msg_id, 0, - "s390_process_IRQ(%04x) encountered " - "negative sense count\n", - irq); -#endif + } /* endif */ } else @@ -3063,7 +3030,7 @@ int s390_process_IRQ( unsigned int irq ) } /* endif */ - } /* endif */ + } /* endif */ /* * for status pending situations other than deferred interrupt @@ -3118,7 +3085,7 @@ int s390_process_IRQ( unsigned int irq ) dp->flag |= DEVSTAT_FINAL_STATUS; udp->flag |= DEVSTAT_FINAL_STATUS; - ioinfo[irq]->irq_desc.handler( irq, udp, ®s ); + ioinfo[irq]->irq_desc.handler( irq, udp, NULL ); // // reset intparm after final status or we will badly present unsolicited @@ -3150,7 +3117,7 @@ int s390_process_IRQ( unsigned int irq ) */ if ( ret ) { - ioinfo[irq]->irq_desc.handler( irq, udp, ®s ); + ioinfo[irq]->irq_desc.handler( irq, udp, NULL ); } /* endif */ @@ -3178,7 +3145,7 @@ int s390_process_IRQ( unsigned int irq ) } /* endif */ - ioinfo[irq]->irq_desc.handler( irq, udp, ®s ); + ioinfo[irq]->irq_desc.handler( irq, udp, NULL ); } /* endif */ @@ -3261,7 +3228,7 @@ int s390_process_IRQ( unsigned int irq ) if ( !ioinfo[irq]->ui.flags.s_pend ) { - ioinfo[irq]->irq_desc.handler( irq, udp, ®s ); + ioinfo[irq]->irq_desc.handler( irq, udp, NULL ); } /* endif */ @@ -3298,18 +3265,12 @@ int set_cons_dev( int irq ) int rc = 0; char dbf_txt[15]; + SANITY_CHECK(irq); + if ( cons_dev != -1 ) { rc = -EBUSY; } - else if ( (irq > highest_subchannel) || (irq < 0) ) - { - rc = -ENODEV; - } - else if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - } else { if (cio_debug_initialized) { @@ -3366,18 +3327,12 @@ int reset_cons_dev( int irq) long cr6 __attribute__ ((aligned (8))); char dbf_txt[15]; + SANITY_CHECK(irq); + if ( cons_dev != -1 ) { rc = -EBUSY; } - else if ( (irq > highest_subchannel) || (irq < 0) ) - { - rc = -ENODEV; - } - else if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - } else { if (cio_debug_initialized) { @@ -3496,7 +3451,7 @@ int enable_cpu_sync_isc( int irq ) int ccode; long cr6 __attribute__ ((aligned (8))); - int count = 0; + int retry = 3; int rc = 0; char dbf_txt[15]; @@ -3538,48 +3493,44 @@ int enable_cpu_sync_isc( int irq ) ccode = msch( irq, &(ioinfo[irq]->schib) ); - if (ccode == 0 ) - { + switch (ccode) { + case 0: /* * enable special isc */ - __ctl_store( cr6, 6, 6); - cr6 |= 0x04000000; // enable sync isc 5 - cr6 &= 0xEFFFFFFF; // disable standard isc 3 - __ctl_load( cr6, 6, 6); - } - else if (ccode == 3) - { - rc = -ENODEV; // very unlikely - - } - else if (ccode == 2) - { - rc = -EBUSY; // device busy ... - - } - else if (ccode == 1) - { + __ctl_store( cr6, 6, 6); + cr6 |= 0x04000000; // enable sync isc 5 + cr6 &= 0xEFFFFFFF; // disable standard isc 3 + __ctl_load( cr6, 6, 6); + retry = 0; + break; + + case 1: // // process pending status // ioinfo[irq]->ui.flags.s_pend = 1; - s390_process_IRQ( irq ); - ioinfo[irq]->ui.flags.s_pend = 0; + + rc = -EIO; /* might be overwritten... */ + retry--; + break; - count++; + case 2: /* busy */ + retry = 0; + rc = -EBUSY; + break; - } /* endif */ + case 3: /* not oper*/ + retry = 0; + rc = -ENODEV; + break; + + } - } while ( ccode == 1 && count < 3 ); + } while ( retry ); - if ( count == 3) - { - rc = -EIO; - - } /* endif */ } else { @@ -3651,6 +3602,7 @@ int disable_cpu_sync_isc( int irq) do { + retry2 = 5; do { ccode = msch( irq, &(ioinfo[irq]->schib) ); @@ -3660,27 +3612,33 @@ int disable_cpu_sync_isc( int irq) /* * disable special interrupt subclass in CPU */ - __ctl_store( cr6, 6, 6); - cr6 &= 0xFBFFFFFF; // disable sync isc 5 - cr6 |= 0x10000000; // enable standard isc 3 - __ctl_load( cr6, 6, 6); + __ctl_store( cr6, 6, 6); + cr6 &= 0xFBFFFFFF; // disable sync isc 5 + cr6 |= 0x10000000; // enable standard isc 3 + __ctl_load( cr6, 6, 6); + + retry2 = 0; break; - case 1: + + case 1: /* status pending */ ioinfo[irq]->ui.flags.s_pend = 1; s390_process_IRQ( irq ); ioinfo[irq]->ui.flags.s_pend = 0; + retry2--; break; - case 2: + + case 2: /* busy */ retry2--; udelay( 100); // give it time break; - default: + + default: /* not oper */ retry2 = 0; break; } /* endswitch */ - } while ( retry2 && (ccode != 0) ); + } while ( retry2 ); retry1--; @@ -4073,7 +4031,7 @@ int read_dev_chars( int irq, void **buffer, int length ) ccw1_t *rdc_ccw; devstat_t devstat; char *rdc_buf; - int devflag; + int devflag = 0; int ret = 0; int emulated = 0; @@ -4087,15 +4045,7 @@ int read_dev_chars( int irq, void **buffer, int length ) } /* endif */ - if ( (irq > highest_subchannel) || (irq < 0 ) ) - { - return( -ENODEV ); - - } - else if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - } + SANITY_CHECK(irq); if ( ioinfo[irq]->ui.flags.oper == 0 ) { @@ -4126,7 +4076,7 @@ int read_dev_chars( int irq, void **buffer, int length ) { ret = request_irq( irq, init_IRQ_handler, - 0, "RDC", &devstat ); + SA_PROBE, "RDC", &devstat ); if ( !ret ) { @@ -4159,22 +4109,27 @@ int read_dev_chars( int irq, void **buffer, int length ) rdc_ccw->cmd_code = CCW_CMD_RDC; rdc_ccw->count = length; rdc_ccw->flags = CCW_FLAG_SLI; - set_normalized_cda( rdc_ccw, (unsigned long)rdc_buf ); + ret = set_normalized_cda( rdc_ccw, (unsigned long)rdc_buf ); + if (!ret) { - memset( ioinfo[irq]->irq_desc.dev_id, - '\0', - sizeof( devstat_t)); - - ret = s390_start_IO( irq, - rdc_ccw, - 0x00524443, // RDC - 0, // n/a - DOIO_WAIT_FOR_INTERRUPT - | DOIO_DONT_CALL_INTHDLR ); - retry--; - devflag = ioinfo[irq]->irq_desc.dev_id->flag; - - clear_normalized_cda( rdc_ccw); + memset( ioinfo[irq]->irq_desc.dev_id, + '\0', + sizeof( devstat_t)); + + ret = s390_start_IO( irq, + rdc_ccw, + 0x00524443, // RDC + 0, // n/a + DOIO_WAIT_FOR_INTERRUPT + | DOIO_DONT_CALL_INTHDLR ); + retry--; + devflag = ioinfo[irq]->irq_desc.dev_id->flag; + + clear_normalized_cda( rdc_ccw); + } else { + udelay(100); //wait for recovery + retry--; + } } while ( ( retry ) && ( ret || (devflag & DEVSTAT_STATUS_PENDING) ) ); @@ -4183,7 +4138,7 @@ int read_dev_chars( int irq, void **buffer, int length ) if ( !retry ) { - ret = -EBUSY; + ret = (ret==-ENOMEM)?-ENOMEM:-EBUSY; } /* endif */ @@ -4222,15 +4177,9 @@ int read_conf_data( int irq, void **buffer, int *length, __u8 lpm ) char dbf_txt[15]; - if ( (irq > highest_subchannel) || (irq < 0 ) ) - { - return( -ENODEV ); - } - else if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - } - else if ( !buffer || !length ) + SANITY_CHECK(irq); + + if ( !buffer || !length ) { return( -EINVAL); } @@ -4267,11 +4216,11 @@ int read_conf_data( int irq, void **buffer, int *length, __u8 lpm ) } /* endif */ - break; + break; - } /* endif */ + } /* endif */ - } /* endfor */ + } /* endfor */ if ( found ) { @@ -4292,7 +4241,7 @@ int read_conf_data( int irq, void **buffer, int *length, __u8 lpm ) pdevstat = &devstat; ret = request_irq( irq, init_IRQ_handler, - 0, "RCD", pdevstat ); + SA_PROBE, "RCD", pdevstat ); if ( !ret ) { @@ -4358,30 +4307,29 @@ int read_conf_data( int irq, void **buffer, int *length, __u8 lpm ) 0x00524344, // == RCD lpm, ioflags ); + switch ( ret ) { + case 0: + case -EIO: + + if ( !(pdevstat->flag & ( DEVSTAT_STATUS_PENDING + | DEVSTAT_NOT_OPER + | DEVSTAT_FLAG_SENSE_AVAIL ) ) ) + { + retry = 0; // we got it ... + } + else + { + retry--; // try again ... + + } /* endif */ + + break; - switch ( ret ) { - case 0 : - case -EIO : - - if ( !(pdevstat->flag & ( DEVSTAT_STATUS_PENDING - | DEVSTAT_NOT_OPER - | DEVSTAT_FLAG_SENSE_AVAIL ) ) ) - { - retry = 0; // we got it ... - } - else - { - retry--; // try again ... - - } /* endif */ - - break; - - default : // -EBUSY, -ENODEV, ??? - retry = 0; - - } /* endswitch */ - + default: // -EBUSY, -ENODEV, ??? + retry = 0; + + } /* endswitch */ + } while ( retry ); } /* endif */ @@ -4440,31 +4388,16 @@ int get_dev_info( int irq, s390_dev_info_t * pdi) static int __inline__ get_next_available_irq( ioinfo_t *pi) { - int ret_val; + int ret_val = -ENODEV; - while ( TRUE ) - { - if ( pi->ui.flags.oper ) - { + while ( pi!=NULL ) { + if ( pi->ui.flags.oper ) { ret_val = pi->irq; break; - } - else - { + } else { pi = pi->next; - - // - // leave at end of list unconditionally - // - if ( pi == NULL ) - { - ret_val = -ENODEV; - break; - } - - } /* endif */ - - } /* endwhile */ + } + } return ret_val; } @@ -4536,54 +4469,44 @@ int get_irq_next( int irq ) int get_dev_info_by_irq( int irq, s390_dev_info_t *pdi) { - if ( irq > highest_subchannel || irq < 0 ) - { - return -ENODEV; - } - else if ( pdi == NULL ) - { + SANITY_CHECK(irq); + + if ( pdi == NULL ) return -EINVAL; + + pdi->devno = ioinfo[irq]->schib.pmcw.dev; + pdi->irq = irq; + + if ( ioinfo[irq]->ui.flags.oper + && !ioinfo[irq]->ui.flags.unknown ) + { + pdi->status = 0; + memcpy( &(pdi->sid_data), + &ioinfo[irq]->senseid, + sizeof( senseid_t)); } - else if ( ioinfo[irq] == INVALID_STORAGE_AREA ) + else if ( ioinfo[irq]->ui.flags.unknown ) { - return( -ENODEV); + pdi->status = DEVSTAT_UNKNOWN_DEV; + memset( &(pdi->sid_data), + '\0', + sizeof( senseid_t)); + pdi->sid_data.cu_type = 0xFFFF; + } else { - pdi->devno = ioinfo[irq]->schib.pmcw.dev; - pdi->irq = irq; - - if ( ioinfo[irq]->ui.flags.oper - && !ioinfo[irq]->ui.flags.unknown ) - { - pdi->status = 0; - memcpy( &(pdi->sid_data), - &ioinfo[irq]->senseid, - sizeof( senseid_t)); - } - else if ( ioinfo[irq]->ui.flags.unknown ) - { - pdi->status = DEVSTAT_UNKNOWN_DEV; - memset( &(pdi->sid_data), - '\0', - sizeof( senseid_t)); - pdi->sid_data.cu_type = 0xFFFF; - - } - else - { - pdi->status = DEVSTAT_NOT_OPER; - memset( &(pdi->sid_data), - '\0', - sizeof( senseid_t)); - pdi->sid_data.cu_type = 0xFFFF; - - } /* endif */ - - if ( ioinfo[irq]->ui.flags.ready ) - pdi->status |= DEVSTAT_DEVICE_OWNED; - + pdi->status = DEVSTAT_NOT_OPER; + memset( &(pdi->sid_data), + '\0', + sizeof( senseid_t)); + pdi->sid_data.cu_type = 0xFFFF; + } /* endif */ + + if ( ioinfo[irq]->ui.flags.ready ) + pdi->status |= DEVSTAT_DEVICE_OWNED; + return 0; } @@ -4595,70 +4518,60 @@ int get_dev_info_by_devno( __u16 devno, s390_dev_info_t *pdi) int rc = -ENODEV; if ( devno > 0x0000ffff ) - { return -ENODEV; - } - else if ( pdi == NULL ) - { + if ( pdi == NULL ) return -EINVAL; - } - else - { - for ( i=0; i <= highest_subchannel; i++ ) + for ( i=0; i <= highest_subchannel; i++ ) { + + if ( ioinfo[i] != INVALID_STORAGE_AREA + && ioinfo[i]->schib.pmcw.dev == devno ) { - - if ( ioinfo[i] != INVALID_STORAGE_AREA - && ioinfo[i]->schib.pmcw.dev == devno ) + + pdi->irq = i; + pdi->devno = devno; + + if ( ioinfo[i]->ui.flags.oper + && !ioinfo[i]->ui.flags.unknown ) { + pdi->status = 0; + memcpy( &(pdi->sid_data), + &ioinfo[i]->senseid, + sizeof( senseid_t)); + } + else if ( ioinfo[i]->ui.flags.unknown ) + { + pdi->status = DEVSTAT_UNKNOWN_DEV; - pdi->irq = i; - pdi->devno = devno; - - if ( ioinfo[i]->ui.flags.oper - && !ioinfo[i]->ui.flags.unknown ) - { - pdi->status = 0; - - memcpy( &(pdi->sid_data), - &ioinfo[i]->senseid, - sizeof( senseid_t)); - } - else if ( ioinfo[i]->ui.flags.unknown ) - { - pdi->status = DEVSTAT_UNKNOWN_DEV; - - memset( &(pdi->sid_data), - '\0', - sizeof( senseid_t)); + memset( &(pdi->sid_data), + '\0', + sizeof( senseid_t)); - pdi->sid_data.cu_type = 0xFFFF; - } - else - { - pdi->status = DEVSTAT_NOT_OPER; - - memset( &(pdi->sid_data), - '\0', - sizeof( senseid_t)); - - pdi->sid_data.cu_type = 0xFFFF; + pdi->sid_data.cu_type = 0xFFFF; + } + else + { + pdi->status = DEVSTAT_NOT_OPER; + + memset( &(pdi->sid_data), + '\0', + sizeof( senseid_t)); - } /* endif */ + pdi->sid_data.cu_type = 0xFFFF; - if ( ioinfo[i]->ui.flags.ready ) - pdi->status |= DEVSTAT_DEVICE_OWNED; + } /* endif */ - rc = 0; /* found */ - break; + if ( ioinfo[i]->ui.flags.ready ) + pdi->status |= DEVSTAT_DEVICE_OWNED; - } /* endif */ + rc = 0; /* found */ + break; - } /* endfor */ + } /* endif */ - return( rc); + } /* endfor */ - } /* endif */ + return( rc); } @@ -4742,7 +4655,7 @@ void s390_device_recognition_irq( int irq ) irq_ret = request_irq( irq, init_IRQ_handler, - 0, + SA_PROBE, "INIT", &devstat); @@ -4804,7 +4717,6 @@ void s390_device_recognition_irq( int irq ) } /* endif */ #endif - s390_DevicePathVerification( irq, 0 ); disable_cpu_sync_isc( irq ); @@ -5040,8 +4952,8 @@ int s390_validate_subchannel( int irq, int enable ) { ioinfo_t *pi = ioinfo_head; - do - { + for (pi=ioinfo_head; pi!=NULL; pi=pi->next) { + if ( irq < pi->next->irq ) { ioinfo[irq]->next = pi->next; @@ -5051,11 +4963,7 @@ int s390_validate_subchannel( int irq, int enable ) break; } /* endif */ - - pi = pi->next; - - } while ( 1 ); - + } } /* endif */ } /* endif */ @@ -5303,20 +5211,13 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) int io_retry; /* retry indicator */ senseid_t *psid = sid;/* start with the external buffer */ - int sbuffer = 0; /* switch SID data buffer */ + int sbuffer = 0; /* switch SID data buffer */ char dbf_txt[15]; - if ( (irq > highest_subchannel) || (irq < 0 ) ) - { - return( -ENODEV ); + int failure = 0; /* nothing went wrong yet */ - } - else if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - - } /* endif */ + SANITY_CHECK(irq); if ( ioinfo[irq]->ui.flags.oper == 0 ) { @@ -5330,6 +5231,8 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) debug_text_event(cio_debug_trace_id, 4, dbf_txt); } + inlreq = 0; /* to make the compiler quiet... */ + if ( !ioinfo[irq]->ui.flags.ready ) { @@ -5341,7 +5244,7 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) * requests and evaluate the devstat area on return therefore * we don't need a real I/O handler in place. */ - irq_ret = request_irq( irq, init_IRQ_handler, 0, "SID", &devstat); + irq_ret = request_irq( irq, init_IRQ_handler, SA_PROBE, "SID", &devstat); if ( irq_ret == 0 ) inlreq = 1; @@ -5403,6 +5306,9 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) if ( domask ) { + failure = 0; + + psid->reserved = 0; psid->cu_type = 0xFFFF; /* initialize fields ... */ psid->cu_model = 0; psid->dev_type = 0; @@ -5423,23 +5329,18 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) irq_ret = s390_start_IO( irq, sense_ccw, 0x00E2C9C4, // == SID - domask, + domask, DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT | DOIO_VALID_LPM | DOIO_DONT_CALL_INTHDLR ); - // - // The OSA_E FE card possibly causes -ETIMEDOUT - // conditions, as the SenseID may stay start - // pending. This will cause start_IO() to finally - // halt the operation we should retry. If the halt - // fails this may cause -EBUSY we simply retry - // and eventually clean up with free_irq(). - // if ( psid->cu_type == 0xFFFF ) { + + failure = 1; + if ( pdevstat->flag & DEVSTAT_STATUS_PENDING ) { #ifdef CONFIG_DEBUG_IO @@ -5448,7 +5349,7 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) "reports pending status, " "retry : %d\n", ioinfo[irq]->schib.pmcw.dev, - irq, + irq, retry); #endif if (cio_debug_initialized) @@ -5487,7 +5388,7 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) "intervention required\n", ioinfo[irq]->schib.pmcw.dev, irq); - io_retry = 1; + io_retry = 0; } else @@ -5514,7 +5415,7 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) pdevstat->ii.sense.data[6], pdevstat->ii.sense.data[7]); #endif - if (cio_debug_initialized) + if (cio_debug_initialized) { debug_sprintf_event(cio_debug_msg_id, 2, "SenseID : UC on " "dev %04X, " @@ -5536,11 +5437,16 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) pdevstat->ii.sense.data[5], pdevstat->ii.sense.data[6], pdevstat->ii.sense.data[7]); + if (psid->reserved != 0xFF) + debug_sprintf_event(cio_debug_msg_id, 2, + "SenseID was not properly " + "executed!\n"); + } } /* endif */ } else if ( ( pdevstat->flag & DEVSTAT_NOT_OPER ) - || ( irq_ret == -ENODEV ) ) + || ( irq_ret == -ENODEV ) ) { #ifdef CONFIG_DEBUG_IO printk( "SenseID : path %02X for " @@ -5566,11 +5472,11 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) } - else if ( (pdevstat->flag != - ( DEVSTAT_START_FUNCTION - | DEVSTAT_FINAL_STATUS ) ) - && !(pdevstat->flag & - DEVSTAT_STATUS_PENDING ) ) + else if ( ( pdevstat->flag != + ( DEVSTAT_START_FUNCTION + | DEVSTAT_FINAL_STATUS ) ) + && !( pdevstat->flag & + DEVSTAT_STATUS_PENDING ) ) { #ifdef CONFIG_DEBUG_IO printk( "SenseID : start_IO() for " @@ -5602,45 +5508,54 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) } else // we got it ... { - if ( !sbuffer ) // switch buffers - { - /* - * we report back the - * first hit only - */ - psid = &isid; + if (psid->reserved != 0xFF) { + /* No, we failed after all... */ + failure = 1; + retry--; - if ( ioinfo[irq]->schib.pmcw.pim != 0x80 ) + } else { + + if ( !sbuffer ) // switch buffers { - sense_ccw[1].cda = (__u32)virt_to_phys( psid ); - } - else - { - sense_ccw[0].cda = (__u32)virt_to_phys( psid ); - + /* + * we report back the + * first hit only + */ + psid = &isid; + + if ( ioinfo[irq]->schib.pmcw.pim != 0x80 ) + { + sense_ccw[1].cda = (__u32)virt_to_phys( psid ); + } + else + { + sense_ccw[0].cda = (__u32)virt_to_phys( psid ); + + } /* endif */ + + /* + * if just the very first + * was requested to be + * sensed disable further + * scans. + */ + if ( !lpm ) + lpm = domask; + + sbuffer = 1; + } /* endif */ - /* - * if just the very first - * was requested to be - * sensed disable further - * scans. - */ - if ( !lpm ) - lpm = domask; - - sbuffer = 1; - - } /* endif */ - - if ( pdevstat->rescnt < (sizeof( senseid_t) - 8) ) - { - ioinfo[irq]->ui.flags.esid = 1; + if ( pdevstat->rescnt < (sizeof( senseid_t) - 8) ) + { + ioinfo[irq]->ui.flags.esid = 1; - } /* endif */ + } /* endif */ - io_retry = 0; + io_retry = 0; + } + } /* endif */ if ( io_retry ) @@ -5654,7 +5569,19 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) } /* endif */ } /* endif */ - + + if ((failure) && (io_retry)) { + /* reset fields... */ + + failure = 0; + + psid->reserved = 0; + psid->cu_type = 0xFFFF; + psid->cu_model = 0; + psid->dev_type = 0; + psid->dev_model = 0; + } + } while ( (io_retry) ); } /* endif - domask */ @@ -5685,7 +5612,7 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) * only if we suffered a command reject, but it doesn't harm */ if ( ( sid->cu_type == 0xFFFF ) - && ( MACHINE_IS_VM ) ) + && ( MACHINE_IS_VM ) ) { VM_virtual_device_info( ioinfo[irq]->schib.pmcw.dev, sid ); @@ -5715,9 +5642,9 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) } /* endif */ - /* - * Issue device info message if unit was operational . - */ + /* + * Issue device info message if unit was operational . + */ if ( !ioinfo[irq]->ui.flags.unknown ) { if ( sid->dev_type != 0 ) { if ( cio_show_msg ) @@ -5791,10 +5718,11 @@ static int __inline__ s390_SetMultiPath( int irq ) * available. Further, a path group ID is set, if possible in multipath * mode, otherwise in single path mode. * + * Note : This function must not be called during normal device recognition, + * but during device driver initiated request_irq() processing only. */ int s390_DevicePathVerification( int irq, __u8 usermask ) { -#if 1 int ccode; __u8 pathmask; __u8 domask; @@ -5971,9 +5899,7 @@ int s390_DevicePathVerification( int irq, __u8 usermask ) } /* endif */ return ret; -#else - return 0; -#endif + } /* @@ -5995,16 +5921,7 @@ int s390_SetPGID( int irq, __u8 lpm, pgid_t *pgid ) int inlreq = 0; /* inline request_irq() */ int mpath = 1; /* try multi-path first */ - if ( (irq > highest_subchannel) || (irq < 0 ) ) - { - return( -ENODEV ); - - } - else if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - - } /* endif */ + SANITY_CHECK(irq); if ( ioinfo[irq]->ui.flags.oper == 0 ) { @@ -6015,14 +5932,14 @@ int s390_SetPGID( int irq, __u8 lpm, pgid_t *pgid ) if ( !ioinfo[irq]->ui.flags.ready ) { /* - * Perform SENSE ID command processing. We have to request device + * Perform SetPGID command processing. We have to request device * ownership and provide a dummy I/O handler. We issue sync. I/O * requests and evaluate the devstat area on return therefore * we don't need a real I/O handler in place. */ irq_ret = request_irq( irq, init_IRQ_handler, - 0, + SA_PROBE, "SPID", pdevstat); @@ -6062,7 +5979,7 @@ int s390_SetPGID( int irq, __u8 lpm, pgid_t *pgid ) pgid->inf.fc = SPID_FUNC_MULTI_PATH | SPID_FUNC_ESTABLISH; /* - * We now issue a SenseID request. In case of BUSY + * We now issue a SetPGID request. In case of BUSY * or STATUS PENDING conditions we retry 5 times. */ do @@ -6099,12 +6016,15 @@ int s390_SetPGID( int irq, __u8 lpm, pgid_t *pgid ) ioinfo[irq]->schib.pmcw.dev, irq, retry); + retry--; + irq_ret = -EIO; } /* endif */ if ( pdevstat->flag == ( DEVSTAT_START_FUNCTION | DEVSTAT_FINAL_STATUS ) ) { retry = 0; // successfully set ... + irq_ret = 0; } else if ( pdevstat->flag & DEVSTAT_FLAG_SENSE_AVAIL ) { @@ -6121,6 +6041,7 @@ int s390_SetPGID( int irq, __u8 lpm, pgid_t *pgid ) | SPID_FUNC_ESTABLISH; mpath = 0; retry--; + irq_ret = -EIO; } else { @@ -6170,6 +6091,7 @@ int s390_SetPGID( int irq, __u8 lpm, pgid_t *pgid ) pdevstat->ii.sense.data[7]); retry--; + irq_ret = -EIO; } /* endif */ @@ -6201,20 +6123,17 @@ int s390_SetPGID( int irq, __u8 lpm, pgid_t *pgid ) else if ( irq_ret != -ENODEV ) { retry--; + irq_ret = -EIO; } else { retry = 0; + irq_ret = -ENODEV; } /* endif */ } while ( retry > 0 ); - if ( retry == 0 ) - { - irq_ret = -EIO; - - } /* endif */ if ( init_IRQ_complete ) { @@ -6256,17 +6175,9 @@ int s390_SensePGID( int irq, __u8 lpm, pgid_t *pgid ) int irq_ret = 0; /* return code */ int retry = 5; /* retry count */ int inlreq = 0; /* inline request_irq() */ + unsigned long flags; - if ( (irq > highest_subchannel) || (irq < 0 ) ) - { - return( -ENODEV ); - - } - else if ( ioinfo[irq] == INVALID_STORAGE_AREA ) - { - return( -ENODEV); - - } /* endif */ + SANITY_CHECK(irq); if ( ioinfo[irq]->ui.flags.oper == 0 ) { @@ -6277,14 +6188,14 @@ int s390_SensePGID( int irq, __u8 lpm, pgid_t *pgid ) if ( !ioinfo[irq]->ui.flags.ready ) { /* - * Perform SENSE ID command processing. We have to request device + * Perform SENSE PGID command processing. We have to request device * ownership and provide a dummy I/O handler. We issue sync. I/O * requests and evaluate the devstat area on return therefore * we don't need a real I/O handler in place. */ irq_ret = request_irq( irq, init_IRQ_handler, - 0, + SA_PROBE, "SNID", pdevstat); @@ -6300,7 +6211,7 @@ int s390_SensePGID( int irq, __u8 lpm, pgid_t *pgid ) if ( irq_ret == 0 ) { - s390irq_spin_lock( irq); + s390irq_spin_lock_irqsave( irq, flags); if ( init_IRQ_complete ) { @@ -6318,7 +6229,7 @@ int s390_SensePGID( int irq, __u8 lpm, pgid_t *pgid ) snid_ccw->flags = CCW_FLAG_SLI; /* - * We now issue a SenseID request. In case of BUSY + * We now issue a SensePGID request. In case of BUSY * or STATUS PENDING conditions we retry 5 times. */ do @@ -6391,6 +6302,7 @@ int s390_SensePGID( int irq, __u8 lpm, pgid_t *pgid ) pdevstat->ii.sense.data[6], pdevstat->ii.sense.data[7]); retry--; + irq_ret = -EIO; } /* endif */ } @@ -6413,11 +6325,13 @@ int s390_SensePGID( int irq, __u8 lpm, pgid_t *pgid ) } retry = 0; + irq_ret = -EIO; } else { retry = 0; // success ... + irq_ret = 0; } /* endif */ } @@ -6458,20 +6372,17 @@ int s390_SensePGID( int irq, __u8 lpm, pgid_t *pgid ) ioinfo[irq]->schib.pmcw.dev, irq_ret); retry--; + irq_ret = -EIO; } else // -ENODEV ... { retry = 0; + irq_ret = -ENODEV; } /* endif */ } while ( retry > 0 ); - if ( retry == 0 ) - { - irq_ret = -EIO; - - } /* endif */ if ( init_IRQ_complete ) { @@ -6483,7 +6394,7 @@ int s390_SensePGID( int irq, __u8 lpm, pgid_t *pgid ) } /* endif */ - s390irq_spin_unlock( irq); + s390irq_spin_unlock_irqrestore( irq, flags); /* * If we installed the irq action handler we have to @@ -6585,12 +6496,25 @@ void s390_do_crw_pending( crwe_t *pcrwe ) if ( ioinfo[irq] != INVALID_STORAGE_AREA ) { #ifdef CONFIG_DEBUG_CRW - printk( "do_crw_pending : ioinfo at %08X\n", + printk( "do_crw_pending : ioinfo at " +#ifdef CONFIG_ARCH_S390X + "%08lX\n", + (unsigned long)ioinfo[irq]); +#else /* CONFIG_ARCH_S390X */ + "%08X\n", (unsigned)ioinfo[irq]); +#endif /* CONFIG_ARCH_S390X */ #endif if (cio_debug_initialized) debug_sprintf_event(cio_debug_crw_id, 4, - "ioinfo at %08X\n"); + "ioinfo at " +#ifdef CONFIG_ARCH_S390X + "%08lX\n", + (unsigned long)ioinfo[irq]); +#else /* CONFIG_ARCH_S390X */ + "%08X\n", + (unsigned)ioinfo[irq]); +#endif /* CONFIG_ARCH_S390X */ } /* endif */ @@ -6892,7 +6816,7 @@ static int chan_subch_open( struct inode *inode, struct file *file) ioinfo[i]->senseid.cu_model ); } else { len += sprintf( info->data+len, - "%04X/%02X ", + " %04X/%02X", ioinfo[i]->senseid.cu_type, ioinfo[i]->senseid.cu_model ); } @@ -7034,30 +6958,6 @@ static ssize_t cio_device_entry_read( struct file *file, char *user_buf, size_t } } -int cio_search_devno_by_inode(struct inode *inode) -{ - int devno = -1; - struct proc_dir_entry *pde; - cio_procfs_device_t *tmp; - - pde = (struct proc_dir_entry *)inode->u.generic_ip; - tmp = cio_procfs_device_list; - - while (tmp) { - if ((tmp->entry->cio_device_entry == pde) || - (tmp->entry->cio_sensedata_entry == pde) || - (tmp->entry->cio_in_use_entry == pde) || - (tmp->entry->cio_chpid_entry == pde)) - break; - tmp = tmp->next; - } - - if (tmp) - devno = tmp->entry->devno; - - return devno; -} - static int cio_sensedata_entry_open( struct inode *inode, struct file *file) { @@ -7067,6 +6967,7 @@ static int cio_sensedata_entry_open( struct inode *inode, struct file *file) tempinfo_t *info; int irq; int devno; + char * devno_str; info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t)); if (info == NULL) { @@ -7081,23 +6982,24 @@ static int cio_sensedata_entry_open( struct inode *inode, struct file *file) vfree(info); rc = -ENOMEM; } else { - devno = cio_search_devno_by_inode(inode); - if (devno != 0xFFFF) { - irq = get_irq_by_devno(devno); - if (irq != -1) { - len += sprintf(info->data+len, "Dev Type/Mod: "); - if (ioinfo[irq]->senseid.dev_type == 0) { - len += sprintf(info->data+len, "%04X/%02X\n", - ioinfo[irq]->senseid.cu_type, - ioinfo[irq]->senseid.cu_model); - } else { - len += sprintf(info->data+len, "%04X/%02X\n", - ioinfo[irq]->senseid.dev_type, - ioinfo[irq]->senseid.dev_model); - len+= sprintf(info->data+len, "CU Type/Mod: %04X/%02X\n", - ioinfo[irq]->senseid.cu_type, - ioinfo[irq]->senseid.cu_model); - } + devno_str = kmalloc(6*sizeof(char), GFP_KERNEL); + memset(devno_str, 0, 6*sizeof(char)); + memcpy(devno_str,file->f_dentry->d_parent->d_name.name, strlen(file->f_dentry->d_parent->d_name.name)+1); + devno = simple_strtoul(devno_str, &devno_str, 16); + irq = get_irq_by_devno(devno); + if (irq != -1) { + len += sprintf(info->data+len, "Dev Type/Mod: "); + if (ioinfo[irq]->senseid.dev_type == 0) { + len += sprintf(info->data+len, "%04X/%02X\n", + ioinfo[irq]->senseid.cu_type, + ioinfo[irq]->senseid.cu_model); + } else { + len += sprintf(info->data+len, "%04X/%02X\n", + ioinfo[irq]->senseid.dev_type, + ioinfo[irq]->senseid.dev_model); + len+= sprintf(info->data+len, "CU Type/Mod: %04X/%02X\n", + ioinfo[irq]->senseid.cu_type, + ioinfo[irq]->senseid.cu_model); } } info->len = len; @@ -7115,6 +7017,7 @@ static int cio_in_use_entry_open( struct inode *inode, struct file *file) tempinfo_t *info; int irq; int devno; + char * devno_str; info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t)); if (info == NULL) { @@ -7129,12 +7032,13 @@ static int cio_in_use_entry_open( struct inode *inode, struct file *file) vfree(info); rc = -ENOMEM; } else { - devno = cio_search_devno_by_inode(inode); - if (devno != -1) { - irq = get_irq_by_devno(devno); - if (irq != -1) { - len += sprintf(info->data+len, "%s\n", ioinfo[irq]->ui.flags.ready?"yes":"no"); - } + devno_str = kmalloc(6*sizeof(char), GFP_KERNEL); + memset(devno_str, 0, 6*sizeof(char)); + memcpy(devno_str,file->f_dentry->d_parent->d_name.name, strlen(file->f_dentry->d_parent->d_name.name)+1); + devno = simple_strtoul(devno_str, &devno_str, 16); + irq = get_irq_by_devno(devno); + if (irq != -1) { + len += sprintf(info->data+len, "%s\n", ioinfo[irq]->ui.flags.ready?"yes":"no"); } info->len = len; } @@ -7152,6 +7056,7 @@ static int cio_chpid_entry_open( struct inode *inode, struct file *file) int irq; int devno; int i; + char * devno_str; info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t)); if (info == NULL) { @@ -7166,14 +7071,15 @@ static int cio_chpid_entry_open( struct inode *inode, struct file *file) vfree(info); rc = -ENOMEM; } else { - devno = cio_search_devno_by_inode(inode); - if (devno != -1) { - irq = get_irq_by_devno(devno); - if (irq != -1) { - for (i=0; i<8; i++) { - len += sprintf(info->data+len, "CHPID[%d]: ", i); - len += sprintf(info->data+len, "%02X\n", ioinfo[irq]->schib.pmcw.chpid[i]); - } + devno_str = kmalloc(6*sizeof(char), GFP_KERNEL); + memset(devno_str, 0, 6*sizeof(char)); + memcpy(devno_str,file->f_dentry->d_parent->d_name.name, strlen(file->f_dentry->d_parent->d_name.name)+1); + devno = simple_strtoul(devno_str, &devno_str, 16); + irq = get_irq_by_devno(devno); + if (irq != -1) { + for (i=0; i<8; i++) { + len += sprintf(info->data+len, "CHPID[%d]: ", i); + len += sprintf(info->data+len, "%02X\n", ioinfo[irq]->schib.pmcw.chpid[i]); } } info->len = len; @@ -7377,6 +7283,8 @@ __initcall(cio_procfs_create); * un-ignore devices by piping to /proc/cio_ignore: * free all frees all blacklisted devices, free <range>,<range>,... * frees specified ranges of devnos + * add <range>,<range>,... will add a range of devices to blacklist - + * but only for devices not already known */ static struct proc_dir_entry *cio_ignore_proc_entry; @@ -7388,6 +7296,7 @@ static int cio_ignore_proc_open(struct inode *inode, struct file *file) int len = 0; tempinfo_t *info; dev_blacklist_range_t *tmp; + long flags; info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t)); if (info == NULL) { @@ -7402,6 +7311,7 @@ static int cio_ignore_proc_open(struct inode *inode, struct file *file) vfree (info); rc = -ENOMEM; } else { + spin_lock_irqsave( &blacklist_lock, flags ); tmp = dev_blacklist_range_head; while (tmp) { len += sprintf(info->data+len, "%04x ", tmp->from); @@ -7410,6 +7320,7 @@ static int cio_ignore_proc_open(struct inode *inode, struct file *file) len += sprintf(info->data+len, "\n"); tmp = tmp->next; } + spin_unlock_irqrestore( &blacklist_lock, flags ); info->len = len; } } @@ -7487,6 +7398,98 @@ static int cio_ignore_proc_init(void) __initcall(cio_ignore_proc_init); +/* + * Entry /proc/irq_count + * display how many irqs have occured per cpu... + */ + +static struct proc_dir_entry *cio_irq_proc_entry; + +static int cio_irq_proc_open(struct inode *inode, struct file *file) +{ + int rc = 0; + int size = 1; + int len = 0; + tempinfo_t *info; + int i; + + info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t)); + if (info == NULL) { + printk( KERN_WARNING "No memory available for data\n"); + rc = -ENOMEM; + } else { + file->private_data = (void *) info; + size += NR_CPUS * 16; + info->data = (char *) vmalloc(size); + if (size && info->data == NULL) { + printk( KERN_WARNING "No memory available for data\n"); + vfree (info); + rc = -ENOMEM; + } else { + for (i=0; i< NR_CPUS; i++) { + if (s390_irq_count[i] != 0) + len += sprintf(info->data+len, "%lx\n", s390_irq_count[i]); + } + info->len = len; + } + } + return rc; +} + +static int cio_irq_proc_close(struct inode *inode, struct file *file) +{ + int rc = 0; + tempinfo_t *p_info = (tempinfo_t *) file->private_data; + + if (p_info) { + if (p_info->data) + vfree(p_info->data); + vfree(p_info); + } + + return rc; +} + +static ssize_t cio_irq_proc_read( struct file *file, char *user_buf, size_t user_len, loff_t * offset) +{ + loff_t len; + tempinfo_t *p_info = (tempinfo_t *) file->private_data; + + if ( *offset>=p_info->len) { + return 0; + } else { + len = MIN(user_len, (p_info->len - *offset)); + if (copy_to_user( user_buf, &(p_info->data[*offset]), len)) + return -EFAULT; + (* offset) += len; + return len; + } +} + +static struct file_operations cio_irq_proc_file_ops = + { + read: cio_irq_proc_read, + open: cio_irq_proc_open, + release: cio_irq_proc_close, + }; + +static int cio_irq_proc_init(void) +{ + + int i; + + if (cio_count_irqs) { + for (i=0; i<NR_CPUS; i++) + s390_irq_count[i]=0; + cio_irq_proc_entry = create_proc_entry("irq_count", S_IFREG|S_IRUGO, &proc_root); + cio_irq_proc_entry->proc_fops = &cio_irq_proc_file_ops; + } + + return 1; +} + +__initcall(cio_irq_proc_init); + /* end of procfs stuff */ schib_t *s390_get_schib( int irq ) diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 1f116d052eba..6d2fc1508ad0 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -106,6 +106,8 @@ MODULE_AUTHOR ("3ware Inc."); MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver"); +MODULE_LICENSE("GPL"); + #include <linux/kernel.h> #include <linux/pci.h> diff --git a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c index e4ef976fa547..097f6d6ebe45 100644 --- a/drivers/scsi/53c7,8xx.c +++ b/drivers/scsi/53c7,8xx.c @@ -215,9 +215,7 @@ #include <linux/version.h> -#ifdef MODULE #include <linux/module.h> -#endif #include <asm/dma.h> #include <asm/io.h> @@ -6429,6 +6427,7 @@ NCR53c7x0_release(struct Scsi_Host *host) { return 1; } #endif /* def MODULE */ +MODULE_LICENSE("GPL"); static Scsi_Host_Template driver_template = NCR53c7xx; #include "scsi_module.c" diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index ea77fd0d541d..98079cc72994 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -51,6 +51,19 @@ /* CHANGELOG * + * Version 2.5 + * + * More Compatibility changes for 710 (now actually works). Enhanced + * support for odd clock speeds which constrain SDTR negotiations. + * correct cacheline separation for scsi messages and status for + * incoherent architectures. Use of the pci mapping functions on + * buffers to begin support for 64 bit drivers. + * + * Version 2.4 + * + * Added support for the 53c710 chip (in 53c700 emulation mode only---no + * special 53c710 instructions or registers are used). + * * Version 2.3 * * More endianness/cache coherency changes. @@ -77,7 +90,7 @@ * Initial modularisation from the D700. See NCR_D700.c for the rest of * the changelog. * */ -#define NCR_700_VERSION "2.3" +#define NCR_700_VERSION "2.5" #include <linux/config.h> #include <linux/version.h> @@ -98,6 +111,7 @@ #include <asm/byteorder.h> #include <linux/blk.h> #include <linux/module.h> +#include <linux/pci.h> #include "scsi.h" #include "hosts.h" @@ -105,6 +119,14 @@ #include "53c700.h" +/* NOTE: For 64 bit drivers there are points in the code where we use + * a non dereferenceable pointer to point to a structure in dma-able + * memory (which is 32 bits) so that we can use all of the structure + * operations but take the address at the end. This macro allows us + * to truncate the 64 bit pointer down to 32 bits without the compiler + * complaining */ +#define to32bit(x) ((__u32)((unsigned long)(x))) + #ifdef NCR_700_DEBUG #define STATIC #else @@ -195,12 +217,19 @@ struct Scsi_Host * __init NCR_700_detect(Scsi_Host_Template *tpnt, struct NCR_700_Host_Parameters *hostdata) { - __u32 *script = kmalloc(sizeof(SCRIPT), GFP_KERNEL); - __u32 pScript; + dma_addr_t pScript, pSlots; + __u32 *script; struct Scsi_Host *host; static int banner = 0; int j; + /* This separation of pScript and script is not strictly + * necessay, but may be useful in architectures which can + * allocate consistent memory on which virt_to_bus will not + * work */ + script = kmalloc(sizeof(SCRIPT), GFP_KERNEL); + pScript = virt_to_bus(script); + /* Fill in the missing routines from the host template */ tpnt->queuecommand = NCR_700_queuecommand; tpnt->eh_abort_handler = NCR_700_abort; @@ -228,40 +257,57 @@ NCR_700_detect(Scsi_Host_Template *tpnt, return NULL; } - hostdata->slots = kmalloc(sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST, GFP_KERNEL); - if(hostdata->slots == NULL) { - printk(KERN_ERR "53c700: Failed to allocate command slots, detatching\n"); + /* This separation of slots and pSlots may facilitate later + * migration to consistent memory on architectures which + * support it */ + hostdata->slots = kmalloc(sizeof(struct NCR_700_command_slot) + * NCR_700_COMMAND_SLOTS_PER_HOST, + GFP_KERNEL); + pSlots = virt_to_bus(hostdata->slots); + + hostdata->msgin = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL); + hostdata->msgout = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL); + hostdata->status = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL); + if(hostdata->slots == NULL || hostdata->msgin == NULL + || hostdata->msgout == NULL || hostdata->status==NULL) { + printk(KERN_ERR "53c700: Failed to allocate command slots or message buffers, detatching\n"); scsi_unregister(host); return NULL; } - memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST); + memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot) + * NCR_700_COMMAND_SLOTS_PER_HOST); for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) { + dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0] + - (unsigned long)&hostdata->slots[0].SG[0]); + hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset)); if(j == 0) hostdata->free_list = &hostdata->slots[j]; else hostdata->slots[j-1].ITL_forw = &hostdata->slots[j]; hostdata->slots[j].state = NCR_700_SLOT_FREE; } - host->hostdata[0] = (__u32)hostdata; + for(j = 0; j < sizeof(SCRIPT)/sizeof(SCRIPT[0]); j++) { script[j] = bS_to_host(SCRIPT[j]); } - /* bus physical address of script */ - pScript = virt_to_bus(script); + /* adjust all labels to be bus physical */ for(j = 0; j < PATCHES; j++) { script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]); } - /* now patch up fixed addresses */ + /* now patch up fixed addresses. + * NOTE: virt_to_bus may be wrong if consistent memory is used + * for these in the future */ script_patch_32(script, MessageLocation, virt_to_bus(&hostdata->msgout[0])); script_patch_32(script, StatusAddress, - virt_to_bus(&hostdata->status)); + virt_to_bus(&hostdata->status[0])); script_patch_32(script, ReceiveMsgAddress, virt_to_bus(&hostdata->msgin[0])); hostdata->script = script; hostdata->pScript = pScript; + dma_cache_wback((unsigned long)script, sizeof(SCRIPT)); hostdata->state = NCR_700_HOST_FREE; spin_lock_init(&hostdata->lock); hostdata->cmd = NULL; @@ -272,19 +318,22 @@ NCR_700_detect(Scsi_Host_Template *tpnt, host->hostdata[0] = (unsigned long)hostdata; /* kick the chip */ NCR_700_writeb(0xff, host, CTEST9_REG); - hostdata->rev = (NCR_700_readb(host, CTEST7_REG)<<4) & 0x0f; + if(hostdata->chip710) + hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f; + else + hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f; hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0); if(banner == 0) { printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n"); banner = 1; } printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no, - hostdata->fast ? "53c700-66" : "53c700", + hostdata->chip710 ? "53c710" : + (hostdata->fast ? "53c700-66" : "53c700"), hostdata->rev, hostdata->differential ? "(Differential)" : ""); /* reset the chip */ NCR_700_chip_reset(host); - NCR_700_writeb(ASYNC_OPERATION , host, SXFER_REG); return host; } @@ -295,7 +344,13 @@ NCR_700_release(struct Scsi_Host *host) struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0]; + /* NOTE: these may be NULL if we weren't fully initialised before + * the scsi_unregister was called */ kfree(hostdata->script); + kfree(hostdata->slots); + kfree(hostdata->msgin); + kfree(hostdata->msgout); + kfree(hostdata->status); return 1; } @@ -308,24 +363,32 @@ NCR_700_identify(int can_disconnect, __u8 lun) } /* - * Function : static int datapath_residual (Scsi_Host *host) + * Function : static int data_residual (Scsi_Host *host) * * Purpose : return residual data count of what's in the chip. If you * really want to know what this function is doing, it's almost a * direct transcription of the algorithm described in the 53c710 * guide, except that the DBC and DFIFO registers are only 6 bits - * wide. + * wide on a 53c700. * * Inputs : host - SCSI host */ static inline int NCR_700_data_residual (struct Scsi_Host *host) { - int count, synchronous; + struct NCR_700_Host_Parameters *hostdata = + (struct NCR_700_Host_Parameters *)host->hostdata[0]; + int count, synchronous = 0; unsigned int ddir; - count = ((NCR_700_readb(host, DFIFO_REG) & 0x3f) - - (NCR_700_readl(host, DBC_REG) & 0x3f)) & 0x3f; + if(hostdata->chip710) { + count = ((NCR_700_readb(host, DFIFO_REG) & 0x7f) - + (NCR_700_readl(host, DBC_REG) & 0x7f)) & 0x7f; + } else { + count = ((NCR_700_readb(host, DFIFO_REG) & 0x3f) - + (NCR_700_readl(host, DBC_REG) & 0x3f)) & 0x3f; + } - synchronous = NCR_700_readb(host, SXFER_REG) & 0x0f; + if(hostdata->fast) + synchronous = NCR_700_readb(host, SXFER_REG) & 0x0f; /* get the data direction */ ddir = NCR_700_readb(host, CTEST0_REG) & 0x01; @@ -345,6 +408,10 @@ NCR_700_data_residual (struct Scsi_Host *host) { if (synchronous && (sstat & SODR_REG_FULL)) ++count; } +#ifdef NCR_700_DEBUG + if(count) + printk("RESIDUAL IS %d (ddir %d)\n", count, ddir); +#endif return count; } @@ -530,21 +597,26 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata, __u8 offset, __u8 period) { int XFERP; - - if(period*4 < NCR_700_MIN_PERIOD) { - printk(KERN_WARNING "53c700: Period %dns is less than SCSI-2 minimum, setting to %d\n", period*4, NCR_700_MIN_PERIOD); - period = NCR_700_MIN_PERIOD/4; + __u8 min_xferp = (hostdata->chip710 + ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP); + __u8 max_offset = (hostdata->chip710 + ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET); + /* NOTE: NCR_700_SDTR_msg[3] contains our offer of the minimum + * period. It is set in NCR_700_chip_setup() */ + if(period < NCR_700_SDTR_msg[3]) { + printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4); + period = NCR_700_SDTR_msg[3]; } XFERP = (period*4 * hostdata->sync_clock)/1000 - 4; - if(offset > NCR_700_MAX_OFFSET) { - printk(KERN_WARNING "53c700: Offset %d exceeds maximum, setting to %d\n", - offset, NCR_700_MAX_OFFSET); - offset = NCR_700_MAX_OFFSET; + if(offset > max_offset) { + printk(KERN_WARNING "53c700: Offset %d exceeds chip maximum, setting to %d\n", + offset, max_offset); + offset = max_offset; } - if(XFERP < NCR_700_MIN_XFERP) { + if(XFERP < min_xferp) { printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n", - XFERP, NCR_700_MIN_XFERP); - XFERP = NCR_700_MIN_XFERP; + XFERP, min_xferp); + XFERP = min_xferp; } return (offset & 0x0f) | (XFERP & 0x07)<<4; } @@ -563,14 +635,28 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) { #ifdef NCR_700_DEBUG - printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is", + printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", SCp, SCp->cmnd[7], result); print_sense("53c700", SCp); #endif if(result == 0) result = SCp->cmnd[7]; } - + + if(SCp->sc_data_direction != SCSI_DATA_NONE && + SCp->sc_data_direction != SCSI_DATA_UNKNOWN) { + int pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction); + if(SCp->use_sg) { + pci_unmap_sg(hostdata->pci_dev, SCp->buffer, + SCp->use_sg, pci_direction); + } else { + pci_unmap_single(hostdata->pci_dev, + slot->dma_handle, + SCp->request_bufflen, + pci_direction); + } + } + free_slot(slot, hostdata); SCp->host_scribble = NULL; @@ -602,19 +688,47 @@ NCR_700_chip_setup(struct Scsi_Host *host) { struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0]; + __u32 dcntl_extra = 0; + __u8 min_period; + __u8 min_xferp = (hostdata->chip710 ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP); + + if(hostdata->chip710) { + __u8 burst_disable = hostdata->burst_disable + ? BURST_DISABLE : 0; + dcntl_extra = COMPAT_700_MODE; + + NCR_700_writeb(dcntl_extra, host, DCNTL_REG); + NCR_700_writeb(BURST_LENGTH_8 | hostdata->dmode_extra, + host, DMODE_710_REG); + NCR_700_writeb(burst_disable | (hostdata->differential ? + DIFF : 0), host, CTEST7_REG); + NCR_700_writeb(BTB_TIMER_DISABLE, host, CTEST0_REG); + NCR_700_writeb(FULL_ARBITRATION | ENABLE_PARITY | PARITY + | AUTO_ATN, host, SCNTL0_REG); + } else { + NCR_700_writeb(BURST_LENGTH_8 | hostdata->dmode_extra, + host, DMODE_700_REG); + NCR_700_writeb(hostdata->differential ? + DIFF : 0, host, CTEST7_REG); + if(hostdata->fast) { + /* this is for 700-66, does nothing on 700 */ + NCR_700_writeb(LAST_DIS_ENBL | ENABLE_ACTIVE_NEGATION + | GENERATE_RECEIVE_PARITY, host, + CTEST8_REG); + } else { + NCR_700_writeb(FULL_ARBITRATION | ENABLE_PARITY + | PARITY | AUTO_ATN, host, SCNTL0_REG); + } + } NCR_700_writeb(1 << host->this_id, host, SCID_REG); NCR_700_writeb(0, host, SBCL_REG); - NCR_700_writeb(0, host, SXFER_REG); + NCR_700_writeb(ASYNC_OPERATION, host, SXFER_REG); NCR_700_writeb(PHASE_MM_INT | SEL_TIMEOUT_INT | GROSS_ERR_INT | UX_DISC_INT | RST_INT | PAR_ERR_INT | SELECT_INT, host, SIEN_REG); NCR_700_writeb(ABORT_INT | INT_INST_INT | ILGL_INST_INT, host, DIEN_REG); - NCR_700_writeb(BURST_LENGTH_8, host, DMODE_REG); - NCR_700_writeb(FULL_ARBITRATION | PARITY | AUTO_ATN, host, SCNTL0_REG); - NCR_700_writeb(LAST_DIS_ENBL | ENABLE_ACTIVE_NEGATION|GENERATE_RECEIVE_PARITY, - host, CTEST8_REG); NCR_700_writeb(ENABLE_SELECT, host, SCNTL1_REG); if(hostdata->clock > 75) { printk(KERN_ERR "53c700: Clock speed %dMHz is too high: 75Mhz is the maximum this chip can be driven at\n", hostdata->clock); @@ -622,13 +736,13 @@ NCR_700_chip_setup(struct Scsi_Host *host) * of spec: sync divider 2, async divider 3 */ DEBUG(("53c700: sync 2 async 3\n")); NCR_700_writeb(SYNC_DIV_2_0, host, SBCL_REG); - NCR_700_writeb(ASYNC_DIV_3_0, host, DCNTL_REG); + NCR_700_writeb(ASYNC_DIV_3_0 | dcntl_extra, host, DCNTL_REG); hostdata->sync_clock = hostdata->clock/2; } else if(hostdata->clock > 50 && hostdata->clock <= 75) { /* sync divider 1.5, async divider 3 */ DEBUG(("53c700: sync 1.5 async 3\n")); NCR_700_writeb(SYNC_DIV_1_5, host, SBCL_REG); - NCR_700_writeb(ASYNC_DIV_3_0, host, DCNTL_REG); + NCR_700_writeb(ASYNC_DIV_3_0 | dcntl_extra, host, DCNTL_REG); hostdata->sync_clock = hostdata->clock*2; hostdata->sync_clock /= 3; @@ -636,30 +750,49 @@ NCR_700_chip_setup(struct Scsi_Host *host) /* sync divider 1, async divider 2 */ DEBUG(("53c700: sync 1 async 2\n")); NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG); - NCR_700_writeb(ASYNC_DIV_2_0, host, DCNTL_REG); + NCR_700_writeb(ASYNC_DIV_2_0 | dcntl_extra, host, DCNTL_REG); hostdata->sync_clock = hostdata->clock; } else if(hostdata->clock > 25 && hostdata->clock <=37) { /* sync divider 1, async divider 1.5 */ DEBUG(("53c700: sync 1 async 1.5\n")); NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG); - NCR_700_writeb(ASYNC_DIV_1_5, host, DCNTL_REG); + NCR_700_writeb(ASYNC_DIV_1_5 | dcntl_extra, host, DCNTL_REG); hostdata->sync_clock = hostdata->clock; } else { DEBUG(("53c700: sync 1 async 1\n")); NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG); - NCR_700_writeb(ASYNC_DIV_1_0, host, DCNTL_REG); + NCR_700_writeb(ASYNC_DIV_1_0 | dcntl_extra, host, DCNTL_REG); /* sync divider 1, async divider 1 */ + hostdata->sync_clock = hostdata->clock; + } + /* Calculate the actual minimum period that can be supported + * by our synchronous clock speed. See the 710 manual for + * exact details of this calculation which is based on a + * setting of the SXFER register */ + min_period = 1000*(4+min_xferp)/(4*hostdata->sync_clock); + if(min_period > NCR_700_MIN_PERIOD) { + NCR_700_SDTR_msg[3] = min_period; } + if(hostdata->chip710) + NCR_700_SDTR_msg[4] = NCR_710_MAX_OFFSET; } STATIC void NCR_700_chip_reset(struct Scsi_Host *host) { - /* Chip reset */ - NCR_700_writeb(SOFTWARE_RESET, host, DCNTL_REG); - udelay(100); + struct NCR_700_Host_Parameters *hostdata = + (struct NCR_700_Host_Parameters *)host->hostdata[0]; + if(hostdata->chip710) { + NCR_700_writeb(SOFTWARE_RESET_710, host, ISTAT_REG); + udelay(100); - NCR_700_writeb(0, host, DCNTL_REG); + NCR_700_writeb(0, host, ISTAT_REG); + } else { + NCR_700_writeb(SOFTWARE_RESET, host, DCNTL_REG); + udelay(100); + + NCR_700_writeb(0, host, DCNTL_REG); + } mdelay(1000); @@ -717,7 +850,7 @@ process_extended_message(struct Scsi_Host *host, printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n", host->host_no); hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout)); + dma_cache_wback((unsigned long)hostdata->msgout, 1); script_patch_16(hostdata->script, MessageCount, 1); /* SendMsgOut returns, so set up the return * address */ @@ -729,7 +862,7 @@ process_extended_message(struct Scsi_Host *host, printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n", host->host_no, pun, lun); hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout)); + dma_cache_wback((unsigned long)hostdata->msgout, 1); script_patch_16(hostdata->script, MessageCount, 1); resume_offset = hostdata->pScript + Ent_SendMessageWithATN; @@ -743,7 +876,7 @@ process_extended_message(struct Scsi_Host *host, printk("\n"); /* just reject it */ hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout)); + dma_cache_wback((unsigned long)hostdata->msgout, 1); script_patch_16(hostdata->script, MessageCount, 1); /* SendMsgOut returns, so set up the return * address */ @@ -761,8 +894,6 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata __u32 temp = dsp + 8, resume_offset = dsp; __u8 pun = 0xff, lun = 0xff; - dma_cache_inv((unsigned long)hostdata->msgin, sizeof(hostdata->msgin)); - if(SCp != NULL) { pun = SCp->target; lun = SCp->lun; @@ -778,8 +909,9 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata switch(hostdata->msgin[0]) { case A_EXTENDED_MSG: - return process_extended_message(host, hostdata, SCp, - dsp, dsps); + resume_offset = process_extended_message(host, hostdata, SCp, + dsp, dsps); + break; case A_REJECT_MSG: if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) { @@ -792,6 +924,8 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun); NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); hostdata->tag_negotiated &= ~(1<<SCp->target); + SCp->device->tagged_queue = 0; + SCp->device->tagged_supported = 0; } else { printk(KERN_WARNING "scsi%d (%d:%d) Unexpected REJECT Message %s\n", host->host_no, pun, lun, @@ -820,7 +954,7 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata printk("\n"); /* just reject it */ hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout)); + dma_cache_wback((unsigned long)hostdata->msgout, 1); script_patch_16(hostdata->script, MessageCount, 1); /* SendMsgOut returns, so set up the return * address */ @@ -829,6 +963,8 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata break; } NCR_700_writel(temp, host, TEMP_REG); + /* set us up to receive another message */ + dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE); return resume_offset; } @@ -846,25 +982,26 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, } if(dsps == A_GOOD_STATUS_AFTER_STATUS) { - dma_cache_inv((unsigned long)hostdata->status, sizeof(hostdata->status)); DEBUG((" COMMAND COMPLETE, status=%02x\n", - hostdata->status)); + hostdata->status[0])); /* OK, if TCQ still on, we know it works */ NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); /* check for contingent allegiance contitions */ - if(status_byte(hostdata->status) == CHECK_CONDITION || - status_byte(hostdata->status) == COMMAND_TERMINATED) { + if(status_byte(hostdata->status[0]) == CHECK_CONDITION || + status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { struct NCR_700_command_slot *slot = (struct NCR_700_command_slot *)SCp->host_scribble; if(SCp->cmnd[0] == REQUEST_SENSE) { /* OOPS: bad device, returning another * contingent allegiance condition */ printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun); - NCR_700_scsi_done(hostdata, SCp, hostdata->status); + NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); } else { - - DEBUG((" cmd %p has status %d, requesting sense\n", - SCp, hostdata->status)); +#ifdef NCR_DEBUG + print_command(SCp->cmnd); + printk(" cmd %p has status %d, requesting sense\n", + SCp, hostdata->status[0]); +#endif /* we can destroy the command here because the * contingent allegiance condition will cause a * retry which will re-copy the command from the @@ -881,7 +1018,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, * was an internal sense request and the original * status at the end of the command */ SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; - SCp->cmnd[7] = hostdata->status; + SCp->cmnd[7] = hostdata->status[0]; + SCp->sc_data_direction = SCSI_DATA_READ; + dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len); slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); slot->SG[0].pAddr = bS_to_host(virt_to_bus(SCp->sense_buffer)); slot->SG[1].ins = bS_to_host(SCRIPT_RETURN); @@ -896,20 +1035,27 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, hostdata->cmd = NULL; } } else { - if(status_byte(hostdata->status) == GOOD && - SCp->cmnd[0] == INQUIRY && SCp->use_sg == 0) { - /* Piggy back the tag queueing support - * on this command */ - if(((char *)SCp->request_buffer)[7] & 0x02) { - printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun); - hostdata->tag_negotiated |= (1<<SCp->target); - NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); - } else { - NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); - hostdata->tag_negotiated &= ~(1<<SCp->target); - } - } - NCR_700_scsi_done(hostdata, SCp, hostdata->status); + // Currently rely on the mid layer evaluation + // of the tag queuing capability + // + //if(status_byte(hostdata->status[0]) == GOOD && + // SCp->cmnd[0] == INQUIRY && SCp->use_sg == 0) { + // /* Piggy back the tag queueing support + // * on this command */ + // pci_dma_sync_single(hostdata->pci_dev, + // slot->dma_handle, + // SCp->request_bufflen, + // PCI_DMA_FROMDEVICE); + // if(((char *)SCp->request_buffer)[7] & 0x02) { + // printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun); + // hostdata->tag_negotiated |= (1<<SCp->target); + // NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); + // } else { + // NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); + // hostdata->tag_negotiated &= ~(1<<SCp->target); + // } + //} + NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); } } else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) { __u8 i = (dsps & 0xf00) >> 8; @@ -947,8 +1093,6 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, struct NCR_700_command_slot *slot; __u8 reselection_id = hostdata->reselection_id; - dma_cache_inv((unsigned long)hostdata->msgin, sizeof(hostdata->msgin)); - lun = hostdata->msgin[0] & 0x1f; hostdata->reselection_id = 0xff; @@ -996,7 +1140,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, script_patch_16(hostdata->script, CommandCount, slot->cmnd->cmd_len); script_patch_32_abs(hostdata->script, SGScriptStartAddress, - virt_to_bus(&slot->SG[0].ins)); + to32bit(&slot->pSG[0].ins)); /* Note: setting SXFER only works if we're * still in the MESSAGE phase, so it is vital @@ -1005,6 +1149,16 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, * should therefore always clear ACK */ NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device), host, SXFER_REG); + dma_cache_inv((unsigned long)hostdata->msgin, + MSG_ARRAY_SIZE); + dma_cache_wback((unsigned long)hostdata->msgout, + MSG_ARRAY_SIZE); + /* I'm just being paranoid here, the command should + * already have been flushed from the cache */ + dma_cache_wback((unsigned long)slot->cmnd->cmnd, + slot->cmnd->cmd_len); + + } } else if(dsps == A_RESELECTED_DURING_SELECTION) { @@ -1022,20 +1176,22 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, /* Take out our own ID */ reselection_id &= ~(1<<host->this_id); - printk(KERN_INFO "scsi%d: (%d:%d) RESELECTION DURING SELECTION, dsp=%p[%04x] state=%d, count=%d\n", - host->host_no, reselection_id, lun, (void *)dsp, dsp - hostdata->pScript, hostdata->state, hostdata->command_slot_count); + /* I've never seen this happen, so keep this as a printk rather + * than a debug */ + printk(KERN_INFO "scsi%d: (%d:%d) RESELECTION DURING SELECTION, dsp=%08x[%04x] state=%d, count=%d\n", + host->host_no, reselection_id, lun, dsp, dsp - hostdata->pScript, hostdata->state, hostdata->command_slot_count); { /* FIXME: DEBUGGING CODE */ - __u32 SG = (__u32)bus_to_virt(hostdata->script[A_SGScriptStartAddress_used[0]]); + __u32 SG = (__u32)bS_to_cpu(hostdata->script[A_SGScriptStartAddress_used[0]]); int i; for(i=0; i< NCR_700_COMMAND_SLOTS_PER_HOST; i++) { - if(SG >= (__u32)(&hostdata->slots[i].SG[0]) - && SG <= (__u32)(&hostdata->slots[i].SG[NCR_700_SG_SEGMENTS])) + if(SG >= to32bit(&hostdata->slots[i].pSG[0]) + && SG <= to32bit(&hostdata->slots[i].pSG[NCR_700_SG_SEGMENTS])) break; } - printk(KERN_INFO "IDENTIFIED SG segment as being %p in slot %p, cmd %p, slot->resume_offset=%p\n", (void *)SG, &hostdata->slots[i], hostdata->slots[i].cmnd, (void *)hostdata->slots[i].resume_offset); + printk(KERN_INFO "IDENTIFIED SG segment as being %08x in slot %p, cmd %p, slot->resume_offset=%08x\n", SG, &hostdata->slots[i], hostdata->slots[i].cmnd, hostdata->slots[i].resume_offset); SCp = hostdata->slots[i].cmnd; } @@ -1061,8 +1217,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, reselection_id = bitmap_to_number(reselection_id); } hostdata->reselection_id = reselection_id; + /* just in case we have a stale simple tag message, clear it */ hostdata->msgin[1] = 0; - dma_cache_wback((unsigned long)hostdata->msgin, sizeof(hostdata->msgin)); + dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE); if(hostdata->tag_negotiated & (1<<reselection_id)) { resume_offset = hostdata->pScript + Ent_GetReselectionWithTag; } else { @@ -1092,8 +1249,8 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, } NCR_700_internal_bus_reset(host); } else if((dsps & 0xfffff000) == A_DEBUG_INTERRUPT) { - printk(KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %p[%04x], continuing\n", - host->host_no, pun, lun, dsps & 0xfff, (void *)dsp, dsp - hostdata->pScript); + printk(KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %08x[%04x], continuing\n", + host->host_no, pun, lun, dsps & 0xfff, dsp, dsp - hostdata->pScript); resume_offset = dsp; } else { printk(KERN_ERR "scsi%d: (%d:%d), unidentified script interrupt 0x%x at %04x\n", @@ -1122,7 +1279,8 @@ process_selection(struct Scsi_Host *host, __u32 dsp) __u8 sbcl; for(count = 0; count < 5; count++) { - id = NCR_700_readb(host, SFBR_REG); + id = NCR_700_readb(host, hostdata->chip710 ? + CTEST9_REG : SFBR_REG); /* Take out our own ID */ id &= ~(1<<host->this_id); @@ -1174,8 +1332,9 @@ process_selection(struct Scsi_Host *host, __u32 dsp) } hostdata->state = NCR_700_HOST_BUSY; hostdata->cmd = NULL; + /* clear any stale simple tag message */ hostdata->msgin[1] = 0; - dma_cache_wback((unsigned long)hostdata->msgin, sizeof(hostdata->msgin)); + dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE); if(id == 0xff) { /* Selected as target, Ignore */ @@ -1188,6 +1347,32 @@ process_selection(struct Scsi_Host *host, __u32 dsp) return resume_offset; } +static inline void +NCR_700_clear_fifo(struct Scsi_Host *host) { + const struct NCR_700_Host_Parameters *hostdata + = (struct NCR_700_Host_Parameters *)host->hostdata[0]; + if(hostdata->chip710) { + NCR_700_writeb(CLR_FIFO_710, host, CTEST8_REG); + } else { + NCR_700_writeb(CLR_FIFO, host, DFIFO_REG); + } +} + +static inline void +NCR_700_flush_fifo(struct Scsi_Host *host) { + const struct NCR_700_Host_Parameters *hostdata + = (struct NCR_700_Host_Parameters *)host->hostdata[0]; + if(hostdata->chip710) { + NCR_700_writeb(FLUSH_DMA_FIFO_710, host, CTEST8_REG); + udelay(10); + NCR_700_writeb(0, host, CTEST8_REG); + } else { + NCR_700_writeb(FLUSH_DMA_FIFO, host, DFIFO_REG); + udelay(10); + NCR_700_writeb(0, host, DFIFO_REG); + } +} + STATIC int NCR_700_start_command(Scsi_Cmnd *SCp) @@ -1227,9 +1412,10 @@ NCR_700_start_command(Scsi_Cmnd *SCp) NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); } - /* REQUEST_SENSE is asking for contingent I_T_L status. If a - * contingent allegiance condition exists, the device will - * refuse all tags, so send the request sense as untagged */ + /* REQUEST_SENSE is asking for contingent I_T_L(_Q) status. + * If a contingent allegiance condition exists, the device + * will refuse all tags, so send the request sense as untagged + * */ if((hostdata->tag_negotiated & (1<<SCp->target)) && (slot->tag != NCR_700_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) { hostdata->msgout[count++] = A_SIMPLE_TAG_MSG; @@ -1244,8 +1430,6 @@ NCR_700_start_command(Scsi_Cmnd *SCp) NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } - dma_cache_wback((unsigned long)hostdata->msgout, count); - script_patch_16(hostdata->script, MessageCount, count); @@ -1258,20 +1442,27 @@ NCR_700_start_command(Scsi_Cmnd *SCp) /* finally plumb the beginning of the SG list into the script * */ script_patch_32_abs(hostdata->script, SGScriptStartAddress, - virt_to_bus(&slot->SG[0].ins)); - NCR_700_writeb(CLR_FIFO, SCp->host, DFIFO_REG); + to32bit(&slot->pSG[0].ins)); + NCR_700_clear_fifo(SCp->host); - /* set the synchronous period/offset */ if(slot->resume_offset == 0) slot->resume_offset = hostdata->pScript; + /* now perform all the writebacks and invalidates */ + dma_cache_wback((unsigned long)hostdata->msgout, count); + dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE); + dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len); + dma_cache_inv((unsigned long)hostdata->status, 1); + + /* set the synchronous period/offset */ NCR_700_writeb(NCR_700_get_SXFER(SCp->device), - SCp->host, SXFER_REG); + SCp->host, SXFER_REG); + NCR_700_writel(slot->temp, SCp->host, TEMP_REG); + NCR_700_writel(slot->resume_offset, SCp->host, DSP_REG); + /* allow interrupts here so that if we're selected we can take * a selection interrupt. The script start may not be * effective in this case, but the selection interrupt will * save our command in that case */ - NCR_700_writel(slot->temp, SCp->host, TEMP_REG); - NCR_700_writel(slot->resume_offset, SCp->host, DSP_REG); restore_flags(flags); return 1; @@ -1342,8 +1533,8 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) hostdata->state = NCR_700_HOST_BUSY; - printk(KERN_ERR "scsi%d: Bus Reset detected, executing command %p, slot %p, dsp %p[%04x]\n", - host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, (void *)dsp, dsp - hostdata->pScript); + printk(KERN_ERR "scsi%d: Bus Reset detected, executing command %p, slot %p, dsp %08x[%04x]\n", + host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, dsp, dsp - hostdata->pScript); /* clear all the negotiated parameters */ for(SDp = host->host_queue; SDp != NULL; SDp = SDp->next) @@ -1396,13 +1587,15 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG))); #endif resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch; - } else if(dsp >= virt_to_bus(&slot->SG[0].ins) && - dsp <= virt_to_bus(&slot->SG[NCR_700_SG_SEGMENTS].ins)) { + } else if(dsp >= to32bit(&slot->pSG[0].ins) && + dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) { int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff; - int SGcount = (dsp - virt_to_bus(&slot->SG[0].ins))/sizeof(struct NCR_700_SG_List); + int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List); int residual = NCR_700_data_residual(host); int i; #ifdef NCR_700_DEBUG + __u32 naddr = NCR_700_readl(host, DNAD_REG); + printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n", host->host_no, pun, lun, SGcount, data_transfer); @@ -1427,6 +1620,11 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) slot->SG[SGcount].ins |= bS_to_host(data_transfer); pAddr = bS_to_cpu(slot->SG[SGcount].pAddr); pAddr += (count - data_transfer); +#ifdef NCR_700_DEBUG + if(pAddr != naddr) { + printk("scsi%d (%d:%d) transfer mismatch pAddr=%lx, naddr=%lx, data_transfer=%d, residual=%d\n", host->host_no, pun, lun, (unsigned long)pAddr, (unsigned long)naddr, data_transfer, residual); + } +#endif slot->SG[SGcount].pAddr = bS_to_host(pAddr); } /* set the executed moves to nops */ @@ -1438,6 +1636,8 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) /* and pretend we disconnected after * the command phase */ resume_offset = hostdata->pScript + Ent_MsgInDuringData; + /* make sure all the data is flushed */ + NCR_700_flush_fifo(host); } else { __u8 sbcl = NCR_700_readb(host, SBCL_REG); printk(KERN_ERR "scsi%d: (%d:%d) phase mismatch at %04x, phase %s\n", @@ -1449,15 +1649,19 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) printk(KERN_ERR "scsi%d: (%d:%d) GROSS ERROR\n", host->host_no, pun, lun); NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16); + } else if(sstat0 & PARITY_ERROR) { + printk(KERN_ERR "scsi%d: (%d:%d) PARITY ERROR\n", + host->host_no, pun, lun); + NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16); } else if(dstat & SCRIPT_INT_RECEIVED) { DEBUG(("scsi%d: (%d:%d) ====>SCRIPT INTERRUPT<====\n", host->host_no, pun, lun)); resume_offset = process_script_interrupt(dsps, dsp, SCp, host, hostdata); } else if(dstat & (ILGL_INST_DETECTED)) { - printk(KERN_ERR "scsi%d: (%d:%d) Illegal Instruction detected at 0x%p[0x%x]!!!\n" + printk(KERN_ERR "scsi%d: (%d:%d) Illegal Instruction detected at 0x%08x[0x%x]!!!\n" " Please email James.Bottomley@HansenPartnership.com with the details\n", host->host_no, pun, lun, - (void *)dsp, dsp - hostdata->pScript); + dsp, dsp - hostdata->pScript); NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16); } else if(dstat & (WATCH_DOG_INTERRUPT|ABORTED)) { printk(KERN_ERR "scsi%d: (%d:%d) serious DMA problem, dstat=%02x\n", @@ -1495,13 +1699,13 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) if(resume_offset) { if(hostdata->state != NCR_700_HOST_BUSY) { - printk(KERN_ERR "scsi%d: Driver error: resume at %p [%04x] with non busy host!\n", - host->host_no, (void *)resume_offset, resume_offset - hostdata->pScript); + printk(KERN_ERR "scsi%d: Driver error: resume at 0x%08x [0x%04x] with non busy host!\n", + host->host_no, resume_offset, resume_offset - hostdata->pScript); hostdata->state = NCR_700_HOST_BUSY; } DEBUG(("Attempting to resume at %x\n", resume_offset)); - NCR_700_writeb(CLR_FIFO, host, DFIFO_REG); + NCR_700_clear_fifo(host); NCR_700_writel(resume_offset, host, DSP_REG); } /* There is probably a technical no-no about this: If we're a @@ -1579,6 +1783,7 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *)) struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)SCp->host->hostdata[0]; __u32 move_ins; + int pci_direction; struct NCR_700_command_slot *slot; int hash; @@ -1618,6 +1823,20 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *)) printk("53c700: scsi%d, command ", SCp->host->host_no); print_command(SCp->cmnd); #endif + if(SCp->device->tagged_supported && !SCp->device->tagged_queue + && (hostdata->tag_negotiated &(1<<SCp->target)) == 0 + && NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) { + /* upper layer has indicated tags are supported. We don't + * necessarily believe it yet. + * + * NOTE: There is a danger here: the mid layer supports + * tag queuing per LUN. We only support it per PUN because + * of potential reselection issues */ + printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->target, SCp->lun); + hostdata->tag_negotiated |= (1<<SCp->target); + NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); + SCp->device->tagged_queue = 1; + } if(hostdata->tag_negotiated &(1<<SCp->target)) { @@ -1681,36 +1900,11 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *)) hostdata->ITL_Hash_back[hash] = slot; slot->ITL_back = NULL; - - /* This is f****g ridiculous; every low level HBA driver has - * to determine the direction of the commands, why isn't this - * done inside the scsi_lib !!??? */ switch (SCp->cmnd[0]) { case REQUEST_SENSE: /* clear the internal sense magic */ SCp->cmnd[6] = 0; /* fall through */ - case INQUIRY: - case MODE_SENSE: - case READ_6: - case READ_10: - case READ_12: - case READ_CAPACITY: - case READ_BLOCK_LIMITS: - case READ_TOC: - move_ins = SCRIPT_MOVE_DATA_IN; - break; - case MODE_SELECT: - case WRITE_6: - case WRITE_10: - case WRITE_12: - move_ins = SCRIPT_MOVE_DATA_OUT; - break; - case TEST_UNIT_READY: - case ALLOW_MEDIUM_REMOVAL: - case START_STOP: - move_ins = 0; - break; default: /* OK, get it from the command */ switch(SCp->sc_data_direction) { @@ -1734,26 +1928,40 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *)) } /* now build the scatter gather list */ + pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction); if(move_ins != 0) { int i; + int sg_count; + dma_addr_t vPtr = 0; + __u32 count = 0; + + if(SCp->use_sg) { + sg_count = pci_map_sg(hostdata->pci_dev, SCp->buffer, + SCp->use_sg, pci_direction); + } else { + vPtr = pci_map_single(hostdata->pci_dev, + SCp->request_buffer, + SCp->request_bufflen, + pci_direction); + count = SCp->request_bufflen; + slot->dma_handle = vPtr; + sg_count = 1; + } + - for(i = 0; i < (SCp->use_sg ? SCp->use_sg : 1); i++) { - void *vPtr; - __u32 count; + for(i = 0; i < sg_count; i++) { if(SCp->use_sg) { - vPtr = (((struct scatterlist *)SCp->buffer)[i].address); - count = ((struct scatterlist *)SCp->buffer)[i].length; - } else { - vPtr = SCp->request_buffer; - count = SCp->request_bufflen; + struct scatterlist *sg = SCp->buffer; + + vPtr = sg_dma_address(&sg[i]); + count = sg_dma_len(&sg[i]); } + slot->SG[i].ins = bS_to_host(move_ins | count); DEBUG((" scatter block %d: move %d[%08x] from 0x%lx\n", - i, count, slot->SG[i].ins, - virt_to_bus(vPtr))); - dma_cache_wback_inv((unsigned long)vPtr, count); - slot->SG[i].pAddr = bS_to_host(virt_to_bus(vPtr)); + i, count, slot->SG[i].ins, (unsigned long)vPtr)); + slot->SG[i].pAddr = bS_to_host(vPtr); } slot->SG[i].ins = bS_to_host(SCRIPT_RETURN); slot->SG[i].pAddr = 0; diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h index 456b78b43328..17b51b0d1097 100644 --- a/drivers/scsi/53c700.h +++ b/drivers/scsi/53c700.h @@ -36,8 +36,8 @@ /* WARNING: Leave this in for now: the dependency preprocessor doesn't * pick up file specific flags, so must define here if they are not * set */ -#if !defined(IO_MAPPED) && !defined(MEM_MAPPED) -#define IO_MAPPED +#if !defined(CONFIG_53C700_IO_MAPPED) && !defined(CONFIG_53C700_MEM_MAPPED) +#error "Config.in must define either CONFIG_53C700_IO_MAPPED or CONFIG_53C700_MEM_MAPPED to use this scsi core." #endif @@ -90,43 +90,43 @@ struct NCR_700_SG_List { static inline void NCR_700_set_SXFER(Scsi_Device *SDp, __u8 sxfer) { - ((__u32)SDp->hostdata) &= 0xffffff00; - ((__u32)SDp->hostdata) |= sxfer & 0xff; + ((unsigned long)SDp->hostdata) &= 0xffffff00; + ((unsigned long)SDp->hostdata) |= sxfer & 0xff; } static inline __u8 NCR_700_get_SXFER(Scsi_Device *SDp) { - return (((__u32)SDp->hostdata) & 0xff); + return (((unsigned long)SDp->hostdata) & 0xff); } static inline void NCR_700_set_depth(Scsi_Device *SDp, __u8 depth) { - ((__u32)SDp->hostdata) &= 0xffff00ff; - ((__u32)SDp->hostdata) |= (0xff00 & (depth << 8)); + ((unsigned long)SDp->hostdata) &= 0xffff00ff; + ((unsigned long)SDp->hostdata) |= (0xff00 & (depth << 8)); } static inline __u8 NCR_700_get_depth(Scsi_Device *SDp) { - return ((((__u32)SDp->hostdata) & 0xff00)>>8); + return ((((unsigned long)SDp->hostdata) & 0xff00)>>8); } static inline int NCR_700_is_flag_set(Scsi_Device *SDp, __u32 flag) { - return (((__u32)SDp->hostdata) & flag) == flag; + return (((unsigned long)SDp->hostdata) & flag) == flag; } static inline int NCR_700_is_flag_clear(Scsi_Device *SDp, __u32 flag) { - return (((__u32)SDp->hostdata) & flag) == 0; + return (((unsigned long)SDp->hostdata) & flag) == 0; } static inline void NCR_700_set_flag(Scsi_Device *SDp, __u32 flag) { - ((__u32)SDp->hostdata) |= (flag & 0xffff0000); + ((unsigned long)SDp->hostdata) |= (flag & 0xffff0000); } static inline void NCR_700_clear_flag(Scsi_Device *SDp, __u32 flag) { - ((__u32)SDp->hostdata) &= ~(flag & 0xffff0000); + ((unsigned long)SDp->hostdata) &= ~(flag & 0xffff0000); } /* These represent the Nexus hashing functions. A Nexus in SCSI terms @@ -162,6 +162,8 @@ hash_ITLQ(__u8 pun, __u8 lun, __u8 tag) } struct NCR_700_command_slot { + struct NCR_700_SG_List SG[NCR_700_SG_SEGMENTS+1]; + struct NCR_700_SG_List *pSG; #define NCR_700_SLOT_MASK 0xFC #define NCR_700_SLOT_MAGIC 0xb8 #define NCR_700_SLOT_FREE (0|NCR_700_SLOT_MAGIC) /* slot may be used */ @@ -170,10 +172,12 @@ struct NCR_700_command_slot { __u8 state; #define NCR_700_NO_TAG 0xdead __u16 tag; - struct NCR_700_SG_List SG[NCR_700_SG_SEGMENTS+1]; __u32 resume_offset; Scsi_Cmnd *cmnd; __u32 temp; + /* if this command is a pci_single mapping, holds the dma address + * for later unmapping in the done routine */ + dma_addr_t dma_handle; /* Doubly linked ITL/ITLQ list kept in strict time order * (latest at the back) */ struct NCR_700_command_slot *ITL_forw; @@ -186,12 +190,16 @@ struct NCR_700_Host_Parameters { /* These must be filled in by the calling driver */ int clock; /* board clock speed in MHz */ __u32 base; /* the base for the port (copied to host) */ + struct pci_dev *pci_dev; + __u8 dmode_extra; /* adjustable bus settings */ __u8 differential:1; /* if we are differential */ -#ifdef __hppa__ +#ifdef CONFIG_53C700_LE_ON_BE /* This option is for HP only. Set it if your chip is wired for * little endian on this platform (which is big endian) */ __u8 force_le_on_be:1; #endif + __u8 chip710:1; /* set if really a 710 not 700 */ + __u8 burst_disable:1; /* set to 1 to disable 710 bursting */ /* NOTHING BELOW HERE NEEDS ALTERING */ __u8 fast:1; /* if we can alter the SCSI bus clock @@ -209,10 +217,11 @@ struct NCR_700_Host_Parameters { enum NCR_700_Host_State state; /* protected by state lock */ Scsi_Cmnd *cmd; - __u8 msgout[8]; + __u8 *msgout; +#define MSG_ARRAY_SIZE 16 __u8 tag_negotiated; - __u8 status; - __u8 msgin[8]; + __u8 *status; + __u8 *msgin; struct NCR_700_command_slot *slots; int saved_slot_position; int command_slot_count; /* protected by state lock */ @@ -237,7 +246,7 @@ struct NCR_700_Host_Parameters { /* * 53C700 Register Interface - the offset from the Selected base * I/O address */ -#ifdef __hppa__ +#ifdef CONFIG_53C700_LE_ON_BE #define bE (hostdata->force_le_on_be ? 0 : 3) #define bSWAP (hostdata->force_le_on_be) #elif defined(__BIG_ENDIAN) @@ -310,6 +319,7 @@ struct NCR_700_Host_Parameters { #define SODL_REG_FULL 0x20 #define SSTAT2_REG 0x0F #define CTEST0_REG 0x14 +#define BTB_TIMER_DISABLE 0x40 #define CTEST1_REG 0x15 #define CTEST2_REG 0x16 #define CTEST3_REG 0x17 @@ -327,6 +337,8 @@ struct NCR_700_Host_Parameters { #define MASTER_CONTROL 0x10 #define DMA_DIRECTION 0x08 #define CTEST7_REG 0x1B +#define BURST_DISABLE 0x80 /* 710 only */ +#define SEL_TIMEOUT_DISABLE 0x10 /* 710 only */ #define DFP 0x08 #define EVP 0x04 #define DIFF 0x01 @@ -337,6 +349,7 @@ struct NCR_700_Host_Parameters { #define CLR_FIFO 0x40 #define ISTAT_REG 0x21 #define ABORT_OPERATION 0x80 +#define SOFTWARE_RESET_710 0x40 #define DMA_INT_PENDING 0x01 #define SCSI_INT_PENDING 0x02 #define CONNECTED 0x08 @@ -345,27 +358,34 @@ struct NCR_700_Host_Parameters { #define SHORTEN_FILTERING 0x04 #define ENABLE_ACTIVE_NEGATION 0x10 #define GENERATE_RECEIVE_PARITY 0x20 +#define CLR_FIFO_710 0x04 +#define FLUSH_DMA_FIFO_710 0x08 #define CTEST9_REG 0x23 #define DBC_REG 0x24 #define DCMD_REG 0x27 #define DNAD_REG 0x28 #define DIEN_REG 0x39 +#define BUS_FAULT 0x20 #define ABORT_INT 0x10 #define INT_INST_INT 0x04 #define WD_INT 0x02 #define ILGL_INST_INT 0x01 #define DCNTL_REG 0x3B #define SOFTWARE_RESET 0x01 +#define COMPAT_700_MODE 0x01 #define SCRPTS_16BITS 0x20 #define ASYNC_DIV_2_0 0x00 -#define ASYNC_DIV_1_5 0x01 -#define ASYNC_DIV_1_0 0x02 -#define ASYNC_DIV_3_0 0x03 -#define DMODE_REG 0x34 +#define ASYNC_DIV_1_5 0x40 +#define ASYNC_DIV_1_0 0x80 +#define ASYNC_DIV_3_0 0xc0 +#define DMODE_710_REG 0x38 +#define DMODE_700_REG 0x34 #define BURST_LENGTH_1 0x00 #define BURST_LENGTH_2 0x40 #define BURST_LENGTH_4 0x80 #define BURST_LENGTH_8 0xC0 +#define DMODE_FC1 0x10 +#define DMODE_FC2 0x20 #define BW16 32 #define MODE_286 16 #define IO_XFER 8 @@ -377,7 +397,11 @@ struct NCR_700_Host_Parameters { /* Parameters to begin SDTR negotiations. Empirically, I find that * the 53c700-66 cannot handle an offset >8, so don't change this */ #define NCR_700_MAX_OFFSET 8 +/* Was hoping the max offset would be greater for the 710, but + * empirically it seems to be 8 also */ +#define NCR_710_MAX_OFFSET 8 #define NCR_700_MIN_XFERP 1 +#define NCR_710_MIN_XFERP 0 #define NCR_700_MIN_PERIOD 25 /* for SDTR message, 100ns */ #define script_patch_32(script, symbol, value) \ @@ -427,14 +451,14 @@ struct NCR_700_Host_Parameters { val |= ((value) & 0xffff); \ (script)[A_##symbol##_used[i]] = bS_to_host(val); \ dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \ - DEBUG((" script, patching ID field %s at %d to 0x%x\n", \ + DEBUG((" script, patching short field %s at %d to 0x%x\n", \ #symbol, A_##symbol##_used[i], val)); \ } \ } #endif -#ifdef MEM_MAPPED +#ifdef CONFIG_53C700_MEM_MAPPED static inline __u8 NCR_700_readb(struct Scsi_Host *host, __u32 reg) { @@ -482,7 +506,7 @@ NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg) writel(bS_to_host(value), host->base + reg); } -#elif defined(IO_MAPPED) +#elif defined(CONFIG_53C700_IO_MAPPED) static inline __u8 NCR_700_readb(struct Scsi_Host *host, __u32 reg) { diff --git a/drivers/scsi/53c700.scr b/drivers/scsi/53c700.scr index 30d22a34dbea..737c3c7e1e46 100644 --- a/drivers/scsi/53c700.scr +++ b/drivers/scsi/53c700.scr @@ -81,6 +81,7 @@ ABSOLUTE REJECT_MSG_BEFORE_CMD = 0x270 ABSOLUTE DISCONNECT_AFTER_CMD = 0x380 ABSOLUTE SDTR_MSG_AFTER_CMD = 0x360 ABSOLUTE WDTR_MSG_AFTER_CMD = 0x3A0 +ABSOLUTE MSG_IN_AFTER_STATUS = 0x440 ABSOLUTE DISCONNECT_AFTER_DATA = 0x580 ABSOLUTE MSG_IN_AFTER_DATA_IN = 0x550 ABSOLUTE MSG_IN_AFTER_DATA_OUT = 0x650 @@ -116,7 +117,8 @@ ABSOLUTE DEBUG_INTERRUPT6 = 0x3006 ; ; SCSI Messages we interpret in the script -; +; +ABSOLUTE COMMAND_COMPLETE_MSG = 0x00 ABSOLUTE EXTENDED_MSG = 0x01 ABSOLUTE SDTR_MSG = 0x01 ABSOLUTE SAVE_DATA_PTRS_MSG = 0x02 @@ -393,7 +395,12 @@ Disconnect8: Finish: MOVE 1, StatusAddress, WHEN STATUS INT NOT_MSG_IN_AFTER_STATUS, WHEN NOT MSG_IN - CALL ReceiveMessage + MOVE 1, ReceiveMsgAddress, WHEN MSG_IN + JUMP FinishCommandComplete, IF COMMAND_COMPLETE_MSG + CALL ProcessReceiveMessage + INT MSG_IN_AFTER_STATUS + ENTRY FinishCommandComplete +FinishCommandComplete: CLEAR ACK WAIT DISCONNECT ENTRY Finish1 diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c index 4ccc318a8114..b02ec8117c7c 100644 --- a/drivers/scsi/53c7xx.c +++ b/drivers/scsi/53c7xx.c @@ -230,9 +230,7 @@ * */ -#ifdef MODULE #include <linux/module.h> -#endif #include <linux/config.h> diff --git a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c index 80b807bf723c..5696214c7e12 100644 --- a/drivers/scsi/AM53C974.c +++ b/drivers/scsi/AM53C974.c @@ -2449,6 +2449,8 @@ static int AM53C974_release(struct Scsi_Host *shp) /* You can specify overrides=a,b,c,d in the same format at AM53C974=a,b,c,d on boot up */ MODULE_PARM(overrides, "1-32i"); +MODULE_LICENSE("GPL"); + static Scsi_Host_Template driver_template = AM53C974; #include "scsi_module.c" diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index e2a6c4c378b8..2ca550633ec4 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -4993,6 +4993,7 @@ __setup("BusLogic=", BusLogic_Setup); /* Get it all started */ +MODULE_LICENSE("GPL"); static SCSI_Host_Template_T driver_template = BUSLOGIC; diff --git a/drivers/scsi/ChangeLog.serverraid b/drivers/scsi/ChangeLog.serverraid index 38848f7515f0..b84ae02113ea 100644 --- a/drivers/scsi/ChangeLog.serverraid +++ b/drivers/scsi/ChangeLog.serverraid @@ -1,25 +1,103 @@ -Change Log -~~~~~~~~~~ +IBM ServeRAID driver Change Log +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 1.00.00 - Initial Public Release - - Functionally equivalent to 0.99.05 + 4.80.20 - Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel ) + - 5 second delay needed after resetting an i960 adapter + + 4.80.14 - Take all semaphores off stack + Clean Up New_IOCTL path + + 4.80.04 - Eliminate calls to strtok() if 2.4.x or greater + - Adjustments to Device Queue Depth + + 4.80.00 - Make ia64 Safe + + 4.72.01 - I/O Mapped Memory release ( so "insmod ips" does not Fail ) + Don't Issue Internal FFDC Command if there are Active Commands + Close Window for getting too many IOCTL's active + + 4.72.00 - Allow for a Scatter-Gather Element to exceed MAX_XFER Size + + 4.71.00 - Change all memory allocations to not use GFP_DMA flag + Code Clean-Up for 2.4.x kernel + + 4.70.15 - Fix Breakup for very large ( non-SG ) requests + + 4.70.13 - Don't release HA Lock in ips_next() until SC taken off queue + - Unregister SCSI device in ips_release() + - Don't Send CDB's if we already know the device is not present + + 4.70.12 - Corrective actions for bad controller ( during initialization ) + + 4.70.09 - Use a Common ( Large Buffer ) for Flashing from the JCRM CD + - Add IPSSEND Flash Support + - Set Sense Data for Unknown SCSI Command + - Use Slot Number from NVRAM Page 5 + - Restore caller's DCDB Structure + + 4.20.14 - Update patch files for kernel 2.4.0-test5 + + 4.20.13 - Fix some failure cases / reset code + - Hook into the reboot_notifier to flush the controller + cache + + 4.20.03 - Rename version to coincide with new release schedules + - Performance fixes + - Fix truncation of /proc files with cat + - Merge in changes through kernel 2.4.0test1ac21 + + 4.10.13 - Fix for dynamic unload and proc file system + + 4.10.00 - Add support for ServeRAID 4M/4L + + 4.00.06 - Fix timeout with initial FFDC command + + 4.00.05 - Remove wish_block from init routine + - Use linux/spinlock.h instead of asm/spinlock.h for kernels + 2.3.18 and later + - Sync with other changes from the 2.3 kernels + + 4.00.04 - Rename structures/constants to be prefixed with IPS_ + + 4.00.03 - Add alternative passthru interface + - Add ability to flash ServeRAID BIOS + + 4.00.02 - Fix problem with PT DCDB with no buffer + + 4.00.01 - Add support for First Failure Data Capture + + 4.00.00 - Add support for ServeRAID 4 + + 3.60.02 - Make DCDB direction based on lookup table. + - Only allow one DCDB command to a SCSI ID at a time. + + 3.60.01 - Remove bogus error check in passthru routine. + + 3.60.00 - Bump max commands to 128 for use with ServeRAID + firmware 3.60. + - Change version to 3.60 to coincide with ServeRAID release + numbering. + + 1.00.00 - Initial Public Release + - Functionally equivalent to 0.99.05 0.99.05 - Fix an oops on certain passthru commands - 0.99.04 - Fix race condition in the passthru mechanism + 0.99.04 - Fix race condition in the passthru mechanism -- this required the interface to the utilities to change - - Fix error recovery code + - Fix error recovery code - 0.99.03 - Make interrupt routine handle all completed request on the - adapter not just the first one - - Make sure passthru commands get woken up if we run out of - SCBs - - Send all of the commands on the queue at once rather than - one at a time since the card will support it. + 0.99.03 - Make interrupt routine handle all completed request on the + adapter not just the first one + - Make sure passthru commands get woken up if we run out of + SCBs + - Send all of the commands on the queue at once rather than + one at a time since the card will support it. - 0.99.02 - Added some additional debug statements to print out + 0.99.02 - Added some additional debug statements to print out errors if an error occurs while trying to read/write to a logical drive (IPS_DEBUG). - Fixed read/write errors when the adapter is using an + - Fixed read/write errors when the adapter is using an 8K stripe size. + diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in index 68560498e442..527995202d2e 100644 --- a/drivers/scsi/Config.in +++ b/drivers/scsi/Config.in @@ -115,9 +115,18 @@ if [ "$CONFIG_PARPORT" != "n" ]; then fi fi dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI -dep_tristate 'NCR Dual 700 MCA SCSI support' CONFIG_SCSI_NCR_D700 $CONFIG_SCSI $CONFIG_MCA +if [ "$CONFIG_MCA" = "y" ]; then + dep_tristate 'NCR Dual 700 MCA SCSI support' CONFIG_SCSI_NCR_D700 $CONFIG_SCSI + if [ "$CONFIG_SCSI_NCR_D700" != "n" ]; then + define_bool CONFIG_53C700_IO_MAPPED y + fi +fi if [ "$CONFIG_PARISC" = "y" ]; then - dep_tristate 'HP LASI SCSI support for 53c700' CONFIG_SCSI_LASI70 $CONFIG_SCSI + dep_tristate 'HP LASI SCSI support for 53c700' CONFIG_SCSI_LASI700 $CONFIG_SCSI + if [ "$CONFIG_SCSI_LASI700" != "n" ]; then + define_bool CONFIG_53C700_MEM_MAPPED y + define_bool CONFIG_53C700_LE_ON_BE y + fi fi dep_tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI $CONFIG_PCI if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 613b90370986..9cb5a6f99121 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -13,29 +13,21 @@ # satisfy certain initialization assumptions in the SCSI layer. # *!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*! -O_TARGET := scsidrv.o -SUB_DIRS := -MOD_SUB_DIRS := -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) pcmcia +CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF +CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS +CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM -subdir-$(CONFIG_SCSI_AIC7XXX) += aic7xxx -ifeq ($(CONFIG_PCMCIA),y) - SUB_DIRS += pcmcia - MOD_IN_SUB_DIRS += pcmcia -else - ifeq ($(CONFIG_PCMCIA),m) - MOD_IN_SUB_DIRS += pcmcia - endif -endif +O_TARGET := scsidrv.o -export-objs := scsi_syms.o 53c700.o 53c700-mem.o +export-objs := scsi_syms.o 53c700.o +mod-subdirs := pcmcia ../acorn/scsi + + +subdir-$(CONFIG_SCSI_AIC7XXX) += aic7xxx +subdir-$(CONFIG_PCMCIA) += pcmcia -CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF -CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS -CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM obj-$(CONFIG_SCSI) += scsi_mod.o @@ -125,13 +117,10 @@ obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o obj-$(CONFIG_SCSI_FCAL) += fcal.o obj-$(CONFIG_SCSI_CPQFCTS) += cpqfc.o -obj-$(CONFIG_SCSI_LASI700) += lasi700.o 53c700-mem.o +obj-$(CONFIG_SCSI_LASI700) += lasi700.o 53c700.o -ifeq ($(CONFIG_ARCH_ACORN),y) -mod-subdirs += ../acorn/scsi -subdir-y += ../acorn/scsi -obj-y += ../acorn/scsi/acorn-scsi.o -endif +subdir-$(CONFIG_ARCH_ACORN) += ../acorn/scsi +obj-$(CONFIG_ARCH_ACORN) += ../acorn/scsi/acorn-scsi.o obj-$(CONFIG_CHR_DEV_ST) += st.o obj-$(CONFIG_CHR_DEV_OSST) += osst.o @@ -149,7 +138,8 @@ sd_mod-objs := sd.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o initio-objs := ini9100u.o i91uscsi.o a100u2w-objs := inia100.o i60uscsi.o -cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o cpqfcTSworker.o cpqfcTStrigger.o +cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \ + cpqfcTSworker.o cpqfcTStrigger.o include $(TOPDIR)/Rules.make @@ -209,10 +199,3 @@ sim710.o : sim710_d.h mv script.h 53c700_d.h 53c700.o: 53c700_d.h - -53c700-mem.o: 53c700_d.h - -53c700-mem.c: 53c700.c - echo "/* WARNING: GENERATED FILE (from $<), DO NOT MODIFY */" > $@ - echo "#define MEM_MAPPED" >> $@ - cat $< >> $@ diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 11338af5f983..9a23dbc35a05 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c @@ -21,9 +21,7 @@ * 4) Maybe change use of "esp" to something more "NCR"'ish. */ -#ifdef MODULE #include <linux/module.h> -#endif #include <linux/config.h> #include <linux/kernel.h> diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c index 91438fff9eee..118acb2db1eb 100644 --- a/drivers/scsi/NCR53c406a.c +++ b/drivers/scsi/NCR53c406a.c @@ -1074,6 +1074,7 @@ void __init calc_port_addr(void) /* SIGNATURE = (port_base+0x0E);*/ /* CONFIG6 = (port_base+0x0F);*/ } +MODULE_LICENSE("GPL"); /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = NCR53c406a; diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index e84b0e6b3260..3495597b5d2c 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -775,9 +775,7 @@ */ #include <linux/config.h> -#ifdef MODULE #include <linux/module.h> -#endif /* MODULE */ #if defined(CONFIG_X86) && !defined(CONFIG_ISA) #define CONFIG_ISA @@ -18682,3 +18680,4 @@ AdvInquiryHandling( } } } +MODULE_LICENSE("BSD without advertising clause"); diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 371141778698..6e95c9efb840 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -333,6 +333,8 @@ enum { #if defined(MODULE) MODULE_AUTHOR("Jürgen Fischer"); MODULE_DESCRIPTION(AHA152X_REVID); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "1-2i"); MODULE_PARM_DESC(io,"base io address of controller"); static int io[] = {0, 0}; diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index a2a6a3fbe4a9..55b0012bd729 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -1800,6 +1800,7 @@ static int aha1542_biosparam(Scsi_Disk * disk, kdev_t dev, int *ip) return 0; } +MODULE_LICENSE("GPL"); /* Eventually this will go into an include file, but this will be later */ diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 4c2027751d90..8e2609ab33e9 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -22,10 +22,7 @@ * if it doesn't work for your devices, take a look. */ -#ifdef MODULE #include <linux/module.h> -#endif - #include <linux/kernel.h> #include <linux/types.h> #include <linux/string.h> @@ -614,6 +611,8 @@ int aha1740_biosparam(Disk * disk, kdev_t dev, int* ip) return 0; } +MODULE_LICENSE("GPL"); + /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = AHA1740; diff --git a/drivers/scsi/aic7xxx/aic7xxx_linux.c b/drivers/scsi/aic7xxx/aic7xxx_linux.c index 916d7b48c455..556d51da6904 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_linux.c +++ b/drivers/scsi/aic7xxx/aic7xxx_linux.c @@ -120,9 +120,7 @@ * under normal conditions. */ -#if defined(MODULE) #include <linux/module.h> -#endif #include "aic7xxx_osm.h" #include "aic7xxx_inline.h" @@ -2870,6 +2868,8 @@ ahc_platform_dump_card_state(struct ahc_softc *ahc) } } +MODULE_LICENSE("Dual BSD/GPL"); + #if defined(MODULE) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) static Scsi_Host_Template driver_template = AIC7XXX; Scsi_Host_Template *aic7xxx_driver_template = &driver_template; diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index 70f086edc4d7..20fbe31d85a5 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c @@ -11963,6 +11963,9 @@ aic7xxx_print_scratch_ram(struct aic7xxx_host *p) #include "aic7xxx_old/aic7xxx_proc.c" +MODULE_LICENSE("Dual BSD/GPL"); + + /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = AIC7XXX; diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index ca628f2b9221..aec2ad4c107e 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -2872,6 +2872,7 @@ int atp870u_release (struct Scsi_Host *pshost) panic("atp870u: bad scsi host passed.\n"); } +MODULE_LICENSE("GPL"); static Scsi_Host_Template driver_template = ATP870U; #include "scsi_module.c" diff --git a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c index ef4ddf667e05..fef34ed3a501 100644 --- a/drivers/scsi/cpqfcTSinit.c +++ b/drivers/scsi/cpqfcTSinit.c @@ -68,6 +68,7 @@ /* Embedded module documentation macros - see module.h */ MODULE_AUTHOR("Compaq Computer Corporation"); MODULE_DESCRIPTION("Driver for Compaq 64-bit/66Mhz PCI Fibre Channel HBA"); +MODULE_LICENSE("GPL"); int cpqfcTS_TargetDeviceReset( Scsi_Device *ScsiDev, unsigned int reset_flags); diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index 6f4aabf24377..399fcfefe51f 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -119,6 +119,7 @@ int dmx3191d_release_resources(struct Scsi_Host *instance) return 0; } +MODULE_LICENSE("GPL"); static Scsi_Host_Template driver_template = DMX3191D; #include "scsi_module.c" diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 1ee77dba489e..3c8a9d1129b2 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -3324,3 +3324,4 @@ static static void adpt_delay(int millisec) static Scsi_Host_Template driver_template = DPT_I2O; #include "scsi_module.c" EXPORT_NO_SYMBOLS; +MODULE_LICENSE("BSD without advertising clause"); diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 845174d27eb1..b1f7abcff28c 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -73,6 +73,7 @@ #include <asm/system.h> +#include <linux/module.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/blk.h> @@ -433,6 +434,8 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, return (0); } +MODULE_LICENSE("GPL"); + #include "NCR5380.c" /* Eventually this will go into an include file, but this will be later */ diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index 93562235ba4f..c7360c43c08a 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -2077,3 +2077,4 @@ static Scsi_Host_Template driver_template = EATA; #ifndef MODULE __setup("eata=", option_setup); #endif /* end MODULE */ +MODULE_LICENSE("BSD"); diff --git a/drivers/scsi/eata_dma.c b/drivers/scsi/eata_dma.c index 20b9ffef1604..6133d6301b2a 100644 --- a/drivers/scsi/eata_dma.c +++ b/drivers/scsi/eata_dma.c @@ -1545,6 +1545,8 @@ int eata_detect(Scsi_Host_Template * tpnt) return(registered_HBAs); } +MODULE_LICENSE("GPL"); + /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = EATA_DMA; #include "scsi_module.c" diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index 13e918a23e8c..83b4234056c8 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c @@ -995,6 +995,7 @@ int eata_pio_detect(Scsi_Host_Template * tpnt) static Scsi_Host_Template driver_template = EATA_PIO; #include "scsi_module.c" +MODULE_LICENSE("GPL"); /* * Overrides for Emacs so that we almost follow Linus's tabbing style. diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index 097893204f3c..8332bf1f47c3 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c @@ -77,9 +77,7 @@ **************************************************************************/ -#ifdef MODULE #include <linux/module.h> -#endif #include <linux/sched.h> #include <linux/blk.h> diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index aeea8d151d8f..229bad39f2c4 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -2035,6 +2035,8 @@ int fdomain_16x0_biosparam( Scsi_Disk *disk, kdev_t dev, int *info_array ) return 0; } +MODULE_LICENSE("GPL"); + /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = FDOMAIN_16X0; diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index f8a816744f61..1d15edfbbb84 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -912,7 +912,7 @@ MODULE_PARM(ncr_5380, "i"); MODULE_PARM(ncr_53c400, "i"); MODULE_PARM(ncr_53c400a, "i"); MODULE_PARM(dtc_3181e, "i"); - +MODULE_LICENSE("GPL"); #else static int __init do_NCR5380_setup(char *str) @@ -970,6 +970,8 @@ static struct isapnp_device_id id_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(isapnp, id_table); +MODULE_LICENSE("GPL"); + #endif diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 1a283cad4280..e41d66ddc16f 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -295,9 +295,7 @@ * phase: Service/parameter/return code special command */ -#ifdef MODULE #include <linux/module.h> -#endif #include <linux/version.h> #include <linux/kernel.h> @@ -687,6 +685,7 @@ MODULE_PARM(rescan, "i"); MODULE_PARM(virt_ctr, "i"); MODULE_PARM(shared_access, "i"); MODULE_AUTHOR("Achim Leubner"); +MODULE_LICENSE("GPL"); #endif #endif diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 444682a7a0fd..8f32310865f0 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -849,3 +849,4 @@ static void __exit exit_idescsi_module(void) module_init(init_idescsi_module); module_exit(exit_idescsi_module); +MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 7c820c9fa792..9290a59c0f3d 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1270,3 +1270,4 @@ static int device_check(int host_no) printk("imm: No devices found, aborting driver load.\n"); return 1; } +MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index 6689585af33f..5b7a6782529f 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -2360,6 +2360,8 @@ static int stop = 0; } +MODULE_LICENSE("GPL"); + static Scsi_Host_Template driver_template = IN2000; #include "scsi_module.c" diff --git a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c index 27734df92346..17ac962a89bd 100644 --- a/drivers/scsi/ini9100u.c +++ b/drivers/scsi/ini9100u.c @@ -112,9 +112,7 @@ #include <linux/version.h> #endif -#ifdef MODULE #include <linux/module.h> -#endif #include <stdarg.h> #include <asm/irq.h> @@ -828,3 +826,4 @@ int i91u_release(struct Scsi_Host *hreg) release_region(hreg->io_port, 256); return 0; } +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c index eace0a7e4974..47cf2b4dfb1f 100644 --- a/drivers/scsi/inia100.c +++ b/drivers/scsi/inia100.c @@ -67,9 +67,7 @@ #include <linux/version.h> #endif -#ifdef MODULE #include <linux/module.h> -#endif #include <stdarg.h> #include <asm/irq.h> @@ -796,4 +794,5 @@ int inia100_release(struct Scsi_Host *hreg) return 0; } +MODULE_LICENSE("Dual BSD/GPL"); /*#include "inia100scsi.c" */ diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index f8f37161b838..6372807d5602 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -3,7 +3,7 @@ /* */ /* Written By: Keith Mitchell, IBM Corporation */ /* */ -/* Copyright (C) 1999 IBM Corporation */ +/* Copyright (C) 2000 IBM Corporation */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -39,8 +39,12 @@ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* */ -/* Bugs/Comments/Suggestions should be mailed to: */ -/* ipslinux@us.ibm.com */ +/* Bugs/Comments/Suggestions about this driver should be mailed to: */ +/* ipslinux@us.ibm.com */ +/* */ +/* For system support issues, contact your local IBM Customer support. */ +/* Directions to find IBM Customer Support for each country can be found at: */ +/* http://www.ibm.com/planetwide/ */ /* */ /*****************************************************************************/ @@ -86,7 +90,7 @@ /* Merge in changes through kernel 2.4.0test1ac21 */ /* 4.20.13 - Fix some failure cases / reset code */ /* - Hook into the reboot_notifier to flush the controller cache */ -/* 4.50.01 - Fix problem when there is a hole in logical drive numbering */ +/* 4.50.01 - Fix problem when there is a hole in logical drive numbering */ /* 4.70.09 - Use a Common ( Large Buffer ) for Flashing from the JCRM CD */ /* - Add IPSSEND Flash Support */ /* - Set Sense Data for Unknown SCSI Command */ @@ -100,7 +104,16 @@ /* 4.71.00 - Change all memory allocations to not use GFP_DMA flag */ /* Code Clean-Up for 2.4.x kernel */ /* 4.72.00 - Allow for a Scatter-Gather Element to exceed MAX_XFER Size */ -/* */ +/* 4.72.01 - I/O Mapped Memory release ( so "insmod ips" does not Fail ) */ +/* Don't Issue Internal FFDC Command if there are Active Commands */ +/* Close Window for getting too many IOCTL's active */ +/* 4.80.00 Make ia64 Safe */ +/* 4.80.04 Eliminate calls to strtok() if 2.4.x or greater */ +/* Adjustments to Device Queue Depth */ +/* 4.80.14 Take all semaphores off stack */ +/* Clean Up New_IOCTL path */ +/* 4.80.20 Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel ) */ +/* 5 second delay needed after resetting an i960 adapter */ /*****************************************************************************/ /* @@ -126,15 +139,16 @@ * nommap - Don't use memory mapped I/O * ioctlsize - Initial size of the IOCTL buffer */ - + #include <asm/io.h> #include <asm/byteorder.h> +#include <asm/page.h> #include <linux/stddef.h> #include <linux/version.h> #include <linux/string.h> #include <linux/errno.h> #include <linux/kernel.h> -#include <linux/ioport.h> +#include <linux/ioport.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/delay.h> @@ -182,9 +196,8 @@ /* * DRIVER_VER */ -#define IPS_VERSION_HIGH "4.72" -#define IPS_VERSION_LOW ".00 " - +#define IPS_VERSION_HIGH "4.80" +#define IPS_VERSION_LOW ".26 " #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27) struct proc_dir_entry proc_scsi_ips = { @@ -194,8 +207,8 @@ struct proc_dir_entry proc_scsi_ips = { }; #endif -#if !defined(__i386__) - #error "This driver has only been tested on the x86 platform" +#if !defined(__i386__) && !defined(__ia64__) + #error "This driver has only been tested on the x86/ia64 platforms" #endif #if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0) @@ -219,7 +232,7 @@ struct proc_dir_entry proc_scsi_ips = { /* * global variables */ -static const char * ips_name = "ips"; +static const char ips_name[] = "ips"; static struct Scsi_Host * ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */ static ips_ha_t * ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */ static unsigned int ips_next_controller = 0; @@ -367,9 +380,12 @@ static int ips_init_morpheus(ips_ha_t *); static int ips_isinit_copperhead(ips_ha_t *); static int ips_isinit_copperhead_memio(ips_ha_t *); static int ips_isinit_morpheus(ips_ha_t *); -static u32 ips_statupd_copperhead(ips_ha_t *); -static u32 ips_statupd_copperhead_memio(ips_ha_t *); -static u32 ips_statupd_morpheus(ips_ha_t *); +static int ips_erase_bios(ips_ha_t *); +static int ips_program_bios(ips_ha_t *, char *, u_int32_t, u_int32_t); +static int ips_verify_bios(ips_ha_t *, char *, u_int32_t, u_int32_t); +static int ips_erase_bios_memio(ips_ha_t *); +static int ips_program_bios_memio(ips_ha_t *, char *, u_int32_t, u_int32_t); +static int ips_verify_bios_memio(ips_ha_t *, char *, u_int32_t, u_int32_t); static void ips_flash_bios_section(void *); static void ips_flash_bios_segment(void *); static void ips_scheduled_flash_bios(void *); @@ -395,25 +411,22 @@ static void ips_statinit_memio(ips_ha_t *); static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t); static void ips_ffdc_reset(ips_ha_t *, int); static void ips_ffdc_time(ips_ha_t *, int); +static u_int32_t ips_statupd_copperhead(ips_ha_t *); +static u_int32_t ips_statupd_copperhead_memio(ips_ha_t *); +static u_int32_t ips_statupd_morpheus(ips_ha_t *); static ips_scb_t * ips_getscb(ips_ha_t *); static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *); static inline void ips_putq_scb_tail(ips_scb_queue_t *, ips_scb_t *); -static inline ips_scb_t * ips_removeq_scb_head(ips_scb_queue_t *); -static inline ips_scb_t * ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *); static inline void ips_putq_wait_head(ips_wait_queue_t *, Scsi_Cmnd *); static inline void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *); -static inline Scsi_Cmnd * ips_removeq_wait_head(ips_wait_queue_t *); -static inline Scsi_Cmnd * ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *); static inline void ips_putq_copp_head(ips_copp_queue_t *, ips_copp_wait_item_t *); static inline void ips_putq_copp_tail(ips_copp_queue_t *, ips_copp_wait_item_t *); +static inline ips_scb_t * ips_removeq_scb_head(ips_scb_queue_t *); +static inline ips_scb_t * ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *); +static inline Scsi_Cmnd * ips_removeq_wait_head(ips_wait_queue_t *); +static inline Scsi_Cmnd * ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *); static inline ips_copp_wait_item_t * ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *); static inline ips_copp_wait_item_t * ips_removeq_copp_head(ips_copp_queue_t *); -static int ips_erase_bios(ips_ha_t *); -static int ips_program_bios(ips_ha_t *, char *, u32, u32); -static int ips_verify_bios(ips_ha_t *, char *, u32, u32); -static int ips_erase_bios_memio(ips_ha_t *); -static int ips_program_bios_memio(ips_ha_t *, char *, u32, u32); -static int ips_verify_bios_memio(ips_ha_t *, char *, u32, u32); #ifndef NO_IPS_CMDLINE static int ips_is_passthru(Scsi_Cmnd *); @@ -449,10 +462,14 @@ void ips_setup(char *ips_str, int *dummy) { #endif int i; + +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) char *p; + char tokens[3] = {',', '.', 0}; +#endif + char *key; char *value; - char tokens[3] = {',', '.', 0}; IPS_OPTION options[] = { {"noreset", &ips_resetcontroller, 0}, #ifdef IPS_DEBUG @@ -467,6 +484,30 @@ ips_setup(char *ips_str, int *dummy) { METHOD_TRACE("ips_setup", 1); +/* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */ +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + /* Search for value */ + while ((key = strsep(&ips_str, ",."))) { + if (!*key) + continue; + value = strchr(key, ':'); + if (value) + *value++ = '\0'; + /* + * We now have key/value pairs. + * Update the variables + */ + for (i = 0; i < (sizeof(options) / sizeof(options[0])); i++) { + if (strnicmp(key, options[i].option_name, strlen(options[i].option_name)) == 0) { + if (value) + *options[i].option_flag = simple_strtoul(value, NULL, 0); + else + *options[i].option_flag = options[i].option_value; + break; + } + } + } +#else for (key = strtok(ips_str, tokens); key; key = strtok(NULL, tokens)) { p = key; @@ -495,6 +536,8 @@ ips_setup(char *ips_str, int *dummy) { } } } +#endif + #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13) return (1); #endif @@ -519,29 +562,29 @@ int ips_detect(Scsi_Host_Template *SHT) { struct Scsi_Host *sh; ips_ha_t *ha; - u32 io_addr; - u32 mem_addr; - u32 io_len; - u32 mem_len; - u16 planer; - u8 revision_id; - u8 bus; - u8 func; - u8 irq; - u16 deviceID[2]; - u16 subdevice_id; + u_int32_t io_addr; + u_int32_t mem_addr; + u_int32_t io_len; + u_int32_t mem_len; + u_int16_t planer; + u_int8_t revision_id; + u_int8_t bus; + u_int8_t func; + u_int8_t irq; + u_int16_t deviceID[2]; + u_int16_t subdevice_id; int i; int j; - u32 count; + u_int32_t count; char *ioremap_ptr; char *mem_ptr; struct pci_dev *dev[2]; struct pci_dev *morpheus = NULL; struct pci_dev *trombone = NULL; #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,14) - u32 currbar; - u32 maskbar; - u8 barnum; + u_int32_t currbar; + u_int32_t maskbar; + u_int8_t barnum; #endif METHOD_TRACE("ips_detect", 1); @@ -557,8 +600,8 @@ ips_detect(Scsi_Host_Template *SHT) { /* If Booting from the ServeRAID Manager CD, Allocate a large Flash */ /* Buffer ( so we won't need to allocate one for each adapter ). */ - if ( ips_cd_boot ) { - ips_FlashData = ( char * ) __get_free_pages( GFP_KERNEL, 7 ); + if ( ips_cd_boot ) { + ips_FlashData = ( char * ) __get_free_pages( GFP_KERNEL, 7 ); if (ips_FlashData == NULL) { /* The validity of this pointer is checked in ips_make_passthru() before it is used */ printk( KERN_WARNING "ERROR: Can't Allocate Large Buffer for Flashing\n" ); @@ -598,12 +641,12 @@ ips_detect(Scsi_Host_Template *SHT) { deviceID[0] = IPS_DEVICEID_MORPHEUS; } else { /* we have both in the system */ - if (trombone->bus < morpheus->bus) { + if (trombone->bus->number < morpheus->bus->number) { dev[0] = trombone; dev[1] = morpheus; deviceID[0] = IPS_DEVICEID_COPPERHEAD; deviceID[1] = IPS_DEVICEID_MORPHEUS; - } else if (trombone->bus > morpheus->bus) { + } else if (trombone->bus->number > morpheus->bus->number) { dev[0] = morpheus; dev[1] = trombone; deviceID[0] = IPS_DEVICEID_MORPHEUS; @@ -704,8 +747,8 @@ ips_detect(Scsi_Host_Template *SHT) { /* setup memory mapped area (if applicable) */ if (mem_addr) { - u32 base; - u32 offs; + u_int32_t base; + u_int32_t offs; DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d", ips_name, ips_next_controller, mem_addr, mem_len); @@ -773,11 +816,11 @@ ips_detect(Scsi_Host_Template *SHT) { continue; } - DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %x", - ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, (u32) mem_ptr); + DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %p", + ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, mem_ptr); /* get the revision ID */ - if (pci_read_config_byte(dev[i], 0x08, &revision_id)) { + if (pci_read_config_byte(dev[i], PCI_REVISION_ID, &revision_id)) { printk(KERN_WARNING "(%s%d) can't get revision id.\n", ips_name, ips_next_controller); @@ -788,7 +831,7 @@ ips_detect(Scsi_Host_Template *SHT) { #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,15) /* get the subdevice id */ - if (pci_read_config_word(dev[i], 0x2e, &subdevice_id)) { + if (pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id)) { printk(KERN_WARNING "(%s%d) can't get subdevice id.\n", ips_name, ips_next_controller); @@ -828,7 +871,7 @@ ips_detect(Scsi_Host_Template *SHT) { ips_num_controllers++; ha->active = 1; - ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_ATOMIC); + ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL); if (!ha->enq) { printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n", @@ -845,7 +888,7 @@ ips_detect(Scsi_Host_Template *SHT) { continue; } - ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_ATOMIC); + ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL); if (!ha->adapt) { printk(KERN_WARNING "(%s%d) Unable to allocate host adapt structure - skipping controller\n", @@ -862,7 +905,7 @@ ips_detect(Scsi_Host_Template *SHT) { continue; } - ha->conf = kmalloc(sizeof(IPS_CONF), GFP_ATOMIC); + ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL); if (!ha->conf) { printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n", @@ -879,7 +922,7 @@ ips_detect(Scsi_Host_Template *SHT) { continue; } - ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_ATOMIC); + ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL); if (!ha->nvram) { printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n", @@ -896,7 +939,7 @@ ips_detect(Scsi_Host_Template *SHT) { continue; } - ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_ATOMIC); + ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL); if (!ha->subsys) { printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n", @@ -913,7 +956,7 @@ ips_detect(Scsi_Host_Template *SHT) { continue; } - ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_ATOMIC); + ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL); if (!ha->dummy) { printk(KERN_WARNING "(%s%d) Unable to allocate host dummy structure - skipping controller\n", @@ -957,11 +1000,10 @@ ips_detect(Scsi_Host_Template *SHT) { sh->cmd_per_lun = sh->hostt->cmd_per_lun; sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; sh->use_clustering = sh->hostt->use_clustering; -/***** Implement the following if it gets into a future kernel -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,4) + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7) sh->max_sectors = 128; #endif -******/ #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,32) sh->wish_block = FALSE; @@ -1075,7 +1117,7 @@ ips_detect(Scsi_Host_Template *SHT) { /* * Allocate a temporary SCB for initialization */ - ha->scbs = (ips_scb_t *) kmalloc(sizeof(ips_scb_t), GFP_ATOMIC); + ha->scbs = (ips_scb_t *) kmalloc(sizeof(ips_scb_t), GFP_KERNEL); if (!ha->scbs) { /* couldn't allocate a temp SCB */ printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n", @@ -1094,7 +1136,7 @@ ips_detect(Scsi_Host_Template *SHT) { } memset(ha->scbs, 0, sizeof(ips_scb_t)); - ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_ATOMIC); + ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_KERNEL); if (!ha->scbs->sg_list) { /* couldn't allocate a temp SCB S/G list */ printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n", @@ -1217,9 +1259,14 @@ ips_release(struct Scsi_Host *sh) { for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++); - if (i == IPS_MAX_ADAPTERS) - panic("(%s) release, invalid Scsi_Host pointer.\n", + if (i == IPS_MAX_ADAPTERS) { + printk(KERN_WARNING "(%s) release, invalid Scsi_Host pointer.\n", ips_name); +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + BUG(); +#endif + return (FALSE); + } ha = IPS_HA(sh); @@ -1242,13 +1289,13 @@ ips_release(struct Scsi_Host *sh) { scb->cmd.flush_cache.reserved3 = 0; scb->cmd.flush_cache.reserved4 = 0; - printk("(%s%d) Flushing Cache.\n", ips_name, ha->host_num); + printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, ha->host_num); /* send command */ if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) - printk("(%s%d) Incomplete Flush.\n", ips_name, ha->host_num); + printk(KERN_NOTICE "(%s%d) Incomplete Flush.\n", ips_name, ha->host_num); - printk("(%s%d) Flushing Complete.\n", ips_name, ha->host_num); + printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", ips_name, ha->host_num); ips_sh[i] = NULL; ips_ha[i] = NULL; @@ -1260,11 +1307,6 @@ ips_release(struct Scsi_Host *sh) { if (ha->io_addr) release_region(ha->io_addr, ha->io_len); -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17) - if (ha->mem_addr) - release_mem_region(ha->mem_addr, ha->mem_len); -#endif - /* free IRQ */ free_irq(ha->irq, ha); @@ -1322,16 +1364,15 @@ ips_halt(struct notifier_block *nb, ulong event, void *buf) { scb->cmd.flush_cache.reserved3 = 0; scb->cmd.flush_cache.reserved4 = 0; - printk("(%s%d) Flushing Cache.\n", ips_name, ha->host_num); + printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, ha->host_num); /* send command */ if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) - printk("(%s%d) Incomplete Flush.\n", ips_name, ha->host_num); + printk(KERN_NOTICE "(%s%d) Incomplete Flush.\n", ips_name, ha->host_num); else - printk("(%s%d) Flushing Complete.\n", ips_name, ha->host_num); + printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", ips_name, ha->host_num); } - unregister_reboot_notifier(&ips_notifier); return (NOTIFY_OK); } @@ -1416,10 +1457,10 @@ int ips_eh_reset(Scsi_Cmnd *SC) { int ret; int i; - unsigned long cpu_flags; ips_ha_t *ha; ips_scb_t *scb; ips_copp_wait_item_t *item; + unsigned long cpu_flags; METHOD_TRACE("ips_eh_reset", 1); @@ -1543,7 +1584,7 @@ ips_eh_reset(Scsi_Cmnd *SC) { } /* FFDC */ - if (ha->subsys->param[3] & 0x300000) { + if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) { struct timeval tv; do_gettimeofday(&tv); @@ -1608,7 +1649,6 @@ int ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { ips_ha_t *ha; unsigned long cpu_flags; - DECLARE_MUTEX_LOCKED(sem); METHOD_TRACE("ips_queue", 1); @@ -1669,8 +1709,23 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { #ifndef NO_IPS_CMDLINE if (ips_is_passthru(SC)) { + ips_copp_wait_item_t *scratch; + /* The IPS_IOCTL_NEW_COMMAND is only used to flash an adapter. This should */ + /* never happen when the adapter is active. Just in case, check here, and */ + /* reject the command if anything else is going on. */ + if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) { + if (ha->scb_activelist.count != 0) { + /* printk( KERN_WARNING "New IOCTL Cmd Return BUSY: %d Cmds Active\n", */ + /* ha->scb_activelist.count ); */ + SC->result = DID_BUS_BUSY << 16; + done(SC); + + return (0); + } + } + /* allocate space for the scribble */ scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_ATOMIC); @@ -1682,7 +1737,8 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { } scratch->scsi_cmd = SC; - scratch->sem = &sem; + sema_init(&ha->ioctl_sem, 0); + scratch->sem = &ha->ioctl_sem; scratch->next = NULL; ips_putq_copp_tail(&ha->copp_waitlist, scratch); @@ -1709,15 +1765,15 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { * not cause contention problems */ if (ips_is_passthru(SC) && SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) { - char *user_area; - char *kern_area; - u32 datasize; + char *user_area; + char *kern_area; + u_int32_t datasize; /* free io_request_lock */ spin_unlock_irq(&io_request_lock); /* wait for the command to finish */ - down(&sem); + down(&ha->ioctl_sem); /* reobtain the lock */ spin_lock_irq(&io_request_lock); @@ -1725,21 +1781,17 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { /* command finished -- copy back */ user_area = *((char **) &SC->cmnd[4]); kern_area = ha->ioctl_data; - datasize = *((u32 *) &SC->cmnd[8]); + datasize = *((u_int32_t *) &SC->cmnd[8]); if (datasize) { if (copy_to_user(user_area, kern_area, datasize) > 0) { DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy out user data", ips_name, ha->host_num); - SC->result = DID_ERROR << 16; - SC->scsi_done(SC); - } else { - SC->scsi_done(SC); } - } else { - SC->scsi_done(SC); } + + SC->scsi_done(SC); } /* If We were using the CD Boot Flash Buffer, Restore the Old Values */ @@ -1819,8 +1871,10 @@ ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) { Scsi_Device *device; ips_ha_t *ha; int count = 0; + int min; ha = IPS_HA(host); + min = ha->max_cmds / 4; for (device = scsi_devs; device; device = device->next) { if (device->host == host) { @@ -1831,10 +1885,14 @@ ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) { for (device = scsi_devs; device; device = device->next) { if (device->host == host) { - if ((device->channel == 0) && (device->type == 0)) - device->queue_depth = ha->max_cmds / count - 1; - else + if ((device->channel == 0) && (device->type == 0)) { + device->queue_depth = ( ha->max_cmds - 1 ) / count; + if (device->queue_depth < min) + device->queue_depth = min; + } + else { device->queue_depth = 2; + } if (device->queue_depth < 2) device->queue_depth = 2; @@ -1943,9 +2001,7 @@ ips_intr_copperhead(ips_ha_t *ha) { cstatus.value = (*ha->func.statupd)(ha); if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) { - printk(KERN_WARNING "(%s%d) Spurious interrupt; no ccb.\n", - ips_name, ha->host_num); - + /* Spurious Interupt ? */ continue; } @@ -2065,9 +2121,7 @@ ips_info(struct Scsi_Host *SH) { bp = &buffer[0]; memset(bp, 0, sizeof(buffer)); - strcpy(bp, "IBM PCI ServeRAID "); - strcat(bp, IPS_VERSION_HIGH); - strcat(bp, IPS_VERSION_LOW); + sprintf(bp, "%s%s%s", "IBM PCI ServeRAID ", IPS_VERSION_HIGH, IPS_VERSION_LOW ); if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) { @@ -2250,37 +2304,14 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { return (IPS_FAILURE); } - if ((pt->CoppCP.cmd.nvram.op_code == IPS_CMD_RW_NVRAM_PAGE) && - (pt->CoppCP.cmd.nvram.page == 5) && - (pt->CoppCP.cmd.nvram.write == 0)) { - - if (pt->CmdBSize < sizeof(IPS_NVRAM_P5)) { - SC->result = DID_ERROR << 16; - - return (IPS_FAILURE); - } - - ips_get_bios_version(ha, IPS_INTR_IORL); - ips_create_nvrampage5(ha, &nvram); - - /* Copy the result back */ - memcpy(SC->request_buffer + sizeof(ips_passthru_t), &nvram, sizeof(IPS_NVRAM_P5)); - - SC->result = DID_OK << 16; - pt->BasicStatus = 0x00; - pt->ExtendedStatus = 0x00; - - return (IPS_SUCCESS_IMM); - } - if (ips_usrcmd(ha, pt, scb)) return (IPS_SUCCESS); else return (IPS_FAILURE); } else if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) { - char *user_area; - char *kern_area; - u32 datasize; + char *user_area; + char *kern_area; + u_int32_t datasize; if (SC->request_bufflen < (sizeof(ips_passthru_t))) { /* wrong size */ @@ -2292,7 +2323,6 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { return (IPS_FAILURE); } - /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */ /* avoid allocating a huge buffer per adapter ( which can fail ). */ if ( (ips_FlashData) && @@ -2305,28 +2335,28 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { ha->ioctl_data = ips_FlashData; ha->ioctl_order = 7; ha->ioctl_datasize = IPS_IMAGE_SIZE; - } + } if ((pt->CoppCP.cmd.nvram.op_code == IPS_CMD_RW_NVRAM_PAGE) && (pt->CoppCP.cmd.nvram.page == 5) && (pt->CoppCP.cmd.nvram.write == 0)) { - datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]); + datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]); if (datasize < sizeof(IPS_NVRAM_P5)) { pt->BasicStatus = 0x0B; pt->ExtendedStatus = 0x00; SC->result = DID_ERROR << 16; - return (IPS_FAILURE); - } + return (IPS_FAILURE); + } ips_get_bios_version(ha, IPS_INTR_IORL); ips_create_nvrampage5(ha, &nvram); user_area = *((char **) &scb->scsi_cmd->cmnd[4]); kern_area = (char *) &nvram; - datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]); + datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]); if (datasize > sizeof(IPS_NVRAM_P5)) datasize = sizeof(IPS_NVRAM_P5); @@ -2337,7 +2367,7 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { pt->ExtendedStatus = 0x00; SC->result = DID_ERROR << 16; - return (IPS_FAILURE); + return (EFAULT); } pt->BasicStatus = 0x00; @@ -2356,7 +2386,6 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { (ha->device_id == IPS_DEVICEID_COPPERHEAD)) { struct tq_struct task; IPS_FLASH_DATA flash_data; - DECLARE_MUTEX_LOCKED(sem); /* We only support one packet */ if (pt->CoppCP.cmd.flashfw.total_packets != 1) { @@ -2371,8 +2400,8 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4); memcpy(&pt->CmdBSize, &SC->cmnd[8], 4); - if (pt->CmdBSize > pt->CoppCP.cmd.flashfw.count) { - pt->CmdBSize = pt->CoppCP.cmd.flashfw.count; + if (pt->CmdBSize > le32_to_cpu(pt->CoppCP.cmd.flashfw.count)) { + pt->CmdBSize = le32_to_cpu(pt->CoppCP.cmd.flashfw.count); } else { /* ERROR: Command/Buffer mismatch */ pt->BasicStatus = 0x0B; @@ -2382,8 +2411,8 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { return (IPS_FAILURE); } - if ((!ha->func.programbios) || - (!ha->func.erasebios) || + if ((!ha->func.programbios) || + (!ha->func.erasebios) || (!ha->func.verifybios)) { pt->BasicStatus = 0x0B; pt->ExtendedStatus = 0x00; @@ -2404,8 +2433,8 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { /* make sure buffer is big enough */ if (pt->CmdBSize > ha->ioctl_datasize) { void *bigger_struct; - u32 count; - u32 order; + u_int32_t count; + u_int32_t order; /* try to allocate a bigger struct */ for (count = PAGE_SIZE, order = 0; @@ -2451,7 +2480,8 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { flash_data.SC = (void *) SC; flash_data.pt = (void *) pt; flash_data.ha = (void *) ha; - flash_data.sem = &sem; + sema_init( &ha->flash_ioctl_sem, 0 ); + flash_data.sem = &ha->flash_ioctl_sem; task.sync = 0; task.routine = ips_scheduled_flash_bios; @@ -2462,9 +2492,9 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { queue_task(&task, &tq_immediate); mark_bh(IMMEDIATE_BH); - + /* Wait for the flash to complete */ - down(&sem); + down(&ha->flash_ioctl_sem); /* Obtain the master lock */ spin_lock_irq(&io_request_lock); @@ -2481,14 +2511,13 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { (ha->device_id == IPS_DEVICEID_COPPERHEAD)) { struct tq_struct task; IPS_FLASH_DATA flash_data; - DECLARE_MUTEX_LOCKED(sem); - /* copy in the size/buffer ptr from the scsi command */ - memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4); - memcpy(&pt->CmdBSize, &SC->cmnd[8], 4); + /* copy in the size/buffer ptr from the scsi command */ + memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4); + memcpy(&pt->CmdBSize, &SC->cmnd[8], 4); - if (pt->CmdBSize > pt->CoppCP.cmd.flashbios.count) { - pt->CmdBSize = pt->CoppCP.cmd.flashbios.count; + if (pt->CmdBSize > le32_to_cpu(pt->CoppCP.cmd.flashbios.count)) { + pt->CmdBSize = le32_to_cpu(pt->CoppCP.cmd.flashbios.count); } else { /* ERROR: Command/Buffer mismatch */ pt->BasicStatus = 0x0B; @@ -2509,32 +2538,32 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { return (IPS_FAILURE); } - /* must have a buffer */ + /* must have a buffer */ if ((!pt->CmdBSize) || (!pt->CmdBuffer)) { pt->BasicStatus = 0x0B; pt->ExtendedStatus = 0x00; SC->result = DID_ERROR << 16; - return (IPS_FAILURE); + return (IPS_FAILURE); } - /* make sure buffer is big enough */ - if (pt->CmdBSize > ha->ioctl_datasize) { - void *bigger_struct; - u32 count; - u32 order; + /* make sure buffer is big enough */ + if (pt->CmdBSize > ha->ioctl_datasize) { + void *bigger_struct; + u_int32_t count; + u_int32_t order; - /* try to allocate a bigger struct */ + /* try to allocate a bigger struct */ for (count = PAGE_SIZE, order = 0; count < pt->CmdBSize; order++, count <<= 1); bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order); - if (bigger_struct) { - /* free the old memory */ + if (bigger_struct) { + /* free the old memory */ free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order); - /* use the new memory */ + /* use the new memory */ ha->ioctl_data = (char *) bigger_struct; ha->ioctl_order = order; ha->ioctl_datasize = count; @@ -2549,26 +2578,27 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { } } - /* copy in the buffer */ - if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) { - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer", - ips_name, ha->host_num); + /* copy in the buffer */ + if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) { + DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer", + ips_name, ha->host_num); pt->BasicStatus = 0x0B; pt->ExtendedStatus = 0x00; SC->result = DID_ERROR << 16; - return (IPS_FAILURE); + return (EFAULT); } flash_data.userbuffer = pt->CmdBuffer; flash_data.usersize = pt->CmdBSize; flash_data.kernbuffer = ha->ioctl_data; flash_data.kernsize = ha->ioctl_datasize; - flash_data.offset = pt->CoppCP.cmd.flashbios.offset; + flash_data.offset = le32_to_cpu(pt->CoppCP.cmd.flashbios.offset); flash_data.SC = (void *) SC; flash_data.pt = (void *) pt; flash_data.ha = (void *) ha; - flash_data.sem = &sem; + sema_init( &ha->flash_ioctl_sem, 0 ); + flash_data.sem = &ha->flash_ioctl_sem; task.sync = 0; task.routine = ips_flash_bios_section; @@ -2579,9 +2609,9 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { queue_task(&task, &tq_immediate); mark_bh(IMMEDIATE_BH); - + /* Wait for the flash to complete */ - down(&sem); + down(&ha->flash_ioctl_sem); /* Obtain the master lock */ spin_lock_irq(&io_request_lock); @@ -2602,9 +2632,9 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { return (IPS_FAILURE); } - if ((*ha->func.erasebios)(ha)) { - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash", - ips_name, ha->host_num); + if ((*ha->func.erasebios)(ha)) { + DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash", + ips_name, ha->host_num); pt->BasicStatus = 0x0B; pt->ExtendedStatus = 0x00; SC->result = DID_ERROR << 16; @@ -2629,8 +2659,8 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { } /* end switch */ - return (IPS_FAILURE); -} + return (IPS_FAILURE); + } /****************************************************************************/ /* */ @@ -2673,7 +2703,7 @@ ips_scheduled_flash_bios(void *data) { if ((*ha->func.erasebios)(ha)) { DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash", - ips_name, ha->host_num); + ips_name, ha->host_num); pt->BasicStatus = 0x0B; pt->ExtendedStatus = 0x00; SC->result = DID_ERROR << 16; @@ -2689,8 +2719,8 @@ ips_scheduled_flash_bios(void *data) { return ; if ((*ha->func.verifybios)(ha, fd->kernbuffer, fd->usersize, fd->offset)) { - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash", - ips_name, ha->host_num); + DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash", + ips_name, ha->host_num); pt->BasicStatus = 0x0B; pt->ExtendedStatus = 0x00; SC->result = DID_ERROR << 16; @@ -2827,13 +2857,13 @@ ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { } if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) - scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb); + scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb)); if (pt->CmdBSize) { if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) - scb->dcdb.buffer_pointer = scb->data_busaddr; + scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); else - scb->cmd.basic_io.sg_addr = scb->data_busaddr; + scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); } /* set timeouts */ @@ -2869,7 +2899,7 @@ ips_newusrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { IPS_SG_LIST *sg_list; char *user_area; char *kern_area; - u32 datasize; + u_int32_t datasize; METHOD_TRACE("ips_usrcmd", 1); @@ -2906,8 +2936,8 @@ ips_newusrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { if (pt->CmdBSize) { if (pt->CmdBSize > ha->ioctl_datasize) { void *bigger_struct; - u32 count; - u32 order; + u_int32_t count; + u_int32_t order; /* try to allocate a bigger struct */ for (count = PAGE_SIZE, order = 0; @@ -2933,7 +2963,7 @@ ips_newusrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { /* Attempt to copy in the data */ user_area = *((char **) &scb->scsi_cmd->cmnd[4]); kern_area = ha->ioctl_data; - datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]); + datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]); if (copy_from_user(kern_area, user_area, datasize) > 0) { DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy in user data", @@ -2947,13 +2977,13 @@ ips_newusrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { } if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) - scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb); + scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb)); if (pt->CmdBSize) { if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) - scb->dcdb.buffer_pointer = scb->data_busaddr; + scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); else - scb->cmd.basic_io.sg_addr = scb->data_busaddr; + scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); } /* set timeouts */ @@ -3000,19 +3030,15 @@ ips_cleanup_passthru(ips_ha_t *ha, ips_scb_t *scb) { pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer; /* Copy data back to the user */ - if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) { /* Copy DCDB Back to Caller's Area */ + if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */ memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof(IPS_DCDB_TABLE)); - } + + pt->BasicStatus = scb->basic_status; + pt->ExtendedStatus = scb->extended_status; - if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_COMMAND) { - /* Copy data back to the user */ - pt->BasicStatus = scb->basic_status; - pt->ExtendedStatus = scb->extended_status; - } else { - pt->BasicStatus = scb->basic_status; - pt->ExtendedStatus = scb->extended_status; - up(scb->sem); - } + if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) + up(&ha->ioctl_sem); + } #endif @@ -3040,8 +3066,8 @@ ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) { copy_info(&info, "\nIBM ServeRAID General Information:\n\n"); - if ((ha->nvram->signature == IPS_NVRAM_P5_SIG) && - (ha->nvram->adapter_type != 0)) + if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) && + (le16_to_cpu(ha->nvram->adapter_type) != 0)) copy_info(&info, "\tController Type : %s\n", ips_adapter_name[ha->ad_type-1]); else copy_info(&info, "\tController Type : Unknown\n"); @@ -3058,7 +3084,7 @@ ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) { copy_info(&info, "\tIRQ number : %d\n", ha->irq); - if (ha->nvram->signature == IPS_NVRAM_P5_SIG) + if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) copy_info(&info, "\tBIOS Version : %c%c%c%c%c%c%c%c\n", ha->nvram->bios_high[0], ha->nvram->bios_high[1], ha->nvram->bios_high[2], ha->nvram->bios_high[3], @@ -3254,10 +3280,10 @@ static void ips_get_bios_version(ips_ha_t *ha, int intr) { ips_scb_t *scb; int ret; - u8 major; - u8 minor; - u8 subminor; - u8 *buffer; + u_int8_t major; + u_int8_t minor; + u_int8_t subminor; + u_int8_t *buffer; char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; METHOD_TRACE("ips_get_bios_version", 1); @@ -3279,7 +3305,7 @@ ips_get_bios_version(ips_ha_t *ha, int intr) { if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55) return; - writel(1, ha->mem_ptr + IPS_REG_FLAP); + writel(cpu_to_le32(1), ha->mem_ptr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ @@ -3287,27 +3313,24 @@ ips_get_bios_version(ips_ha_t *ha, int intr) { return; /* Get Major version */ - writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP); + writel(cpu_to_le32(0x1FF), ha->mem_ptr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ major = readb(ha->mem_ptr + IPS_REG_FLDP); /* Get Minor version */ - writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP); + writel(cpu_to_le32(0x1FE), ha->mem_ptr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ - minor = readb(ha->mem_ptr + IPS_REG_FLDP); - /* Get Sub Minor version */ - writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP); + /* Get SubMinor version */ + writel(cpu_to_le32(0x1FD), ha->mem_ptr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(5);/* 5 us */ - + udelay(5); /* 5 us */ subminor = readb(ha->mem_ptr + IPS_REG_FLDP); - } else { /* Programmed I/O */ @@ -3319,7 +3342,7 @@ ips_get_bios_version(ips_ha_t *ha, int intr) { if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) return ; - outl(1, ha->io_addr + IPS_REG_FLAP); + outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ @@ -3327,21 +3350,21 @@ ips_get_bios_version(ips_ha_t *ha, int intr) { return ; /* Get Major version */ - outl(0x1FF, ha->io_addr + IPS_REG_FLAP); + outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ major = inb(ha->io_addr + IPS_REG_FLDP); /* Get Minor version */ - outl(0x1FE, ha->io_addr + IPS_REG_FLAP); + outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ minor = inb(ha->io_addr + IPS_REG_FLDP); - + /* Get SubMinor version */ - outl(0x1FD, ha->io_addr + IPS_REG_FLAP); + outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ @@ -3368,8 +3391,8 @@ ips_get_bios_version(ips_ha_t *ha, int intr) { scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.flashfw.type = 1; scb->cmd.flashfw.direction = 0; - scb->cmd.flashfw.count = 0x800; - scb->cmd.flashfw.buffer_addr = VIRT_TO_BUS(buffer); + scb->cmd.flashfw.count = cpu_to_le32(0x800); + scb->cmd.flashfw.buffer_addr = cpu_to_le32(VIRT_TO_BUS(buffer)); scb->cmd.flashfw.total_packets = 1; scb->cmd.flashfw.packet_num = 0; @@ -3384,10 +3407,9 @@ ips_get_bios_version(ips_ha_t *ha, int intr) { } if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) { - major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */ - minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */ - subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fe after the header (0xc0) */ - + major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */ + minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */ + subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */ } else { return; } @@ -3495,7 +3517,7 @@ ips_hainit(ips_ha_t *ha) { } /* setup max concurrent commands */ - if (ha->subsys->param[4] & 0x1) { + if (le32_to_cpu(ha->subsys->param[4]) & 0x1) { /* Use the new method */ ha->max_cmds = ha->enq->ucConcurrentCmdCount; } else { @@ -3570,7 +3592,7 @@ ips_next(ips_ha_t *ha, int intr) { cpu_flags2 = 0; } - if (ha->subsys->param[3] & 0x300000) { + if ((ha->subsys->param[3] & 0x300000) && ( ha->scb_activelist.count == 0 )) { struct timeval tv; do_gettimeofday(&tv); @@ -3604,6 +3626,7 @@ ips_next(ips_ha_t *ha, int intr) { IPS_QUEUE_UNLOCK(&ha->copp_waitlist); item = ips_removeq_copp_head(&ha->copp_waitlist); + ha->num_ioctl++; IPS_HA_UNLOCK(cpu_flags); scb->scsi_cmd = item->scsi_cmd; scb->sem = item->sem; @@ -3618,14 +3641,14 @@ ips_next(ips_ha_t *ha, int intr) { /* raise the semaphore */ if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) { - u32 datasize; + u_int32_t datasize; datasize = 0; memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4); - up(scb->sem); + up(&ha->ioctl_sem); } else { scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } + } } ips_freescb(ha, scb); @@ -3636,11 +3659,11 @@ ips_next(ips_ha_t *ha, int intr) { /* raise the semaphore */ if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) { - u32 datasize; + u_int32_t datasize; datasize = 0; memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4); - up(scb->sem); + up(&ha->ioctl_sem); } else { scb->scsi_cmd->scsi_done(scb->scsi_cmd); } @@ -3655,22 +3678,23 @@ ips_next(ips_ha_t *ha, int intr) { if (ret != IPS_SUCCESS) { IPS_HA_LOCK(cpu_flags); IPS_QUEUE_LOCK(&ha->copp_waitlist); + ha->num_ioctl--; continue; } ret = ips_send_cmd(ha, scb); - if (ret == IPS_SUCCESS) { + if (ret == IPS_SUCCESS) ips_putq_scb_head(&ha->scb_activelist, scb); - ha->num_ioctl++; - } + else + ha->num_ioctl--; switch(ret) { case IPS_FAILURE: if (scb->scsi_cmd) { /* raise the semaphore */ if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) - up(scb->sem); + up(&ha->ioctl_sem); scb->scsi_cmd->result = DID_ERROR << 16; } @@ -3681,7 +3705,7 @@ ips_next(ips_ha_t *ha, int intr) { if (scb->scsi_cmd) { /* raise the semaphore */ if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) - up(scb->sem); + up(&ha->ioctl_sem); } ips_freescb(ha, scb); @@ -3716,7 +3740,7 @@ ips_next(ips_ha_t *ha, int intr) { SC = ips_removeq_wait(&ha->scb_waitlist, q); if (SC == NULL) /* Should never happen, but good to check anyway */ continue; - + IPS_HA_UNLOCK(cpu_flags); /* Unlock HA after command is taken off queue */ SC->result = DID_OK; @@ -3757,17 +3781,17 @@ ips_next(ips_ha_t *ha, int intr) { } else { /* Check for the first Element being bigger than MAX_XFER */ if (sg[0].length > ha->max_xfer) { - scb->sg_list[0].address = VIRT_TO_BUS(sg[0].address); + scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[0].address)); scb->sg_list[0].length = ha->max_xfer; scb->data_len = ha->max_xfer; scb->breakup = 0; - scb->sg_break=1; + scb->sg_break=1; scb->sg_len = 1; - } + } else { for (i = 0; i < SC->use_sg; i++) { - scb->sg_list[i].address = VIRT_TO_BUS(sg[i].address); - scb->sg_list[i].length = sg[i].length; + scb->sg_list[i].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address)); + scb->sg_list[i].length = cpu_to_le32(sg[i].length); if (scb->data_len + sg[i].length > ha->max_xfer) { /* @@ -3776,7 +3800,7 @@ ips_next(ips_ha_t *ha, int intr) { scb->breakup = i; break; } - + scb->data_len += sg[i].length; } @@ -4423,9 +4447,9 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { * data and had to be broke up. If so, queue * the rest of the data and continue. */ - if (scb->breakup || scb->sg_break) { - /* We had a data breakup */ - u8 bk_save; + if (scb->breakup) { + /* we had a data breakup */ + u_int8_t bk_save; bk_save = scb->breakup; scb->breakup = 0; @@ -4438,7 +4462,7 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { sg = scb->scsi_cmd->request_buffer; if (scb->scsi_cmd->use_sg == 1) { - if (sg[0].length - (bk_save * ha->max_xfer)) { + if (sg[0].length - (bk_save * ha->max_xfer) > ha->max_xfer) { /* Further breakup required */ scb->data_len = ha->max_xfer; scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer)); @@ -4480,7 +4504,7 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { } else { /* ( sg_break == 0 ), so this is our first look at a new sg piece */ if (sg[bk_save].length > ha->max_xfer) { - scb->sg_list[0].address = VIRT_TO_BUS(sg[bk_save].address); + scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[bk_save].address)); scb->sg_list[0].length = ha->max_xfer; scb->breakup = bk_save; scb->sg_break = 1; @@ -4493,8 +4517,8 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { scb->sg_break = 0; /* We're only doing full units here */ for (i = bk_save; i < scb->scsi_cmd->use_sg; i++) { - scb->sg_list[i - bk_save].address = VIRT_TO_BUS(sg[i].address); - scb->sg_list[i - bk_save].length = sg[i].length; + scb->sg_list[i - bk_save].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address)); + scb->sg_list[i - bk_save].length = cpu_to_le32(sg[i].length); if (scb->data_len + sg[i].length > ha->max_xfer) { scb->breakup = i; /* sneaky, if not more work, than breakup is 0 */ break; @@ -4510,7 +4534,8 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { scb->dcdb.transfer_length = scb->data_len; scb->data_busaddr = VIRT_TO_BUS(scb->sg_list); } - } else { + + } else { /* Non S/G Request */ if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) { /* Further breakup required */ @@ -4751,7 +4776,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { int ret; char *sp; int device_error; - + METHOD_TRACE("ips_send_cmd", 1); ret = IPS_SUCCESS; @@ -4800,27 +4825,29 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { scb->scsi_cmd->result = DID_OK << 16; if (scb->scsi_cmd->cmnd[0] == INQUIRY) { - IPS_INQ_DATA inq; + IPS_SCSI_INQ_DATA inquiry; - memset(&inq, 0, sizeof(IPS_INQ_DATA)); + memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA)); - inq.DeviceType = TYPE_PROCESSOR; - inq.DeviceTypeQualifier = 0; - inq.RemoveableMedia = 0; - inq.Versions = 0x1; /* SCSI I */ - inq.AdditionalLength = 31; - strncpy(inq.VendorId, "IBM ", 8); - strncpy(inq.ProductId, "SERVERAID ", 16); - strncpy(inq.ProductRevisionLevel, "1.00", 4); + inquiry.DeviceType = IPS_SCSI_INQ_TYPE_PROCESSOR; + inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; + inquiry.Version = IPS_SCSI_INQ_REV2; + inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; + inquiry.AdditionalLength = 31; + inquiry.Flags[0] = IPS_SCSI_INQ_Address16; + inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync; + strncpy(inquiry.VendorId, "IBM ", 8); + strncpy(inquiry.ProductId, "SERVERAID ", 16); + strncpy(inquiry.ProductRevisionLevel, "1.00", 4); - memcpy(scb->scsi_cmd->request_buffer, &inq, scb->scsi_cmd->request_bufflen); + memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen); scb->scsi_cmd->result = DID_OK << 16; } } else { scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.logical_info.buffer_addr = VIRT_TO_BUS(&ha->adapt->logical_drive_info); + scb->cmd.logical_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(&ha->adapt->logical_drive_info)); scb->cmd.logical_info.reserved = 0; scb->cmd.logical_info.reserved2 = 0; ret = IPS_SUCCESS; @@ -4846,19 +4873,20 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.basic_io.log_drv = scb->target_id; scb->cmd.basic_io.sg_count = scb->sg_len; - scb->cmd.basic_io.sg_addr = scb->data_busaddr; + scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); if (scb->cmd.basic_io.lba) - scb->cmd.basic_io.lba += scb->cmd.basic_io.sector_count; + scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) + + le16_to_cpu(scb->cmd.basic_io.sector_count)); else scb->cmd.basic_io.lba = (((scb->scsi_cmd->cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd->cmnd[2] << 8) | (scb->scsi_cmd->cmnd[3])); - scb->cmd.basic_io.sector_count = scb->data_len / IPS_BLKSIZE; + scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE); - if (scb->cmd.basic_io.sector_count == 0) - scb->cmd.basic_io.sector_count = 256; + if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0) + scb->cmd.basic_io.sector_count = cpu_to_le16(256); scb->cmd.basic_io.reserved = 0; ret = IPS_SUCCESS; @@ -4877,21 +4905,22 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.basic_io.log_drv = scb->target_id; scb->cmd.basic_io.sg_count = scb->sg_len; - scb->cmd.basic_io.sg_addr = scb->data_busaddr; + scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); if (scb->cmd.basic_io.lba) - scb->cmd.basic_io.lba += scb->cmd.basic_io.sector_count; + scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) + + le16_to_cpu(scb->cmd.basic_io.sector_count)); else scb->cmd.basic_io.lba = ((scb->scsi_cmd->cmnd[2] << 24) | (scb->scsi_cmd->cmnd[3] << 16) | (scb->scsi_cmd->cmnd[4] << 8) | scb->scsi_cmd->cmnd[5]); - scb->cmd.basic_io.sector_count = scb->data_len / IPS_BLKSIZE; + scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE); scb->cmd.basic_io.reserved = 0; - if (scb->cmd.basic_io.sector_count == 0) { + if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) { /* * This is a null condition * we don't have to do anything @@ -4911,14 +4940,14 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { case MODE_SENSE: scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->enq); + scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->enq)); ret = IPS_SUCCESS; break; case READ_CAPACITY: scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.logical_info.buffer_addr = VIRT_TO_BUS(&ha->adapt->logical_drive_info); + scb->cmd.logical_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(&ha->adapt->logical_drive_info)); scb->cmd.logical_info.reserved = 0; scb->cmd.logical_info.reserved2 = 0; scb->cmd.logical_info.reserved3 = 0; @@ -4974,7 +5003,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id); scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb); + scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb)); scb->cmd.dcdb.reserved = 0; scb->cmd.dcdb.reserved2 = 0; scb->cmd.dcdb.reserved3 = 0; @@ -4995,7 +5024,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; scb->dcdb.sense_length = sizeof(scb->scsi_cmd->sense_buffer); - scb->dcdb.buffer_pointer = scb->data_busaddr; + scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); scb->dcdb.sg_count = scb->sg_len; scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len; memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); @@ -5017,8 +5046,8 @@ static void ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) { ips_scb_t *scb; ips_stat_t *sp; - u8 basic_status; - u8 ext_status; + u_int8_t basic_status; + u_int8_t ext_status; int errcode; METHOD_TRACE("ips_chkstatus", 1); @@ -5029,7 +5058,7 @@ ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) { sp = &ha->sp; sp->residue_len = 0; - sp->scb_addr = (u32) scb; + sp->scb_addr = (void *) scb; /* Remove the item from the active queue */ ips_removeq_scb(&ha->scb_activelist, scb); @@ -5198,22 +5227,24 @@ ips_online(ips_ha_t *ha, ips_scb_t *scb) { /****************************************************************************/ static int ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) { - IPS_INQ_DATA inq; + IPS_SCSI_INQ_DATA inquiry; METHOD_TRACE("ips_inquiry", 1); - memset(&inq, 0, sizeof(IPS_INQ_DATA)); + memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA)); - inq.DeviceType = TYPE_DISK; - inq.DeviceTypeQualifier = 0; - inq.RemoveableMedia = 0; - inq.Versions = 0x1; /* SCSI I */ - inq.AdditionalLength = 31; - strncpy(inq.VendorId, "IBM ", 8); - strncpy(inq.ProductId, "SERVERAID ", 16); - strncpy(inq.ProductRevisionLevel, "1.00", 4); + inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD; + inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; + inquiry.Version = IPS_SCSI_INQ_REV2; + inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; + inquiry.AdditionalLength = 31; + inquiry.Flags[0] = IPS_SCSI_INQ_Address16; + inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync; + strncpy(inquiry.VendorId, "IBM ", 8); + strncpy(inquiry.ProductId, "SERVERAID ", 16); + strncpy(inquiry.ProductRevisionLevel, "1.00", 4); - memcpy(scb->scsi_cmd->request_buffer, &inq, scb->scsi_cmd->request_bufflen); + memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen); return (1); } @@ -5229,17 +5260,17 @@ ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) { /****************************************************************************/ static int ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) { - IPS_CAPACITY *cap; + IPS_SCSI_CAPACITY *cap; METHOD_TRACE("ips_rdcap", 1); if (scb->scsi_cmd->bufflen < 8) return (0); - cap = (IPS_CAPACITY *) scb->scsi_cmd->request_buffer; + cap = (IPS_SCSI_CAPACITY *) scb->scsi_cmd->request_buffer; - cap->lba = htonl(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count - 1); - cap->len = htonl((u32) IPS_BLKSIZE); + cap->lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1); + cap->len = cpu_to_be32((u_int32_t) IPS_BLKSIZE); return (1); } @@ -5255,14 +5286,14 @@ ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) { /****************************************************************************/ static int ips_msense(ips_ha_t *ha, ips_scb_t *scb) { - u16 heads; - u16 sectors; - u32 cylinders; - ips_mdata_t mdata; + u_int16_t heads; + u_int16_t sectors; + u_int32_t cylinders; + IPS_SCSI_MODE_PAGE_DATA mdata; METHOD_TRACE("ips_msense", 1); - if (ha->enq->ulDriveSize[scb->target_id] > 0x400000 && + if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 && (ha->enq->ucMiscFlag & 0x8) == 0) { heads = IPS_NORM_HEADS; sectors = IPS_NORM_SECTORS; @@ -5271,51 +5302,48 @@ ips_msense(ips_ha_t *ha, ips_scb_t *scb) { sectors = IPS_COMP_SECTORS; } - cylinders = ha->enq->ulDriveSize[scb->target_id] / (heads * sectors); + cylinders = (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) - 1) / (heads * sectors); - mdata.plh.plh_type = 0; - mdata.plh.plh_wp = 0; - mdata.plh.plh_bdl = 8; + memset(&mdata, 0, sizeof(IPS_SCSI_MODE_PAGE_DATA)); + + mdata.hdr.BlockDescLength = 8; switch (scb->scsi_cmd->cmnd[2] & 0x3f) { case 0x03: /* page 3 */ - mdata.pdata.pg3.pg_pc = 0x3; - mdata.pdata.pg3.pg_res1 = 0; - mdata.pdata.pg3.pg_len = sizeof(IPS_DADF); - mdata.plh.plh_len = 3 + mdata.plh.plh_bdl + mdata.pdata.pg3.pg_len; - mdata.pdata.pg3.pg_trk_z = 0; - mdata.pdata.pg3.pg_asec_z = 0; - mdata.pdata.pg3.pg_atrk_z = 0; - mdata.pdata.pg3.pg_atrk_v = 0; - mdata.pdata.pg3.pg_sec_t = htons(sectors); - mdata.pdata.pg3.pg_bytes_s = htons(IPS_BLKSIZE); - mdata.pdata.pg3.pg_intl = htons(1); - mdata.pdata.pg3.pg_trkskew = 0; - mdata.pdata.pg3.pg_cylskew = 0; - mdata.pdata.pg3.pg_res2 = 0; - mdata.pdata.pg3.pg_ins = 0; - mdata.pdata.pg3.pg_surf = 0; - mdata.pdata.pg3.pg_rmb = 0; - mdata.pdata.pg3.pg_hsec = 0; - mdata.pdata.pg3.pg_ssec = 1; + mdata.pdata.pg3.PageCode = 3; + mdata.pdata.pg3.PageLength = sizeof(IPS_SCSI_MODE_PAGE3); + mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength; + mdata.pdata.pg3.TracksPerZone = 0; + mdata.pdata.pg3.AltSectorsPerZone = 0; + mdata.pdata.pg3.AltTracksPerZone = 0; + mdata.pdata.pg3.AltTracksPerVolume = 0; + mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors); + mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE); + mdata.pdata.pg3.Interleave = cpu_to_be16(1); + mdata.pdata.pg3.TrackSkew = 0; + mdata.pdata.pg3.CylinderSkew = 0; + mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector; break; case 0x4: - mdata.pdata.pg4.pg_pc = 0x4; - mdata.pdata.pg4.pg_res1 = 0; - mdata.pdata.pg4.pg_len = sizeof(IPS_RDDG); - mdata.plh.plh_len = 3 + mdata.plh.plh_bdl + mdata.pdata.pg4.pg_len; - mdata.pdata.pg4.pg_cylu = (cylinders >> 8) & 0xffff; - mdata.pdata.pg4.pg_cyll = cylinders & 0xff; - mdata.pdata.pg4.pg_head = heads; - mdata.pdata.pg4.pg_wrpcompu = 0; - mdata.pdata.pg4.pg_wrpcompl = 0; - mdata.pdata.pg4.pg_redwrcur = 0; - mdata.pdata.pg4.pg_drstep = htons(1); - mdata.pdata.pg4.pg_landu = 0; - mdata.pdata.pg4.pg_landl = 0; - mdata.pdata.pg4.pg_res2 = 0; + mdata.pdata.pg4.PageCode = 4; + mdata.pdata.pg4.PageLength = sizeof(IPS_SCSI_MODE_PAGE4); + mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength; + mdata.pdata.pg4.CylindersHigh = cpu_to_be16((cylinders >> 8) & 0xFFFF); + mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF); + mdata.pdata.pg4.Heads = heads; + mdata.pdata.pg4.WritePrecompHigh = 0; + mdata.pdata.pg4.WritePrecompLow = 0; + mdata.pdata.pg4.ReducedWriteCurrentHigh = 0; + mdata.pdata.pg4.ReducedWriteCurrentLow = 0; + mdata.pdata.pg4.StepRate = cpu_to_be16(1); + mdata.pdata.pg4.LandingZoneHigh = 0; + mdata.pdata.pg4.LandingZoneLow = 0; + mdata.pdata.pg4.flags = 0; + mdata.pdata.pg4.RotationalOffset = 0; + mdata.pdata.pg4.MediumRotationRate = 0; break; + default: return (0); } /* end switch */ @@ -5336,19 +5364,20 @@ ips_msense(ips_ha_t *ha, ips_scb_t *scb) { /****************************************************************************/ static int ips_reqsen(ips_ha_t *ha, ips_scb_t *scb) { - char *sp; + IPS_SCSI_REQSEN reqsen; METHOD_TRACE("ips_reqsen", 1); - sp = (char *) scb->scsi_cmd->sense_buffer; - memset(sp, 0, sizeof(scb->scsi_cmd->sense_buffer)); + memset(&reqsen, 0, sizeof(IPS_SCSI_REQSEN)); - sp[0] = 0x70; - sp[3] = NO_SENSE; - sp[7] = 0xe; - sp[12] = NO_SENSE; + reqsen.ResponseCode = IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR; + reqsen.AdditionalLength = 10; + reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE; + reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE; - return (0); + memcpy(scb->scsi_cmd->request_buffer, &reqsen, scb->scsi_cmd->request_bufflen); + + return (1); } /****************************************************************************/ @@ -5419,8 +5448,14 @@ ips_free(ips_ha_t *ha) { iounmap(ha->ioremap_ptr); ha->ioremap_ptr = NULL; ha->mem_ptr = NULL; - ha->mem_addr = 0; } + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17) + if (ha->mem_addr) + release_mem_region(ha->mem_addr, ha->mem_len); +#endif + ha->mem_addr = 0; + } } @@ -5441,10 +5476,9 @@ ips_allocatescbs(ips_ha_t *ha) { METHOD_TRACE("ips_allocatescbs", 1); /* Allocate memory for the CCBs */ - ha->scbs = (ips_scb_t *) kmalloc(ha->max_cmds * sizeof(ips_scb_t), GFP_ATOMIC); + ha->scbs = (ips_scb_t *) kmalloc(ha->max_cmds * sizeof(ips_scb_t), GFP_KERNEL); if (ha->scbs == NULL) - return 0; - + return 0; memset(ha->scbs, 0, ha->max_cmds * sizeof(ips_scb_t)); @@ -5494,7 +5528,7 @@ ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) { /* Initialize dummy command bucket */ ha->dummy->op_code = 0xFF; - ha->dummy->ccsar = VIRT_TO_BUS(ha->dummy); + ha->dummy->ccsar = cpu_to_le32(VIRT_TO_BUS(ha->dummy)); ha->dummy->command_id = IPS_MAX_CMDS; /* set bus address of scb */ @@ -5502,8 +5536,8 @@ ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) { scb->sg_list = sg_list; /* Neptune Fix */ - scb->cmd.basic_io.cccr = IPS_BIT_ILE; - scb->cmd.basic_io.ccsar = VIRT_TO_BUS(ha->dummy); + scb->cmd.basic_io.cccr = cpu_to_le32((u_int32_t) IPS_BIT_ILE); + scb->cmd.basic_io.ccsar = cpu_to_le32(VIRT_TO_BUS(ha->dummy)); } /****************************************************************************/ @@ -5578,8 +5612,8 @@ ips_freescb(ips_ha_t *ha, ips_scb_t *scb) { /****************************************************************************/ static int ips_isinit_copperhead(ips_ha_t *ha) { - u8 scpr; - u8 isr; + u_int8_t scpr; + u_int8_t isr; METHOD_TRACE("ips_isinit_copperhead", 1); @@ -5603,8 +5637,8 @@ ips_isinit_copperhead(ips_ha_t *ha) { /****************************************************************************/ static int ips_isinit_copperhead_memio(ips_ha_t *ha) { - u8 isr=0; - u8 scpr; + u_int8_t isr=0; + u_int8_t scpr; METHOD_TRACE("ips_is_init_copperhead_memio", 1); @@ -5628,13 +5662,13 @@ ips_isinit_copperhead_memio(ips_ha_t *ha) { /****************************************************************************/ static int ips_isinit_morpheus(ips_ha_t *ha) { - u32 post; - u32 bits; + u_int32_t post; + u_int32_t bits; METHOD_TRACE("ips_is_init_morpheus", 1); - post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); - bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + post = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG0)); + bits = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR)); if (post == 0) return (0); @@ -5684,13 +5718,13 @@ ips_enable_int_copperhead_memio(ips_ha_t *ha) { /****************************************************************************/ static void ips_enable_int_morpheus(ips_ha_t *ha) { - u32 Oimr; + u_int32_t Oimr; METHOD_TRACE("ips_enable_int_morpheus", 1); - Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); + Oimr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_OIMR)); Oimr &= ~0x08; - writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); + writel(cpu_to_le32(Oimr), ha->mem_ptr + IPS_REG_I960_OIMR); } /****************************************************************************/ @@ -5704,10 +5738,10 @@ ips_enable_int_morpheus(ips_ha_t *ha) { /****************************************************************************/ static int ips_init_copperhead(ips_ha_t *ha) { - u8 Isr; - u8 Cbsp; - u8 PostByte[IPS_MAX_POST_BYTES]; - u8 ConfigByte[IPS_MAX_CONFIG_BYTES]; + u_int8_t Isr; + u_int8_t Cbsp; + u_int8_t PostByte[IPS_MAX_POST_BYTES]; + u_int8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; int i, j; METHOD_TRACE("ips_init_copperhead", 1); @@ -5742,7 +5776,7 @@ ips_init_copperhead(ips_ha_t *ha) { if (Isr & IPS_BIT_GHI) break; - MDELAY(IPS_ONE_SEC); /* 100 msec */ + MDELAY(IPS_ONE_SEC); /* 1 sec */ } if (j >= 240) @@ -5767,7 +5801,7 @@ ips_init_copperhead(ips_ha_t *ha) { return (0); /* setup CCCR */ - outw(0x1010, ha->io_addr + IPS_REG_CCCR); + outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR); /* Enable busmastering */ outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR); @@ -5793,10 +5827,10 @@ ips_init_copperhead(ips_ha_t *ha) { /****************************************************************************/ static int ips_init_copperhead_memio(ips_ha_t *ha) { - u8 Isr=0; - u8 Cbsp; - u8 PostByte[IPS_MAX_POST_BYTES]; - u8 ConfigByte[IPS_MAX_CONFIG_BYTES]; + u_int8_t Isr=0; + u_int8_t Cbsp; + u_int8_t PostByte[IPS_MAX_POST_BYTES]; + u_int8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; int i, j; METHOD_TRACE("ips_init_copperhead_memio", 1); @@ -5856,7 +5890,7 @@ ips_init_copperhead_memio(ips_ha_t *ha) { return (0); /* setup CCCR */ - writel(0x1010, ha->mem_ptr + IPS_REG_CCCR); + writel(cpu_to_le32(0x1010), ha->mem_ptr + IPS_REG_CCCR); /* Enable busmastering */ writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR); @@ -5883,17 +5917,17 @@ ips_init_copperhead_memio(ips_ha_t *ha) { /****************************************************************************/ static int ips_init_morpheus(ips_ha_t *ha) { - u32 Post; - u32 Config; - u32 Isr; - u32 Oimr; - int i; + u_int32_t Post; + u_int32_t Config; + u_int32_t Isr; + u_int32_t Oimr; + int i; METHOD_TRACE("ips_init_morpheus", 1); /* Wait up to 45 secs for Post */ for (i = 0; i < 45; i++) { - Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR)); if (Isr & IPS_BIT_I960_MSG0I) break; @@ -5909,11 +5943,11 @@ ips_init_morpheus(ips_ha_t *ha) { return (0); } - Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); + Post = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG0)); /* Clear the interrupt bit */ - Isr = (u32) IPS_BIT_I960_MSG0I; - writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + Isr = (u_int32_t) IPS_BIT_I960_MSG0I; + writel(cpu_to_le32(Isr), ha->mem_ptr + IPS_REG_I2O_HIR); if (Post < (IPS_GOOD_POST_STATUS << 8)) { printk(KERN_WARNING "(%s%d) reset controller fails (post status %x).\n", @@ -5924,7 +5958,7 @@ ips_init_morpheus(ips_ha_t *ha) { /* Wait up to 240 secs for config bytes */ for (i = 0; i < 240; i++) { - Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR)); if (Isr & IPS_BIT_I960_MSG1I) break; @@ -5940,16 +5974,16 @@ ips_init_morpheus(ips_ha_t *ha) { return (0); } - Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1); + Config = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG1)); /* Clear interrupt bit */ - Isr = (u32) IPS_BIT_I960_MSG1I; - writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + Isr = (u_int32_t) IPS_BIT_I960_MSG1I; + writel(cpu_to_le32(Isr), ha->mem_ptr + IPS_REG_I2O_HIR); /* Turn on the interrupts */ - Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); + Oimr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_OIMR)); Oimr &= ~0x8; - writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); + writel(cpu_to_le32(Oimr), ha->mem_ptr + IPS_REG_I960_OIMR); /* if we get here then everything went OK */ return (1); @@ -6056,8 +6090,8 @@ ips_reset_copperhead_memio(ips_ha_t *ha) { /****************************************************************************/ static int ips_reset_morpheus(ips_ha_t *ha) { - int reset_counter; - u8 junk; + int reset_counter; + u_int8_t junk; unsigned long cpu_flags; METHOD_TRACE("ips_reset_morpheus", 1); @@ -6072,10 +6106,10 @@ ips_reset_morpheus(ips_ha_t *ha) { while (reset_counter < 2) { reset_counter++; - writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); + writel(cpu_to_le32(0x80000000), ha->mem_ptr + IPS_REG_I960_IDR); - /* Delay for 300 msec */ - MDELAY(300 * IPS_ONE_MSEC); + /* Delay for 5 sec */ + MDELAY(5 * IPS_ONE_SEC); /* Do a PCI config read to wait for adapter */ pci_read_config_byte(ha->pcidev, 4, &junk); @@ -6105,7 +6139,7 @@ ips_reset_morpheus(ips_ha_t *ha) { /****************************************************************************/ static void ips_statinit(ips_ha_t *ha) { - u32 phys_status_start; + u_int32_t phys_status_start; METHOD_TRACE("ips_statinit", 1); @@ -6114,10 +6148,10 @@ ips_statinit(ips_ha_t *ha) { ha->adapt->p_status_tail = ha->adapt->status; phys_status_start = VIRT_TO_BUS(ha->adapt->status); - outl(phys_status_start, ha->io_addr + IPS_REG_SQSR); - outl(phys_status_start + IPS_STATUS_Q_SIZE, ha->io_addr + IPS_REG_SQER); - outl(phys_status_start + IPS_STATUS_SIZE, ha->io_addr + IPS_REG_SQHR); - outl(phys_status_start, ha->io_addr + IPS_REG_SQTR); + outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR); + outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->io_addr + IPS_REG_SQER); + outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->io_addr + IPS_REG_SQHR); + outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR); ha->adapt->hw_status_start = phys_status_start; ha->adapt->hw_status_tail = phys_status_start; @@ -6134,7 +6168,7 @@ ips_statinit(ips_ha_t *ha) { /****************************************************************************/ static void ips_statinit_memio(ips_ha_t *ha) { - u32 phys_status_start; + u_int32_t phys_status_start; METHOD_TRACE("ips_statinit_memio", 1); @@ -6143,10 +6177,10 @@ ips_statinit_memio(ips_ha_t *ha) { ha->adapt->p_status_tail = ha->adapt->status; phys_status_start = VIRT_TO_BUS(ha->adapt->status); - writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR); - writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER); - writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR); - writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR); + writel(cpu_to_le32(phys_status_start), ha->mem_ptr + IPS_REG_SQSR); + writel(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->mem_ptr + IPS_REG_SQER); + writel(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->mem_ptr + IPS_REG_SQHR); + writel(cpu_to_le32(phys_status_start), ha->mem_ptr + IPS_REG_SQTR); ha->adapt->hw_status_start = phys_status_start; ha->adapt->hw_status_tail = phys_status_start; @@ -6161,7 +6195,7 @@ ips_statinit_memio(ips_ha_t *ha) { /* Remove an element from the status queue */ /* */ /****************************************************************************/ -static u32 +static u_int32_t ips_statupd_copperhead(ips_ha_t *ha) { METHOD_TRACE("ips_statupd_copperhead", 1); @@ -6173,7 +6207,7 @@ ips_statupd_copperhead(ips_ha_t *ha) { ha->adapt->hw_status_tail = ha->adapt->hw_status_start; } - outl(ha->adapt->hw_status_tail, ha->io_addr + IPS_REG_SQTR); + outl(cpu_to_le32(ha->adapt->hw_status_tail), ha->io_addr + IPS_REG_SQTR); return (ha->adapt->p_status_tail->value); } @@ -6187,7 +6221,7 @@ ips_statupd_copperhead(ips_ha_t *ha) { /* Remove an element from the status queue */ /* */ /****************************************************************************/ -static u32 +static u_int32_t ips_statupd_copperhead_memio(ips_ha_t *ha) { METHOD_TRACE("ips_statupd_copperhead_memio", 1); @@ -6199,7 +6233,7 @@ ips_statupd_copperhead_memio(ips_ha_t *ha) { ha->adapt->hw_status_tail = ha->adapt->hw_status_start; } - writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR); + writel(cpu_to_le32(ha->adapt->hw_status_tail), ha->mem_ptr + IPS_REG_SQTR); return (ha->adapt->p_status_tail->value); } @@ -6213,13 +6247,13 @@ ips_statupd_copperhead_memio(ips_ha_t *ha) { /* Remove an element from the status queue */ /* */ /****************************************************************************/ -static u32 +static u_int32_t ips_statupd_morpheus(ips_ha_t *ha) { - u32 val; + u_int32_t val; METHOD_TRACE("ips_statupd_morpheus", 1); - val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ); + val = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ)); return (val); } @@ -6235,9 +6269,9 @@ ips_statupd_morpheus(ips_ha_t *ha) { /****************************************************************************/ static int ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { - u32 TimeOut; - u16 val; - unsigned long cpu_flags; + u_int32_t TimeOut; + u_int32_t val; + unsigned long cpu_flags; METHOD_TRACE("ips_issue_copperhead", 1); @@ -6261,7 +6295,7 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { TimeOut = 0; - while ((val = inw(ha->io_addr + IPS_REG_CCCR)) & IPS_BIT_SEM) { + while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) { udelay(1000); if (++TimeOut >= IPS_SEM_TIMEOUT) { @@ -6279,8 +6313,8 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { } /* end if */ } /* end while */ - outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR); - outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR); + outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); + outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); IPS_HA_UNLOCK(cpu_flags); @@ -6298,8 +6332,8 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { /****************************************************************************/ static int ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { - u32 TimeOut; - u32 val; + u_int32_t TimeOut; + u_int32_t val; unsigned long cpu_flags; METHOD_TRACE("ips_issue_copperhead_memio", 1); @@ -6324,7 +6358,7 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { TimeOut = 0; - while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) { + while ((val = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_CCCR))) & IPS_BIT_SEM) { udelay(1000); if (++TimeOut >= IPS_SEM_TIMEOUT) { @@ -6342,8 +6376,8 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { } /* end if */ } /* end while */ - writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR); - writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR); + writel(cpu_to_le32(scb->scb_busaddr), ha->mem_ptr + IPS_REG_CCSAR); + writel(cpu_to_le32(IPS_BIT_START_CMD), ha->mem_ptr + IPS_REG_CCCR); IPS_HA_UNLOCK(cpu_flags); @@ -6383,7 +6417,7 @@ ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { IPS_HA_LOCK(cpu_flags); - outl(scb->scb_busaddr, ha->io_addr + IPS_REG_I2O_INMSGQ); + outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); IPS_HA_UNLOCK(cpu_flags); @@ -6423,7 +6457,7 @@ ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) { IPS_HA_LOCK(cpu_flags); - writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ); + writel(cpu_to_le32(scb->scb_busaddr), ha->mem_ptr + IPS_REG_I2O_INMSGQ); IPS_HA_UNLOCK(cpu_flags); @@ -6441,7 +6475,7 @@ ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) { /****************************************************************************/ static int ips_isintr_copperhead(ips_ha_t *ha) { - u8 Isr; + u_int8_t Isr; METHOD_TRACE("ips_isintr_copperhead", 2); @@ -6473,7 +6507,7 @@ ips_isintr_copperhead(ips_ha_t *ha) { /****************************************************************************/ static int ips_isintr_copperhead_memio(ips_ha_t *ha) { - u8 Isr; + u_int8_t Isr; METHOD_TRACE("ips_isintr_memio", 2); @@ -6505,11 +6539,11 @@ ips_isintr_copperhead_memio(ips_ha_t *ha) { /****************************************************************************/ static int ips_isintr_morpheus(ips_ha_t *ha) { - u32 Isr; + u_int32_t Isr; METHOD_TRACE("ips_isintr_morpheus", 2); - Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR)); if (Isr & IPS_BIT_I2O_OPQI) return (1); @@ -6529,7 +6563,7 @@ ips_isintr_morpheus(ips_ha_t *ha) { static int ips_wait(ips_ha_t *ha, int time, int intr) { int ret; - u8 done; + u_int8_t done; METHOD_TRACE("ips_wait", 1); @@ -6628,7 +6662,7 @@ ips_write_driver_status(ips_ha_t *ha, int intr) { /* check to make sure the page has a valid */ /* signature */ - if (ha->nvram->signature != IPS_NVRAM_P5_SIG) { + if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) { DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.", ips_name, ha->host_num, ha->nvram->signature); @@ -6636,16 +6670,22 @@ ips_write_driver_status(ips_ha_t *ha, int intr) { } DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.", - ips_name, ha->host_num, ha->nvram->adapter_type, ha->nvram->adapter_slot, + ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type), + ha->nvram->adapter_slot, ha->nvram->bios_high[0], ha->nvram->bios_high[1], ha->nvram->bios_high[2], ha->nvram->bios_high[3], ha->nvram->bios_low[0], ha->nvram->bios_low[1], ha->nvram->bios_low[2], ha->nvram->bios_low[3]); + ips_get_bios_version(ha, intr); + /* change values (as needed) */ ha->nvram->operating_system = IPS_OS_LINUX; + ha->nvram->adapter_type = ha->ad_type; strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4); strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4); + strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4); + strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4); /* now update the page */ if (!ips_readwrite_page5(ha, TRUE, intr)) { @@ -6658,6 +6698,7 @@ ips_write_driver_status(ips_ha_t *ha, int intr) { /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */ ha->slot_num = ha->nvram->adapter_slot; + return (1); } @@ -6687,7 +6728,7 @@ ips_read_adapter_status(ips_ha_t *ha, int intr) { scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.basic_io.sg_count = 0; - scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->enq); + scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->enq)); scb->cmd.basic_io.lba = 0; scb->cmd.basic_io.sector_count = 0; scb->cmd.basic_io.log_drv = 0; @@ -6728,7 +6769,7 @@ ips_read_subsystem_parameters(ips_ha_t *ha, int intr) { scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.basic_io.sg_count = 0; - scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->subsys); + scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->subsys)); scb->cmd.basic_io.lba = 0; scb->cmd.basic_io.sector_count = 0; scb->cmd.basic_io.log_drv = 0; @@ -6761,8 +6802,7 @@ ips_read_config(ips_ha_t *ha, int intr) { METHOD_TRACE("ips_read_config", 1); /* set defaults for initiator IDs */ - ha->conf->init_id[0] = IPS_ADAPTER_ID; - for (i = 1; i < 4; i++) + for (i = 0; i < 4; i++) ha->conf->init_id[i] = 7; scb = &ha->scbs[ha->max_cmds-1]; @@ -6774,7 +6814,7 @@ ips_read_config(ips_ha_t *ha, int intr) { scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->conf); + scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->conf)); /* send command */ if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || @@ -6784,8 +6824,7 @@ ips_read_config(ips_ha_t *ha, int intr) { memset(ha->conf, 0, sizeof(IPS_CONF)); /* reset initiator IDs */ - ha->conf->init_id[0] = IPS_ADAPTER_ID; - for (i = 1; i < 4; i++) + for (i = 0; i < 4; i++) ha->conf->init_id[i] = 7; return (0); @@ -6821,7 +6860,7 @@ ips_readwrite_page5(ips_ha_t *ha, int write, int intr) { scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.nvram.page = 5; scb->cmd.nvram.write = write; - scb->cmd.nvram.buffer_addr = VIRT_TO_BUS(ha->nvram); + scb->cmd.nvram.buffer_addr = cpu_to_le32(VIRT_TO_BUS(ha->nvram)); scb->cmd.nvram.reserved = 0; scb->cmd.nvram.reserved2 = 0; @@ -7043,11 +7082,13 @@ ips_fix_ffdc_time(ips_ha_t *ha, ips_scb_t *scb, time_t current_time) { /****************************************************************************/ static int ips_erase_bios(ips_ha_t *ha) { - int timeout; - u8 status=0; + int timeout; + u_int8_t status=0; METHOD_TRACE("ips_erase_bios", 1); + status = 0; + /* Clear the status register */ outl(0, ha->io_addr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) @@ -7152,11 +7193,13 @@ ips_erase_bios(ips_ha_t *ha) { /****************************************************************************/ static int ips_erase_bios_memio(ips_ha_t *ha) { - int timeout; - u8 status; + int timeout; + u_int8_t status; METHOD_TRACE("ips_erase_bios_memio", 1); + status = 0; + /* Clear the status register */ writel(0, ha->mem_ptr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) @@ -7260,16 +7303,18 @@ ips_erase_bios_memio(ips_ha_t *ha) { /* */ /****************************************************************************/ static int -ips_program_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { - int i; - int timeout; - u8 status=0; +ips_program_bios(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) { + int i; + int timeout; + u_int8_t status=0; METHOD_TRACE("ips_program_bios", 1); + status = 0; + for (i = 0; i < buffersize; i++) { /* write a byte */ - outl(i + offset, ha->io_addr + IPS_REG_FLAP); + outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ @@ -7347,16 +7392,18 @@ ips_program_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { /* */ /****************************************************************************/ static int -ips_program_bios_memio(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { - int i; - int timeout; - u8 status=0; +ips_program_bios_memio(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) { + int i; + int timeout; + u_int8_t status=0; METHOD_TRACE("ips_program_bios_memio", 1); + status = 0; + for (i = 0; i < buffersize; i++) { /* write a byte */ - writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); + writel(cpu_to_le32(i + offset), ha->mem_ptr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ @@ -7434,9 +7481,9 @@ ips_program_bios_memio(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { /* */ /****************************************************************************/ static int -ips_verify_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { - u8 checksum; - int i; +ips_verify_bios(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) { + u_int8_t checksum; + int i; METHOD_TRACE("ips_verify_bios", 1); @@ -7448,7 +7495,7 @@ ips_verify_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) return (1); - outl(1, ha->io_addr + IPS_REG_FLAP); + outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) @@ -7457,11 +7504,11 @@ ips_verify_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { checksum = 0xff; for (i = 2; i < buffersize; i++) { - outl(i + offset, ha->io_addr + IPS_REG_FLAP); + outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ - checksum = (u8) checksum + inb(ha->io_addr + IPS_REG_FLDP); + checksum = (u_int8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP); } if (checksum != 0) @@ -7481,9 +7528,9 @@ ips_verify_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { /* */ /****************************************************************************/ static int -ips_verify_bios_memio(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { - u8 checksum; - int i; +ips_verify_bios_memio(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) { + u_int8_t checksum; + int i; METHOD_TRACE("ips_verify_bios_memio", 1); @@ -7504,11 +7551,11 @@ ips_verify_bios_memio(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { checksum = 0xff; for (i = 2; i < buffersize; i++) { - writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); + writel(cpu_to_le32(i + offset), ha->mem_ptr + IPS_REG_FLAP); if (ha->revision_id == IPS_REVID_TROMBONE64) udelay(5); /* 5 us */ - checksum = (u8) checksum + readb(ha->mem_ptr + IPS_REG_FLDP); + checksum = (u_int8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP); } if (checksum != 0) @@ -7519,9 +7566,10 @@ ips_verify_bios_memio(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) { return (0); } +#if defined (MODULE) static Scsi_Host_Template driver_template = IPS; #include "scsi_module.c" - +#endif /* * Overrides for Emacs so that we almost follow Linus's tabbing style. diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index cf0e3fc0160c..514055e16909 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h @@ -50,6 +50,12 @@ #include <asm/uaccess.h> #include <asm/io.h> + /* type definitions */ + #define u_int8_t uint8_t + #define u_int16_t uint16_t + #define u_int32_t uint32_t + #define u_int64_t uint64_t + /* Prototypes */ extern int ips_detect(Scsi_Host_Template *); extern int ips_release(struct Scsi_Host *); @@ -99,11 +105,11 @@ #ifndef verify_area_20 #define verify_area_20(t,a,sz) (0) /* success */ #endif - + #ifndef DECLARE_MUTEX_LOCKED #define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED; #endif - + /* * Lock macros */ @@ -326,6 +332,53 @@ #define IPS_TIMEOUT20M 0x30 /* + * SCSI Inquiry Data Flags + */ + #define IPS_SCSI_INQ_TYPE_DASD 0x00 + #define IPS_SCSI_INQ_TYPE_PROCESSOR 0x03 + #define IPS_SCSI_INQ_LU_CONNECTED 0x00 + #define IPS_SCSI_INQ_RD_REV2 0x02 + #define IPS_SCSI_INQ_REV2 0x02 + #define IPS_SCSI_INQ_REV3 0x03 + #define IPS_SCSI_INQ_Address16 0x01 + #define IPS_SCSI_INQ_Address32 0x02 + #define IPS_SCSI_INQ_MedChanger 0x08 + #define IPS_SCSI_INQ_MultiPort 0x10 + #define IPS_SCSI_INQ_EncServ 0x40 + #define IPS_SCSI_INQ_SoftReset 0x01 + #define IPS_SCSI_INQ_CmdQue 0x02 + #define IPS_SCSI_INQ_Linked 0x08 + #define IPS_SCSI_INQ_Sync 0x10 + #define IPS_SCSI_INQ_WBus16 0x20 + #define IPS_SCSI_INQ_WBus32 0x40 + #define IPS_SCSI_INQ_RelAdr 0x80 + + /* + * SCSI Request Sense Data Flags + */ + #define IPS_SCSI_REQSEN_VALID 0x80 + #define IPS_SCSI_REQSEN_CURRENT_ERR 0x70 + #define IPS_SCSI_REQSEN_NO_SENSE 0x00 + + /* + * SCSI Mode Page Equates + */ + #define IPS_SCSI_MP3_SoftSector 0x01 + #define IPS_SCSI_MP3_HardSector 0x02 + #define IPS_SCSI_MP3_Removeable 0x04 + #define IPS_SCSI_MP3_AllocateSurface 0x08 + + /* + * Configuration Structure Flags + */ + #define IPS_CFG_USEROPT_UPDATECOUNT(cfg) (((cfg)->UserOpt & 0xffff000) >> 16) + #define IPS_CFG_USEROPT_CONCURSTART(cfg) (((cfg)->UserOpt & 0xf000) >> 12) + #define IPS_CFG_USEROPT_STARTUPDELAY(cfg) (((cfg)->UserOpt & 0xf00) >> 8) + #define IPS_CFG_USEROPT_REARRANGE(cfg) ((cfg)->UserOpt & 0x80) + #define IPS_CFG_USEROPT_CDBOOT(cfg) ((cfg)->UserOpt & 0x40) + #define IPS_CFG_USEROPT_CLUSTER(cfg) ((cfg)->UserOpt & 0x20) + + /* * Host adapter Flags (bit numbers) */ #define IPS_IN_INTR 0 @@ -427,201 +480,201 @@ * IBM PCI Raid Command Formats */ typedef struct { - u8 op_code; - u8 command_id; - u8 log_drv; - u8 sg_count; - u32 lba; - u32 sg_addr; - u16 sector_count; - u16 reserved; - u32 ccsar; - u32 cccr; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t log_drv; + u_int8_t sg_count; + u_int32_t lba; + u_int32_t sg_addr; + u_int16_t sector_count; + u_int16_t reserved; + u_int32_t ccsar; + u_int32_t cccr; } IPS_IO_CMD, *PIPS_IO_CMD; typedef struct { - u8 op_code; - u8 command_id; - u16 reserved; - u32 reserved2; - u32 buffer_addr; - u32 reserved3; - u32 ccsar; - u32 cccr; + u_int8_t op_code; + u_int8_t command_id; + u_int16_t reserved; + u_int32_t reserved2; + u_int32_t buffer_addr; + u_int32_t reserved3; + u_int32_t ccsar; + u_int32_t cccr; } IPS_LD_CMD, *PIPS_LD_CMD; typedef struct { - u8 op_code; - u8 command_id; - u8 reserved; - u8 reserved2; - u32 reserved3; - u32 buffer_addr; - u32 reserved4; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t reserved; + u_int8_t reserved2; + u_int32_t reserved3; + u_int32_t buffer_addr; + u_int32_t reserved4; } IPS_IOCTL_CMD, *PIPS_IOCTL_CMD; typedef struct { - u8 op_code; - u8 command_id; - u16 reserved; - u32 reserved2; - u32 dcdb_address; - u32 reserved3; - u32 ccsar; - u32 cccr; + u_int8_t op_code; + u_int8_t command_id; + u_int16_t reserved; + u_int32_t reserved2; + u_int32_t dcdb_address; + u_int32_t reserved3; + u_int32_t ccsar; + u_int32_t cccr; } IPS_DCDB_CMD, *PIPS_DCDB_CMD; typedef struct { - u8 op_code; - u8 command_id; - u8 channel; - u8 source_target; - u32 reserved; - u32 reserved2; - u32 reserved3; - u32 ccsar; - u32 cccr; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t channel; + u_int8_t source_target; + u_int32_t reserved; + u_int32_t reserved2; + u_int32_t reserved3; + u_int32_t ccsar; + u_int32_t cccr; } IPS_CS_CMD, *PIPS_CS_CMD; typedef struct { - u8 op_code; - u8 command_id; - u8 log_drv; - u8 control; - u32 reserved; - u32 reserved2; - u32 reserved3; - u32 ccsar; - u32 cccr; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t log_drv; + u_int8_t control; + u_int32_t reserved; + u_int32_t reserved2; + u_int32_t reserved3; + u_int32_t ccsar; + u_int32_t cccr; } IPS_US_CMD, *PIPS_US_CMD; typedef struct { - u8 op_code; - u8 command_id; - u8 reserved; - u8 state; - u32 reserved2; - u32 reserved3; - u32 reserved4; - u32 ccsar; - u32 cccr; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t reserved; + u_int8_t state; + u_int32_t reserved2; + u_int32_t reserved3; + u_int32_t reserved4; + u_int32_t ccsar; + u_int32_t cccr; } IPS_FC_CMD, *PIPS_FC_CMD; typedef struct { - u8 op_code; - u8 command_id; - u8 reserved; - u8 desc; - u32 reserved2; - u32 buffer_addr; - u32 reserved3; - u32 ccsar; - u32 cccr; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t reserved; + u_int8_t desc; + u_int32_t reserved2; + u_int32_t buffer_addr; + u_int32_t reserved3; + u_int32_t ccsar; + u_int32_t cccr; } IPS_STATUS_CMD, *PIPS_STATUS_CMD; typedef struct { - u8 op_code; - u8 command_id; - u8 page; - u8 write; - u32 reserved; - u32 buffer_addr; - u32 reserved2; - u32 ccsar; - u32 cccr; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t page; + u_int8_t write; + u_int32_t reserved; + u_int32_t buffer_addr; + u_int32_t reserved2; + u_int32_t ccsar; + u_int32_t cccr; } IPS_NVRAM_CMD, *PIPS_NVRAM_CMD; typedef struct { - u8 op_code; - u8 command_id; - u8 reset_count; - u8 reset_type; - u8 second; - u8 minute; - u8 hour; - u8 day; - u8 reserved1[4]; - u8 month; - u8 yearH; - u8 yearL; - u8 reserved2; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t reset_count; + u_int8_t reset_type; + u_int8_t second; + u_int8_t minute; + u_int8_t hour; + u_int8_t day; + u_int8_t reserved1[4]; + u_int8_t month; + u_int8_t yearH; + u_int8_t yearL; + u_int8_t reserved2; } IPS_FFDC_CMD, *PIPS_FFDC_CMD; typedef struct { - u8 op_code; - u8 command_id; - u8 type; - u8 direction; - u32 count; - u32 buffer_addr; - u8 total_packets; - u8 packet_num; - u16 reserved; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t type; + u_int8_t direction; + u_int32_t count; + u_int32_t buffer_addr; + u_int8_t total_packets; + u_int8_t packet_num; + u_int16_t reserved; } IPS_FLASHFW_CMD, *PIPS_FLASHFW_CMD; typedef struct { - u8 op_code; - u8 command_id; - u8 type; - u8 direction; - u32 count; - u32 buffer_addr; - u32 offset; + u_int8_t op_code; + u_int8_t command_id; + u_int8_t type; + u_int8_t direction; + u_int32_t count; + u_int32_t buffer_addr; + u_int32_t offset; } IPS_FLASHBIOS_CMD, *PIPS_FLASHBIOS_CMD; typedef union { - IPS_IO_CMD basic_io; - IPS_LD_CMD logical_info; - IPS_IOCTL_CMD ioctl_info; - IPS_DCDB_CMD dcdb; - IPS_CS_CMD config_sync; - IPS_US_CMD unlock_stripe; - IPS_FC_CMD flush_cache; - IPS_STATUS_CMD status; - IPS_NVRAM_CMD nvram; - IPS_FFDC_CMD ffdc; + IPS_IO_CMD basic_io; + IPS_LD_CMD logical_info; + IPS_IOCTL_CMD ioctl_info; + IPS_DCDB_CMD dcdb; + IPS_CS_CMD config_sync; + IPS_US_CMD unlock_stripe; + IPS_FC_CMD flush_cache; + IPS_STATUS_CMD status; + IPS_NVRAM_CMD nvram; + IPS_FFDC_CMD ffdc; IPS_FLASHFW_CMD flashfw; IPS_FLASHBIOS_CMD flashbios; } IPS_HOST_COMMAND, *PIPS_HOST_COMMAND; typedef struct { - u8 logical_id; - u8 reserved; - u8 raid_level; - u8 state; - u32 sector_count; + u_int8_t logical_id; + u_int8_t reserved; + u_int8_t raid_level; + u_int8_t state; + u_int32_t sector_count; } IPS_DRIVE_INFO, *PIPS_DRIVE_INFO; typedef struct { - u8 no_of_log_drive; - u8 reserved[3]; + u_int8_t no_of_log_drive; + u_int8_t reserved[3]; IPS_DRIVE_INFO drive_info[IPS_MAX_LD]; } IPS_LD_INFO, *PIPS_LD_INFO; typedef struct { - u8 device_address; - u8 cmd_attribute; - u16 transfer_length; - u32 buffer_pointer; - u8 cdb_length; - u8 sense_length; - u8 sg_count; - u8 reserved; - u8 scsi_cdb[12]; - u8 sense_info[64]; - u8 scsi_status; - u8 reserved2[3]; + u_int8_t device_address; + u_int8_t cmd_attribute; + u_int16_t transfer_length; + u_int32_t buffer_pointer; + u_int8_t cdb_length; + u_int8_t sense_length; + u_int8_t sg_count; + u_int8_t reserved; + u_int8_t scsi_cdb[12]; + u_int8_t sense_info[64]; + u_int8_t scsi_status; + u_int8_t reserved2[3]; } IPS_DCDB_TABLE, *PIPS_DCDB_TABLE; typedef union { struct { - volatile u8 reserved; - volatile u8 command_id; - volatile u8 basic_status; - volatile u8 extended_status; + volatile u_int8_t reserved; + volatile u_int8_t command_id; + volatile u_int8_t basic_status; + volatile u_int8_t extended_status; } fields; - volatile u32 value; + volatile u_int32_t value; } IPS_STATUS, *PIPS_STATUS; typedef struct { @@ -629,233 +682,234 @@ typedef struct { volatile PIPS_STATUS p_status_start; volatile PIPS_STATUS p_status_end; volatile PIPS_STATUS p_status_tail; - volatile u32 hw_status_start; - volatile u32 hw_status_tail; + volatile u_int32_t hw_status_start; + volatile u_int32_t hw_status_tail; IPS_LD_INFO logical_drive_info; } IPS_ADAPTER, *PIPS_ADAPTER; typedef struct { - u8 ucLogDriveCount; - u8 ucMiscFlag; - u8 ucSLTFlag; - u8 ucBSTFlag; - u8 ucPwrChgCnt; - u8 ucWrongAdrCnt; - u8 ucUnidentCnt; - u8 ucNVramDevChgCnt; - u8 CodeBlkVersion[8]; - u8 BootBlkVersion[8]; - u32 ulDriveSize[IPS_MAX_LD]; - u8 ucConcurrentCmdCount; - u8 ucMaxPhysicalDevices; - u16 usFlashRepgmCount; - u8 ucDefunctDiskCount; - u8 ucRebuildFlag; - u8 ucOfflineLogDrvCount; - u8 ucCriticalDrvCount; - u16 usConfigUpdateCount; - u8 ucBlkFlag; - u8 reserved; - u16 usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS]; + u_int8_t ucLogDriveCount; + u_int8_t ucMiscFlag; + u_int8_t ucSLTFlag; + u_int8_t ucBSTFlag; + u_int8_t ucPwrChgCnt; + u_int8_t ucWrongAdrCnt; + u_int8_t ucUnidentCnt; + u_int8_t ucNVramDevChgCnt; + u_int8_t CodeBlkVersion[8]; + u_int8_t BootBlkVersion[8]; + u_int32_t ulDriveSize[IPS_MAX_LD]; + u_int8_t ucConcurrentCmdCount; + u_int8_t ucMaxPhysicalDevices; + u_int16_t usFlashRepgmCount; + u_int8_t ucDefunctDiskCount; + u_int8_t ucRebuildFlag; + u_int8_t ucOfflineLogDrvCount; + u_int8_t ucCriticalDrvCount; + u_int16_t usConfigUpdateCount; + u_int8_t ucBlkFlag; + u_int8_t reserved; + u_int16_t usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS]; } IPS_ENQ, *PIPS_ENQ; typedef struct { - u8 ucInitiator; - u8 ucParameters; - u8 ucMiscFlag; - u8 ucState; - u32 ulBlockCount; - u8 ucDeviceId[28]; + u_int8_t ucInitiator; + u_int8_t ucParameters; + u_int8_t ucMiscFlag; + u_int8_t ucState; + u_int32_t ulBlockCount; + u_int8_t ucDeviceId[28]; } IPS_DEVSTATE, *PIPS_DEVSTATE; typedef struct { - u8 ucChn; - u8 ucTgt; - u16 ucReserved; - u32 ulStartSect; - u32 ulNoOfSects; + u_int8_t ucChn; + u_int8_t ucTgt; + u_int16_t ucReserved; + u_int32_t ulStartSect; + u_int32_t ulNoOfSects; } IPS_CHUNK, *PIPS_CHUNK; typedef struct { - u16 ucUserField; - u8 ucState; - u8 ucRaidCacheParam; - u8 ucNoOfChunkUnits; - u8 ucStripeSize; - u8 ucParams; - u8 ucReserved; - u32 ulLogDrvSize; + u_int16_t ucUserField; + u_int8_t ucState; + u_int8_t ucRaidCacheParam; + u_int8_t ucNoOfChunkUnits; + u_int8_t ucStripeSize; + u_int8_t ucParams; + u_int8_t ucReserved; + u_int32_t ulLogDrvSize; IPS_CHUNK chunk[IPS_MAX_CHUNKS]; } IPS_LD, *PIPS_LD; typedef struct { - u8 board_disc[8]; - u8 processor[8]; - u8 ucNoChanType; - u8 ucNoHostIntType; - u8 ucCompression; - u8 ucNvramType; - u32 ulNvramSize; + u_int8_t board_disc[8]; + u_int8_t processor[8]; + u_int8_t ucNoChanType; + u_int8_t ucNoHostIntType; + u_int8_t ucCompression; + u_int8_t ucNvramType; + u_int32_t ulNvramSize; } IPS_HARDWARE, *PIPS_HARDWARE; typedef struct { - u8 ucLogDriveCount; - u8 ucDateD; - u8 ucDateM; - u8 ucDateY; - u8 init_id[4]; - u8 host_id[12]; - u8 time_sign[8]; - - struct { - u32 usCfgDrvUpdateCnt:16; - u32 ConcurDrvStartCnt:4; - u32 StartupDelay:4; - u32 auto_rearrange:1; - u32 cd_boot:1; - u32 cluster:1; - u32 reserved:5; - } UserOpt; - - u16 user_field; - u8 ucRebuildRate; - u8 ucReserve; + u_int8_t ucLogDriveCount; + u_int8_t ucDateD; + u_int8_t ucDateM; + u_int8_t ucDateY; + u_int8_t init_id[4]; + u_int8_t host_id[12]; + u_int8_t time_sign[8]; + u_int32_t UserOpt; + u_int16_t user_field; + u_int8_t ucRebuildRate; + u_int8_t ucReserve; IPS_HARDWARE hardware_disc; IPS_LD logical_drive[IPS_MAX_LD]; IPS_DEVSTATE dev[IPS_MAX_CHANNELS][IPS_MAX_TARGETS+1]; - u8 reserved[512]; - + u_int8_t reserved[512]; } IPS_CONF, *PIPS_CONF; typedef struct { - u32 signature; - u8 reserved; - u8 adapter_slot; - u16 adapter_type; - u8 bios_high[4]; - u8 bios_low[4]; - u16 reserved2; - u8 reserved3; - u8 operating_system; - u8 driver_high[4]; - u8 driver_low[4]; - u8 reserved4[100]; + u_int32_t signature; + u_int8_t reserved; + u_int8_t adapter_slot; + u_int16_t adapter_type; + u_int8_t bios_high[4]; + u_int8_t bios_low[4]; + u_int16_t reserved2; + u_int8_t reserved3; + u_int8_t operating_system; + u_int8_t driver_high[4]; + u_int8_t driver_low[4]; + u_int8_t reserved4[100]; } IPS_NVRAM_P5, *PIPS_NVRAM_P5; typedef struct _IPS_SUBSYS { - u32 param[128]; + u_int32_t param[128]; } IPS_SUBSYS, *PIPS_SUBSYS; +/** + ** SCSI Structures + **/ + /* * Inquiry Data Format */ typedef struct { - u8 DeviceType:5; - u8 DeviceTypeQualifier:3; - u8 DeviceTypeModifier:7; - u8 RemoveableMedia:1; - u8 Versions; - u8 ResponseDataFormat; - u8 AdditionalLength; - u16 Reserved; - u8 SoftReset:1; - u8 CommandQueue:1; - u8 Reserved2:1; - u8 LinkedCommands:1; - u8 Synchronous:1; - u8 Wide16Bit:1; - u8 Wide32Bit:1; - u8 RelativeAddressing:1; - u8 VendorId[8]; - u8 ProductId[16]; - u8 ProductRevisionLevel[4]; - u8 VendorSpecific[20]; - u8 Reserved3[40]; -} IPS_INQ_DATA, *PIPS_INQ_DATA; + u_int8_t DeviceType; + u_int8_t DeviceTypeQualifier; + u_int8_t Version; + u_int8_t ResponseDataFormat; + u_int8_t AdditionalLength; + u_int8_t Reserved; + u_int8_t Flags[2]; + char VendorId[8]; + char ProductId[16]; + char ProductRevisionLevel[4]; +} IPS_SCSI_INQ_DATA, *PIPS_SCSI_INQ_DATA; /* * Read Capacity Data Format */ typedef struct { - u32 lba; - u32 len; -} IPS_CAPACITY; + u_int32_t lba; + u_int32_t len; +} IPS_SCSI_CAPACITY; + +/* + * Request Sense Data Format + */ +typedef struct { + u_int8_t ResponseCode; + u_int8_t SegmentNumber; + u_int8_t Flags; + u_int8_t Information[4]; + u_int8_t AdditionalLength; + u_int8_t CommandSpecific[4]; + u_int8_t AdditionalSenseCode; + u_int8_t AdditionalSenseCodeQual; + u_int8_t FRUCode; + u_int8_t SenseKeySpecific[3]; +} IPS_SCSI_REQSEN; /* - * Sense Data Format + * Sense Data Format - Page 3 */ typedef struct { - u8 pg_pc:6; /* Page Code */ - u8 pg_res1:2; /* Reserved */ - u8 pg_len; /* Page Length */ - u16 pg_trk_z; /* Tracks per zone */ - u16 pg_asec_z; /* Alternate sectors per zone */ - u16 pg_atrk_z; /* Alternate tracks per zone */ - u16 pg_atrk_v; /* Alternate tracks per volume */ - u16 pg_sec_t; /* Sectors per track */ - u16 pg_bytes_s; /* Bytes per physical sectors */ - u16 pg_intl; /* Interleave */ - u16 pg_trkskew; /* Track skew factor */ - u16 pg_cylskew; /* Cylinder Skew Factor */ - u32 pg_res2:27; /* Reserved */ - u32 pg_ins:1; /* Inhibit Slave */ - u32 pg_surf:1; /* Allocate Surface Sectors */ - u32 pg_rmb:1; /* Removeable */ - u32 pg_hsec:1; /* Hard sector formatting */ - u32 pg_ssec:1; /* Soft sector formatting */ -} IPS_DADF; + u_int8_t PageCode; + u_int8_t PageLength; + u_int16_t TracksPerZone; + u_int16_t AltSectorsPerZone; + u_int16_t AltTracksPerZone; + u_int16_t AltTracksPerVolume; + u_int16_t SectorsPerTrack; + u_int16_t BytesPerSector; + u_int16_t Interleave; + u_int16_t TrackSkew; + u_int16_t CylinderSkew; + u_int8_t flags; + u_int8_t reserved[3]; +} IPS_SCSI_MODE_PAGE3; +/* + * Sense Data Format - Page 4 + */ +typedef struct { + u_int8_t PageCode; + u_int8_t PageLength; + u_int16_t CylindersHigh; + u_int8_t CylindersLow; + u_int8_t Heads; + u_int16_t WritePrecompHigh; + u_int8_t WritePrecompLow; + u_int16_t ReducedWriteCurrentHigh; + u_int8_t ReducedWriteCurrentLow; + u_int16_t StepRate; + u_int16_t LandingZoneHigh; + u_int8_t LandingZoneLow; + u_int8_t flags; + u_int8_t RotationalOffset; + u_int8_t Reserved; + u_int16_t MediumRotationRate; + u_int8_t Reserved2[2]; +} IPS_SCSI_MODE_PAGE4; + +/* + * Sense Data Format - Block Descriptor (DASD) + */ typedef struct { - u8 pg_pc:6; /* Page Code */ - u8 pg_res1:2; /* Reserved */ - u8 pg_len; /* Page Length */ - u16 pg_cylu; /* Number of cylinders (upper) */ - u8 pg_cyll; /* Number of cylinders (lower) */ - u8 pg_head; /* Number of heads */ - u16 pg_wrpcompu; /* Write precomp (upper) */ - u32 pg_wrpcompl:8; /* Write precomp (lower) */ - u32 pg_redwrcur:24; /* Reduced write current */ - u32 pg_drstep:16; /* Drive step rate */ - u32 pg_landu:16; /* Landing zone cylinder (upper) */ - u32 pg_landl:8; /* Landing zone cylinder (lower) */ - u32 pg_res2:24; /* Reserved */ -} IPS_RDDG; - -struct ips_blk_desc { - u8 bd_dencode; - u8 bd_nblks1; - u8 bd_nblks2; - u8 bd_nblks3; - u8 bd_res; - u8 bd_blen1; - u8 bd_blen2; - u8 bd_blen3; -}; + u_int32_t NumberOfBlocks; + u_int8_t DensityCode; + u_int16_t BlockLengthHigh; + u_int8_t BlockLengthLow; +} IPS_SCSI_MODE_PAGE_BLKDESC; +/* + * Sense Data Format - Mode Page Header + */ typedef struct { - u8 plh_len; /* Data length */ - u8 plh_type; /* Medium type */ - u8 plh_res:7; /* Reserved */ - u8 plh_wp:1; /* Write protect */ - u8 plh_bdl; /* Block descriptor length */ -} ips_sense_plh_t; + u_int8_t DataLength; + u_int8_t MediumType; + u_int8_t Reserved; + u_int8_t BlockDescLength; +} IPS_SCSI_MODE_PAGE_HEADER; typedef struct { - ips_sense_plh_t plh; - struct ips_blk_desc blk_desc; + IPS_SCSI_MODE_PAGE_HEADER hdr; + IPS_SCSI_MODE_PAGE_BLKDESC blkdesc; union { - IPS_DADF pg3; - IPS_RDDG pg4; + IPS_SCSI_MODE_PAGE3 pg3; + IPS_SCSI_MODE_PAGE4 pg4; } pdata; -} ips_mdata_t; +} IPS_SCSI_MODE_PAGE_DATA; /* * Scatter Gather list format */ typedef struct ips_sglist { - u32 address; - u32 length; + u_int32_t address; + u_int32_t length; } IPS_SG_LIST, *PIPS_SG_LIST; typedef struct _IPS_INFOSTR { @@ -874,23 +928,24 @@ typedef struct { typedef struct { void *userbuffer; - u32 usersize; + u_int32_t usersize; void *kernbuffer; - u32 kernsize; + u_int32_t kernsize; void *ha; void *SC; void *pt; struct semaphore *sem; - u32 offset; - u32 retcode; + u_int32_t offset; + u_int32_t retcode; } IPS_FLASH_DATA; /* * Status Info */ typedef struct ips_stat { - u32 residue_len; - u32 scb_addr; + u_int32_t residue_len; + void *scb_addr; + u_int8_t padding[12 - sizeof(void *)]; } ips_stat_t; /* @@ -899,8 +954,8 @@ typedef struct ips_stat { typedef struct ips_scb_queue { struct ips_scb *head; struct ips_scb *tail; - u32 count; - u32 cpu_flags; + u_int32_t count; + u_int32_t cpu_flags; spinlock_t lock; } ips_scb_queue_t; @@ -910,8 +965,8 @@ typedef struct ips_scb_queue { typedef struct ips_wait_queue { Scsi_Cmnd *head; Scsi_Cmnd *tail; - u32 count; - u32 cpu_flags; + u_int32_t count; + u_int32_t cpu_flags; spinlock_t lock; } ips_wait_queue_t; @@ -924,8 +979,8 @@ typedef struct ips_copp_wait_item { typedef struct ips_copp_queue { struct ips_copp_wait_item *head; struct ips_copp_wait_item *tail; - u32 count; - u32 cpu_flags; + u_int32_t count; + u_int32_t cpu_flags; spinlock_t lock; } ips_copp_queue_t; @@ -933,33 +988,33 @@ typedef struct ips_copp_queue { struct ips_ha; typedef struct { - int (*reset)(struct ips_ha *); - int (*issue)(struct ips_ha *, struct ips_scb *); - int (*isinit)(struct ips_ha *); - int (*isintr)(struct ips_ha *); - int (*init)(struct ips_ha *); - int (*erasebios)(struct ips_ha *); - int (*programbios)(struct ips_ha *, char *, u32, u32); - int (*verifybios)(struct ips_ha *, char *, u32, u32); - u32 (*statupd)(struct ips_ha *); - void (*statinit)(struct ips_ha *); - void (*intr)(struct ips_ha *); - void (*enableint)(struct ips_ha *); + int (*reset)(struct ips_ha *); + int (*issue)(struct ips_ha *, struct ips_scb *); + int (*isinit)(struct ips_ha *); + int (*isintr)(struct ips_ha *); + int (*init)(struct ips_ha *); + int (*erasebios)(struct ips_ha *); + int (*programbios)(struct ips_ha *, char *, u_int32_t, u_int32_t); + int (*verifybios)(struct ips_ha *, char *, u_int32_t, u_int32_t); + void (*statinit)(struct ips_ha *); + void (*intr)(struct ips_ha *); + void (*enableint)(struct ips_ha *); + u_int32_t (*statupd)(struct ips_ha *); } ips_hw_func_t; typedef struct ips_ha { - u8 ha_id[IPS_MAX_CHANNELS+1]; - u32 dcdb_active[IPS_MAX_CHANNELS]; - u32 io_addr; /* Base I/O address */ - u8 irq; /* IRQ for adapter */ - u8 ntargets; /* Number of targets */ - u8 nbus; /* Number of buses */ - u8 nlun; /* Number of Luns */ - u16 ad_type; /* Adapter type */ - u16 host_num; /* Adapter number */ - u32 max_xfer; /* Maximum Xfer size */ - u32 max_cmds; /* Max concurrent commands */ - u32 num_ioctl; /* Number of Ioctls */ + u_int8_t ha_id[IPS_MAX_CHANNELS+1]; + u_int32_t dcdb_active[IPS_MAX_CHANNELS]; + u_int32_t io_addr; /* Base I/O address */ + u_int8_t irq; /* IRQ for adapter */ + u_int8_t ntargets; /* Number of targets */ + u_int8_t nbus; /* Number of buses */ + u_int8_t nlun; /* Number of Luns */ + u_int16_t ad_type; /* Adapter type */ + u_int16_t host_num; /* Adapter number */ + u_int32_t max_xfer; /* Maximum Xfer size */ + u_int32_t max_cmds; /* Max concurrent commands */ + u_int32_t num_ioctl; /* Number of Ioctls */ ips_stat_t sp; /* Status packer pointer */ struct ips_scb *scbs; /* Array of all CCBS */ struct ips_scb *scb_freelist; /* SCB free list */ @@ -973,23 +1028,23 @@ typedef struct ips_ha { IPS_NVRAM_P5 *nvram; /* NVRAM page 5 data */ IPS_SUBSYS *subsys; /* Subsystem parameters */ char *ioctl_data; /* IOCTL data area */ - u32 ioctl_datasize; /* IOCTL data size */ - u32 cmd_in_progress; /* Current command in progress*/ - long flags; /* HA flags */ - u8 waitflag; /* are we waiting for cmd */ - u8 active; - u16 reset_count; /* number of resets */ - u32 last_ffdc; /* last time we sent ffdc info*/ - u8 revision_id; /* Revision level */ - u16 device_id; /* PCI device ID */ - u8 slot_num; /* PCI Slot Number */ - u16 subdevice_id; /* Subsystem device ID */ - u8 ioctl_order; /* Number of pages in ioctl */ - u8 reserved2; /* Empty */ - u8 bios_version[8]; /* BIOS Revision */ - u32 mem_addr; /* Memory mapped address */ - u32 io_len; /* Size of IO Address */ - u32 mem_len; /* Size of memory address */ + u_int32_t ioctl_datasize; /* IOCTL data size */ + u_int32_t cmd_in_progress; /* Current command in progress*/ + unsigned long flags; /* HA flags */ + u_int8_t waitflag; /* are we waiting for cmd */ + u_int8_t active; + u_int16_t reset_count; /* number of resets */ + u_int32_t last_ffdc; /* last time we sent ffdc info*/ + u_int8_t revision_id; /* Revision level */ + u_int16_t device_id; /* PCI device ID */ + u_int8_t slot_num; /* PCI Slot Number */ + u_int16_t subdevice_id; /* Subsystem device ID */ + u_int8_t ioctl_order; /* Number of pages in ioctl */ + u_int8_t reserved2; /* Empty */ + u_int8_t bios_version[8]; /* BIOS Revision */ + u_int32_t mem_addr; /* Memory mapped address */ + u_int32_t io_len; /* Size of IO Address */ + u_int32_t mem_len; /* Size of memory address */ char *mem_ptr; /* Memory mapped Ptr */ char *ioremap_ptr; /* ioremapped memory pointer */ ips_hw_func_t func; /* hw function pointers */ @@ -997,6 +1052,8 @@ typedef struct ips_ha { spinlock_t scb_lock; spinlock_t copp_lock; spinlock_t ips_lock; + struct semaphore ioctl_sem; /* Semaphore for new IOCTL's */ + struct semaphore flash_ioctl_sem; /* Semaphore for Flashing */ char *save_ioctl_data; /* Save Area for ioctl_data */ u8 save_ioctl_order; /* Save Area for ioctl_order */ u32 save_ioctl_datasize;/* Save Area for ioctl_datasize */ @@ -1010,21 +1067,21 @@ typedef void (*ips_scb_callback) (ips_ha_t *, struct ips_scb *); typedef struct ips_scb { IPS_HOST_COMMAND cmd; IPS_DCDB_TABLE dcdb; - u8 target_id; - u8 bus; - u8 lun; - u8 cdb[12]; - u32 scb_busaddr; - u32 data_busaddr; - u32 timeout; - u8 basic_status; - u8 extended_status; - u8 breakup; - u8 sg_break; - u32 data_len; - u32 sg_len; - u32 flags; - u32 op_code; + u_int8_t target_id; + u_int8_t bus; + u_int8_t lun; + u_int8_t cdb[12]; + u_int32_t scb_busaddr; + u_int32_t data_busaddr; + u_int32_t timeout; + u_int8_t basic_status; + u_int8_t extended_status; + u_int8_t breakup; + u_int8_t sg_break; + u_int32_t data_len; + u_int32_t sg_len; + u_int32_t flags; + u_int32_t op_code; IPS_SG_LIST *sg_list; Scsi_Cmnd *scsi_cmd; struct ips_scb *q_next; @@ -1035,20 +1092,20 @@ typedef struct ips_scb { typedef struct ips_scb_pt { IPS_HOST_COMMAND cmd; IPS_DCDB_TABLE dcdb; - u8 target_id; - u8 bus; - u8 lun; - u8 cdb[12]; - u32 scb_busaddr; - u32 data_busaddr; - u32 timeout; - u8 basic_status; - u8 extended_status; - u16 breakup; - u32 data_len; - u32 sg_len; - u32 flags; - u32 op_code; + u_int8_t target_id; + u_int8_t bus; + u_int8_t lun; + u_int8_t cdb[12]; + u_int32_t scb_busaddr; + u_int32_t data_busaddr; + u_int32_t timeout; + u_int8_t basic_status; + u_int8_t extended_status; + u_int16_t breakup; + u_int32_t data_len; + u_int32_t sg_len; + u_int32_t flags; + u_int32_t op_code; IPS_SG_LIST *sg_list; Scsi_Cmnd *scsi_cmd; struct ips_scb *q_next; @@ -1059,16 +1116,16 @@ typedef struct ips_scb_pt { * Passthru Command Format */ typedef struct { - u8 CoppID[4]; - u32 CoppCmd; - u32 PtBuffer; - u8 *CmdBuffer; - u32 CmdBSize; + u_int8_t CoppID[4]; + u_int32_t CoppCmd; + u_int32_t PtBuffer; + u_int8_t *CmdBuffer; + u_int32_t CmdBSize; ips_scb_pt_t CoppCP; - u32 TimeOut; - u8 BasicStatus; - u8 ExtendedStatus; - u16 reserved; + u_int32_t TimeOut; + u_int8_t BasicStatus; + u_int8_t ExtendedStatus; + u_int16_t reserved; } ips_passthru_t; #endif diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index 0bd3a64e24ec..b678ced62f9b 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -109,6 +109,7 @@ static Scsi_Host_Template __initdata *host_tpnt = NULL; static int __initdata host_count = 0; static struct parisc_device_id lasi700_scsi_tbl[] = { LASI700_ID_TABLE, + LASI710_ID_TABLE, { 0 } }; @@ -136,32 +137,48 @@ lasi700_driver_callback(struct parisc_device *dev) { unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET; int irq = busdevice_alloc_irq(dev); + char *driver_name; struct Scsi_Host *host; struct NCR_700_Host_Parameters *hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + if(dev->id.sversion == LASI_700_SVERSION) { + driver_name = "lasi700"; + } else { + driver_name = "lasi710"; + } if(hostdata == NULL) { - printk(KERN_ERR "lasi700: Failed to allocate host data\n"); + printk(KERN_ERR "%s: Failed to allocate host data\n", + driver_name); return 1; } memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); - if(request_mem_region(base, 64, "lasi700") == NULL) { - printk(KERN_ERR "lasi700: Failed to claim memory region\n"); + if(request_mem_region(base, 64, driver_name) == NULL) { + printk(KERN_ERR "%s: Failed to claim memory region\n", + driver_name); kfree(hostdata); return 1; } hostdata->base = base; hostdata->differential = 0; - hostdata->clock = LASI700_CLOCK; - hostdata->force_le_on_be = 1; + if(dev->id.sversion == LASI_700_SVERSION) { + hostdata->clock = LASI700_CLOCK; + hostdata->force_le_on_be = 1; + } else { + hostdata->clock = LASI710_CLOCK; + hostdata->force_le_on_be = 0; + hostdata->chip710 = 1; + hostdata->dmode_extra = DMODE_FC2; + } if((host = NCR_700_detect(host_tpnt, hostdata)) == NULL) { kfree(hostdata); release_mem_region(host->base, 64); return 1; } host->irq = irq; - if(request_irq(irq, NCR_700_intr, SA_SHIRQ, "lasi700", host)) { - printk(KERN_ERR "lasi700: irq problem, detatching\n"); + if(request_irq(irq, NCR_700_intr, SA_SHIRQ, driver_name, host)) { + printk(KERN_ERR "%s: irq problem, detatching\n", + driver_name); scsi_unregister(host); NCR_700_release(host); return 1; diff --git a/drivers/scsi/lasi700.h b/drivers/scsi/lasi700.h index 2c2cee9cdd83..21b03b9f8c2e 100644 --- a/drivers/scsi/lasi700.h +++ b/drivers/scsi/lasi700.h @@ -38,9 +38,19 @@ static int lasi700_release(struct Scsi_Host *host); this_id: 7, \ } +#define LASI_710_SVERSION 0x082 +#define LASI_700_SVERSION 0x071 + #define LASI700_ID_TABLE { \ hw_type: HPHW_FIO, \ - sversion: 0x071, \ + sversion: LASI_700_SVERSION, \ + hversion: HVERSION_ANY_ID, \ + hversion_rev: HVERSION_REV_ANY_ID, \ +} + +#define LASI710_ID_TABLE { \ + hw_type: HPHW_FIO, \ + sversion: LASI_710_SVERSION, \ hversion: HVERSION_ANY_ID, \ hversion_rev: HVERSION_REV_ANY_ID, \ } @@ -52,6 +62,7 @@ static int lasi700_release(struct Scsi_Host *host); } #define LASI700_CLOCK 25 +#define LASI710_CLOCK 40 #define LASI_SCSI_CORE_OFFSET 0x100 #endif diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 3b68638de951..af3de8f1b0a0 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -552,6 +552,8 @@ static void WROUTDOOR (mega_host_config * megaCfg, ulong value) MODULE_AUTHOR ("American Megatrends Inc."); MODULE_DESCRIPTION ("AMI MegaRAID driver"); +MODULE_LICENSE("GPL"); + #define DRIVER_LOCK_T #define DRIVER_LOCK_INIT(p) diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 4b47827a258c..263e1827d165 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -116,10 +116,7 @@ #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) -#ifdef MODULE #include <linux/module.h> -#endif - #include <asm/dma.h> #include <asm/io.h> #include <asm/system.h> @@ -9270,6 +9267,7 @@ const char *ncr53c8xx_info (struct Scsi_Host *host) /* ** Module stuff */ +MODULE_LICENSE("GPL"); #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) static diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 996831be2a43..f78c076216f8 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -83,6 +83,8 @@ static int max_sg_segs = 0; #ifdef MODULE MODULE_AUTHOR("Willem Riede"); MODULE_DESCRIPTION("OnStream SCSI Tape Driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(buffer_kbs, "i"); MODULE_PARM(write_threshold_kbs, "i"); MODULE_PARM(max_buffers, "i"); diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index 03e941fd9387..83e1e5934bfa 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -110,9 +110,7 @@ * (IRQ_AUTO == 254, IRQ_NONE == 255 in NCR5380.h) */ -#ifdef MODULE #include <linux/module.h> -#endif #include <asm/system.h> #include <linux/signal.h> @@ -609,3 +607,4 @@ static Scsi_Host_Template driver_template = MV_PAS16; MODULE_PARM(pas16_addr, "h"); MODULE_PARM(pas16_irq, "i"); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c index 38fa634e5919..af3f40708bd3 100644 --- a/drivers/scsi/pci2000.c +++ b/drivers/scsi/pci2000.c @@ -858,6 +858,7 @@ int Pci2000_BiosParam (Scsi_Disk *disk, kdev_t dev, int geom[]) } +MODULE_LICENSE("BSD without advertisement clause"); /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = PCI2000; diff --git a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c index e5cc17c6fb7a..5130ae7f8495 100644 --- a/drivers/scsi/pci2220i.c +++ b/drivers/scsi/pci2220i.c @@ -2924,6 +2924,7 @@ int Pci2220i_BiosParam (Scsi_Disk *disk, kdev_t dev, int geom[]) return 0; } +MODULE_LICENSE("BSD without advertising clause"); /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = PCI2220I; diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 344e65c747cb..92b571b97d7f 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -92,6 +92,8 @@ MODULE_PARM(synchronous, "i"); MODULE_PARM(reset_delay, "i"); MODULE_PARM(ext_trans, "i"); +MODULE_LICENSE("Dual MPL/GPL"); + /*====================================================================*/ typedef struct scsi_info_t { diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index b0902e3f9a7e..0ef2a6befa85 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -66,6 +66,8 @@ MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>"); MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module"); +MODULE_LICENSE("GPL"); + MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); #ifdef PCMCIA_DEBUG diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 2530c78ad0d5..862b18219f90 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -1145,3 +1145,4 @@ static int device_check(int host_no) printk("ppa: No devices found, aborting driver load.\n"); return 1; } +MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c index d3987e52aa4b..f4110a0f3783 100644 --- a/drivers/scsi/psi240i.c +++ b/drivers/scsi/psi240i.c @@ -714,6 +714,7 @@ int Psi240i_BiosParam (Scsi_Disk *disk, kdev_t dev, int geom[]) return 0; } +MODULE_LICENSE("GPL"); /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = PSI240I; diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 2b1730b968fc..deec416105cf 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -6812,6 +6812,7 @@ static char *qla1280_get_token(char *cmdline, char *str ) *cp = '\0'; return( cp ); } +MODULE_LICENSE("GPL"); /* * Overrides for Emacs so that we almost follow Linus's tabbing style. diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c index f6a9ecfcd052..6a8a50955df7 100644 --- a/drivers/scsi/qlogicfas.c +++ b/drivers/scsi/qlogicfas.c @@ -685,6 +685,7 @@ const char *qlogicfas_info(struct Scsi_Host * host) { return qinfo; } +MODULE_LICENSE("GPL"); /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = QLOGICFAS; diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c index ab87e2c06444..b631502f3a5f 100644 --- a/drivers/scsi/qlogicfc.c +++ b/drivers/scsi/qlogicfc.c @@ -2259,6 +2259,7 @@ void isp2x00_print_scsi_cmd(Scsi_Cmnd * cmd) #endif /* DEBUG_ISP2x00 */ +MODULE_LICENSE("GPL"); static Scsi_Host_Template driver_template = QLOGICFC; diff --git a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c index e9fdcdf9dc64..f75f301939ef 100644 --- a/drivers/scsi/qlogicisp.c +++ b/drivers/scsi/qlogicisp.c @@ -1994,6 +1994,7 @@ void isp1020_print_scsi_cmd(Scsi_Cmnd *cmd) #endif /* DEBUG_ISP1020 */ +MODULE_LICENSE("GPL"); static Scsi_Host_Template driver_template = QLOGICISP; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index b3412dd10d19..9f5de0a36668 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -2515,6 +2515,7 @@ static char *scsihosts; MODULE_PARM(scsihosts, "s"); MODULE_DESCRIPTION("SCSI core"); +MODULE_LICENSE("GPL"); #ifndef MODULE int __init scsi_setup(char *str) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 8a9a6d92eb38..c80772c226b7 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -805,3 +805,4 @@ static Scsi_Host_Template driver_template = SCSI_DEBUG; * tab-width: 8 * End: */ +MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 32d257fa1f92..6cd3b1a5d551 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1409,3 +1409,4 @@ static void __exit exit_sd(void) module_init(init_sd); module_exit(exit_sd); +MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 0725567f219b..2cf059b14403 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -257,6 +257,8 @@ static int irq = IRQ; MODULE_PARM (base_address, "i"); MODULE_PARM (controller_type, "b"); MODULE_PARM (irq, "i"); +MODULE_LICENSE("GPL"); + #define retcode(result) (((result) << 16) | (message << 8) | status) #define STATUS ((u8) isa_readb(st0x_cr_sr)) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index acdb31529de7..906d30481d2b 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1373,6 +1373,8 @@ static void sg_detach(Scsi_Device * scsidp) MODULE_AUTHOR("Douglas Gilbert"); MODULE_DESCRIPTION("SCSI generic (sg) driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(def_reserved_size, "i"); MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd"); diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 7035a4f06284..085e97d6c140 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -187,6 +187,8 @@ char *sim710; /* command line passed by insmod */ MODULE_AUTHOR("Richard Hirst"); MODULE_DESCRIPTION("Simple NCR53C710 driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(sim710, "s"); #endif diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 0d7e770b2efa..2d879db6d90f 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -940,3 +940,4 @@ static void __exit exit_sr(void) module_init(init_sr); module_exit(exit_sr); +MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 3433c1f2e177..83368d4cc5f2 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -78,6 +78,8 @@ static int max_sg_segs; MODULE_AUTHOR("Kai Makisara"); MODULE_DESCRIPTION("SCSI Tape Driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(buffer_kbs, "i"); MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size (KB; 32)"); MODULE_PARM(write_threshold_kbs, "i"); diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c index 03e6a188154b..07b487d8383b 100644 --- a/drivers/scsi/sym53c416.c +++ b/drivers/scsi/sym53c416.c @@ -847,6 +847,8 @@ static int sym53c416_bios_param(Disk *disk, kdev_t dev, int *ip) #ifdef MODULE MODULE_AUTHOR("Lieven Willems"); +MODULE_LICENSE("GPL"); + MODULE_PARM(sym53c416, "1-2i"); MODULE_PARM(sym53c416_1, "1-2i"); MODULE_PARM(sym53c416_2, "1-2i"); diff --git a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c index db21493e78ff..293152c2279e 100644 --- a/drivers/scsi/sym53c8xx.c +++ b/drivers/scsi/sym53c8xx.c @@ -101,9 +101,7 @@ #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) -#ifdef MODULE #include <linux/module.h> -#endif #include <asm/dma.h> #include <asm/io.h> @@ -14702,6 +14700,8 @@ sym_read_Tekram_nvram (ncr_slot *np, u_short device_id, Tekram_nvram *nvram) ** Module stuff */ +MODULE_LICENSE("GPL"); + #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) static #endif diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index 3abd78cd2b7e..7119128d71ed 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -120,6 +120,7 @@ #include "sd.h" #include <linux/stat.h> #include <linux/init.h> +#include <linux/module.h> static struct override { unsigned long address; @@ -394,6 +395,8 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src return 0; } +MODULE_LICENSE("GPL"); + #include "NCR5380.c" /* Eventually this will go into an include file, but this will be later */ diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 7bcbaf62960c..83d0684f110e 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -492,6 +492,8 @@ MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter #if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30) MODULE_AUTHOR("C.L. Huang / Kurt Garloff"); MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters"); +MODULE_LICENSE("GPL"); + MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); #endif diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index fd957d04b4f2..4ddab3936421 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -1756,6 +1756,7 @@ int u14_34f_release(struct Scsi_Host *shpnt) { return FALSE; } +MODULE_LICENSE("BSD without advertisement clause"); static Scsi_Host_Template driver_template = ULTRASTOR_14_34F; #include "scsi_module.c" diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c index b2437a1a1fac..a0104d6fe2c2 100644 --- a/drivers/scsi/ultrastor.c +++ b/drivers/scsi/ultrastor.c @@ -124,9 +124,7 @@ * Release ICM slot by clearing first byte on 24F. */ -#ifdef MODULE #include <linux/module.h> -#endif #include <linux/stddef.h> #include <linux/string.h> @@ -1167,6 +1165,8 @@ static void do_ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs) spin_unlock_irqrestore(&io_request_lock, flags); } +MODULE_LICENSE("GPL"); + /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = ULTRASTOR_14F; diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index 3bb27517f99f..e8c91abe09a5 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -142,9 +142,7 @@ * WD7000 driver now work on kernels >= 2.1.x */ -#ifdef MODULE #include <linux/module.h> -#endif #include <stdarg.h> #include <linux/kernel.h> @@ -1780,6 +1778,8 @@ int wd7000_biosparam (Disk *disk, kdev_t dev, int *ip) return (0); } +MODULE_LICENSE("GPL"); + /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = WD7000; diff --git a/drivers/sound/ac97.c b/drivers/sound/ac97.c index dc3d9584d8c7..258060ecbb6a 100644 --- a/drivers/sound/ac97.c +++ b/drivers/sound/ac97.c @@ -445,6 +445,8 @@ EXPORT_SYMBOL(ac97_put_register); EXPORT_SYMBOL(ac97_get_mixer_scaled); EXPORT_SYMBOL(ac97_mixer_ioctl); EXPORT_SYMBOL(ac97_reset); +MODULE_LICENSE("GPL"); + /* * Local variables: diff --git a/drivers/sound/ac97_codec.c b/drivers/sound/ac97_codec.c index 3d5882c85d6a..ffd330877e6d 100644 --- a/drivers/sound/ac97_codec.c +++ b/drivers/sound/ac97_codec.c @@ -1020,3 +1020,4 @@ unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate) } EXPORT_SYMBOL(ac97_set_adc_rate); +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/aci.c b/drivers/sound/aci.c index 5d8ac31e0ede..97be26ef7e5e 100644 --- a/drivers/sound/aci.c +++ b/drivers/sound/aci.c @@ -706,3 +706,4 @@ static void __exit unload_aci(void) module_init(attach_aci); module_exit(unload_aci); +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/ad1816.c b/drivers/sound/ad1816.c index e75aba529568..501bc1bbe6be 100644 --- a/drivers/sound/ad1816.c +++ b/drivers/sound/ad1816.c @@ -1471,3 +1471,4 @@ static int __init setup_ad1816(char *str) __setup("ad1816=", setup_ad1816); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c index 684c95b35f5d..b1dbbba26dec 100644 --- a/drivers/sound/ad1848.c +++ b/drivers/sound/ad1848.c @@ -3064,3 +3064,4 @@ static int __init setup_ad1848(char *str) __setup("ad1848=", setup_ad1848); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/adlib_card.c b/drivers/sound/adlib_card.c index 6b370c2fc7d4..46e9deb63ae4 100644 --- a/drivers/sound/adlib_card.c +++ b/drivers/sound/adlib_card.c @@ -70,3 +70,4 @@ static int __init setup_adlib(char *str) } __setup("adlib=", setup_adlib); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/aedsp16.c b/drivers/sound/aedsp16.c index 2ac5efad2214..67ff5cd68a37 100644 --- a/drivers/sound/aedsp16.c +++ b/drivers/sound/aedsp16.c @@ -1325,6 +1325,7 @@ MODULE_PARM(mpu_base, "i"); MODULE_PARM_DESC(mpu_base,"MPU-401 I/O base address (0x300 0x310 0x320 0x330)"); MODULE_AUTHOR("Riccardo Facchetti <fizban@tin.it>"); MODULE_DESCRIPTION("Audio Excel DSP 16 Driver Version " VERSION); +MODULE_LICENSE("GPL"); static int __init do_init_aedsp16(void) { printk("Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98\n"); diff --git a/drivers/sound/awe_wave.c b/drivers/sound/awe_wave.c index 4455c32c55d5..cdc86091647f 100644 --- a/drivers/sound/awe_wave.c +++ b/drivers/sound/awe_wave.c @@ -213,6 +213,8 @@ static int isapnp = 0; MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>"); MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "base i/o port of Emu8000"); MODULE_PARM(memsize, "i"); diff --git a/drivers/sound/cmpci.c b/drivers/sound/cmpci.c index 87180a2779c5..d0c9262c81e5 100644 --- a/drivers/sound/cmpci.c +++ b/drivers/sound/cmpci.c @@ -3140,6 +3140,8 @@ static int __init init_cmpci(void) MODULE_AUTHOR("ChenLi Tien, cltien@cmedia.com.tw"); MODULE_DESCRIPTION("CM8x38 Audio Driver"); +MODULE_LICENSE("GPL"); + static void __exit cleanup_cmpci(void) { diff --git a/drivers/sound/cs4232.c b/drivers/sound/cs4232.c index d4ff105d211e..15bd72c404e7 100644 --- a/drivers/sound/cs4232.c +++ b/drivers/sound/cs4232.c @@ -329,6 +329,8 @@ static int __initdata isapnp = 1; MODULE_DESCRIPTION("CS4232 based soundcard driver"); MODULE_AUTHOR("Hannu Savolainen, Paul Barton-Davis"); +MODULE_LICENSE("GPL"); + MODULE_PARM(io,"i"); MODULE_PARM_DESC(io,"base I/O port for AD1848"); MODULE_PARM(irq,"i"); diff --git a/drivers/sound/cs4281/cs4281m.c b/drivers/sound/cs4281/cs4281m.c index e0cb0b1d0738..1035eb618e98 100644 --- a/drivers/sound/cs4281/cs4281m.c +++ b/drivers/sound/cs4281/cs4281m.c @@ -4512,6 +4512,7 @@ void __exit cs4281_cleanup_module(void) MODULE_AUTHOR("gw boynton, audio@crystal.cirrus.com"); MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver"); +MODULE_LICENSE("GPL"); // --------------------------------------------------------------------- diff --git a/drivers/sound/cs46xx.c b/drivers/sound/cs46xx.c index c8f8d8bea2a5..e79662a952e2 100644 --- a/drivers/sound/cs46xx.c +++ b/drivers/sound/cs46xx.c @@ -5259,6 +5259,8 @@ static struct cs_card_type cards[]={ MODULE_AUTHOR("Alan Cox <alan@redhat.com>, Jaroslav Kysela, <pcaudio@crystal.cirrus.com>"); MODULE_DESCRIPTION("Crystal SoundFusion Audio Support"); +MODULE_LICENSE("GPL"); + static const char cs46xx_banner[] = KERN_INFO "Crystal 4280/46xx + AC97 Audio, version " CS46XX_MAJOR_VERSION "." CS46XX_MINOR_VERSION "." CS46XX_ARCH ", " __TIME__ " " __DATE__ "\n"; static const char fndmsg[] = KERN_INFO "cs46xx: Found %d audio device(s).\n"; diff --git a/drivers/sound/emu10k1/main.c b/drivers/sound/emu10k1/main.c index 950ca1ec9b61..cdacad83b37c 100644 --- a/drivers/sound/emu10k1/main.c +++ b/drivers/sound/emu10k1/main.c @@ -999,6 +999,7 @@ static void __devexit emu10k1_remove(struct pci_dev *pci_dev) MODULE_AUTHOR("Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@opensource.creative.com)"); MODULE_DESCRIPTION("Creative EMU10K1 PCI Audio Driver v" DRIVER_VERSION "\nCopyright (C) 1999 Creative Technology Ltd."); +MODULE_LICENSE("GPL"); static struct pci_driver emu10k1_pci_driver = { name: "emu10k1", diff --git a/drivers/sound/es1370.c b/drivers/sound/es1370.c index b2ea46a86fb5..3da841bb01ec 100644 --- a/drivers/sound/es1370.c +++ b/drivers/sound/es1370.c @@ -2541,6 +2541,8 @@ MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone"); MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); MODULE_DESCRIPTION("ES1370 AudioPCI Driver"); +MODULE_LICENSE("GPL"); + /* --------------------------------------------------------------------- */ diff --git a/drivers/sound/es1371.c b/drivers/sound/es1371.c index 2d0714825c77..f685c5b1ec99 100644 --- a/drivers/sound/es1371.c +++ b/drivers/sound/es1371.c @@ -2757,6 +2757,8 @@ MODULE_PARM_DESC(amplifier, "Set to 1 if the machine needs the amp control enabl MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver"); +MODULE_LICENSE("GPL"); + /* --------------------------------------------------------------------- */ diff --git a/drivers/sound/esssolo1.c b/drivers/sound/esssolo1.c index decf5057a7c1..6db33a2dca47 100644 --- a/drivers/sound/esssolo1.c +++ b/drivers/sound/esssolo1.c @@ -2468,6 +2468,8 @@ static int __init init_solo1(void) MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); MODULE_DESCRIPTION("ESS Solo1 Driver"); +MODULE_LICENSE("GPL"); + static void __exit cleanup_solo1(void) { diff --git a/drivers/sound/gus_card.c b/drivers/sound/gus_card.c index 9b937a253e5c..8b77f4e3ac18 100644 --- a/drivers/sound/gus_card.c +++ b/drivers/sound/gus_card.c @@ -232,6 +232,7 @@ MODULE_PARM(no_wave_dma, "i"); MODULE_PARM(db16, "i"); MODULE_PARM(gus16, "i"); #endif +MODULE_LICENSE("GPL"); static int __init init_gus(void) { diff --git a/drivers/sound/i810_audio.c b/drivers/sound/i810_audio.c index 3139a8c448ad..4b03682ceeea 100644 --- a/drivers/sound/i810_audio.c +++ b/drivers/sound/i810_audio.c @@ -2700,6 +2700,7 @@ static void __exit i810_remove(struct pci_dev *pci_dev) MODULE_AUTHOR(""); MODULE_DESCRIPTION("Intel 810 audio support"); +MODULE_LICENSE("GPL"); MODULE_PARM(ftsodell, "i"); MODULE_PARM(clocking, "i"); MODULE_PARM(strict_clocking, "i"); diff --git a/drivers/sound/mad16.c b/drivers/sound/mad16.c index 05f1dab80000..268c31f3c479 100644 --- a/drivers/sound/mad16.c +++ b/drivers/sound/mad16.c @@ -1071,3 +1071,4 @@ static int __init setup_mad16(char *str) __setup("mad16=", setup_mad16); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/maestro.c b/drivers/sound/maestro.c index b2392d1a8f40..e72cc4a11694 100644 --- a/drivers/sound/maestro.c +++ b/drivers/sound/maestro.c @@ -257,6 +257,8 @@ static int clocking=48000; MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Alan Cox <alan@redhat.com>"); MODULE_DESCRIPTION("ESS Maestro Driver"); +MODULE_LICENSE("GPL"); + #ifdef M_DEBUG MODULE_PARM(debug,"i"); #endif diff --git a/drivers/sound/maestro3.c b/drivers/sound/maestro3.c index b6c63a8d8d49..2de6518d55bf 100644 --- a/drivers/sound/maestro3.c +++ b/drivers/sound/maestro3.c @@ -2905,6 +2905,8 @@ static int m3_resume(struct pci_dev *pci_dev) MODULE_AUTHOR("Zach Brown <zab@zabbo.net>"); MODULE_DESCRIPTION("ESS Maestro3/Allegro Driver"); +MODULE_LICENSE("GPL"); + #ifdef M_DEBUG MODULE_PARM(debug,"i"); #endif diff --git a/drivers/sound/maui.c b/drivers/sound/maui.c index 54927b719457..863d3e003eed 100644 --- a/drivers/sound/maui.c +++ b/drivers/sound/maui.c @@ -474,3 +474,4 @@ static int __init setup_maui(char *str) __setup("maui=", setup_maui); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/midibuf.c b/drivers/sound/midibuf.c index d0db7d5d213d..66815f307b78 100644 --- a/drivers/sound/midibuf.c +++ b/drivers/sound/midibuf.c @@ -253,13 +253,13 @@ void MIDIbuf_release(int dev, struct file *file) midi_devs[dev]->close(dev); + open_devs--; + if (open_devs == 0) + del_timer_sync(&poll_timer); vfree(midi_in_buf[dev]); vfree(midi_out_buf[dev]); midi_in_buf[dev] = NULL; midi_out_buf[dev] = NULL; - if (open_devs < 2) - del_timer(&poll_timer);; - open_devs--; if (midi_devs[dev]->owner) __MOD_DEC_USE_COUNT (midi_devs[dev]->owner); diff --git a/drivers/sound/mpu401.c b/drivers/sound/mpu401.c index f457d5c76537..f3a006162fe0 100644 --- a/drivers/sound/mpu401.c +++ b/drivers/sound/mpu401.c @@ -1794,3 +1794,4 @@ static int __init setup_mpu401(char *str) __setup("mpu401=", setup_mpu401); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/msnd.c b/drivers/sound/msnd.c index a9facd762566..b80cdf908130 100644 --- a/drivers/sound/msnd.c +++ b/drivers/sound/msnd.c @@ -392,6 +392,8 @@ EXPORT_SYMBOL(msnd_disable_irq); #ifdef MODULE MODULE_AUTHOR ("Andrew Veliath <andrewtv@usa.net>"); MODULE_DESCRIPTION ("Turtle Beach MultiSound Driver Base"); +MODULE_LICENSE("GPL"); + int init_module(void) { diff --git a/drivers/sound/msnd_pinnacle.c b/drivers/sound/msnd_pinnacle.c index 91150cd96a0e..83d6c29cc0ed 100644 --- a/drivers/sound/msnd_pinnacle.c +++ b/drivers/sound/msnd_pinnacle.c @@ -1571,6 +1571,8 @@ static int __init msnd_pinnacle_cfg_devices(int cfg, int reset, msnd_pinnacle_cf #ifdef MODULE MODULE_AUTHOR ("Andrew Veliath <andrewtv@usa.net>"); MODULE_DESCRIPTION ("Turtle Beach " LONGNAME " Linux Driver"); +MODULE_LICENSE("GPL"); + MODULE_PARM (io, "i"); MODULE_PARM (irq, "i"); MODULE_PARM (mem, "i"); diff --git a/drivers/sound/nm256_audio.c b/drivers/sound/nm256_audio.c index 13ce7186df84..ed8930434502 100644 --- a/drivers/sound/nm256_audio.c +++ b/drivers/sound/nm256_audio.c @@ -1653,6 +1653,8 @@ static struct pci_device_id nm256_pci_tbl[] __devinitdata = { {0,} }; MODULE_DEVICE_TABLE(pci, nm256_pci_tbl); +MODULE_LICENSE("GPL"); + struct pci_driver nm256_pci_driver = { name:"nm256_audio", diff --git a/drivers/sound/opl3.c b/drivers/sound/opl3.c index c86eb61d5aa0..0adfeb298c2d 100644 --- a/drivers/sound/opl3.c +++ b/drivers/sound/opl3.c @@ -1250,3 +1250,4 @@ static int __init setup_opl3(char *str) __setup("opl3=", setup_opl3); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/opl3sa.c b/drivers/sound/opl3sa.c index 3295a85a85c6..b8bb4b973946 100644 --- a/drivers/sound/opl3sa.c +++ b/drivers/sound/opl3sa.c @@ -334,3 +334,4 @@ static int __init setup_opl3sa(char *str) __setup("opl3sa=", setup_opl3sa); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/opl3sa2.c b/drivers/sound/opl3sa2.c index 51c5cf29e6f5..7791f2cad1ea 100644 --- a/drivers/sound/opl3sa2.c +++ b/drivers/sound/opl3sa2.c @@ -164,6 +164,8 @@ static int __initdata multiple; /* = 0 */ MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver)."); MODULE_AUTHOR("Scott Murray <scott@spiteful.org>"); +MODULE_LICENSE("GPL"); + MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "Set I/O base of OPL3-SA2 or SA3 card (usually 0x370. Address must be even and must be from 0x100 to 0xFFE)"); diff --git a/drivers/sound/pas2_card.c b/drivers/sound/pas2_card.c index 52e0d2865d44..31cdc0f8049d 100644 --- a/drivers/sound/pas2_card.c +++ b/drivers/sound/pas2_card.c @@ -403,6 +403,8 @@ MODULE_PARM(joystick,"i"); MODULE_PARM(symphony,"i"); MODULE_PARM(broken_bus_clock,"i"); +MODULE_LICENSE("GPL"); + static int __init init_pas2(void) { printk(KERN_INFO "Pro Audio Spectrum driver Copyright (C) by Hannu Savolainen 1993-1996\n"); diff --git a/drivers/sound/pss.c b/drivers/sound/pss.c index 6663f682cfb3..1804f9d69ed1 100644 --- a/drivers/sound/pss.c +++ b/drivers/sound/pss.c @@ -1132,6 +1132,8 @@ MODULE_PARM(pss_mixer, "b"); MODULE_PARM_DESC(pss_mixer, "Enable (1) or disable (0) PSS mixer (controlling of output volume, bass, treble, synth volume). The mixer is not available on all PSS cards."); MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl"); MODULE_DESCRIPTION("Module for PSS sound cards (based on AD1848, ADSP-2115 and ESC614). This module includes control of output amplifier and synth volume of the Beethoven ADSP-16 card (this may work with other PSS cards).\n"); +MODULE_LICENSE("GPL"); + static int fw_load = 0; static int pssmpu = 0, pssmss = 0; diff --git a/drivers/sound/rme96xx.c b/drivers/sound/rme96xx.c index 28f1ab272614..212580c7c06f 100644 --- a/drivers/sound/rme96xx.c +++ b/drivers/sound/rme96xx.c @@ -52,6 +52,8 @@ MODULE_PARM_DESC(devices, "number of dsp devices allocated by the driver"); MODULE_AUTHOR("Guenter Geiger, geiger@debian.org"); MODULE_DESCRIPTION("RME9652/36 \"Hammerfall\" Driver"); +MODULE_LICENSE("GPL"); + #ifdef DEBUG #define DBG(x) printk("RME_DEBUG:");x diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c index 869fa7d8b83f..43945c4a6814 100644 --- a/drivers/sound/sb_card.c +++ b/drivers/sound/sb_card.c @@ -211,6 +211,7 @@ static int pnplegacy = 0; #endif MODULE_DESCRIPTION("Soundblaster driver"); +MODULE_LICENSE("GPL"); MODULE_PARM(io, "i"); MODULE_PARM(irq, "i"); @@ -374,11 +375,6 @@ static struct { 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 32", - ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0047), - ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0,0,0, - 0,1,1,-1}, - {"Sound Blaster AWE 32", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0,0,0,0, diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c index 9a601cef863d..ba1df155a3cb 100644 --- a/drivers/sound/sb_common.c +++ b/drivers/sound/sb_common.c @@ -1292,3 +1292,4 @@ EXPORT_SYMBOL(sb_be_quiet); EXPORT_SYMBOL(probe_sbmpu); EXPORT_SYMBOL(unload_sbmpu); EXPORT_SYMBOL(smw_free); +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/sb_mixer.c b/drivers/sound/sb_mixer.c index 6eca75faecf7..c71807a6db9b 100644 --- a/drivers/sound/sb_mixer.c +++ b/drivers/sound/sb_mixer.c @@ -748,6 +748,9 @@ int sb_mixer_init(sb_devc * devc, struct module *owner) void sb_mixer_unload(sb_devc *devc) { + if (devc->my_mixerdev == -1) + return; + kfree(mixer_devs[devc->my_mixerdev]); sound_unload_mixerdev(devc->my_mixerdev); sbmixnum--; diff --git a/drivers/sound/sgalaxy.c b/drivers/sound/sgalaxy.c index 9d16bbe9f669..1e310971653d 100644 --- a/drivers/sound/sgalaxy.c +++ b/drivers/sound/sgalaxy.c @@ -194,3 +194,4 @@ static int __init setup_sgalaxy(char *str) __setup("sgalaxy=", setup_sgalaxy); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/sonicvibes.c b/drivers/sound/sonicvibes.c index 0299f99a816e..f3f86b354f26 100644 --- a/drivers/sound/sonicvibes.c +++ b/drivers/sound/sonicvibes.c @@ -2458,6 +2458,8 @@ MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled"); MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); MODULE_DESCRIPTION("S3 SonicVibes Driver"); +MODULE_LICENSE("GPL"); + /* --------------------------------------------------------------------- */ diff --git a/drivers/sound/sound_core.c b/drivers/sound/sound_core.c index 83e7cd921f19..984fc2394fcb 100644 --- a/drivers/sound/sound_core.c +++ b/drivers/sound/sound_core.c @@ -547,6 +547,7 @@ EXPORT_SYMBOL(mod_firmware_load); MODULE_DESCRIPTION("Core sound module"); MODULE_AUTHOR("Alan Cox"); +MODULE_LICENSE("GPL"); static void __exit cleanup_soundcore(void) { diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c index b3808587d7c7..55a99a5e75e4 100644 --- a/drivers/sound/soundcard.c +++ b/drivers/sound/soundcard.c @@ -44,6 +44,7 @@ #include <linux/delay.h> #include <linux/proc_fs.h> #include <linux/smp_lock.h> +#include <linux/module.h> /* * This ought to be moved into include/asm/dma.h @@ -645,6 +646,7 @@ static void __exit oss_cleanup(void) module_init(oss_init); module_exit(oss_cleanup); +MODULE_LICENSE("GPL"); int sound_alloc_dma(int chn, char *deviceID) diff --git a/drivers/sound/sscape.c b/drivers/sound/sscape.c index 694321be7fd5..55c77c7df062 100644 --- a/drivers/sound/sscape.c +++ b/drivers/sound/sscape.c @@ -1528,3 +1528,4 @@ static int __init setup_sscape(char *str) __setup("sscape=", setup_sscape); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c index 5e173ebea909..13971cc5022a 100644 --- a/drivers/sound/trident.c +++ b/drivers/sound/trident.c @@ -4165,6 +4165,8 @@ static void __exit trident_remove(struct pci_dev *pci_dev) MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee"); MODULE_DESCRIPTION("Trident 4DWave/SiS 7018/ALi 5451 and Tvia/IGST CyberPro5050 PCI Audio Driver"); +MODULE_LICENSE("GPL"); + #define TRIDENT_MODULE_NAME "trident" diff --git a/drivers/sound/trix.c b/drivers/sound/trix.c index 03b4b1999cf3..356b66d7aed7 100644 --- a/drivers/sound/trix.c +++ b/drivers/sound/trix.c @@ -543,3 +543,4 @@ static int __init setup_trix (char *str) __setup("trix=", setup_trix); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/uart401.c b/drivers/sound/uart401.c index 8a2f169d47ed..038eb96e28e2 100644 --- a/drivers/sound/uart401.c +++ b/drivers/sound/uart401.c @@ -478,3 +478,4 @@ static int __init setup_uart401(char *str) __setup("uart401=", setup_uart401); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/uart6850.c b/drivers/sound/uart6850.c index 437f28102d91..4ebcf2f8ee3d 100644 --- a/drivers/sound/uart6850.c +++ b/drivers/sound/uart6850.c @@ -361,3 +361,4 @@ static int __init setup_uart6850(char *str) } __setup("uart6850=", setup_uart6850); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/v_midi.c b/drivers/sound/v_midi.c index 4362de3467a4..826896cb7aa3 100644 --- a/drivers/sound/v_midi.c +++ b/drivers/sound/v_midi.c @@ -287,3 +287,4 @@ static void __exit cleanup_vmidi(void) module_init(init_vmidi); module_exit(cleanup_vmidi); +MODULE_LICENSE("GPL"); diff --git a/drivers/sound/via82cxxx_audio.c b/drivers/sound/via82cxxx_audio.c index 1ea4615e0173..854175122a28 100644 --- a/drivers/sound/via82cxxx_audio.c +++ b/drivers/sound/via82cxxx_audio.c @@ -3254,6 +3254,8 @@ module_exit(cleanup_via82cxxx_audio); MODULE_AUTHOR("Jeff Garzik <jgarzik@mandrakesoft.com>"); MODULE_DESCRIPTION("DSP audio and mixer driver for Via 82Cxxx audio devices"); +MODULE_LICENSE("GPL"); + EXPORT_NO_SYMBOLS; diff --git a/drivers/sound/wavfront.c b/drivers/sound/wavfront.c index 9743ec1f6253..632e73127a82 100644 --- a/drivers/sound/wavfront.c +++ b/drivers/sound/wavfront.c @@ -3486,6 +3486,7 @@ static int irq = -1; MODULE_AUTHOR ("Paul Barton-Davis <pbd@op.net>"); MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver"); +MODULE_LICENSE("GPL"); MODULE_PARM (io,"i"); MODULE_PARM (irq,"i"); diff --git a/drivers/sound/ymfpci.c b/drivers/sound/ymfpci.c index 21d1eadce554..6ed4d261176e 100644 --- a/drivers/sound/ymfpci.c +++ b/drivers/sound/ymfpci.c @@ -2525,6 +2525,7 @@ static void __devexit ymf_remove_one(struct pci_dev *pcidev) MODULE_AUTHOR("Jaroslav Kysela"); MODULE_DESCRIPTION("Yamaha YMF7xx PCI Audio"); +MODULE_LICENSE("GPL"); static struct pci_driver ymfpci_driver = { name: "ymfpci", diff --git a/drivers/usb/pegasus.h b/drivers/usb/pegasus.h index 182d27a1086a..8104c0cc56bf 100644 --- a/drivers/usb/pegasus.h +++ b/drivers/usb/pegasus.h @@ -142,6 +142,7 @@ struct usb_eth_dev { #define VENDOR_SMARTBRIDGES 0x08d1 #define VENDOR_SMC 0x0707 #define VENDOR_SOHOWARE 0x15e8 +#define VENDOR_BELKIN 0x050d #else /* PEGASUS_DEV */ @@ -235,5 +236,8 @@ PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100, DEFAULT_GPIO_RESET ) +PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", + VENDOR_BELKIN, 0x0121, + DEFAULT_GPIO_RESET | PEGASUS_II ) #endif /* PEGASUS_DEV */ diff --git a/drivers/usb/scanner.h b/drivers/usb/scanner.h index e4b21bad0368..50dea437173f 100644 --- a/drivers/usb/scanner.h +++ b/drivers/usb/scanner.h @@ -67,6 +67,7 @@ static struct usb_device_id scanner_device_ids [] = { /* Acer */ { USB_DEVICE(0x04a5, 0x2060) }, /* Prisa Acerscan 620U & 640U (!)*/ { USB_DEVICE(0x04a5, 0x2040) }, /* Prisa AcerScan 620U (!) */ + { USB_DEVICE(0x04a5, 0x20c0) }, /* Prisa AcerScan 1240UT */ { USB_DEVICE(0x04a5, 0x2022) }, /* Vuego Scan Brisa 340U */ /* Agfa */ { USB_DEVICE(0x06bd, 0x0001) }, /* SnapScan 1212U */ diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 556afcf3ca2f..a2b68fa36b85 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -108,6 +108,12 @@ static __devinitdata struct usb_device_id id_table_combined [] = { { USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) }, { USB_DEVICE(PERACOM_VID, PERACOM_PID) }, { USB_DEVICE(GOHUBS_VID, GOHUBS_PID) }, + { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) }, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id belkin_dockstation_table [] = { + { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) }, { } /* Terminating entry */ }; @@ -133,6 +139,27 @@ static __devinitdata struct usb_device_id gocom232_table [] = { MODULE_DEVICE_TABLE (usb, id_table_combined); +/* All of the device info needed for the Belkin dockstation serial converter */ +struct usb_serial_device_type belkin_dockstation_device = { + name: "Belkin F5U120-PC USB Serial Adapter", + id_table: belkin_dockstation_table, /* the Belkin F5U103 device */ + needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */ + needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ + needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ + num_interrupt_in: 1, + num_bulk_in: 1, + num_bulk_out: 1, + num_ports: 1, + open: belkin_sa_open, + close: belkin_sa_close, + read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */ + ioctl: belkin_sa_ioctl, + set_termios: belkin_sa_set_termios, + break_ctl: belkin_sa_break_ctl, + startup: belkin_sa_startup, + shutdown: belkin_sa_shutdown, +}; + /* All of the device info needed for the Belkin serial converter */ struct usb_serial_device_type belkin_sa_device = { name: "Belkin F5U103 USB Serial Adapter", @@ -345,7 +372,7 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp) static void belkin_sa_read_int_callback (struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; - struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private; + struct belkin_sa_private *priv; struct usb_serial *serial; unsigned char *data = urb->transfer_buffer; @@ -353,16 +380,17 @@ static void belkin_sa_read_int_callback (struct urb *urb) if (urb->status) return; - if (port_paranoia_check (port, "belkin_sa_read_interrupt")) return; + if (port_paranoia_check (port, __FUNCTION__)) return; serial = port->serial; - if (serial_paranoia_check (serial, "belkin_sa_read_interrupt")) return; + if (serial_paranoia_check (serial, __FUNCTION__)) return; usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data); /* Handle known interrupt data */ /* ignore data[0] and data[1] */ + priv = (struct belkin_sa_private *)port->private; priv->last_msr = data[BELKIN_SA_MSR_INDEX]; /* Record Control Line states */ @@ -603,6 +631,7 @@ static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, un static int __init belkin_sa_init (void) { + usb_serial_register (&belkin_dockstation_device); usb_serial_register (&belkin_sa_device); usb_serial_register (&belkin_old_device); usb_serial_register (&peracom_device); @@ -614,6 +643,7 @@ static int __init belkin_sa_init (void) static void __exit belkin_sa_exit (void) { + usb_serial_deregister (&belkin_dockstation_device); usb_serial_deregister (&belkin_sa_device); usb_serial_deregister (&belkin_old_device); usb_serial_deregister (&peracom_device); diff --git a/drivers/usb/serial/belkin_sa.h b/drivers/usb/serial/belkin_sa.h index daf51f7ece29..73f401cc341d 100644 --- a/drivers/usb/serial/belkin_sa.h +++ b/drivers/usb/serial/belkin_sa.h @@ -33,6 +33,9 @@ #ifndef __LINUX_USB_SERIAL_BSA_H #define __LINUX_USB_SERIAL_BSA_H +#define BELKIN_DOCKSTATION_VID 0x050d /* Vendor Id */ +#define BELKIN_DOCKSTATION_PID 0x1203 /* Product Id */ + #define BELKIN_SA_VID 0x050d /* Vendor Id */ #define BELKIN_SA_PID 0x0103 /* Product Id */ diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 6f6139854db0..65b633b656cc 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -309,16 +309,16 @@ static void cyberjack_read_int_callback( struct urb *urb ) struct usb_serial *serial; unsigned char *data = urb->transfer_buffer; + if (port_paranoia_check (port, __FUNCTION__)) return; + dbg(__FUNCTION__ " - port %d", port->number); /* the urb might have been killed. */ if (urb->status) return; - if (port_paranoia_check (port, "cyberjack_read_interrupt")) return; - serial = port->serial; - if (serial_paranoia_check (serial, "cyberjack_read_interrupt")) return; + if (serial_paranoia_check (serial, __FUNCTION__)) return; usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data); diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 660f26f79249..a3600c7e34d0 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -12,6 +12,9 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * 2001_Sep_19 gkh + * Added break support. + * * 2001_Aug_30 gkh * fixed oops in write_bulk_callback. * @@ -53,7 +56,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.7" +#define DRIVER_VERSION "v0.8" #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver" @@ -67,6 +70,26 @@ static __devinitdata struct usb_device_id id_table [] = { MODULE_DEVICE_TABLE (usb, id_table); +#define SET_LINE_REQUEST_TYPE 0x21 +#define SET_LINE_REQUEST 0x20 + +#define SET_CONTROL_REQUEST_TYPE 0x21 +#define SET_CONTROL_REQUEST 0x22 + +#define BREAK_REQUEST_TYPE 0x21 +#define BREAK_REQUEST 0x23 +#define BREAK_ON 0xffff +#define BREAK_OFF 0x0000 + +#define GET_LINE_REQUEST_TYPE 0xa1 +#define GET_LINE_REQUEST 0x21 + +#define VENDOR_WRITE_REQUEST_TYPE 0x40 +#define VENDOR_WRITE_REQUEST 0x01 + +#define VENDOR_READ_REQUEST_TYPE 0xc0 +#define VENDOR_READ_REQUEST 0x01 + /* function prototypes for a PL2303 serial converter */ static int pl2303_open (struct usb_serial_port *port, struct file *filp); static void pl2303_close (struct usb_serial_port *port, struct file *filp); @@ -80,6 +103,7 @@ static void pl2303_write_bulk_callback (struct urb *urb); static int pl2303_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count); static void pl2303_break_ctl(struct usb_serial_port *port,int break_state); +static void pl2303_shutdown (struct usb_serial *serial); /* All of the device info needed for the PL2303 SIO serial converter */ @@ -102,6 +126,7 @@ static struct usb_serial_device_type pl2303_device = { read_bulk_callback: pl2303_read_bulk_callback, read_int_callback: pl2303_read_int_callback, write_bulk_callback: pl2303_write_bulk_callback, + shutdown: pl2303_shutdown, }; @@ -145,54 +170,60 @@ static int pl2303_write (struct usb_serial_port *port, int from_user, const uns -static void -pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios) -{ /* pl2303_set_termios */ +static void pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios) +{ struct usb_serial *serial = port->serial; - unsigned int cflag = port->tty->termios->c_cflag; - unsigned char buf[7] = { 0, 0, 0, 0, 0, 0, 0}; + unsigned int cflag; + unsigned char *buf; int baud; int i; + dbg (__FUNCTION__ " - port %d", port->number); - dbg ("pl2303_set_termios port %d", port->number); + if ((!port->tty) || (!port->tty->termios)) { + dbg(__FUNCTION__" - no tty structures"); + return; + } + cflag = port->tty->termios->c_cflag; + /* check that they really want us to change something */ + if (old_termios) { + if ((cflag == old_termios->c_cflag) && + (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { + dbg(__FUNCTION__ " - nothing to change..."); + return; + } + } + buf = kmalloc (7, GFP_KERNEL); + if (!buf) { + err(__FUNCTION__ " - out of memory."); + return; + } + memset (buf, 0x00, 0x07); + i = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0), - 0x21, 0xa1, 0, 0, buf, 7, 100); - + GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE, + 0, 0, buf, 7, 100); dbg ("0xa1:0x21:0:0 %d - %x %x %x %x %x %x %x", i, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), - 1, 0x40, 0, 1, NULL, 0, 100); + VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE, + 0, 1, NULL, 0, 100); dbg ("0x40:1:0:1 %d", i); - - if (cflag & CSIZE) { switch (cflag & CSIZE) { - case CS5: - buf[6] = 5; - dbg ("Setting CS5"); - break; - case CS6: - buf[6] = 6; - dbg ("Setting CS6"); - break; - case CS7: - buf[6] = 7; - dbg ("Setting CS7"); - break; - case CS8: - buf[6] = 8; - dbg ("Setting CS8"); - break; + case CS5: buf[6] = 5; break; + case CS6: buf[6] = 6; break; + case CS7: buf[6] = 7; break; default: - err ("CSIZE was set but not CS5-CS8"); + case CS8: buf[6] = 8; break; } + dbg (__FUNCTION__ " - data bits = %d", buf[6]); } baud = 0; @@ -216,7 +247,7 @@ pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios) err ("pl2303 driver does not support the baudrate requested (fix it)"); break; } - + dbg (__FUNCTION__ " - baud = %d", baud); if (baud) { buf[0] = baud & 0xff; buf[1] = (baud >> 8) & 0xff; @@ -224,16 +255,17 @@ pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios) buf[3] = (baud >> 24) & 0xff; } - /* For reference buf[4]=0 is 1 stop bits */ /* For reference buf[4]=1 is 1.5 stop bits */ /* For reference buf[4]=2 is 2 stop bits */ - if (cflag & CSTOPB) { buf[4] = 2; + dbg(__FUNCTION__ " - stop bits = 2"); + } else { + buf[4] = 0; + dbg(__FUNCTION__ " - stop bits = 1"); } - if (cflag & PARENB) { /* For reference buf[5]=0 is none parity */ /* For reference buf[5]=1 is odd parity */ @@ -242,45 +274,52 @@ pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios) /* For reference buf[5]=4 is space parity */ if (cflag & PARODD) { buf[5] = 1; + dbg(__FUNCTION__ " - parity = odd"); } else { buf[5] = 2; + dbg(__FUNCTION__ " - parity = even"); } + } else { + buf[5] = 0; + dbg(__FUNCTION__ " - parity = none"); } i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), - 0x20, 0x21, 0, 0, buf, 7, 100); - + SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE, + 0, 0, buf, 7, 100); dbg ("0x21:0x20:0:0 %d", i); i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), - 0x22, 0x21, 1, 0, NULL, 0, 100); - + SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE, + 1, 0, NULL, 0, 100); dbg ("0x21:0x22:1:0 %d", i); - +#if 0 i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), - 0x22, 0x21, 3, 0, NULL, 0, 100); + SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE, + 1, 0, NULL, 0, 100); + dbg ("0x21:0x22:1:0 %d", i); + i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), + SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE, + 3, 0, NULL, 0, 100); dbg ("0x21:0x22:3:0 %d", i); - +#endif buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0; i = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0), - 0x21, 0xa1, 0, 0, buf, 7, 100); - + GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE, + 0, 0, buf, 7, 100); dbg ("0xa1:0x21:0:0 %d - %x %x %x %x %x %x %x", i, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); if (cflag & CRTSCTS) { - i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), - 0x01, 0x40, 0x0, 0x41, NULL, 0, 100); - + VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST_TYPE, + 0x0, 0x41, NULL, 0, 100); dbg ("0x40:0x1:0x0:0x41 %d", i); - } - - return; + kfree (buf); } @@ -294,7 +333,7 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp) if (port_paranoia_check (port, __FUNCTION__)) return -ENODEV; - dbg (__FUNCTION__ "- port %d", port->number); + dbg (__FUNCTION__ " - port %d", port->number); down (&port->sem); @@ -311,20 +350,20 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp) #define SOUP(a,b,c,d) \ result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), \ - b, a, c , d, NULL, 0, 100); \ + b, a, c, d, NULL, 0, 100); \ dbg("0x%x:0x%x:0x%x:0x%x %d",a,b,c,d,result); - FISH (0xc0, 1, 0x8484, 0); - SOUP (0x40, 1, 0x0404, 0); - FISH (0xc0, 1, 0x8484, 0); - FISH (0xc0, 1, 0x8383, 0); - FISH (0xc0, 1, 0x8484, 0); - SOUP (0x40, 1, 0x0404, 1); - FISH (0xc0, 1, 0x8484, 0); - FISH (0xc0, 1, 0x8383, 0); - SOUP (0x40, 1, 0, 1); - SOUP (0x40, 1, 1, 0xc0); - SOUP (0x40, 1, 2, 4); + FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 0); + FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); + FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); + FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1); + FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); + FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1); + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0xc0); + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 4); /* Setup termios */ *(port->tty->termios) = tty_std_termios; @@ -334,6 +373,7 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp) //FIXME: need to assert RTS and DTR if CRTSCTS off + dbg (__FUNCTION__ " - submitting read urb"); port->read_urb->dev = serial->dev; result = usb_submit_urb (port->read_urb); if (result) { @@ -343,6 +383,7 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp) return -EPROTO; } + dbg (__FUNCTION__ " - submitting interrupt urb"); port->interrupt_in_urb->dev = serial->dev; result = usb_submit_urb (port->interrupt_in_urb); if (result) { @@ -360,6 +401,7 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp) static void pl2303_close (struct usb_serial_port *port, struct file *filp) { unsigned int c_cflag; + int result; if (port_paranoia_check (port, __FUNCTION__)) return; @@ -377,28 +419,30 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp) } /* shutdown our urbs */ - usb_unlink_urb (port->write_urb); - usb_unlink_urb (port->read_urb); - usb_unlink_urb (port->interrupt_in_urb); + dbg (__FUNCTION__ " - shutting down urbs"); + result = usb_unlink_urb (port->write_urb); + if (result) + dbg (__FUNCTION__ " - usb_unlink_urb (write_urb) failed with reason: %d", result); + + result = usb_unlink_urb (port->read_urb); + if (result) + dbg (__FUNCTION__ " - usb_unlink_urb (read_urb) failed with reason: %d", result); + + result = usb_unlink_urb (port->interrupt_in_urb); + if (result) + dbg (__FUNCTION__ " - usb_unlink_urb (interrupt_in_urb) failed with reason: %d", result); port->active = 0; port->open_count = 0; } up (&port->sem); + MOD_DEC_USE_COUNT; } -static int -pl2303_ioctl (struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg) +static int pl2303_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg) { -// struct usb_serial *serial = port->serial; -// __u16 urb_value=0; /* Will hold the new flags */ -// char buf[1]; -// int ret, mask; - - dbg ("pl2303_sio ioctl 0x%04x", cmd); /* Based on code from acm.c and others */ @@ -423,23 +467,50 @@ pl2303_ioctl (struct usb_serial_port *port, struct file *file, return(-ENOIOCTLCMD); break; } - dbg ("pl2303_ioctl returning 0"); return 0; -} /* pl2303_ioctl */ +} -static void pl2303_break_ctl(struct usb_serial_port *port,int break_state) +static void pl2303_break_ctl (struct usb_serial_port *port, int break_state) { -//FIXME + struct usb_serial *serial = port->serial; + u16 state; + int result; + + dbg (__FUNCTION__ " - port %d", port->number); + + if (break_state == 0) + state = BREAK_OFF; + else + state = BREAK_ON; + dbg (__FUNCTION__" - turning break %s", state==BREAK_OFF ? "off" : "on"); + + result = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0), + BREAK_REQUEST, BREAK_REQUEST_TYPE, state, + 0, NULL, 0, 100); + if (result) + dbg (__FUNCTION__" - error sending break = %d", result); } -static void -pl2303_read_int_callback (struct urb *urb) +static void pl2303_shutdown (struct usb_serial *serial) +{ + int i; + + dbg (__FUNCTION__); + + /* stop everything on all ports */ + for (i = 0; i < serial->num_ports; ++i) + while (serial->port[i].open_count > 0) + pl2303_close (&serial->port[i], NULL); +} + + +static void pl2303_read_int_callback (struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; - struct usb_serial *serial = get_usb_serial (port, "pl2303_read_int_callback"); + struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); //unsigned char *data = urb->transfer_buffer; //int i; @@ -482,13 +553,23 @@ static void pl2303_read_bulk_callback (struct urb *urb) return; } - /* PL2303 mysteriously fails with -EPROTO reschedule the read */ if (urb->status) { - urb->status = 0; - urb->dev = serial->dev; - result = usb_submit_urb(urb); - if (result) - err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); + dbg (__FUNCTION__ " - urb->status = %d", urb->status); + if (!port->active) { + dbg (__FUNCTION__ " - port is closed, exiting."); + return; + } + if (urb->status == -EPROTO) { + /* PL2303 mysteriously fails with -EPROTO reschedule the read */ + dbg (__FUNCTION__ " - caught -EPROTO, resubmitting the urb"); + urb->status = 0; + urb->dev = serial->dev; + result = usb_submit_urb(urb); + if (result) + err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); + return; + } + dbg (__FUNCTION__ " - unable to handle the error, exiting."); return; } @@ -505,11 +586,13 @@ static void pl2303_read_bulk_callback (struct urb *urb) tty_flip_buffer_push (tty); } - /* Schedule the next read*/ - urb->dev = serial->dev; - result = usb_submit_urb(urb); - if (result) - err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); + /* Schedule the next read _if_ we are still open */ + if (port->active) { + urb->dev = serial->dev; + result = usb_submit_urb(urb); + if (result) + err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); + } return; } diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c index fd727b37ba38..3d46afd72a67 100644 --- a/drivers/usb/serial/usbserial.c +++ b/drivers/usb/serial/usbserial.c @@ -307,7 +307,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.3" +#define DRIVER_VERSION "v1.4" #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux-usb/" #define DRIVER_DESC "USB Serial Driver core" @@ -343,6 +343,13 @@ static struct usb_serial_device_type generic_device = { num_ports: 1, shutdown: generic_shutdown, }; + +#define if_generic_do(x) \ + if ((serial->dev->descriptor.idVendor == vendor) && \ + (serial->dev->descriptor.idProduct == product)) \ + x +#else +#define if_generic_do(x) #endif @@ -505,8 +512,6 @@ static int serial_open (struct tty_struct *tty, struct file * filp) return -ENODEV; } - MOD_INC_USE_COUNT; - /* set up our port structure making the tty driver remember our port object, and us it */ portNumber = MINOR(tty->device) - serial->minor; port = &serial->port[portNumber]; @@ -544,8 +549,6 @@ static void serial_close(struct tty_struct *tty, struct file * filp) } else { generic_close(port, filp); } - - MOD_DEC_USE_COUNT; } @@ -768,7 +771,8 @@ static int generic_open (struct usb_serial_port *port, struct file *filp) if (port_paranoia_check (port, __FUNCTION__)) return -ENODEV; - MOD_INC_USE_COUNT; + /* only increment our usage count, if this device is _really_ a generic device */ + if_generic_do(MOD_INC_USE_COUNT); dbg(__FUNCTION__ " - port %d", port->number); @@ -828,7 +832,9 @@ static void generic_close (struct usb_serial_port *port, struct file * filp) } up (&port->sem); - MOD_DEC_USE_COUNT; + + /* only decrement our usage count, if this device is _really_ a generic device */ + if_generic_do(MOD_DEC_USE_COUNT); } diff --git a/drivers/usb/serial/xircom_pgs_fw.h b/drivers/usb/serial/xircom_pgs_fw.h index 3caeb7d8b412..423d2caa170b 100644 --- a/drivers/usb/serial/xircom_pgs_fw.h +++ b/drivers/usb/serial/xircom_pgs_fw.h @@ -2,7 +2,7 @@ * USB Xircom PGS Firmware * * Copyright (c) 1999, 2000 Brian Warner <warner@lothar.com> - * Copyright (c) 2001 Cristian M. Craciunescu + * Copyright (c) 2001 Cristian M. Craciunescu <cristi@dnt.ro> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index babac970c19e..4777aef7a688 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -1,5 +1,5 @@ /* - * USB Skeleton driver - 0.4 + * USB Skeleton driver - 0.5 * * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) * @@ -22,6 +22,7 @@ * * History: * + * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux * 2001_08_21 - 0.4 - more small bug fixes. * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people @@ -598,6 +599,9 @@ static void skel_disconnect(struct usb_device *udev, void *ptr) minor = dev->minor; + /* remove our devfs node */ + devfs_unregister(dev->devfs); + /* if the device is not opened, then we clean up right now */ if (!dev->open_count) { skel_delete (dev); @@ -606,9 +610,6 @@ static void skel_disconnect(struct usb_device *udev, void *ptr) up (&dev->sem); } - /* remove our devfs node */ - devfs_unregister(dev->devfs); - info("USB Skeleton #%d now disconnected", minor); up (&minor_table_mutex); } diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index 684260fef844..b637a66dc5c9 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -2397,6 +2397,7 @@ EXPORT_SYMBOL(usb_clear_halt); EXPORT_SYMBOL(usb_set_interface); EXPORT_SYMBOL(usb_get_configuration); EXPORT_SYMBOL(usb_set_configuration); +EXPORT_SYMBOL(usb_get_status); EXPORT_SYMBOL(usb_get_current_frame_number); diff --git a/drivers/usb/usbvideo.c b/drivers/usb/usbvideo.c index bed9911b6396..3c09474b476c 100644 --- a/drivers/usb/usbvideo.c +++ b/drivers/usb/usbvideo.c @@ -1181,7 +1181,7 @@ int usbvideo_RegisterVideoDevice(uvd_t *uvd) assert(uvd->handle != NULL); if (uvd->handle->uses_procfs) { if (uvd->debug > 0) { - info("%s: Creating /proc/%s/ filesystem entries.", + info("%s: Creating /proc/video/%s/ filesystem entries.", proc, uvd->handle->drvName); } usbvideo_procfs_level2_create(uvd); @@ -2472,3 +2472,4 @@ static int usbvideo_default_procfs_write_proc( } #endif /* USES_PROC_FS */ +MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbgen.c b/drivers/video/fbgen.c index 2b4aab636ab5..20556a073a30 100644 --- a/drivers/video/fbgen.c +++ b/drivers/video/fbgen.c @@ -440,3 +440,4 @@ void fbgen_blank(int blank, struct fb_info *info) } else fbgen_install_cmap(currcon, info2); } +MODULE_LICENSE("GPL"); diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c index b92ce4055918..27ee97cc7740 100644 --- a/drivers/video/matrox/i2c-matroxfb.c +++ b/drivers/video/matrox/i2c-matroxfb.c @@ -349,3 +349,4 @@ MODULE_DESCRIPTION("Support module providing I2C buses present on Matrox videoca module_init(i2c_matroxfb_init); module_exit(i2c_matroxfb_exit); /* no __setup required */ +MODULE_LICENSE("GPL"); diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c index a724411ec009..c8578f7efac0 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.c +++ b/drivers/video/matrox/matroxfb_DAC1064.c @@ -4,7 +4,7 @@ * * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz> * - * Version: 1.53 2001/06/18 + * Version: 1.54 2001/09/09 * * See matroxfb_base.c for contributors. * @@ -319,7 +319,7 @@ void DAC1064_global_restore(CPMINFO const struct matrox_hw_state* hw) { outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]); if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) { outDAC1064(PMINFO 0x20, 0x04); - outDAC1064(PMINFO 0x1F, 0x00); + outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type)); if (ACCESS_FBINFO(devflags.g450dac)) { outDAC1064(PMINFO M1064_X8B, 0xCC); /* only matrox know... */ outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]); @@ -851,6 +851,11 @@ static void MGAG100_reset(WPMINFO struct matrox_hw_state* hw){ } } DAC1064_setmclk(PMINFO hw, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333); + if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) { + if (ACCESS_FBINFO(devflags.dfp_type) == -1) { + ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F); + } + } if (ACCESS_FBINFO(devflags.noinit)) return; MGAG100_setPixClock(PMINFO 4, 25175); @@ -929,3 +934,4 @@ EXPORT_SYMBOL(matrox_G100); EXPORT_SYMBOL(DAC1064_global_init); EXPORT_SYMBOL(DAC1064_global_restore); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c index b5172699ddf5..16f1e7653a82 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.c +++ b/drivers/video/matrox/matroxfb_Ti3026.c @@ -863,3 +863,4 @@ struct matrox_switch matrox_millennium = { }; EXPORT_SYMBOL(matrox_millennium); #endif +MODULE_LICENSE("GPL"); diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c index 8af7d5c33886..56f128200227 100644 --- a/drivers/video/matrox/matroxfb_accel.c +++ b/drivers/video/matrox/matroxfb_accel.c @@ -1237,3 +1237,4 @@ void matrox_init_putc(WPMINFO struct display* p, void (*dac_createcursor)(WPMINF ACCESS_FBINFO(curr.putcs) = matrox_cfbX_putcs; } } +MODULE_LICENSE("GPL"); diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index b2823794b38a..feb79a4caea0 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -4,7 +4,7 @@ * * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz> * - * Version: 1.53 2001/06/18 + * Version: 1.54 2001/09/09 * * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org> * @@ -1326,6 +1326,7 @@ static unsigned int fv; /* "matrox:fv:xxxxx" */ static unsigned int fh; /* "matrox:fh:xxxxxk" */ static unsigned int maxclk; /* "matrox:maxclk:xxxxM" */ static int dfp; /* "matrox:dfp */ +static int dfp_type = -1; /* "matrox:dfp:xxx */ static int memtype = -1; /* "matrox:memtype:xxx" */ static char fontname[64]; /* "matrox:font:xxxxx" */ @@ -1640,6 +1641,7 @@ static int initMatrox2(WPMINFO struct display* d, struct board* b){ if (dfp) ACCESS_FBINFO(output.ph) |= MATROXFB_OUTPUT_CONN_DFP; } + ACCESS_FBINFO(devflags.dfp_type) = dfp_type; ACCESS_FBINFO(devflags.g450dac) = b->flags & DEVF_G450DAC; ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode); ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode); @@ -2155,6 +2157,7 @@ static struct pci_device_id matroxfb_devices[] __devinitdata = { MODULE_DEVICE_TABLE(pci, matroxfb_devices); + static struct pci_driver matroxfb_driver = { name: "matroxfb", id_table: matroxfb_devices, @@ -2405,6 +2408,10 @@ int __init matroxfb_setup(char *options) { mem = simple_strtoul(this_opt+4, NULL, 0); else if (!strncmp(this_opt, "mode:", 5)) strncpy(videomode, this_opt+5, sizeof(videomode)-1); + else if (!strncmp(this_opt, "dfp:", 4)) { + dfp_type = simple_strtoul(this_opt+4, NULL, 0); + dfp = 1; + } #ifdef CONFIG_PPC else if (!strncmp(this_opt, "vmode:", 6)) { unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0); @@ -2510,6 +2517,8 @@ int __init matroxfb_init(void) MODULE_AUTHOR("(c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>"); MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450"); +MODULE_LICENSE("GPL"); + MODULE_PARM(mem, "i"); MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)"); MODULE_PARM(disabled, "i"); @@ -2586,6 +2595,8 @@ MODULE_PARM(cross4MB, "i"); MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)"); MODULE_PARM(dfp, "i"); MODULE_PARM_DESC(dfp, "Specifies whether to use digital flat panel interface of G200/G400 (0 or 1) (default=0)"); +MODULE_PARM(dfp_type, "i"); +MODULE_PARM_DESC(dfp_type, "Specifies DFP interface type (0 to 255) (default=read from hardware)"); #ifdef CONFIG_PPC MODULE_PARM(vmode, "i"); MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)"); diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index cd93ad2bcb7b..b402d17fb09c 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -1,8 +1,8 @@ /* * - * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400 + * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450 * - * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz> + * (c) 1998,1999,2000,2001 Petr Vandrovec <vandrove@vc.cvut.cz> * */ #ifndef __MATROXFB_H__ @@ -533,6 +533,7 @@ struct matrox_fb_info { /* 0 except for 6MB Millenium */ int memtype; int g450dac; + int dfp_type; } devflags; struct display_switch dispsw; struct { diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c index ff9d6fb751c1..8669fb7fcf9c 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/matrox/matroxfb_misc.c @@ -4,7 +4,7 @@ * * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz> * - * Version: 1.50 2000/08/10 + * Version: 1.54 2001/09/09 * * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org> * @@ -63,6 +63,9 @@ * "Mark Vojkovich" <mvojkovi@ucsd.edu> * G400 support * + * "David C. Hansen" <haveblue@us.ibm.com> + * Fixes + * * (following author is not in any relation with this code, but his code * is included in this driver) * @@ -654,7 +657,3 @@ EXPORT_SYMBOL(matroxfb_fastfont_tryset); /* accel */ EXPORT_SYMBOL(matroxfb_fastfont_init); /* DAC1064, Ti3026 */ EXPORT_SYMBOL(matroxfb_vgaHWinit); /* DAC1064, Ti3026 */ EXPORT_SYMBOL(matroxfb_vgaHWrestore); /* DAC1064, Ti3026 */ -#ifdef MATROXFB_USE_SPINLOCK -spinlock_t matroxfb_spinlock = SPIN_LOCK_UNLOCKED; -EXPORT_SYMBOL(matroxfb_spinlock); -#endif diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index c6852569c32f..cebcfabb887d 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -1111,6 +1111,7 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var) #ifdef FBCON_HAS_CFB16 case 15: rc = 15; /* fix for 15 bpp depths on Riva 128 based cards */ + break; case 16: rc = 16; /* directcolor... 16 entries SW palette */ break; /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */ @@ -2131,3 +2132,4 @@ MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)"); MODULE_AUTHOR("Ani Joshi, maintainer"); MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c index a69f35203dff..9ed344b43779 100644 --- a/drivers/video/sun3fb.c +++ b/drivers/video/sun3fb.c @@ -521,7 +521,7 @@ void sun3fb_palette(int enter) /* * Initialisation */ -static void __init sun3fb_init_fb(int fbtype, unsigned long addr) +static int __init sun3fb_init_fb(int fbtype, unsigned long addr) { static struct linux_sbus_device sdb; struct fb_fix_screeninfo *fix; @@ -587,8 +587,8 @@ sizechange: fb->cursor.hwsize.fby = 32; if (depth > 1 && !fb->color_map) { - fb->color_map = kmalloc(256 * 3, GFP_ATOMIC); - return -ENOMEM; + if((fb->color_map = kmalloc(256 * 3, GFP_ATOMIC))==NULL) + return -ENOMEM; } switch(fbtype) { @@ -605,7 +605,7 @@ sizechange: if (!p) { kfree(fb); - -ENODEV; + return -ENODEV; } if (p == SBUSFBINIT_SIZECHANGE) diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index a413a3bdc8cc..8b0399dbf18a 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c @@ -2069,6 +2069,8 @@ static void __exit tdfxfb_exit(void) MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>"); MODULE_DESCRIPTION("3Dfx framebuffer device driver"); +MODULE_LICENSE("GPL"); + #ifdef MODULE module_init(tdfxfb_init); diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index c7b856010445..22d9bfd25049 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c @@ -17,6 +17,8 @@ #include <linux/locks.h> #include <linux/mm.h> #include <linux/smp_lock.h> +#include <linux/module.h> + #include "adfs.h" @@ -373,3 +375,4 @@ void adfs_write_inode(struct inode *inode, int unused) adfs_dir_update(sb, &obj); unlock_kernel(); } +MODULE_LICENSE("GPL"); diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 3863e93a8645..2104b91b9e81 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -29,6 +29,7 @@ #include <linux/smp_lock.h> #include <asm/system.h> #include <asm/uaccess.h> +#include <linux/module.h> extern struct inode_operations affs_symlink_inode_operations; extern struct timezone sys_tz; @@ -413,3 +414,4 @@ err: affs_unlock_link(inode); goto done; } +MODULE_LICENSE("GPL"); diff --git a/fs/autofs/init.c b/fs/autofs/init.c index 0aaa8134a867..0e7fff94f254 100644 --- a/fs/autofs/init.c +++ b/fs/autofs/init.c @@ -38,3 +38,4 @@ void autofs_say(const char *name, int len) printk(")\n"); } #endif +MODULE_LICENSE("GPL"); diff --git a/fs/autofs4/init.c b/fs/autofs4/init.c index dc63926ad463..dbb3e5385ded 100644 --- a/fs/autofs4/init.c +++ b/fs/autofs4/init.c @@ -28,3 +28,4 @@ static void __exit exit_autofs4_fs(void) module_init(init_autofs4_fs) module_exit(exit_autofs4_fs) +MODULE_LICENSE("GPL"); diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 8e33b4ab2a02..6a4a4c5487cf 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -19,6 +19,7 @@ MODULE_AUTHOR("Tigran A. Aivazian <tigran@veritas.com>"); MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux"); +MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; #undef DEBUG diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 5ec84c3bf847..befc354f7026 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -513,3 +513,4 @@ EXPORT_NO_SYMBOLS; module_init(init_aout_binfmt); module_exit(exit_aout_binfmt); +MODULE_LICENSE("GPL"); diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index abf73f3dd399..76b6c22490d7 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -31,6 +31,7 @@ #include <linux/init.h> #include <linux/highuid.h> #include <linux/smp_lock.h> +#include <linux/compiler.h> #include <asm/uaccess.h> #include <asm/param.h> @@ -408,7 +409,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) char * elf_interpreter = NULL; unsigned int interpreter_type = INTERPRETER_NONE; unsigned char ibcs2_interpreter = 0; - mm_segment_t old_fs; unsigned long error; struct elf_phdr * elf_ppnt, *elf_phdata; unsigned long elf_bss, k, elf_brk; @@ -609,8 +609,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) the image should be loaded at fixed address, not at a variable address. */ - old_fs = get_fs(); - set_fs(get_ds()); for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { int elf_prot = 0, elf_flags; unsigned long vaddr; @@ -618,6 +616,22 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) if (elf_ppnt->p_type != PT_LOAD) continue; + if (unlikely (elf_brk > elf_bss)) { + unsigned long nbyte; + + /* There was a PT_LOAD segment with p_memsz > p_filesz + before this one. Map anonymous pages, if needed, + and clear the area. */ + set_brk (elf_bss + load_bias, elf_brk + load_bias); + nbyte = ELF_PAGEOFFSET(elf_bss); + if (nbyte) { + nbyte = ELF_MIN_ALIGN - nbyte; + if (nbyte > elf_brk - elf_bss) + nbyte = elf_brk - elf_bss; + clear_user((void *) elf_bss + load_bias, nbyte); + } + } + if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ; if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; @@ -661,7 +675,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) if (k > elf_brk) elf_brk = k; } - set_fs(old_fs); elf_entry += load_bias; elf_bss += load_bias; diff --git a/fs/block_dev.c b/fs/block_dev.c index 937800df179a..8ce2918bf78d 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -345,7 +345,6 @@ struct block_device *bdget(dev_t dev) inode->i_rdev = kdev; inode->i_dev = kdev; inode->i_bdev = new_bdev; - inode->i_blkbits = blksize_bits(block_size(kdev)); inode->i_data.a_ops = &def_blk_aops; inode->i_data.gfp_mask = GFP_USER; spin_lock(&bdev_lock); diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 6d8ee9009301..9be6577fee73 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -250,3 +250,5 @@ static void __exit exit_devpts_fs(void) module_init(init_devpts_fs) module_exit(exit_devpts_fs) +MODULE_LICENSE("GPL"); + diff --git a/fs/efs/inode.c b/fs/efs/inode.c index ad0681bb5b87..39e503d3fbc8 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c @@ -9,6 +9,8 @@ #include <linux/efs_fs.h> #include <linux/efs_fs_sb.h> +#include <linux/module.h> + extern int efs_get_block(struct inode *, long, struct buffer_head *, int); static int efs_readpage(struct file *file, struct page *page) @@ -302,3 +304,4 @@ efs_block_t efs_map_block(struct inode *inode, efs_block_t block) { return 0; } +MODULE_LICENSE("GPL"); diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 167b7ee0b6c7..f092bfa9c295 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -8,6 +8,7 @@ #define __KERNEL_SYSCALLS__ +#include <linux/module.h> #include <linux/types.h> #include <linux/sched.h> #include <linux/nfs_fs.h> @@ -17,7 +18,7 @@ #include <linux/lockd/lockd.h> #include <linux/smp_lock.h> -#define NLMDBG_FACILITY NLMDBG_CIENT +#define NLMDBG_FACILITY NLMDBG_CLIENT /* * Local function prototypes @@ -131,29 +132,63 @@ nlmclnt_grant(struct nlm_lock *lock) */ /* + * Mark the locks for reclaiming. + * FIXME: In 2.5 we don't want to iterate through any global file_lock_list. + * Maintain NLM lock reclaiming lists in the nlm_host instead. + */ +static +void nlmclnt_mark_reclaim(struct nlm_host *host) +{ + struct file_lock *fl; + struct inode *inode; + struct list_head *tmp; + + list_for_each(tmp, &file_lock_list) { + fl = list_entry(tmp, struct file_lock, fl_link); + + inode = fl->fl_file->f_dentry->d_inode; + if (inode->i_sb->s_magic != NFS_SUPER_MAGIC) + continue; + if (fl->fl_u.nfs_fl.host != host) + continue; + if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED)) + continue; + fl->fl_u.nfs_fl.flags |= NFS_LCK_RECLAIM; + } +} + +/* + * Someone has sent us an SM_NOTIFY. Ensure we bind to the new port number, + * that we mark locks for reclaiming, and that we bump the pseudo NSM state. + */ +static inline +void nlmclnt_prepare_reclaim(struct nlm_host *host, u32 newstate) +{ + host->h_monitored = 0; + host->h_nsmstate = newstate; + host->h_state++; + host->h_nextrebind = 0; + nlm_rebind_host(host); + nlmclnt_mark_reclaim(host); + dprintk("NLM: reclaiming locks for host %s", host->h_name); +} + +/* * Reclaim all locks on server host. We do this by spawning a separate * reclaimer thread. - * FIXME: should bump MOD_USE_COUNT while reclaiming */ void nlmclnt_recovery(struct nlm_host *host, u32 newstate) { - if (!host->h_reclaiming++) { + if (host->h_reclaiming++) { if (host->h_nsmstate == newstate) return; - printk(KERN_WARNING - "lockd: Uh-oh! Interfering reclaims for host %s", - host->h_name); - host->h_monitored = 0; - host->h_nsmstate = newstate; - host->h_state++; - nlm_release_host(host); + nlmclnt_prepare_reclaim(host, newstate); } else { - host->h_monitored = 0; - host->h_nsmstate = newstate; - host->h_state++; + nlmclnt_prepare_reclaim(host, newstate); nlm_get_host(host); - kernel_thread(reclaimer, host, 0); + MOD_INC_USE_COUNT; + kernel_thread(reclaimer, host, CLONE_SIGNAL); } } @@ -163,32 +198,38 @@ reclaimer(void *ptr) struct nlm_host *host = (struct nlm_host *) ptr; struct nlm_wait *block; struct list_head *tmp; + struct file_lock *fl; + struct inode *inode; + daemonize(); reparent_to_init(); snprintf(current->comm, sizeof(current->comm), "%s-reclaim", host->h_name); - + /* This one ensures that our parent doesn't terminate while the * reclaim is in progress */ lock_kernel(); lockd_up(); - /* First, reclaim all locks that have been granted previously. */ + /* First, reclaim all locks that have been marked. */ restart: - tmp = file_lock_list.next; - while (tmp != &file_lock_list) { - struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link); - struct inode *inode = fl->fl_file->f_dentry->d_inode; - if (inode->i_sb->s_magic == NFS_SUPER_MAGIC && - nlm_cmp_addr(NFS_ADDR(inode), &host->h_addr) && - fl->fl_u.nfs_fl.state != host->h_state && - (fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED)) { - fl->fl_u.nfs_fl.flags &= ~ NFS_LCK_GRANTED; - nlmclnt_reclaim(host, fl); /* This sleeps */ - goto restart; - } - tmp = tmp->next; + list_for_each(tmp, &file_lock_list) { + fl = list_entry(tmp, struct file_lock, fl_link); + + inode = fl->fl_file->f_dentry->d_inode; + if (inode->i_sb->s_magic != NFS_SUPER_MAGIC) + continue; + if (fl->fl_u.nfs_fl.host != host) + continue; + if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_RECLAIM)) + continue; + + fl->fl_u.nfs_fl.flags &= ~NFS_LCK_RECLAIM; + nlmclnt_reclaim(host, fl); + if (signalled()) + break; + goto restart; } host->h_reclaiming = 0; @@ -206,6 +247,7 @@ restart: nlm_release_host(host); lockd_down(); unlock_kernel(); + MOD_DEC_USE_COUNT; return 0; } diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 02be5d927532..bf42dd94a6f8 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -51,7 +51,8 @@ nlmclnt_lookup_host(struct sockaddr_in *sin, int proto, int version) struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *rqstp) { - return nlm_lookup_host(rqstp->rq_client, &rqstp->rq_addr, 0, 0); + return nlm_lookup_host(rqstp->rq_client, &rqstp->rq_addr, + rqstp->rq_prot, rqstp->rq_vers); } /* @@ -97,7 +98,9 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin, nlm_gc_hosts(); for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) { - if (host->h_version != version || host->h_proto != proto) + if (proto && host->h_proto != proto) + continue; + if (version && host->h_version != version) continue; if (nlm_match_host(host, clnt, sin)) { @@ -325,7 +328,8 @@ nlm_gc_hosts(void) } dprintk("lockd: delete host %s\n", host->h_name); *q = host->h_next; - if (host->h_monitored) + /* Don't unmonitor hosts that have been invalidated */ + if (host->h_monitored && !host->h_killed) nsm_unmonitor(host); if ((clnt = host->h_rpcclnt) != NULL) { if (atomic_read(&clnt->cl_users)) { diff --git a/fs/lockd/lockd_syms.c b/fs/lockd/lockd_syms.c index b3990ed9893f..2de24bbfd29c 100644 --- a/fs/lockd/lockd_syms.c +++ b/fs/lockd/lockd_syms.c @@ -35,8 +35,4 @@ EXPORT_SYMBOL(nlmclnt_proc); EXPORT_SYMBOL(nlmsvc_invalidate_client); EXPORT_SYMBOL(nlmsvc_ops); -/* Configuration at insmod time */ -EXPORT_SYMBOL(nlmsvc_grace_period); -EXPORT_SYMBOL(nlmsvc_timeout); - #endif /* CONFIG_MODULES */ diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 10dce3addaf2..208c4950472e 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -43,7 +43,7 @@ nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res) args.addr = host->h_addr.sin_addr.s_addr; args.prog = NLM_PROGRAM; - args.vers = 1; + args.vers = host->h_version; args.proc = NLMPROC_NSM_NOTIFY; memset(res, 0, sizeof(*res)); diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 4eb1bcf3f6f0..d3339912a25d 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -43,7 +43,7 @@ struct nlmsvc_binding * nlmsvc_ops; static DECLARE_MUTEX(nlmsvc_sema); static unsigned int nlmsvc_users; static pid_t nlmsvc_pid; -unsigned long nlmsvc_grace_period; +int nlmsvc_grace_period; unsigned long nlmsvc_timeout; static DECLARE_MUTEX_LOCKED(lockd_start); @@ -56,6 +56,25 @@ static DECLARE_WAIT_QUEUE_HEAD(lockd_exit); unsigned long nlm_grace_period; unsigned long nlm_timeout = LOCKD_DFLT_TIMEO; +static unsigned long set_grace_period(void) +{ + unsigned long grace_period; + + /* Note: nlm_timeout should always be nonzero */ + if (nlm_grace_period) + grace_period = ((nlm_grace_period + nlm_timeout - 1) + / nlm_timeout) * nlm_timeout * HZ; + else + grace_period = nlm_timeout * 5 * HZ; + nlmsvc_grace_period = 1; + return grace_period + jiffies; +} + +static inline void clear_grace_period(void) +{ + nlmsvc_grace_period = 0; +} + /* * This is the lockd kernel thread */ @@ -84,7 +103,7 @@ lockd(struct svc_rqst *rqstp) spin_lock_irq(¤t->sigmask_lock); siginitsetinv(¤t->blocked, sigmask(SIGKILL)); recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sigmask_lock); /* kick rpciod */ rpciod_up(); @@ -93,21 +112,10 @@ lockd(struct svc_rqst *rqstp) if (!nlm_timeout) nlm_timeout = LOCKD_DFLT_TIMEO; - -#ifdef RPC_DEBUG - nlmsvc_grace_period = 10 * HZ; -#else - if (nlm_grace_period) { - nlmsvc_grace_period += (1 + nlm_grace_period / nlm_timeout) - * nlm_timeout * HZ; - } else { - nlmsvc_grace_period += 5 * nlm_timeout * HZ; - } -#endif - - grace_period_expire = nlmsvc_grace_period + jiffies; nlmsvc_timeout = nlm_timeout * HZ; + grace_period_expire = set_grace_period(); + /* * The main request loop. We don't terminate until the last * NFS mount or NFS daemon has gone away, and we've been sent a @@ -122,13 +130,7 @@ lockd(struct svc_rqst *rqstp) spin_unlock_irq(¤t->sigmask_lock); if (nlmsvc_ops) { nlmsvc_ops->detach(); -#ifdef RPC_DEBUG - nlmsvc_grace_period = 10 * HZ; -#else - nlmsvc_grace_period += 5 * nlm_timeout * HZ; - -#endif - grace_period_expire = nlmsvc_grace_period + jiffies; + grace_period_expire = set_grace_period(); } } @@ -140,16 +142,15 @@ lockd(struct svc_rqst *rqstp) */ if (!nlmsvc_grace_period) { timeout = nlmsvc_retry_blocked(); - } else if (time_before(nlmsvc_grace_period, jiffies)) - nlmsvc_grace_period = 0; + } else if (time_before(grace_period_expire, jiffies)) + clear_grace_period(); /* * Find a socket with data available and call its * recvfrom routine. */ - if ((err = svc_recv(serv, rqstp, timeout)) == -EAGAIN - || err == -EINTR - ) + err = svc_recv(serv, rqstp, timeout); + if (err == -EAGAIN || err == -EINTR) continue; if (err < 0) { printk(KERN_WARNING @@ -345,7 +346,7 @@ cleanup_module(void) * Define NLM program and procedures */ static struct svc_version nlmsvc_version1 = { - 1, 16, nlmsvc_procedures, NULL + 1, 17, nlmsvc_procedures, NULL }; static struct svc_version nlmsvc_version3 = { 3, 24, nlmsvc_procedures, NULL diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index bb72c629ed5b..28d8cbf1e063 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -420,6 +420,8 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, void *resp) { struct sockaddr_in saddr = rqstp->rq_addr; + int vers = rqstp->rq_vers; + int prot = rqstp->rq_prot; struct nlm_host *host; dprintk("lockd: SM_NOTIFY called\n"); @@ -435,8 +437,8 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, /* Obtain the host pointer for this NFS server and try to * reclaim all locks we hold on this server. */ - saddr.sin_addr.s_addr = argp->addr; - if ((host = nlm_lookup_host(NULL, &saddr, IPPROTO_UDP, 1)) != NULL) { + saddr.sin_addr.s_addr = argp->addr; + if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) { nlmclnt_recovery(host, argp->state); nlm_release_host(host); } @@ -444,7 +446,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, /* If we run on an NFS server, delete all locks held by the client */ if (nlmsvc_ops != NULL) { struct svc_client *clnt; - saddr.sin_addr.s_addr = argp->addr; + saddr.sin_addr.s_addr = argp->addr; if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) { nlmsvc_free_host_resources(host); @@ -549,7 +551,8 @@ struct svc_procedure nlmsvc_procedures4[] = { PROC(cancel_res, cancelres, norep, res, void), PROC(unlock_res, unlockres, norep, res, void), PROC(granted_res, grantedres, norep, res, void), - PROC(none, void, void, void, void), + /* statd callback */ + PROC(sm_notify, reboot, void, reboot, void), PROC(none, void, void, void, void), PROC(none, void, void, void, void), PROC(none, void, void, void, void), @@ -558,6 +561,4 @@ struct svc_procedure nlmsvc_procedures4[] = { PROC(nm_lock, lockargs, res, args, res), PROC(free_all, notify, void, args, void), - /* statd callback */ - PROC(sm_notify, reboot, void, reboot, void), }; diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 5002972ec0f6..6af031e95125 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -445,6 +445,8 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, void *resp) { struct sockaddr_in saddr = rqstp->rq_addr; + int vers = rqstp->rq_vers; + int prot = rqstp->rq_prot; struct nlm_host *host; dprintk("lockd: SM_NOTIFY called\n"); @@ -460,8 +462,8 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, /* Obtain the host pointer for this NFS server and try to * reclaim all locks we hold on this server. */ - saddr.sin_addr.s_addr = argp->addr; - if ((host = nlm_lookup_host(NULL, &saddr, IPPROTO_UDP, 1)) != NULL) { + saddr.sin_addr.s_addr = argp->addr; + if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) { nlmclnt_recovery(host, argp->state); nlm_release_host(host); } @@ -574,7 +576,8 @@ struct svc_procedure nlmsvc_procedures[] = { PROC(cancel_res, cancelres, norep, res, void), PROC(unlock_res, unlockres, norep, res, void), PROC(granted_res, grantedres, norep, res, void), - PROC(none, void, void, void, void), + /* statd callback */ + PROC(sm_notify, reboot, void, reboot, void), PROC(none, void, void, void, void), PROC(none, void, void, void, void), PROC(none, void, void, void, void), @@ -583,6 +586,4 @@ struct svc_procedure nlmsvc_procedures[] = { PROC(nm_lock, lockargs, res, args, res), PROC(free_all, notify, void, args, void), - /* statd callback */ - PROC(sm_notify, reboot, void, reboot, void), }; diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 9bcc192ee618..e7bcab77540c 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c @@ -305,6 +305,7 @@ nlmsvc_invalidate_client(struct svc_client *clnt) dprintk("lockd: invalidating client for %s\n", host->h_name); nlmsvc_free_host_resources(host); host->h_expires = 0; + host->h_killed = 1; nlm_release_host(host); } } diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index e1e917e396a8..08b3cec38134 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -367,7 +367,8 @@ nlmsvc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp) if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN))) return 0; argp->state = ntohl(*p++); - argp->addr = ntohl(*p++); + /* Preserve the address in network byte order */ + argp->addr = *p++; return xdr_argsize_check(rqstp, p); } diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index bb083aae309a..bdae6b80e01e 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c @@ -373,7 +373,8 @@ nlm4svc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp) if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN))) return 0; argp->state = ntohl(*p++); - argp->addr = ntohl(*p++); + /* Preserve the address in network byte order */ + argp->addr = *p++; return xdr_argsize_check(rqstp, p); } diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 7530c2955d40..05d7b93c65c7 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -529,3 +529,5 @@ EXPORT_NO_SYMBOLS; module_init(init_minix_fs) module_exit(exit_minix_fs) +MODULE_LICENSE("GPL"); + diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 1ddf41daabf9..37b4e581ecbf 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -730,3 +730,4 @@ EXPORT_NO_SYMBOLS; module_init(init_ncp_fs) module_exit(exit_ncp_fs) +MODULE_LICENSE("GPL"); diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 1742244077f5..9f4268a0d4b8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -312,6 +312,7 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent) if (data->flags & NFS_MOUNT_NOAC) { data->acregmin = data->acregmax = 0; data->acdirmin = data->acdirmax = 0; + sb->s_flags |= MS_SYNCHRONOUS; } server->acregmin = data->acregmin*HZ; server->acregmax = data->acregmax*HZ; diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 86cfd1b811ef..2c9987eba727 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -362,8 +362,8 @@ nfs3_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { struct nfs_fattr dir_attr; - struct nfs3_createargs arg = { NFS_FH(dir), name->name, name->len, - sattr, 0, { 0, 0 } }; + struct nfs3_mkdirargs arg = { NFS_FH(dir), name->name, name->len, + sattr }; struct nfs3_diropres res = { &dir_attr, fhandle, fattr }; int status; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 42f5f90677d9..8fe2b47874a8 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -288,7 +288,7 @@ nfs_writepage(struct page *page) goto out; do_it: lock_kernel(); - if (NFS_SERVER(inode)->rsize >= PAGE_CACHE_SIZE) { + if (NFS_SERVER(inode)->wsize >= PAGE_CACHE_SIZE && !IS_SYNC(inode)) { err = nfs_writepage_async(NULL, inode, page, 0, offset); if (err >= 0) err = 0; @@ -1031,7 +1031,7 @@ nfs_updatepage(struct file *file, struct page *page, unsigned int offset, unsign * If wsize is smaller than page size, update and write * page synchronously. */ - if (NFS_SERVER(inode)->wsize < PAGE_SIZE) + if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE || IS_SYNC(inode)) return nfs_writepage_sync(file, inode, page, offset, count); /* diff --git a/fs/nls/nls_cp1251.c b/fs/nls/nls_cp1251.c index ab794fd76d64..e51ada6fd2f8 100644 --- a/fs/nls/nls_cp1251.c +++ b/fs/nls/nls_cp1251.c @@ -315,3 +315,4 @@ module_exit(exit_nls_cp1251) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp1255.c b/fs/nls/nls_cp1255.c index cfe693c29f7a..cebbd9028735 100644 --- a/fs/nls/nls_cp1255.c +++ b/fs/nls/nls_cp1255.c @@ -396,3 +396,4 @@ module_exit(exit_nls_cp1255) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp437.c b/fs/nls/nls_cp437.c index e20e276073b1..a592fe8f1f08 100644 --- a/fs/nls/nls_cp437.c +++ b/fs/nls/nls_cp437.c @@ -401,3 +401,4 @@ module_exit(exit_nls_cp437) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp737.c b/fs/nls/nls_cp737.c index 2894e5c5656a..53c65bc9f292 100644 --- a/fs/nls/nls_cp737.c +++ b/fs/nls/nls_cp737.c @@ -364,3 +364,4 @@ module_exit(exit_nls_cp737) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp775.c b/fs/nls/nls_cp775.c index 4578c6ba11c4..f6f0686b8460 100644 --- a/fs/nls/nls_cp775.c +++ b/fs/nls/nls_cp775.c @@ -333,3 +333,4 @@ module_exit(exit_nls_cp775) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp850.c b/fs/nls/nls_cp850.c index b2bb68aab081..c38e89d61dec 100644 --- a/fs/nls/nls_cp850.c +++ b/fs/nls/nls_cp850.c @@ -329,3 +329,4 @@ module_exit(exit_nls_cp850) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp852.c b/fs/nls/nls_cp852.c index a4be6d26366c..82260bbe7ac0 100644 --- a/fs/nls/nls_cp852.c +++ b/fs/nls/nls_cp852.c @@ -351,3 +351,4 @@ module_exit(exit_nls_cp852) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp855.c b/fs/nls/nls_cp855.c index 778c99a0fa67..97f57690a62e 100644 --- a/fs/nls/nls_cp855.c +++ b/fs/nls/nls_cp855.c @@ -313,3 +313,4 @@ module_exit(exit_nls_cp855) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp857.c b/fs/nls/nls_cp857.c index 19d521025482..349ca72416b6 100644 --- a/fs/nls/nls_cp857.c +++ b/fs/nls/nls_cp857.c @@ -315,3 +315,4 @@ module_exit(exit_nls_cp857) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp860.c b/fs/nls/nls_cp860.c index eff20e40ccf4..23da03086ff8 100644 --- a/fs/nls/nls_cp860.c +++ b/fs/nls/nls_cp860.c @@ -378,3 +378,4 @@ module_exit(exit_nls_cp860) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp861.c b/fs/nls/nls_cp861.c index c6263740d065..fe03d1e97e8f 100644 --- a/fs/nls/nls_cp861.c +++ b/fs/nls/nls_cp861.c @@ -401,3 +401,4 @@ module_exit(exit_nls_cp861) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp862.c b/fs/nls/nls_cp862.c index f4c70e6fae0f..6c452204d409 100644 --- a/fs/nls/nls_cp862.c +++ b/fs/nls/nls_cp862.c @@ -435,3 +435,4 @@ module_exit(exit_nls_cp862) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp863.c b/fs/nls/nls_cp863.c index a443851ad9dd..51e62d1bb516 100644 --- a/fs/nls/nls_cp863.c +++ b/fs/nls/nls_cp863.c @@ -395,3 +395,4 @@ module_exit(exit_nls_cp863) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp864.c b/fs/nls/nls_cp864.c index b58e27c73a17..f4e6a804db42 100644 --- a/fs/nls/nls_cp864.c +++ b/fs/nls/nls_cp864.c @@ -421,3 +421,4 @@ module_exit(exit_nls_cp864) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp865.c b/fs/nls/nls_cp865.c index f115fb6fb526..63c004fc41ad 100644 --- a/fs/nls/nls_cp865.c +++ b/fs/nls/nls_cp865.c @@ -401,3 +401,4 @@ module_exit(exit_nls_cp865) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp866.c b/fs/nls/nls_cp866.c index 04f6636875d6..118a55e271af 100644 --- a/fs/nls/nls_cp866.c +++ b/fs/nls/nls_cp866.c @@ -319,3 +319,4 @@ module_exit(exit_nls_cp866) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp869.c b/fs/nls/nls_cp869.c index 082feaad37d8..d6535038317e 100644 --- a/fs/nls/nls_cp869.c +++ b/fs/nls/nls_cp869.c @@ -329,3 +329,4 @@ module_exit(exit_nls_cp869) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/nls/nls_cp874.c b/fs/nls/nls_cp874.c index ff01f91aa064..061d68cc8b5a 100644 --- a/fs/nls/nls_cp874.c +++ b/fs/nls/nls_cp874.c @@ -287,3 +287,4 @@ module_exit(exit_nls_cp874) * c-continued-brace-offset: 0 * End: */ +MODULE_LICENSE("BSD without advertising clause"); diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 010231e08608..6d00b601a179 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -177,6 +177,15 @@ char *disk_name (struct gendisk *hd, int minor, char *buf) sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part); return buf; } + if (hd->major == ATARAID_MAJOR) { + int disk = minor >> hd->minor_shift; + int part = minor & (( 1 << hd->minor_shift) - 1); + if (part == 0) + sprintf(buf, "%s/d%d", maj, disk); + else + sprintf(buf, "%s/d%dp%d", maj, disk, part); + return buf; + } if (part) sprintf(buf, "%s%c%d", maj, unit+'a', part); else diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 492546331f87..48734c6c75ef 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -209,3 +209,4 @@ out_no_root: iput(root_inode); return NULL; } +MODULE_LICENSE("GPL"); diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 107470d34be5..75ad8a8f5d03 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -511,3 +511,5 @@ EXPORT_NO_SYMBOLS; module_init(init_qnx4_fs) module_exit(exit_qnx4_fs) +MODULE_LICENSE("GPL"); + diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index c50502204331..40c6c7347fcb 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -4,6 +4,7 @@ * Copyright (C) 2000 Linus Torvalds. * 2000 Transmeta Corp. * + * Usage limits added by David Gibson, Linuxcare Australia. * This file is released under the GPL. */ @@ -348,3 +349,5 @@ static void __exit exit_ramfs_fs(void) module_init(init_ramfs_fs) module_exit(exit_ramfs_fs) +MODULE_LICENSE("GPL"); + diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index 4d90804e6017..477d2eb6872b 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c @@ -548,3 +548,4 @@ EXPORT_NO_SYMBOLS; module_init(init_romfs_fs) module_exit(exit_romfs_fs) +MODULE_LICENSE("GPL"); diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 9bb9b690478a..348e5acad771 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -653,3 +653,4 @@ EXPORT_NO_SYMBOLS; module_init(init_smb_fs) module_exit(exit_smb_fs) +MODULE_LICENSE("GPL"); diff --git a/fs/sysv/super.c b/fs/sysv/super.c index 66e46552d48b..efbd2294b0c7 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c @@ -502,3 +502,4 @@ EXPORT_NO_SYMBOLS; module_init(init_sysv_fs) module_exit(exit_sysv_fs) +MODULE_LICENSE("GPL"); diff --git a/fs/umsdos/inode.c b/fs/umsdos/inode.c index f3ccd379ba28..98009bff861f 100644 --- a/fs/umsdos/inode.c +++ b/fs/umsdos/inode.c @@ -475,3 +475,4 @@ EXPORT_NO_SYMBOLS; module_init(init_umsdos_fs) module_exit(exit_umsdos_fs) +MODULE_LICENSE("GPL"); diff --git a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h index 49c848738f87..42f32426eac5 100644 --- a/include/asm-i386/highmem.h +++ b/include/asm-i386/highmem.h @@ -26,8 +26,11 @@ #include <asm/kmap_types.h> #include <asm/pgtable.h> -/* undef for production */ +#ifdef CONFIG_DEBUG_HIGHMEM #define HIGHMEM_DEBUG 1 +#else +#define HIGHMEM_DEBUG 0 +#endif /* declarations for highmem.c */ extern unsigned long highstart_pfn, highend_pfn; diff --git a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h index 69f1eb9a9b96..b132819e0871 100644 --- a/include/asm-i386/io_apic.h +++ b/include/asm-i386/io_apic.h @@ -28,7 +28,8 @@ struct IO_APIC_reg_00 { struct IO_APIC_reg_01 { __u32 version : 8, - __reserved_2 : 8, + __reserved_2 : 7, + PRQ : 1, entries : 8, __reserved_1 : 8; } __attribute__ ((packed)); diff --git a/include/asm-ia64/module.h b/include/asm-ia64/module.h index 10c1e866db25..52f500a875a8 100644 --- a/include/asm-ia64/module.h +++ b/include/asm-ia64/module.h @@ -14,7 +14,13 @@ #define module_map(x) vmalloc(x) #define module_unmap(x) ia64_module_unmap(x) #define module_arch_init(x) ia64_module_init(x) -#define arch_init_modules(x) do { } while (0) +#define arch_init_modules(x) { static struct archdata archdata; \ + register char *kernel_gp asm ("gp");\ + archdata.gp = kernel_gp; \ + kernel_module.archdata_start = (const char *) &archdata; \ + kernel_module.archdata_end = (const char *) (&archdata + 1); \ + } + /* * This must match in size and layout the data created by diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h index 1587f92f968a..96cdb786590f 100644 --- a/include/asm-sparc/uaccess.h +++ b/include/asm-sparc/uaccess.h @@ -1,4 +1,4 @@ -/* $Id: uaccess.h,v 1.22 2000/08/29 07:01:58 davem Exp $ +/* $Id: uaccess.h,v 1.23 2001/09/24 03:51:39 davem Exp $ * uaccess.h: User space memore access functions. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -116,6 +116,7 @@ switch (size) { \ case 1: __put_user_asm(x,b,addr,__pu_ret); break; \ case 2: __put_user_asm(x,h,addr,__pu_ret); break; \ case 4: __put_user_asm(x,,addr,__pu_ret); break; \ +case 8: __put_user_asm(x,d,addr,__pu_ret); break; \ default: __pu_ret = __put_user_bad(); break; \ } } else { __pu_ret = -EFAULT; } __pu_ret; }) @@ -126,6 +127,7 @@ switch (size) { \ case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \ case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \ case 4: __put_user_asm_ret(x,,addr,retval,__foo); break; \ +case 8: __put_user_asm_ret(x,d,addr,retval,__foo); break; \ default: if (__put_user_bad()) return retval; break; \ } } else return retval; }) @@ -135,6 +137,7 @@ switch (size) { \ case 1: __put_user_asm(x,b,addr,__pu_ret); break; \ case 2: __put_user_asm(x,h,addr,__pu_ret); break; \ case 4: __put_user_asm(x,,addr,__pu_ret); break; \ +case 8: __put_user_asm(x,d,addr,__pu_ret); break; \ default: __pu_ret = __put_user_bad(); break; \ } __pu_ret; }) @@ -144,6 +147,7 @@ switch (size) { \ case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \ case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \ case 4: __put_user_asm_ret(x,,addr,retval,__foo); break; \ +case 8: __put_user_asm_ret(x,d,addr,retval,__foo); break; \ default: if (__put_user_bad()) return retval; break; \ } }) @@ -202,6 +206,7 @@ switch (size) { \ case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \ case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \ case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \ +case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \ default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \ } } else { __gu_val = 0; __gu_ret = -EFAULT; } x = (type) __gu_val; __gu_ret; }) @@ -212,6 +217,7 @@ switch (size) { \ case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \ case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \ case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \ +case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \ default: if (__get_user_bad()) return retval; \ } x = (type) __gu_val; } else return retval; }) @@ -222,6 +228,7 @@ switch (size) { \ case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \ case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \ case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \ +case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \ default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \ } x = (type) __gu_val; __gu_ret; }) @@ -231,6 +238,7 @@ switch (size) { \ case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \ case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \ case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \ +case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \ default: if (__get_user_bad()) return retval; \ } x = (type) __gu_val; }) diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h index 4f621f2cb463..cddeb3274448 100644 --- a/include/asm-sparc64/ide.h +++ b/include/asm-sparc64/ide.h @@ -1,4 +1,4 @@ -/* $Id: ide.h,v 1.19 2000/05/27 00:49:37 davem Exp $ +/* $Id: ide.h,v 1.21 2001/09/25 20:21:48 kanoj Exp $ * ide.h: Ultra/PCI specific IDE glue. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -14,6 +14,8 @@ #include <asm/pgalloc.h> #include <asm/io.h> #include <asm/hdreg.h> +#include <asm/page.h> +#include <asm/spitfire.h> #undef MAX_HWIFS #define MAX_HWIFS 2 @@ -151,7 +153,9 @@ static __inline__ void ide_insw(unsigned long port, void *dst, unsigned long count) { +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ unsigned long end = (unsigned long)dst + (count << 1); +#endif u16 *ps = dst; u32 *pi; @@ -172,7 +176,9 @@ static __inline__ void ide_insw(unsigned long port, if(count) *ps++ = inw_be(port); +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ __flush_dcache_range((unsigned long)dst, end); +#endif } static __inline__ void outw_be(unsigned short w, unsigned long addr) @@ -186,7 +192,9 @@ static __inline__ void ide_outsw(unsigned long port, const void *src, unsigned long count) { +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ unsigned long end = (unsigned long)src + (count << 1); +#endif const u16 *ps = src; const u32 *pi; @@ -207,7 +215,9 @@ static __inline__ void ide_outsw(unsigned long port, if(count) outw_be(*ps, port); +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ __flush_dcache_range((unsigned long)src, end); +#endif } #define T_CHAR (0x0000) /* char: don't touch */ diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index fa0dfb673c09..feba6c1a05d4 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h @@ -1,4 +1,4 @@ -/* $Id: pgalloc.h,v 1.21 2001/08/22 22:16:56 kanoj Exp $ */ +/* $Id: pgalloc.h,v 1.23 2001/09/25 20:21:48 kanoj Exp $ */ #ifndef _SPARC64_PGALLOC_H #define _SPARC64_PGALLOC_H @@ -7,6 +7,8 @@ #include <linux/sched.h> #include <asm/page.h> +#include <asm/spitfire.h> +#include <asm/pgtable.h> /* Cache and TLB flush operations. */ @@ -29,6 +31,8 @@ extern void flush_icache_range(unsigned long start, unsigned long end); extern void __flush_dcache_page(void *addr, int flush_icache); +extern void __flush_icache_page(unsigned long); +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ #define flush_dcache_page(page) \ do { if ((page)->mapping && \ !((page)->mapping->i_mmap) && \ @@ -39,6 +43,18 @@ do { if ((page)->mapping && \ ((tlb_type == spitfire) && \ (page)->mapping != NULL)); \ } while(0) +#else /* L1DCACHE_SIZE > PAGE_SIZE */ +#define flush_dcache_page(page) \ +do { if ((page)->mapping && \ + !((page)->mapping->i_mmap) && \ + !((page)->mapping->i_mmap_shared)) \ + set_bit(PG_dcache_dirty, &(page)->flags); \ + else \ + if ((tlb_type == spitfire) && \ + (page)->mapping != NULL) \ + __flush_icache_page(__get_phys((unsigned long)((page)->virtual))); \ +} while(0) +#endif /* L1DCACHE_SIZE > PAGE_SIZE */ extern void __flush_dcache_range(unsigned long start, unsigned long end); @@ -227,6 +243,14 @@ extern __inline__ void free_pgd_slow(pgd_t *pgd) #endif /* CONFIG_SMP */ +#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ +#define VPTE_COLOR(address) (((address) >> (PAGE_SHIFT + 10)) & 1UL) +#define DCACHE_COLOR(address) (((address) >> PAGE_SHIFT) & 1UL) +#else +#define VPTE_COLOR(address) 0 +#define DCACHE_COLOR(address) 0 +#endif + #define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) extern __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) @@ -254,9 +278,7 @@ extern __inline__ pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long extern __inline__ void free_pmd_fast(pmd_t *pmd) { - unsigned long color; - - color = (((unsigned long)pmd >> PAGE_SHIFT) & 0x1UL); + unsigned long color = DCACHE_COLOR((unsigned long)pmd); *(unsigned long *)pmd = (unsigned long) pte_quicklist[color]; pte_quicklist[color] = (unsigned long *) pmd; pgtable_cache_size++; @@ -273,7 +295,7 @@ extern pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address); extern __inline__ pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) { - unsigned long color = (address >> (PAGE_SHIFT + 10)) & 0x1UL; + unsigned long color = VPTE_COLOR(address); unsigned long *ret; if((ret = (unsigned long *)pte_quicklist[color]) != NULL) { @@ -286,7 +308,7 @@ extern __inline__ pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long extern __inline__ void free_pte_fast(pte_t *pte) { - unsigned long color = (((unsigned long)pte >> PAGE_SHIFT) & 0x1); + unsigned long color = DCACHE_COLOR((unsigned long)pte); *(unsigned long *)pte = (unsigned long) pte_quicklist[color]; pte_quicklist[color] = (unsigned long *) pte; pgtable_cache_size++; diff --git a/include/asm-sparc64/shmparam.h b/include/asm-sparc64/shmparam.h index 03ace40fd0bb..97c667e7c0e4 100644 --- a/include/asm-sparc64/shmparam.h +++ b/include/asm-sparc64/shmparam.h @@ -1,7 +1,10 @@ -/* $Id: shmparam.h,v 1.4 1999/12/09 10:32:44 davem Exp $ */ +/* $Id: shmparam.h,v 1.5 2001/09/24 21:17:57 kanoj Exp $ */ #ifndef _ASMSPARC64_SHMPARAM_H #define _ASMSPARC64_SHMPARAM_H -#define SHMLBA (PAGE_SIZE<<1) /* attach addr a multiple of this */ +#include <asm/spitfire.h> + +/* attach addr a multiple of this */ +#define SHMLBA ((PAGE_SIZE > L1DCACHE_SIZE) ? PAGE_SIZE : L1DCACHE_SIZE) #endif /* _ASMSPARC64_SHMPARAM_H */ diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h index 4554806dac66..26a67f822452 100644 --- a/include/asm-sparc64/spitfire.h +++ b/include/asm-sparc64/spitfire.h @@ -1,4 +1,4 @@ -/* $Id: spitfire.h,v 1.15 2001/03/27 00:10:15 davem Exp $ +/* $Id: spitfire.h,v 1.16 2001/09/24 21:17:57 kanoj Exp $ * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -46,6 +46,8 @@ extern enum ultra_tlb_layout tlb_type; #define SPITFIRE_HIGHEST_LOCKED_TLBENT (64 - 1) #define CHEETAH_HIGHEST_LOCKED_TLBENT (16 - 1) +#define L1DCACHE_SIZE 0x4000 + #define sparc64_highest_locked_tlbent() \ (tlb_type == spitfire ? \ SPITFIRE_HIGHEST_LOCKED_TLBENT : \ diff --git a/include/asm-sparc64/string.h b/include/asm-sparc64/string.h index 5aa023f91395..88348de5635d 100644 --- a/include/asm-sparc64/string.h +++ b/include/asm-sparc64/string.h @@ -1,4 +1,4 @@ -/* $Id: string.h,v 1.19 2001/06/05 20:56:33 davem Exp $ +/* $Id: string.h,v 1.20 2001/09/27 04:36:24 kanoj Exp $ * string.h: External definitions for optimized assembly string * routines for the Linux Kernel. * @@ -17,10 +17,6 @@ extern void __memmove(void *,const void *,__kernel_size_t); extern __kernel_size_t __memcpy(void *,const void *,__kernel_size_t); -extern __kernel_size_t __memcpy_short(void *,const void *,__kernel_size_t,long,long); -extern __kernel_size_t __memcpy_entry(void *,const void *,__kernel_size_t,long,long); -extern __kernel_size_t __memcpy_16plus(void *,const void *,__kernel_size_t,long,long); -extern __kernel_size_t __memcpy_384plus(void *,const void *,__kernel_size_t,long,long); extern void *__memset(void *,int,__kernel_size_t); extern void *__builtin_memcpy(void *,const void *,__kernel_size_t); extern void *__builtin_memset(void *,int,__kernel_size_t); diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h index bf60670f47b3..a5590b897c8c 100644 --- a/include/asm-sparc64/uaccess.h +++ b/include/asm-sparc64/uaccess.h @@ -1,4 +1,4 @@ -/* $Id: uaccess.h,v 1.33 2000/08/29 07:01:58 davem Exp $ */ +/* $Id: uaccess.h,v 1.34 2001/09/27 04:36:24 kanoj Exp $ */ #ifndef _ASM_UACCESS_H #define _ASM_UACCESS_H @@ -249,22 +249,6 @@ __asm__ __volatile__( \ extern int __get_user_bad(void); -extern __kernel_size_t __memcpy_short(void *to, const void *from, - __kernel_size_t size, - long asi_src, long asi_dst); - -extern __kernel_size_t __memcpy_entry(void *to, const void *from, - __kernel_size_t size, - long asi_src, long asi_dst); - -extern __kernel_size_t __memcpy_16plus(void *to, const void *from, - __kernel_size_t size, - long asi_src, long asi_dst); - -extern __kernel_size_t __memcpy_386plus(void *to, const void *from, - __kernel_size_t size, - long asi_src, long asi_dst); - extern __kernel_size_t __copy_from_user(void *to, const void *from, __kernel_size_t size); diff --git a/include/linux/capi.h b/include/linux/capi.h index 0c347e003b21..f474920a7541 100644 --- a/include/linux/capi.h +++ b/include/linux/capi.h @@ -1,10 +1,12 @@ -/* - * $Id: capi.h,v 1.4 2000/06/12 09:20:20 kai Exp $ +/* $Id: capi.h,v 1.4.6.1 2001/09/23 22:25:05 kai Exp $ * * CAPI 2.0 Interface for Linux * * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de) * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #ifndef __LINUX_CAPI_H__ diff --git a/include/linux/concap.h b/include/linux/concap.h index 79d642288891..b58f9667b6c2 100644 --- a/include/linux/concap.h +++ b/include/linux/concap.h @@ -1,5 +1,11 @@ -/* $Id: concap.h,v 1.2 1999/08/23 15:54:21 keil Exp $ -*/ +/* $Id: concap.h,v 1.2.8.1 2001/09/23 22:25:05 kai Exp $ + * + * Copyright 1997 by Henner Eisen <eis@baty.hanse.de> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + #ifndef _LINUX_CONCAP_H #define _LINUX_CONCAP_H #ifdef __KERNEL__ @@ -9,15 +15,12 @@ /* Stuff to support encapsulation protocols genericly. The encapsulation protocol is processed at the uppermost layer of the network interface. - (c) 1997 by Henner Eisen <eis@baty.hanse.de> - This software is subject to the GNU General Public License. - Based on a ideas developed in a 'synchronous device' thread in the linux-x25 mailing list contributed by Alan Cox, Thomasz Motylewski and Jonathan Naylor. For more documetation on this refer to Documentation/isdn/README.concap - */ +*/ struct concap_proto_ops; struct concap_device_ops; diff --git a/include/linux/hysdn_if.h b/include/linux/hysdn_if.h index 9abd59bd707a..166d5ec134d8 100644 --- a/include/linux/hysdn_if.h +++ b/include/linux/hysdn_if.h @@ -1,23 +1,13 @@ -/* $Id: hysdn_if.h,v 1.1.8.2 2001/05/17 20:41:52 kai Exp $ - - * Linux driver for HYSDN cards, ioctl definitions shared by hynetmgr and driver. - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH - * - * Copyright 1999 by Werner Cornelius (werner@titro.de) +/* $Id: hysdn_if.h,v 1.1.8.3 2001/09/23 22:25:05 kai Exp $ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Linux driver for HYSDN cards + * ioctl definitions shared by hynetmgr and driver. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH + * Copyright 1999 by Werner Cornelius (werner@titro.de) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/include/linux/isdn.h b/include/linux/isdn.h index ef82d31915d5..0f1dda941c26 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h @@ -1,24 +1,13 @@ -/* $Id: isdn.h,v 1.111.6.8 2001/08/17 12:34:28 kai Exp $ - +/* $Id: isdn.h,v 1.111.6.9 2001/09/23 22:25:05 kai Exp $ + * * Main header for the Linux ISDN subsystem (linklevel). * * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/include/linux/isdn_divertif.h b/include/linux/isdn_divertif.h index ef532bad430f..0e7e44ce8301 100644 --- a/include/linux/isdn_divertif.h +++ b/include/linux/isdn_divertif.h @@ -1,22 +1,12 @@ -/* $Id: isdn_divertif.h,v 1.4 2000/05/11 22:29:22 kai Exp $ - - * Header for the diversion supplementary interface for i4l. +/* $Id: isdn_divertif.h,v 1.4.6.1 2001/09/23 22:25:05 kai Exp $ * - * Copyright 1998 by Werner Cornelius (werner@isdn4linux.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * Header for the diversion supplementary interface for i4l. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Author Werner Cornelius (werner@titro.de) + * Copyright by Werner Cornelius (werner@titro.de) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/include/linux/isdn_lzscomp.h b/include/linux/isdn_lzscomp.h index 8f64bfa6720f..ca16cb1be43a 100644 --- a/include/linux/isdn_lzscomp.h +++ b/include/linux/isdn_lzscomp.h @@ -1,10 +1,12 @@ -/* - * $Id: isdn_lzscomp.h,v 1.1 1998/07/08 16:52:33 hipp Exp $ +/* $Id: isdn_lzscomp.h,v 1.1.10.1 2001/09/23 22:25:05 kai Exp $ * * Header for isdn_lzscomp.c * Concentrated here to not mess up half a dozen kernel headers with code * snippets * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * */ #define CI_LZS_COMPRESS 17 diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h index c43517f16f87..cc2df8915c89 100644 --- a/include/linux/isdn_ppp.h +++ b/include/linux/isdn_ppp.h @@ -1,4 +1,9 @@ -/* -*- mode: c; c-basic-offset: 2 -*- */ +/* + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ + #ifndef _LINUX_ISDN_PPP_H #define _LINUX_ISDN_PPP_H diff --git a/include/linux/isdnif.h b/include/linux/isdnif.h index e09c9cccee02..672e8b15cbf6 100644 --- a/include/linux/isdnif.h +++ b/include/linux/isdnif.h @@ -1,25 +1,13 @@ -/* $Id: isdnif.h,v 1.37.6.5 2001/06/11 22:08:38 kai Exp $ - - * Linux ISDN subsystem +/* $Id: isdnif.h,v 1.37.6.6 2001/09/23 22:25:05 kai Exp $ * + * Linux ISDN subsystem * Definition of the interface between the subsystem and its low-level drivers. * * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. * */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 1ee66f6e10c9..904588c1754e 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -96,6 +96,9 @@ static inline void console_verbose(void) extern void bust_spinlocks(int yes); extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */ +extern int tainted; +extern const char *print_tainted(void); + #if DEBUG #define pr_debug(fmt,arg...) \ printk(KERN_DEBUG fmt,##arg) diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 5df76c9c4321..caa826a929e4 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -47,6 +47,7 @@ struct nlm_host { unsigned short h_authflavor; /* RPC authentication type */ unsigned short h_reclaiming : 1, h_inuse : 1, + h_killed : 1, h_monitored : 1; wait_queue_head_t h_gracewait; /* wait while reclaiming */ u32 h_state; /* pseudo-state counter */ @@ -120,7 +121,7 @@ extern struct svc_procedure nlmsvc_procedures[]; #ifdef CONFIG_LOCKD_V4 extern struct svc_procedure nlmsvc_procedures4[]; #endif -extern unsigned long nlmsvc_grace_period; +extern int nlmsvc_grace_period; extern unsigned long nlmsvc_timeout; /* diff --git a/include/linux/lockd/nlm.h b/include/linux/lockd/nlm.h index e22388d5097b..869b630cba24 100644 --- a/include/linux/lockd/nlm.h +++ b/include/linux/lockd/nlm.h @@ -49,10 +49,10 @@ enum { #define NLMPROC_CANCEL_RES 13 #define NLMPROC_UNLOCK_RES 14 #define NLMPROC_GRANTED_RES 15 +#define NLMPROC_NSM_NOTIFY 16 /* statd callback */ #define NLMPROC_SHARE 20 #define NLMPROC_UNSHARE 21 #define NLMPROC_NM_LOCK 22 #define NLMPROC_FREE_ALL 23 -#define NLMPROC_NSM_NOTIFY 24 /* statd callback */ #endif /* LINUX_LOCKD_NLM_H */ diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index c06273bbf126..cbf710c5572d 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -21,6 +21,7 @@ #define NVRAM_MINOR 144 #define I2O_MINOR 166 #define MICROCODE_MINOR 184 +#define MWAVE_MINOR 219 /* ACP/Mwave Modem */ #define MPT_MINOR 220 #define MISC_DYNAMIC_MINOR 255 diff --git a/include/linux/module.h b/include/linux/module.h index 7dc117a3329c..d32bf62b8fb0 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -346,12 +346,14 @@ extern struct module *module_list; #define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module #define EXPORT_SYMBOL(var) error config_must_be_included_before_module #define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module +#define EXPORT_SYMBOL_GPL(var) error config_must_be_included_before_module #elif !defined(CONFIG_MODULES) #define __EXPORT_SYMBOL(sym,str) #define EXPORT_SYMBOL(var) #define EXPORT_SYMBOL_NOVERS(var) +#define EXPORT_SYMBOL_GPL(var) #else @@ -362,10 +364,19 @@ const struct module_symbol __ksymtab_##sym \ __attribute__((section("__ksymtab"))) = \ { (unsigned long)&sym, __kstrtab_##sym } +#define __EXPORT_SYMBOL_GPL(sym, str) \ +const char __kstrtab_##sym[] \ +__attribute__((section(".kstrtab"))) = str; \ +const struct module_symbol __ksymtab_GPLONLY_##sym \ +__attribute__((section("__ksymtab"))) = \ +{ (unsigned long)&sym, __kstrtab_GPLONLY_##sym } + #if defined(MODVERSIONS) || !defined(CONFIG_MODVERSIONS) #define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) +#define EXPORT_SYMBOL_GPL(var) __EXPORT_SYMBOL_GPL(var, __MODULE_STRING(var)) #else #define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var))) +#define EXPORT_SYMBOL_GPL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var))) #endif #define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) diff --git a/include/linux/nfs_fs_i.h b/include/linux/nfs_fs_i.h index 2903f4c83b6c..7fc3bae2278b 100644 --- a/include/linux/nfs_fs_i.h +++ b/include/linux/nfs_fs_i.h @@ -99,5 +99,6 @@ struct nfs_lock_info { * Lock flag values */ #define NFS_LCK_GRANTED 0x0001 /* lock has been granted */ +#define NFS_LCK_RECLAIM 0x0002 /* lock marked for reclaiming */ #endif diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 2d7b4f7a044a..0cba3d5028d3 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -345,6 +345,7 @@ #define PCI_DEVICE_ID_IBM_3780IDSP 0x007d #define PCI_DEVICE_ID_IBM_CHUKAR 0x0096 #define PCI_DEVICE_ID_IBM_405GP 0x0156 +#define PCI_DEVICE_ID_IBM_SERVERAIDI960 0x01bd #define PCI_DEVICE_ID_IBM_MPIC_2 0xffff #define PCI_VENDOR_ID_COMPEX2 0x101a // pci.ids says "AT&T GIS (NCR)" diff --git a/include/linux/sem.h b/include/linux/sem.h index 7013af7ea617..3679276fdb21 100644 --- a/include/linux/sem.h +++ b/include/linux/sem.h @@ -68,11 +68,11 @@ struct seminfo { #define SEMMNS (SEMMNI*SEMMSL) /* <= INT_MAX max # of semaphores in system */ #define SEMOPM 32 /* <= 1 000 max num of ops per semop call */ #define SEMVMX 32767 /* <= 32767 semaphore maximum value */ +#define SEMAEM SEMVMX /* adjust on exit max value */ /* unused */ #define SEMUME SEMOPM /* max num of undo entries per process */ #define SEMMNU SEMMNS /* num of undo structures system wide */ -#define SEMAEM (SEMVMX >> 1) /* adjust on exit max value */ #define SEMMAP SEMMNS /* # of entries in semaphore map */ #define SEMUSZ 20 /* sizeof struct sem_undo */ diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 3d34e45883a8..de85345183a7 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -121,6 +121,7 @@ enum KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */ KERN_S390_USER_DEBUG_LOGGING=51, /* int: dumps of user faults */ KERN_CORE_USES_PID=52, /* int: use core or core.%pid */ + KERN_TAINTED=53, /* int: various kernel tainted flags */ KERN_CADPID=54, /* int: PID of the process to notify on CAD */ }; diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h index de03136e551a..1e484e5fd032 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h @@ -24,6 +24,8 @@ struct sysrq_key_op { char *action_msg; }; +#ifdef CONFIG_MAGIC_SYSRQ + /* Generic SysRq interface -- you may call it from any device driver, supplying * ASCII code of the key, pointer to registers and kbd/tty structs (if they * are available -- else NULL's). @@ -42,7 +44,6 @@ void __handle_sysrq_nolock(int, struct pt_regs *, struct kbd_struct *, struct tty_struct *); -#ifdef CONFIG_MAGIC_SYSRQ /* * Sysrq registration manipulation functions @@ -55,7 +56,8 @@ void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p); extern __inline__ int __sysrq_swap_key_ops_nolock(int key, struct sysrq_key_op *insert_op_p, - struct sysrq_key_op *remove_op_p) { + struct sysrq_key_op *remove_op_p) +{ int retval; if (__sysrq_get_key_op(key) == remove_op_p) { __sysrq_put_key_op(key, insert_op_p); @@ -87,10 +89,18 @@ static inline int unregister_sysrq_key(int key, struct sysrq_key_op *op_p) } #else -#define register_sysrq_key(a,b) do {} while(0) -#define unregister_sysrq_key(a,b) do {} while(0) + +static inline int __reterr(void) +{ + return -EINVAL; +} + +#define register_sysrq_key(ig,nore) __reterr() +#define unregister_sysrq_key(ig,nore) __reterr() + #endif + /* Deferred actions */ extern int emergency_sync_scheduled; diff --git a/include/linux/timer.h b/include/linux/timer.h index 803d268f12e3..e3249bf933a0 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -19,7 +19,6 @@ struct timer_list { unsigned long data; void (*function)(unsigned long); }; -typedef struct timer_list timer_t; extern void add_timer(struct timer_list * timer); extern int del_timer(struct timer_list * timer); diff --git a/include/net/tcp.h b/include/net/tcp.h index 4cb72ebec3f7..2cd60784ada2 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -266,13 +266,13 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) * Never offer a window over 32767 without using window scaling. Some * poor stacks do signed 16bit maths! */ -#define MAX_TCP_WINDOW 32767 +#define MAX_TCP_WINDOW 32767U /* Minimal accepted MSS. It is (60+60+8) - (20+20). */ -#define TCP_MIN_MSS 88 +#define TCP_MIN_MSS 88U /* Minimal RCV_MSS. */ -#define TCP_MIN_RCVMSS 536 +#define TCP_MIN_RCVMSS 536U /* After receiving this amount of duplicate ACKs fast retransmit starts. */ #define TCP_FASTRETRANS_THRESH 3 @@ -281,7 +281,7 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) #define TCP_MAX_REORDERING 127 /* Maximal number of ACKs sent quickly to accelerate slow-start. */ -#define TCP_MAX_QUICKACKS 16 +#define TCP_MAX_QUICKACKS 16U /* urg_data states */ #define TCP_URG_VALID 0x0100 @@ -323,21 +323,21 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) * TIME-WAIT timer. */ -#define TCP_DELACK_MAX (HZ/5) /* maximal time to delay before sending an ACK */ +#define TCP_DELACK_MAX ((unsigned)(HZ/5)) /* maximal time to delay before sending an ACK */ #if HZ >= 100 -#define TCP_DELACK_MIN (HZ/25) /* minimal time to delay before sending an ACK */ -#define TCP_ATO_MIN (HZ/25) +#define TCP_DELACK_MIN ((unsigned)(HZ/25)) /* minimal time to delay before sending an ACK */ +#define TCP_ATO_MIN ((unsigned)(HZ/25)) #else -#define TCP_DELACK_MIN 4 -#define TCP_ATO_MIN 4 +#define TCP_DELACK_MIN 4U +#define TCP_ATO_MIN 4U #endif -#define TCP_RTO_MAX (120*HZ) -#define TCP_RTO_MIN (HZ/5) -#define TCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial RTO value */ +#define TCP_RTO_MAX ((unsigned)(120*HZ)) +#define TCP_RTO_MIN ((unsigned)(HZ/5)) +#define TCP_TIMEOUT_INIT ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value */ -#define TCP_RESOURCE_PROBE_INTERVAL (HZ/2) /* Maximal interval between probes - * for local resources. - */ +#define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes + * for local resources. + */ #define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */ #define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ @@ -919,14 +919,13 @@ static __inline__ unsigned int tcp_current_mss(struct sock *sk) static inline void tcp_initialize_rcv_mss(struct sock *sk) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache); + unsigned int hint = min(tp->advmss, tp->mss_cache); - hint = min_t(unsigned int, hint, tp->rcv_wnd/2); - - tp->ack.rcv_mss = max_t(unsigned int, - min_t(unsigned int, - hint, TCP_MIN_RCVMSS), - TCP_MIN_MSS); + hint = min(hint, tp->rcv_wnd/2); + hint = min(hint, TCP_MIN_RCVMSS); + hint = max(hint, TCP_MIN_MSS); + + tp->ack.rcv_mss = hint; } static __inline__ void __tcp_fast_path_on(struct tcp_opt *tp, u32 snd_wnd) @@ -1065,7 +1064,7 @@ static inline int tcp_wspace(struct sock *sk) * "Packets left network, but not honestly ACKed yet" PLUS * "Packets fast retransmitted" */ -static __inline__ int tcp_packets_in_flight(struct tcp_opt *tp) +static __inline__ unsigned int tcp_packets_in_flight(struct tcp_opt *tp) { return tp->packets_out - tp->left_out + tp->retrans_out; } @@ -1077,7 +1076,7 @@ static __inline__ int tcp_packets_in_flight(struct tcp_opt *tp) */ static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp) { - return max_t(u32, tp->snd_cwnd >> 1, 2); + return max(tp->snd_cwnd >> 1U, 2U); } /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd. @@ -1089,7 +1088,7 @@ static inline __u32 tcp_current_ssthresh(struct tcp_opt *tp) if ((1<<tp->ca_state)&(TCPF_CA_CWR|TCPF_CA_Recovery)) return tp->snd_ssthresh; else - return max_t(u32, tp->snd_ssthresh, + return max(tp->snd_ssthresh, ((tp->snd_cwnd >> 1) + (tp->snd_cwnd >> 2))); } @@ -1126,8 +1125,8 @@ static inline void __tcp_enter_cwr(struct tcp_opt *tp) { tp->undo_marker = 0; tp->snd_ssthresh = tcp_recalc_ssthresh(tp); - tp->snd_cwnd = min_t(u32, tp->snd_cwnd, - tcp_packets_in_flight(tp) + 1); + tp->snd_cwnd = min(tp->snd_cwnd, + tcp_packets_in_flight(tp) + 1U); tp->snd_cwnd_cnt = 0; tp->high_seq = tp->snd_nxt; tp->snd_cwnd_stamp = tcp_time_stamp; @@ -1484,16 +1483,18 @@ static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack, * be a multiple of mss if possible. We assume here that mss >= 1. * This MUST be enforced by all callers. */ -static inline void tcp_select_initial_window(int space, __u32 mss, +static inline void tcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, __u32 *window_clamp, int wscale_ok, __u8 *rcv_wscale) { + unsigned int space = (__space < 0 ? 0 : __space); + /* If no clamp set the clamp to the max possible scaled window */ if (*window_clamp == 0) (*window_clamp) = (65535 << 14); - space = min_t(u32, *window_clamp, space); + space = min(*window_clamp, space); /* Quantize space offering to a multiple of mss if possible. */ if (space > mss) @@ -1505,7 +1506,7 @@ static inline void tcp_select_initial_window(int space, __u32 mss, * our initial window offering to 32k. There should also * be a sysctl option to stop being nice. */ - (*rcv_wnd) = min_t(int, space, MAX_TCP_WINDOW); + (*rcv_wnd) = min(space, MAX_TCP_WINDOW); (*rcv_wscale) = 0; if (wscale_ok) { /* See RFC1323 for an explanation of the limit to 14 */ @@ -1514,7 +1515,7 @@ static inline void tcp_select_initial_window(int space, __u32 mss, (*rcv_wscale)++; } if (*rcv_wscale && sysctl_tcp_app_win && space>=mss && - space - max_t(unsigned int, (space>>sysctl_tcp_app_win), mss>>*rcv_wscale) < 65536/2) + space - max((space>>sysctl_tcp_app_win), mss>>*rcv_wscale) < 65536/2) (*rcv_wscale)--; } @@ -1532,7 +1533,7 @@ static inline void tcp_select_initial_window(int space, __u32 mss, *rcv_wnd = init_cwnd*mss; } /* Set the clamp no higher than max representable value */ - (*window_clamp) = min_t(u32, 65535 << (*rcv_wscale), *window_clamp); + (*window_clamp) = min(65535U << (*rcv_wscale), *window_clamp); } static inline int tcp_win_from_space(int space) @@ -1698,8 +1699,8 @@ static inline void tcp_enter_memory_pressure(void) static inline void tcp_moderate_sndbuf(struct sock *sk) { if (!(sk->userlocks&SOCK_SNDBUF_LOCK)) { - sk->sndbuf = min_t(int, sk->sndbuf, sk->wmem_queued/2); - sk->sndbuf = max_t(int, sk->sndbuf, SOCK_MIN_SNDBUF); + sk->sndbuf = min(sk->sndbuf, sk->wmem_queued/2); + sk->sndbuf = max(sk->sndbuf, SOCK_MIN_SNDBUF); } } diff --git a/init/main.c b/init/main.c index 0976a7dd18e0..d4c15678e4f8 100644 --- a/init/main.c +++ b/init/main.c @@ -65,7 +65,7 @@ extern int irda_proto_init(void); extern int irda_device_init(void); #endif -#ifdef CONFIG_X86_IO_APIC +#ifdef CONFIG_X86_LOCAL_APIC #include <asm/smp.h> #endif @@ -479,7 +479,7 @@ extern void cpu_idle(void); #ifndef CONFIG_SMP -#ifdef CONFIG_X86_IO_APIC +#ifdef CONFIG_X86_LOCAL_APIC static void __init smp_init(void) { APIC_init_uniprocessor(); diff --git a/ipc/sem.c b/ipc/sem.c index c9c424dfa965..1c8d9837082f 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -53,6 +53,8 @@ * * SMP-threaded, sysctl's added * (c) 1999 Manfred Spraul <manfreds@colorfullife.com> + * Enforced range limit on SEM_UNDO + * (c) 2001 Red Hat Inc <alan@redhat.com> */ #include <linux/config.h> @@ -256,8 +258,19 @@ static int try_atomic_semop (struct sem_array * sma, struct sembuf * sops, curr->sempid = (curr->sempid << 16) | pid; curr->semval += sem_op; if (sop->sem_flg & SEM_UNDO) - un->semadj[sop->sem_num] -= sem_op; - + { + int undo = un->semadj[sop->sem_num] - sem_op; + /* + * Exceeding the undo range is an error. + */ + if (undo < (-SEMAEM - 1) || undo > SEMAEM) + { + /* Don't undo the undo */ + sop->sem_flg &= ~SEM_UNDO; + goto out_of_range; + } + un->semadj[sop->sem_num] = undo; + } if (curr->semval < 0) goto would_block; if (curr->semval > SEMVMX) diff --git a/kernel/panic.c b/kernel/panic.c index f9957aeef4d1..1eccb0e0c749 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -99,3 +99,24 @@ NORET_TYPE void panic(const char * fmt, ...) CHECK_EMERGENCY_SYNC } } + +/** + * print_tainted - return a string to represent the kernel taint state. + * + * The string is overwritten by the next call to print_taint(). + */ + +const char *print_tainted() +{ + static char buf[20]; + if (tainted) { + snprintf(buf, sizeof(buf), "Tainted: %c%c", + tainted & 1 ? 'P' : 'G', + tainted & 2 ? 'F' : ' '); + } + else + snprintf(buf, sizeof(buf), "Not tainted"); + return(buf); +} + +int tainted = 0; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 3378b95d209c..1e9c81d9ec0d 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -170,6 +170,8 @@ static ctl_table kern_table[] = { 0644, NULL, &proc_dointvec}, {KERN_CORE_USES_PID, "core_uses_pid", &core_uses_pid, sizeof(int), 0644, NULL, &proc_dointvec}, + {KERN_TAINTED, "tainted", &tainted, sizeof(int), + 0644, NULL, &proc_dointvec}, {KERN_CAP_BSET, "cap-bound", &cap_bset, sizeof(kernel_cap_t), 0600, NULL, &proc_dointvec_bset}, #ifdef CONFIG_BLK_DEV_INITRD diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 3c399c826b51..f5048d1f7e13 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -58,6 +58,7 @@ #include <linux/atalk.h> #include <linux/init.h> #include <linux/proc_fs.h> +#include <linux/module.h> int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; int sysctl_aarp_tick_time = AARP_TICK_TIME; @@ -982,3 +983,4 @@ void aarp_unregister_proc_fs(void) } #endif #endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */ +MODULE_LICENSE("GPL"); diff --git a/net/atm/common.c b/net/atm/common.c index 37386ca2690f..1cb08448deaa 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -930,6 +930,8 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg) if (size) ret_val = put_user(size,&((struct atmif_sioc *) arg)->length) ? -EFAULT : 0; + else + ret_val = 0; done: spin_unlock (&atm_dev_lock); diff --git a/net/atm/lec.c b/net/atm/lec.c index 275a8bc261e6..e481864a9f61 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -2193,3 +2193,4 @@ lec_arp_check_empties(struct lec_priv *priv, lec_arp_put(priv->lec_arp_tables,entry); lec_arp_unlock(priv); } +MODULE_LICENSE("GPL"); diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 69bec4cf34ef..c36bbaaeb0c5 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -1479,3 +1479,4 @@ void cleanup_module(void) return; } #endif /* MODULE */ +MODULE_LICENSE("GPL"); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 75d0176980dc..575a9079597b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2028,3 +2028,5 @@ int hci_core_cleanup(void) { return 0; } + +MODULE_LICENSE("GPL"); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 73e0e4df1479..094feb068d39 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2312,3 +2312,5 @@ module_exit(l2cap_cleanup); MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>"); MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION); +MODULE_LICENSE("GPL"); + diff --git a/net/bridge/br.c b/net/bridge/br.c index cda2e570aa5a..80f6807afd20 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -82,3 +82,4 @@ EXPORT_NO_SYMBOLS; module_init(br_init) module_exit(br_deinit) +MODULE_LICENSE("GPL"); diff --git a/net/core/dev.c b/net/core/dev.c index d39c4a03ccd7..4ab29669876e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -552,9 +552,32 @@ int dev_alloc_name(struct net_device *dev, const char *name) { int i; char buf[32]; + char *p, c; /* - * If you need over 100 please also fix the algorithm... + * Verify the string as this thing may have come from + * the user. There must be one "%d" and no other "%" + * characters. + */ + p = name; + while ((c = *p++) != 0) { + if (c == '%') { + c = *p++; + if (c != 'd') + return -EINVAL; + + while ((c = *p++) != 0) { + if (c == '%') + return -EINVAL; + } + goto name_ok; + } + } + return -EINVAL; + + name_ok: + /* + * If you need over 100 please also fix the algorithm... */ for (i = 0; i < 100; i++) { sprintf(buf,name,i); diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 3d76882a74c9..85b068fb3170 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -725,11 +725,11 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) if (skb) { if (skb_queue_len(&neigh->arp_queue) >= neigh->parms->queue_len) { struct sk_buff *buff; - buff = neigh->arp_queue.prev; + buff = neigh->arp_queue.next; __skb_unlink(buff, &neigh->arp_queue); kfree_skb(buff); } - __skb_queue_head(&neigh->arp_queue, skb); + __skb_queue_tail(&neigh->arp_queue, skb); } write_unlock_bh(&neigh->lock); return 1; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index ac62692297c0..82d2cc50de75 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1,7 +1,7 @@ /* * NET3 IP device support routines. * - * Version: $Id: devinet.c,v 1.42 2001/05/16 16:45:35 davem Exp $ + * Version: $Id: devinet.c,v 1.43 2001/09/26 22:52:58 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,6 +20,10 @@ * Changes: * Alexey Kuznetsov: pa_* fields are replaced with ifaddr lists. * Cyrus Durgin: updated for kmod + * Matthias Andree: in devinet_ioctl, compare label and + * address (4.4BSD alias style support), + * fall back to comparing just the label + * if no match found. */ #include <linux/config.h> @@ -463,6 +467,7 @@ static __inline__ int inet_abc_len(u32 addr) int devinet_ioctl(unsigned int cmd, void *arg) { struct ifreq ifr; + struct sockaddr_in sin_orig; struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr; struct in_device *in_dev; struct in_ifaddr **ifap = NULL; @@ -470,6 +475,7 @@ int devinet_ioctl(unsigned int cmd, void *arg) struct net_device *dev; char *colon; int ret = 0; + int tryaddrmatch = 0; /* * Fetch the caller's info block into kernel space @@ -479,6 +485,9 @@ int devinet_ioctl(unsigned int cmd, void *arg) return -EFAULT; ifr.ifr_name[IFNAMSIZ-1] = 0; + /* save original address for comparison */ + memcpy(&sin_orig, sin, sizeof(*sin)); + colon = strchr(ifr.ifr_name, ':'); if (colon) *colon = 0; @@ -492,10 +501,11 @@ int devinet_ioctl(unsigned int cmd, void *arg) case SIOCGIFBRDADDR: /* Get the broadcast address */ case SIOCGIFDSTADDR: /* Get the destination address */ case SIOCGIFNETMASK: /* Get the netmask for the interface */ - /* Note that this ioctls will not sleep, + /* Note that these ioctls will not sleep, so that we do not impose a lock. One day we will be forced to put shlock here (I mean SMP) */ + tryaddrmatch = (sin_orig.sin_family == AF_INET); memset(sin, 0, sizeof(*sin)); sin->sin_family = AF_INET; break; @@ -529,9 +539,27 @@ int devinet_ioctl(unsigned int cmd, void *arg) *colon = ':'; if ((in_dev=__in_dev_get(dev)) != NULL) { - for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next) - if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0) - break; + if (tryaddrmatch) { + /* Matthias Andree */ + /* compare label and address (4.4BSD style) */ + /* note: we only do this for a limited set of ioctls + and only if the original address family was AF_INET. + This is checked above. */ + for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next) { + if ((strcmp(ifr.ifr_name, ifa->ifa_label) == 0) + && (sin_orig.sin_addr.s_addr == ifa->ifa_address)) { + break; /* found */ + } + } + } + /* we didn't get a match, maybe the application is + 4.3BSD-style and passed in junk so we fall back to + comparing just the label */ + if (ifa == NULL) { + for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next) + if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0) + break; + } } if (ifa == NULL && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) { diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 514418f051eb..bc3af5838e7b 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -3,7 +3,7 @@ * * This source is covered by the GNU GPL, the same as all kernel sources. * - * Version: $Id: inetpeer.c,v 1.6 2001/06/21 20:30:14 davem Exp $ + * Version: $Id: inetpeer.c,v 1.7 2001/09/20 21:22:50 davem Exp $ * * Authors: Andrey V. Savochkin <saw@msu.ru> */ @@ -67,6 +67,7 @@ * ip_id_count: idlock */ +/* Exported for inet_getid inline function. */ spinlock_t inet_peer_idlock = SPIN_LOCK_UNLOCKED; static kmem_cache_t *peer_cachep; @@ -83,10 +84,13 @@ static rwlock_t peer_pool_lock = RW_LOCK_UNLOCKED; #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */ static volatile int peer_total; +/* Exported for sysctl_net_ipv4. */ int inet_peer_threshold = 65536 + 128; /* start to throw entries more * aggressively at this stage */ int inet_peer_minttl = 120 * HZ; /* TTL under high load: 120 sec */ int inet_peer_maxttl = 10 * 60 * HZ; /* usual time to live: 10 min */ + +/* Exported for inet_putpeer inline function. */ struct inet_peer *inet_peer_unused_head, **inet_peer_unused_tailp = &inet_peer_unused_head; spinlock_t inet_peer_unused_lock = SPIN_LOCK_UNLOCKED; @@ -95,10 +99,12 @@ spinlock_t inet_peer_unused_lock = SPIN_LOCK_UNLOCKED; static void peer_check_expire(unsigned long dummy); static struct timer_list peer_periodic_timer = { { NULL, NULL }, 0, 0, &peer_check_expire }; + +/* Exported for sysctl_net_ipv4. */ int inet_peer_gc_mintime = 10 * HZ, inet_peer_gc_maxtime = 120 * HZ; - +/* Called from ip_output.c:ip_init */ void __init inet_initpeers(void) { struct sysinfo si; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index fd7b3d226b58..ad4d70d01ee1 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -284,7 +284,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int } if (i==100) goto failed; - memcpy(parms->name, dev->name, IFNAMSIZ); + memcpy(nt->parms.name, dev->name, IFNAMSIZ); } if (register_netdevice(dev) < 0) goto failed; @@ -1011,6 +1011,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) err = -EPERM; if (t == &ipgre_fb_tunnel) goto done; + dev = t->dev; } err = unregister_netdevice(dev); break; @@ -1296,3 +1297,4 @@ void cleanup_module(void) } #endif +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 9dfe03e702c0..18210bb45a9f 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1,5 +1,5 @@ /* - * $Id: ipconfig.c,v 1.37 2001/04/30 18:54:12 davem Exp $ + * $Id: ipconfig.c,v 1.38 2001/09/25 23:23:07 davem Exp $ * * Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or * user-supplied information to configure own IP address and routes. @@ -816,62 +816,67 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str u8 *ext; #ifdef IPCONFIG_DHCP - - u32 server_id = INADDR_NONE; - int mt = 0; - - ext = &b->exten[4]; - while (ext < end && *ext != 0xff) { - u8 *opt = ext++; - if (*opt == 0) /* Padding */ - continue; - ext += *ext + 1; - if (ext >= end) - break; - switch (*opt) { - case 53: /* Message type */ - if (opt[1]) - mt = opt[2]; - break; - case 54: /* Server ID (IP address) */ - if (opt[1] >= 4) - memcpy(&server_id, opt + 2, 4); - break; + if (ic_proto_enabled & IC_USE_DHCP) { + u32 server_id = INADDR_NONE; + int mt = 0; + + ext = &b->exten[4]; + while (ext < end && *ext != 0xff) { + u8 *opt = ext++; + if (*opt == 0) /* Padding */ + continue; + ext += *ext + 1; + if (ext >= end) + break; + switch (*opt) { + case 53: /* Message type */ + if (opt[1]) + mt = opt[2]; + break; + case 54: /* Server ID (IP address) */ + if (opt[1] >= 4) + memcpy(&server_id, opt + 2, 4); + break; + }; } - } #ifdef IPCONFIG_DEBUG - printk("DHCP: Got message type %d\n", mt); + printk("DHCP: Got message type %d\n", mt); #endif - switch (mt) { - case DHCPOFFER: - /* While in the process of accepting one offer, - ignore all others. */ - if (ic_myaddr != INADDR_NONE) - goto drop; - /* Let's accept that offer. */ - ic_myaddr = b->your_ip; - ic_servaddr = server_id; + switch (mt) { + case DHCPOFFER: + /* While in the process of accepting one offer, + * ignore all others. + */ + if (ic_myaddr != INADDR_NONE) + goto drop; + + /* Let's accept that offer. */ + ic_myaddr = b->your_ip; + ic_servaddr = server_id; #ifdef IPCONFIG_DEBUG - printk("DHCP: Offered address %u.%u.%u.%u", NIPQUAD(ic_myaddr)); - printk(" by server %u.%u.%u.%u\n", NIPQUAD(ic_servaddr)); + printk("DHCP: Offered address %u.%u.%u.%u", + NIPQUAD(ic_myaddr)); + printk(" by server %u.%u.%u.%u\n", + NIPQUAD(ic_servaddr)); #endif - break; + break; - case DHCPACK: - /* Yeah! */ - break; + case DHCPACK: + /* Yeah! */ + break; - default: - /* Urque. Forget it*/ - ic_myaddr = INADDR_NONE; - ic_servaddr = INADDR_NONE; - goto drop; - } + default: + /* Urque. Forget it*/ + ic_myaddr = INADDR_NONE; + ic_servaddr = INADDR_NONE; + goto drop; + }; - ic_dhcp_msgtype = mt; + ic_dhcp_msgtype = mt; + } #endif /* IPCONFIG_DHCP */ ext = &b->exten[4]; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 19c4807b9a7f..29b6f50102fb 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -1,7 +1,7 @@ /* * Linux NET3: IP/IP protocol decoder. * - * Version: $Id: ipip.c,v 1.47 2001/09/18 00:36:07 davem Exp $ + * Version: $Id: ipip.c,v 1.49 2001/09/25 22:35:47 davem Exp $ * * Authors: * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95 @@ -255,7 +255,7 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) } if (i==100) goto failed; - memcpy(parms->name, dev->name, IFNAMSIZ); + memcpy(nt->parms.name, dev->name, IFNAMSIZ); } if (register_netdevice(dev) < 0) goto failed; @@ -758,6 +758,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) err = -EPERM; if (t == &ipip_fb_tunnel) goto done; + dev = t->dev; } err = unregister_netdevice(dev); break; @@ -903,3 +904,4 @@ static void __exit ipip_fini(void) module_init(ipip_init); #endif module_exit(ipip_fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index 8f7469cb71be..6de776d8dc9e 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c @@ -417,6 +417,7 @@ static int __init init(void) EXPORT_SYMBOL(ip_ftp_lock); EXPORT_SYMBOL(ip_conntrack_ftp); +MODULE_LICENSE("GPL"); module_init(init); module_exit(fini); diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 4a98c004927d..3c60c0d78ea1 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -33,6 +33,8 @@ #endif struct module *ip_conntrack_module = THIS_MODULE; +MODULE_LICENSE("GPL"); + static unsigned int print_tuple(char *buffer, const struct ip_conntrack_tuple *tuple, diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c index f9cb9bebe4f1..26b27d5bb169 100644 --- a/net/ipv4/netfilter/ip_nat_ftp.c +++ b/net/ipv4/netfilter/ip_nat_ftp.c @@ -369,3 +369,4 @@ static int __init init(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 20982c479db5..f6e13323d43e 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -343,3 +343,4 @@ EXPORT_SYMBOL(ip_nat_cheat_check); EXPORT_SYMBOL(ip_nat_mangle_tcp_packet); EXPORT_SYMBOL(ip_nat_seq_adjust); EXPORT_SYMBOL(ip_nat_delete_sack); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 6f6d5853a8ee..06949c2172be 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -685,5 +685,7 @@ static void __exit fini(void) } MODULE_DESCRIPTION("IPv4 packet queue handler"); +MODULE_LICENSE("GPL"); + module_init(init); module_exit(fini); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 3c430d0803bc..8a0477e4de3f 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1764,3 +1764,4 @@ EXPORT_SYMBOL(ipt_unregister_target); module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipchains_core.c b/net/ipv4/netfilter/ipchains_core.c index e4812aafd1b1..bf320445cd10 100644 --- a/net/ipv4/netfilter/ipchains_core.c +++ b/net/ipv4/netfilter/ipchains_core.c @@ -1765,3 +1765,4 @@ int ipfw_init_or_cleanup(int init) #endif return ret; } +MODULE_LICENSE("BSD without advertisement clause"); diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index c7f9dfe37cff..0c97dd27b0cc 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c @@ -353,3 +353,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_MARK.c b/net/ipv4/netfilter/ipt_MARK.c index dd8bb322691c..63a998d6c719 100644 --- a/net/ipv4/netfilter/ipt_MARK.c +++ b/net/ipv4/netfilter/ipt_MARK.c @@ -64,3 +64,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 38d619f387bc..82515c49a8f2 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c @@ -204,3 +204,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_MIRROR.c b/net/ipv4/netfilter/ipt_MIRROR.c index 9449c5128691..d984d7e1fb9a 100644 --- a/net/ipv4/netfilter/ipt_MIRROR.c +++ b/net/ipv4/netfilter/ipt_MIRROR.c @@ -151,3 +151,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index 7954d273a26c..82d1e8be6b4c 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c @@ -105,3 +105,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 8e46a2f875eb..787be9b2016b 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c @@ -374,3 +374,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c index 9dd50740aea4..ced0a9dced52 100644 --- a/net/ipv4/netfilter/ipt_TCPMSS.c +++ b/net/ipv4/netfilter/ipt_TCPMSS.c @@ -243,3 +243,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c index 2967ed241b7c..e6061d707ac5 100644 --- a/net/ipv4/netfilter/ipt_TOS.c +++ b/net/ipv4/netfilter/ipt_TOS.c @@ -83,3 +83,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_limit.c b/net/ipv4/netfilter/ipt_limit.c index 6665f1ce475a..6f8124194d37 100644 --- a/net/ipv4/netfilter/ipt_limit.c +++ b/net/ipv4/netfilter/ipt_limit.c @@ -133,3 +133,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_mac.c b/net/ipv4/netfilter/ipt_mac.c index ce280b3c2e8c..b18270ae6780 100644 --- a/net/ipv4/netfilter/ipt_mac.c +++ b/net/ipv4/netfilter/ipt_mac.c @@ -62,3 +62,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_mark.c b/net/ipv4/netfilter/ipt_mark.c index b7528a4c237f..05066530ee5c 100644 --- a/net/ipv4/netfilter/ipt_mark.c +++ b/net/ipv4/netfilter/ipt_mark.c @@ -48,3 +48,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_multiport.c b/net/ipv4/netfilter/ipt_multiport.c index b1727bb7c551..1d9b3c395434 100644 --- a/net/ipv4/netfilter/ipt_multiport.c +++ b/net/ipv4/netfilter/ipt_multiport.c @@ -101,3 +101,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c index 7467dfaf0268..764c50b7ab7d 100644 --- a/net/ipv4/netfilter/ipt_owner.c +++ b/net/ipv4/netfilter/ipt_owner.c @@ -152,3 +152,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c index 94f6bbfa5e08..1a273138a1e5 100644 --- a/net/ipv4/netfilter/ipt_state.c +++ b/net/ipv4/netfilter/ipt_state.c @@ -61,3 +61,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_tcpmss.c b/net/ipv4/netfilter/ipt_tcpmss.c index 7dae37a33694..001f7a83777a 100644 --- a/net/ipv4/netfilter/ipt_tcpmss.c +++ b/net/ipv4/netfilter/ipt_tcpmss.c @@ -106,3 +106,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c index dfbcb40e56cb..4f51305e1b5f 100644 --- a/net/ipv4/netfilter/ipt_tos.c +++ b/net/ipv4/netfilter/ipt_tos.c @@ -49,3 +49,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ipt_unclean.c b/net/ipv4/netfilter/ipt_unclean.c index 69d18834df3b..80b6c55dbb0e 100644 --- a/net/ipv4/netfilter/ipt_unclean.c +++ b/net/ipv4/netfilter/ipt_unclean.c @@ -583,3 +583,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 8c21d6cd90f7..38b5f0257acf 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c @@ -179,3 +179,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index cefcd79e6f0d..1c26b28f5013 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c @@ -204,3 +204,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0093121215cc..21c7328091e4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.211 2001/09/20 00:35:35 davem Exp $ + * Version: $Id: tcp.c,v 1.212 2001/09/21 21:27:34 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -852,7 +852,7 @@ ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size page = pages[poffset/PAGE_SIZE]; offset = poffset % PAGE_SIZE; - size = min_t(unsigned int, psize, PAGE_SIZE-offset); + size = min(psize, PAGE_SIZE-offset); if (tp->send_head==NULL || (copy = mss_now - skb->len) <= 0) { new_segment: diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a8a17f063694..fd193c721fe7 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.236 2001/09/18 22:29:09 davem Exp $ + * Version: $Id: tcp_input.c,v 1.237 2001/09/21 21:27:34 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -168,7 +168,7 @@ static void tcp_incr_quickack(struct tcp_opt *tp) if (quickacks==0) quickacks=2; if (quickacks > tp->ack.quick) - tp->ack.quick = min_t(unsigned int, quickacks, TCP_MAX_QUICKACKS); + tp->ack.quick = min(quickacks, TCP_MAX_QUICKACKS); } void tcp_enter_quickack_mode(struct tcp_opt *tp) @@ -198,7 +198,7 @@ static void tcp_fixup_sndbuf(struct sock *sk) int sndmem = tp->mss_clamp+MAX_TCP_HEADER+16+sizeof(struct sk_buff); if (sk->sndbuf < 3*sndmem) - sk->sndbuf = min_t(int, 3*sndmem, sysctl_tcp_wmem[2]); + sk->sndbuf = min(3*sndmem, sysctl_tcp_wmem[2]); } /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) @@ -262,7 +262,7 @@ tcp_grow_window(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) incr = __tcp_grow_window(sk, tp, skb); if (incr) { - tp->rcv_ssthresh = min_t(u32, tp->rcv_ssthresh + incr, tp->window_clamp); + tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, tp->window_clamp); tp->ack.quick |= 1; } } @@ -282,7 +282,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk) while (tcp_win_from_space(rcvmem) < tp->advmss) rcvmem += 128; if (sk->rcvbuf < 4*rcvmem) - sk->rcvbuf = min_t(int, 4*rcvmem, sysctl_tcp_rmem[2]); + sk->rcvbuf = min(4*rcvmem, sysctl_tcp_rmem[2]); } /* 4. Try to fixup all. It is made iimediately after connection enters @@ -304,16 +304,16 @@ static void tcp_init_buffer_space(struct sock *sk) tp->window_clamp = maxwin; if (sysctl_tcp_app_win && maxwin>4*tp->advmss) - tp->window_clamp = max_t(u32, maxwin-(maxwin>>sysctl_tcp_app_win), 4*tp->advmss); + tp->window_clamp = max(maxwin-(maxwin>>sysctl_tcp_app_win), 4*tp->advmss); } /* Force reservation of one segment. */ if (sysctl_tcp_app_win && tp->window_clamp > 2*tp->advmss && tp->window_clamp + tp->advmss > maxwin) - tp->window_clamp = max_t(u32, 2*tp->advmss, maxwin-tp->advmss); + tp->window_clamp = max(2*tp->advmss, maxwin-tp->advmss); - tp->rcv_ssthresh = min_t(u32, tp->rcv_ssthresh, tp->window_clamp); + tp->rcv_ssthresh = min(tp->rcv_ssthresh, tp->window_clamp); tp->snd_cwnd_stamp = tcp_time_stamp; } @@ -321,7 +321,7 @@ static void tcp_init_buffer_space(struct sock *sk) static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp) { struct sk_buff *skb; - int app_win = tp->rcv_nxt - tp->copied_seq; + unsigned int app_win = tp->rcv_nxt - tp->copied_seq; int ofo_win = 0; tp->ack.quick = 0; @@ -338,7 +338,7 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp) !(sk->userlocks&SOCK_RCVBUF_LOCK) && !tcp_memory_pressure && atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) - sk->rcvbuf = min_t(int, atomic_read(&sk->rmem_alloc), sysctl_tcp_rmem[2]); + sk->rcvbuf = min(atomic_read(&sk->rmem_alloc), sysctl_tcp_rmem[2]); } if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) { app_win += ofo_win; @@ -346,11 +346,11 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp) app_win >>= 1; if (app_win > tp->ack.rcv_mss) app_win -= tp->ack.rcv_mss; - app_win = max_t(unsigned int, app_win, 2*tp->advmss); + app_win = max(app_win, 2U*tp->advmss); if (!ofo_win) - tp->window_clamp = min_t(u32, tp->window_clamp, app_win); - tp->rcv_ssthresh = min_t(u32, tp->window_clamp, 2*tp->advmss); + tp->window_clamp = min(tp->window_clamp, app_win); + tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss); } } @@ -472,7 +472,7 @@ static __inline__ void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt) /* no previous measure. */ tp->srtt = m<<3; /* take the measured time to be rtt */ tp->mdev = m<<2; /* make sure rto = 3*rtt */ - tp->mdev_max = tp->rttvar = max_t(u32, tp->mdev, TCP_RTO_MIN); + tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN); tp->rtt_seq = tp->snd_nxt; } } @@ -575,7 +575,7 @@ void tcp_update_metrics(struct sock *sk) tp->ca_state == TCP_CA_Open) { /* Cong. avoidance phase, cwnd is reliable. */ if (!(dst->mxlock&(1<<RTAX_SSTHRESH))) - dst->ssthresh = max_t(u32, tp->snd_cwnd>>1, tp->snd_ssthresh); + dst->ssthresh = max(tp->snd_cwnd>>1, tp->snd_ssthresh); if (!(dst->mxlock&(1<<RTAX_CWND))) dst->cwnd = (dst->cwnd + tp->snd_cwnd)>>1; } else { @@ -617,7 +617,7 @@ __u32 tcp_init_cwnd(struct tcp_opt *tp) else if (cwnd > tp->snd_ssthresh) cwnd = tp->snd_ssthresh; - return min_t(u32, cwnd, tp->snd_cwnd_clamp); + return min_t(__u32, cwnd, tp->snd_cwnd_clamp); } /* Initialize metrics on socket. */ @@ -668,7 +668,7 @@ static void tcp_init_metrics(struct sock *sk) tp->srtt = dst->rtt; if (dst->rttvar > tp->mdev) { tp->mdev = dst->rttvar; - tp->mdev_max = tp->rttvar = max_t(u32, tp->mdev, TCP_RTO_MIN); + tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN); } tcp_set_rto(tp); tcp_bound_rto(tp); @@ -693,7 +693,7 @@ reset: static void tcp_update_reordering(struct tcp_opt *tp, int metric, int ts) { if (metric > tp->reordering) { - tp->reordering = min_t(unsigned int, TCP_MAX_REORDERING, metric); + tp->reordering = min(TCP_MAX_REORDERING, metric); /* This exciting event is worth to be remembered. 8) */ if (ts) @@ -848,12 +848,12 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if (sacked&TCPCB_RETRANS) { if ((dup_sack && in_sack) && (sacked&TCPCB_SACKED_ACKED)) - reord = min_t(int, fack_count, reord); + reord = min(fack_count, reord); } else { /* If it was in a hole, we detected reordering. */ if (fack_count < prior_fackets && !(sacked&TCPCB_SACKED_ACKED)) - reord = min_t(int, fack_count, reord); + reord = min(fack_count, reord); } /* Nothing to do; acked frame is about to be dropped. */ @@ -885,7 +885,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ */ if (!(sacked & TCPCB_RETRANS) && fack_count < prior_fackets) - reord = min_t(int, fack_count, reord); + reord = min(fack_count, reord); if (sacked & TCPCB_LOST) { TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; @@ -901,7 +901,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ tp->fackets_out = fack_count; } else { if (dup_sack && (sacked&TCPCB_RETRANS)) - reord = min_t(int, fack_count, reord); + reord = min(fack_count, reord); } /* D-SACK. We can detect redundant retransmission @@ -1177,7 +1177,7 @@ tcp_time_to_recover(struct sock *sk, struct tcp_opt *tp) * recovery more? */ if (tp->packets_out <= tp->reordering && - tp->sacked_out >= max_t(u32, tp->packets_out/2, sysctl_tcp_reordering) && + tp->sacked_out >= max_t(__u32, tp->packets_out/2, sysctl_tcp_reordering) && !tcp_may_send_now(sk, tp)) { /* We have nothing to send. This connection is limited * either by receiver window or by application. @@ -1194,9 +1194,10 @@ tcp_time_to_recover(struct sock *sk, struct tcp_opt *tp) */ static void tcp_check_reno_reordering(struct tcp_opt *tp, int addend) { - u32 holes = min_t(unsigned int, - max_t(unsigned int, tp->lost_out, 1), - tp->packets_out); + u32 holes; + + holes = max(tp->lost_out, 1U); + holes = min(holes, tp->packets_out); if (tp->sacked_out + holes > tp->packets_out) { tp->sacked_out = tp->packets_out - holes; @@ -1291,7 +1292,7 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_opt *tp) */ static __inline__ void tcp_moderate_cwnd(struct tcp_opt *tp) { - tp->snd_cwnd = min_t(u32, tp->snd_cwnd, + tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+tcp_max_burst(tp)); tp->snd_cwnd_stamp = tcp_time_stamp; } @@ -1308,7 +1309,7 @@ static void tcp_cwnd_down(struct tcp_opt *tp) if (decr && tp->snd_cwnd > tp->snd_ssthresh/2) tp->snd_cwnd -= decr; - tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tcp_packets_in_flight(tp)+1); + tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1); tp->snd_cwnd_stamp = tcp_time_stamp; } @@ -1340,15 +1341,14 @@ static void DBGUNDO(struct sock *sk, struct tcp_opt *tp, const char *msg) static void tcp_undo_cwr(struct tcp_opt *tp, int undo) { if (tp->prior_ssthresh) { - tp->snd_cwnd = max_t(unsigned int, - tp->snd_cwnd, tp->snd_ssthresh<<1); + tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1); if (undo && tp->prior_ssthresh > tp->snd_ssthresh) { tp->snd_ssthresh = tp->prior_ssthresh; TCP_ECN_withdraw_cwr(tp); } } else { - tp->snd_cwnd = max_t(unsigned int, tp->snd_cwnd, tp->snd_ssthresh); + tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh); } tcp_moderate_cwnd(tp); tp->snd_cwnd_stamp = tcp_time_stamp; @@ -1450,7 +1450,7 @@ static int tcp_try_undo_loss(struct sock *sk, struct tcp_opt *tp) static __inline__ void tcp_complete_cwr(struct tcp_opt *tp) { - tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_ssthresh); + tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); tp->snd_cwnd_stamp = tcp_time_stamp; } @@ -1836,7 +1836,7 @@ static void tcp_ack_probe(struct sock *sk) */ } else { tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, - min_t(u32, tp->rto << tp->backoff, TCP_RTO_MAX)); + min(tp->rto << tp->backoff, TCP_RTO_MAX)); } } @@ -2323,7 +2323,7 @@ static __inline__ void tcp_dsack_set(struct tcp_opt *tp, u32 seq, u32 end_seq) tp->dsack = 1; tp->duplicate_sack[0].start_seq = seq; tp->duplicate_sack[0].end_seq = end_seq; - tp->eff_sacks = min_t(unsigned int, tp->num_sacks+1, 4-tp->tstamp_ok); + tp->eff_sacks = min(tp->num_sacks+1, 4-tp->tstamp_ok); } } @@ -2376,7 +2376,7 @@ static void tcp_sack_maybe_coalesce(struct tcp_opt *tp) * Decrease num_sacks. */ tp->num_sacks--; - tp->eff_sacks = min_t(unsigned int, tp->num_sacks+tp->dsack, 4-tp->tstamp_ok); + tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok); for(i=this_sack; i < tp->num_sacks; i++) sp[i] = sp[i+1]; continue; @@ -2438,7 +2438,7 @@ new_sack: sp->start_seq = seq; sp->end_seq = end_seq; tp->num_sacks++; - tp->eff_sacks = min_t(unsigned int, tp->num_sacks+tp->dsack, 4-tp->tstamp_ok); + tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok); } /* RCV.NXT advances, some SACKs should be eaten. */ @@ -2475,7 +2475,7 @@ static void tcp_sack_remove(struct tcp_opt *tp) } if (num_sacks != tp->num_sacks) { tp->num_sacks = num_sacks; - tp->eff_sacks = min_t(unsigned int, tp->num_sacks+tp->dsack, 4-tp->tstamp_ok); + tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok); } } @@ -2807,7 +2807,7 @@ tcp_collapse(struct sock *sk, struct sk_buff *head, if (offset < 0) BUG(); if (size > 0) { - size = min_t(int, copy, size); + size = min(copy, size); if (skb_copy_bits(skb, offset, skb_put(nskb, size), size)) BUG(); TCP_SKB_CB(nskb)->end_seq += size; @@ -2886,7 +2886,7 @@ static int tcp_prune_queue(struct sock *sk) if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf) tcp_clamp_window(sk, tp); else if (tcp_memory_pressure) - tp->rcv_ssthresh = min_t(u32, tp->rcv_ssthresh, 4*tp->advmss); + tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss); tcp_collapse_ofo_queue(sk); tcp_collapse(sk, sk->receive_queue.next, @@ -2941,7 +2941,7 @@ void tcp_cwnd_application_limited(struct sock *sk) if (tp->ca_state == TCP_CA_Open && sk->socket && !test_bit(SOCK_NOSPACE, &sk->socket->flags)) { /* Limited by application or receiver window. */ - u32 win_used = max_t(u32, tp->snd_cwnd_used, 2); + u32 win_used = max(tp->snd_cwnd_used, 2U); if (win_used < tp->snd_cwnd) { tp->snd_ssthresh = tcp_current_ssthresh(tp); tp->snd_cwnd = (tp->snd_cwnd+win_used)>>1; @@ -2970,7 +2970,7 @@ static void tcp_new_space(struct sock *sk) demanded = max_t(unsigned int, tp->snd_cwnd, tp->reordering+1); sndmem *= 2*demanded; if (sndmem > sk->sndbuf) - sk->sndbuf = min_t(int, sndmem, sysctl_tcp_wmem[2]); + sk->sndbuf = min(sndmem, sysctl_tcp_wmem[2]); tp->snd_cwnd_stamp = tcp_time_stamp; } @@ -3520,7 +3520,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, if (tp->wscale_ok == 0) { tp->snd_wscale = tp->rcv_wscale = 0; - tp->window_clamp = min_t(u32, tp->window_clamp, 65535); + tp->window_clamp = min(tp->window_clamp, 65535U); } if (tp->saw_tstamp) { diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a60c4057646d..69455b35eabd 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.230 2001/09/01 00:31:50 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.231 2001/09/26 23:38:47 davem Exp $ * * IPv4 specific functions * @@ -1486,7 +1486,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk,struct sk_buff *skb) bh_lock_sock(nsk); return nsk; } - tcp_tw_put((struct tcp_tw_bucket*)sk); + tcp_tw_put((struct tcp_tw_bucket*)nsk); return NULL; } diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 8ace4da5d89a..8697cb25eefb 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_minisocks.c,v 1.13 2001/09/18 22:29:10 davem Exp $ + * Version: $Id: tcp_minisocks.c,v 1.14 2001/09/21 21:27:34 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -766,7 +766,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, newtp->rcv_wscale = req->rcv_wscale; } else { newtp->snd_wscale = newtp->rcv_wscale = 0; - newtp->window_clamp = min_t(u32, newtp->window_clamp, 65535); + newtp->window_clamp = min(newtp->window_clamp, 65535U); } newtp->snd_wnd = ntohs(skb->h.th->window) << newtp->snd_wscale; newtp->max_window = newtp->snd_wnd; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index c1210dd392a5..a3844e347564 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_output.c,v 1.141 2001/09/18 22:29:10 davem Exp $ + * Version: $Id: tcp_output.c,v 1.142 2001/09/21 21:27:34 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -105,11 +105,11 @@ static void tcp_cwnd_restart(struct tcp_opt *tp) u32 cwnd = tp->snd_cwnd; tp->snd_ssthresh = tcp_current_ssthresh(tp); - restart_cwnd = min_t(u32, restart_cwnd, cwnd); + restart_cwnd = min(restart_cwnd, cwnd); while ((delta -= tp->rto) > 0 && cwnd > restart_cwnd) cwnd >>= 1; - tp->snd_cwnd = max_t(u32, cwnd, restart_cwnd); + tp->snd_cwnd = max(cwnd, restart_cwnd); tp->snd_cwnd_stamp = tcp_time_stamp; tp->snd_cwnd_used = 0; } @@ -526,7 +526,7 @@ int tcp_sync_mss(struct sock *sk, u32 pmtu) /* Bound mss with half of window */ if (tp->max_window && mss_now > (tp->max_window>>1)) - mss_now = max_t(u32, (tp->max_window>>1), 68 - tp->tcp_header_len); + mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len); /* And store cached results */ tp->pmtu_cookie = pmtu; @@ -651,7 +651,7 @@ u32 __tcp_select_window(struct sock *sk) */ int mss = tp->ack.rcv_mss; int free_space = tcp_space(sk); - int full_space = min_t(unsigned int, tp->window_clamp, tcp_full_space(sk)); + int full_space = min_t(int, tp->window_clamp, tcp_full_space(sk)); int window; if (mss > full_space) @@ -661,7 +661,7 @@ u32 __tcp_select_window(struct sock *sk) tp->ack.quick = 0; if (tcp_memory_pressure) - tp->rcv_ssthresh = min_t(u32, tp->rcv_ssthresh, 4*tp->advmss); + tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss); if (free_space < mss) return 0; @@ -817,7 +817,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) /* Do not sent more than we queued. 1/4 is reserved for possible * copying overhead: frgagmentation, tunneling, mangling etc. */ - if (atomic_read(&sk->wmem_alloc) > min_t(int, sk->wmem_queued+(sk->wmem_queued>>2),sk->sndbuf)) + if (atomic_read(&sk->wmem_alloc) > min(sk->wmem_queued+(sk->wmem_queued>>2),sk->sndbuf)) return -EAGAIN; /* If receiver has shrunk his window, and skb is out of @@ -1264,13 +1264,13 @@ void tcp_send_delayed_ack(struct sock *sk) * directly. */ if (tp->srtt) { - int rtt = max_t(unsigned int, tp->srtt>>3, TCP_DELACK_MIN); + int rtt = max(tp->srtt>>3, TCP_DELACK_MIN); if (rtt < max_ato) max_ato = rtt; } - ato = min_t(int, ato, max_ato); + ato = min(ato, max_ato); } /* Stay within the limit we were given */ @@ -1386,7 +1386,7 @@ int tcp_write_wakeup(struct sock *sk) */ if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq || skb->len > mss) { - seg_size = min_t(int, seg_size, mss); + seg_size = min(seg_size, mss); TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; if (tcp_fragment(sk, skb, seg_size)) return -1; @@ -1429,7 +1429,7 @@ void tcp_send_probe0(struct sock *sk) tp->backoff++; tp->probes_out++; tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, - min_t(u32, tp->rto << tp->backoff, TCP_RTO_MAX)); + min(tp->rto << tp->backoff, TCP_RTO_MAX)); } else { /* If packet was not sent due to local congestion, * do not backoff and do not remember probes_out. @@ -1440,6 +1440,6 @@ void tcp_send_probe0(struct sock *sk) if (!tp->probes_out) tp->probes_out=1; tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, - min_t(unsigned int, tp->rto << tp->backoff, TCP_RESOURCE_PROBE_INTERVAL)); + min(tp->rto << tp->backoff, TCP_RESOURCE_PROBE_INTERVAL)); } } diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index b867d766e281..a0cdd875397f 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_timer.c,v 1.86 2001/09/18 22:29:10 davem Exp $ + * Version: $Id: tcp_timer.c,v 1.87 2001/09/21 21:27:34 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -248,7 +248,7 @@ static void tcp_delack_timer(unsigned long data) if (tcp_ack_scheduled(tp)) { if (!tp->ack.pingpong) { /* Delayed ACK missed: inflate ATO. */ - tp->ack.ato = min_t(u32, tp->ack.ato << 1, tp->rto); + tp->ack.ato = min(tp->ack.ato << 1, tp->rto); } else { /* Delayed ACK missed: leave pingpong mode and * deflate ATO. @@ -381,7 +381,7 @@ static void tcp_retransmit_timer(struct sock *sk) if (!tp->retransmits) tp->retransmits=1; tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, - min_t(u32, tp->rto, TCP_RESOURCE_PROBE_INTERVAL)); + min(tp->rto, TCP_RESOURCE_PROBE_INTERVAL)); goto out; } @@ -404,7 +404,7 @@ static void tcp_retransmit_timer(struct sock *sk) tp->retransmits++; out_reset_timer: - tp->rto = min_t(u32, tp->rto << 1, TCP_RTO_MAX); + tp->rto = min(tp->rto << 1, TCP_RTO_MAX); tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); if (tp->retransmits > sysctl_tcp_retries1) __sk_dst_reset(sk); @@ -517,8 +517,7 @@ static void tcp_synack_timer(struct sock *sk) if (req->retrans++ == 0) lopt->qlen_young--; - timeo = min_t(unsigned long, - (TCP_TIMEOUT_INIT << req->retrans), + timeo = min((TCP_TIMEOUT_INIT << req->retrans), TCP_RTO_MAX); req->expires = now + timeo; reqp = &req->dl_next; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 5e9ec1c2ac5b..2c297fd633f9 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -718,3 +718,4 @@ static void inet6_exit(void) } module_exit(inet6_exit); #endif /* MODULE */ +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 20a668c43339..42a8498136fe 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1801,3 +1801,4 @@ EXPORT_SYMBOL(ip6t_unregister_target); module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c index 08df336e811f..1bd758fc3221 100644 --- a/net/ipv6/netfilter/ip6t_MARK.c +++ b/net/ipv6/netfilter/ip6t_MARK.c @@ -65,3 +65,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/netfilter/ip6t_limit.c b/net/ipv6/netfilter/ip6t_limit.c index 0d79a9a8bd73..fca374dbd363 100644 --- a/net/ipv6/netfilter/ip6t_limit.c +++ b/net/ipv6/netfilter/ip6t_limit.c @@ -133,3 +133,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/netfilter/ip6t_mark.c b/net/ipv6/netfilter/ip6t_mark.c index 9a78b1ca269f..6a7b61cc0b99 100644 --- a/net/ipv6/netfilter/ip6t_mark.c +++ b/net/ipv6/netfilter/ip6t_mark.c @@ -48,3 +48,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index 33de64cc9847..3d922ab36555 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c @@ -181,3 +181,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 612c292c4668..da87bbb3e8a8 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c @@ -187,3 +187,4 @@ static void __exit fini(void) module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 981e1c9d5e8a..b3cc361c9ca2 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -6,7 +6,7 @@ * Pedro Roque <roque@di.fc.ul.pt> * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> * - * $Id: sit.c,v 1.52 2001/09/01 00:31:50 davem Exp $ + * $Id: sit.c,v 1.53 2001/09/25 05:09:53 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -712,6 +712,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) err = -EPERM; if (t == &ipip6_fb_tunnel) goto done; + dev = t->dev; } err = unregister_netdevice(dev); break; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 33e9cb1ec507..899f658575a2 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -5,7 +5,7 @@ * Authors: * Pedro Roque <roque@di.fc.ul.pt> * - * $Id: tcp_ipv6.c,v 1.138 2001/09/01 00:31:50 davem Exp $ + * $Id: tcp_ipv6.c,v 1.139 2001/09/26 23:38:47 davem Exp $ * * Based on: * linux/net/ipv4/tcp.c @@ -1098,7 +1098,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) bh_lock_sock(nsk); return nsk; } - tcp_tw_put((struct tcp_tw_bucket*)sk); + tcp_tw_put((struct tcp_tw_bucket*)nsk); return NULL; } diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 263795d7b2c3..163dc0bdca38 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -2637,3 +2637,4 @@ static void __exit ipx_proto_finito(void) } module_exit(ipx_proto_finito); +MODULE_LICENSE("GPL"); diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index f9fe554430c5..358637933205 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -2571,6 +2571,7 @@ module_exit(irda_proto_cleanup); MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem"); +MODULE_LICENSE("GPL"); #ifdef CONFIG_IRDA_DEBUG MODULE_PARM(irda_debug, "1l"); #endif diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c index bc791de5fbfd..6346d82488ae 100644 --- a/net/irda/ircomm/ircomm_core.c +++ b/net/irda/ircomm/ircomm_core.c @@ -514,6 +514,7 @@ int ircomm_proc_read(char *buf, char **start, off_t offset, int len) #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dag@brattli.net>"); MODULE_DESCRIPTION("IrCOMM protocol"); +MODULE_LICENSE("GPL"); int init_module(void) { diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index eb711c50e36c..7104eb14bb56 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -1363,6 +1363,7 @@ done: #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("IrCOMM serial TTY driver"); +MODULE_LICENSE("GPL"); int init_module(void) { diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index 6afae7405793..18ca9dbdae73 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c @@ -1184,6 +1184,7 @@ void irlan_mod_dec_use_count(void) MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("The Linux IrDA LAN protocol"); +MODULE_LICENSE("GPL"); MODULE_PARM(eth, "i"); MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)"); diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index cc27e20aa5f8..8a8f9aad845a 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c @@ -14,6 +14,7 @@ */ #include "irnet_ppp.h" /* Private header */ +#include <linux/module.h> /************************* CONTROL CHANNEL *************************/ /* @@ -1095,3 +1096,4 @@ cleanup_module(void) return ppp_irnet_cleanup(); } #endif /* MODULE */ +MODULE_LICENSE("GPL"); diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 31dedf1eaae7..3bd3dfcc2762 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -383,3 +383,4 @@ void cleanup_module(void) unregister_tcf_proto_ops(&cls_fw_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 60cdf0ea6999..1bde988d391f 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -638,3 +638,4 @@ void cleanup_module(void) unregister_tcf_proto_ops(&cls_route4_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/cls_rsvp.c b/net/sched/cls_rsvp.c index 8388aee4c019..05a937b59032 100644 --- a/net/sched/cls_rsvp.c +++ b/net/sched/cls_rsvp.c @@ -39,3 +39,4 @@ #define RSVP_OPS cls_rsvp_ops #include "cls_rsvp.h" +MODULE_LICENSE("GPL"); diff --git a/net/sched/cls_rsvp6.c b/net/sched/cls_rsvp6.c index 0699602134ce..85ed7b400bb4 100644 --- a/net/sched/cls_rsvp6.c +++ b/net/sched/cls_rsvp6.c @@ -40,3 +40,4 @@ #define RSVP_OPS cls_rsvp6_ops #include "cls_rsvp.h" +MODULE_LICENSE("GPL"); diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 750eb46722db..babb9a721dfe 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -515,3 +515,4 @@ void cleanup_module(void) unregister_tcf_proto_ops(&cls_tcindex_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 413cf129d4be..29355b36597b 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -726,3 +726,4 @@ void cleanup_module(void) unregister_tcf_proto_ops(&cls_u32_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 0ece0280713e..92c44d14cfc9 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -2120,3 +2120,4 @@ void cleanup_module(void) unregister_qdisc(&cbq_qdisc_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_csz.c b/net/sched/sch_csz.c index 2ccb86e590a9..69e410a6fec8 100644 --- a/net/sched/sch_csz.c +++ b/net/sched/sch_csz.c @@ -1069,3 +1069,4 @@ void cleanup_module(void) unregister_qdisc(&csz_qdisc_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 184ca0ac8fda..9990f1cf07d9 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -490,3 +490,4 @@ void cleanup_module(void) unregister_qdisc(&dsmark_qdisc_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 0f03ba4e1ed8..dba5b1aeaecf 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -632,3 +632,4 @@ void cleanup_module(void) unregister_qdisc(&gred_qdisc_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index 6caff3849ba7..91e6bb9058ce 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c @@ -392,3 +392,4 @@ void cleanup_module(void) unregister_qdisc(&ingress_qdisc_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 015cab96b485..71ec89664e32 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -421,3 +421,4 @@ void cleanup_module(void) } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index e377e0e0f29f..3cfa114796d5 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -497,3 +497,4 @@ void cleanup_module(void) unregister_qdisc(&red_qdisc_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index c9a4bea68710..c2df11f156b1 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -496,3 +496,4 @@ void cleanup_module(void) unregister_qdisc(&sfq_qdisc_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index dde3d0ddf28f..9faf302a17e2 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -427,3 +427,4 @@ void cleanup_module(void) unregister_qdisc(&tbf_qdisc_ops); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 1b7119ffd340..7bc13e30ced7 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -493,3 +493,4 @@ void cleanup_module(void) rtnl_unlock(); } #endif +MODULE_LICENSE("GPL"); diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 2308dc9b0a58..3aabeff42924 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -772,8 +772,8 @@ rpc_allocate(unsigned int flags, unsigned int size) } if (flags & RPC_TASK_ASYNC) return NULL; - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ>>4); + current->policy |= SCHED_YIELD; + schedule(); } while (!signalled()); return NULL; @@ -1116,8 +1116,8 @@ rpciod_killall(void) __rpc_schedule(); if (all_tasks) { dprintk("rpciod_killall: waiting for tasks to exit\n"); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + current->policy |= SCHED_YIELD; + schedule(); } } @@ -1187,8 +1187,8 @@ rpciod_down(void) * wait briefly before checking the process id. */ current->sigpending = 0; - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + current->policy |= SCHED_YIELD; + schedule(); /* * Display a message if we're going to wait longer. */ diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 4e7c18517d4d..4140d3ffbf2d 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -95,7 +95,7 @@ xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen) if ((len = ntohl(*p++)) > maxlen) return NULL; *lenp = len; - *sp = p; + *sp = (char *) p; return p + XDR_QUADLEN(len); } diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c index cd5ef990f5a3..5170a3cc94e5 100644 --- a/net/wanrouter/af_wanpipe.c +++ b/net/wanrouter/af_wanpipe.c @@ -2763,3 +2763,4 @@ int init_module(void) return 0; } #endif +MODULE_LICENSE("GPL"); diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 1f9a4bdf3a25..62bdaca17dce 100644 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -31,6 +31,12 @@ use strict; # Return error code. # Keith Owens <kaos@ocs.com.au> +# 23/09/2001 - Added support for typedefs, structs, enums and unions +# Support for Context section; can be terminated using empty line +# Small fixes (like spaces vs. \s in regex) +# -- Tim Jansen <tim@tjansen.de> + + # # This will read a 'c' file and scan for embedded comments in the # style of gnome comments (+minor extensions - see below). @@ -95,7 +101,48 @@ use strict; # */ # etc. # -# All descriptions can be multiline, apart from the short function description. +# Beside functions you can also write documentation for structs, unions, +# enums and typedefs. Instead of the function name you must write the name +# of the declaration; the struct/union/enum/typedef must always precede +# the name. Nesting of declarations is not supported. +# Use the argument mechanism to document members or constants. In +# structs and unions you must declare one member per declaration +# (comma-separated members are not allowed - the parser does not support +# this). +# e.g. +# /** +# * struct my_struct - short description +# * @a: first member +# * @b: second member +# * +# * Longer description +# */ +# struct my_struct { +# int a; +# int b; +# }; +# +# All descriptions can be multiline, except the short function description. +# +# You can also add additional sections. When documenting kernel functions you +# should document the "Context:" of the function, e.g. whether the functions +# can be called form interrupts. Unlike other sections you can end it with an +# empty line. +# Example-sections should contain the string EXAMPLE so that they are marked +# appropriately in DocBook. +# +# Example: +# /** +# * user_function - function that can only be called in user context +# * @a: some argument +# * Context: !in_interrupt() +# * +# * Some description +# * Example: +# * user_function(22); +# */ +# ... +# # # All descriptive text is further processed, scanning for the following special # patterns, which are highlighted appropriately. @@ -115,7 +162,6 @@ my $type_param = '\@(\w+)'; my $type_struct = '\&((struct\s*)?[_\w]+)'; my $type_env = '(\$\w+)'; - # Output conversion substitutions. # One for each output format @@ -177,14 +223,18 @@ my %highlights = %highlights_man; my $blankline = $blankline_man; my $modulename = "Kernel API"; my $function_only = 0; +my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', + 'November', 'December')[(localtime)[4]] . + " " . ((localtime)[5]+1900); # Essentially these are globals # They probably want to be tidied up made more localised or summat. # CAVEAT EMPTOR! Some of the others I localised may not want to be which # could cause "use of undefined value" or other bugs. -my ($function, %function_table,%parametertypes,$function_purpose); -my ($type,$file,$function_name,$return_type); -my ($newsection,$newcontents,$prototype,$filelist); +my ($function, %function_table,%parametertypes,$declaration_purpose); +my ($type,$file,$declaration_name,$return_type); +my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map); my $lineprefix=""; @@ -193,28 +243,38 @@ my $lineprefix=""; # 1 - looking for function name # 2 - scanning field start. # 3 - scanning prototype. -my $state = 0; +# 4 - documentation block +my $state; + +#declaration types: can be +# 'function', 'struct', 'union', 'enum', 'typedef' +my $decl_type; + my $doc_special = "\@\%\$\&"; -my $doc_start = "^/\\*\\*\$"; -my $doc_end = "\\*/"; -my $doc_com = "\\s*\\*\\s*"; -my $doc_func = $doc_com."(\\w+):?"; -my $doc_sect = $doc_com."([".$doc_special."]?[\\w ]+):(.*)"; -my $doc_content = $doc_com."(.*)"; -my $doc_block = $doc_com."DOC:\\s*(.*)?"; - -my %constants = (); -my %parameters = (); -my @parameterlist = (); -my %sections = (); -my @sectionlist = (); -my %source_map = (); +my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. +my $doc_end = '\*/'; +my $doc_com = '\s*\*\s*'; +my $doc_decl = $doc_com.'(\w+)'; +my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)'; +my $doc_content = $doc_com.'(.*)'; +my $doc_block = $doc_com.'DOC:\s*(.*)?'; + +my %constants; +my %parameterdescs; +my @parameterlist; +my %sections; +my @sectionlist; my $contents = ""; my $section_default = "Description"; # default section my $section_intro = "Introduction"; my $section = $section_default; +my $section_context = "Context"; + +my $undescribed = "-- undescribed --"; + +reset_state(); while ($ARGV[0] =~ m/^-(.*)/) { my $cmd = shift @ARGV; @@ -280,7 +340,7 @@ sub dump_section { } elsif ($name =~ m/$type_param/) { # print STDERR "parameter def '$1' = '$contents'\n"; $name = $1; - $parameters{$name} = $contents; + $parameterdescs{$name} = $contents; } else { # print STDERR "other section '$name' = '$contents'\n"; $sections{$name} = $contents; @@ -291,28 +351,28 @@ sub dump_section { ## # output function # -# parameters, a hash. +# parameterdescs, a hash. # function => "function name" # parameterlist => @list of parameters -# parameters => %parameter descriptions +# parameterdescs => %parameter descriptions # sectionlist => @list of sections # sections => %descriont descriptions # -sub output_highlight(@) { +sub output_highlight { my $contents = join "\n",@_; my $line; -# DEBUG -# if (!defined $contents) { -# use Carp; -# confess "output_highlight got called with no args?\n"; -# } +# DEBUG +# if (!defined $contents) { +# use Carp; +# confess "output_highlight got called with no args?\n"; +# } eval $dohighlight; die $@ if $@; foreach $line (split "\n", $contents) { - if ($line eq ""){ + if ($line eq ""){ print $lineprefix, $blankline; } else { $line =~ s/\\\\\\/\&/g; @@ -322,9 +382,98 @@ sub output_highlight(@) { } } +#output sections in html +sub output_section_html(%) { + my %args = %{$_[0]}; + my $section; + + foreach $section (@{$args{'sectionlist'}}) { + print "<h3>$section</h3>\n"; + print "<blockquote>\n"; + output_highlight($args{'sections'}{$section}); + print "</blockquote>\n"; + } +} + +# output enum in html +sub output_enum_html(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + print "<h2>enum ".$args{'enum'}."</h2>\n"; + + print "<b>enum ".$args{'enum'}."</b> {<br>\n"; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print " <b>".$parameter."</b>"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ",\n"; + } + print "<br>"; + } + print "};<br>\n"; + + print "<h3>Constants</h3>\n"; + print "<dl>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print "<dt><b>".$parameter."</b>\n"; + print "<dd>"; + output_highlight($args{'parameterdescs'}{$parameter}); + } + print "</dl>\n"; + output_section_html(@_); + print "<hr>\n"; +} + +# output tyepdef in html +sub output_typedef_html(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + print "<h2>typedef ".$args{'typedef'}."</h2>\n"; + + print "<b>typedef ".$args{'typedef'}."</b>\n"; + output_section_html(@_); + print "<hr>\n"; +} + +# output struct in html +sub output_struct_html(%) { + my %args = %{$_[0]}; + my ($parameter); -# output in html -sub output_html(%) { + print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>\n"; + print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n"; + } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + print " <i>$1</i> <b>$parameter</b>$2;<br>\n"; + } else { + print " <i>$type</i> <b>$parameter</b>;<br>\n"; + } + } + print "};<br>\n"; + + print "<h3>Members</h3>\n"; + print "<dl>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print "<dt><b>".$parameter."</b>\n"; + print "<dd>"; + output_highlight($args{'parameterdescs'}{$parameter}); + } + print "</dl>\n"; + output_section_html(@_); + print "<hr>\n"; +} + +# output function in html +sub output_function_html(%) { my %args = %{$_[0]}; my ($parameter, $section); my $count; @@ -352,22 +501,17 @@ sub output_html(%) { print "<h3>Arguments</h3>\n"; print "<dl>\n"; foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; print "<dt><b>".$parameter."</b>\n"; print "<dd>"; - output_highlight($args{'parameters'}{$parameter}); + output_highlight($args{'parameterdescs'}{$parameter}); } print "</dl>\n"; - foreach $section (@{$args{'sectionlist'}}) { - print "<h3>$section</h3>\n"; - print "<blockquote>\n"; - output_highlight($args{'sections'}{$section}); - print "</blockquote>\n"; - } + output_section_html(@_); print "<hr>\n"; } - -# output in html +# output intro in html sub output_intro_html(%) { my %args = %{$_[0]}; my ($parameter, $section); @@ -382,8 +526,26 @@ sub output_intro_html(%) { print "<hr>\n"; } -# output in sgml DocBook -sub output_sgml(%) { +sub output_section_sgml(%) { + my %args = %{$_[0]}; + my $section; + # print out each section + $lineprefix=" "; + foreach $section (@{$args{'sectionlist'}}) { + print "<refsect1>\n <title>$section</title>\n <para>\n"; + if ($section =~ m/EXAMPLE/i) { + print "<example><para>\n"; + } + output_highlight($args{'sections'}{$section}); + if ($section =~ m/EXAMPLE/i) { + print "</para></example>\n"; + } + print " </para>\n</refsect1>\n"; + } +} + +# output function in sgml DocBook +sub output_function_sgml(%) { my %args = %{$_[0]}; my ($parameter, $section); my $count; @@ -406,10 +568,9 @@ sub output_sgml(%) { print "<refsynopsisdiv>\n"; print " <title>Synopsis</title>\n"; - print " <funcsynopsis>\n"; + print " <funcsynopsis><funcprototype>\n"; print " <funcdef>".$args{'functiontype'}." "; - print "<function>".$args{'function'}." "; - print "</function></funcdef>\n"; + print "<function>".$args{'function'}." </function></funcdef>\n"; $count = 0; if ($#{$args{'parameterlist'}} >= 0) { @@ -438,7 +599,7 @@ sub output_sgml(%) { print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n"; print " <listitem>\n <para>\n"; $lineprefix=" "; - output_highlight($args{'parameters'}{$parameter}); + output_highlight($args{'parameterdescs'}{$parameter}); print " </para>\n </listitem>\n </varlistentry>\n"; } print " </variablelist>\n"; @@ -447,19 +608,157 @@ sub output_sgml(%) { } print "</refsect1>\n"; - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - print "<refsect1>\n <title>$section</title>\n <para>\n"; - if ($section =~ m/EXAMPLE/i) { - print "<example><para>\n"; - } - output_highlight($args{'sections'}{$section}); - if ($section =~ m/EXAMPLE/i) { - print "</para></example>\n"; + output_section_sgml(@_); + print "</refentry>\n\n"; +} + +# output struct in sgml DocBook +sub output_struct_sgml(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $id; + + $id = "API-struct-".$args{'struct'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "<refentry>\n"; + print "<refmeta>\n"; + print "<refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n"; + print "</refmeta>\n"; + print "<refnamediv>\n"; + print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n"; + print " <refpurpose>\n"; + print " "; + output_highlight ($args{'purpose'}); + print " </refpurpose>\n"; + print "</refnamediv>\n"; + + print "<refsynopsisdiv>\n"; + print " <title>Synopsis</title>\n"; + print " <programlisting>\n"; + print $args{'type'}." ".$args{'struct'}." {\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print " $1 $parameter ($2);\n"; + } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + print " $1 $parameter$2;\n"; + } else { + print " ".$type." ".$parameter.";\n"; } - print " </para>\n</refsect1>\n"; } + print "};"; + print " </programlisting>\n"; + print "</refsynopsisdiv>\n"; + + print " <refsect1>\n"; + print " <title>Members</title>\n"; + + print " <variablelist>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print " <varlistentry>"; + print " <term>$parameter</term>\n"; + print " <listitem><para>\n"; + output_highlight($args{'parameterdescs'}{$parameter}); + print " </para></listitem>\n"; + print " </varlistentry>\n"; + } + print " </variablelist>\n"; + print " </refsect1>\n"; + + output_section_sgml(@_); + + print "</refentry>\n\n"; +} + +# output enum in sgml DocBook +sub output_enum_sgml(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + my $id; + + $id = "API-enum-".$args{'enum'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "<refentry>\n"; + print "<refmeta>\n"; + print "<refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n"; + print "</refmeta>\n"; + print "<refnamediv>\n"; + print " <refname>enum ".$args{'enum'}."</refname>\n"; + print " <refpurpose>\n"; + print " "; + output_highlight ($args{'purpose'}); + print " </refpurpose>\n"; + print "</refnamediv>\n"; + + print "<refsynopsisdiv>\n"; + print " <title>Synopsis</title>\n"; + print " <programlisting>\n"; + print "enum ".$args{'enum'}." {\n"; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print " $parameter"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ","; + } + print "\n"; + } + print "};"; + print " </programlisting>\n"; + print "</refsynopsisdiv>\n"; + + print "<refsect1>\n"; + print " <title>Constants</title>\n"; + print " <variablelist>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print " <varlistentry>"; + print " <term>$parameter</term>\n"; + print " <listitem><para>\n"; + output_highlight($args{'parameterdescs'}{$parameter}); + print " </para></listitem>\n"; + print " </varlistentry>\n"; + } + print " </variablelist>\n"; + print "</refsect1>\n"; + + output_section_sgml(@_); + + print "</refentry>\n\n"; +} + +# output typedef in sgml DocBook +sub output_typedef_sgml(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $id; + + $id = "API-typedef-".$args{'typedef'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "<refentry>\n"; + print "<refmeta>\n"; + print "<refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n"; + print "</refmeta>\n"; + print "<refnamediv>\n"; + print " <refname>typedef ".$args{'typedef'}."</refname>\n"; + print " <refpurpose>\n"; + print " "; + output_highlight ($args{'purpose'}); + print " </refpurpose>\n"; + print "</refnamediv>\n"; + + print "<refsynopsisdiv>\n"; + print " <title>Synopsis</title>\n"; + print " <synopsis>typedef ".$args{'typedef'}.";</synopsis>\n"; + print "</refsynopsisdiv>\n"; + + output_section_sgml(@_); print "</refentry>\n\n"; } @@ -491,7 +790,7 @@ sub output_intro_sgml(%) { } # output in sgml DocBook -sub output_gnome { +sub output_function_gnome { my %args = %{$_[0]}; my ($parameter, $section); my $count; @@ -535,7 +834,7 @@ sub output_gnome { print " <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n"; print " <entry>\n"; $lineprefix=" "; - output_highlight($args{'parameters'}{$parameter}); + output_highlight($args{'parameterdescs'}{$parameter}); print " </entry></row>\n"; } print " </tbody></tgroup></informaltable>\n"; @@ -565,13 +864,13 @@ sub output_gnome { } ## -# output in man -sub output_man(%) { +# output function in man +sub output_function_man(%) { my %args = %{$_[0]}; my ($parameter, $section); my $count; - print ".TH \"$args{'module'}\" 9 \"$args{'function'}\" \"April 2001\" \"API Manual\" LINUX\n"; + print ".TH \"$args{'module'}\" 9 \"$args{'function'}\" \"$man_date\" \"API Manual\" LINUX\n"; print ".SH NAME\n"; print $args{'function'}." \\- ".$args{'purpose'}."\n"; @@ -600,7 +899,88 @@ sub output_man(%) { print ".SH Arguments\n"; foreach $parameter (@{$args{'parameterlist'}}) { print ".IP \"".$parameter."\" 12\n"; - output_highlight($args{'parameters'}{$parameter}); + output_highlight($args{'parameterdescs'}{$parameter}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output enum in man +sub output_enum_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n"; + + print ".SH NAME\n"; + print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n"; + + print ".SH SYNOPSIS\n"; + print "enum ".$args{'enum'}." {\n"; + $count = 0; + foreach my $parameter (@{$args{'parameterlist'}}) { + print ".br\n.BI \" $parameter\"\n"; + if ($count == $#{$args{'parameterlist'}}) { + print "\n};\n"; + last; + } + else { + print ", \n.br\n"; + } + $count++; + } + + print ".SH Constants\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print ".IP \"".$parameter."\" 12\n"; + output_highlight($args{'parameterdescs'}{$parameter}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output struct in man +sub output_struct_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n"; + + print ".SH NAME\n"; + print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n"; + + print ".SH SYNOPSIS\n"; + print $args{'type'}." ".$args{'struct'}." {\n"; + + foreach my $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print "\n.br\n"; + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print ".BI \" ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n"; + } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + print ".BI \" ".$1."\" ".$parameter.$2." \""."\"\n;\n"; + } else { + $type =~ s/([^\*])$/$1 /; + print ".BI \" ".$type."\" ".$parameter." \""."\"\n;\n"; + } + print "\n.br\n"; + } + print "};\n.br\n"; + + print ".SH Arguments\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print ".IP \"".$parameter."\" 12\n"; + output_highlight($args{'parameterdescs'}{$parameter}); } foreach $section (@{$args{'sectionlist'}}) { print ".SH \"$section\"\n"; @@ -608,12 +988,29 @@ sub output_man(%) { } } +## +# output typedef in man +sub output_typedef_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n"; + + print ".SH NAME\n"; + print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n"; + + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + sub output_intro_man(%) { my %args = %{$_[0]}; my ($parameter, $section); my $count; - print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"April 2001\" \"API Manual\" LINUX\n"; + print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n"; foreach $section (@{$args{'sectionlist'}}) { print ".SH \"$section\"\n"; @@ -623,7 +1020,7 @@ sub output_intro_man(%) { ## # output in text -sub output_text(%) { +sub output_function_text(%) { my %args = %{$_[0]}; my ($parameter, $section); @@ -632,6 +1029,7 @@ sub output_text(%) { print $start; my $count = 0; foreach my $parameter (@{$args{'parameterlist'}}) { + $type = $args{'parametertypes'}{$parameter}; if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { # pointer-to-function print $1.$parameter.") (".$2; @@ -649,15 +1047,94 @@ sub output_text(%) { print "Arguments:\n\n"; foreach $parameter (@{$args{'parameterlist'}}) { - print $parameter."\n\t".$args{'parameters'}{$parameter}."\n"; + print $parameter."\n\t".$args{'parameterdescs'}{$parameter}."\n"; } + output_section_text(@_); +} + +#output sections in text +sub output_section_text(%) { + my %args = %{$_[0]}; + my $section; + + print "\n"; foreach $section (@{$args{'sectionlist'}}) { print "$section:\n\n"; output_highlight($args{'sections'}{$section}); - } + } print "\n\n"; } +# output enum in text +sub output_enum_text(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + print "Enum:\n\n"; + + print "enum ".$args{'enum'}." {\n"; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print "\t$parameter"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ","; + } + print "\n"; + } + print "};\n\n"; + + print "Constants:\n\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print "$parameter\n\t"; + print $args{'parameterdescs'}{$parameter}."\n"; + } + + output_section_text(@_); +} + +# output typedef in text +sub output_typedef_text(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + print "Typedef:\n\n"; + + print "typedef ".$args{'typedef'}."\n"; + output_section_text(@_); +} + +# output struct as text +sub output_struct_text(%) { + my %args = %{$_[0]}; + my ($parameter); + + print $args{'type'}." ".$args{'struct'}.":\n\n"; + print $args{'type'}." ".$args{'struct'}." {\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print "\t$1 $parameter) ($2);\n"; + } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + print "\t$1 $parameter$2;\n"; + } else { + print "\t".$type." ".$parameter.";\n"; + } + } + print "};\n\n"; + + print "Members:\n\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print "$parameter\n\t"; + print $args{'parameterdescs'}{$parameter}."\n"; + } + print "\n"; + output_section_text(@_); +} + sub output_intro_text(%) { my %args = %{$_[0]}; my ($parameter, $section); @@ -670,12 +1147,18 @@ sub output_intro_text(%) { } ## -# generic output function - calls the right one based -# on current output mode. -sub output_function { +# generic output function for typedefs +sub output_declaration { no strict 'refs'; - my $func = "output_".$output_mode; - &$func(@_); + my $name = shift; + my $functype = shift; + my $func = "output_${functype}_$output_mode"; + if (($function_only==0) || + ( $function_only == 1 && defined($function_table{$name})) || + ( $function_only == 2 && !defined($function_table{$name}))) + { + &$func(@_); + } } ## @@ -687,6 +1170,179 @@ sub output_intro { &$func(@_); } +## +# takes a declaration (struct, union, enum, typedef) and +# invokes the right handler. NOT called for functions. +sub dump_declaration($$) { + no strict 'refs'; + my ($prototype, $file) = @_; + my $func = "dump_".$decl_type; + &$func(@_); +} + +sub dump_union($$) { + dump_struct(@_); +} + +sub dump_struct($$) { + my $x = shift; + my $file = shift; + + if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) { + $declaration_name = $2; + my $members = $3; + + # ignore embedded structs or unions + $members =~ s/{.*}//g; + + create_parameterlist($members, ';'); + + output_declaration($declaration_name, + 'struct', + {'struct' => $declaration_name, + 'module' => $modulename, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose, + 'type' => $decl_type + }); + } + else { + print STDERR "Cannot parse struct or union!\n"; + } +} + +sub dump_enum($$) { + my $x = shift; + my $file = shift; + + if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { + $declaration_name = $1; + my $members = $2; + + foreach my $arg (split ',', $members) { + $arg =~ s/^\s*(\w+).*/$1/; + push @parameterlist, $arg; + if (!$parameterdescs{$arg}) { + $parameterdescs{$arg} = $undescribed; + print STDERR "Warning($file:$.): Enum value '$arg' ". + "described in enum '$declaration_name'\n"; + } + + } + + output_declaration($declaration_name, + 'enum', + {'enum' => $declaration_name, + 'module' => $modulename, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } + else { + print STDERR "Cannot parse enum!\n"; + } +} + +sub dump_typedef($$) { + my $x = shift; + my $file = shift; + + while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) { + $x =~ s/\(*.\)\s*;$/;/; + $x =~ s/\[*.\]\s*;$/;/; + } + + if ($x =~ /typedef.*\s+(\w+)\s*;/) { + $declaration_name = $1; + + output_declaration($declaration_name, + 'typedef', + {'typedef' => $declaration_name, + 'module' => $modulename, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } + else { + print STDERR "Cannot parse typedef!\n"; + } +} + +sub create_parameterlist($$) { + my $args = shift; + my $splitter = shift; + my $type; + my $param; + + while ($args =~ /(\([^\),]+),/) { + $args =~ s/(\([^\),]+),/$1#/g; + } + + foreach my $arg (split($splitter, $args)) { + # strip leading/trailing spaces + $arg =~ s/^\s*//; + $arg =~ s/\s*$//; + $arg =~ s/\s+/ /; + + if ($arg =~ m/\(/) { + # pointer-to-function + $arg =~ tr/#/,/; + $arg =~ m/[^\(]+\(\*([^\)]+)\)/; + $param = $1; + $type = $arg; + $type =~ s/([^\(]+\(\*)$param/$1/; + } else { + # evil magic to get fixed array parameters to work + $arg =~ s/(.+\s+)(.+)\[.*/$1* $2/; + my @args = split('\s', $arg); + + $param = pop @args; + if ($param =~ m/^(\*+)(.*)/) { + $param = $2; + push @args, $1; + } + elsif ($param =~ m/(.*?)\s*:\s*(\d+)/) { + $param = $1; + push @args, ":$2"; + } + $type = join " ", @args; + } + + if ($type eq "" && $param eq "...") + { + $type="..."; + $param="..."; + $parameterdescs{"..."} = "variable arguments"; + } + elsif ($type eq "" && ($param eq "" or $param eq "void")) + { + $type=""; + $param="void"; + $parameterdescs{void} = "no arguments"; + } + if (defined $type && $type && !defined $parameterdescs{$param}) { + $parameterdescs{$param} = $undescribed; + + if (($type eq 'function') || ($type eq 'enum')) { + print STDERR "Warning($file:$.): Function parameter ". + "or member '$param' not " . + "described in '$declaration_name'\n"; + } + ++$errors; + } + + push @parameterlist, $param; + $parametertypes{$param} = $type; + } +} ## # takes a function prototype and the name of the current file being @@ -733,122 +1389,30 @@ sub dump_function($$) { $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) { $return_type = $1; - $function_name = $2; + $declaration_name = $2; my $args = $3; - my ($param); - - # allow for up to six args to function pointers - $args =~ s/(\([^\),]+),/$1#/g; - $args =~ s/(\([^\),]+),/$1#/g; - $args =~ s/(\([^\),]+),/$1#/g; - $args =~ s/(\([^\),]+),/$1#/g; - $args =~ s/(\([^\),]+),/$1#/g; -# print STDERR "ARGS = '$args'\n"; - - foreach my $arg (split ',', $args) { - # strip leading/trailing spaces - $arg =~ s/^\s*//; - $arg =~ s/\s*$//; - - if ($arg =~ m/\(/) { - # pointer-to-function - $arg =~ tr/#/,/; - $arg =~ m/[^\(]+\(\*([^\)]+)\)/; - $param = $1; - $type = $arg; - $type =~ s/([^\(]+\(\*)$param/$1/; - } else { - # evil magic to get fixed array parameters to work - $arg =~ s/(.+\s+)(.+)\[.*/$1* $2/; -# print STDERR "SCAN ARG: '$arg'\n"; - my @args = split('\s', $arg); - -# print STDERR " -> @args\n"; - $param = pop @args; -# print STDERR " -> @args\n"; - if ($param =~ m/^(\*+)(.*)/) { - $param = $2; - push @args, $1; - } - $type = join " ", @args; - } - if ($type eq "" && $param eq "...") - { - $type="..."; - $param="..."; - $parameters{"..."} = "variable arguments"; - } - elsif ($type eq "" && ($param eq "" or $param eq "void")) - { - $type=""; - $param="void"; - $parameters{void} = "no arguments"; - } - if (defined $type && $type && !defined $parameters{$param}) { - $parameters{$param} = "-- undescribed --"; - print STDERR "Warning($file:$.): Function parameter '$param' not described in '$function_name'\n"; - ++$errors; - } - - push @parameterlist, $param; - $parametertypes{$param} = $type; -# print STDERR "param = '$param', type = '$type'\n"; - } + create_parameterlist($args, ','); } else { print STDERR "Error($.): cannot understand prototype: '$prototype'\n"; ++$errors; return; } - if ($function_only==0 || - ( $function_only == 1 && defined($function_table{$function_name})) || - ( $function_only == 2 && !defined($function_table{$function_name}))) - { - output_function({'function' => $function_name, - 'module' => $modulename, - 'functiontype' => $return_type, - 'parameterlist' => \@parameterlist, - 'parameters' => \%parameters, - 'parametertypes' => \%parametertypes, - 'sectionlist' => \@sectionlist, - 'sections' => \%sections, - 'purpose' => $function_purpose - }); - } + output_declaration($declaration_name, + 'function', + {'function' => $declaration_name, + 'module' => $modulename, + 'functiontype' => $return_type, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); } -###################################################################### -# main -# states -# 0 - normal code -# 1 - looking for function name -# 2 - scanning field start. -# 3 - scanning prototype. -$state = 0; -$section = ""; - -$doc_special = "\@\%\$\&"; - -$doc_start = "^/\\*\\*\\s*\$"; # Allow whitespace at end of comment start. -$doc_end = "\\*/"; -$doc_com = "\\s*\\*\\s*"; -$doc_func = $doc_com."(\\w+):?"; -$doc_sect = $doc_com."([".$doc_special."]?[\\w ]+):(.*)"; -$doc_content = $doc_com."(.*)"; -$doc_block = $doc_com."DOC:\\s*(.*)?"; - -%constants = (); -%parameters = (); -@parameterlist = (); -%sections = (); -@sectionlist = (); - -$contents = ""; -$section_default = "Description"; # default section -$section_intro = "Introduction"; -$section = $section_default; - sub process_file($); # Read the file that maps relative names to absolute names for @@ -879,8 +1443,68 @@ foreach (@ARGV) { exit($errors); +sub reset_state { + $function = ""; + %constants = (); + %parameterdescs = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + + $state = 0; +} + +sub process_state3_function($) { + my $x = shift; + + if ($x =~ m#\s*/\*\s+MACDOC\s*#io) { + # do nothing + } + elsif ($x =~ /([^\{]*)/) { + $prototype .= $1; + } + if (($x =~ /\{/) || ($x =~ /\#/) || ($x =~ /;/)) { + $prototype =~ s@/\*.*?\*/@@gos; # strip comments. + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. + $prototype =~ s@^\s+@@gos; # strip leading spaces + dump_function($prototype,$file); + reset_state(); + } +} + +sub process_state3_type($) { + my $x = shift; + + $x =~ s@/\*.*?\*/@@gos; # strip comments. + $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's. + $x =~ s@^\s+@@gos; # strip leading spaces + $x =~ s@\s+$@@gos; # strip trailing spaces + + while (1) { + if ( $x =~ /([^{};]*)([{};])(.*)/ ) { + $prototype .= $1 . $2; + ($2 eq '{') && $brcount++; + ($2 eq '}') && $brcount--; + if (($2 eq ';') && ($brcount == 0)) { + dump_declaration($prototype,$file); + reset_state(); + last; + } + $x = $3; + } else { + $prototype .= $x; + last; + } + } +} + sub process_file($) { my ($file) = @_; + my $identifier; + my $func; + if (defined($source_map{$file})) { $file = $source_map{$file}; } @@ -906,16 +1530,32 @@ sub process_file($) { $section = $1; } } - elsif (/$doc_func/o) { - $function = $1; + elsif (/$doc_decl/o) { + $identifier = $1; + if (/\s*([\w\s]+?)\s*-/) { + $identifier = $1; + } + $state = 2; if (/-(.*)/) { - $function_purpose = $1; + $declaration_purpose = $1; + } else { + $declaration_purpose = ""; + } + if ($identifier =~ m/^struct/) { + $decl_type = 'struct'; + } elsif ($identifier =~ m/^union/) { + $decl_type = 'union'; + } elsif ($identifier =~ m/^enum/) { + $decl_type = 'enum'; + } elsif ($identifier =~ m/^typedef/) { + $decl_type = 'typedef'; } else { - $function_purpose = ""; + $decl_type = 'function'; } + if ($verbose) { - print STDERR "Info($.): Scanning doc for $function\n"; + print STDERR "Info($.): Scanning doc for $identifier\n"; } } else { print STDERR "WARN($.): Cannot understand $_ on line $.", @@ -952,13 +1592,15 @@ sub process_file($) { $contents = ""; } -# print STDERR "end of doc comment, looking for prototype\n"; $prototype = ""; $state = 3; + $brcount = 0; +# print STDERR "end of doc comment, looking for prototype\n"; } elsif (/$doc_content/) { # miguel-style comment kludge, look for blank lines after # @parameter line to signify start of description - if ($1 eq "" && $section =~ m/^@/) { + if ($1 eq "" && + ($section =~ m/^@/ || $section eq $section_context)) { $contents =~ s/\&/\\\\\\amp;/g; $contents =~ s/\</\\\\\\lt;/g; $contents =~ s/\>/\\\\\\gt;/g; @@ -974,28 +1616,10 @@ sub process_file($) { ++$errors; } } elsif ($state == 3) { # scanning for function { (end of prototype) - if (m#\s*/\*\s+MACDOC\s*#io) { - # do nothing - } - elsif (/([^\{]*)/) { - $prototype .= $1; - } - if (/\{/ || /\#/ || /;/) { # added for #define AK, ';' added for declarations. - $prototype =~ s@/\*.*?\*/@@gos; # strip comments. - $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. - $prototype =~ s@^ +@@gos; # strip leading spaces - dump_function($prototype,$file); - - $function = ""; - %constants = (); - %parameters = (); - %parametertypes = (); - @parameterlist = (); - %sections = (); - @sectionlist = (); - $prototype = ""; - - $state = 0; + if ($decl_type eq 'function') { + process_state3_function($_); + } else { + process_state3_type($_); } } elsif ($state == 4) { # Documentation block @@ -1006,7 +1630,7 @@ sub process_file($) { $contents = ""; $function = ""; %constants = (); - %parameters = (); + %parameterdescs = (); %parametertypes = (); @parameterlist = (); %sections = (); @@ -1026,7 +1650,7 @@ sub process_file($) { $contents = ""; $function = ""; %constants = (); - %parameters = (); + %parameterdescs = (); %parametertypes = (); @parameterlist = (); %sections = (); |
