diff -u --recursive --new-file v1.1.47/linux/CREDITS linux/CREDITS --- v1.1.47/linux/CREDITS Sun Aug 21 17:48:23 1994 +++ linux/CREDITS Wed Aug 24 14:58:30 1994 @@ -228,6 +228,13 @@ S: Great Baddow, Essex CM2 8HN S: UK +N: Michael Hipp +E: mhipp@student.uni-tuebingen.de +D: drivers for the racal ni5210 & ni6510 ethernet-boards +S: Talstr. 1 +S: D - 72072 Tuebingen +S: Germany + N: Dirk Hohndel E: hohndel@informatik.uni-wuerzburg.de D: XFree86 diff -u --recursive --new-file v1.1.47/linux/Makefile linux/Makefile --- v1.1.47/linux/Makefile Mon Aug 22 21:57:52 1994 +++ linux/Makefile Thu Aug 25 09:15:27 1994 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 47 +SUBLEVEL = 48 ARCH = i386 @@ -110,8 +110,11 @@ include/asm: ( cd include ; ln -sf asm-$(ARCH) asm) -symlinks: boot include/asm +kernel/entry.S: + ln -sf ../arch/$(ARCH)/entry.S kernel/entry.S +symlinks: boot include/asm kernel/entry.S + config.in: arch/$(ARCH)/config.in cp $< $@ @@ -183,7 +186,7 @@ rm -f include/linux/autoconf.h tools/version.h rm -f drivers/sound/local.h rm -f .version .config* config.in config.old - rm -f boot include/asm + rm -f boot include/asm kernel/entry.S rm -f .depend `find . -name .depend -print` distclean: mrproper diff -u --recursive --new-file v1.1.47/linux/arch/i386/config.in linux/arch/i386/config.in --- v1.1.47/linux/arch/i386/config.in Sun Aug 21 17:48:24 1994 +++ linux/arch/i386/config.in Wed Aug 24 14:58:47 1994 @@ -108,6 +108,8 @@ if [ "$CONFIG_NET_ALPHA" = "y" ]; then bool 'EtherExpress support' CONFIG_EEXPRESS n bool 'AT1700 support' CONFIG_AT1700 n + bool 'NI5210 support' CONFIG_NI52 n + bool 'NI6510 support' CONFIG_NI65 n fi bool 'HP PCLAN support' CONFIG_HPLAN n bool 'NE2000/NE1000 support' CONFIG_NE2000 y @@ -118,8 +120,6 @@ bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n fi bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n -#bool 'NI52EE support' CONFIG_NI52 n -#bool 'NI65EE support' CONFIG_NI65 n bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n if [ "$CONFIG_NET_POCKET" = "y" ]; then bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n diff -u --recursive --new-file v1.1.47/linux/arch/i386/entry.S linux/arch/i386/entry.S --- v1.1.47/linux/arch/i386/entry.S Thu Jan 1 02:00:00 1970 +++ linux/arch/i386/entry.S Tue Aug 23 10:12:03 1994 @@ -0,0 +1,545 @@ +/* + * linux/arch/i386/entry.S + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* + * entry.S contains the system-call and fault low-level handling routines. + * This also contains the timer-interrupt handler, as well as all interrupts + * and faults that can result in a task-switch. + * + * NOTE: This code handles signal-recognition, which happens every time + * after a timer-interrupt and after each system call. + * + * I changed all the .align's to 4 (16 byte alignment), as that's faster + * on a 486. + * + * Stack layout in 'ret_from_system_call': + * ptrace needs to have all regs on the stack. + * if the order here is changed, it needs to be + * updated in fork.c:copy_process, signal.c:do_signal, + * ptrace.c and ptrace.h + * + * 0(%esp) - %ebx + * 4(%esp) - %ecx + * 8(%esp) - %edx + * C(%esp) - %esi + * 10(%esp) - %edi + * 14(%esp) - %ebp + * 18(%esp) - %eax + * 1C(%esp) - %ds + * 20(%esp) - %es + * 24(%esp) - %fs + * 28(%esp) - %gs + * 2C(%esp) - orig_eax + * 30(%esp) - %eip + * 34(%esp) - %cs + * 38(%esp) - %eflags + * 3C(%esp) - %oldesp + * 40(%esp) - %oldss + */ + +#include +#include + +EBX = 0x00 +ECX = 0x04 +EDX = 0x08 +ESI = 0x0C +EDI = 0x10 +EBP = 0x14 +EAX = 0x18 +DS = 0x1C +ES = 0x20 +FS = 0x24 +GS = 0x28 +ORIG_EAX = 0x2C +EIP = 0x30 +CS = 0x34 +EFLAGS = 0x38 +OLDESP = 0x3C +OLDSS = 0x40 + +CF_MASK = 0x00000001 +IF_MASK = 0x00000200 +NT_MASK = 0x00004000 +VM_MASK = 0x00020000 + +/* + * these are offsets into the task-struct. + */ +state = 0 +counter = 4 +priority = 8 +signal = 12 +blocked = 16 +flags = 20 +errno = 24 +dbgreg6 = 52 +dbgreg7 = 56 +exec_domain = 60 + +ENOSYS = 38 + +.globl _system_call,_lcall7 +.globl _device_not_available, _coprocessor_error +.globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op +.globl _double_fault,_coprocessor_segment_overrun +.globl _invalid_TSS,_segment_not_present,_stack_segment +.globl _general_protection,_reserved +.globl _alignment_check,_page_fault +.globl ret_from_sys_call, _sys_call_table + +#define SAVE_ALL \ + cld; \ + push %gs; \ + push %fs; \ + push %es; \ + push %ds; \ + pushl %eax; \ + pushl %ebp; \ + pushl %edi; \ + pushl %esi; \ + pushl %edx; \ + pushl %ecx; \ + pushl %ebx; \ + movl $(KERNEL_DS),%edx; \ + mov %dx,%ds; \ + mov %dx,%es; \ + movl $(USER_DS),%edx; \ + mov %dx,%fs; + +#define RESTORE_ALL \ + cmpw $(KERNEL_CS),CS(%esp); \ + je 1f; \ + movl _current,%eax; \ + movl dbgreg7(%eax),%ebx; \ + movl %ebx,%db7; \ +1: popl %ebx; \ + popl %ecx; \ + popl %edx; \ + popl %esi; \ + popl %edi; \ + popl %ebp; \ + popl %eax; \ + pop %ds; \ + pop %es; \ + pop %fs; \ + pop %gs; \ + addl $4,%esp; \ + iret + +.align 4 +_lcall7: + pushfl # We get a different stack layout with call gates, + pushl %eax # which has to be cleaned up later.. + SAVE_ALL + movl EIP(%esp),%eax # due to call gates, this is eflags, not eip.. + movl CS(%esp),%edx # this is eip.. + movl EFLAGS(%esp),%ecx # and this is cs.. + movl %eax,EFLAGS(%esp) # + movl %edx,EIP(%esp) # Now we move them to their "normal" places + movl %ecx,CS(%esp) # + movl %esp,%eax + movl _current,%edx + pushl %eax + movl exec_domain(%edx),%edx # Get the execution domain + movl 4(%edx),%edx # Get the lcall7 handler for the domain + call *%edx + popl %eax + jmp ret_from_sys_call + +.align 4 +handle_bottom_half: + pushfl + incl _intr_count + sti + call _do_bottom_half + popfl + decl _intr_count + jmp 9f +.align 4 +reschedule: + pushl $ret_from_sys_call + jmp _schedule +.align 4 +_system_call: + pushl %eax # save orig_eax + SAVE_ALL + movl $-ENOSYS,EAX(%esp) + cmpl $(NR_syscalls),%eax + jae ret_from_sys_call + movl _sys_call_table(,%eax,4),%eax + testl %eax,%eax + je ret_from_sys_call + movl _current,%ebx + andl $~CF_MASK,EFLAGS(%esp) # clear carry - assume no errors + movl $0,errno(%ebx) + movl %db6,%edx + movl %edx,dbgreg6(%ebx) # save current hardware debugging status + testb $0x20,flags(%ebx) # PF_TRACESYS + jne 1f + call *%eax + movl %eax,EAX(%esp) # save the return value + movl errno(%ebx),%edx + negl %edx + je ret_from_sys_call + movl %edx,EAX(%esp) + orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error + jmp ret_from_sys_call +.align 4 +1: call _syscall_trace + movl ORIG_EAX(%esp),%eax + call _sys_call_table(,%eax,4) + movl %eax,EAX(%esp) # save the return value + movl _current,%eax + movl errno(%eax),%edx + negl %edx + je 1f + movl %edx,EAX(%esp) + orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error +1: call _syscall_trace + + .align 4,0x90 +ret_from_sys_call: + cmpl $0,_intr_count + jne 2f +9: movl _bh_mask,%eax + andl _bh_active,%eax + jne handle_bottom_half + movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are + testl $(VM_MASK),%eax # different then + jne 1f + cmpw $(KERNEL_CS),CS(%esp) # was old code segment supervisor ? + je 2f +1: sti + orl $(IF_MASK),%eax # these just try to make sure + andl $~NT_MASK,%eax # the program doesn't do anything + movl %eax,EFLAGS(%esp) # stupid + cmpl $0,_need_resched + jne reschedule + movl _current,%eax + cmpl _task,%eax # task[0] cannot have signals + je 2f + cmpl $0,state(%eax) # state + jne reschedule + cmpl $0,counter(%eax) # counter + je reschedule + movl blocked(%eax),%ecx + movl %ecx,%ebx # save blocked in %ebx for signal handling + notl %ecx + andl signal(%eax),%ecx + jne signal_return +2: RESTORE_ALL +.align 4 +signal_return: + movl %esp,%ecx + pushl %ecx + testl $(VM_MASK),EFLAGS(%ecx) + jne v86_signal_return + pushl %ebx + call _do_signal + popl %ebx + popl %ebx + RESTORE_ALL +.align 4 +v86_signal_return: + call _save_v86_state + movl %eax,%esp + pushl %eax + pushl %ebx + call _do_signal + popl %ebx + popl %ebx + RESTORE_ALL + +.align 4 +_divide_error: + pushl $0 # no error code + pushl $_do_divide_error +.align 4,0x90 +error_code: + push %fs + push %es + push %ds + pushl %eax + pushl %ebp + pushl %edi + pushl %esi + pushl %edx + pushl %ecx + pushl %ebx + movl $0,%eax + movl %eax,%db7 # disable hardware debugging... + cld + movl $-1, %eax + xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. ) + xorl %ebx,%ebx # zero ebx + mov %gs,%bx # get the lower order bits of gs + xchgl %ebx, GS(%esp) # get the address and save gs. + pushl %eax # push the error code + lea 4(%esp),%edx + pushl %edx + movl $(KERNEL_DS),%edx + mov %dx,%ds + mov %dx,%es + movl $(USER_DS),%edx + mov %dx,%fs + pushl %eax + movl _current,%eax + movl %db6,%edx + movl %edx,dbgreg6(%eax) # save current hardware debugging status + popl %eax + call *%ebx + addl $8,%esp + jmp ret_from_sys_call + +.align 4 +_coprocessor_error: + pushl $0 + pushl $_do_coprocessor_error + jmp error_code + +.align 4 +_device_not_available: + pushl $-1 # mark this as an int + SAVE_ALL + pushl $ret_from_sys_call + movl %cr0,%eax + testl $0x4,%eax # EM (math emulation bit) + je _math_state_restore + pushl $0 # temporary storage for ORIG_EIP + call _math_emulate + addl $4,%esp + ret + +.align 4 +_debug: + pushl $0 + pushl $_do_debug + jmp error_code + +.align 4 +_nmi: + pushl $0 + pushl $_do_nmi + jmp error_code + +.align 4 +_int3: + pushl $0 + pushl $_do_int3 + jmp error_code + +.align 4 +_overflow: + pushl $0 + pushl $_do_overflow + jmp error_code + +.align 4 +_bounds: + pushl $0 + pushl $_do_bounds + jmp error_code + +.align 4 +_invalid_op: + pushl $0 + pushl $_do_invalid_op + jmp error_code + +.align 4 +_coprocessor_segment_overrun: + pushl $0 + pushl $_do_coprocessor_segment_overrun + jmp error_code + +.align 4 +_reserved: + pushl $0 + pushl $_do_reserved + jmp error_code + +.align 4 +_double_fault: + pushl $_do_double_fault + jmp error_code + +.align 4 +_invalid_TSS: + pushl $_do_invalid_TSS + jmp error_code + +.align 4 +_segment_not_present: + pushl $_do_segment_not_present + jmp error_code + +.align 4 +_stack_segment: + pushl $_do_stack_segment + jmp error_code + +.align 4 +_general_protection: + pushl $_do_general_protection + jmp error_code + +.align 4 +_alignment_check: + pushl $_do_alignment_check + jmp error_code + +.align 4 +_page_fault: + pushl $_do_page_fault + jmp error_code + +.data +.align 4 +_sys_call_table: + .long _sys_setup /* 0 */ + .long _sys_exit + .long _sys_fork + .long _sys_read + .long _sys_write + .long _sys_open /* 5 */ + .long _sys_close + .long _sys_waitpid + .long _sys_creat + .long _sys_link + .long _sys_unlink /* 10 */ + .long _sys_execve + .long _sys_chdir + .long _sys_time + .long _sys_mknod + .long _sys_chmod /* 15 */ + .long _sys_chown + .long _sys_break + .long _sys_stat + .long _sys_lseek + .long _sys_getpid /* 20 */ + .long _sys_mount + .long _sys_umount + .long _sys_setuid + .long _sys_getuid + .long _sys_stime /* 25 */ + .long _sys_ptrace + .long _sys_alarm + .long _sys_fstat + .long _sys_pause + .long _sys_utime /* 30 */ + .long _sys_stty + .long _sys_gtty + .long _sys_access + .long _sys_nice + .long _sys_ftime /* 35 */ + .long _sys_sync + .long _sys_kill + .long _sys_rename + .long _sys_mkdir + .long _sys_rmdir /* 40 */ + .long _sys_dup + .long _sys_pipe + .long _sys_times + .long _sys_prof + .long _sys_brk /* 45 */ + .long _sys_setgid + .long _sys_getgid + .long _sys_signal + .long _sys_geteuid + .long _sys_getegid /* 50 */ + .long _sys_acct + .long _sys_phys + .long _sys_lock + .long _sys_ioctl + .long _sys_fcntl /* 55 */ + .long _sys_mpx + .long _sys_setpgid + .long _sys_ulimit + .long _sys_olduname + .long _sys_umask /* 60 */ + .long _sys_chroot + .long _sys_ustat + .long _sys_dup2 + .long _sys_getppid + .long _sys_getpgrp /* 65 */ + .long _sys_setsid + .long _sys_sigaction + .long _sys_sgetmask + .long _sys_ssetmask + .long _sys_setreuid /* 70 */ + .long _sys_setregid + .long _sys_sigsuspend + .long _sys_sigpending + .long _sys_sethostname + .long _sys_setrlimit /* 75 */ + .long _sys_getrlimit + .long _sys_getrusage + .long _sys_gettimeofday + .long _sys_settimeofday + .long _sys_getgroups /* 80 */ + .long _sys_setgroups + .long _sys_select + .long _sys_symlink + .long _sys_lstat + .long _sys_readlink /* 85 */ + .long _sys_uselib + .long _sys_swapon + .long _sys_reboot + .long _sys_readdir + .long _sys_mmap /* 90 */ + .long _sys_munmap + .long _sys_truncate + .long _sys_ftruncate + .long _sys_fchmod + .long _sys_fchown /* 95 */ + .long _sys_getpriority + .long _sys_setpriority + .long _sys_profil + .long _sys_statfs + .long _sys_fstatfs /* 100 */ + .long _sys_ioperm + .long _sys_socketcall + .long _sys_syslog + .long _sys_setitimer + .long _sys_getitimer /* 105 */ + .long _sys_newstat + .long _sys_newlstat + .long _sys_newfstat + .long _sys_uname + .long _sys_iopl /* 110 */ + .long _sys_vhangup + .long _sys_idle + .long _sys_vm86 + .long _sys_wait4 + .long _sys_swapoff /* 115 */ + .long _sys_sysinfo + .long _sys_ipc + .long _sys_fsync + .long _sys_sigreturn + .long _sys_clone /* 120 */ + .long _sys_setdomainname + .long _sys_newuname + .long _sys_modify_ldt + .long _sys_adjtimex + .long _sys_mprotect /* 125 */ + .long _sys_sigprocmask + .long _sys_create_module + .long _sys_init_module + .long _sys_delete_module + .long _sys_get_kernel_syms /* 130 */ + .long _sys_quotactl + .long _sys_getpgid + .long _sys_fchdir + .long _sys_bdflush + .long _sys_sysfs /* 135 */ + .long _sys_personality + .long 0 /* for afs_syscall */ + .long _sys_setfsuid + .long _sys_setfsgid + .long _sys_llseek /* 140 */ + .space (NR_syscalls-139)*4 + .space (NR_syscalls-140)*4 diff -u --recursive --new-file v1.1.47/linux/drivers/block/cdu31a.c linux/drivers/block/cdu31a.c --- v1.1.47/linux/drivers/block/cdu31a.c Thu Aug 11 20:43:00 1994 +++ linux/drivers/block/cdu31a.c Tue Aug 23 09:48:49 1994 @@ -2035,7 +2035,7 @@ dma_channel = cdu31a_addresses[i].dma_num; if (dma_channel > 0) { - if (request_dma(dma_channel)) + if (request_dma(dma_channel,"cdu31a")) { dma_channel = -1; printk("Unable to grab DMA%d for the CDU31A driver\n", diff -u --recursive --new-file v1.1.47/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v1.1.47/linux/drivers/block/floppy.c Mon Aug 22 21:57:52 1994 +++ linux/drivers/block/floppy.c Thu Aug 25 13:32:39 1994 @@ -280,8 +280,8 @@ { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" }, /* 19 1.74 MB 3.5" */ { 1760,11,2,80,0,0x1C,0x09,0xCF,0x6C,"d880" }, /* 20 880KB 5.25" */ - { 2080,13,2,80,0,0x1C,0x0A,0xCF,0x6C,"D1040" }, /* 21 1.04MB 3.5" */ - { 2240,14,2,80,0,0x1C,0x1A,0xCF,0x6C,"D1120" }, /* 22 1.12MB 3.5" */ + { 2080,13,2,80,0,0x1C,0x01,0xCF,0x6C,"D1040" }, /* 21 1.04MB 3.5" */ + { 2240,14,2,80,0,0x1C,0x19,0xCF,0x6C,"D1120" }, /* 22 1.12MB 3.5" */ { 3200,20,2,80,0,0x1C,0x20,0xCF,0x6C,"h1600" }, /* 23 1.6MB 5.25" */ { 3520,22,2,80,0,0x1C,0x08,0xCF,0x6C,"H1760" }, /* 24 1.76MB 3.5" */ { 3840,24,2,80,0,0x1C,0x18,0xCF,0x6C,"H1920" }, /* 25 1.92MB 3.5" */ @@ -290,7 +290,7 @@ { 7680,48,2,80,0,0x25,0x63,0xCF,0x6C,"E3840" }, /* 28 3.84MB 3.5" */ { 3680,23,2,80,0,0x1C,0x10,0xCF,0x6C,"H1840" }, /* 29 1.84MB 3.5" */ - { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"H800" }, /* 30 800KB 3.5" */ + { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" }, /* 30 800KB 3.5" */ { 3200,20,2,80,0,0x1C,0x00,0xCF,0x6C,"H1600" }, /* 31 1.6MB 3.5" */ }; @@ -2923,7 +2923,8 @@ #if N_FDC > 1 fdc_state[1].address = 0x370; #endif - for(fdc = 0 ; fdc < N_FDC; fdc++){ + for (i = 0 ; i < N_FDC ; i++) { + fdc = i; FDCS->dtr = -1; FDCS->dor = 0; FDCS->reset = 0; @@ -2932,8 +2933,9 @@ } /* initialise drive state */ - for ( current_drive=0; current_drive < N_DRIVE ; current_drive++){ - DRS->flags = 0; + for (i = 0; i < N_DRIVE ; i++) { + current_drive = i; + DRS->flags = FD_VERIFY; DRS->generation = 0; DRS->keep_data = 0; DRS->fd_ref = 0; @@ -2941,7 +2943,8 @@ } floppy_grab_irq_and_dma(); - for(fdc = 0 ; fdc < N_FDC; fdc++){ + for (i = 0 ; i < N_FDC ; i++) { + fdc = i; FDCS->rawcmd = 2; if(user_reset_fdc(-1,FD_RESET_IF_NEEDED)) continue; @@ -2980,7 +2983,7 @@ FLOPPY_IRQ); return -1; } - if (request_dma(FLOPPY_DMA)) { + if (request_dma(FLOPPY_DMA,"floppy")) { printk(DEVICE_NAME ": Unable to grab DMA%d for the floppy driver\n", FLOPPY_DMA); diff -u --recursive --new-file v1.1.47/linux/drivers/block/hd.c linux/drivers/block/hd.c --- v1.1.47/linux/drivers/block/hd.c Mon Aug 22 21:57:52 1994 +++ linux/drivers/block/hd.c Thu Aug 25 10:01:08 1994 @@ -35,6 +35,7 @@ #include #include #include +#include #define REALLY_SLOW_IO #include @@ -234,16 +235,39 @@ static unsigned int mult_count [MAX_HD] = {0,}; /* currently enabled MultMode count */ static struct request WCURRENT; -static void rawstring (char *prefix, unsigned char *s, int n) +static void fixstring(unsigned char *s, int n) { - if (prefix) - printk(prefix); - if (s && *s) { - int i; - for (i=0; i < n && s[i^1] == ' '; ++i); /* skip blanks */ - for (; i < n && s[i^1]; ++i) /* flip bytes */ - if (s[i^1] != ' ' || ((i+1) < n && s[(i+1)^1] != ' ')) - printk("%c",s[i^1]); + int i; + unsigned short *ss = (unsigned short *) s; + + /* convert from big-endian to little-endian */ + for (i = n ; (i -= 2) >= 0 ; ss++) + *ss = (*ss >> 8) | (*ss << 8); + + /* "strnlen()" */ + for (i = 0 ; i < n ; i++) { + if (!s[i]) { + n = i; + break; + } + } + + /* wipe out trailing spaces */ + while (n > 0) { + if (s[n-1] != ' ') + break; + n--; + s[n] = '\0'; + } + + /* wipe out leading spaces */ + if (*s == ' ') { + unsigned char *t = s; + while (n-- && *++s == ' '); + while (n-- >= 0) { + *t++ = *s; + *s++ = '\0'; + } } } @@ -272,15 +296,21 @@ hd_info[dev].head = id.cur_heads; hd_info[dev].sect = id.cur_sectors; } - printk (" hd%c: ", dev+'a'); - rawstring(NULL, id.model, sizeof(id.model)); - printk (", %dMB w/%dKB Cache, CHS=%d/%d/%d, MaxMult=%d\n", - id.cyls*id.heads*id.sectors/2048, id.buf_size/2, - hd_info[dev].cyl, hd_info[dev].head, hd_info[dev].sect, id.max_multsect); + fixstring (id.serial_no, sizeof(id.serial_no)); + fixstring (id.fw_rev, sizeof(id.fw_rev)); + fixstring (id.model, sizeof(id.model)); + printk (" hd%c: %.40s, %dMB w/%dKB Cache, CHS=%d/%d/%d, MaxMult=%d\n", + dev+'a', id.model, id.cyls*id.heads*id.sectors/2048, + id.buf_size/2, hd_info[dev].cyl, hd_info[dev].head, + hd_info[dev].sect, id.max_multsect); /* save drive info for later query via HDIO_GETIDENTITY */ if (NULL != (hd_ident_info[dev] = (struct hd_driveid *)kmalloc(sizeof(id),GFP_ATOMIC))) *hd_ident_info[dev] = id; + /* Quantum drives go weird at this point, so reset them! In */ + /* fact, do a reset in any case in case we changed the geometry */ + special_op[dev] += reset = 1; + /* flush remaining 384 (reserved/undefined) ID bytes: */ insw(HD_DATA,(char *)&id,sizeof(id)/2); insw(HD_DATA,(char *)&id,sizeof(id)/2); @@ -335,7 +365,6 @@ { int i; - printk(KERN_DEBUG "HD-controller reset\n"); outb_p(4,HD_CMD); for(i = 0; i < 1000; i++) nop(); outb(hd_info[0].ctl & 0x0f ,HD_CMD); @@ -361,12 +390,15 @@ } if (++i < NR_HD) { if (unmask_intr[i]) { - printk("hd%c: disabled irq-unmasking\n",i+'a'); - unmask_intr[i] = 0; + unmask_intr[i] = DEFAULT_UNMASK_INTR; + printk("hd%c: reset irq-unmasking to %d\n",i+'a', + DEFAULT_UNMASK_INTR); } if (mult_req[i] || mult_count[i]) { - printk("hd%c: disabled multiple mode\n",i+'a'); - mult_req[i] = mult_count[i] = 0; + mult_count[i] = 0; + mult_req[i] = DEFAULT_MULT_COUNT; + printk("hd%c: reset multiple mode to %d\n",i+'a', + DEFAULT_MULT_COUNT); } hd_out(i,hd_info[i].sect,hd_info[i].sect,hd_info[i].head-1, hd_info[i].cyl,WIN_SPECIFY,&reset_hd); @@ -399,7 +431,7 @@ if (!CURRENT) return; - dev = MINOR(CURRENT->dev) >> 6; + dev = DEVICE_NR(CURRENT->dev); if (++CURRENT->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) { end_request(0); special_op[dev] += recalibrate[dev] = 1; @@ -607,10 +639,9 @@ { DEVICE_INTR = NULL; sti(); - reset = 1; if (!CURRENT) return; - special_op [DEVICE_NR(CURRENT->dev)] ++; + special_op [DEVICE_NR(CURRENT->dev)] += reset = 1; printk(KERN_DEBUG "HD timeout\n"); cli(); if (++CURRENT->errors >= MAX_ERRORS) { @@ -761,7 +792,7 @@ if ((!inode) || (!inode->i_rdev)) return -EINVAL; - dev = MINOR(inode->i_rdev) >> 6; + dev = DEVICE_NR(inode->i_rdev); if (dev >= NR_HD) return -EINVAL; switch (cmd) { @@ -877,7 +908,7 @@ static int hd_open(struct inode * inode, struct file * filp) { int target; - target = DEVICE_NR(MINOR(inode->i_rdev)); + target = DEVICE_NR(inode->i_rdev); while (busy[target]) sleep_on(&busy_wait); @@ -894,7 +925,7 @@ int target; sync_dev(inode->i_rdev); - target = DEVICE_NR(MINOR(inode->i_rdev)); + target = DEVICE_NR(inode->i_rdev); access_count[target]--; } @@ -1073,7 +1104,7 @@ int i; long flags; - target = DEVICE_NR(MINOR(dev)); + target = DEVICE_NR(dev); gdev = &GENDISK_STRUCT; save_flags(flags); diff -u --recursive --new-file v1.1.47/linux/drivers/block/ramdisk.c linux/drivers/block/ramdisk.c --- v1.1.47/linux/drivers/block/ramdisk.c Thu Aug 11 20:43:02 1994 +++ linux/drivers/block/ramdisk.c Thu Aug 25 13:32:57 1994 @@ -189,6 +189,7 @@ printk("Unable to grab floppy IRQ/DMA for loading ramdisk image\n"); return; } + check_disk_change(ROOT_DEV); do_load(); floppy_release_irq_and_dma(); } diff -u --recursive --new-file v1.1.47/linux/drivers/block/xd.c linux/drivers/block/xd.c --- v1.1.47/linux/drivers/block/xd.c Thu Aug 11 20:43:03 1994 +++ linux/drivers/block/xd.c Tue Aug 23 09:48:49 1994 @@ -167,7 +167,7 @@ printk("xd_geninit: drive %d geometry - heads = %d, cylinders = %d, sectors = %d\n",i,xd_info[i].heads,xd_info[i].cylinders,xd_info[i].sectors); if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT harddisk")) { - if (request_dma(xd_dma)) { + if (request_dma(xd_dma,"xd")) { printk("xd_geninit: unable to get DMA%d\n",xd_dma); free_irq(xd_irq); } diff -u --recursive --new-file v1.1.47/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v1.1.47/linux/drivers/char/tpqic02.c Mon Aug 15 11:47:06 1994 +++ linux/drivers/char/tpqic02.c Tue Aug 23 09:48:50 1994 @@ -2840,7 +2840,7 @@ } /* After IRQ, allocate DMA channel */ - if (request_dma(QIC02_TAPE_DMA)) { + if (request_dma(QIC02_TAPE_DMA,"QIC-02")) { printk(TPQIC02_NAME ": can't allocate DMA%d for QIC-02 tape\n", QIC02_TAPE_DMA); free_irq(QIC02_TAPE_IRQ); diff -u --recursive --new-file v1.1.47/linux/drivers/net/lance.c linux/drivers/net/lance.c --- v1.1.47/linux/drivers/net/lance.c Thu Aug 11 20:43:12 1994 +++ linux/drivers/net/lance.c Tue Aug 23 09:48:50 1994 @@ -371,7 +371,7 @@ return -EAGAIN; } - if (request_dma(dev->dma)) { + if (request_dma(dev->dma,"lance")) { free_irq(dev->irq); return -EAGAIN; } diff -u --recursive --new-file v1.1.47/linux/drivers/net/net_init.c linux/drivers/net/net_init.c --- v1.1.47/linux/drivers/net/net_init.c Sun Aug 21 17:48:26 1994 +++ linux/drivers/net/net_init.c Thu Aug 25 14:21:21 1994 @@ -101,7 +101,7 @@ *mem_startp += alloc_size; } else dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL); - memset(dev, 0, sizeof(alloc_size)); + memset(dev, 0, alloc_size); if (sizeof_private) dev->priv = (void *) (dev + 1); dev->name = sizeof_private + (char *)(dev + 1); diff -u --recursive --new-file v1.1.47/linux/drivers/net/ni52.c linux/drivers/net/ni52.c --- v1.1.47/linux/drivers/net/ni52.c Thu Jan 1 02:00:00 1970 +++ linux/drivers/net/ni52.c Wed Aug 24 14:58:48 1994 @@ -0,0 +1,1153 @@ +/* + * net-3-driver for the NI5210 card (i82586 Ethernet chip) + * + * This is an extension to the Linux operating system, and is covered by the + * same Gnu Public License that covers that work. + * + * Alphacode 0.51 (94/08/19) for Linux 1.1.47 (or later) + * Copyrights (c) 1994 by Michael Hipp (mhipp@student.uni-tuebingen.de) + * [feel free to mail ....] + * + * CAN YOU PLEASE REPORT ME YOUR PERFORMANCE EXPERIENCES !!. + * + * autoprobe for: base_addr: 0x300,0x280,0x360,0x320,0x340 + * mem_start: 0xd0000,0xd4000,0xd8000 (8K and 16K) + * + * sources: + * skeleton.c from Donald Becker + * + * I have also done a look in the following sources: (mail me if you need them) + * crynwr-packet-driver by Russ Nelson + * Garret A. Wollman's (fourth) i82586-driver for BSD + * (before getting an i82596 manual, the existing drivers helped + * me a lot to understand this tricky chip.) + * + * Known Bugs: + * The internal sysbus seems to be slow. So we often lose packets because of + * overruns while receiving from a fast remote host. + * This can slow down TCP connections. Maybe the newer ni5210 cards are better. + */ + +/* + * 19.Aug.94: changed request_irq() parameter (MH) + * + * 20.July.94: removed cleanup bugs, removed a 16K-mem-probe-bug (MH) + * + * 19.July.94: lotsa cleanups .. (MH) + * + * 17.July.94: some patches ... verified to run with 1.1.29 (MH) + * + * 4.July.94: patches for Linux 1.1.24 (MH) + * + * 26.March.94: patches for Linux 1.0 and iomem-auto-probe (MH) + * + * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff, too (MH) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ni52.h" + +#define DEBUG /* debug on */ + +/* +#define DEBUG1 +#define DEBUG2 +#define DEBUG3 +*/ + +#define SYSBUSVAL 1 + +#define ni_attn586() {outb(0,dev->base_addr+NI52_ATTENTION);} +#define ni_reset586() {outb(0,dev->base_addr+NI52_RESET);} + +#define make32(ptr16) (p->memtop + (short) (ptr16) ) +#define make24(ptr32) ((char *) (ptr32) - p->base) +#define make16(ptr32) ((unsigned short) ((unsigned long) (ptr32) - (unsigned long) p->memtop )) + +/******************* how to calc the buffers ***************************** + +IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, do also a +--------------- #define ONLY_ONE_XMIT_BUF + btw: it seems, that only the ONLY_ONE_XMIT_BUF Mode is stable + + +sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8; +sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT +sizeof(rfd) = 24; sizeof(rbd) = 12; +sizeof(tbd) = 8; sizeof(transmit_cmd) = 16; +sizeof(nop_cmd) = 8; + +examples: +--------- + +->cfg1: NUM_RECV_FRAMES=16, NUM_RECV_BUFFS=48, RECV_BUFF_SIZE=256, + NUM_XMIT_BUFFS=2 ,XMIT_BUFF_SIZE=1514 + +NUM_RECV_FRAMES * sizeof(rfd) = 384; +NUM_RECV_BUFFS * ( sizeof(rbd) + RECV_BUFF_SIZE) = 12864 +NUM_XMIT_BUFFS * ( sizeof(tbd+transmit_cmd+nop_cmd) + XMIT_BUFF_SIZE) = 3092 +INIT = 36 +-------------------- +16358 (36 bytes left!) + +************************ + +->cfg2: NUM_RECV_FRAMES=9, NUM_RECV_BUFFS=18, RECV_BUFF_SIZE=256, + NUM_XMIT_BUFFS=2 ,XMIT_BUFF_SIZE=1514 + +NUM_RECV_FRAMES * sizeof(rfd) = 216 +NUM_RECV_BUFFS * ( sizeof(rbd) + RECV_BUFF_SIZE) = 4824 +NUM_XMIT_BUFFS * ( sizeof(tbd+transmit_cmd+nop_cmd) + XMIT_BUFF_SIZE) = 3092 +INIT = 36 +------------------ +8180 (24 bytes left!) + +->cfg3: NUM_RECV_FRAMES=7, NUM_RECV_BUFFS=24, RECV_BUFF_SIZE=256, + NUM_XMIT_BUFFS=1, XMIT_BUFF_SIZE=1514 + 168 + 6432 + 1538 + 36 + 16 = 8190 + +***************************************************************************/ + +#if 0 +/* config-1 for 16Kram card */ +# define NUM_RECV_FRAMES 16 /* number of frames to allow for receive */ +# define NUM_RECV_BUFFS 48 /* number of buffers to allocate */ +# define RECV_BUFF_SIZE 256 /* size of each buffer, POWER OF 2 & EVEN*/ +# define XMIT_BUFF_SIZE 1514 /* length of transmit buffer (EVEN) */ +# define NUM_XMIT_BUFFS 2 /* number of Xmit-Buffs */ +#elif 0 +/* config-2 for 8Kram card */ +# define NUM_RECV_FRAMES 9 +# define NUM_RECV_BUFFS 18 +# define RECV_BUFF_SIZE 256 +# define XMIT_BUFF_SIZE 1514 +# define NUM_XMIT_BUFFS 2 +#elif 1 +/* + * config-3 for 8Kram card ___use_this_config____ seems to be stable + */ +# define NUM_RECV_FRAMES 7 +# define NUM_RECV_BUFFS 24 +# define RECV_BUFF_SIZE 256 +# define XMIT_BUFF_SIZE 1514 +# define NUM_XMIT_BUFFS 1 +# define ONLY_ONE_XMIT_BUF +# define NO_NOPCOMMANDS +#elif 0 +/* + * cfg-4 for 16K, ONLY_ONE_XMIT_BUF + */ +# define NUM_RECV_FRAMES 20 +# define NUM_RECV_BUFFS 27 +# define RECV_BUFF_SIZE 512 +# define XMIT_BUFF_SIZE 1514 +# define NUM_XMIT_BUFFS 1 +# define ONLY_ONE_XMIT_BUF +#else +# define NUM_RECV_FRAMES 4 +# define NUM_RECV_BUFFS 4 +# define RECV_BUFF_SIZE 1536 +# define XMIT_BUFF_SIZE 1536 +# define NUM_XMIT_BUFFS 1 +# define ONLY_ONE_XMIT_BUF +# define NO_NOPCOMMANDS +#endif + +#define DELAY(x) {int i=jiffies; \ + if(loops_per_sec == 1) \ + while(i+(x)>jiffies); \ + else \ + __delay((loops_per_sec>>5)*x); \ + } + +extern void autoirq_setup(int waittime); +extern int autoirq_report(int waittime); +extern void *irq2dev_map[16]; + +#ifndef HAVE_PORTRESERVE +#define check_region(ioaddr, size) 0 +#define snarf_region(ioaddr, size); do ; while (0) +#endif + +#define NI52_TOTAL_SIZE 16 +#define NI52_ADDR0 0x02 +#define NI52_ADDR1 0x07 +#define NI52_ADDR2 0x01 + +static int ni52_probe1(struct device *dev,int ioaddr); +static void ni52_interrupt(int reg_ptr); +static int ni52_open(struct device *dev); +static int ni52_close(struct device *dev); +static int ni52_send_packet(struct sk_buff *,struct device *); +static struct enet_statistics *ni52_get_stats(struct device *dev); +static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); + +/* helper-functions */ +static int init586(struct device *dev); +static int check586(struct device *dev,char *where,unsigned size); +static void alloc586(struct device *dev); +static void startrecv586(struct device *dev); +static void *alloc_rfa(struct device *dev,void *ptr); +static void ni52_rcv_int(struct device *dev); +static void ni52_xmt_int(struct device *dev); +static void ni52_rnr_int(struct device *dev); + +struct priv +{ + struct enet_statistics stats; + unsigned long base; + char *memtop,*max_cbuff32,*min_cbuff32,*max_cbuff24; + volatile struct rbd_struct *rbd_last; + volatile struct rfd_struct *rfd_last,*rfd_top,*rfd_first; + volatile struct scp_struct *scp; /* volatile is important */ + volatile struct iscp_struct *iscp; /* volatile is important */ + volatile struct scb_struct *scb; /* volatile is important */ + volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS]; + volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS]; +#ifdef ONLY_ONE_XMIT_BUF + volatile struct nop_cmd_struct *nop_cmds[2]; +#else + volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS]; +#endif + volatile int nop_point; + volatile char *xmit_cbuffs[NUM_XMIT_BUFFS]; + volatile int xmit_count,xmit_last; +}; + + +/********************************************** + * close device + */ + +static int ni52_close(struct device *dev) +{ + free_irq(dev->irq); + irq2dev_map[dev->irq] = 0; + + ni_reset586(); /* the hard way to stop the receiver */ + + dev->start = 0; + dev->tbusy = 0; + + return 0; +} + +/********************************************** + * open device + */ + +static int ni52_open(struct device *dev) +{ + alloc586(dev); + init586(dev); + startrecv586(dev); + + if(request_irq(dev->irq, &ni52_interrupt,0,"ni52")) + { + ni_reset586(); + return -EAGAIN; + } + irq2dev_map[dev->irq] = dev; + + dev->interrupt = 0; + dev->tbusy = 0; + dev->start = 1; + + return 0; /* most done by init */ +} + +/********************************************** + * Check to see if there's an 82586 out there. + */ + +static int check586(struct device *dev,char *where,unsigned size) +{ + struct priv *p = (struct priv *) dev->priv; + char *iscp_addrs[2]; + int i; + + p->base = (unsigned long) where + size - 0x01000000; + p->memtop = where + size; + p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS); + memset((char *)p->scp,0, sizeof(struct scp_struct)); + p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus */ + + iscp_addrs[0] = where; + iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct); + + for(i=0;i<2;i++) + { + p->iscp = (struct iscp_struct *) iscp_addrs[i]; + memset((char *)p->iscp,0, sizeof(struct iscp_struct)); + + p->scp->iscp = make24(p->iscp); + p->iscp->busy = 1; + + ni_reset586(); + ni_attn586(); + DELAY(2); /* wait a while... */ + + if(p->iscp->busy) + return 0; + } + return 1; +} + +/****************************************************************** + * set iscp at the right place, called by ni52_probe1 and open586. + */ + +void alloc586(struct device *dev) +{ + struct priv *p = (struct priv *) dev->priv; + + p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS); + p->scb = (struct scb_struct *) (dev->mem_start); + p->iscp = (struct iscp_struct *) ((char *)p->scp - sizeof(struct iscp_struct)); + + memset((char *) p->iscp,0,sizeof(struct iscp_struct)); + memset((char *) p->scp ,0,sizeof(struct scp_struct)); + + p->scp->iscp = make24(p->iscp); + p->scp->sysbus = SYSBUSVAL; + p->iscp->scb_offset = make16(p->scb); + + p->iscp->busy = 1; + ni_reset586(); + ni_attn586(); + +#ifdef DEBUG + DELAY(2); + + if(p->iscp->busy) + printk("%s: Init-Problems (alloc).\n",dev->name); +#endif + + memset((char *)p->scb,0,sizeof(struct scb_struct)); +} + +/********************************************** + * probe the ni5210-card + */ + +int ni52_probe(struct device *dev) +{ + int *port, ports[] = {0x300, 0x280, 0x360 , 0x320 , 0x340, 0}; + int base_addr = dev->base_addr; + + if (base_addr > 0x1ff) /* Check a single specified location. */ + if( (inb(base_addr+NI52_MAGIC1) == NI52_MAGICVAL1) && + (inb(base_addr+NI52_MAGIC2) == NI52_MAGICVAL2)) + return ni52_probe1(dev, base_addr); + else if (base_addr > 0) /* Don't probe at all. */ + return ENXIO; + + for (port = ports; *port; port++) { + int ioaddr = *port; + if (check_region(ioaddr, NI52_TOTAL_SIZE)) + continue; + if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || + !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2)) + continue; + + dev->base_addr = ioaddr; + if (ni52_probe1(dev, ioaddr) == 0) + return 0; + } + + dev->base_addr = base_addr; + return ENODEV; +} + +static int ni52_probe1(struct device *dev,int ioaddr) +{ + long memaddrs[] = { 0xd0000,0xd2000,0xd4000,0xd6000,0xd8000, 0 }; + int i,size; + + for(i=0;idev_addr[i] = inb(dev->base_addr+i); + + if(dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1 + || dev->dev_addr[2] != NI52_ADDR2) + return ENODEV; + + printk("%s: Ni52 found at %#3x, ",dev->name,dev->base_addr); + + snarf_region(ioaddr,NI52_TOTAL_SIZE); + + dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); + /* warning: we don't free it on errors */ + memset((char *) dev->priv,0,sizeof(struct priv)); + + /* + * check (or search) IO-Memory, 8K and 16K + */ + if(dev->mem_start != 0) /* no auto-mem-probe */ + { + size = 0x4000; + if(!check586(dev,(char *) dev->mem_start,size)) { + size = 0x2000; + if(!check586(dev,(char *) dev->mem_start,size)) { + printk("?memprobe, Can't find memory at 0x%lx!\n",dev->mem_start); + return ENODEV; + } + } + } + else + { + for(i=0;;i++) + { + if(!memaddrs[i]) { + printk("?memprobe, Can't find io-memory!\n"); + return ENODEV; + } + dev->mem_start = memaddrs[i]; + size = 0x2000; + if(check586(dev,(char *)dev->mem_start,size)) /* 8K-check */ + break; + size = 0x4000; + if(check586(dev,(char *)dev->mem_start,size)) /* 16K-check */ + break; + } + } + + ((struct priv *) (dev->priv))->base = dev->mem_start + size - 0x01000000; + alloc586(dev); + + printk("Memaddr: 0x%lx, Memsize: %d, ",dev->mem_start,size); + + if(dev->irq < 2) + { + autoirq_setup(0); + ni_reset586(); + ni_attn586(); + if(!(dev->irq = autoirq_report(2))) + { + printk("?autoirq, Failed to detect IRQ line!\n"); + return 1; + } + } + else if(dev->irq == 2) + dev->irq = 9; + + printk("IRQ %d.\n",dev->irq); + + dev->open = &ni52_open; + dev->stop = &ni52_close; + dev->get_stats = &ni52_get_stats; + dev->hard_start_xmit = &ni52_send_packet; + dev->set_multicast_list = &set_multicast_list; + + dev->if_port = 0; + + ether_setup(dev); + + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 0; + + return 0; +} + +/********************************************** + * init the chip (ni52-interrupt should be disabled?!) + * needs a correct 'allocated' memory + */ + +static int init586(struct device *dev) +{ + void *ptr; + unsigned long s; + int i,result=0; + struct priv *p = (struct priv *) dev->priv; + volatile struct configure_cmd_struct *cfg_cmd; + volatile struct iasetup_cmd_struct *ias_cmd; + volatile struct tdr_cmd_struct *tdr_cmd; + + ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct)); + + cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */ + + cfg_cmd->byte_cnt = 0x04; /* number of cfg bytes */ + cfg_cmd->fifo = 0xc8; /* fifo-limit (8=tx:32/rx:64) | monitor */ + cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */ + cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */ + cfg_cmd->cmd_status = 0; + cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST; + cfg_cmd->cmd_link = 0xffff; + + p->scb->cbl_offset = make16(cfg_cmd); + + p->scb->cmd = CUC_START; /* cmd.-unit start */ + ni_attn586(); + + s = jiffies; /* warning: only active with interrupts on !! */ + while(!(cfg_cmd->cmd_status & STAT_COMPL)) + if(jiffies-s > 30) break; + + if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK)) + { + printk("%s (ni52): configure command failed: %x\n",dev->name,cfg_cmd->cmd_status); + return 1; + } + + /* + * individual address setup + */ + ias_cmd = (struct iasetup_cmd_struct *)ptr; + + ias_cmd->cmd_status = 0; + ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST; + ias_cmd->cmd_link = 0xffff; + + memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN); + + p->scb->cbl_offset = make16(ias_cmd); + + p->scb->cmd = CUC_START; /* cmd.-unit start */ + ni_attn586(); + + s = jiffies; + while(!(ias_cmd->cmd_status & STAT_COMPL)) + if(jiffies-s > 30) break; + + if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) { + printk("%s (ni52): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status); + return 1; + } + + /* + * TDR, wire check .. e.g. no resistor e.t.c + */ + tdr_cmd = (struct tdr_cmd_struct *)ptr; + + tdr_cmd->cmd_status = 0; + tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST; + tdr_cmd->cmd_link = 0xffff; + tdr_cmd->status = 0; + + p->scb->cbl_offset = make16(tdr_cmd); + + p->scb->cmd = CUC_START; /* cmd.-unit start */ + ni_attn586(); + + s = jiffies; + while(!(tdr_cmd->cmd_status & STAT_COMPL)) + if(jiffies - s > 30) { + printk("%s: Problems while running the TDR.\n",dev->name); + result = 1; + } + + if(!result) + { + DELAY(2); /* wait for result */ + result = tdr_cmd->status; + + p->scb->cmd = p->scb->status & STAT_MASK; + ni_attn586(); /* ack the interrupts */ + + if(result & TDR_LNK_OK) ; + else if(result & TDR_XCVR_PRB) + printk("%s: TDR: Transceiver problem!\n",dev->name); + else if(result & TDR_ET_OPN) + printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK); + else if(result & TDR_ET_SRT) + { + if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */ + printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK); + } + else + printk("%s: TDR: Unknown status %04x\n",dev->name,result); + } + + /* + * ack interrupts + */ + p->scb->cmd = p->scb->status & STAT_MASK; + ni_attn586(); + + /* + * alloc nop/xmit-cmds + */ +#ifdef ONLY_ONE_XMIT_BUF + for(i=0;i<2;i++) + { + p->nop_cmds[i] = (struct nop_cmd_struct *)ptr; + p->nop_cmds[i]->cmd_cmd = 0; + p->nop_cmds[i]->cmd_status = 0; + p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); + ptr += sizeof(struct nop_cmd_struct); + } + p->xmit_cmds[0] = (struct transmit_cmd_struct *)ptr; /* transmit cmd/buff 0 */ + ptr += sizeof(struct transmit_cmd_struct); +#else + for(i=0;inop_cmds[i] = (struct nop_cmd_struct *)ptr; + p->nop_cmds[i]->cmd_cmd = 0; + p->nop_cmds[i]->cmd_status = 0; + p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); + ptr += sizeof(struct nop_cmd_struct); + p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /* transmit cmd/buff 0 */ + ptr += sizeof(struct transmit_cmd_struct); + } +#endif + + ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ + + /* + * alloc xmit-buffs + */ + for(i=0;ixmit_cbuffs[i] = (char *)ptr; /* char-buffs */ + ptr += XMIT_BUFF_SIZE; + p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */ + ptr += sizeof(struct tbd_struct); + if((void *)ptr > (void *)p->iscp) + { + printk("%s: not enough shared-mem for your configuration!\n",dev->name); + return 1; + } + memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct)); + memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct)); + p->xmit_cmds[i]->cmd_status = STAT_COMPL; + p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i])); + p->xmit_buffs[i]->next = 0xffff; + p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i])); + } + + p->xmit_count = 0; + p->xmit_last = 0; +#ifndef NO_NOPCOMMANDS + p->nop_point = 0; +#endif + + /* + * 'start transmitter' (nop-loop) + */ +#ifndef NO_NOPCOMMANDS + p->scb->cbl_offset = make16(p->nop_cmds[0]); + p->scb->cmd = CUC_START; + ni_attn586(); + while(p->scb->cmd); +#else +/* + p->nop_cmds[0]->cmd_link = make16(p->nop_cmds[1]); + p->nop_cmds[1]->cmd_link = make16(p->xmit_cmds[0]); +*/ + p->xmit_cmds[0]->cmd_link = 0xffff; + p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT; +#endif + + return 0; +} + +/****************************************************** + * This is a helper routine for ni52_nr_int() and init586(). + * It sets up the Receive Frame Area (RFA). + */ + +static void *alloc_rfa(struct device *dev,void *ptr) +{ + volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr; + volatile struct rbd_struct *rbd; + int i; + struct priv *p = (struct priv *) dev->priv; + + memset((char *) rfd,0,sizeof(struct rfd_struct)*NUM_RECV_FRAMES); + p->rfd_first = rfd; + + for(i = 0; i < NUM_RECV_FRAMES; i++) + rfd[i].next = make16(rfd + (i+1) % NUM_RECV_FRAMES); + rfd[NUM_RECV_FRAMES-1].last = RFD_LAST; /* set EOL (no RU suspend) */ + + ptr = (char *) (rfd + NUM_RECV_FRAMES); + + rbd = (struct rbd_struct *) ptr; + ptr += sizeof(struct rbd_struct)*NUM_RECV_BUFFS; + + /* clr descriptors */ + memset((char *) rbd,0,sizeof(struct rbd_struct)*NUM_RECV_BUFFS); + + p->min_cbuff32 = ptr; + for(i=0;imax_cbuff32 = ptr; + p->max_cbuff24 = make24(p->max_cbuff32); + + p->rfd_top = p->rfd_first; + p->rfd_last = p->rfd_first + NUM_RECV_FRAMES - 1; + + p->rbd_last = rbd + NUM_RECV_BUFFS - 1; + + p->scb->rfa_offset = make16(p->rfd_first); + p->rfd_first->rbd_offset = make16(rbd); + + return ptr; +} + + +/************************************************** + * Interrupt Handler ... + */ + +static void ni52_interrupt(int reg_ptr) +{ + struct device *dev = (struct device *) irq2dev_map[-((struct pt_regs *)reg_ptr)->orig_eax-2]; + unsigned short stat; + int pd = 0; + struct priv *p; + +#ifdef DEBUG2 + printk("(1)"); +#endif + + if (dev == NULL) { + printk ("ni52-interrupt: irq %d for unknown device.\n",(int) -(((struct pt_regs *)reg_ptr)->orig_eax+2)); + return; + } + p = (struct priv *) dev->priv; + + if(dev->interrupt) + { + printk("(ni52-I)"); + return; + } + + dev->interrupt = 1; + + while((stat=p->scb->status & STAT_MASK)) + { + p->scb->cmd = stat; + ni_attn586(); /* ack inter. */ + + if(pd) + printk("ni52-%04x/%04x-",(int) stat,(int) p->scb->status); /* debug */ + + if(stat & (STAT_FR | STAT_RNR)) + ni52_rcv_int(dev); + + if(stat & STAT_CX) + ni52_xmt_int(dev); + +#ifndef NO_NOPCOMMANDS + if(stat & STAT_CNA) +#else + if( (stat & STAT_CNA) && !(stat & STAT_CX) ) +#endif + printk("%s: oops! CU has left active state. stat: %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status); + + if(stat & STAT_RNR) + { + printk("%s: rnr: %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status); + ni52_rnr_int(dev); + pd = 1; /* local debug on */ + } + +#ifdef DEBUG2 + pd++; +#endif + + while(p->scb->cmd) + { + int i; /* wait for ack. (ni52_xmt_int can be faster than ack!!) */ + for(i=0;i<200;i++); + } + } + +#ifdef DEBUG + { + static int old_ovr=0; + int l; + if((l = p->scb->ovrn_errs - old_ovr)) + { + if(l > 0) + p->stats.rx_over_errors += l; + else + old_ovr=0; + } + } +#endif + +#ifdef DEBUG2 + printk("(2)"); +#endif + + dev->interrupt = 0; +} + +/******************************************************* + * receive-interrupt + */ + +static void ni52_rcv_int(struct device *dev) +{ + int status; + unsigned short totlen,pnt; + struct sk_buff *skb; + struct rbd_struct *rbd,*rbd_first; + struct priv *p = (struct priv *) dev->priv; + + for(;(status = p->rfd_top->status) & STAT_COMPL;) + { + rbd = rbd_first = (struct rbd_struct *) make32(p->rfd_top->rbd_offset); + +#ifdef DEBUG1 + { + struct rbd_struct *rbd1 = rbd; + if(rbd1==p->rbd_last) + printk("L"); + printk("S:%04x/%x/%02x >",(int) rbd1->status,(int) rbd1->size>>12,(int)((unsigned long) rbd1 & 0xff)); + rbd1 = (struct rbd_struct *) make32(rbd1->next); + for(;rbd1 != rbd_first;rbd1 = (struct rbd_struct *) make32(rbd1->next)) + { + if(rbd1 == p->rbd_last) + printk("L:"); + printk("%04x/%x-",(int) rbd1->status>>12,(int) rbd1->size>>12); + } + printk("< "); + } + { + struct rfd_struct *rfd1 = p->rfd_top; + if(rfd1==p->rfd_last) + printk("L"); + printk("S:%04x/%x/%02x >",(int) rfd1->status,(int) rfd1->last>>12,(int)((unsigned long) rfd1 & 0xff)); + rfd1 = (struct rfd_struct *) make32(rfd1->next); + for(;rfd1 != p->rfd_top;rfd1 = (struct rfd_struct *) make32(rfd1->next)) + { + if(rfd1 == p->rfd_last) + printk("L:"); + printk("%x/%x-",(int) rfd1->status>>12,(int) rfd1->last>>12); + } + printk("<\n"); + } +#endif + + p->rfd_top->status = 0; + p->rfd_top->last = RFD_LAST; + p->rfd_last->last = 0; /* delete RFD_LAST, no RU suspend */ + p->rfd_last = p->rfd_top; + p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); + + if(status & RFD_ERRMASK) + printk("%s: RFD-Error ... status: %04x.\n",dev->name,status); + + if(status & STAT_OK) + { + for(totlen=0; !(rbd->status & RBD_LAST); rbd=(struct rbd_struct *) make32(rbd->next)) { + totlen += RECV_BUFF_SIZE; + rbd->status = 0; + } + totlen += rbd->status & RBD_MASK; + rbd->status = 0; + + skb = (struct sk_buff *) alloc_skb(totlen, GFP_ATOMIC); + + if (skb != NULL) /* copy header */ + { + skb->len = totlen; + skb->dev = dev; + + if(rbd->buffer < rbd_first->buffer) + { + pnt = p->max_cbuff24 - rbd_first->buffer; + memcpy( (char *) skb->data,p->max_cbuff32-pnt,pnt); + memcpy( (char *) skb->data+pnt,p->min_cbuff32,totlen-pnt); + } + else + memcpy( (char *) skb->data,(char *) p->base+(unsigned long) rbd_first->buffer, totlen); + + rbd->size |= RBD_LAST; + p->rbd_last->size &= ~RBD_LAST; + p->rbd_last = rbd; + + netif_rx(skb); + p->stats.rx_packets++; + } + else + { + rbd->size |= RBD_LAST; + p->rbd_last->size &= ~RBD_LAST; + p->rbd_last = rbd; + } + } + else /* frame !(ok), only with 'save-bad-frames' */ + { + printk("%s: oops! rfd-error-status: %04x\n",dev->name,status); + p->stats.rx_errors++; + } + } +} + +/********************************************************** + * I never got this error , (which should occure if someone + * wants to blast your machine) so I couldn't debug it for now. + * but we _try_ to fix the receiver not ready int. + */ + +static void ni52_rnr_int(struct device *dev) +{ + struct priv *p = (struct priv *) dev->priv; + + p->stats.rx_errors++; + + while(p->scb->cmd); /* wait for the last cmd */ + p->scb->cmd = RUC_ABORT; + ni_attn586(); + while(p->scb->cmd); /* wait for accept cmd. */ + + alloc_rfa(dev,(char *)p->rfd_first); + startrecv586(dev); /* restart */ +} + +/********************************************************** + * handle xmit - interrupt + */ + +static void ni52_xmt_int(struct device *dev) +{ + int status; + struct priv *p = (struct priv *) dev->priv; + +/* + if(!(p->xmit_cmds[0]->cmd_status & STAT_COMPL)) + return; +*/ + + if( (status=p->xmit_cmds[p->xmit_last]->cmd_status) & STAT_OK) + { + p->stats.tx_packets++; + p->stats.collisions += (status & TCMD_MAXCOLLMASK); + dev->tbusy = 0; + mark_bh(NET_BH); + } + else + { + p->stats.tx_errors++; + if(status & TCMD_LATECOLL) { + printk("%s: late collision detected.\n",dev->name); + p->stats.collisions++; + } + else if(status & TCMD_NOCARRIER) { + p->stats.tx_carrier_errors++; + printk("%s: no carrier detected.\n",dev->name); + } + else if(status & TCMD_LOSTCTS) + printk("%s: loss of CTS detected.\n",dev->name); + else if(status & TCMD_UNDERRUN) { + printk("%s: DMA underrun detected.\n",dev->name); + } + else if(status & TCMD_MAXCOLL) { + printk("%s: Max. collisions exceeded.\n",dev->name); + p->stats.collisions += 16; + } + } + +#ifndef ONLY_ONE_XMIT_BUF + if( (++p->xmit_last) == NUM_XMIT_BUFFS) + p->xmit_last = 0; +#endif + +} + +/*********************************************************** + * (re)start the receiver + */ + +static void startrecv586(struct device *dev) +{ + struct priv *p = (struct priv *) dev->priv; + + p->scb->rfa_offset = make16(p->rfd_first); + p->scb->cmd = RUC_START; + ni_attn586(); /* start cmd. */ + while(p->scb->cmd); /* wait for accept cmd. (no timeout!!) */ + + DELAY(2); /* isn't necess. */ + + p->scb->cmd = p->scb->status & STAT_MASK; + ni_attn586(); /* ack interr */ +} + +/****************************************************** + * send frame + */ + +static int ni52_send_packet(struct sk_buff *skb, struct device *dev) +{ + int len; +#ifndef NO_NOPCOMMANDS + int next_nop; +#endif + struct priv *p = (struct priv *) dev->priv; + + if(dev->tbusy) + { + int tickssofar = jiffies - dev->trans_start; + + if (tickssofar < 30) + return 1; + +#ifdef DEBUG + printk("%s: xmitter timed out, try to restart! stat: %04x\n",dev->name,p->scb->status); + printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status); +#endif + + ni52_close(dev); + ni52_open(dev); + dev->trans_start = jiffies; + } + + if(skb == NULL) + { + dev_tint(dev); + return 0; + } + + if (skb->len <= 0) + return 0; + + if (set_bit(0, (void*)&dev->tbusy) != 0) + printk("%s: Transmitter access conflict.\n", dev->name); + else + { + memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len); + len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; + +#ifdef ONLY_ONE_XMIT_BUF +# ifdef NO_NOPCOMMANDS + p->xmit_buffs[0]->size = TBD_LAST | len; + p->xmit_cmds[0]->cmd_status = 0; + p->scb->cbl_offset = make16(p->xmit_cmds[0]); + p->scb->cmd = CUC_START; + + dev->trans_start = jiffies; + ni_attn586(); + while(p->scb->cmd) + for(len=0;len<256;len++); + + /* DELAY(1); */ /* TEST;TEST;TEST */ +# else + next_nop = (p->nop_point + 1) & 0x1; + p->xmit_buffs[0]->size = TBD_LAST | len; + + p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_INT; + p->xmit_cmds[0]->cmd_status = 0; + p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link + = make16((p->nop_cmds[next_nop])); + p->nop_cmds[next_nop]->cmd_status = 0; + + p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0])); + dev->trans_start = jiffies; + p->nop_point = next_nop; +# endif +#else + p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len; + if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS ) + next_nop = 0; + + p->xmit_cmds[p->xmit_count]->cmd_cmd = CMD_XMIT | CMD_INT; + p->xmit_cmds[p->xmit_count]->cmd_status = 0; + p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link + = make16((p->nop_cmds[next_nop])); + p->nop_cmds[next_nop]->cmd_status = 0; + + p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count])); + dev->trans_start = jiffies; + p->xmit_count = next_nop; + + cli(); + if(p->xmit_count != p->xmit_last) + dev->tbusy = 0; + sti(); +#endif + } + + dev_kfree_skb(skb,FREE_WRITE); + + return 0; +} + +static struct enet_statistics *ni52_get_stats(struct device *dev) +{ + struct priv *p = (struct priv *) dev->priv; +#ifdef DEBUG3 + printk("ni52: errs, crc %d, align %d, ressource %d, ovrn %d.\n",(int) p->scb->crc_errs,(int) p->scb->aln_errs,(int) p->scb->rsc_errs,(int) p->scb->ovrn_errs); +#endif + return &p->stats; +} + +static void set_multicast_list(struct device *dev, int num_addrs, void *addrs) +{ +/* + struct priv *p = (struct priv *) dev->priv; + volatile struct configure_cmd_struct *cfg_cmd; +*/ + + if(!num_addrs) + printk("%s: Currently, the Ni52 driver doesn't support promiscous or multicast mode.\n",dev->name); + +#if 0 + p->scb->cmd = CUC_SUSPEND; + ni_attn586(); + while(p->scb->cmd); + p->scb->cmd = RUC_SUSPEND; + ni_attn586(); + while(p->scb->cmd); + + cfg_cmd = (struct configure_cmd_struct *) p->xmit_cbuffs[0]; /* we're using a transmitcommand */ + + cfg_cmd->cmd_status = 0; + cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST; + cfg_cmd->cmd_link = 0xffff; + + cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */ + cfg_cmd->fifo = 0x08; /* fifo-limit (8=tx:32/rx:64) */ + cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */ + cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */ + cfg_cmd->priority = 0x00; + cfg_cmd->ifd = 0x60; + cfg_cmd->time_low = 0x00; + cfg_cmd->time_high = 0xf2; + cfg_cmd->promisc = 0x01; /* promisc on */ + cfg_cmd->carr_coll = 0x00; + + p->scb->cbl_offset = make16(cfg_cmd); + + p->scb->cmd = CUC_START; /* cmd.-unit start */ + ni_attn586(); + while(p->scb->cmd); + + p->scb->cbl_offset = p->nop_cmds[0]->cmd_link = make16(p->nop_cmds[0]); + p->scb->cmd = CUC_START; + ni_atthn586(); + while(p->scb->cmd); + p->scb->cmd = RUC_RESUME; + ni_atthn586(); + while(p->scb->cmd); +#endif + +} diff -u --recursive --new-file v1.1.47/linux/drivers/net/ni52.h linux/drivers/net/ni52.h --- v1.1.47/linux/drivers/net/ni52.h Thu Jan 1 02:00:00 1970 +++ linux/drivers/net/ni52.h Wed Aug 24 14:58:48 1994 @@ -0,0 +1,284 @@ +/* + * Intel i82586 Ethernet definitions + * + * This is an extension to the Linux operating system, and is covered by the + * same Gnu Public License that covers that work. + * + * copyrights (c) 1994 by Michael Hipp (mhipp@student.uni-tuebingen.de) + * + * I have done a look in the following sources: + * crynwr-packet-driver by Russ Nelson + * Garret A. Wollman's i82586-driver for BSD + */ + + +#define NI52_RESET 0 /* writing to this address, resets the i82586 */ +#define NI52_ATTENTION 1 /* channel attention, kick the 586 */ +#define NI52_TENA 3 /* 2-5 possibly wrong, Xmit enable */ +#define NI52_TDIS 2 /* Xmit disable */ +#define NI52_INTENA 5 /* Interrupt enable */ +#define NI52_INTDIS 4 /* Interrupt disable */ +#define NI52_MAGIC1 6 /* dunno exact function */ +#define NI52_MAGIC2 7 /* dunno exact function */ + +#define NI52_MAGICVAL1 0x00 /* magic-values for ni5210 card */ +#define NI52_MAGICVAL2 0x55 + +/* + * where to find the System Configuration Pointer (SCP) + */ +#define SCP_DEFAULT_ADDRESS 0xfffff4 + + +/* + * System Configuration Pointer Struct + */ + +struct scp_struct +{ + unsigned short zero_dum0; /* has to be zero */ + unsigned char sysbus; /* 0=16Bit,1=8Bit */ + unsigned char zero_dum1; /* has to be zero for 586 */ + unsigned short zero_dum2; + unsigned short zero_dum3; + char *iscp; /* pointer to the iscp-block */ +}; + + +/* + * Intermediate System Configuration Pointer (ISCP) + */ +struct iscp_struct +{ + unsigned char busy; /* 586 clears after succesful init */ + unsigned char zero_dummy; /* hast to be zero */ + unsigned short scb_offset; /* pointeroffset to the scb_base */ + char *scb_base; /* base-address of all 16-bit offsets */ +}; + +/* + * System Control Block (SCB) + */ +struct scb_struct +{ + unsigned short status; /* status word */ + unsigned short cmd; /* command word */ + unsigned short cbl_offset; /* pointeroffset, command block list */ + unsigned short rfa_offset; /* pointeroffset, receive frame area */ + unsigned short crc_errs; /* CRC-Error counter */ + unsigned short aln_errs; /* allignmenterror counter */ + unsigned short rsc_errs; /* Resourceerror counter */ + unsigned short ovrn_errs; /* OVerrunerror counter */ +}; + +/* + * possbile command values for the command word + */ +#define RUC_MASK 0x0070 /* mask for RU commands */ +#define RUC_NOP 0x0000 /* NOP-command */ +#define RUC_START 0x0010 /* start RU */ +#define RUC_RESUME 0x0020 /* resume RU after suspend */ +#define RUC_SUSPEND 0x0030 /* suspend RU */ +#define RUC_ABORT 0x0040 /* abort receiver operation immediately */ + +#define CUC_MASK 0x0700 /* mask for CU command */ +#define CUC_NOP 0x0000 /* NOP-command */ +#define CUC_START 0x0100 /* start execution of 1. cmd on the CBL */ +#define CUC_RESUME 0x0200 /* resume after suspend */ +#define CUC_SUSPEND 0x0300 /* Suspend CU */ +#define CUC_ABORT 0x0400 /* abort command operation immediately */ + +#define ACK_MASK 0xf000 /* mask for ACK command */ +#define ACK_CX 0x8000 /* acknowledges STAT_CX */ +#define ACK_FR 0x4000 /* ack. STAT_FR */ +#define ACK_CNA 0x2000 /* ack. STAT_CNA */ +#define ACK_RNR 0x1000 /* ack. STAT_RNR */ + +/* + * possbile status values for the status word + */ +#define STAT_MASK 0xf000 /* mask for cause of interrupt */ +#define STAT_CX 0x8000 /* CU finished cmd with its I bit set */ +#define STAT_FR 0x4000 /* RU finished receiveing a frame */ +#define STAT_CNA 0x2000 /* CU left active state */ +#define STAT_RNR 0x1000 /* RU left ready state */ + +#define CU_STATUS 0x700 /* CU status, 0=idle */ +#define CU_SUSPEND 0x100 /* CU is suspended */ +#define CU_ACTIVE 0x200 /* CU is active */ + +#define RU_STATUS 0x70 /* RU status, 0=idle */ +#define RU_SUSPEND 0x10 /* RU suspended */ +#define RU_NOSPACE 0x20 /* RU no resources */ +#define RU_READY 0x40 /* RU is ready */ + +/* + * Receive Frame Descriptor (RFD) + */ +struct rfd_struct +{ + unsigned short status; /* status word */ + unsigned short last; /* Bit15,Last Frame on List / Bit14,suspend */ + unsigned short next; /* linkoffset to next RFD */ + unsigned short rbd_offset; /* pointeroffset to RBD-buffer */ + unsigned char dest[6]; /* ethernet-address, destination */ + unsigned char source[6]; /* ethernet-address, source */ + unsigned short length; /* 802.3 frame-length */ + unsigned short zero_dummy; /* dummy */ +}; + +#define RFD_LAST 0x8000 /* last: last rfd in the list */ +#define RFD_SUSP 0x4000 /* last: suspend RU after */ +#define RFD_ERRMASK 0x0fe1 /* status: errormask */ +#define RFD_MATCHADD 0x0002 /* status: Destinationaddress !matchs IA */ +#define RFD_RNR 0x0200 /* status: receiver out of resources */ + +/* + * Receive Buffer Descriptor (RBD) + */ +struct rbd_struct +{ + unsigned short status; /* status word,number of used bytes in buff */ + unsigned short next; /* pointeroffset to next RBD */ + char *buffer; /* recevie buffer address pointer */ + unsigned short size; /* size of this buffer */ + unsigned short zero_dummy; /* dummy */ +}; + +#define RBD_LAST 0x8000 /* last buffer */ +#define RBD_USED 0x4000 /* this buffer has data */ +#define RBD_MASK 0x3fff /* size-mask for length */ + +/* + * Statusvalues for Commands/RFD + */ +#define STAT_COMPL 0x8000 /* status: frame/command is complete */ +#define STAT_BUSY 0x4000 /* status: frame/command is busy */ +#define STAT_OK 0x2000 /* status: frame/command is ok */ + +/* + * Action-Commands + */ +#define CMD_NOP 0x0000 /* NOP */ +#define CMD_IASETUP 0x0001 /* initial address setup command */ +#define CMD_CONFIGURE 0x0002 /* configure command */ +#define CMD_MCSETUP 0x0003 /* MC setup command */ +#define CMD_XMIT 0x0004 /* transmit command */ +#define CMD_TDR 0x0005 /* time domain reflectometer (TDR) command */ +#define CMD_DUMP 0x0006 /* dump command */ +#define CMD_DIAGNOSE 0x0007 /* diagnose command */ + +/* + * Action command bits + */ +#define CMD_LAST 0x8000 /* indicates last command in the CBL */ +#define CMD_SUSPEND 0x4000 /* suspend CU after this CB */ +#define CMD_INT 0x2000 /* generate interrupt after execution */ + +/* + * NOP - command + */ +struct nop_cmd_struct +{ + unsigned short cmd_status; /* statius of this command */ + unsigned short cmd_cmd; /* the command itself (+bits) */ + unsigned short cmd_link; /* offsetpointer to next command */ +}; + +/* + * IA Setup command + */ +struct iasetup_cmd_struct +{ + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned char iaddr[6]; +}; + +/* + * Configure command + */ +struct configure_cmd_struct +{ + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned char byte_cnt; /* size of the config-cmd */ + unsigned char fifo; /* fifo/recv monitor */ + unsigned char sav_bf; /* save bad frames (bit7=1)*/ + unsigned char adr_len; /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/ + unsigned char priority; /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */ + unsigned char ifs; /* inter frame spacing */ + unsigned char time_low; /* slot time low */ + unsigned char time_high; /* slot time high(0-2) and max. retries(4-7) */ + unsigned char promisc; /* promisc-mode(0) , et al (1-7) */ + unsigned char carr_coll; /* carrier(0-3)/collision(4-7) stuff */ + unsigned char fram_len; /* minimal frame len */ + unsigned char dummy; /* dummy */ +}; + +/* + * Multicast Setup command + */ +struct mcsetup_cmd_struct +{ + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned short mc_cnt; /* number of bytes in the MC-List */ + unsigned char mc_list[16][6]; /* the list for 16 entries */ +}; + +/* + * transmit command + */ +struct transmit_cmd_struct +{ + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned short tbd_offset; /* pointeroffset to TBD */ + unsigned char dest[6]; /* destination address of the frame */ + unsigned short length; /* user defined: 802.3 length / Ether type */ +}; + +#define TCMD_ERRMASK 0x0fa0 +#define TCMD_MAXCOLLMASK 0x000f +#define TCMD_MAXCOLL 0x0020 +#define TCMD_HEARTBEAT 0x0040 +#define TCMD_DEFFERED 0x0080 +#define TCMD_UNDERRUN 0x0100 +#define TCMD_LOSTCTS 0x0200 +#define TCMD_NOCARRIER 0x0400 +#define TCMD_LATECOLL 0x0800 + +struct tdr_cmd_struct +{ + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned short status; +}; + +#define TDR_LNK_OK 0x8000 /* No link problem identified */ +#define TDR_XCVR_PRB 0x4000 /* indiactes a transceiver problem */ +#define TDR_ET_OPN 0x2000 /* open, no correct termination */ +#define TDR_ET_SRT 0x1000 /* TDR detected a short circuit */ +#define TDR_TIMEMASK 0x07ff /* mask for the time field */ + +/* + * Transmit Buffer Descriptor (TBD) + */ +struct tbd_struct +{ + unsigned short size; /* size + EOF-Flag(15) */ + unsigned short next; /* pointeroffset to next TBD */ + char *buffer; /* pointer to buffer */ +}; + +#define TBD_LAST 0x8000 /* EOF-Flag, indicates last buffer in list */ + + + + diff -u --recursive --new-file v1.1.47/linux/drivers/net/ni65.c linux/drivers/net/ni65.c --- v1.1.47/linux/drivers/net/ni65.c Thu Jan 1 02:00:00 1970 +++ linux/drivers/net/ni65.c Thu Aug 25 15:17:39 1994 @@ -0,0 +1,647 @@ +/* + * ni6510 (am7990 'lance' chip) driver for Linux-net-3 by MH + * Alphacode v0.33 (94/08/22) for 1.1.47 (or later) + * + * ---------------------------------------------------------- + * WARNING: DOESN'T WORK ON MACHINES WITH MORE THAN 16MB !!!! + * ---------------------------------------------------------- + * + * copyright (c) 1994 M.Hipp + * + * This is an extension to the Linux operating system, and is covered by the + * same Gnu Public License that covers the Linux-kernel. + * + * comments/bugs/suggestions can be sent to: + * Michael Hipp + * email: mhipp@student.uni-tuebingen.de + * + * sources: + * some things are from the 'ni6510-packet-driver for dos by Russ Nelson' + * and from the original drivers by D.Becker + */ + +/* + * Aug.22: changes in xmit_intr (ack more than one xmitted-packet), ni65_send_packet (p->lock) (MH) + * + * July.16: fixed bugs in recv_skb and skb-alloc stuff (MH) + */ + +/* + * known BUGS: 16MB limit + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ni65.h" + +/************************************ + * skeleton-stuff + */ + +#ifndef HAVE_PORTRESERVE +#define check_region(ioaddr, size) 0 +#define snarf_region(ioaddr, size); do ; while (0) +#endif + +#ifndef NET_DEBUG +#define NET_DEBUG 2 +#endif +/* +static unsigned int net_debug = NET_DEBUG; +*/ + +#define NI65_TOTAL_SIZE 16 + +#define SA_ADDR0 0x02 +#define SA_ADDR1 0x07 +#define SA_ADDR2 0x01 +#define CARD_ID0 0x00 +#define CARD_ID1 0x55 + +/*****************************************/ + +#define PORT dev->base_addr + +#define RMDNUM 8 +#define RMDNUMMASK 0x6000 /* log2(RMDNUM)<<13 */ +#define TMDNUM 4 +#define TMDNUMMASK 0x4000 /* log2(TMDNUM)<<13 */ + +#define R_BUF_SIZE 1518 +#define T_BUF_SIZE 1518 + +#define MEMSIZE 8+RMDNUM*8+TMDNUM*8 + +#define L_DATAREG 0x00 +#define L_ADDRREG 0x02 + +#define L_RESET 0x04 +#define L_CONFIG 0x05 +#define L_EBASE 0x08 + +/* + * to access the am7990-regs, you have to write + * reg-number into L_ADDRREG, then you can access it using L_DATAREG + */ +#define CSR0 0x00 +#define CSR1 0x01 +#define CSR2 0x02 +#define CSR3 0x03 + +/* if you #define NO_STATIC the driver is faster but you will have (more) problems with >16MB memory */ +#undef NO_STATIC + +#define writereg(val,reg) {outw(reg,PORT+L_ADDRREG);inw(PORT+L_ADDRREG); \ + outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);} +#define readreg(reg) (outw(reg,PORT+L_ADDRREG),inw(PORT+L_ADDRREG),\ + inw(PORT+L_DATAREG)) +#define writedatareg(val) {outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);} + +static int ni65_probe1(struct device *dev,int); +static void ni65_interrupt(int reg_ptr); + static void recv_intr(struct device *dev); + static void xmit_intr(struct device *dev); +static int ni65_open(struct device *dev); + static int am7990_reinit(struct device *dev); +static int ni65_send_packet(struct sk_buff *skb, struct device *dev); +static int ni65_close(struct device *dev); +static struct enet_statistics *ni65_get_stats(struct device *); + +static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); + +extern void *irq2dev_map[16]; + +struct priv +{ + struct init_block ib; + void *memptr; + struct rmd *rmdhead; + struct tmd *tmdhead; + int rmdnum; + int tmdnum,tmdlast; + struct sk_buff *recv_skb[RMDNUM]; + void *tmdbufs[TMDNUM]; + int lock,xmit_queued; + struct enet_statistics stats; +}; + +int irqtab[] = { 9,12,15,5 }; /* irq config-translate */ +int dmatab[] = { 0,3,5,6 }; /* dma config-translate */ + +/* + * open (most done by init) + */ + +static int ni65_open(struct device *dev) +{ + if(am7990_reinit(dev)) + { + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + return 0; + } + else + { + dev->start = 0; + return -EAGAIN; + } +} + +static int ni65_close(struct device *dev) +{ + outw(0,PORT+L_RESET); /* that's the hard way */ + dev->tbusy = 1; + dev->start = 0; + return 0; +} + +/* + * Probe The Card (not the lance-chip) + * and set hardaddress + */ + +int ni65_probe(struct device *dev) +{ + int *port, ports[] = {0x300,0x320,0x340,0x360, 0}; + int base_addr = dev->base_addr; + + if (base_addr > 0x1ff) /* Check a single specified location. */ + return ni65_probe1(dev, base_addr); + else if (base_addr > 0) /* Don't probe at all. */ + return ENXIO; + + for (port = ports; *port; port++) + { + int ioaddr = *port; + if (check_region(ioaddr, NI65_TOTAL_SIZE)) + continue; + if( !(inb(ioaddr+L_EBASE+6) == CARD_ID0) || + !(inb(ioaddr+L_EBASE+7) == CARD_ID1) ) + continue; + dev->base_addr = ioaddr; + if (ni65_probe1(dev, ioaddr) == 0) + return 0; + } + + dev->base_addr = base_addr; + return ENODEV; +} + + +static int ni65_probe1(struct device *dev,int ioaddr) +{ + int i; + unsigned char station_addr[6]; + struct priv *p; + + for(i=0;i<6;i++) + station_addr[i] = dev->dev_addr[i] = inb(PORT+L_EBASE+i); + + if(station_addr[0] != SA_ADDR0 || station_addr[1] != SA_ADDR1) + { + printk("%s: wrong Hardaddress \n",dev->name); + return ENODEV; + } + + if(dev->irq == 0) + dev->irq = irqtab[(inw(PORT+L_CONFIG)>>2)&3]; + if(dev->dma == 0) + dev->dma = dmatab[inw(PORT+L_CONFIG)&3]; + + printk("%s: %s found at %#3x, IRQ %d DMA %d.\n", dev->name, + "network card", dev->base_addr, dev->irq,dev->dma); + + { + int irqval = request_irq(dev->irq, &ni65_interrupt,0,"ni65"); + if (irqval) { + printk ("%s: unable to get IRQ %d (irqval=%d).\n", + dev->name,dev->irq, irqval); + return EAGAIN; + } + if(request_dma(dev->dma, "ni65") != 0) + { + printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma); + free_irq(dev->irq); + return EAGAIN; + } + } + irq2dev_map[dev->irq] = dev; + + /* Grab the region so we can find another board if autoIRQ fails. */ + snarf_region(ioaddr,NI65_TOTAL_SIZE); + + p = dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); + memset((char *) dev->priv,0,sizeof(struct priv)); + + dev->open = ni65_open; + dev->stop = ni65_close; + dev->hard_start_xmit = ni65_send_packet; + dev->get_stats = ni65_get_stats; + dev->set_multicast_list = set_multicast_list; + + ether_setup(dev); + + dev->interrupt = 0; + dev->tbusy = 0; + dev->start = 0; + + if( (p->memptr = kmalloc(MEMSIZE,GFP_KERNEL)) == NULL) { + printk("%s: Can't alloc TMD/RMD-buffer.\n",dev->name); + return EAGAIN; + } + if( (unsigned long) (p->memptr + MEMSIZE) & 0xff000000) { + printk("%s: Can't alloc TMD/RMD buffer in lower 16MB!\n",dev->name); + return EAGAIN; + } + p->tmdhead = (struct tmd *) ((( (unsigned long)p->memptr ) + 8) & 0xfffffff8); + p->rmdhead = (struct rmd *) (p->tmdhead + TMDNUM); + +#ifndef NO_STATIC + for(i=0;itmdbufs[i] = kmalloc(T_BUF_SIZE,GFP_ATOMIC)) == NULL) { + printk("%s: Can't alloc Xmit-Mem.\n",dev->name); + return EAGAIN; + } + if( (unsigned long) (p->tmdbufs[i]+T_BUF_SIZE) & 0xff000000) { + printk("%s: Can't alloc Xmit-Mem in lower 16MB!\n",dev->name); + return EAGAIN; + } + } +#endif + + for(i=0;irecv_skb[i] = (struct sk_buff *) alloc_skb(R_BUF_SIZE,GFP_ATOMIC)) == NULL) { + printk("%s: unable to alloc recv-mem\n",dev->name); + return EAGAIN; + } + if( (unsigned long) (p->recv_skb[i]->data + R_BUF_SIZE) & 0xff000000) { + printk("%s: unable to alloc receive-memory in lower 16MB!\n",dev->name); + return EAGAIN; + } + } + + return 0; /* we've found everyting */ +} + +/* + * init lance (write init-values .. init-buffers) (open-helper) + */ + +static int am7990_reinit(struct device *dev) +{ + int i,j; + struct tmd *tmdp; + struct rmd *rmdp; + struct priv *p = (struct priv *) dev->priv; + + p->lock = 0; + p->xmit_queued = 0; + + disable_dma(dev->dma); /* I've never worked with dma, but we do it like the packetdriver */ + set_dma_mode(dev->dma,DMA_MODE_CASCADE); + enable_dma(dev->dma); + + outw(0,PORT+L_RESET); /* first: reset the card */ + if(inw(PORT+L_DATAREG) != 0x4) + { + printk("%s: can't RESET ni6510 card: %04x\n",dev->name,(int) inw(PORT+L_DATAREG)); + disable_dma(dev->dma); + free_dma(dev->dma); + free_irq(dev->irq); + return 0; + } + + /* here: memset all buffs to zero */ + + memset(p->memptr,0,MEMSIZE); + + p->tmdnum = 0; p->tmdlast = 0; + for(i=0;itmdhead + i; +#ifndef NO_STATIC + tmdp->u.buffer = (unsigned long) p->tmdbufs[i]; +#endif + tmdp->u.s.status = XMIT_START | XMIT_END; + } + + p->rmdnum = 0; + for(i=0;irmdhead + i; + rmdp->u.buffer = (unsigned long) p->recv_skb[i]->data; + rmdp->u.s.status = RCV_OWN; + rmdp->blen = -R_BUF_SIZE; + rmdp->mlen = 0; + } + + for(i=0;i<6;i++) + { + p->ib.eaddr[i] = dev->dev_addr[i]; + } + p->ib.mode = 0; + for(i=0;i<8;i++) + p->ib.filter[i] = 0; + p->ib.trplow = (unsigned short) (( (unsigned long) p->tmdhead ) & 0xffff); + p->ib.trphigh = (unsigned short) ((( (unsigned long) p->tmdhead )>>16) & 0x00ff) | TMDNUMMASK; + p->ib.rrplow = (unsigned short) (( (unsigned long) p->rmdhead ) & 0xffff); + p->ib.rrphigh = (unsigned short) ((( (unsigned long) p->rmdhead )>>16) & 0x00ff) | RMDNUMMASK; + + writereg(0,CSR3); /* busmaster/no word-swap */ + writereg((unsigned short) (((unsigned long) &(p->ib)) & 0xffff),CSR1); + writereg((unsigned short) (((unsigned long) &(p->ib))>>16),CSR2); + + writereg(CSR0_INIT,CSR0); /* this changes L_ADDRREG to CSR0 */ + + /* + * NOW, WE NEVER WILL CHANGE THE L_ADDRREG, CSR0 IS ALWAYS SELECTED + */ + + for(i=0;i<5;i++) + { + for(j=0;j<2000000;j++); /* wait a while */ + if(inw(PORT+L_DATAREG) & CSR0_IDON) break; /* init ok ? */ + } + if(i == 5) + { + printk("%s: can't init am7990, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG)); + disable_dma(dev->dma); + free_dma(dev->dma); + free_irq(dev->irq); + return 0; /* false */ + } + + writedatareg(CSR0_CLRALL | CSR0_INEA | CSR0_STRT); /* start lance , enable interrupts */ + + return 1; /* OK */ +} + +/* + * interrupt handler + */ + +static void ni65_interrupt(int reg_ptr) +{ + int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); + int csr0; + struct device *dev = (struct device *) irq2dev_map[irq]; + + if (dev == NULL) { + printk ("net_interrupt(): irq %d for unknown device.\n", irq); + return; + } + + csr0 = inw(PORT+L_DATAREG); + writedatareg(csr0 & CSR0_CLRALL); /* ack interrupts, disable int. */ + + dev->interrupt = 1; + + if(csr0 & CSR0_ERR) + { + struct priv *p = (struct priv *) dev->priv; + + if(csr0 & CSR0_BABL) + p->stats.tx_errors++; + if(csr0 & CSR0_MISS) + p->stats.rx_errors++; + } + + if(csr0 & CSR0_RINT) /* RECV-int? */ + { + recv_intr(dev); + } + if(csr0 & CSR0_TINT) /* XMIT-int? */ + { + xmit_intr(dev); + } + + writedatareg(CSR0_INEA); /* reenable inter. */ + dev->interrupt = 0; + + return; +} + +/* + * We have received an Xmit-Interrupt .. + * send a new packet if necessary + */ + +static void xmit_intr(struct device *dev) +{ + int tmdstat; + struct tmd *tmdp; + struct priv *p = (struct priv *) dev->priv; + +#ifdef NO_STATIC + struct sk_buff *skb; +#endif + + while(p->xmit_queued) + { + tmdp = p->tmdhead + p->tmdlast; + tmdstat = tmdp->u.s.status; + if(tmdstat & XMIT_OWN) + break; +#ifdef NO_STATIC + skb = (struct sk_buff *) p->tmdbufs[p->tmdlast]; + dev_kfree_skb(skb,FREE_WRITE); +#endif + + if(tmdstat & XMIT_ERR) + { + printk("%s: xmit-error: %04x %04x\n",dev->name,(int) tmdstat,(int) tmdp->status2); + if(tmdp->status2 & XMIT_TDRMASK) + printk("%s: tdr-problems (e.g. no resistor)\n",dev->name); + + /* checking some errors */ + if(tmdp->status2 & XMIT_RTRY) + p->stats.tx_aborted_errors++; + if(tmdp->status2 & XMIT_LCAR) + p->stats.tx_carrier_errors++; + p->stats.tx_errors++; + tmdp->status2 = 0; + } + else + p->stats.tx_packets++; + + p->tmdlast = (p->tmdlast + 1) & (TMDNUM-1); + if(p->tmdlast == p->tmdnum) + p->xmit_queued = 0; + } + + dev->tbusy = 0; + mark_bh(NET_BH); +} + +/* + * We have received a packet + */ + +static void recv_intr(struct device *dev) +{ + struct rmd *rmdp; + int rmdstat,len; + struct sk_buff *skb,*skb1; + struct priv *p = (struct priv *) dev->priv; + + rmdp = p->rmdhead + p->rmdnum; + while(!( (rmdstat = rmdp->u.s.status) & RCV_OWN)) + { + if( (rmdstat & (RCV_START | RCV_END)) != (RCV_START | RCV_END) ) /* is packet start & end? */ + { + if(rmdstat & RCV_START) + { + p->stats.rx_errors++; + p->stats.rx_length_errors++; + printk("%s: packet too long\n",dev->name); + } + rmdp->u.s.status = RCV_OWN; /* change owner */ + } + else if(rmdstat & RCV_ERR) + { + printk("%s: receive-error: %04x\n",dev->name,(int) rmdstat ); + p->stats.rx_errors++; + if(rmdstat & RCV_FRAM) p->stats.rx_frame_errors++; + if(rmdstat & RCV_OFLO) p->stats.rx_over_errors++; + if(rmdstat & RCV_CRC) p->stats.rx_crc_errors++; + rmdp->u.s.status = RCV_OWN; + printk("%s: lance-status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG)); + } + else + { + len = (rmdp->mlen & 0x0fff) - 4; /* -4: ignore FCS */ + skb = alloc_skb(R_BUF_SIZE,GFP_ATOMIC); + if(skb != NULL) + { + if( (unsigned long) (skb->data + R_BUF_SIZE) & 0xff000000) { + memcpy(skb->data,p->recv_skb[p->rmdnum]->data,len); + skb1 = skb; + } + else { + skb1 = p->recv_skb[p->rmdnum]; + p->recv_skb[p->rmdnum] = skb; + rmdp->u.buffer = (unsigned long) (skb->data); + } + rmdp->u.s.status = RCV_OWN; + rmdp->mlen = 0; /* not necc ???? */ + skb1->len = len; + skb1->dev = dev; + p->stats.rx_packets++; + netif_rx(skb1); + } + else + { + rmdp->u.s.status = RCV_OWN; + printk("%s: can't alloc new sk_buff\n",dev->name); + p->stats.rx_dropped++; + } + } + p->rmdnum++; p->rmdnum &= RMDNUM-1; + rmdp = p->rmdhead + p->rmdnum; + } +} + +/* + * kick xmitter .. + */ + +static int ni65_send_packet(struct sk_buff *skb, struct device *dev) +{ + struct priv *p = (struct priv *) dev->priv; + struct tmd *tmdp; + + if(dev->tbusy) + { + int tickssofar = jiffies - dev->trans_start; + if (tickssofar < 25) + return 1; + + printk("%s: xmitter timed out, try to restart!\n",dev->name); + am7990_reinit(dev); + dev->tbusy=0; + dev->trans_start = jiffies; + } + + if(skb == NULL) + { + dev_tint(dev); + return 0; + } + + if (skb->len <= 0) + return 0; + + if (set_bit(0, (void*)&dev->tbusy) != 0) + { + printk("%s: Transmitter access conflict.\n", dev->name); + return 1; + } + if(set_bit(0,(void*) &p->lock) != 0) + { + printk("%s: Queue was locked!\n",dev->name); + return 1; + } + + { + short len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + + tmdp = p->tmdhead + p->tmdnum; + +#ifdef NO_STATIC + tmdp->u.buffer = (unsigned long) (skb->data); + p->tmdbufs[p->tmdnum] = skb; +#else + memcpy((char *) (tmdp->u.buffer & 0x00ffffff),(char *)skb->data,skb->len); + dev_kfree_skb (skb, FREE_WRITE); +#endif + tmdp->blen = -len; + tmdp->u.s.status = XMIT_OWN | XMIT_START | XMIT_END; + + cli(); + p->xmit_queued = 1; + writedatareg(CSR0_TDMD | CSR0_INEA); /* enable xmit & interrupt */ + p->tmdnum++; p->tmdnum &= TMDNUM-1; + + if( !((p->tmdhead + p->tmdnum)->u.s.status & XMIT_OWN) ) + dev->tbusy = 0; + p->lock = 0; + sti(); + + dev->trans_start = jiffies; + + } + + return 0; +} + +static struct enet_statistics *ni65_get_stats(struct device *dev) +{ + return &((struct priv *) dev->priv)->stats; +} + +static void set_multicast_list(struct device *dev, int num_addrs, void *addrs) +{ +} + +/* + * END of ni65.c + */ + diff -u --recursive --new-file v1.1.47/linux/drivers/net/ni65.h linux/drivers/net/ni65.h --- v1.1.47/linux/drivers/net/ni65.h Thu Jan 1 02:00:00 1970 +++ linux/drivers/net/ni65.h Wed Aug 24 14:58:49 1994 @@ -0,0 +1,130 @@ +/* am7990 (lance) definitions + * + * This is a extension to the Linux operating system, and is covered by + * same Gnu Public License that covers that work. + * + * Michael Hipp + * email: mhipp@student.uni-tuebingen.de + * + * sources: (mail me or ask archie if you need them) + * crynwr-packet-driver + */ + +/* + * Control and Status Register 0 (CSR0) bit definitions + * (R=Readable) (W=Writeable) (S=Set on write) (C-Clear on write) + * + */ + +#define CSR0_ERR 0x8000 /* Error summary (R) */ +#define CSR0_BABL 0x4000 /* Babble transmitter timeout error (RC) */ +#define CSR0_CERR 0x2000 /* Collision Error (RC) */ +#define CSR0_MISS 0x1000 /* Missed packet (RC) */ +#define CSR0_MERR 0x0800 /* Memory Error (RC) */ +#define CSR0_RINT 0x0400 /* Reciever Interrupt (RC) */ +#define CSR0_TINT 0x0200 /* Transmit Interrupt (RC) */ +#define CSR0_IDON 0x0100 /* Initialization Done (RC) */ +#define CSR0_INTR 0x0080 /* Interrupt Flag (R) */ +#define CSR0_INEA 0x0040 /* Interrupt Enable (RW) */ +#define CSR0_RXON 0x0020 /* Receiver on (R) */ +#define CSR0_TXON 0x0010 /* Transmitter on (R) */ +#define CSR0_TDMD 0x0008 /* Transmit Demand (RS) */ +#define CSR0_STOP 0x0004 /* Stop (RS) */ +#define CSR0_STRT 0x0002 /* Start (RS) */ +#define CSR0_INIT 0x0001 /* Initialize (RS) */ + +#define CSR0_CLRALL 0x7f00 /* mask for all clearable bits */ +/* + * Initialization Block Mode operation Bit Definitions. + */ + +#define M_PROM 0x8000 /* Promiscuous Mode */ +#define M_INTL 0x0040 /* Internal Loopback */ +#define M_DRTY 0x0020 /* Disable Retry */ +#define M_COLL 0x0010 /* Force Collision */ +#define M_DTCR 0x0008 /* Disable Transmit CRC) */ +#define M_LOOP 0x0004 /* Loopback */ +#define M_DTX 0x0002 /* Disable the Transmitter */ +#define M_DRX 0x0001 /* Disable the Reciever */ + + +/* + * Receive message descriptor bit definitions. + */ + +#define RCV_OWN 0x80 /* owner bit 0 = host, 1 = lance */ +#define RCV_ERR 0x40 /* Error Summary */ +#define RCV_FRAM 0x20 /* Framing Error */ +#define RCV_OFLO 0x10 /* Overflow Error */ +#define RCV_CRC 0x08 /* CRC Error */ +#define RCV_BUF_ERR 0x04 /* Buffer Error */ +#define RCV_START 0x02 /* Start of Packet */ +#define RCV_END 0x01 /* End of Packet */ + + +/* + * Transmit message descriptor bit definitions. + */ + +#define XMIT_OWN 0x80 /* owner bit 0 = host, 1 = lance */ +#define XMIT_ERR 0x40 /* Error Summary */ +#define XMIT_RETRY 0x10 /* more the 1 retry needed to Xmit */ +#define XMIT_1_RETRY 0x08 /* one retry needed to Xmit */ +#define XMIT_DEF 0x04 /* Deferred */ +#define XMIT_START 0x02 /* Start of Packet */ +#define XMIT_END 0x01 /* End of Packet */ + +/* + * transmit status (2) (valid if XMIT_ERR == 1) + */ + +#define XMIT_RTRY 0x0200 /* Failed after 16 retransmissions */ +#define XMIT_LCAR 0x0400 /* Loss of Carrier */ +#define XMIT_LCOL 0x1000 /* Late collision */ +#define XMIT_RESERV 0x2000 /* Reserved */ +#define XMIT_UFLO 0x4000 /* Underflow (late memory) */ +#define XMIT_BUFF 0x8000 /* Buffering error (no ENP) */ +#define XMIT_TDRMASK 0x003f /* time-domain-reflectometer-value */ + +struct init_block +{ + unsigned short mode; + unsigned char eaddr[6]; + unsigned char filter[8]; + unsigned short rrplow; /* receive ring pointer (align 8) */ + unsigned short rrphigh; /* bit 13-15: number of rmd's (power of 2) */ + unsigned short trplow; /* transmit ring pointer (align 8) */ + unsigned short trphigh; /* bit 13-15: number of tmd's (power of 2) */ +}; + +struct rmd /* Receive Message Descriptor */ +{ + union + { + volatile unsigned long buffer; + struct + { + volatile unsigned char dummy[3]; + volatile unsigned char status; + } s; + } u; + short blen; + volatile unsigned short mlen; +}; + +struct tmd +{ + union + { + volatile unsigned long buffer; + struct + { + volatile unsigned char dummy[3]; + volatile unsigned char status; + } s; + } u; + unsigned short blen; + volatile unsigned short status2; +}; + + diff -u --recursive --new-file v1.1.47/linux/drivers/net/skeleton.c linux/drivers/net/skeleton.c --- v1.1.47/linux/drivers/net/skeleton.c Thu Aug 11 20:43:14 1994 +++ linux/drivers/net/skeleton.c Tue Aug 23 09:48:50 1994 @@ -236,7 +236,7 @@ /* Always snarf a DMA channel after the IRQ. */ - if (request_dma(dev->dma)) { + if (request_dma(dev->dma,"skeleton ethernet")) { free_irq(dev->irq); return -EAGAIN; } diff -u --recursive --new-file v1.1.47/linux/drivers/net/znet.c linux/drivers/net/znet.c --- v1.1.47/linux/drivers/net/znet.c Thu Aug 11 20:43:15 1994 +++ linux/drivers/net/znet.c Tue Aug 23 09:48:51 1994 @@ -248,8 +248,8 @@ /* These should never fail. You can't add devices to a sealed box! */ if (request_irq(dev->irq, &znet_interrupt, 0, "ZNet") - || request_dma(zn.rx_dma) - || request_dma(zn.tx_dma)) { + || request_dma(zn.rx_dma,"ZNet rx") + || request_dma(zn.tx_dma,"ZNet tx")) { printk(KERN_WARNING "%s: Not opened -- resource busy?!?\n", dev->name); return EBUSY; } diff -u --recursive --new-file v1.1.47/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c --- v1.1.47/linux/drivers/scsi/aha1542.c Sun Aug 21 17:48:27 1994 +++ linux/drivers/scsi/aha1542.c Tue Aug 23 09:48:51 1994 @@ -876,7 +876,7 @@ } if (dma_chan != 0xFF) { - if (request_dma(dma_chan)) { + if (request_dma(dma_chan,"aha1542")) { printk("Unable to allocate DMA channel for Adaptec.\n"); free_irq(irq_level); goto unregister; diff -u --recursive --new-file v1.1.47/linux/drivers/scsi/buslogic.c linux/drivers/scsi/buslogic.c --- v1.1.47/linux/drivers/scsi/buslogic.c Sun Aug 21 17:48:27 1994 +++ linux/drivers/scsi/buslogic.c Tue Aug 23 09:48:51 1994 @@ -1082,7 +1082,7 @@ } if (dma) { - if (request_dma(dma)) { + if (request_dma(dma,"buslogic")) { buslogic_printk("Unable to allocate DMA channel for " "BusLogic controller.\n"); free_irq(irq); diff -u --recursive --new-file v1.1.47/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- v1.1.47/linux/drivers/scsi/sr.c Mon Aug 22 21:57:54 1994 +++ linux/drivers/scsi/sr.c Mon Aug 22 21:03:50 1994 @@ -654,7 +654,7 @@ if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0; printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", - ++sr_template.dev_noticed, + sr_template.dev_noticed++, SDp->host->host_no , SDp->id, SDp->lun); return 1; diff -u --recursive --new-file v1.1.47/linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c --- v1.1.47/linux/drivers/scsi/ultrastor.c Sun Aug 21 17:48:30 1994 +++ linux/drivers/scsi/ultrastor.c Tue Aug 23 09:48:51 1994 @@ -498,7 +498,7 @@ config.interrupt); return FALSE; } - if (config.dma_channel && request_dma(config.dma_channel)) { + if (config.dma_channel && request_dma(config.dma_channel,"Ultrastor")) { printk("Unable to allocate DMA channel %u for UltraStor controller.\n", config.dma_channel); free_irq(config.interrupt); diff -u --recursive --new-file v1.1.47/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c --- v1.1.47/linux/drivers/scsi/wd7000.c Sun Aug 21 17:48:30 1994 +++ linux/drivers/scsi/wd7000.c Tue Aug 23 09:48:52 1994 @@ -1047,7 +1047,7 @@ printk("wd7000_init: can't get IRQ %d.\n", host->irq); return 0; } - if (request_dma(host->dma)) { + if (request_dma(host->dma,"wd7000")) { printk("wd7000_init: can't get DMA channel %d.\n", host->dma); free_irq(host->irq); return 0; diff -u --recursive --new-file v1.1.47/linux/drivers/sound/dma.h linux/drivers/sound/dma.h --- v1.1.47/linux/drivers/sound/dma.h Fri Oct 29 09:20:30 1993 +++ linux/drivers/sound/dma.h Tue Aug 23 09:48:52 1994 @@ -259,7 +259,7 @@ /* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr); /* reserve a DMA channel */ +extern int request_dma(unsigned int dmanr,char * deviceID); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ diff -u --recursive --new-file v1.1.47/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c --- v1.1.47/linux/drivers/sound/dmabuf.c Sun Aug 21 17:48:31 1994 +++ linux/drivers/sound/dmabuf.c Tue Aug 23 09:48:52 1994 @@ -832,7 +832,7 @@ unsigned long flags; int chan = audio_devs[dev]->dmachan; - if (ALLOC_DMA_CHN (chan)) + if (ALLOC_DMA_CHN (chan,"audio")) { printk ("Unable to grab DMA%d for the audio driver\n", chan); return RET_ERROR (EBUSY); diff -u --recursive --new-file v1.1.47/linux/drivers/sound/os.h linux/drivers/sound/os.h --- v1.1.47/linux/drivers/sound/os.h Sun Aug 21 17:48:31 1994 +++ linux/drivers/sound/os.h Tue Aug 23 09:48:52 1994 @@ -93,7 +93,7 @@ #define SOMEONE_WAITING(q, f) (f.mode & WK_SLEEP) #define WAKE_UP(q, f) {f.mode = WK_WAKEUP;wake_up(&q);} -#define ALLOC_DMA_CHN(chn) request_dma(chn) +#define ALLOC_DMA_CHN(chn,deviceID) request_dma(chn,deviceID) #define RELEASE_DMA_CHN(chn) free_dma(chn) #define GET_TIME() jiffies diff -u --recursive --new-file v1.1.47/linux/drivers/sound/sb16_dsp.c linux/drivers/sound/sb16_dsp.c --- v1.1.47/linux/drivers/sound/sb16_dsp.c Tue Jul 19 10:19:07 1994 +++ linux/drivers/sound/sb16_dsp.c Tue Aug 23 09:48:52 1994 @@ -228,7 +228,7 @@ sb_reset_dsp (); - if (ALLOC_DMA_CHN (dma8)) + if (ALLOC_DMA_CHN (dma8,"sb16 8bit")) { printk ("SB16: Unable to grab DMA%d\n", dma8); sb_free_irq (); @@ -236,7 +236,7 @@ } if (dma16 != dma8) - if (ALLOC_DMA_CHN (dma16)) + if (ALLOC_DMA_CHN (dma16,"sb16 16bit")) { printk ("SB16: Unable to grab DMA%d\n", dma16); sb_free_irq (); diff -u --recursive --new-file v1.1.47/linux/fs/block_dev.c linux/fs/block_dev.c --- v1.1.47/linux/fs/block_dev.c Sun Aug 21 17:48:32 1994 +++ linux/fs/block_dev.c Mon Aug 22 21:16:03 1994 @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -117,6 +118,10 @@ buf += chars; bh->b_uptodate = 1; mark_buffer_dirty(bh, 0); + if (filp->f_flags & O_SYNC) { + ll_rw_block(WRITE, 1, &bh); + wait_on_buffer(bh); + } brelse(bh); } filp->f_reada = 1; diff -u --recursive --new-file v1.1.47/linux/fs/ext2/CHANGES linux/fs/ext2/CHANGES --- v1.1.47/linux/fs/ext2/CHANGES Sun Aug 21 17:48:35 1994 +++ linux/fs/ext2/CHANGES Wed Aug 24 15:05:37 1994 @@ -1,5 +1,7 @@ Changes from version 0.5 to version 0.5a ======================================== + - Added a revision level in the superblock. + - Full support for O_SYNC flag of the open system call. - New mount options: `bsddf' and `minixdf'. `bsddf' causes ext2fs to remove the blocks used for FS structures from the total block count in statfs. With `minixdf', ext2fs mimics Minix behavior diff -u --recursive --new-file v1.1.47/linux/fs/ext2/file.c linux/fs/ext2/file.c --- v1.1.47/linux/fs/ext2/file.c Sun Aug 21 17:48:35 1994 +++ linux/fs/ext2/file.c Mon Aug 22 21:16:03 1994 @@ -258,6 +258,14 @@ pos = inode->i_size; else pos = filp->f_pos; + /* + * If a file has been opened in synchronous mode, we have to ensure + * that meta-data will also be written synchronously. Thus, we + * set the i_osync field. This field is tested by the allocation + * routines. + */ + if (filp->f_flags & O_SYNC) + inode->u.ext2_i.i_osync++; written = 0; while (written < count) { bh = ext2_getblk (inode, pos / sb->s_blocksize, 1, &err); @@ -286,10 +294,16 @@ buf += c; bh->b_uptodate = 1; mark_buffer_dirty(bh, 0); + if (filp->f_flags & O_SYNC) { + ll_rw_block (WRITE, 1, &bh); + wait_on_buffer (bh); + } brelse (bh); } if (pos > inode->i_size) inode->i_size = pos; + if (filp->f_flags & O_SYNC) + inode->u.ext2_i.i_osync--; up(&inode->i_sem); inode->i_ctime = inode->i_mtime = CURRENT_TIME; filp->f_pos = pos; diff -u --recursive --new-file v1.1.47/linux/fs/ext2/inode.c linux/fs/ext2/inode.c --- v1.1.47/linux/fs/ext2/inode.c Sun Aug 21 17:48:35 1994 +++ linux/fs/ext2/inode.c Mon Aug 22 21:16:03 1994 @@ -236,7 +236,7 @@ inode->u.ext2_i.i_next_alloc_goal = tmp; inode->i_ctime = CURRENT_TIME; inode->i_blocks += blocks; - if (IS_SYNC(inode)) + if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) ext2_sync_inode (inode); else inode->i_dirt = 1; @@ -307,7 +307,7 @@ } *p = tmp; mark_buffer_dirty(bh, 1); - if (IS_SYNC(inode)) { + if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) { ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); } @@ -535,6 +535,7 @@ inode->u.ext2_i.i_faddr = raw_inode->i_faddr; inode->u.ext2_i.i_frag_no = raw_inode->i_frag; inode->u.ext2_i.i_frag_size = raw_inode->i_fsize; + inode->u.ext2_i.i_osync = 0; inode->u.ext2_i.i_file_acl = raw_inode->i_file_acl; inode->u.ext2_i.i_dir_acl = raw_inode->i_dir_acl; inode->u.ext2_i.i_version = raw_inode->i_version; diff -u --recursive --new-file v1.1.47/linux/fs/proc/array.c linux/fs/proc/array.c --- v1.1.47/linux/fs/proc/array.c Thu Aug 11 20:43:27 1994 +++ linux/fs/proc/array.c Tue Aug 23 09:48:52 1994 @@ -463,6 +463,7 @@ extern int get_filesystem_list(char *); extern int get_ksyms_list(char *); extern int get_irq_list(char *); +extern int get_dma_list(char *); static int get_root_array(char * page, int type) { @@ -501,6 +502,9 @@ case PROC_KSYMS: return get_ksyms_list(page); + + case PROC_DMA: + return get_dma_list(page); } return -EBADF; } diff -u --recursive --new-file v1.1.47/linux/fs/proc/root.c linux/fs/proc/root.c --- v1.1.47/linux/fs/proc/root.c Thu Aug 11 20:43:27 1994 +++ linux/fs/proc/root.c Tue Aug 23 09:48:52 1994 @@ -71,6 +71,7 @@ { PROC_INTERRUPTS, 10,"interrupts" }, { PROC_FILESYSTEMS, 11,"filesystems" }, { PROC_KSYMS, 5, "ksyms" }, + { PROC_DMA, 3, "dma" }, }; #define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0]))) diff -u --recursive --new-file v1.1.47/linux/include/asm-i386/bitops.h linux/include/asm-i386/bitops.h --- v1.1.47/linux/include/asm-i386/bitops.h Mon Aug 22 21:57:55 1994 +++ linux/include/asm-i386/bitops.h Mon Aug 22 21:38:32 1994 @@ -66,7 +66,7 @@ /* * Find-bit routines.. */ -extern inline int find_first_zero_bit (unsigned long * addr, unsigned size) +extern inline int find_first_zero_bit(void * addr, unsigned size) { int res; @@ -92,8 +92,7 @@ return res; } -extern inline int find_next_zero_bit (unsigned long * addr, int size, - int offset) +extern inline int find_next_zero_bit (void * addr, int size, int offset) { unsigned long * p = ((unsigned long *) addr) + (offset >> 5); int set = 0, bit = offset & 31, res; @@ -117,7 +116,7 @@ /* * No zero yet, search remaining full bytes for a zero */ - res = find_first_zero_bit (p, size - 32 * (p - addr)); + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); return (offset + set + res); } diff -u --recursive --new-file v1.1.47/linux/include/asm-i386/dma.h linux/include/asm-i386/dma.h --- v1.1.47/linux/include/asm-i386/dma.h Sun Aug 21 17:48:37 1994 +++ linux/include/asm-i386/dma.h Tue Aug 23 09:49:02 1994 @@ -259,7 +259,7 @@ /* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr); /* reserve a DMA channel */ +extern int request_dma(unsigned int dmanr, char * deviceID); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ diff -u --recursive --new-file v1.1.47/linux/include/asm-i386/string.h linux/include/asm-i386/string.h --- v1.1.47/linux/include/asm-i386/string.h Sun Aug 21 17:48:37 1994 +++ linux/include/asm-i386/string.h Mon Aug 22 15:53:52 1994 @@ -447,7 +447,7 @@ return s; case 3: *(unsigned short *)s = pattern; - *(2+(unsigned char *)s) = pattern >> 16; + *(2+(unsigned char *)s) = pattern; return s; case 4: *(unsigned long *)s = pattern; diff -u --recursive --new-file v1.1.47/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h --- v1.1.47/linux/include/linux/ext2_fs.h Sun Aug 21 17:48:38 1994 +++ linux/include/linux/ext2_fs.h Wed Aug 24 15:05:37 1994 @@ -47,7 +47,7 @@ /* * The second extended file system version */ -#define EXT2FS_DATE "94/08/12" +#define EXT2FS_DATE "94/08/24" #define EXT2FS_VERSION "0.5a" /* @@ -348,12 +348,15 @@ unsigned long s_lastcheck; /* time of last check */ unsigned long s_checkinterval; /* max. time between checks */ unsigned long s_creator_os; /* OS */ - unsigned long s_reserved[237]; /* Padding to the end of the block */ + unsigned long s_rev_level; /* Revision level */ + unsigned long s_reserved[236]; /* Padding to the end of the block */ }; #define EXT2_OS_LINUX 0 #define EXT2_OS_HURD 1 #define EXT2_OS_MASIX 2 + +#define EXT2_CURRENT_REV 0 /* * Structure of a directory entry diff -u --recursive --new-file v1.1.47/linux/include/linux/ext2_fs_i.h linux/include/linux/ext2_fs_i.h --- v1.1.47/linux/include/linux/ext2_fs_i.h Sun Aug 21 17:48:38 1994 +++ linux/include/linux/ext2_fs_i.h Mon Aug 22 21:16:03 1994 @@ -24,7 +24,7 @@ unsigned long i_faddr; unsigned char i_frag_no; unsigned char i_frag_size; - unsigned short i_pad1; + unsigned short i_osync; unsigned long i_file_acl; unsigned long i_dir_acl; unsigned long i_dtime; diff -u --recursive --new-file v1.1.47/linux/include/linux/fcntl.h linux/include/linux/fcntl.h --- v1.1.47/linux/include/linux/fcntl.h Tue May 24 00:34:55 1994 +++ linux/include/linux/fcntl.h Mon Aug 22 21:16:03 1994 @@ -1,7 +1,8 @@ #ifndef _LINUX_FCNTL_H #define _LINUX_FCNTL_H -/* open/fcntl - O_SYNC isn't implemented yet */ +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ #define O_ACCMODE 0003 #define O_RDONLY 00 #define O_WRONLY 01 diff -u --recursive --new-file v1.1.47/linux/include/linux/hdreg.h linux/include/linux/hdreg.h --- v1.1.47/linux/include/linux/hdreg.h Sat Aug 6 21:32:07 1994 +++ linux/include/linux/hdreg.h Thu Aug 25 08:22:58 1994 @@ -87,12 +87,12 @@ unsigned short vendor0; /* vendor unique */ unsigned short vendor1; /* vendor unique */ unsigned short vendor2; /* vendor unique */ - unsigned char serial_no[20]; /* big_endian; 0 = not_specified */ + unsigned char serial_no[20]; /* 0 = not_specified */ unsigned short buf_type; unsigned short buf_size; /* 512 byte increments; 0 = not_specified */ unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */ - unsigned char fw_rev[8]; /* big_endian; 0 = not_specified */ - unsigned char model[40]; /* big_endian; 0 = not_specified */ + unsigned char fw_rev[8]; /* 0 = not_specified */ + unsigned char model[40]; /* 0 = not_specified */ unsigned char max_multsect; /* 0=not_implemented */ unsigned char vendor3; /* vendor unique */ unsigned short dword_io; /* 0=not_implemented; 1=implemented */ diff -u --recursive --new-file v1.1.47/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h --- v1.1.47/linux/include/linux/proc_fs.h Thu Aug 11 20:43:33 1994 +++ linux/include/linux/proc_fs.h Tue Aug 23 09:49:08 1994 @@ -23,7 +23,8 @@ PROC_DEVICES, PROC_INTERRUPTS, PROC_FILESYSTEMS, - PROC_KSYMS + PROC_KSYMS, + PROC_DMA }; enum pid_directory_inos { diff -u --recursive --new-file v1.1.47/linux/include/linux/socket.h linux/include/linux/socket.h --- v1.1.47/linux/include/linux/socket.h Mon Aug 22 21:57:55 1994 +++ linux/include/linux/socket.h Mon Aug 22 21:14:36 1994 @@ -20,7 +20,6 @@ #define SOCK_RAW 3 /* raw socket */ #define SOCK_RDM 4 /* reliably-delivered message */ #define SOCK_SEQPACKET 5 /* sequential packet socket */ -#define SOCK_NCP 6 /* Novell NCP socket */ #define SOCK_PACKET 10 /* linux specific way of */ /* getting packets at the dev */ /* level. For writing rarp and */ diff -u --recursive --new-file v1.1.47/linux/init/main.c linux/init/main.c --- v1.1.47/linux/init/main.c Fri Aug 19 14:04:06 1994 +++ linux/init/main.c Mon Aug 22 15:44:10 1994 @@ -496,7 +496,7 @@ if (hlt_works_ok) { printk("Checking 'hlt' instruction... "); __asm__ __volatile__("hlt ; hlt ; hlt ; hlt"); - printk(" Ok.\n"); + printk("Ok.\n"); } system_utsname.machine[1] = '0' + x86; diff -u --recursive --new-file v1.1.47/linux/kernel/Makefile linux/kernel/Makefile --- v1.1.47/linux/kernel/Makefile Wed Aug 3 09:32:33 1994 +++ linux/kernel/Makefile Tue Aug 23 09:55:17 1994 @@ -16,7 +16,7 @@ .c.o: $(CC) $(CFLAGS) -c $< -OBJS = sched.o sys_call.o traps.o irq.o dma.o fork.o exec_domain.o \ +OBJS = sched.o entry.o traps.o irq.o dma.o fork.o exec_domain.o \ panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o \ signal.o ptrace.o ioport.o itimer.o \ info.o ldt.o time.o tqueue.o vm86.o bios32.o splx.o @@ -27,9 +27,9 @@ $(LD) -r -o kernel.o $(OBJS) sync -sys_call.s: sys_call.S +entry.s: entry.S -sys_call.o: sys_call.s +entry.o: entry.s sched.o: sched.c $(CC) $(CFLAGS) $(PROFILING) -fno-omit-frame-pointer -c $< diff -u --recursive --new-file v1.1.47/linux/kernel/dma.c linux/kernel/dma.c --- v1.1.47/linux/kernel/dma.c Mon Jul 25 17:56:44 1994 +++ linux/kernel/dma.c Tue Aug 23 09:49:08 1994 @@ -29,11 +29,21 @@ * DMA0 used to be reserved for DRAM refresh, but apparently not any more... * DMA4 is reserved for cascading. */ +/* static volatile unsigned int dma_chan_busy[MAX_DMA_CHANNELS] = { 0, 0, 0, 0, 1, 0, 0, 0 }; - - +*/ +static volatile char * dma_chan_busy[MAX_DMA_CHANNELS] = { + 0, + 0, + 0, + 0, + "cascade", + 0, + 0, + 0 +}; /* Atomically swap memory location [32 bits] with `newval'. * This avoid the cli()/sti() junk and related problems. @@ -60,17 +70,30 @@ } /* mutex_atomic_swap */ +int get_dma_list(char *buf) +{ + int i, len = 0; + + for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) { + if (dma_chan_busy[i]) { + len += sprintf(buf+len, "%2d: %s\n", + i, + dma_chan_busy[i]); + } + } + return len; +} -int request_dma(unsigned int dmanr) +int request_dma(unsigned int dmanr, char * deviceID) { if (dmanr >= MAX_DMA_CHANNELS) return -EINVAL; - if (mutex_atomic_swap(&dma_chan_busy[dmanr], 1) != 0) + if (mutex_atomic_swap((unsigned int *) &dma_chan_busy[dmanr], (unsigned int) deviceID) != 0) return -EBUSY; - else - /* old flag was 0, now contains 1 to indicate busy */ - return 0; + + /* old flag was 0, now contains 1 to indicate busy */ + return 0; } /* request_dma */ @@ -81,7 +104,10 @@ return; } - if (mutex_atomic_swap(&dma_chan_busy[dmanr], 0) == 0) + if (mutex_atomic_swap((unsigned int *) &dma_chan_busy[dmanr], 0) == 0) { printk("Trying to free free DMA%d\n", dmanr); + return; + } + } /* free_dma */ diff -u --recursive --new-file v1.1.47/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v1.1.47/linux/kernel/ksyms.c Sun Aug 21 17:48:40 1994 +++ linux/kernel/ksyms.c Tue Aug 23 09:49:08 1994 @@ -41,7 +41,7 @@ extern void (*do_floppy)(void); #endif -extern int request_dma(unsigned int dmanr); +extern int request_dma(unsigned int dmanr, char * deviceID); extern void free_dma(unsigned int dmanr); extern int do_execve(char * filename, char ** argv, char ** envp, diff -u --recursive --new-file v1.1.47/linux/net/inet/datagram.c linux/net/inet/datagram.c --- v1.1.47/linux/net/inet/datagram.c Mon Aug 22 21:57:55 1994 +++ linux/net/inet/datagram.c Mon Aug 22 21:14:36 1994 @@ -177,8 +177,7 @@ switch(sel_type) { case SEL_IN: - if ((sk->type==SOCK_SEQPACKET || sk->type==SOCK_NCP) - && sk->state==TCP_CLOSE) + if (sk->type==SOCK_SEQPACKET && sk->state==TCP_CLOSE) { /* Connection closed: Wake up */ return(1); diff -u --recursive --new-file v1.1.47/linux/net/inet/ipx.c linux/net/inet/ipx.c --- v1.1.47/linux/net/inet/ipx.c Mon Aug 22 21:57:55 1994 +++ linux/net/inet/ipx.c Mon Aug 22 21:14:37 1994 @@ -56,16 +56,8 @@ #include /* For TIOCOUTQ/INQ */ #include #include "p8022.h" -#include "ncp.h" #ifdef CONFIG_IPX - -static void ipx_delete_timer (ipx_socket *sk); -static int ipx_do_sendto(ipx_socket *sk, ipx_address *ipx, - void *ubuf, int len, int flag, unsigned char type); -static void ipx_add_timer (ipx_socket *sk, int len); -static void ipx_reset_timer (ipx_socket *sk, int len); - /***********************************************************************************************************************\ * * * Handlers for the socket list. * @@ -83,9 +75,7 @@ static void ipx_remove_socket(ipx_socket *sk) { ipx_socket *s; - unsigned long flags; - save_flags(flags); cli(); s=ipx_socket_list; if(s==sk) @@ -99,23 +89,20 @@ if(s->next==sk) { s->next=sk->next; - restore_flags(flags); + sti(); return; } s=s->next; } - restore_flags(flags); + sti(); } static void ipx_insert_socket(ipx_socket *sk) { - unsigned long flags; - - save_flags(flags); cli(); sk->next=ipx_socket_list; ipx_socket_list=sk; - restore_flags(flags); + sti(); } static ipx_socket *ipx_find_socket(int port) @@ -146,10 +133,9 @@ ipx_remove_socket(sk); while((skb=skb_dequeue(&sk->receive_queue))!=NULL) + { kfree_skb(skb,FREE_READ); - - while((skb=skb_dequeue(&sk->write_queue))!=NULL) - kfree_skb(skb,FREE_WRITE); + } kfree_s(sk,sizeof(*sk)); } @@ -165,24 +151,20 @@ /* Theory.. Keep printing in the same place until we pass offset */ - len += sprintf (buffer," local_address rem_address tx_queue rx_queue st uid\n"); + len += sprintf (buffer,"Type local_address rem_address tx_queue rx_queue st uid\n"); for (s = ipx_socket_list; s != NULL; s = s->next) { - len += sprintf (buffer+len,"%02X ", s->ipx_type); - len += sprintf (buffer+len,"%08lX:%02X%02X%02X%02X%02X%02X:%04X ", htonl(s->ipx_source_addr.net), + len += sprintf (buffer+len,"%02X ", s->ipx_type); + len += sprintf (buffer+len,"%08lX:%02X%02X%02X%02X%02X%02X:%02X ", htonl(s->ipx_source_addr.net), s->ipx_source_addr.node[0], s->ipx_source_addr.node[1], s->ipx_source_addr.node[2], s->ipx_source_addr.node[3], s->ipx_source_addr.node[4], s->ipx_source_addr.node[5], htons(s->ipx_source_addr.sock)); - len += sprintf (buffer+len,"%08lX:%02X%02X%02X%02X%02X%02X:%04X ", htonl(s->ipx_dest_addr.net), + len += sprintf (buffer+len,"%08lX:%02X%02X%02X%02X%02X%02X:%02X ", htonl(s->ipx_dest_addr.net), s->ipx_dest_addr.node[0], s->ipx_dest_addr.node[1], s->ipx_dest_addr.node[2], s->ipx_dest_addr.node[3], s->ipx_dest_addr.node[4], s->ipx_dest_addr.node[5], htons(s->ipx_dest_addr.sock)); len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc); - len += sprintf (buffer+len,"%02X ", s->state); - if (s->socket) - len += sprintf (buffer+len,"%d\n", SOCK_INODE(s->socket)->i_uid); - else - len += sprintf (buffer+len,"%d\n", SOCK_INODE(s->ncp.ncp->socket)->i_uid); + len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid); /* Are we still dumping unwanted data then discard the record */ pos=begin+len; @@ -483,7 +465,7 @@ static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg) { - /* ipx_socket *sk=(ipx_socket *)sock->data; */ + ipx_socket *sk=(ipx_socket *)sock->data; switch(cmd) { default: @@ -584,56 +566,20 @@ wake_up_interruptible(sk->sleep); } -static void watch_callback(struct sock *sk, int len) -{ - ipx_packet *ipx; - struct sk_buff *skb; - char *data; - - skb=skb_dequeue(&sk->receive_queue); - if(skb==NULL) - return; - - ipx = (ipx_packet *)(skb->h.raw); - data = (char *)(ipx+1); - - if (*(data+1) == '?') - ipx_do_sendto(sk,&(ipx->ipx_source),"\0Y",2,0,sk->ipx_type); - - kfree_skb(skb, FREE_READ); -} - -static void mail_callback(struct sock *sk, int len) +static int ipx_create(struct socket *sock, int protocol) { - ipx_packet *ipx; - struct sk_buff *skb; - char *data; - - skb=skb_dequeue(&sk->receive_queue); - if(skb==NULL) - return; - - ipx = (ipx_packet *)(skb->h.raw); - data = (char *)(ipx+1); - if (*(data+1) == '!') + ipx_socket *sk; + sk=(ipx_socket *)kmalloc(sizeof(*sk),GFP_KERNEL); + if(sk==NULL) + return(-ENOMEM); + switch(sock->type) { - struct ncp_request_sf req; - - req.func=0x15; - req.s_func=0x01; - req.s_len=htons(1); - - ipx_do_sendto(sk->ncp.ncp, &(sk->ncp.ncp->ipx_dest_addr), - &req, sizeof(req), 0,sk->ncp.ncp->ipx_type); + case SOCK_DGRAM: + break; + default: + kfree_s((void *)sk,sizeof(*sk)); + return(-ESOCKTNOSUPPORT); } - - kfree_skb(skb, FREE_READ); - -} - -static void ipx_do_create(struct socket *sock, ipx_socket *sk) -{ - sk->dead=0; sk->next=NULL; sk->broadcast=0; @@ -652,6 +598,7 @@ skb_queue_head_init(&sk->back_log); sk->state=TCP_CLOSE; sk->socket=sock; + sk->type=sock->type; sk->ipx_type=0; /* General user level IPX */ sk->debug=0; @@ -663,76 +610,14 @@ { sock->data=(void *)sk; sk->sleep=sock->wait; - sk->type=sock->type; } - else - sk->type=SOCK_DGRAM; - sk->priority=SOPRI_NORMAL; sk->state_change=def_callback1; sk->data_ready=def_callback2; sk->write_space=def_callback1; sk->error_report=def_callback1; sk->zapped=1; - - return; -} - -static int ncp_create(struct socket *sock, int protocol) -{ - ipx_socket *sk; - ipx_socket *skw; - ipx_socket *skm; - - if ((sk=(ipx_socket *)kmalloc(sizeof(*sk),GFP_KERNEL))==NULL) - return(-ENOMEM); - - if ((skw=(ipx_socket *)kmalloc(sizeof(*skw),GFP_KERNEL))==NULL) - { - kfree_s((void *)sk, sizeof(*sk)); - return(-ENOMEM); - } - - if ((skm=(ipx_socket *)kmalloc(sizeof(*skm),GFP_KERNEL))==NULL) - { - kfree_s((void *)skw, sizeof(*skw)); - kfree_s((void *)sk, sizeof(*sk)); - return(-ENOMEM); - } - - ipx_do_create(sock, sk); - sk->ncp.ncp=NULL; - sk->ncp.watchdog=skw; - sk->ncp.mail=skm; - ipx_do_create(NULL, skw); - skw->ncp.ncp=sk; - skw->data_ready=watch_callback; - ipx_do_create(NULL, skm); - skm->ncp.ncp=sk; - skm->data_ready=mail_callback; - - return(0); -} - -static int ipx_create(struct socket *sock, int protocol) -{ - ipx_socket *sk; - - switch(sock->type) - { - case SOCK_DGRAM: - break; - case SOCK_NCP: - return(ncp_create(sock, protocol)); - default: - return(-ESOCKTNOSUPPORT); - } - if ((sk=(ipx_socket *)kmalloc(sizeof(*sk),GFP_KERNEL))==NULL) - return(-ENOMEM); - - ipx_do_create(sock, sk); - return(0); } @@ -748,79 +633,47 @@ return(0); if(!sk->dead) sk->state_change(sk); - + sk->dead=1; sock->data=NULL; - - if (sk->type == SOCK_NCP) - { - sk->ncp.watchdog->dead=1; - ipx_destroy_socket(sk->ncp.watchdog); - sk->ncp.mail->dead=1; - ipx_destroy_socket(sk->ncp.mail); - - if ((sk->state == TCP_ESTABLISHED) || (sk->state == TCP_SYN_SENT)) - { - struct ncp_request req; - - sk->state=TCP_CLOSE_WAIT; - - ipx_do_sendto(sk, &(sk->ipx_dest_addr), &req, - sizeof(req), 0, sk->ipx_type); - } - else - { - sk->dead=1; - if (sk->state != TCP_CLOSE) - ipx_delete_timer(sk); - ipx_destroy_socket(sk); - } - } - else - { - sk->dead=1; - ipx_destroy_socket(sk); - } + ipx_destroy_socket(sk); return(0); } static unsigned short first_free_socketnum(void) { - static unsigned short socketNum = 0x3fff; + static unsigned short socketNum = 0x4000; - while (ipx_find_socket(htons(++socketNum)) != NULL) - if (socketNum > 0x7ffc) socketNum = 0x3fff; + while (ipx_find_socket(htons(socketNum)) != NULL) + if (socketNum > 0x7ffc) socketNum = 0x4000; - return htons(socketNum); + return htons(socketNum++); } static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len) { - ipx_socket *sk=(ipx_socket *)sock->data; + ipx_socket *sk; struct ipx_route *rt; unsigned char *nodestart; struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr; + sk=(ipx_socket *)sock->data; + if(sk->zapped==0) return(-EIO); if(addr_len!=sizeof(struct sockaddr_ipx)) return -EINVAL; - if (addr->sipx_port == 0) { addr->sipx_port = first_free_socketnum(); - if (sk->type == SOCK_NCP) - while ((ipx_find_socket(htons(ntohs(addr->sipx_port)+1))) - || (ipx_find_socket(htons(ntohs(addr->sipx_port)+2)))) - addr->sipx_port = first_free_socketnum(); if (addr->sipx_port == 0) return -EINVAL; } if(ntohs(addr->sipx_port)<0x4000 && !suser()) return(-EPERM); /* protect IPX system stuff like routing/sap */ - + /* Source addresses are easy. It must be our network:node pair for an interface routed to IPX with the ipx routing ioctl() */ @@ -832,19 +685,6 @@ return -EADDRINUSE; } - if (sk->type == SOCK_NCP) - { - if ((ipx_find_socket(htons(ntohs(addr->sipx_port)+1))) - || (ipx_find_socket(htons(ntohs(addr->sipx_port)+2)))) - { - if(sk->debug) - printk("IPX: bind failed because port %X in use.\n", - (int)addr->sipx_port); - return -EADDRINUSE; - } - addr->sipx_type=IPX_TYPE_NCP; - } - sk->ipx_source_addr.sock=addr->sipx_port; if (addr->sipx_network == 0L) @@ -865,7 +705,6 @@ } sk->ipx_source_addr.net=rt->net; - sk->ipx_type=addr->sipx_type; /* IPX addresses zero pad physical addresses less than 6 */ memset(sk->ipx_source_addr.node,'\0',6); @@ -874,102 +713,41 @@ ipx_insert_socket(sk); sk->zapped=0; - - if (sk->type == SOCK_NCP) - { - sk->ncp.watchdog->ipx_source_addr.net=rt->net; - sk->ncp.watchdog->ipx_source_addr.sock=htons(ntohs(addr->sipx_port)+1); - - memset(sk->ncp.watchdog->ipx_source_addr.node,'\0',6); - nodestart = sk->ncp.watchdog->ipx_source_addr.node + (6 - rt->dev->addr_len); - memcpy(nodestart,rt->dev->dev_addr,rt->dev->addr_len); - - ipx_insert_socket(sk->ncp.watchdog); - sk->ncp.watchdog->zapped=0; - - sk->ncp.mail->ipx_source_addr.net=rt->net; - sk->ncp.mail->ipx_source_addr.sock=htons(ntohs(addr->sipx_port)+2); - - memset(sk->ncp.mail->ipx_source_addr.node,'\0',6); - nodestart = sk->ncp.mail->ipx_source_addr.node + (6 - rt->dev->addr_len); - memcpy(nodestart,rt->dev->dev_addr,rt->dev->addr_len); - - ipx_insert_socket(sk->ncp.mail); - sk->ncp.mail->zapped=0; - - sk->mtu=rt->dev->mtu; - } - if(sk->debug) printk("IPX: socket is bound.\n"); return(0); } -static int ncp_connect(struct socket *sock, ipx_socket *sk) -{ - struct ncp_request req; - int err; - - sk->ncp.conn=0xffff; - sk->ncp.seq=0; - - sock->state = SS_CONNECTING; - sk->state = TCP_SYN_SENT; - sk->rto = 0; - - ipx_do_sendto(sk, &(sk->ipx_dest_addr), &req, sizeof(req), 0, sk->ipx_type); - - while(sk->state != TCP_ESTABLISHED) - { - if (sk->err) - { - err=sk->err; - sk->err=0; - return -err; - } - interruptible_sleep_on(sk->sleep); - } - - return(0); -} - static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) { ipx_socket *sk=(ipx_socket *)sock->data; - struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr; - + struct sockaddr_ipx *addr; + sk->state = TCP_CLOSE; sock->state = SS_UNCONNECTED; - if(addr_len!=sizeof(struct sockaddr_ipx)) + if(addr_len!=sizeof(addr)) return(-EINVAL); + addr=(struct sockaddr_ipx *)uaddr; - if(sk->ipx_source_addr.sock==0) + if(sk->ipx_source_addr.net==0) /* put the autobinding in */ { + struct sockaddr_ipx uaddr; int ret; - struct sockaddr_ipx addr; - addr.sipx_type = 0; - addr.sipx_port = 0; - addr.sipx_network = 0L; - ret = ipx_bind (sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_ipx)); + uaddr.sipx_port = 0; + uaddr.sipx_network = 0L; + ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); if (ret != 0) return (ret); } - sk->ipx_dest_addr.net=addr->sipx_network; sk->ipx_dest_addr.sock=addr->sipx_port; memcpy(sk->ipx_dest_addr.node,addr->sipx_node,sizeof(sk->ipx_source_addr.node)); if(ipxrtr_get_dev(sk->ipx_dest_addr.net)==NULL) return -ENETUNREACH; - - if (sk->type == SOCK_NCP) - return(ncp_connect(sock, sk)); - - sk->ipx_type=addr->sipx_type; - sock->state = SS_CONNECTED; sk->state=TCP_ESTABLISHED; return(0); @@ -992,9 +770,10 @@ { ipx_address *addr; struct sockaddr_ipx sipx; - ipx_socket *sk=(ipx_socket *)sock->data; + ipx_socket *sk; - + sk=(ipx_socket *)sock->data; + *uaddr_len = sizeof(struct sockaddr_ipx); if(peer) @@ -1004,21 +783,7 @@ addr=&sk->ipx_dest_addr; } else - { - if(sk->ipx_source_addr.sock==0) - /* put the autobinding in */ - { - int ret; - - sipx.sipx_type = 0; - sipx.sipx_port = 0; - sipx.sipx_network = 0L; - ret = ipx_bind (sock, (struct sockaddr *)&sipx, sizeof(struct sockaddr_ipx)); - if (ret != 0) return (ret); - } - addr=&sk->ipx_source_addr; - } sipx.sipx_family = AF_IPX; sipx.sipx_port = addr->sock; @@ -1028,411 +793,6 @@ return(0); } -static int ipx_build_header(ipx_address *ipx, struct sk_buff *skb, - ipx_socket *sk, int len, unsigned char type) -{ - ipx_packet *ipx_pack; - ipx_route *rt; - struct datalink_proto *dl = NULL; - unsigned char IPXaddr[6]; - int self_addressing = 0; - int broadcast = 0; - - if(sk->debug) - printk("IPX: build_header: Addresses built.\n"); - - if(memcmp(&ipx->node,&ipx_broadcast_node,6)==0) - { - if (!sk->broadcast) - return -ENETUNREACH; - broadcast = 1; - } - - /* Build a packet */ - - if(sk->debug) - printk("IPX: build_header: building packet.\n"); - - /* Find out where this has to go */ - if (ipx->net == 0L) { - rt = ipxrtr_get_default_net(); - if (rt != NULL) - ipx->net = rt->net; - } else - rt=ipxrtr_get_dev(ipx->net); - - if(rt==NULL) - { - return -ENETUNREACH; - } - - dl=rt->datalink; - - skb->mem_addr=skb; - skb->sk=sk; - skb->free=1; - skb->arp=1; - skb->tries=0; - - if(sk->debug) - printk("Building MAC header.\n"); - skb->dev=rt->dev; - - /* Build Data Link header */ - dl->datalink_header(dl, skb, - (rt->flags&IPX_RT_ROUTED)?rt->router_node:ipx->node); - - /* See if we are sending to ourself */ - memset(IPXaddr, '\0', 6); - memcpy(IPXaddr+(6 - skb->dev->addr_len), skb->dev->dev_addr, - skb->dev->addr_len); - - self_addressing = !memcmp(IPXaddr, - (rt->flags&IPX_RT_ROUTED)?rt->router_node - :ipx->node, - 6); - - /* Now the IPX */ - if(sk->debug) - printk("Building IPX Header.\n"); - ipx_pack=(ipx_packet *)skb->h.raw; - ipx_pack->ipx_checksum=0xFFFF; - ipx_pack->ipx_pktsize=htons(len+sizeof(ipx_packet)); - ipx_pack->ipx_tctrl=0; - ipx_pack->ipx_type=type; - - memcpy(&ipx_pack->ipx_source,&sk->ipx_source_addr,sizeof(ipx_pack->ipx_source)); - memcpy(&ipx_pack->ipx_dest,ipx,sizeof(ipx_pack->ipx_dest)); - - if((skb->dev->flags&IFF_LOOPBACK) || self_addressing) - skb->pkt_type=PACKET_HOST; - else - if (broadcast) - skb->pkt_type=PACKET_BROADCAST; - else - skb->pkt_type=PACKET_OTHERHOST; - - return 0; -} - -static int ipx_xmit(struct sk_buff *skb) -{ - struct sk_buff *skb1; - struct device *dev= skb->dev; - ipx_packet *ipx=(ipx_packet *)skb->h.raw; - ipx_route *rt; - struct packet_type pt; - - if (ipx->ipx_dest.net == 0L) - rt = ipxrtr_get_default_net(); - else - rt=ipxrtr_get_dev(ipx->ipx_dest.net); - - if (rt == NULL) - return -ENETUNREACH; - - pt.type=rt->dlink_type; - - skb->tries++; - - switch (skb->pkt_type) - { - case PACKET_HOST: - if (!skb->free) - { - skb1=alloc_skb(skb->len, GFP_ATOMIC); - if (skb1 != NULL) - { - skb1->mem_addr=skb1; - skb1->free=1; - skb1->arp=1; - skb1->len=skb->len; - skb1->sk = NULL; - skb1->h.raw = skb1->data + rt->datalink->header_length - + dev->hard_header_len; - memcpy(skb1->data, skb->data, skb->len); - ipx_rcv(skb1,dev,&pt); - } - } - else - { - - - /* loop back */ - skb->sk->wmem_alloc-=skb->mem_len; - skb->sk = NULL; - ipx_rcv(skb,dev,&pt); - } - break; - - case PACKET_BROADCAST: - skb1=alloc_skb(skb->len, GFP_ATOMIC); - if (skb1 != NULL) - { - skb1->mem_addr=skb1; - skb1->free=1; - skb1->arp=1; - skb1->len=skb->len; - skb1->sk = NULL; - skb1->h.raw = skb1->data + rt->datalink->header_length - + dev->hard_header_len; - memcpy(skb1->data, skb->data, skb->len); - ipx_rcv(skb1,dev,&pt); - } - default: - if (!skb->free) - { - skb1=alloc_skb(skb->len, GFP_ATOMIC); - if (skb1 != NULL) - { - skb1->mem_addr=skb1; - skb1->free=1; - skb1->arp=1; - skb1->len=skb->len; - skb1->sk = NULL; - skb1->h.raw = skb1->data + rt->datalink->header_length - + dev->hard_header_len; - memcpy(skb1->data, skb->data, skb->len); - } - } - else - skb1=skb; - if (skb1 != NULL) - { - if (skb1->sk) - dev_queue_xmit(skb1,dev,skb->sk->priority); - else - dev_queue_xmit(skb1,dev,SOPRI_NORMAL); - } - } - - return(0); - -} - -static int ipx_retransmit(ipx_socket *sk) -{ - struct sk_buff *skb = sk->write_queue.next; - int num=0; - - ipx_packet *ipx; - struct ncp_request *req; - - if (skb == NULL) - return(num); - - if (skb == skb->next) - return(num); - - do - { - ipx=(ipx_packet *)skb->h.raw; - req=(struct ncp_request *)(ipx+1); - - ipx_xmit(skb); - - num++; - skb=skb->next; - } - while (skb->next != sk->write_queue.next); - - return (num); -} - -static void ipx_timer (unsigned long data) -{ - ipx_socket *sk = (ipx_socket *) data; - int num; - - cli(); - if (in_bh) - { - sk->timer.expires = 10; - add_timer(&sk->timer); - sti(); - return; - } - sti(); - - num=ipx_retransmit(sk); - - sk->rto++; - - if (sk->rto >= MAX_TIMEOUT) - { - struct sk_buff *skb; - - while((skb=skb_dequeue(&sk->write_queue))!=NULL) - kfree_skb(skb,FREE_WRITE); - - sk->err=ETIMEDOUT; - sk->state=TCP_CLOSE; - sk->socket->state=SS_UNCONNECTED; - if(!sk->dead) - sk->error_report(sk); - return; - } - - if (num) - ipx_reset_timer(sk, NCP_TIMEOUT); - - return; -} - -static void ipx_delete_timer (ipx_socket *sk) -{ - unsigned long flags; - - save_flags (flags); - cli(); - - del_timer (&sk->timer); - - restore_flags(flags); -} - -static void ipx_add_timer (ipx_socket *sk, int len) -{ - init_timer (&sk->timer); - sk->timer.data = (unsigned long) sk; - sk->timer.function = &ipx_timer; - sk->timer.expires = len; - add_timer(&sk->timer); -} - -static void ipx_reset_timer (ipx_socket *sk, int len) -{ - - ipx_delete_timer (sk); - sk->timer.data = (unsigned long) sk; - sk->timer.function = &ipx_timer; - sk->timer.expires = len; - add_timer(&sk->timer); -} - -static struct sk_buff *find_req(ipx_socket *sk, unsigned char seq) -{ - ipx_packet *ipx; - struct ncp_request *req; - struct sk_buff *skb = sk->write_queue.next; - - if (skb == NULL) - return (NULL); - - if (skb == skb->next) - return (NULL); - - do - { - ipx=(ipx_packet *)skb->h.raw; - req=(struct ncp_request *)(ipx+1); - if (req->seq == seq) - { - skb_unlink(skb); - return (skb); - } - skb=skb->next; - } - while (skb->next != sk->write_queue.next); - - return (NULL); -} - -static int ncp_rcv(ipx_socket *sk, struct sk_buff *skb) -{ - ipx_packet *ipx=(ipx_packet *)skb->h.raw; - struct ncp_reply *rep= (struct ncp_reply *)(ipx+1); - struct ncp_request_sf *req; - struct sk_buff *skb1; - - if (rep->p_type != NCP_REPLY) - { - kfree_skb(skb, FREE_READ); - return (0); - } - - skb1=find_req(sk, rep->seq); - - if (skb1 == NULL) - { - kfree_skb(skb, FREE_READ); - return (0); - } - - if (&sk->write_queue == sk->write_queue.next) - { - sk->rto=0; - ipx_delete_timer(sk); - } - - ipx=(ipx_packet *)skb1->h.raw; - req=(struct ncp_request_sf *)(ipx+1); - - switch (sk->state) - { - case TCP_CLOSE_WAIT: - kfree_skb(skb, FREE_READ); - sk->socket->data = NULL; - sk->state=TCP_CLOSE; - if(!sk->dead) - sk->state_change(sk); - sk->dead=1; - if (&sk->write_queue != sk->write_queue.next) - ipx_delete_timer(sk); - ipx_destroy_socket(sk); - break; - case TCP_SYN_SENT: - - if ((rep->f_stat == 0) && (rep->c_stat == 0)) - { - sk->state=TCP_ESTABLISHED; - sk->socket->state = SS_CONNECTED; - sk->ncp.conn=rep->c_low + (rep->c_high * 0xff); - if(!sk->dead) - sk->state_change(sk); - } - else - { - sk->state=TCP_CLOSE; - sk->socket->state = SS_UNCONNECTED; - sk->err=ECONNREFUSED; - if (&sk->write_queue != sk->write_queue.next) - ipx_delete_timer(sk); - if(!sk->dead) - sk->error_report(sk); - } - kfree_skb(skb, FREE_READ); - break; - default: - if ((req->func==0x15)&&(req->s_func==0x01)) - { - char *data = (char *)(rep+1); - int len=(int)*data; - - if (len != 0) - { - memcpy(data, data+1, len); - *(data+len)='\0'; - printk("\007%s\n",data); - } - kfree_skb(skb, FREE_READ); - } - else - { - sk->rmem_alloc+=skb->mem_len; - skb->sk = sk; - - skb_queue_tail(&sk->receive_queue,skb); - if(!sk->dead) - sk->data_ready(sk,skb->len); - } - } - - kfree_skb(skb1, FREE_WRITE); - - return(0); -} - int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) { /* NULL here for pt means the packet was looped back */ @@ -1582,9 +942,6 @@ kfree_skb(skb,FREE_READ); /* Socket is full */ return(0); } - - if (sock->type == SOCK_NCP) - return (ncp_rcv(sock, skb)); sock->rmem_alloc+=skb->mem_len; skb->sk = sock; @@ -1595,27 +952,65 @@ return(0); } -static int ipx_do_sendto(ipx_socket *sk, ipx_address *ipx, - void *ubuf, int len, int flag, unsigned char type) +static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock, + unsigned flags, struct sockaddr *usip, int addr_len) { + ipx_socket *sk=(ipx_socket *)sock->data; + struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)usip; + struct sockaddr_ipx local_sipx; struct sk_buff *skb; struct device *dev; - ipx_packet *ipx_pack; + struct ipx_packet *ipx; int size; ipx_route *rt; struct datalink_proto *dl = NULL; + unsigned char IPXaddr[6]; + int self_addressing = 0; + int broadcast = 0; + + if(flags) + return -EINVAL; + + if(usipx) + { + if(sk->ipx_source_addr.net==0) + /* put the autobinding in */ + { + struct sockaddr_ipx uaddr; + int ret; + uaddr.sipx_port = 0; + uaddr.sipx_network = 0L; + ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); + if (ret != 0) return (ret); + } + if(addr_len sipx_family != AF_IPX) + return -EINVAL; + if(htons(usipx->sipx_port)<0x4000 && !suser()) + return -EPERM; + } + else + { + if(sk->state!=TCP_ESTABLISHED) + return -ENOTCONN; + usipx=&local_sipx; + usipx->sipx_family=AF_IPX; + usipx->sipx_port=sk->ipx_dest_addr.sock; + usipx->sipx_network=sk->ipx_dest_addr.net; + memcpy(usipx->sipx_node,sk->ipx_dest_addr.node,sizeof(usipx->sipx_node)); + } + if(sk->debug) printk("IPX: sendto: Addresses built.\n"); - if ((sk->type == SOCK_NCP) && (len < sizeof (struct ncp_request))) - return -EINVAL; - - if(memcmp(&ipx->node,&ipx_broadcast_node,6)==0) + if(memcmp(&usipx->sipx_node,&ipx_broadcast_node,6)==0) { if (!sk->broadcast) return -ENETUNREACH; + broadcast = 1; } /* Build a packet */ @@ -1626,12 +1021,12 @@ size=sizeof(ipx_packet)+len; /* For mac headers */ /* Find out where this has to go */ - if (ipx->net == 0L) { + if (usipx->sipx_network == 0L) { rt = ipxrtr_get_default_net(); if (rt != NULL) - ipx->net = rt->net; + usipx->sipx_network = rt->net; } else - rt=ipxrtr_get_dev(ipx->net); + rt=ipxrtr_get_dev(usipx->sipx_network); if(rt==NULL) { @@ -1651,117 +1046,86 @@ return -EAGAIN; } - if (flag) - skb=alloc_skb(size,GFP_KERNEL); - else - skb=alloc_skb(size,GFP_ATOMIC); - + skb=alloc_skb(size,GFP_KERNEL); if(skb==NULL) return -ENOMEM; - - sk->wmem_alloc+=skb->mem_len; + skb->mem_addr=skb; + skb->sk=sk; + skb->free=1; + skb->arp=1; skb->len=size; - ipx_build_header(ipx, skb, sk, len, type); - - ipx_pack = (ipx_packet *)(skb->h.raw); - - /* User data follows immediately after the IPX data */ - if (flag) - memcpy_fromfs((char *)(ipx_pack+1),ubuf,len); - else - memcpy((char *)(ipx_pack+1),ubuf,len); - - if (sk->type == SOCK_NCP) - { - struct ncp_request *req=(struct ncp_request *)(ipx_pack+1); + sk->wmem_alloc+=skb->mem_len; - switch (sk->state) - { - case TCP_SYN_SENT: - req->p_type = NCP_OPEN; - break; - case TCP_CLOSE_WAIT: - req->p_type = NCP_CLOSE; - break; - default: - req->p_type = NCP_REQUEST; - } - req->c_low = (sk->ncp.conn) & 0xff; - req->c_high = (sk->ncp.conn >>8) & 0xff; - req->seq = (sk->ncp.seq)++; - req->task = 1; + if(sk->debug) + printk("Building MAC header.\n"); + skb->dev=rt->dev; + + /* Build Data Link header */ + dl->datalink_header(dl, skb, + (rt->flags&IPX_RT_ROUTED)?rt->router_node:usipx->sipx_node); - skb->free=0; + /* See if we are sending to ourself */ + memset(IPXaddr, '\0', 6); + memcpy(IPXaddr+(6 - skb->dev->addr_len), skb->dev->dev_addr, + skb->dev->addr_len); - if (&sk->write_queue == sk->write_queue.next) - ipx_add_timer(sk, NCP_TIMEOUT); - else - ipx_reset_timer(sk, NCP_TIMEOUT); - - skb_queue_tail(&sk->write_queue,skb); - } + self_addressing = !memcmp(IPXaddr, + (rt->flags&IPX_RT_ROUTED)?rt->router_node + :usipx->sipx_node, + 6); + /* Now the IPX */ + if(sk->debug) + printk("Building IPX Header.\n"); + ipx=(ipx_packet *)skb->h.raw; + ipx->ipx_checksum=0xFFFF; + ipx->ipx_pktsize=htons(len+sizeof(ipx_packet)); + ipx->ipx_tctrl=0; + ipx->ipx_type=usipx->sipx_type; + + memcpy(&ipx->ipx_source,&sk->ipx_source_addr,sizeof(ipx->ipx_source)); + ipx->ipx_dest.net=usipx->sipx_network; + memcpy(ipx->ipx_dest.node,usipx->sipx_node,sizeof(ipx->ipx_dest.node)); + ipx->ipx_dest.sock=usipx->sipx_port; + if(sk->debug) + printk("IPX: Appending user data.\n"); + /* User data follows immediately after the IPX data */ + memcpy_fromfs((char *)(ipx+1),ubuf,len); if(sk->debug) printk("IPX: Transmitting buffer\n"); - - ipx_xmit(skb); - - return len; -} - -static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock, - unsigned flags, struct sockaddr *usip, int addr_len) -{ - ipx_socket *sk=(ipx_socket *)sock->data; - ipx_address ipx; - struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)usip; - struct sockaddr_ipx local_sipx; - - if(flags) - return -EINVAL; - - if(usipx) - { - if (sk->type == SOCK_NCP) - return -EINVAL; + if((dev->flags&IFF_LOOPBACK) || self_addressing) { + struct packet_type pt; - if(sk->ipx_source_addr.sock==0) - /* put the autobinding in */ - { - int ret; + /* loop back */ + pt.type = rt->dlink_type; + sk->wmem_alloc-=skb->mem_len; + skb->sk = NULL; + ipx_rcv(skb,dev,&pt); + } else { + if (broadcast) { + struct packet_type pt; + struct sk_buff *skb2; - local_sipx.sipx_type = 0; - local_sipx.sipx_port = 0; - local_sipx.sipx_network = 0L; - ret = ipx_bind (sock, (struct sockaddr *)&local_sipx, sizeof(struct sockaddr_ipx)); - if (ret != 0) return (ret); + /* loop back */ + pt.type = rt->dlink_type; + + skb2=alloc_skb(skb->len, GFP_ATOMIC); + skb2->mem_addr=skb2; + skb2->free=1; + skb2->arp=1; + skb2->len=skb->len; + skb2->sk = NULL; + skb2->h.raw = skb2->data + rt->datalink->header_length + + dev->hard_header_len; + memcpy(skb2->data, skb->data, skb->len); + ipx_rcv(skb2,dev,&pt); } - - if(addr_len sipx_family != AF_IPX) - return -EINVAL; - if(htons(usipx->sipx_port)<0x4000 && !suser()) - return -EPERM; - - ipx.net=usipx->sipx_network; - ipx.sock=usipx->sipx_port; - memcpy(ipx.node,usipx->sipx_node, sizeof(ipx.node)); - return (ipx_do_sendto(sk, &ipx, ubuf, len, 1, - usipx->sipx_type)); - } - else - { - if(sk->state!=TCP_ESTABLISHED) - return -ENOTCONN; - - return (ipx_do_sendto(sk, &(sk->ipx_dest_addr), ubuf, - len, 1, sk->ipx_type)); + dev_queue_xmit(skb,dev,SOPRI_NORMAL); } + return len; } - static int ipx_send(struct socket *sock, void *ubuf, int size, int noblock, unsigned flags) { @@ -1778,7 +1142,7 @@ int copied = 0; struct sk_buff *skb; int er; - + if(sk->err) { er= -sk->err; @@ -1806,14 +1170,12 @@ sipx->sipx_type = ipx->ipx_type; } skb_free_datagram(skb); - return(copied); } static int ipx_write(struct socket *sock, char *ubuf, int size, int noblock) { - return ipx_send(sock,ubuf,size,noblock,0); } Only in v1.1.47/linux/net/inet: ncp.h diff -u --recursive --new-file v1.1.47/linux/net/inet/sock.h linux/net/inet/sock.h --- v1.1.47/linux/net/inet/sock.h Mon Aug 22 21:57:56 1994 +++ linux/net/inet/sock.h Mon Aug 22 21:14:37 1994 @@ -41,7 +41,6 @@ #endif #ifdef CONFIG_IPX #include "ipx.h" -#include "ncp.h" #endif #define SOCK_ARRAY_SIZE 64 @@ -138,7 +137,6 @@ #ifdef CONFIG_IPX ipx_address ipx_source_addr,ipx_dest_addr; unsigned short ipx_type; - struct ncp_info ncp; #endif #ifdef CONFIG_AX25 /* Really we want to add a per protocol private area */ diff -u --recursive --new-file v1.1.47/linux/net/socket.c linux/net/socket.c --- v1.1.47/linux/net/socket.c Mon Aug 22 21:57:56 1994 +++ linux/net/socket.c Mon Aug 22 21:14:37 1994 @@ -592,8 +592,7 @@ if ((type != SOCK_STREAM && type != SOCK_DGRAM && type != SOCK_SEQPACKET && type != SOCK_RAW && - type != SOCK_PACKET && type != SOCK_NCP) - || protocol < 0) + type != SOCK_PACKET) || protocol < 0) return(-EINVAL); /*