diff -u --recursive --new-file v2.0.13/linux/Documentation/Changes linux/Documentation/Changes --- v2.0.13/linux/Documentation/Changes Sat Aug 10 10:03:14 1996 +++ linux/Documentation/Changes Mon Aug 19 09:45:51 1996 @@ -26,11 +26,14 @@ valtozasokrol, az alabbi cimen megtalaljak Nyitrai Tamas forditasat: http://www.datanet.hu/generations/linux/newkernel.html. + Tamas also maintains a version of this file in English at +http://www.datanet.hu/generations/linux/Changes.html. + For people who prefer Japanese (thanks to Mitsuhiro Kojima): Kono bunshou no nihongo ban wa http://jf.gee.kyoto-u.ac.jp/JF/v2.0/Changes-2.0.html ni arimasu. -Last updated: August 6, 1996. +Last updated: August 18, 1996. Current Author: Chris Ricker (gt1355b@prism.gatech.edu). Current Releases @@ -147,6 +150,14 @@ caused by hardware problems. See http://www.bitwizard.nl/sig11/ for the sig11 FAQ. + On the other hand, if you're using a gcc patched for Pentium +optimization and are getting these errors, downgrade to a standard GNU +gcc before assuming your hardware (or the kernel) is to blame.. + + On a related note, if you get random OOPses that don't seem to be +related to anything and you have a motherboard with APM support, try +disabling the APM support and/or compiling the kernel with APM support. + Procps utilities ================ @@ -528,7 +539,7 @@ `-Tlatin1' options to `-Tascii'. An alternate solution, for those of you who can't reformat your man files in .../cat* directories is to edit /usr/lib/man.config, setting the PAGER to `PAGER -(LESSCHARSET=latin1;export LESSCHARSET;/usr/bin/less -is'. +(LESSCHARSET=latin1;export LESSCHARSET;/usr/bin/less -is)'. E2fsprogs ========= diff -u --recursive --new-file v2.0.13/linux/Makefile linux/Makefile --- v2.0.13/linux/Makefile Sat Aug 17 21:19:25 1996 +++ linux/Makefile Sat Aug 17 21:19:04 1996 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 0 -SUBLEVEL = 13 +SUBLEVEL = 14 ARCH = i386 diff -u --recursive --new-file v2.0.13/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c --- v2.0.13/linux/arch/alpha/kernel/osf_sys.c Wed Jun 26 11:05:40 1996 +++ linux/arch/alpha/kernel/osf_sys.c Sun Aug 18 10:42:02 1996 @@ -189,13 +189,48 @@ return do_mmap(file, addr, len, prot, flags, off); } -asmlinkage int osf_statfs(char * path, struct statfs * buffer, unsigned long bufsiz) + +/* + * The OSF/1 statfs structure is much larger, but this should + * match the beginning, at least. + */ +struct osf_statfs { + short f_type; + short f_flags; + int f_fsize; + int f_bsize; + int f_blocks; + int f_bfree; + int f_bavail; + int f_files; + int f_ffree; + __kernel_fsid_t f_fsid; +} * osf_stat; + +static void linux_to_osf_statfs (struct statfs * linux_stat, struct osf_statfs * osf_stat) +{ + osf_stat->f_type = linux_stat->f_type; + osf_stat->f_flags = 0; /* mount flags */ + /* Linux doesn't provide a "fundamental filesystem block size": */ + osf_stat->f_fsize = linux_stat->f_bsize; + osf_stat->f_bsize = linux_stat->f_bsize; + osf_stat->f_blocks = linux_stat->f_blocks; + osf_stat->f_bfree = linux_stat->f_bfree; + osf_stat->f_bavail = linux_stat->f_bavail; + osf_stat->f_files = linux_stat->f_files; + osf_stat->f_ffree = linux_stat->f_ffree; + osf_stat->f_fsid = linux_stat->f_fsid; +} + + +asmlinkage int osf_statfs(char * path, struct osf_statfs * buffer, unsigned long bufsiz) { + struct statfs linux_stat; struct inode * inode; int retval; - if (bufsiz > sizeof(struct statfs)) - bufsiz = sizeof(struct statfs); + if (bufsiz > sizeof(struct osf_statfs)) + bufsiz = sizeof(struct osf_statfs); retval = verify_area(VERIFY_WRITE, buffer, bufsiz); if (retval) return retval; @@ -206,13 +241,15 @@ iput(inode); return -ENOSYS; } - inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz); + inode->i_sb->s_op->statfs(inode->i_sb, &linux_stat, sizeof(linux_stat)); + linux_to_osf_statfs(&linux_stat, buffer); iput(inode); return 0; } -asmlinkage int osf_fstatfs(unsigned long fd, struct statfs * buffer, unsigned long bufsiz) +asmlinkage int osf_fstatfs(unsigned long fd, struct osf_statfs * buffer, unsigned long bufsiz) { + struct statfs linux_stat; struct file * file; struct inode * inode; int retval; @@ -220,15 +257,16 @@ retval = verify_area(VERIFY_WRITE, buffer, bufsiz); if (retval) return retval; - if (bufsiz > sizeof(struct statfs)) - bufsiz = sizeof(struct statfs); + if (bufsiz > sizeof(struct osf_statfs)) + bufsiz = sizeof(struct osf_statfs); if (fd >= NR_OPEN || !(file = current->files->fd[fd])) return -EBADF; if (!(inode = file->f_inode)) return -ENOENT; if (!inode->i_sb->s_op->statfs) return -ENOSYS; - inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz); + inode->i_sb->s_op->statfs(inode->i_sb, &linux_stat, sizeof(linux_stat)); + linux_to_osf_statfs(&linux_stat, buffer); return 0; } diff -u --recursive --new-file v2.0.13/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v2.0.13/linux/arch/alpha/kernel/process.c Sat Aug 17 21:19:26 1996 +++ linux/arch/alpha/kernel/process.c Sun Aug 18 10:37:57 1996 @@ -85,7 +85,7 @@ */ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) { - current->tss.segment = USER_DS; + set_fs(USER_DS); regs->pc = pc; regs->ps = 8; wrusp(sp); @@ -157,7 +157,8 @@ childstack->r26 = (unsigned long) ret_from_sys_call; p->tss.usp = usp; p->tss.ksp = (unsigned long) childstack; - p->tss.flags = 1; + p->tss.pal_flags = 1; /* set FEN, clear everything else */ + p->tss.flags = current->tss.flags; p->mm->context = 0; } diff -u --recursive --new-file v2.0.13/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c --- v2.0.13/linux/arch/alpha/kernel/setup.c Tue Jun 4 06:06:37 1996 +++ linux/arch/alpha/kernel/setup.c Sun Aug 18 10:37:57 1996 @@ -135,11 +135,10 @@ * installation. Later we'll add other abbreviations * as well... */ - if(strcmp(COMMAND_LINE, "INSTALL") == 0) { + if (strcmp(COMMAND_LINE, "INSTALL") == 0) { strcpy(command_line, "root=/dev/fd0 load_ramdisk=1"); strcpy(saved_command_line, command_line); - } - else { + } else { strcpy(command_line, COMMAND_LINE); strcpy(saved_command_line, COMMAND_LINE); } diff -u --recursive --new-file v2.0.13/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c --- v2.0.13/linux/arch/alpha/kernel/signal.c Tue Jul 2 19:08:34 1996 +++ linux/arch/alpha/kernel/signal.c Tue Aug 20 13:41:32 1996 @@ -30,24 +30,42 @@ /* * The OSF/1 sigprocmask calling sequence is different from the * C sigprocmask() sequence.. + * + * how: + * 1 - SIG_BLOCK + * 2 - SIG_UNBLOCK + * 3 - SIG_SETMASK + * + * We change the range to -1 .. 1 in order to let gcc easily + * use the conditional move instructions. */ -asmlinkage unsigned long osf_sigprocmask(int how, unsigned long newmask) +asmlinkage unsigned long osf_sigprocmask(int how, unsigned long newmask, + long a2, long a3, long a4, long a5, struct pt_regs regs) { - unsigned long oldmask = current->blocked; + unsigned long ok, oldmask; + struct task_struct * tsk; - newmask &= _BLOCKABLE; - switch (how) { - case SIG_BLOCK: - current->blocked |= newmask; - return oldmask; - case SIG_UNBLOCK: - current->blocked &= ~newmask; - return oldmask; - case SIG_SETMASK: - current->blocked = newmask; - return oldmask; + ok = how-1; /* 0 .. 2 */ + tsk = current; + ok = ok <= 2; + oldmask = -EINVAL; + if (ok) { + long sign; /* -1 .. 1 */ + unsigned long block, unblock; + + oldmask = tsk->blocked; + newmask &= _BLOCKABLE; + sign = how-2; + unblock = oldmask & ~newmask; + block = oldmask | newmask; + if (!sign) + block = unblock; + regs.r0 = 0; /* special no error return */ + if (sign <= 0) + newmask = block; + tsk->blocked = newmask; } - return -EINVAL; + return oldmask; } /* diff -u --recursive --new-file v2.0.13/linux/arch/alpha/lib/io.c linux/arch/alpha/lib/io.c --- v2.0.13/linux/arch/alpha/lib/io.c Thu Nov 9 10:04:33 1995 +++ linux/arch/alpha/lib/io.c Tue Aug 20 16:57:15 1996 @@ -156,24 +156,83 @@ /* * Read COUNT 32-bit words from port PORT into memory starting at - * SRC. SRC must be at least word aligned. This is used by the - * IDE driver to read disk sectors. Performance is important, but - * the interfaces seems to be slow: just using the inlined version - * of the inw() breaks things. + * SRC. Now works with any alignment in SRC. Performance is important, + * but the interfaces seems to be slow: just using the inlined version + * of the inl() breaks things. */ void insl (unsigned long port, void *dst, unsigned long count) { - if (((unsigned long)dst) & 0x3) { - panic("insl: memory not aligned"); - } - - while (count) { + unsigned int l = 0, l2; + + if (!count) + return; + + switch (((unsigned long) dst) & 0x3) + { + case 0x00: /* Buffer 32-bit aligned */ + while (count--) + { + *(unsigned int *) dst = inl(port); + ((unsigned int *) dst)++; + } + break; + + /* Assuming little endian Alphas in cases 0x01 -- 0x03 ... */ + + case 0x02: /* Buffer 16-bit aligned */ + --count; + + l = inl(port); + *(unsigned short *) dst = l; + ((unsigned short *) dst)++; + + while (count--) + { + l2 = inl(port); + *(unsigned int *) dst = l >> 16 | l2 << 16; + ((unsigned int *) dst)++; + l = l2; + } + *(unsigned short *) dst = l >> 16; + break; + case 0x01: /* Buffer 8-bit aligned */ + --count; + + l = inl(port); + *(unsigned char *) dst = l; + ((unsigned char *) dst)++; + *(unsigned short *) dst = l >> 8; + ((unsigned short *) dst)++; + while (count--) + { + l2 = inl(port); + *(unsigned int *) dst = l >> 24 | l2 << 8; + ((unsigned int *) dst)++; + l = l2; + } + *(unsigned char *) dst = l >> 24; + break; + case 0x03: /* Buffer 8-bit aligned */ --count; - *(unsigned int *) dst = inl(port); - ((unsigned int *) dst)++; + + l = inl(port); + *(unsigned char *) dst = l; + ((unsigned char *) dst)++; + while (count--) + { + l2 = inl(port); + *(unsigned int *) dst = l << 24 | l2 >> 8; + ((unsigned int *) dst)++; + l = l2; + } + *(unsigned short *) dst = l >> 8; + ((unsigned short *) dst)++; + *(unsigned char *) dst = l >> 24; + break; } } + /* * Like insb but in the opposite direction. * Don't worry as much about doing aligned memory transfers: @@ -223,20 +282,79 @@ /* * Like insl but in the opposite direction. This is used by the IDE - * driver to write disk sectors. Performance is important, but the - * interfaces seems to be slow: just using the inlined version of the - * outw() breaks things. + * driver to write disk sectors. Works with any alignment in SRC. + * Performance is important, but the interfaces seems to be slow: + * just using the inlined version of the outl() breaks things. */ void outsl (unsigned long port, const void *src, unsigned long count) { - if (((unsigned long)src) & 0x3) { - panic("outsw: memory not aligned"); - } - - while (count) { + unsigned int l = 0, l2; + + if (!count) + return; + + switch (((unsigned long) src) & 0x3) + { + case 0x00: /* Buffer 32-bit aligned */ + while (count--) + { + outl(*(unsigned int *) src, port); + ((unsigned int *) src)++; + } + break; + + /* Assuming little endian Alphas in cases 0x01 -- 0x03 ... */ + + case 0x02: /* Buffer 16-bit aligned */ --count; - outl(*(unsigned int *) src, port); - ((unsigned int *) src)++; + + l = *(unsigned short *) src << 16; + ((unsigned short *) src)++; + + while (count--) + { + l2 = *(unsigned int *) src; + ((unsigned int *) src)++; + outl (l >> 16 | l2 << 16, port); + l = l2; + } + l2 = *(unsigned short *) src; + outl (l >> 16 | l2 << 16, port); + break; + case 0x01: /* Buffer 8-bit aligned */ + --count; + + l = *(unsigned char *) src << 8; + ((unsigned char *) src)++; + l |= *(unsigned short *) src << 16; + ((unsigned short *) src)++; + while (count--) + { + l2 = *(unsigned int *) src; + ((unsigned int *) src)++; + outl (l >> 8 | l2 << 24, port); + l = l2; + } + l2 = *(unsigned char *) src; + outl (l >> 8 | l2 << 24, port); + break; + case 0x03: /* Buffer 8-bit aligned */ + --count; + + l = *(unsigned char *) src << 24; + ((unsigned char *) src)++; + while (count--) + { + l2 = *(unsigned int *) src; + ((unsigned int *) src)++; + outl (l >> 24 | l2 << 8, port); + l = l2; + } + l2 = *(unsigned short *) src; + ((unsigned short *) src)++; + l2 |= *(unsigned char *) src << 16; + outl (l >> 24 | l2 << 8, port); + break; } } diff -u --recursive --new-file v2.0.13/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c --- v2.0.13/linux/arch/alpha/mm/init.c Sat Aug 17 21:19:26 1996 +++ linux/arch/alpha/mm/init.c Sun Aug 18 10:37:57 1996 @@ -131,8 +131,8 @@ newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT; pgd_val(swapper_pg_dir[1023]) = (newptbr << 32) | pgprot_val(PAGE_KERNEL); init_task.tss.ptbr = newptbr; - init_task.tss.flags = 1; - init_task.tss.segment = KERNEL_DS; + init_task.tss.pal_flags = 1; /* set FEN, clear everything else */ + init_task.tss.flags = 0; init_task.kernel_stack_page = INIT_STACK; load_PCB(&init_task.tss); diff -u --recursive --new-file v2.0.13/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.0.13/linux/drivers/block/genhd.c Thu Aug 1 15:53:34 1996 +++ linux/drivers/block/genhd.c Tue Aug 20 16:44:45 1996 @@ -37,6 +37,7 @@ */ #include +#define SYS_IND(p) get_unaligned(&p->sys_ind) #define NR_SECTS(p) get_unaligned(&p->nr_sects) #define START_SECT(p) get_unaligned(&p->start_sect) @@ -100,8 +101,8 @@ static inline int is_extended_partition(struct partition *p) { - return (p->sys_ind == DOS_EXTENDED_PARTITION || - p->sys_ind == LINUX_EXTENDED_PARTITION); + return (SYS_IND(p) == DOS_EXTENDED_PARTITION || + SYS_IND(p) == LINUX_EXTENDED_PARTITION); } #ifdef CONFIG_MSDOS_PARTITION @@ -277,7 +278,7 @@ */ extern int ide_xlate_1024(kdev_t, int, const char *); unsigned int sig = *(unsigned short *)(data + 2); - if (p->sys_ind == EZD_PARTITION) { + if (SYS_IND(p) == EZD_PARTITION) { /* * The remainder of the disk must be accessed using * a translated geometry that reduces the number of @@ -290,7 +291,7 @@ data += 512; goto check_table; } - } else if (p->sys_ind == DM6_PARTITION) { + } else if (SYS_IND(p) == DM6_PARTITION) { /* * Everything on the disk is offset by 63 sectors, @@ -313,7 +314,7 @@ * DM6 signature in MBR, courtesy of OnTrack */ (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]"); - } else if (p->sys_ind == DM6_AUX1PARTITION || p->sys_ind == DM6_AUX3PARTITION) { + } else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) { /* * DM6 on other than the first (boot) drive */ @@ -364,7 +365,7 @@ hd->part[minor].nr_sects = 2; } #ifdef CONFIG_BSD_DISKLABEL - if (p->sys_ind == BSD_PARTITION) { + if (SYS_IND(p) == BSD_PARTITION) { printk(" <"); bsd_disklabel_partition(hd, MKDEV(hd->major, minor)); printk(" >"); diff -u --recursive --new-file v2.0.13/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c --- v2.0.13/linux/drivers/block/ide-tape.c Fri May 3 11:07:24 1996 +++ linux/drivers/block/ide-tape.c Sat Aug 17 20:51:18 1996 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-tape.c Version 1.5 - ALPHA Apr 12, 1996 + * linux/drivers/block/ide-tape.c Version 1.6 - ALPHA Aug 16, 1996 * * Copyright (C) 1995, 1996 Gadi Oxman * @@ -184,6 +184,8 @@ * Ver 1.5 Apr 12 96 Fixed shared interface operation, broken in 1.3.85. * Fixed pipelined read mode inefficiency. * Fixed nasty null dereferencing bug. + * Ver 1.6 Aug 16 96 Fixed FPU usage in the driver. + * Fixed end of media bug. * * We are currently in an *alpha* stage. The driver is not complete and not * much tested. I would strongly suggest to: @@ -1224,8 +1226,7 @@ { idetape_tape_t *tape=&(drive->tape); unsigned int allocation_length; - double service_time,nr_units; - + #if IDETAPE_DEBUG_LOG printk ("ide-tape: Reached idetape_setup\n"); #endif /* IDETAPE_DEBUG_LOG */ @@ -1259,8 +1260,11 @@ idetape_get_mode_sense_results (drive); - tape->data_buffer_size=tape->capabilities.ctl*tape->tape_block_size; - + tape->data_buffer_size = tape->capabilities.ctl * tape->tape_block_size; + while (tape->data_buffer_size > 0xffff) { + tape->capabilities.ctl /= 2; + tape->data_buffer_size = tape->capabilities.ctl * tape->tape_block_size; + } allocation_length=tape->data_buffer_size; if (tape->data_buffer_size % IDETAPE_ALLOCATION_BLOCK) allocation_length+=IDETAPE_ALLOCATION_BLOCK; @@ -1304,14 +1308,11 @@ * constantly streaming. */ - service_time=((double) tape->data_buffer_size/1024.0)/((double) tape->capabilities.speed*(1000.0/1024.0)); - nr_units=(double) tape->capabilities.buffer_size*512.0/(double) tape->data_buffer_size; - if (tape->max_number_of_stages) - tape->best_dsc_rw_frequency=(unsigned long) (0.5*nr_units*service_time*HZ); - else - tape->best_dsc_rw_frequency=(unsigned long) (service_time*HZ); - + tape->best_dsc_rw_frequency = (unsigned long) ((tape->capabilities.buffer_size * 32 * HZ) / (tape->capabilities.speed * 125)); + else + tape->best_dsc_rw_frequency = (unsigned long) ((tape->data_buffer_size * HZ) / (tape->capabilities.speed * 1000)); + /* * Ensure that the number we got makes sense. */ @@ -2105,6 +2106,7 @@ void idetape_retry_pc (ide_drive_t *drive) { + idetape_tape_t *tape = &drive->tape; idetape_packet_command_t *pc; struct request *new_rq; @@ -2116,6 +2118,7 @@ pc->buffer=pc->temp_buffer; pc->buffer_size=IDETAPE_TEMP_BUFFER_SIZE; pc->current_position=pc->temp_buffer; + tape->reset_issued = 1; idetape_queue_pc_head (drive,pc,new_rq); } @@ -3217,7 +3220,7 @@ rq.sector = tape->block_address; rq.nr_sectors = rq.current_nr_sectors = blocks; - if (tape->active_data_request != NULL || tape->current_number_of_stages <= 0.25*tape->max_number_of_stages) { + if (tape->active_data_request != NULL || tape->current_number_of_stages <= tape->max_number_of_stages / 4) { new_stage=idetape_kmalloc_stage (drive); while (new_stage != NULL) { new_stage->rq=rq; @@ -3335,7 +3338,7 @@ * keep up with the higher speeds of the tape. */ - if (tape->active_data_request == NULL && tape->current_number_of_stages >= 0.75*tape->max_number_of_stages) + if (tape->active_data_request == NULL && tape->current_number_of_stages >= (3 * tape->max_number_of_stages) / 4) idetape_insert_pipeline_into_queue (drive); if (tape->error_in_pipeline_stage) { /* Return a deferred error */ @@ -4458,8 +4461,7 @@ printk ("Reached idetape_increase_max_pipeline_stages\n"); #endif /* IDETAPE_DEBUG_LOG */ - tape->max_number_of_stages+=IDETAPE_INCREASE_STAGES_RATE* - (IDETAPE_MAX_PIPELINE_STAGES-IDETAPE_MIN_PIPELINE_STAGES); + tape->max_number_of_stages+=IDETAPE_INCREASE_STAGES_RATE; if (tape->max_number_of_stages >= IDETAPE_MAX_PIPELINE_STAGES) tape->max_number_of_stages = IDETAPE_MAX_PIPELINE_STAGES; diff -u --recursive --new-file v2.0.13/linux/drivers/block/ide-tape.h linux/drivers/block/ide-tape.h --- v2.0.13/linux/drivers/block/ide-tape.h Fri May 3 11:07:24 1996 +++ linux/drivers/block/ide-tape.h Sat Aug 17 20:51:18 1996 @@ -53,7 +53,7 @@ #define IDETAPE_MIN_PIPELINE_STAGES 100 #define IDETAPE_MAX_PIPELINE_STAGES 200 -#define IDETAPE_INCREASE_STAGES_RATE 0.2 +#define IDETAPE_INCREASE_STAGES_RATE 20 /* * Assuming the tape shares an interface with another device, the default diff -u --recursive --new-file v2.0.13/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v2.0.13/linux/drivers/net/3c509.c Mon Aug 5 10:13:52 1996 +++ linux/drivers/net/3c509.c Sun Aug 18 11:22:50 1996 @@ -47,11 +47,11 @@ #include #include #include /* for CONFIG_MCA */ +#include /* for udelay() */ #include #include - #ifdef EL3_DEBUG int el3_debug = EL3_DEBUG; #else @@ -310,28 +310,24 @@ */ static ushort read_eeprom(short ioaddr, int index) { - int timer; - outw(EEPROM_READ + index, ioaddr + 10); /* Pause for at least 162 us. for the read to take place. */ - for (timer = 0; timer < 162*4 + 400; timer++) - SLOW_DOWN_IO; + udelay (200); return inw(ioaddr + 12); } /* Read a word from the EEPROM when in the ISA ID probe state. */ static ushort id_read_eeprom(int index) { - int timer, bit, word = 0; + int bit, word = 0; /* Issue read command, and pause for at least 162 us. for it to complete. Assume extra-fast 16Mhz bus. */ outb(EEPROM_READ + index, id_port); - /* This should really be done by looking at one of the timer channels. */ - for (timer = 0; timer < 162*4 + 400; timer++) - SLOW_DOWN_IO; - + /* Pause for at least 162 us. for the read to take place. */ + udelay (200); + for (bit = 15; bit >= 0; bit--) word = (word << 1) + (inb(id_port) & 0x01); diff -u --recursive --new-file v2.0.13/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c --- v2.0.13/linux/drivers/net/de4x5.c Tue Jul 9 08:08:18 1996 +++ linux/drivers/net/de4x5.c Tue Aug 20 08:45:26 1996 @@ -205,11 +205,16 @@ reported by and . Upgraded alloc_device() code. + 0.431 28-Jun-96 Fix potential bug in queue_pkt() from discussion + with + 0.44 13-Aug-96 Fix RX overflow bug in 2114[023] chips. + Fix EISA probe bugs reported by + and ========================================================================= */ -static const char *version = "de4x5.c:v0.43 96/6/21 davies@wanton.lkg.dec.com\n"; +static const char *version = "de4x5.c:v0.44 96/8/13 davies@wanton.lkg.dec.com\n"; #include @@ -344,6 +349,7 @@ #define MAX_EISA_SLOTS 16 #define EISA_SLOT_INC 0x1000 +#define EISA_ALLOWED_IRQ_LIST {5, 9, 10, 11} #define DE4X5_SIGNATURE {"DE425","DE434","DE435","DE450","DE500"} #define DE4X5_NAME_LENGTH 8 @@ -534,6 +540,7 @@ int save_cnt; /* Flag if state already saved */ struct sk_buff *skb; /* Save the (re-ordered) skb's */ } cache; + int rx_ovf; /* Check for 'RX overflow' tag */ }; /* @@ -571,6 +578,7 @@ static void de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int de4x5_close(struct device *dev); static struct enet_statistics *de4x5_get_stats(struct device *dev); +static void de4x5_local_stats(struct device *dev, char *buf, int pkt_len); static void set_multicast_list(struct device *dev); static int de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd); @@ -584,6 +592,7 @@ static int de4x5_tx(struct device *dev); static int de4x5_ast(struct device *dev); static int de4x5_txur(struct device *dev); +static int de4x5_rx_ovfc(struct device *dev); static int autoconf_media(struct device *dev); static void create_packet(struct device *dev, char *frame, int len); @@ -672,7 +681,9 @@ #endif /* MODULE */ static char name[DE4X5_NAME_LENGTH + 1]; +static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST; static int num_de4x5s = 0, num_eth = 0; +static int cfrv = 0; /* ** Miscellaneous defines... @@ -756,10 +767,10 @@ dev->base_addr = iobase; if (lp->bus == EISA) { - printk("%s: %s at %04lx (EISA slot %ld)", + printk("%s: %s at 0x%04lx (EISA slot %ld)", dev->name, name, iobase, ((iobase>>12)&0x0f)); } else { /* PCI port address */ - printk("%s: %s at %04lx (PCI bus %d, device %d)", dev->name, name, + printk("%s: %s at 0x%04lx (PCI bus %d, device %d)", dev->name, name, iobase, lp->bus_num, lp->device); } @@ -888,6 +899,12 @@ /* Create a loopback packet frame for later media probing */ create_packet(dev, lp->frame, sizeof(lp->frame)); + /* Check if the RX overflow bug needs testing for */ + tmpchs = cfrv & 0x000000fe; + if ((lp->chipset == DC21140) && (tmpchs == 0x20)) { + lp->rx_ovf = 1; + } + /* Initialise the adapter state */ lp->state = CLOSED; @@ -1128,26 +1145,21 @@ } while (skb && !dev->tbusy && !lp->tx_skb[lp->tx_new]) { - set_bit(0, (void*)&dev->tbusy); cli(); - if (TX_BUFFS_AVAIL) { /* Fill in a Tx ring entry */ - load_packet(dev, skb->data, - TD_IC | TD_LS | TD_FS | skb->len, skb); - outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */ + set_bit(0, (void*)&dev->tbusy); + load_packet(dev, skb->data, TD_IC | TD_LS | TD_FS | skb->len, skb); + outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */ - lp->tx_new = (++lp->tx_new) % lp->txRingSize; - dev->trans_start = jiffies; + lp->tx_new = (++lp->tx_new) % lp->txRingSize; + dev->trans_start = jiffies; - if (TX_BUFFS_AVAIL) { - dev->tbusy = 0; /* Another pkt may be queued */ - } - skb = de4x5_get_cache(dev); + if (TX_BUFFS_AVAIL) { + dev->tbusy = 0; /* Another pkt may be queued */ } + skb = de4x5_get_cache(dev); sti(); } - if (skb && (dev->tbusy || lp->tx_skb[lp->tx_new])) { - de4x5_putb_cache(dev, skb); - } + if (skb) de4x5_putb_cache(dev, skb); } lp->cache.lock = 0; @@ -1234,13 +1246,20 @@ de4x5_rx(struct device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - int i, entry; + u_long iobase = dev->base_addr; + int entry; s32 status; - char *buf; for (entry=lp->rx_new; lp->rx_ring[entry].status>=0;entry=lp->rx_new) { status = lp->rx_ring[entry].status; + if (lp->rx_ovf) { + if (inl(DE4X5_MFC) & MFC_FOCM) { + de4x5_rx_ovfc(dev); + break; + } + } + if (status & RD_FS) { /* Remember the start of frame */ lp->rx_old = entry; } @@ -1269,34 +1288,13 @@ } de4x5_dbg_rx(skb, pkt_len); - /* Push up the protocol stack */ + /* Push up the protocol stack */ skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); /* Update stats */ lp->stats.rx_packets++; - for (i=1; ipktStats.bins[i]++; - i = DE4X5_PKT_STAT_SZ; - } - } - buf = skb->data; /* Look at the dest addr */ - if (buf[0] & 0x01) { /* Multicast/Broadcast */ - if ((*(s32 *)&buf[0] == -1) && (*(s16 *)&buf[4] == -1)) { - lp->pktStats.broadcast++; - } else { - lp->pktStats.multicast++; - } - } else if ((*(s32 *)&buf[0] == *(s32 *)&dev->dev_addr[0]) && - (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) { - lp->pktStats.unicast++; - } - - lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */ - if (lp->pktStats.bins[0] == 0) { /* Reset counters */ - memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats)); - } + de4x5_local_stats(dev, skb->data, pkt_len); } /* Change buffer ownership for this frame, back to the adapter */ @@ -1338,7 +1336,6 @@ if (status & TD_NC) lp->stats.tx_carrier_errors++; if (status & TD_LC) lp->stats.tx_window_errors++; if (status & TD_UF) lp->stats.tx_fifo_errors++; - if (status & TD_LC) lp->stats.collisions++; if (status & TD_EC) lp->pktStats.excessive_collisions++; if (status & TD_DE) lp->stats.tx_aborted_errors++; @@ -1353,6 +1350,10 @@ lp->lostMedia = 0; /* Remove transient problem */ lp->linkOK++; } + /* Update the collision counter */ + lp->stats.collisions += ((status & TD_EC) ? 16 : + ((status & TD_CC) >> 3)); + /* Free the buffer. */ if (lp->tx_skb[entry] != NULL) { dev_kfree_skb(lp->tx_skb[entry], FREE_WRITE); @@ -1416,6 +1417,27 @@ return 0; } +static int +de4x5_rx_ovfc(struct device *dev) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int iobase = dev->base_addr; + int omr; + + omr = inl(DE4X5_OMR); + outl(omr & ~OMR_SR, DE4X5_OMR); + while (inl(DE4X5_STS) & STS_RS); + + for (; lp->rx_ring[lp->rx_new].status>=0;) { + lp->rx_ring[lp->rx_new].status = R_OWN; + lp->rx_new = (++lp->rx_new % lp->rxRingSize); + } + + outl(omr, DE4X5_OMR); + + return 0; +} + static int de4x5_close(struct device *dev) { @@ -1469,6 +1491,37 @@ } static void +de4x5_local_stats(struct device *dev, char *buf, int pkt_len) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int i; + + for (i=1; ipktStats.bins[i]++; + i = DE4X5_PKT_STAT_SZ; + } + } + if (buf[0] & 0x01) { /* Multicast/Broadcast */ + if ((*(s32 *)&buf[0] == -1) && (*(s16 *)&buf[4] == -1)) { + lp->pktStats.broadcast++; + } else { + lp->pktStats.multicast++; + } + } else if ((*(s32 *)&buf[0] == *(s32 *)&dev->dev_addr[0]) && + (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) { + lp->pktStats.unicast++; + } + + lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */ + if (lp->pktStats.bins[0] == 0) { /* Reset counters */ + memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats)); + } + + return; +} + +static void load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -1608,11 +1661,16 @@ for (status = -ENODEV; (i> 16); vendor = (u_short) cfid; + /* Read the EISA Configuration Registers */ + dev->irq = inb(EISA_REG0); + dev->irq = de4x5_irq[(dev->irq >> 1) & 0x03]; + lp->chipset = device; - DevicePresent(EISA_APROM); + DevicePresent(DE4X5_APROM); /* Write the PCI Configuration Registers */ outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS); outl(0x00006000, PCI_CFLT); @@ -1690,6 +1748,9 @@ /* Set the chipset information */ lp->chipset = device; + /* Get the chip configuration revision register */ + pcibios_read_config_dword(pb, PCI_DEVICE, PCI_REVISION_ID, &cfrv); + /* Get the board I/O address */ pcibios_read_config_dword(pb, PCI_DEVICE, PCI_BASE_ADDRESS_0, &iobase); iobase &= CBIO_MASK; @@ -3552,7 +3613,10 @@ /* Restore CSR6 */ outl(omr, DE4X5_OMR); - + + /* Reset CSR8 */ + inl(DE4X5_MFC); + return omr; } @@ -3579,6 +3643,9 @@ /* Restore CSR6 */ outl(omr, DE4X5_OMR); + /* Reset CSR8 */ + inl(DE4X5_MFC); + return omr; } diff -u --recursive --new-file v2.0.13/linux/drivers/net/de4x5.h linux/drivers/net/de4x5.h --- v2.0.13/linux/drivers/net/de4x5.h Sat Apr 27 11:14:49 1996 +++ linux/drivers/net/de4x5.h Tue Aug 20 08:45:26 1996 @@ -337,10 +337,19 @@ #define IMR_TIM 0x00000001 /* Transmit Interrupt Mask */ /* -** DC21040 Missed Frame Counter (DE4X5_MFC) +** DC21040 Missed Frames Counter (DE4X5_MFC) */ -#define MFC_OVFL 0x00010000 /* Counter Overflow Bit */ -#define MFC_CNTR 0x0000ffff /* Counter Bits */ +#define MFC_OVFL 0x00010000 /* Missed Frames Counter Overflow Bit */ +#define MFC_CNTR 0x0000ffff /* Missed Frames Counter Bits */ + +/* +** DC21140 Missed Frames and FIFO Overflow Counters (DE4X5_MFC) +*/ +#define MFC_FOCO 0x10000000 /* FIFO Overflow Counter Overflow Bit */ +#define MFC_FOC 0x0ffe0000 /* FIFO Overflow Counter Bits */ +#define MFC_OVFL 0x00010000 /* Missed Frames Counter Overflow Bit */ +#define MFC_CNTR 0x0000ffff /* Missed Frames Counter Bits */ +#define MFC_FOCM 0x1ffe0000 /* FIFO Overflow Counter Mask */ /* ** DC21040 Ethernet Address PROM (DE4X5_APROM) diff -u --recursive --new-file v2.0.13/linux/drivers/net/depca.c linux/drivers/net/depca.c --- v2.0.13/linux/drivers/net/depca.c Mon Apr 29 17:11:39 1996 +++ linux/drivers/net/depca.c Tue Aug 20 08:45:26 1996 @@ -202,11 +202,13 @@ Add new multicasting code. 0.421 22-Apr-96 Fix alloc_device() bug 0.422 29-Apr-96 Fix depca_hw_init() bug + 0.423 7-Jun-96 Fix module load bug + 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c ========================================================================= */ -static const char *version = "depca.c:v0.422 96/4/29 davies@wanton.lkg.dec.com\n"; +static const char *version = "depca.c:v0.43 96/8/16 davies@wanton.lkg.dec.com\n"; #include @@ -231,6 +233,7 @@ #include #include #include +#include #include "depca.h" @@ -407,6 +410,8 @@ static void isa_probe(struct device *dev, u_long iobase); static void eisa_probe(struct device *dev, u_long iobase); static struct device *alloc_device(struct device *dev, u_long iobase); +static int depca_dev_index(char *s); +static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)); static int load_packet(struct device *dev, struct sk_buff *skb); static void depca_dbg_open(struct device *dev); @@ -483,22 +488,13 @@ outb(nicsr, DEPCA_NICSR); if (inw(DEPCA_DATA) == STOP) { - if (mem == 0) { - while (mem_base[mem_chkd]) { - mem_start = mem_base[mem_chkd++]; - DepcaSignature(name, mem_start); - if (*name != '\0') break; - } - } else { - mem_start = mem; - if (adapter_name) { - strcpy(name, adapter_name); - } else{ - DepcaSignature(name, mem_start); - } - } + do { + strcpy(name, (adapter_name ? adapter_name : "")); + mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]); + DepcaSignature(name, mem_start); + } while (!mem && mem_base[mem_chkd] && (adapter == unknown)); - if ((*name != '\0') && mem_start) { /* found a DEPCA device */ + if ((adapter != unknown) && mem_start) { /* found a DEPCA device */ dev->base_addr = ioaddr; if ((ioaddr&0x0fff)==DEPCA_EISA_IO_PORTS) {/* EISA slot address */ @@ -650,6 +646,8 @@ printk(" which has an Ethernet PROM CRC error.\n"); status = -ENXIO; } + } else { + status = -ENXIO; } if (!status) { if (depca_debug > 0) { @@ -1290,113 +1288,95 @@ } /* -** Allocate the device by pointing to the next available space in the -** device structure. Should one not be available, it is created. +** Search the entire 'eth' device list for a fixed probe. If a match isn't +** found then check for an autoprobe or unused device location. If they +** are not available then insert a new device structure at the end of +** the current list. */ -static struct device *alloc_device(struct device *dev, u_long iobase) +static struct device * +alloc_device(struct device *dev, u_long iobase) { - int addAutoProbe = 0; - struct device *tmp = NULL, *ret; - int (*init)(struct device *) = NULL; + struct device *adev = NULL; + int fixed = 0, new_dev = 0; - /* - ** Check the device structures for an end of list or unused device - */ - if (!loading_module) { - while (dev->next != NULL) { - if ((dev->base_addr == DEPCA_NDA) || (dev->base_addr == 0)) break; - dev = dev->next; /* walk through eth device list */ - num_eth++; /* increment eth device number */ + num_eth = depca_dev_index(dev->name); + if (loading_module) return dev; + + while (1) { + if (((dev->base_addr == DEPCA_NDA) || (dev->base_addr==0)) && !adev) { + adev=dev; + } else if ((dev->priv == NULL) && (dev->base_addr==iobase)) { + fixed = 1; + } else { + if (dev->next == NULL) { + new_dev = 1; + } else if (strncmp(dev->next->name, "eth", 3) != 0) { + new_dev = 1; + } + } + if ((dev->next == NULL) || new_dev || fixed) break; + dev = dev->next; + num_eth++; + } + if (adev && !fixed) { + dev = adev; + num_eth = depca_dev_index(dev->name); + new_dev = 0; } - /* - ** If an autoprobe is requested for another device, we must re-insert - ** the request later in the list. Remember the current information. - */ - if ((dev->base_addr == 0) && (num_depcas > 0)) { - addAutoProbe++; - tmp = dev->next; /* point to the next device */ - init = dev->init; /* remember the probe function */ + if (((dev->next == NULL) && + ((dev->base_addr != DEPCA_NDA) && (dev->base_addr != 0)) && !fixed) || + new_dev) { + num_eth++; /* New device */ + dev = insert_device(dev, iobase, depca_probe); } + + return dev; +} - /* - ** If at end of list and can't use current entry, malloc one up. - ** If memory could not be allocated, print an error message. - */ - if ((dev->next == NULL) && - !((dev->base_addr == DEPCA_NDA) || (dev->base_addr == 0))){ - dev->next = (struct device *)kmalloc(sizeof(struct device) + 8, - GFP_KERNEL); - - dev = dev->next; /* point to the new device */ - if (dev == NULL) { - printk("eth%d: Device not initialised, insufficient memory\n", - num_eth); - } else { - /* - ** If the memory was allocated, point to the new memory area - ** and initialize it (name, I/O address, next device (NULL) and - ** initialisation probe routine). - */ +/* +** If at end of eth device list and can't use current entry, malloc +** one up. If memory could not be allocated, print an error message. +*/ +static struct device * +insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +{ + struct device *new; + + new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL); + if (new == NULL) { + printk("eth%d: Device not initialised, insufficient memory\n",num_eth); + return NULL; + } else { + new->next = dev->next; + dev->next = new; + dev = dev->next; /* point to the new device */ dev->name = (char *)(dev + 1); if (num_eth > 9999) { - sprintf(dev->name,"eth????"); /* New device name */ + sprintf(dev->name,"eth????");/* New device name */ } else { - sprintf(dev->name,"eth%d", num_eth);/* New device name */ + sprintf(dev->name,"eth%d", num_eth);/* New device name */ } - dev->base_addr = iobase; /* assign the io address */ - dev->next = NULL; /* mark the end of list */ - dev->init = &depca_probe; /* initialisation routine */ - num_depcas++; - } + dev->base_addr = iobase; /* assign the io address */ + dev->init = init; /* initialisation routine */ } - ret = dev; /* return current struct, or NULL */ - - /* - ** Now figure out what to do with the autoprobe that has to be inserted. - ** Firstly, search the (possibly altered) list for an empty space. - */ - if (ret != NULL) { - if (addAutoProbe) { - for (;(tmp->next!=NULL) && (tmp->base_addr!=DEPCA_NDA); tmp=tmp->next); - - /* - ** If no more device structures and can't use the current one, malloc - ** one up. If memory could not be allocated, print an error message. - */ - if ((tmp->next == NULL) && !(tmp->base_addr == DEPCA_NDA)) { - tmp->next = (struct device *)kmalloc(sizeof(struct device) + 8, - GFP_KERNEL); - tmp = tmp->next; /* point to the new device */ - if (tmp == NULL) { - printk("%s: Insufficient memory to extend the device list.\n", - dev->name); - } else { - /* - ** If the memory was allocated, point to the new memory area - ** and initialize it (name, I/O address, next device (NULL) and - ** initialisation probe routine). - */ - tmp->name = (char *)(tmp + 1); - if (num_eth > 9999) { - sprintf(tmp->name,"eth????"); /* New device name */ - } else { - sprintf(tmp->name,"eth%d", num_eth);/* New device name */ - } - tmp->base_addr = 0; /* re-insert the io address */ - tmp->next = NULL; /* mark the end of list */ - tmp->init = init; /* initialisation routine */ - } - } else { /* structure already exists */ - tmp->base_addr = 0; /* re-insert the io address */ - } - } + + return dev; +} + +static int +depca_dev_index(char *s) +{ + int i=0, j=0; + + for (;*s; s++) { + if (isdigit(*s)) { + j=1; + i = (i * 10) + (*s - '0'); + } else if (j) break; } - } else { - ret = dev; - } - return ret; + return i; } /* @@ -1410,12 +1390,13 @@ const char *signatures[] = DEPCA_SIGNATURE; char tmpstr[16]; - for (i=0;i<16;i++) { /* copy the first 16 bytes of ROM to */ - tmpstr[i] = readb(paddr+0xc000+i); /* a temporary string */ + /* Copy the first 16 bytes of ROM */ + for (i=0;i<16;i++) { + tmpstr[i] = readb(paddr+0xc000+i); } - strcpy(name,""); - for (i=0;*signatures[i]!='\0' && *name=='\0';i++) { + /* Check if PROM contains a valid string */ + for (i=0;*signatures[i]!='\0';i++) { for (j=0,k=0;j<16 && k - Added verify_area() calls in depca_ioctl() from + Added verify_area() calls in ewrk3_ioctl() from suggestion by . Add new multicasting code. 0.41 20-Jan-96 Fix IRQ set up problem reported by . 0.42 22-Apr-96 Fix alloc_device() bug + 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c ========================================================================= */ -static const char *version = "ewrk3.c:v0.42 96/4/22 davies@wanton.lkg.dec.com\n"; +static const char *version = "ewrk3.c:v0.43 96/8/16 davies@wanton.lkg.dec.com\n"; #include @@ -162,6 +163,7 @@ #include #include #include +#include #include "ewrk3.h" @@ -315,6 +317,8 @@ static void isa_probe(struct device *dev, u_long iobase); static void eisa_probe(struct device *dev, u_long iobase); static struct device *alloc_device(struct device *dev, u_long iobase); +static int ewrk3_dev_index(char *s); +static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)); #ifdef MODULE @@ -1368,113 +1372,95 @@ } /* -** Allocate the device by pointing to the next available space in the -** device structure. Should one not be available, it is created. +** Search the entire 'eth' device list for a fixed probe. If a match isn't +** found then check for an autoprobe or unused device location. If they +** are not available then insert a new device structure at the end of +** the current list. */ -static struct device *alloc_device(struct device *dev, u_long iobase) +static struct device * +alloc_device(struct device *dev, u_long iobase) { - int addAutoProbe = 0; - struct device *tmp = NULL, *ret; - int (*init)(struct device *) = NULL; + struct device *adev = NULL; + int fixed = 0, new_dev = 0; - /* - ** Check the device structures for an end of list or unused device - */ - if (!loading_module) { - while (dev->next != NULL) { - if ((dev->base_addr == EWRK3_NDA) || (dev->base_addr == 0)) break; - dev = dev->next; /* walk through eth device list */ - num_eth++; /* increment eth device number */ + num_eth = ewrk3_dev_index(dev->name); + if (loading_module) return dev; + + while (1) { + if (((dev->base_addr == EWRK3_NDA) || (dev->base_addr==0)) && !adev) { + adev=dev; + } else if ((dev->priv == NULL) && (dev->base_addr==iobase)) { + fixed = 1; + } else { + if (dev->next == NULL) { + new_dev = 1; + } else if (strncmp(dev->next->name, "eth", 3) != 0) { + new_dev = 1; + } + } + if ((dev->next == NULL) || new_dev || fixed) break; + dev = dev->next; + num_eth++; + } + if (adev && !fixed) { + dev = adev; + num_eth = ewrk3_dev_index(dev->name); + new_dev = 0; } - /* - ** If an autoprobe is requested for another device, we must re-insert - ** the request later in the list. Remember the current position first. - */ - if ((dev->base_addr == 0) && (num_ewrk3s > 0)) { - addAutoProbe++; - tmp = dev->next; /* point to the next device */ - init = dev->init; /* remember the probe function */ + if (((dev->next == NULL) && + ((dev->base_addr != EWRK3_NDA) && (dev->base_addr != 0)) && !fixed) || + new_dev) { + num_eth++; /* New device */ + dev = insert_device(dev, iobase, ewrk3_probe); } + + return dev; +} - /* - ** If at end of list and can't use current entry, malloc one up. - ** If memory could not be allocated, print an error message. - */ - if ((dev->next == NULL) && - !((dev->base_addr == EWRK3_NDA) || (dev->base_addr == 0))){ - dev->next = (struct device *)kmalloc(sizeof(struct device) + 8, - GFP_KERNEL); - - dev = dev->next; /* point to the new device */ - if (dev == NULL) { - printk("eth%d: Device not initialised, insufficient memory\n", - num_eth); - } else { - /* - ** If the memory was allocated, point to the new memory area - ** and initialize it (name, I/O address, next device (NULL) and - ** initialisation probe routine). - */ +/* +** If at end of eth device list and can't use current entry, malloc +** one up. If memory could not be allocated, print an error message. +*/ +static struct device * +insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +{ + struct device *new; + + new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL); + if (new == NULL) { + printk("eth%d: Device not initialised, insufficient memory\n",num_eth); + return NULL; + } else { + new->next = dev->next; + dev->next = new; + dev = dev->next; /* point to the new device */ dev->name = (char *)(dev + 1); if (num_eth > 9999) { - sprintf(dev->name,"eth????"); /* New device name */ + sprintf(dev->name,"eth????");/* New device name */ } else { - sprintf(dev->name,"eth%d", num_eth);/* New device name */ + sprintf(dev->name,"eth%d", num_eth);/* New device name */ } - dev->base_addr = iobase; /* assign the io address */ - dev->next = NULL; /* mark the end of list */ - dev->init = &ewrk3_probe; /* initialisation routine */ - num_ewrk3s++; - } + dev->base_addr = iobase; /* assign the io address */ + dev->init = init; /* initialisation routine */ } - ret = dev; /* return current struct, or NULL */ - - /* - ** Now figure out what to do with the autoprobe that has to be inserted. - ** Firstly, search the (possibly altered) list for an empty space. - */ - if (ret != NULL) { - if (addAutoProbe) { - for (;(tmp->next!=NULL) && (tmp->base_addr!=EWRK3_NDA); tmp=tmp->next); - /* - ** If no more device structures and can't use the current one, malloc - ** one up. If memory could not be allocated, print an error message. - */ - if ((tmp->next == NULL) && !(tmp->base_addr == EWRK3_NDA)) { - tmp->next = (struct device *)kmalloc(sizeof(struct device) + 8, - GFP_KERNEL); - tmp = tmp->next; /* point to the new device */ - if (tmp == NULL) { - printk("%s: Insufficient memory to extend the device list.\n", - dev->name); - } else { - /* - ** If the memory was allocated, point to the new memory area - ** and initialize it (name, I/O address, next device (NULL) and - ** initialisation probe routine). - */ - tmp->name = (char *)(tmp + 1); - if (num_eth > 9999) { - sprintf(tmp->name,"eth????"); /* New device name */ - } else { - sprintf(tmp->name,"eth%d", num_eth);/* New device name */ - } - tmp->base_addr = 0; /* re-insert the io address */ - tmp->next = NULL; /* mark the end of list */ - tmp->init = init; /* initialisation routine */ - } - } else { /* structure already exists */ - tmp->base_addr = 0; /* re-insert the io address */ - } - } + return dev; +} + +static int +ewrk3_dev_index(char *s) +{ + int i=0, j=0; + + for (;*s; s++) { + if (isdigit(*s)) { + j=1; + i = (i * 10) + (*s - '0'); + } else if (j) break; } - } else { - ret = dev; - } - return ret; + return i; } /* @@ -1927,9 +1913,9 @@ /* * Local variables: - * kernel-compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c ewrk3.c" + * compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c" * - * module-compile-command: "gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c ewrk3.c" + * compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c" * End: */ diff -u --recursive --new-file v2.0.13/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c --- v2.0.13/linux/drivers/net/wavelan.c Mon Mar 4 09:16:36 1996 +++ linux/drivers/net/wavelan.c Sat Aug 17 21:02:01 1996 @@ -69,7 +69,7 @@ extern int wavelan_probe(device *); /* See Space.c */ -static const char *version = "wavelan.c:v7 95/4/8\n"; +static const char *version = "wavelan.c:v8 96/8/18\n"; /* * Entry point forward declarations. @@ -786,6 +786,13 @@ #endif /* 0 */ 0x390, }; + static struct proc_dir_entry pe = + { + PROC_NET_WAVELAN, 7, "wavelan", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + wavelan_get_info + }; if (wavelan_debug > 0) printk("%s: ->wavelan_probe(dev=0x%x (base_addr=0x%x))\n", dev->name, (unsigned int)dev, (unsigned int)dev->base_addr); @@ -822,6 +829,8 @@ r = wavelan_probe1(dev, base_addr); if (wavelan_debug > 0) printk("%s: <-wavelan_probe(): %d\n", dev->name, r); + if (r == 0) + proc_net_register(&pe); return r; } @@ -834,13 +843,7 @@ { if (wavelan_debug > 0) printk("%s: <-wavelan_probe(): 0\n", dev->name); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_WAVELAN, 7, "wavelan", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - wavelan_get_info - }); - + proc_net_register(&pe); return 0; } } @@ -2495,6 +2498,7 @@ * Marc Meertens (Marc.Meertens@Utrecht.NCR.com), * Pauline Middelink (middelin@polyware.iaf.nl), * Robert Morris (rtm@das.harvard.edu), + * Jean Tourrilhes (jt@hplb.hpl.hp.com), * Girish Welling (welling@paul.rutgers.edu), * * Thanks go also to: @@ -2517,6 +2521,6 @@ * Please send bug reports, updates, comments to: * * Bruce Janson Email: bruce@cs.usyd.edu.au - * Basser Department of Computer Science Phone: +61-2-351-3423 - * University of Sydney, N.S.W., 2006, AUSTRALIA Fax: +61-2-351-3838 + * Basser Department of Computer Science Phone: +61-2-9351-3423 + * University of Sydney, N.S.W., 2006, AUSTRALIA Fax: +61-2-9351-3838 */ diff -u --recursive --new-file v2.0.13/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.0.13/linux/drivers/pci/pci.c Sat Aug 17 21:19:26 1996 +++ linux/drivers/pci/pci.c Sat Aug 17 21:03:34 1996 @@ -205,7 +205,9 @@ DEVICE( CYCLADES, CYCLOM_Z_Hi, "Cyclom-Z above 1Mbyte"), DEVICE( SYMPHONY, SYMPHONY_101, "82C101"), DEVICE( TEKRAM, TEKRAM_DC290, "DC-290"), + DEVICE( 3DLABS, 3DLABS_300SX, "GLINT 300SX"), DEVICE( AVANCE, AVANCE_2302, "ALG-2302"), + DEVICE( S3, S3_ViRGE, "ViRGE"), DEVICE( S3, S3_811, "Trio32/Trio64"), DEVICE( S3, S3_868, "Vision 868"), DEVICE( S3, S3_928, "Vision 928-P"), @@ -509,6 +511,7 @@ case PCI_VENDOR_ID_CYCLADES: return "Cyclades"; case PCI_VENDOR_ID_SYMPHONY: return "Symphony"; case PCI_VENDOR_ID_TEKRAM: return "Tekram"; + case PCI_VENDOR_ID_3DLABS: return "3Dlabs"; case PCI_VENDOR_ID_AVANCE: return "Avance"; case PCI_VENDOR_ID_S3: return "S3 Inc."; case PCI_VENDOR_ID_INTEL: return "Intel"; diff -u --recursive --new-file v2.0.13/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c --- v2.0.13/linux/drivers/scsi/aha152x.c Sun Jun 9 12:47:12 1996 +++ linux/drivers/scsi/aha152x.c Sat Aug 17 21:02:50 1996 @@ -20,9 +20,15 @@ * General Public License for more details. * * - * $Id: aha152x.c,v 1.16 1996/06/09 00:04:56 root Exp $ + * $Id: aha152x.c,v 1.17 1996/08/17 16:05:14 fischer Exp fischer $ * * $Log: aha152x.c,v $ + * Revision 1.17 1996/08/17 16:05:14 fischer + * - biosparam improved + * - interrupt verification + * - updated documentation + * - cleanups + * * Revision 1.16 1996/06/09 00:04:56 root * - added configuration symbols for insmod (aha152x/aha152x1) * @@ -39,7 +45,7 @@ * (to avoid spurious interrupts) * * Revision 1.12 1995/12/16 12:26:07 fischer - * - barrier()'s added + * - barrier()s added * - configurable RESET delay added * * Revision 1.11 1995/12/06 21:18:35 fischer @@ -177,34 +183,115 @@ DESCRIPTION: - This is the Linux low-level SCSI driver for Adaptec AHA-1520/1522 - SCSI host adapters. + This is the Linux low-level SCSI driver for Adaptec AHA-1520/1522 SCSI + host adapters. + + CONFIGURATION ARGUMENTS: - PER-DEFINE CONFIGURABLE OPTIONS: + IOPORT base io address (0x340/0x140) + IRQ interrupt level (9-12; default 11) + SCSI_ID scsi id of controller (0-7; default 7) + RECONNECT allow targets to disconnect from the bus (0/1; default 1 [on]) + PARITY enable parity checking (0/1; default 1 [on]) + SYNCHRONOUS enable synchronous transfers (0/1; default 0 [off]) + (NOT WORKING YET) + DELAY: bus reset delay (default 100) + EXT_TRANS: enable extended translation (0/1: default 0 [off]) + (see NOTES below) - AUTOCONF: - use configuration the controller reports (only 152x) + COMPILE TIME CONFIGURATION (put into AHA152X in drivers/scsi/Makefile): - SKIP_BIOSTEST: + -DAUTOCONF + use configuration the controller reports (AHA-152x only) + + -DSKIP_BIOSTEST Don't test for BIOS signature (AHA-1510 or disabled BIOS) - SETUP0 { IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY }: - override for the first controller + -DSETUP0="{ IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY, EXT_TRANS }" + override for the first controller - SETUP1 { IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY }: + -DSETUP1="{ IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY, EXT_TRANS }" override for the second controller LILO COMMAND LINE OPTIONS: - aha152x=[,[,[,[,[,[,]]]]]] + aha152x=[,[,[,[,[,[, [,1GB: + - take current geometry from the partition table + (using scsicam_bios_param and accept only `valid' geometries, + ie. either (C/32/64) or (C/63/255)). This can be extended + translation even if it's not enabled in the driver. + - if that fails, take extended translation if enabled by override, + kernel or module parameter, otherwise take default translation and + ask the user for verification. This might on not yet partitioned + disks or REFERENCES USED: @@ -257,6 +344,8 @@ #include "aha152x.h" #include +#include + struct proc_dir_entry proc_scsi_aha152x = { PROC_SCSI_AHA152X, 7, "aha152x", S_IFDIR | S_IRUGO | S_IXUGO, 2 @@ -338,11 +427,11 @@ #if defined(MODULE) #if defined(DEBUG_AHA152X) -int aha152x[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, DEBUG_DEFAULT }; -int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, DEBUG_DEFAULT }; +int aha152x[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT }; +int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT }; #else -int aha152x[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT }; -int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT }; +int aha152x[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 }; +int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 }; #endif #endif @@ -356,6 +445,7 @@ int parity; int synchronous; int delay; + int ext_trans; #ifdef DEBUG_AHA152X int debug; #endif @@ -365,14 +455,15 @@ static struct Scsi_Host *aha152x_host[IRQS]; #define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata) -#define CURRENT_SC (HOSTDATA(shpnt)->current_SC) -#define ISSUE_SC (HOSTDATA(shpnt)->issue_SC) -#define DISCONNECTED_SC (HOSTDATA(shpnt)->disconnected_SC) +#define CURRENT_SC (HOSTDATA(shpnt)->current_SC) +#define ISSUE_SC (HOSTDATA(shpnt)->issue_SC) +#define DISCONNECTED_SC (HOSTDATA(shpnt)->disconnected_SC) #define DELAY (HOSTDATA(shpnt)->delay) -#define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->target]) +#define EXT_TRANS (HOSTDATA(shpnt)->ext_trans) +#define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->target]) #define MSG(i) (HOSTDATA(shpnt)->message[i]) #define MSGLEN (HOSTDATA(shpnt)->message_len) -#define ADDMSG(x) (MSG(MSGLEN++)=x) +#define ADDMSG(x) (MSG(MSGLEN++)=x) struct aha152x_hostdata { Scsi_Cmnd *issue_SC; @@ -387,6 +478,9 @@ int parity; int synchronous; int delay; + int ext_trans; + + int swint; unsigned char syncrate[8]; @@ -441,12 +535,12 @@ #define ADDRESS_COUNT (sizeof(addresses) / sizeof(void *)) /* signatures for various AIC-6[23]60 based controllers. - The point in detecting signatures is to avoid useless - and maybe harmful probes on ports. I'm not sure that - all listed boards pass auto-configuration. For those - which fail the BIOS signature is obsolete, because - user intervention to supply the configuration is - needed anyway. */ + The point in detecting signatures is to avoid useless and maybe + harmful probes on ports. I'm not sure that all listed boards pass + auto-configuration. For those which fail the BIOS signature is + obsolete, because user intervention to supply the configuration is + needed anyway. May be an information whether or not the BIOS supports + extended translation could be also useful here. */ static struct signature { char *signature; int sig_offset; @@ -473,7 +567,7 @@ unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */ while (jiffies < the_time) - barrier(); + barrier(); } /* @@ -486,12 +580,11 @@ new_SC->host_scribble = (unsigned char *) NULL; if(!*SC) *SC=new_SC; - else - { - for(end=*SC; end->host_scribble; end = (Scsi_Cmnd *) end->host_scribble) - ; - end->host_scribble = (unsigned char *) new_SC; - } + else { + for(end=*SC; end->host_scribble; end = (Scsi_Cmnd *) end->host_scribble) + ; + end->host_scribble = (unsigned char *) new_SC; + } } static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd **SC) @@ -518,6 +611,7 @@ prev->host_scribble = ptr->host_scribble; else *SC= (Scsi_Cmnd *) ptr->host_scribble; + return ptr; } @@ -548,36 +642,30 @@ { int phase, sstat1; - while(1) - { - do - { - while(!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE|SCSIRSTI|REQINIT))) - barrier(); - if(sstat1 & BUSFREE) - return P_BUSFREE; - if(sstat1 & SCSIRSTI) - { - printk("aha152x: RESET IN\n"); - SETPORT(SSTAT1, SCSIRSTI); - } - } - while(TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT)); - - SETPORT(SSTAT1, CLRSCSIPERR); - - phase = GETPORT(SCSISIG) & P_MASK ; - - if(TESTHI(SSTAT1, SCSIPERR)) - { - if((phase & (CDO|MSGO))==0) /* DATA phase */ - return P_PARITY; + while(1) { + do { + while(!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE|SCSIRSTI|REQINIT))) + barrier(); + if(sstat1 & BUSFREE) + return P_BUSFREE; + if(sstat1 & SCSIRSTI) { + printk("aha152x: RESET IN\n"); + SETPORT(SSTAT1, SCSIRSTI); + } + } while(TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT)); - make_acklow(shpnt); - } - else - return phase; - } + SETPORT(SSTAT1, CLRSCSIPERR); + + phase = GETPORT(SCSISIG) & P_MASK ; + + if(TESTHI(SSTAT1, SCSIPERR)) { + if((phase & (CDO|MSGO))==0) /* DATA phase */ + return P_PARITY; + + make_acklow(shpnt); + } else + return phase; + } } /* called from init/main.c */ @@ -594,25 +682,23 @@ setup[setup_count].parity = ints[0] >= 5 ? ints[5] : 1; setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 0 /* FIXME: 1 */; setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT; + setup[setup_count].ext_trans = ints[0] >= 8 ? ints[8] : 0; #ifdef DEBUG_AHA152X - setup[setup_count].debug = ints[0] >= 8 ? ints[8] : DEBUG_DEFAULT; - if(ints[0]>8) - { - printk("aha152x: usage: aha152x=[,[," - "[,[,[,[,[,]]]]]]]\n"); + setup[setup_count].debug = ints[0] >= 9 ? ints[9] : DEBUG_DEFAULT; + if(ints[0]>9) { + printk("aha152x: usage: aha152x=[,[," + "[,[,[,[,[,[,]]]]]]]]\n"); #else - if(ints[0]>7) - { - printk("aha152x: usage: aha152x=[,[," - "[,[,[,[,]]]]]]\n"); + if(ints[0]>8) { + printk("aha152x: usage: aha152x=[,[," + "[,[,[,[,[,]]]]]]]\n"); #endif - } - else + } else setup_count++; } /* - Test, if port_base is valid. + * Test, if port_base is valid. */ static int aha152x_porttest(int io_port) { @@ -647,7 +733,7 @@ if(!aha152x_porttest(setup->io_port)) return 0; - if((setup->irq < IRQ_MIN) && (setup->irq > IRQ_MAX)) + if(setup->irqirq>IRQ_MAX) return 0; if((setup->scsiid < 0) || (setup->scsiid > 7)) @@ -661,10 +747,24 @@ if((setup->synchronous < 0) || (setup->synchronous > 1)) return 0; + + if((setup->ext_trans < 0) || (setup->ext_trans > 1)) + return 0; + return 1; } +void aha152x_swintr(int irqno, void *dev_id, struct pt_regs * regs) +{ + struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN]; + + if(!shpnt) + panic("aha152x: catched software interrupt for unknown controller.\n"); + + HOSTDATA(shpnt)->swint++; +} + int aha152x_detect(Scsi_Host_Template * tpnt) { @@ -678,56 +778,56 @@ for(i=0; iio_port = setup[i].io_port; - shpnt->n_io_port = IO_RANGE; - shpnt->irq = setup[i].irq; - - ISSUE_SC = (Scsi_Cmnd *) NULL; - CURRENT_SC = (Scsi_Cmnd *) NULL; - DISCONNECTED_SC = (Scsi_Cmnd *) NULL; - - HOSTDATA(shpnt)->reconnect = setup[i].reconnect; - HOSTDATA(shpnt)->parity = setup[i].parity; - HOSTDATA(shpnt)->synchronous = setup[i].synchronous; - HOSTDATA(shpnt)->delay = setup[i].delay; + for(i=0; iio_port = setup[i].io_port; + shpnt->n_io_port = IO_RANGE; + shpnt->irq = setup[i].irq; + + ISSUE_SC = (Scsi_Cmnd *) NULL; + CURRENT_SC = (Scsi_Cmnd *) NULL; + DISCONNECTED_SC = (Scsi_Cmnd *) NULL; + + HOSTDATA(shpnt)->reconnect = setup[i].reconnect; + HOSTDATA(shpnt)->parity = setup[i].parity; + HOSTDATA(shpnt)->synchronous = setup[i].synchronous; + HOSTDATA(shpnt)->delay = setup[i].delay; + HOSTDATA(shpnt)->ext_trans = setup[i].ext_trans; #ifdef DEBUG_AHA152X - HOSTDATA(shpnt)->debug = setup[i].debug; + HOSTDATA(shpnt)->debug = setup[i].debug; #endif - HOSTDATA(shpnt)->aborting = 0; - HOSTDATA(shpnt)->abortion_complete = 0; - HOSTDATA(shpnt)->abort_result = 0; - HOSTDATA(shpnt)->commands = 0; + HOSTDATA(shpnt)->aborting = 0; + HOSTDATA(shpnt)->abortion_complete = 0; + HOSTDATA(shpnt)->abort_result = 0; + HOSTDATA(shpnt)->commands = 0; - HOSTDATA(shpnt)->message_len = 0; + HOSTDATA(shpnt)->message_len = 0; - for(j=0; j<8; j++) - HOSTDATA(shpnt)->syncrate[j] = 0; + for(j=0; j<8; j++) + HOSTDATA(shpnt)->syncrate[j] = 0; - SETPORT(SCSIID, setup[i].scsiid << 4); - shpnt->this_id=setup[i].scsiid; + SETPORT(SCSIID, setup[i].scsiid << 4); + shpnt->this_id=setup[i].scsiid; - if(setup[i].reconnect) - shpnt->hostt->can_queue=AHA152X_MAXQUEUE; + if(setup[i].reconnect) + shpnt->hostt->can_queue=AHA152X_MAXQUEUE; - /* RESET OUT */ - SETBITS(SCSISEQ, SCSIRSTO); - do_pause(30); - CLRBITS(SCSISEQ, SCSIRSTO); - do_pause(setup[i].delay); + /* RESET OUT */ + SETBITS(SCSISEQ, SCSIRSTO); + do_pause(30); + CLRBITS(SCSISEQ, SCSIRSTO); + do_pause(setup[i].delay); - aha152x_reset_ports(shpnt); + aha152x_reset_ports(shpnt); - printk("aha152x%d: vital data: PORTBASE=0x%03x, IRQ=%d, SCSI ID=%d," - " reconnect=%s, parity=%s, synchronous=%s, delay=%d\n", - i, - shpnt->io_port, - shpnt->irq, - shpnt->this_id, - HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled", - HOSTDATA(shpnt)->parity ? "enabled" : "disabled", - HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled", - HOSTDATA(shpnt)->delay); + printk("aha152x%d: vital data: PORTBASE=0x%03x, IRQ=%d, SCSI ID=%d," + " reconnect=%s, parity=%s, synchronous=%s, delay=%d, extended translation=%s\n", + i, + shpnt->io_port, + shpnt->irq, + shpnt->this_id, + HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled", + HOSTDATA(shpnt)->parity ? "enabled" : "disabled", + HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled", + HOSTDATA(shpnt)->delay, + HOSTDATA(shpnt)->ext_trans ? "enabled" : "disabled"); + + request_region(shpnt->io_port, IO_RANGE, "aha152x"); /* Register */ + + /* not expecting any interrupts */ + SETPORT(SIMODE0, 0); + SETPORT(SIMODE1, 0); + + SETBITS(DMACNTRL0, INTEN); + + ok = request_irq(shpnt->irq, aha152x_swintr, SA_INTERRUPT, "aha152x", NULL); + if(ok<0) { + if(ok == -EINVAL) + printk("aha152x%d: bad IRQ %d.\n", i, shpnt->irq); + else if(ok == -EBUSY) + printk("aha152x%d: IRQ %d already in use.\n", i, shpnt->irq); + else + printk("\naha152x%d: Unexpected error code %d on requesting IRQ %d.\n", i, ok, shpnt->irq); + printk("aha152x: driver needs an IRQ.\n"); - request_region(shpnt->io_port, IO_RANGE, "aha152x"); /* Register */ - - /* not expecting any interrupts */ - SETPORT(SIMODE0, 0); - SETPORT(SIMODE1, 0); + scsi_unregister(shpnt); + shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0; + continue; + } - SETBITS(DMACNTRL0, INTEN); + HOSTDATA(shpnt)->swint=0; - ok = request_irq(setup[i].irq, aha152x_intr, SA_INTERRUPT, "aha152x", NULL); - - if(ok<0) - { - if(ok == -EINVAL) - { - printk("aha152x%d: bad IRQ %d.\n", i, setup[i].irq); - printk(" Contact author.\n"); - } - else - if(ok == -EBUSY) - printk("aha152x%d: IRQ %d already in use. Configure another.\n", - i, setup[i].irq); - else - { - printk("\naha152x%d: Unexpected error code on" - " requesting IRQ %d.\n", i, setup[i].irq); - printk(" Contact author.\n"); - } - printk("aha152x: driver needs an IRQ.\n"); - continue; - } + printk("aha152x: trying software interrupt, "); + SETBITS(DMACNTRL0, SWINT); + + the_time=jiffies+100; + while(!HOSTDATA(shpnt)->swint && jiffiesirq,0); + + if(!HOSTDATA(shpnt)->swint) { + if(TESTHI(DMASTAT, INTSTAT)) { + printk("lost.\n"); + } else { + printk("failed.\n"); + } + + printk("aha152x: IRQ %d possibly wrong. Please verify.\n", shpnt->irq); + + scsi_unregister(shpnt); + shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0; + continue; } + + printk("ok.\n"); + + CLRBITS(DMACNTRL0, SWINT); + + /* clear interrupts */ + SETPORT(SSTAT0, 0x7f); + SETPORT(SSTAT1, 0xef); + + if(request_irq(shpnt->irq,aha152x_intr,SA_INTERRUPT,"aha152x",NULL)<0) { + printk("aha152x: failed to reassign interrupt.\n"); + } + } return (setup_count>0); } @@ -943,14 +1079,13 @@ #endif #if defined(DEBUG_QUEUE) - if(HOSTDATA(shpnt)->debug & debug_queue) - { - printk("SCpnt (target = %d lun = %d cmnd = ", - SCpnt->target, SCpnt->lun); + if(HOSTDATA(shpnt)->debug & debug_queue) { + printk("SCpnt (target = %d lun = %d cmnd = ", + SCpnt->target, SCpnt->lun); print_command(SCpnt->cmnd); - printk(", cmd_len=%d, pieces = %d size = %u), ", - SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen); - disp_ports(shpnt); + printk(", cmd_len=%d, pieces = %d size = %u), ", + SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen); + disp_ports(shpnt); } #endif @@ -963,22 +1098,18 @@ SCp.buffers_residual : left buffers in list SCp.phase : current state of the command */ SCpnt->SCp.phase = not_issued; - if (SCpnt->use_sg) - { - SCpnt->SCp.buffer = - (struct scatterlist *) SCpnt->request_buffer; - SCpnt->SCp.ptr = SCpnt->SCp.buffer->address; - SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; - SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; - } - else - { - SCpnt->SCp.ptr = (char *)SCpnt->request_buffer; - SCpnt->SCp.this_residual = SCpnt->request_bufflen; - SCpnt->SCp.buffer = NULL; - SCpnt->SCp.buffers_residual = 0; - } - + if (SCpnt->use_sg) { + SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer; + SCpnt->SCp.ptr = SCpnt->SCp.buffer->address; + SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; + SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; + } else { + SCpnt->SCp.ptr = (char *)SCpnt->request_buffer; + SCpnt->SCp.this_residual = SCpnt->request_bufflen; + SCpnt->SCp.buffer = NULL; + SCpnt->SCp.buffers_residual = 0; + } + SCpnt->SCp.Status = CHECK_CONDITION; SCpnt->SCp.Message = 0; SCpnt->SCp.have_data_in = 0; @@ -998,11 +1129,10 @@ append_SC(&ISSUE_SC, SCpnt); /* Enable bus free interrupt, when we aren't currently on the bus */ - if(!CURRENT_SC) - { - SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); - SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); - } + if(!CURRENT_SC) { + SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); + SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); + } restore_flags(flags); #if defined(DEBUG_RACE) @@ -1035,10 +1165,9 @@ cli(); #if defined(DEBUG_ABORT) - if(HOSTDATA(shpnt)->debug & debug_abort) - { - printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned int) SCpnt); - show_queues(shpnt); + if(HOSTDATA(shpnt)->debug & debug_abort) { + printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned int) SCpnt); + show_queues(shpnt); } #endif @@ -1048,43 +1177,48 @@ prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble) ; - if(ptr) - { - /* dequeue */ - if(prev) - prev->host_scribble = ptr->host_scribble; - else - ISSUE_SC = (Scsi_Cmnd *) ptr->host_scribble; - restore_flags(flags); + if(ptr) { + /* dequeue */ + if(prev) + prev->host_scribble = ptr->host_scribble; + else + ISSUE_SC = (Scsi_Cmnd *) ptr->host_scribble; - ptr->host_scribble = NULL; - ptr->result = DID_ABORT << 16; - ptr->scsi_done(ptr); - return SCSI_ABORT_SUCCESS; - } + HOSTDATA(shpnt)->commands--; + + restore_flags(flags); + + ptr->host_scribble = NULL; + ptr->result = DID_ABORT << 16; + ptr->scsi_done(ptr); + + return SCSI_ABORT_SUCCESS; + } /* if the bus is busy or a command is currently processed, we can't do anything more */ - if (TESTLO(SSTAT1, BUSFREE) || (CURRENT_SC && CURRENT_SC!=SCpnt)) - { - /* fail abortion, if bus is busy */ + if (TESTLO(SSTAT1, BUSFREE) || (CURRENT_SC && CURRENT_SC!=SCpnt)) { + /* fail abortion, if bus is busy */ - if(!CURRENT_SC) - printk("bus busy w/o current command, "); + if(!CURRENT_SC) + printk("bus busy w/o current command, "); - restore_flags(flags); - return SCSI_ABORT_BUSY; - } + restore_flags(flags); + + return SCSI_ABORT_BUSY; + } /* bus is free */ - if(CURRENT_SC) - { + if(CURRENT_SC) { + HOSTDATA(shpnt)->commands--; + /* target entered bus free before COMMAND COMPLETE, nothing to abort */ restore_flags(flags); - CURRENT_SC->result = DID_ERROR << 16; - CURRENT_SC->scsi_done(CURRENT_SC); - CURRENT_SC = (Scsi_Cmnd *) NULL; + CURRENT_SC->result = DID_ERROR << 16; + CURRENT_SC->scsi_done(CURRENT_SC); + CURRENT_SC = (Scsi_Cmnd *) NULL; + return SCSI_ABORT_SUCCESS; } @@ -1094,54 +1228,57 @@ prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble) ; - if(ptr) - if(!HOSTDATA(shpnt)->aborting) - { - /* dequeue */ - if(prev) - prev->host_scribble = ptr->host_scribble; - else - DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble; - - /* set command current and initiate selection, - let the interrupt routine take care of the abortion */ - CURRENT_SC = ptr; - ptr->SCp.phase = in_selection|aborted; - SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target); - - ADDMSG(ABORT); - - /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */ - SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0)); - SETPORT(SIMODE1, ENSELTIMO); - - /* Enable SELECTION OUT sequence */ - SETBITS(SCSISEQ, ENSELO | ENAUTOATNO); - - SETBITS(DMACNTRL0, INTEN); - HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS; - HOSTDATA(shpnt)->aborting++; - HOSTDATA(shpnt)->abortion_complete=0; + if(!ptr) { + /* command wasn't found */ + printk("command not found\n"); + restore_flags(flags); - sti(); /* Hi Eric, guess what ;-) */ - - /* sleep until the abortion is complete */ - while(!HOSTDATA(shpnt)->abortion_complete) - barrier(); - HOSTDATA(shpnt)->aborting=0; - return HOSTDATA(shpnt)->abort_result; - } + return SCSI_ABORT_NOT_RUNNING; + } + + if(!HOSTDATA(shpnt)->aborting) { + /* dequeue */ + if(prev) + prev->host_scribble = ptr->host_scribble; else - { - /* we're already aborting a command */ - restore_flags(flags); - return SCSI_ABORT_BUSY; - } + DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble; - /* command wasn't found */ - printk("command not found\n"); - restore_flags(flags); - return SCSI_ABORT_NOT_RUNNING; + HOSTDATA(shpnt)->commands--; + + /* set command current and initiate selection, + let the interrupt routine take care of the abortion */ + CURRENT_SC = ptr; + ptr->SCp.phase = in_selection|aborted; + SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target); + + ADDMSG(ABORT); + + /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */ + SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0)); + SETPORT(SIMODE1, ENSELTIMO); + + /* Enable SELECTION OUT sequence */ + SETBITS(SCSISEQ, ENSELO | ENAUTOATNO); + + SETBITS(DMACNTRL0, INTEN); + HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS; + HOSTDATA(shpnt)->aborting++; + HOSTDATA(shpnt)->abortion_complete=0; + + sti(); /* Hi Eric, guess what ;-) */ + + /* sleep until the abortion is complete */ + while(!HOSTDATA(shpnt)->abortion_complete) + barrier(); + HOSTDATA(shpnt)->aborting=0; + + return HOSTDATA(shpnt)->abort_result; + } else { + /* we're already aborting a command */ + restore_flags(flags); + + return SCSI_ABORT_BUSY; + } } /* @@ -1182,7 +1319,7 @@ * Reset registers, reset a hanging bus and * kill active and disconnected commands for target w/o soft reset */ -int aha152x_reset(Scsi_Cmnd *SCpnt) +int aha152x_reset(Scsi_Cmnd *SCpnt, unsigned int unused) { struct Scsi_Host *shpnt = SCpnt->host; unsigned long flags; @@ -1191,74 +1328,66 @@ aha152x_reset_ports(shpnt); /* Reset, if bus hangs */ - if(TESTLO(SSTAT1, BUSFREE)) - { - CLRBITS(DMACNTRL0, INTEN); + if(TESTLO(SSTAT1, BUSFREE)) { + CLRBITS(DMACNTRL0, INTEN); #if defined(DEBUG_RESET) - if(HOSTDATA(shpnt)->debug & debug_reset) - { - printk("aha152x: reset(), bus not free: SCSI RESET OUT\n"); - show_queues(shpnt); - } + if(HOSTDATA(shpnt)->debug & debug_reset) { + printk("aha152x: reset(), bus not free: SCSI RESET OUT\n"); + show_queues(shpnt); + } #endif - ptr=CURRENT_SC; - if(ptr && !ptr->device->soft_reset) - { - ptr->host_scribble = NULL; - ptr->result = DID_RESET << 16; - ptr->scsi_done(CURRENT_SC); - CURRENT_SC=NULL; - } - - save_flags(flags); - cli(); - prev=NULL; ptr=DISCONNECTED_SC; - while(ptr) - { - if(!ptr->device->soft_reset) - { - if(prev) - prev->host_scribble = ptr->host_scribble; - else - DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble; - - next = (Scsi_Cmnd *) ptr->host_scribble; - - ptr->host_scribble = NULL; - ptr->result = DID_RESET << 16; - ptr->scsi_done(ptr); - - ptr = next; - } - else - { - prev=ptr; - ptr = (Scsi_Cmnd *) ptr->host_scribble; - } - } - restore_flags(flags); + ptr=CURRENT_SC; + if(ptr && !ptr->device->soft_reset) { + ptr->host_scribble = NULL; + ptr->result = DID_RESET << 16; + ptr->scsi_done(CURRENT_SC); + CURRENT_SC=NULL; + } + + save_flags(flags); + cli(); + prev=NULL; ptr=DISCONNECTED_SC; + while(ptr) { + if(!ptr->device->soft_reset) { + if(prev) + prev->host_scribble = ptr->host_scribble; + else + DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble; -#if defined(DEBUG_RESET) - if(HOSTDATA(shpnt)->debug & debug_reset) - { - printk("commands on targets w/ soft-resets:\n"); - show_queues(shpnt); - } -#endif - - /* RESET OUT */ - SETPORT(SCSISEQ, SCSIRSTO); - do_pause(30); - SETPORT(SCSISEQ, 0); - do_pause(DELAY); + next = (Scsi_Cmnd *) ptr->host_scribble; - SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); - SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); + ptr->host_scribble = NULL; + ptr->result = DID_RESET << 16; + ptr->scsi_done(ptr); + + ptr = next; + } else { + prev=ptr; + ptr = (Scsi_Cmnd *) ptr->host_scribble; + } + } + restore_flags(flags); - SETPORT(DMACNTRL0, INTEN); +#if defined(DEBUG_RESET) + if(HOSTDATA(shpnt)->debug & debug_reset) { + printk("commands on targets w/ soft-resets:\n"); + show_queues(shpnt); } +#endif + + /* RESET OUT */ + SETPORT(SCSISEQ, SCSIRSTO); + do_pause(30); + SETPORT(SCSISEQ, 0); + do_pause(DELAY); + + SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); + SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); + + SETPORT(DMACNTRL0, INTEN); + } return SCSI_RESET_SUCCESS; } @@ -1268,29 +1397,54 @@ */ int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array) { + struct Scsi_Host *shpnt=disk->device->host; + #if defined(DEBUG_BIOSPARAM) if(HOSTDATA(shpnt)->debug & debug_biosparam) printk("aha152x_biosparam: dev=%s, size=%d, ", kdevname(dev), disk->capacity); #endif - - if(disk->capacity<=1024*64*32) { - info_array[0]=64; - info_array[1]=32; - info_array[2]=disk->capacity / (64 * 32); - } else { - info_array[0] = 255; - info_array[1] = 63; - info_array[2] = disk->capacity / (255 * 63); - if(info_array[2] > 1023) - info_array[2]=1023; + + /* try default translation */ + info_array[0]=64; + info_array[1]=32; + info_array[2]=disk->capacity / (64 * 32); + + /* for disks >1GB do some guessing */ + if(info_array[2]>=1024) { + int info[3]; + + /* try to figure out the geometry from the partition table */ + if(scsicam_bios_param(disk, dev, info)<0 || + !((info[0]==64 && info[1]==32) || (info[0]==255 && info[1]==63))) { + if(EXT_TRANS) { + printk("aha152x: unable to verify geometry for disk with >1GB.\n" + " using extended translation.\n"); + info_array[0] = 255; + info_array[1] = 63; + info_array[2] = disk->capacity / (255 * 63); + } else { + printk("aha152x: unable to verify geometry for disk with >1GB.\n" + " Using default translation. Please verify yourself.\n" + " Perhaps you need to enable extended translation in the driver.\n" + " See /usr/src/linux/drivers/scsi/aha152x.c for details.\n"); + } + } else { + info_array[0]=info[0]; + info_array[1]=info[1]; + info_array[2]=info[2]; + + if(info[0]==255 && !EXT_TRANS) { + printk("aha152x: current partition table is using extended translation.\n" + " using it also, although it's not explicty enabled.\n"); + } + } } #if defined(DEBUG_BIOSPARAM) - if(HOSTDATA(shpnt)->debug & debug_biosparam) - { + if(HOSTDATA(shpnt)->debug & debug_biosparam) { printk("bios geometry: head=%d, sec=%d, cyl=%d\n", - info_array[0], info_array[1], info_array[2]); + info_array[0], info_array[1], info_array[2]); printk("WARNING: check, if the bios geometry is correct.\n"); } #endif @@ -1307,68 +1461,66 @@ Scsi_Cmnd *done_SC; #if defined(DEBUG_DONE) - if(HOSTDATA(shpnt)->debug & debug_done) - { + if(HOSTDATA(shpnt)->debug & debug_done) { printk("\naha152x: done(), "); disp_ports(shpnt); } #endif - if (CURRENT_SC) - { + if(CURRENT_SC) { #if defined(DEBUG_DONE) - if(HOSTDATA(shpnt)->debug & debug_done) - printk("done(%x), ", error); + if(HOSTDATA(shpnt)->debug & debug_done) + printk("done(%x), ", error); #endif - save_flags(flags); - cli(); + save_flags(flags); + cli(); - done_SC = CURRENT_SC; - CURRENT_SC = NULL; + done_SC = CURRENT_SC; + CURRENT_SC = NULL; - /* turn led off, when no commands are in the driver */ - HOSTDATA(shpnt)->commands--; - if(!HOSTDATA(shpnt)->commands) - SETPORT(PORTA, 0); /* turn led off */ + /* turn led off, when no commands are in the driver */ + HOSTDATA(shpnt)->commands--; + if(!HOSTDATA(shpnt)->commands) + SETPORT(PORTA, 0); /* turn led off */ #if defined(DEBUG_QUEUES) - if(HOSTDATA(shpnt)->debug & debug_queues) - printk("ok (%d), ", HOSTDATA(shpnt)->commands); + if(HOSTDATA(shpnt)->debug & debug_queues) + printk("ok (%d), ", HOSTDATA(shpnt)->commands); #endif - restore_flags(flags); + restore_flags(flags); - SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); - SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); + SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); + SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); +#if 0 +/* Why poll for the BUS FREE phase, when we have setup the interrupt!? */ #if defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & debug_phases) - printk("BUS FREE loop, "); + if(HOSTDATA(shpnt)->debug & debug_phases) + printk("BUS FREE loop, "); #endif - while(TESTLO(SSTAT1, BUSFREE)) - barrier(); + while(TESTLO(SSTAT1, BUSFREE)) + barrier(); #if defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & debug_phases) - printk("BUS FREE\n"); + if(HOSTDATA(shpnt)->debug & debug_phases) + printk("BUS FREE\n"); +#endif #endif - done_SC->result = error; - if(done_SC->scsi_done) - { + done_SC->result = error; + if(done_SC->scsi_done) { #if defined(DEBUG_DONE) - if(HOSTDATA(shpnt)->debug & debug_done) - printk("calling scsi_done, "); + if(HOSTDATA(shpnt)->debug & debug_done) + printk("calling scsi_done, "); #endif - done_SC->scsi_done(done_SC); + done_SC->scsi_done(done_SC); #if defined(DEBUG_DONE) - if(HOSTDATA(shpnt)->debug & debug_done) - printk("done returned, "); + if(HOSTDATA(shpnt)->debug & debug_done) + printk("done returned, "); #endif - } - else - panic("aha152x: current_SC->scsi_done() == NULL"); - } - else + } else + panic("aha152x: current_SC->scsi_done() == NULL"); + } else aha152x_panic(shpnt, "done() called outside of command"); } @@ -1390,9 +1542,12 @@ #endif #endif - /* no more interrupts from the controller, while we busy. + if(!shpnt) + panic("aha152x: catched interrupt for unknown controller.\n"); + + /* no more interrupts from the controller, while we're busy. INTEN has to be restored, when we're ready to leave - intr(). To avoid race conditions we have to return + intr(). To avoid race conditions, we have to return immediately afterwards. */ CLRBITS(DMACNTRL0, INTEN); sti(); /* Yes, sti() really needs to be here */ @@ -1403,104 +1558,98 @@ */ if(TESTHI(SSTAT0, SELDI) && DISCONNECTED_SC && - (!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection)) ) - { - int identify_msg, target, i; + (!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection)) ) { + int identify_msg, target, i; - /* Avoid conflicts when a target reconnects - while we are trying to connect to another. */ - if(CURRENT_SC) - { + /* Avoid conflicts when a target reconnects + while we are trying to connect to another. */ + if(CURRENT_SC) { #if defined(DEBUG_QUEUES) - if(HOSTDATA(shpnt)->debug & debug_queues) - printk("i+, "); + if(HOSTDATA(shpnt)->debug & debug_queues) + printk("i+, "); #endif - save_flags(flags); - cli(); - append_SC(&ISSUE_SC, CURRENT_SC); - CURRENT_SC=NULL; - restore_flags(flags); - } - - /* disable sequences */ - SETPORT(SCSISEQ, 0); - SETPORT(SSTAT0, CLRSELDI); - SETPORT(SSTAT1, CLRBUSFREE); + save_flags(flags); + cli(); + append_SC(&ISSUE_SC, CURRENT_SC); + CURRENT_SC=NULL; + restore_flags(flags); + } + + /* disable sequences */ + SETPORT(SCSISEQ, 0); + SETPORT(SSTAT0, CLRSELDI); + SETPORT(SSTAT1, CLRBUSFREE); #if defined(DEBUG_QUEUES) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_queues|debug_phases)) - printk("reselected, "); + if(HOSTDATA(shpnt)->debug & (debug_queues|debug_phases)) + printk("reselected, "); #endif - i = GETPORT(SELID) & ~(1 << shpnt->this_id); - target=0; - if(i) - for(; (i & 1)==0; target++, i>>=1) - ; - else - aha152x_panic(shpnt, "reconnecting target unknown"); + i = GETPORT(SELID) & ~(1 << shpnt->this_id); + target=0; + + if(i==0) + aha152x_panic(shpnt, "reconnecting target unknown"); + + for(; (i & 1)==0; target++, i>>=1) + ; #if defined(DEBUG_QUEUES) - if(HOSTDATA(shpnt)->debug & debug_queues) - printk("SELID=%02x, target=%d, ", GETPORT(SELID), target); + if(HOSTDATA(shpnt)->debug & debug_queues) + printk("SELID=%02x, target=%d, ", GETPORT(SELID), target); #endif - SETPORT(SCSIID, (shpnt->this_id << OID_) | target); - SETPORT(SCSISEQ, ENRESELI); + SETPORT(SCSIID, (shpnt->this_id << OID_) | target); + SETPORT(SCSISEQ, ENRESELI); - if(TESTLO(SSTAT0, SELDI)) - aha152x_panic(shpnt, "RESELI failed"); + if(TESTLO(SSTAT0, SELDI)) + aha152x_panic(shpnt, "RESELI failed"); - SETPORT(SCSIRATE, HOSTDATA(shpnt)->syncrate[target]&0x7f); + SETPORT(SCSIRATE, HOSTDATA(shpnt)->syncrate[target]&0x7f); - SETPORT(SCSISIG, P_MSGI); + SETPORT(SCSISIG, P_MSGI); - /* Get identify message */ - if((i=getphase(shpnt))!=P_MSGI) - { - printk("target doesn't enter MSGI to identify (phase=%02x)\n", i); - aha152x_panic(shpnt, "unknown lun"); - } - SETPORT(SCSISEQ, 0); + /* Get identify message */ + if((i=getphase(shpnt))!=P_MSGI) { + printk("target doesn't enter MSGI to identify (phase=%02x)\n", i); + aha152x_panic(shpnt, "unknown lun"); + } + SETPORT(SCSISEQ, 0); - SETPORT(SXFRCTL0, CH1); + SETPORT(SXFRCTL0, CH1); - identify_msg = GETPORT(SCSIBUS); + identify_msg = GETPORT(SCSIBUS); - if(!(identify_msg & IDENTIFY_BASE)) - { - printk("target=%d, inbound message (%02x) != IDENTIFY\n", - target, identify_msg); - aha152x_panic(shpnt, "unknown lun"); - } + if(!(identify_msg & IDENTIFY_BASE)) { + printk("target=%d, inbound message (%02x) != IDENTIFY\n", + target, identify_msg); + aha152x_panic(shpnt, "unknown lun"); + } #if defined(DEBUG_QUEUES) - if(HOSTDATA(shpnt)->debug & debug_queues) - printk("identify=%02x, lun=%d, ", identify_msg, identify_msg & 0x3f); + if(HOSTDATA(shpnt)->debug & debug_queues) + printk("identify=%02x, lun=%d, ", identify_msg, identify_msg & 0x3f); #endif - save_flags(flags); - cli(); + save_flags(flags); + cli(); #if defined(DEBUG_QUEUES) - if(HOSTDATA(shpnt)->debug & debug_queues) - printk("d-, "); + if(HOSTDATA(shpnt)->debug & debug_queues) + printk("d-, "); #endif - CURRENT_SC = remove_SC(&DISCONNECTED_SC, - target, - identify_msg & 0x3f); - - if(!CURRENT_SC) - { - printk("lun=%d, ", identify_msg & 0x3f); - aha152x_panic(shpnt, "no disconnected command for that lun"); - } + CURRENT_SC = remove_SC(&DISCONNECTED_SC, target, identify_msg & 0x3f); - CURRENT_SC->SCp.phase &= ~disconnected; - restore_flags(flags); + if(!CURRENT_SC) { + printk("lun=%d, ", identify_msg & 0x3f); + aha152x_panic(shpnt, "no disconnected command for that lun"); + } - make_acklow(shpnt); - if(getphase(shpnt)!=P_MSGI) { + CURRENT_SC->SCp.phase &= ~disconnected; + restore_flags(flags); + + make_acklow(shpnt); + if(getphase(shpnt)!=P_MSGI) { SETPORT(SIMODE0, 0); SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); #if defined(DEBUG_RACE) @@ -1509,63 +1658,59 @@ SETBITS(DMACNTRL0, INTEN); return; } - } + } /* Check, if we aren't busy with a command */ - if(!CURRENT_SC) - { - /* bus is free to issue a queued command */ - if(TESTHI(SSTAT1, BUSFREE) && ISSUE_SC) - { - save_flags(flags); - cli(); + if(!CURRENT_SC) { + /* bus is free to issue a queued command */ + if(TESTHI(SSTAT1, BUSFREE) && ISSUE_SC) { + save_flags(flags); + cli(); #if defined(DEBUG_QUEUES) - if(HOSTDATA(shpnt)->debug & debug_queues) - printk("i-, "); + if(HOSTDATA(shpnt)->debug & debug_queues) + printk("i-, "); #endif - CURRENT_SC = remove_first_SC(&ISSUE_SC); - restore_flags(flags); + CURRENT_SC = remove_first_SC(&ISSUE_SC); + restore_flags(flags); #if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases)) - printk("issuing command, "); + if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases)) + printk("issuing command, "); #endif - CURRENT_SC->SCp.phase = in_selection; + CURRENT_SC->SCp.phase = in_selection; #if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases)) - printk("selecting %d, ", CURRENT_SC->target); + if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases)) + printk("selecting %d, ", CURRENT_SC->target); #endif - SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target); + SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target); - /* Enable interrupts for SELECTION OUT DONE and SELECTION OUT INITIATED */ - SETPORT(SXFRCTL1, HOSTDATA(shpnt)->parity ? (ENSPCHK|ENSTIMER) : ENSTIMER); + /* Enable interrupts for SELECTION OUT DONE and SELECTION OUT INITIATED */ + SETPORT(SXFRCTL1, HOSTDATA(shpnt)->parity ? (ENSPCHK|ENSTIMER) : ENSTIMER); - /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */ - SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0)); - SETPORT(SIMODE1, ENSELTIMO); + /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */ + SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0)); + SETPORT(SIMODE1, ENSELTIMO); - /* Enable SELECTION OUT sequence */ - SETBITS(SCSISEQ, ENSELO | ENAUTOATNO); - - } - else - { - /* No command we are busy with and no new to issue */ - printk("aha152x: ignoring spurious interrupt, nothing to do\n"); - if(TESTHI(DMACNTRL0, SWINT)) { - printk("aha152x: SWINT is set! Why?\n"); - CLRBITS(DMACNTRL0, SWINT); - } - show_queues(shpnt); - } + /* Enable SELECTION OUT sequence */ + SETBITS(SCSISEQ, ENSELO | ENAUTOATNO); + + } else { + /* No command we are busy with and no new to issue */ + printk("aha152x: ignoring spurious interrupt, nothing to do\n"); + if(TESTHI(DMACNTRL0, SWINT)) { + printk("aha152x: SWINT is set! Why?\n"); + CLRBITS(DMACNTRL0, SWINT); + } + show_queues(shpnt); + } #if defined(DEBUG_RACE) - leave_driver("(selecting) intr"); + leave_driver("(selecting) intr"); #endif - SETBITS(DMACNTRL0, INTEN); - return; - } + SETBITS(DMACNTRL0, INTEN); + return; + } /* the bus is busy with something */ @@ -1575,126 +1720,120 @@ #endif /* we are waiting for the result of a selection attempt */ - if(CURRENT_SC->SCp.phase & in_selection) - { - if(TESTLO(SSTAT1, SELTO)) - /* no timeout */ - if(TESTHI(SSTAT0, SELDO)) - { - /* clear BUS FREE interrupt */ - SETPORT(SSTAT1, CLRBUSFREE); - - /* Disable SELECTION OUT sequence */ - CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO); - - /* Disable SELECTION OUT DONE interrupt */ - CLRBITS(SIMODE0, ENSELDO); - CLRBITS(SIMODE1, ENSELTIMO); - - if(TESTLO(SSTAT0, SELDO)) - { - printk("aha152x: passing bus free condition\n"); + if(CURRENT_SC->SCp.phase & in_selection) { + if(TESTLO(SSTAT1, SELTO)) + /* no timeout */ + if(TESTHI(SSTAT0, SELDO)) { + /* clear BUS FREE interrupt */ + SETPORT(SSTAT1, CLRBUSFREE); + + /* Disable SELECTION OUT sequence */ + CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO); + + /* Disable SELECTION OUT DONE interrupt */ + CLRBITS(SIMODE0, ENSELDO); + CLRBITS(SIMODE1, ENSELTIMO); + + if(TESTLO(SSTAT0, SELDO)) { + printk("aha152x: passing bus free condition\n"); #if defined(DEBUG_RACE) - leave_driver("(passing bus free) intr"); + leave_driver("(passing bus free) intr"); #endif - SETBITS(DMACNTRL0, INTEN); + SETBITS(DMACNTRL0, INTEN); + + if(CURRENT_SC->SCp.phase & aborted) { + HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR; + HOSTDATA(shpnt)->abortion_complete++; + } - if(CURRENT_SC->SCp.phase & aborted) - { - HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR; - HOSTDATA(shpnt)->abortion_complete++; - } - - aha152x_done(shpnt, DID_NO_CONNECT << 16); - return; - } + aha152x_done(shpnt, DID_NO_CONNECT << 16); + + return; + } #if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases)) - printk("SELDO (SELID=%x), ", GETPORT(SELID)); + if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases)) + printk("SELDO (SELID=%x), ", GETPORT(SELID)); #endif - /* selection was done */ - SETPORT(SSTAT0, CLRSELDO); + /* selection was done */ + SETPORT(SSTAT0, CLRSELDO); #if defined(DEBUG_ABORT) - if((HOSTDATA(shpnt)->debug & debug_abort) && (CURRENT_SC->SCp.phase & aborted)) - printk("(ABORT) target selected, "); + if((HOSTDATA(shpnt)->debug & debug_abort) && (CURRENT_SC->SCp.phase & aborted)) + printk("(ABORT) target selected, "); #endif - CURRENT_SC->SCp.phase &= ~in_selection; - CURRENT_SC->SCp.phase |= in_other; + CURRENT_SC->SCp.phase &= ~in_selection; + CURRENT_SC->SCp.phase |= in_other; - ADDMSG(IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun)); + ADDMSG(IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun)); - if(!(SYNCRATE&0x80) && HOSTDATA(shpnt)->synchronous) - { - ADDMSG(EXTENDED_MESSAGE); - ADDMSG(3); - ADDMSG(EXTENDED_SDTR); - ADDMSG(50); - ADDMSG(8); + if(!(SYNCRATE&0x80) && HOSTDATA(shpnt)->synchronous) { + ADDMSG(EXTENDED_MESSAGE); + ADDMSG(3); + ADDMSG(EXTENDED_SDTR); + ADDMSG(50); + ADDMSG(8); - printk("outbound SDTR: "); - print_msg(&MSG(MSGLEN-5)); + printk("outbound SDTR: "); + print_msg(&MSG(MSGLEN-5)); - SYNCRATE=0x80; - CURRENT_SC->SCp.phase |= in_sync; - } + SYNCRATE=0x80; + CURRENT_SC->SCp.phase |= in_sync; + } #if defined(DEBUG_RACE) - leave_driver("(SELDO) intr"); + leave_driver("(SELDO) intr"); #endif - SETPORT(SCSIRATE, SYNCRATE&0x7f); + SETPORT(SCSIRATE, SYNCRATE&0x7f); - SETPORT(SCSISIG, P_MSGO); + SETPORT(SCSISIG, P_MSGO); - SETPORT(SIMODE0, 0); - SETPORT(SIMODE1, ENREQINIT|ENBUSFREE); - SETBITS(DMACNTRL0, INTEN); - return; - } - else - aha152x_panic(shpnt, "neither timeout nor selection\007"); - else - { -#if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases)) - printk("SELTO, "); + SETPORT(SIMODE0, 0); + SETPORT(SIMODE1, ENREQINIT|ENBUSFREE); + SETBITS(DMACNTRL0, INTEN); + + return; + } else + aha152x_panic(shpnt, "neither timeout nor selection\007"); + else { +#if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) + if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases)) + printk("SELTO, "); #endif - /* end selection attempt */ - CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO); + /* end selection attempt */ + CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO); - /* timeout */ - SETPORT(SSTAT1, CLRSELTIMO); + /* timeout */ + SETPORT(SSTAT1, CLRSELTIMO); - SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); - SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); - SETBITS(DMACNTRL0, INTEN); + SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); + SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); + SETBITS(DMACNTRL0, INTEN); #if defined(DEBUG_RACE) - leave_driver("(SELTO) intr"); + leave_driver("(SELTO) intr"); #endif - if(CURRENT_SC->SCp.phase & aborted) - { + if(CURRENT_SC->SCp.phase & aborted) { #if defined(DEBUG_ABORT) - if(HOSTDATA(shpnt)->debug & debug_abort) - printk("(ABORT) selection timeout, "); + if(HOSTDATA(shpnt)->debug & debug_abort) + printk("(ABORT) selection timeout, "); #endif - HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR; - HOSTDATA(shpnt)->abortion_complete++; - } - - if(TESTLO(SSTAT0, SELINGO)) - /* ARBITRATION not won */ - aha152x_done(shpnt, DID_BUS_BUSY << 16); - else - /* ARBITRATION won, but SELECTION failed */ - aha152x_done(shpnt, DID_NO_CONNECT << 16); + HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR; + HOSTDATA(shpnt)->abortion_complete++; + } - return; - } + if(TESTLO(SSTAT0, SELINGO)) + /* ARBITRATION not won */ + aha152x_done(shpnt, DID_BUS_BUSY << 16); + else + /* ARBITRATION won, but SELECTION failed */ + aha152x_done(shpnt, DID_NO_CONNECT << 16); + + return; } + } /* enable interrupt, when target leaves current phase */ phase = getphase(shpnt); @@ -1705,756 +1844,712 @@ (CURRENT_SC->SCp.phase & ~((P_MASK|1)<<16)) | (phase << 16); /* information transfer phase */ - switch(phase) + switch(phase) { + case P_MSGO: /* MESSAGE OUT */ { - case P_MSGO: /* MESSAGE OUT */ - { - int i, identify=0, abort=0; + int i, identify=0, abort=0; #if defined(DEBUG_INTR) || defined(DEBUG_MSGO) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgo|debug_phases)) - printk("MESSAGE OUT, "); + if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgo|debug_phases)) + printk("MESSAGE OUT, "); #endif - if(MSGLEN==0) - { - ADDMSG(MESSAGE_REJECT); + if(MSGLEN==0) { + ADDMSG(MESSAGE_REJECT); #if defined(DEBUG_MSGO) - if(HOSTDATA(shpnt)->debug & debug_msgo) - printk("unexpected MSGO; rejecting, "); + if(HOSTDATA(shpnt)->debug & debug_msgo) + printk("unexpected MESSAGE OUT phase; rejecting, "); #endif - } - + } - CLRBITS(SXFRCTL0, ENDMA); + CLRBITS(SXFRCTL0, ENDMA); - SETPORT(SIMODE0, 0); - SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE); + SETPORT(SIMODE0, 0); + SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE); - /* wait for data latch to become ready or a phase change */ - while(TESTLO(DMASTAT, INTSTAT)) - barrier(); + /* wait for data latch to become ready or a phase change */ + while(TESTLO(DMASTAT, INTSTAT)) + barrier(); #if defined(DEBUG_MSGO) - if(HOSTDATA(shpnt)->debug & debug_msgo) - { - int i; + if(HOSTDATA(shpnt)->debug & debug_msgo) { + int i; - printk("messages ("); - for(i=0; idebug & debug_msgo) - printk("%x ", MSG(i)); + if(HOSTDATA(shpnt)->debug & debug_msgo) + printk("%x ", MSG(i)); #endif - if(i==MSGLEN-1) - { - /* Leave MESSAGE OUT after transfer */ - SETPORT(SSTAT1, CLRATNO); - } - - SETPORT(SCSIDAT, MSG(i)); + if(i==MSGLEN-1) { + /* Leave MESSAGE OUT after transfer */ + SETPORT(SSTAT1, CLRATNO); + } + + SETPORT(SCSIDAT, MSG(i)); - make_acklow(shpnt); - getphase(shpnt); + make_acklow(shpnt); + getphase(shpnt); - if(MSG(i)==IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun)) - identify++; + if(MSG(i)==IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun)) + identify++; - if(MSG(i)==ABORT) - abort++; + if(MSG(i)==ABORT) + abort++; - } + } - MSGLEN=0; + MSGLEN=0; - if(identify) - CURRENT_SC->SCp.phase |= sent_ident; + if(identify) + CURRENT_SC->SCp.phase |= sent_ident; - if(abort) - { - /* revive abort(); abort() enables interrupts */ - HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS; - HOSTDATA(shpnt)->abortion_complete++; + if(abort) { + /* revive abort(); abort() enables interrupts */ + HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS; + HOSTDATA(shpnt)->abortion_complete++; - CURRENT_SC->SCp.phase &= ~(P_MASK<<16); + CURRENT_SC->SCp.phase &= ~(P_MASK<<16); - /* exit */ - SETBITS(DMACNTRL0, INTEN); + /* exit */ + SETBITS(DMACNTRL0, INTEN); #if defined(DEBUG_RACE) - leave_driver("(ABORT) intr"); + leave_driver("(ABORT) intr"); #endif - aha152x_done(shpnt, DID_ABORT<<16); - return; - } + aha152x_done(shpnt, DID_ABORT<<16); + + return; } - break; + } + break; - case P_CMD: /* COMMAND phase */ + case P_CMD: /* COMMAND phase */ #if defined(DEBUG_INTR) || defined(DEBUG_CMD) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_intr|debug_cmd|debug_phases)) - printk("COMMAND, "); + if(HOSTDATA(shpnt)->debug & (debug_intr|debug_cmd|debug_phases)) + printk("COMMAND, "); #endif - if(!(CURRENT_SC->SCp.sent_command)) - { - int i; + if(!(CURRENT_SC->SCp.sent_command)) { + int i; - CLRBITS(SXFRCTL0, ENDMA); + CLRBITS(SXFRCTL0, ENDMA); - SETPORT(SIMODE0, 0); - SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE); + SETPORT(SIMODE0, 0); + SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE); - /* wait for data latch to become ready or a phase change */ - while(TESTLO(DMASTAT, INTSTAT)) - barrier(); + /* wait for data latch to become ready or a phase change */ + while(TESTLO(DMASTAT, INTSTAT)) + barrier(); - for(i=0; icmd_len && TESTLO(SSTAT1, PHASEMIS); i++) - { - SETPORT(SCSIDAT, CURRENT_SC->cmnd[i]); - - make_acklow(shpnt); - getphase(shpnt); - } + for(i=0; icmd_len && TESTLO(SSTAT1, PHASEMIS); i++) { + SETPORT(SCSIDAT, CURRENT_SC->cmnd[i]); - if(icmd_len && TESTHI(SSTAT1, PHASEMIS)) - aha152x_panic(shpnt, "target left COMMAND"); + make_acklow(shpnt); + getphase(shpnt); + } - CURRENT_SC->SCp.sent_command++; - } - else - aha152x_panic(shpnt, "Nothing to send while in COMMAND"); + if(icmd_len && TESTHI(SSTAT1, PHASEMIS)) + aha152x_panic(shpnt, "target left COMMAND"); + + CURRENT_SC->SCp.sent_command++; + } else + aha152x_panic(shpnt, "Nothing to send while in COMMAND"); break; - case P_MSGI: /* MESSAGE IN phase */ - { - int start_sync=0; + case P_MSGI: /* MESSAGE IN phase */ + { + int start_sync=0; #if defined(DEBUG_INTR) || defined(DEBUG_MSGI) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgi|debug_phases)) - printk("MESSAGE IN, "); + if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgi|debug_phases)) + printk("MESSAGE IN, "); #endif - SETPORT(SXFRCTL0, CH1); + SETPORT(SXFRCTL0, CH1); - SETPORT(SIMODE0, 0); - SETPORT(SIMODE1, ENBUSFREE); + SETPORT(SIMODE0, 0); + SETPORT(SIMODE1, ENBUSFREE); - while(phase == P_MSGI) - { - CURRENT_SC->SCp.Message = GETPORT(SCSIDAT); - switch(CURRENT_SC->SCp.Message) - { - case DISCONNECT: + while(phase == P_MSGI) { + CURRENT_SC->SCp.Message = GETPORT(SCSIDAT); + switch(CURRENT_SC->SCp.Message) { + case DISCONNECT: #if defined(DEBUG_MSGI) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases)) - printk("target disconnected, "); + if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases)) + printk("target disconnected, "); #endif - CURRENT_SC->SCp.Message = 0; - CURRENT_SC->SCp.phase |= disconnected; - if(!HOSTDATA(shpnt)->reconnect) - aha152x_panic(shpnt, "target was not allowed to disconnect"); - break; - - case COMMAND_COMPLETE: + CURRENT_SC->SCp.Message = 0; + CURRENT_SC->SCp.phase |= disconnected; + if(!HOSTDATA(shpnt)->reconnect) + aha152x_panic(shpnt, "target was not allowed to disconnect"); + + break; + + case COMMAND_COMPLETE: #if defined(DEBUG_MSGI) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases)) - printk("inbound message (COMMAND COMPLETE), "); + if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases)) + printk("inbound message (COMMAND COMPLETE), "); #endif - done++; - break; + done++; + break; - case MESSAGE_REJECT: - if(CURRENT_SC->SCp.phase & in_sync) - { - CURRENT_SC->SCp.phase &= ~in_sync; - SYNCRATE=0x80; - printk("synchronous rejected, "); - } - else - printk("inbound message (MESSAGE REJECT), "); + case MESSAGE_REJECT: + if(CURRENT_SC->SCp.phase & in_sync) { + CURRENT_SC->SCp.phase &= ~in_sync; + SYNCRATE=0x80; + printk("synchronous rejected, "); + } else + printk("inbound message (MESSAGE REJECT), "); #if defined(DEBUG_MSGI) - if(HOSTDATA(shpnt)->debug & debug_msgi) - printk("inbound message (MESSAGE REJECT), "); + if(HOSTDATA(shpnt)->debug & debug_msgi) + printk("inbound message (MESSAGE REJECT), "); #endif - break; + break; - case SAVE_POINTERS: + case SAVE_POINTERS: #if defined(DEBUG_MSGI) - if(HOSTDATA(shpnt)->debug & debug_msgi) - printk("inbound message (SAVE DATA POINTERS), "); + if(HOSTDATA(shpnt)->debug & debug_msgi) + printk("inbound message (SAVE DATA POINTERS), "); #endif - break; + break; - case RESTORE_POINTERS: + case RESTORE_POINTERS: #if defined(DEBUG_MSGI) - if(HOSTDATA(shpnt)->debug & debug_msgi) - printk("inbound message (RESTORE DATA POINTERS), "); + if(HOSTDATA(shpnt)->debug & debug_msgi) + printk("inbound message (RESTORE DATA POINTERS), "); #endif - break; + break; - case EXTENDED_MESSAGE: - { - char buffer[16]; - int i; + case EXTENDED_MESSAGE: + { + char buffer[16]; + int i; #if defined(DEBUG_MSGI) - if(HOSTDATA(shpnt)->debug & debug_msgi) - printk("inbound message (EXTENDED MESSAGE), "); + if(HOSTDATA(shpnt)->debug & debug_msgi) + printk("inbound message (EXTENDED MESSAGE), "); #endif - make_acklow(shpnt); - if(getphase(shpnt)!=P_MSGI) - break; - - buffer[0]=EXTENDED_MESSAGE; - buffer[1]=GETPORT(SCSIDAT); - - for(i=0; idebug & debug_msgi) - print_msg(buffer); + if(HOSTDATA(shpnt)->debug & debug_msgi) + print_msg(buffer); #endif - switch(buffer [2]) - { - case EXTENDED_SDTR: - { - long ticks; - - if(buffer[1]!=3) - aha152x_panic(shpnt, "SDTR message length != 3"); - - if(!HOSTDATA(shpnt)->synchronous) - break; - - printk("inbound SDTR: "); print_msg(buffer); - - ticks=(buffer[3]*4+49)/50; - - if(CURRENT_SC->SCp.phase & in_sync) - { - /* we initiated SDTR */ - if(ticks>9 || buffer[4]<1 || buffer[4]>8) - aha152x_panic(shpnt, "received SDTR invalid"); - - SYNCRATE |= ((ticks-2)<<4) + buffer[4]; - } - else if(ticks<=9 && buffer[4]>=1) - { - if(buffer[4]>8) - buffer[4]=8; - - ADDMSG(EXTENDED_MESSAGE); - ADDMSG(3); - ADDMSG(EXTENDED_SDTR); - if(ticks<4) - { - ticks=4; - ADDMSG(50); - } - else - ADDMSG(buffer[3]); - - ADDMSG(buffer[4]); - - printk("outbound SDTR: "); - print_msg(&MSG(MSGLEN-5)); - - CURRENT_SC->SCp.phase |= in_sync; - - SYNCRATE |= ((ticks-2)<<4) + buffer[4]; - - start_sync++; - } - else - { - /* requested SDTR is too slow, do it asynchronously */ - ADDMSG(MESSAGE_REJECT); - SYNCRATE = 0; - } - - SETPORT(SCSIRATE, SYNCRATE&0x7f); - } - break; - - case EXTENDED_MODIFY_DATA_POINTER: - case EXTENDED_EXTENDED_IDENTIFY: - case EXTENDED_WDTR: - default: - ADDMSG(MESSAGE_REJECT); - break; - } - } - break; + switch(buffer [2]) { + case EXTENDED_SDTR: + { + long ticks; + + if(buffer[1]!=3) + aha152x_panic(shpnt, "SDTR message length != 3"); + + if(!HOSTDATA(shpnt)->synchronous) + break; + + printk("inbound SDTR: "); print_msg(buffer); + + ticks=(buffer[3]*4+49)/50; + + if(CURRENT_SC->SCp.phase & in_sync) { + /* we initiated SDTR */ + if(ticks>9 || buffer[4]<1 || buffer[4]>8) + aha152x_panic(shpnt, "received SDTR invalid"); + + SYNCRATE |= ((ticks-2)<<4) + buffer[4]; + } else if(ticks<=9 && buffer[4]>=1) { + if(buffer[4]>8) + buffer[4]=8; + + ADDMSG(EXTENDED_MESSAGE); + ADDMSG(3); + ADDMSG(EXTENDED_SDTR); + if(ticks<4) { + ticks=4; + ADDMSG(50); + } else + ADDMSG(buffer[3]); + + ADDMSG(buffer[4]); + + printk("outbound SDTR: "); + print_msg(&MSG(MSGLEN-5)); + + CURRENT_SC->SCp.phase |= in_sync; + + SYNCRATE |= ((ticks-2)<<4) + buffer[4]; + + start_sync++; + } else { + /* requested SDTR is too slow, do it asynchronously */ + ADDMSG(MESSAGE_REJECT); + SYNCRATE = 0; + } + + SETPORT(SCSIRATE, SYNCRATE&0x7f); + } + break; + + case EXTENDED_MODIFY_DATA_POINTER: + case EXTENDED_EXTENDED_IDENTIFY: + case EXTENDED_WDTR: + default: + ADDMSG(MESSAGE_REJECT); + break; + } + } + break; - default: - printk("unsupported inbound message %x, ", - CURRENT_SC->SCp.Message); - break; + default: + printk("unsupported inbound message %x, ", CURRENT_SC->SCp.Message); + break; - } + } - make_acklow(shpnt); - phase=getphase(shpnt); - } + make_acklow(shpnt); + phase=getphase(shpnt); + } - if(start_sync) - CURRENT_SC->SCp.phase |= in_sync; - else - CURRENT_SC->SCp.phase &= ~in_sync; + if(start_sync) + CURRENT_SC->SCp.phase |= in_sync; + else + CURRENT_SC->SCp.phase &= ~in_sync; - if(MSGLEN>0) - SETPORT(SCSISIG, P_MSGI|ATNO); + if(MSGLEN>0) + SETPORT(SCSISIG, P_MSGI|ATNO); /* clear SCSI fifo on BUSFREE */ if(phase==P_BUSFREE) - SETPORT(SXFRCTL0, CH1|CLRCH1); + SETPORT(SXFRCTL0, CH1|CLRCH1); - if(CURRENT_SC->SCp.phase & disconnected) - { - save_flags(flags); - cli(); + if(CURRENT_SC->SCp.phase & disconnected) { + save_flags(flags); + cli(); #if defined(DEBUG_QUEUES) - if(HOSTDATA(shpnt)->debug & debug_queues) - printk("d+, "); + if(HOSTDATA(shpnt)->debug & debug_queues) + printk("d+, "); #endif - append_SC(&DISCONNECTED_SC, CURRENT_SC); - CURRENT_SC->SCp.phase |= 1<<16; - CURRENT_SC = NULL; - restore_flags(flags); - - SETBITS(SCSISEQ, ENRESELI); - - SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); - SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); - - SETBITS(DMACNTRL0, INTEN); - return; - } + append_SC(&DISCONNECTED_SC, CURRENT_SC); + CURRENT_SC->SCp.phase |= 1<<16; + CURRENT_SC = NULL; + restore_flags(flags); + + SETBITS(SCSISEQ, ENRESELI); + + SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); + SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); + + SETBITS(DMACNTRL0, INTEN); + + return; } - break; + } + break; - case P_STATUS: /* STATUS IN phase */ + case P_STATUS: /* STATUS IN phase */ #if defined(DEBUG_STATUS) || defined(DEBUG_INTR) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_status|debug_intr|debug_phases)) - printk("STATUS, "); + if(HOSTDATA(shpnt)->debug & (debug_status|debug_intr|debug_phases)) + printk("STATUS, "); #endif - SETPORT(SXFRCTL0, CH1); + SETPORT(SXFRCTL0, CH1); - SETPORT(SIMODE0, 0); - SETPORT(SIMODE1, ENREQINIT|ENBUSFREE); + SETPORT(SIMODE0, 0); + SETPORT(SIMODE1, ENREQINIT|ENBUSFREE); - if(TESTHI(SSTAT1, PHASEMIS)) - printk("aha152x: passing STATUS phase"); - - CURRENT_SC->SCp.Status = GETPORT(SCSIBUS); - make_acklow(shpnt); - getphase(shpnt); + if(TESTHI(SSTAT1, PHASEMIS)) + printk("aha152x: passing STATUS phase"); + + CURRENT_SC->SCp.Status = GETPORT(SCSIBUS); + make_acklow(shpnt); + getphase(shpnt); #if defined(DEBUG_STATUS) - if(HOSTDATA(shpnt)->debug & debug_status) - { - printk("inbound status "); - print_status(CURRENT_SC->SCp.Status); - printk(", "); - } + if(HOSTDATA(shpnt)->debug & debug_status) { + printk("inbound status "); + print_status(CURRENT_SC->SCp.Status); + printk(", "); + } #endif - break; + break; - case P_DATAI: /* DATA IN phase */ - { - int fifodata, data_count, done; + case P_DATAI: /* DATA IN phase */ + { + int fifodata, data_count, done; #if defined(DEBUG_DATAI) || defined(DEBUG_INTR) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr|debug_phases)) - printk("DATA IN, "); + if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr|debug_phases)) + printk("DATA IN, "); #endif #if 0 - if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT)) - printk("aha152x: P_DATAI: %d(%d) bytes left in FIFO, resetting\n", - GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT)); + if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT)) + printk("aha152x: P_DATAI: %d(%d) bytes left in FIFO, resetting\n", + GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT)); #endif - /* reset host fifo */ - SETPORT(DMACNTRL0, RSTFIFO); - SETPORT(DMACNTRL0, RSTFIFO|ENDMA); + /* reset host fifo */ + SETPORT(DMACNTRL0, RSTFIFO); + SETPORT(DMACNTRL0, RSTFIFO|ENDMA); - SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN); + SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN); - SETPORT(SIMODE0, 0); - SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); + SETPORT(SIMODE0, 0); + SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); - /* done is set when the FIFO is empty after the target left DATA IN */ - done=0; + /* done is set when the FIFO is empty after the target left DATA IN */ + done=0; - /* while the target stays in DATA to transfer data */ - while (!done) - { + /* while the target stays in DATA to transfer data */ + while (!done) { #if defined(DEBUG_DATAI) - if(HOSTDATA(shpnt)->debug & debug_datai) - printk("expecting data, "); + if(HOSTDATA(shpnt)->debug & debug_datai) + printk("expecting data, "); #endif - /* wait for PHASEMIS or full FIFO */ - while(TESTLO (DMASTAT, DFIFOFULL|INTSTAT)) - barrier(); + /* wait for PHASEMIS or full FIFO */ + while(TESTLO(DMASTAT, DFIFOFULL|INTSTAT)) + barrier(); #if defined(DEBUG_DATAI) - if(HOSTDATA(shpnt)->debug & debug_datai) - printk("ok, "); + if(HOSTDATA(shpnt)->debug & debug_datai) + printk("ok, "); #endif - - if(TESTHI(DMASTAT, DFIFOFULL)) - fifodata=GETPORT(FIFOSTAT); - else - { - /* wait for SCSI fifo to get empty */ - while(TESTLO(SSTAT2, SEMPTY)) - barrier(); + + if(TESTHI(DMASTAT, DFIFOFULL)) + fifodata=GETPORT(FIFOSTAT); + else { + /* wait for SCSI fifo to get empty */ + while(TESTLO(SSTAT2, SEMPTY)) + barrier(); - /* rest of data in FIFO */ - fifodata=GETPORT(FIFOSTAT); + /* rest of data in FIFO */ + fifodata=GETPORT(FIFOSTAT); #if defined(DEBUG_DATAI) - if(HOSTDATA(shpnt)->debug & debug_datai) - printk("last transfer, "); + if(HOSTDATA(shpnt)->debug & debug_datai) + printk("last transfer, "); #endif - done=1; - } + done=1; + } #if defined(DEBUG_DATAI) - if(HOSTDATA(shpnt)->debug & debug_datai) - printk("fifodata=%d, ", fifodata); + if(HOSTDATA(shpnt)->debug & debug_datai) + printk("fifodata=%d, ", fifodata); #endif - while(fifodata && CURRENT_SC->SCp.this_residual) - { - data_count=fifodata; + while(fifodata && CURRENT_SC->SCp.this_residual) { + data_count=fifodata; - /* limit data transfer to size of first sg buffer */ - if (data_count > CURRENT_SC->SCp.this_residual) - data_count = CURRENT_SC->SCp.this_residual; + /* limit data transfer to size of first sg buffer */ + if(data_count > CURRENT_SC->SCp.this_residual) + data_count = CURRENT_SC->SCp.this_residual; - fifodata -= data_count; + fifodata -= data_count; #if defined(DEBUG_DATAI) - if(HOSTDATA(shpnt)->debug & debug_datai) - printk("data_count=%d, ", data_count); + if(HOSTDATA(shpnt)->debug & debug_datai) + printk("data_count=%d, ", data_count); #endif - if(data_count&1) - { - /* get a single byte in byte mode */ - SETBITS(DMACNTRL0, _8BIT); - *CURRENT_SC->SCp.ptr++ = GETPORT(DATAPORT); - CURRENT_SC->SCp.this_residual--; - } - if(data_count>1) - { - CLRBITS(DMACNTRL0, _8BIT); - data_count >>= 1; /* Number of words */ - insw(DATAPORT, CURRENT_SC->SCp.ptr, data_count); -#if defined(DEBUG_DATAI) - if(HOSTDATA(shpnt)->debug & debug_datai) - /* show what comes with the last transfer */ - if(done) - { -#ifdef 0 - int i; - unsigned char *data; -#endif - - printk("data on last transfer (%d bytes) ", - 2*data_count); -#ifdef 0 - printk("data on last transfer (%d bytes: ", - 2*data_count); - data = (unsigned char *) CURRENT_SC->SCp.ptr; - for(i=0; i<2*data_count; i++) - printk("%2x ", *data++); - printk("), "); -#endif - } -#endif - CURRENT_SC->SCp.ptr += 2 * data_count; - CURRENT_SC->SCp.this_residual -= 2 * data_count; - } - - /* if this buffer is full and there are more buffers left */ - if (!CURRENT_SC->SCp.this_residual && - CURRENT_SC->SCp.buffers_residual) - { - /* advance to next buffer */ - CURRENT_SC->SCp.buffers_residual--; - CURRENT_SC->SCp.buffer++; - CURRENT_SC->SCp.ptr = - CURRENT_SC->SCp.buffer->address; - CURRENT_SC->SCp.this_residual = - CURRENT_SC->SCp.buffer->length; - } - } + if(data_count&1) { + /* get a single byte in byte mode */ + SETBITS(DMACNTRL0, _8BIT); + *CURRENT_SC->SCp.ptr++ = GETPORT(DATAPORT); + CURRENT_SC->SCp.this_residual--; + } - /* - * Fifo should be empty - */ - if(fifodata>0) - { - printk("aha152x: more data than expected (%d bytes)\n", - GETPORT(FIFOSTAT)); - SETBITS(DMACNTRL0, _8BIT); - printk("aha152x: data ("); - while(fifodata--) - printk("%2x ", GETPORT(DATAPORT)); - printk(")\n"); - } - + if(data_count>1) { + CLRBITS(DMACNTRL0, _8BIT); + data_count >>= 1; /* Number of words */ + insw(DATAPORT, CURRENT_SC->SCp.ptr, data_count); #if defined(DEBUG_DATAI) if(HOSTDATA(shpnt)->debug & debug_datai) - if(!fifodata) - printk("fifo empty, "); - else - printk("something left in fifo, "); + /* show what comes with the last transfer */ + if(done) { +#if 0 + int i; + unsigned char *data; #endif - } + + printk("data on last transfer (%d bytes) ", + 2*data_count); +#if 0 + printk("data on last transfer (%d bytes: ", + 2*data_count); + data = (unsigned char *) CURRENT_SC->SCp.ptr; + for(i=0; i<2*data_count; i++) + printk("%2x ", *data++); + printk("), "); +#endif + } +#endif + CURRENT_SC->SCp.ptr += 2 * data_count; + CURRENT_SC->SCp.this_residual -= 2 * data_count; + } + + /* if this buffer is full and there are more buffers left */ + if(!CURRENT_SC->SCp.this_residual && + CURRENT_SC->SCp.buffers_residual) { + /* advance to next buffer */ + CURRENT_SC->SCp.buffers_residual--; + CURRENT_SC->SCp.buffer++; + CURRENT_SC->SCp.ptr = CURRENT_SC->SCp.buffer->address; + CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length; + } + } + + /* + * FIFO should be empty + */ + if(fifodata>0) { + printk("aha152x: more data than expected (%d bytes)\n", + GETPORT(FIFOSTAT)); + SETBITS(DMACNTRL0, _8BIT); + printk("aha152x: data ("); + while(fifodata--) + printk("%2x ", GETPORT(DATAPORT)); + printk(")\n"); + } #if defined(DEBUG_DATAI) - if((HOSTDATA(shpnt)->debug & debug_datai) && - (CURRENT_SC->SCp.buffers_residual || - CURRENT_SC->SCp.this_residual)) - printk("left buffers (buffers=%d, bytes=%d), ", - CURRENT_SC->SCp.buffers_residual, - CURRENT_SC->SCp.this_residual); + if(HOSTDATA(shpnt)->debug & debug_datai) + if(!fifodata) + printk("fifo empty, "); + else + printk("something left in fifo, "); #endif - /* transfer can be considered ended, when SCSIEN reads back zero */ - CLRBITS(SXFRCTL0, SCSIEN|DMAEN); - while(TESTHI(SXFRCTL0, SCSIEN)) - barrier(); - CLRBITS(DMACNTRL0, ENDMA); + } + +#if defined(DEBUG_DATAI) + if((HOSTDATA(shpnt)->debug & debug_datai) && + (CURRENT_SC->SCp.buffers_residual || + CURRENT_SC->SCp.this_residual)) + printk("left buffers (buffers=%d, bytes=%d), ", + CURRENT_SC->SCp.buffers_residual, CURRENT_SC->SCp.this_residual); +#endif + /* transfer can be considered ended, when SCSIEN reads back zero */ + CLRBITS(SXFRCTL0, SCSIEN|DMAEN); + while(TESTHI(SXFRCTL0, SCSIEN)) + barrier(); + CLRBITS(DMACNTRL0, ENDMA); #if defined(DEBUG_DATAI) || defined(DEBUG_INTR) - if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr)) - printk("got %d bytes, ", GETSTCNT()); + if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr)) + printk("got %d bytes, ", GETSTCNT()); #endif - CURRENT_SC->SCp.have_data_in++; - } - break; + CURRENT_SC->SCp.have_data_in++; + } + break; - case P_DATAO: /* DATA OUT phase */ - { - int data_count; + case P_DATAO: /* DATA OUT phase */ + { + int data_count; #if defined(DEBUG_DATAO) || defined(DEBUG_INTR) || defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr|debug_phases)) - printk("DATA OUT, "); + if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr|debug_phases)) + printk("DATA OUT, "); #endif #if defined(DEBUG_DATAO) - if(HOSTDATA(shpnt)->debug & debug_datao) - printk("got data to send (bytes=%d, buffers=%d), ", - CURRENT_SC->SCp.this_residual, - CURRENT_SC->SCp.buffers_residual); + if(HOSTDATA(shpnt)->debug & debug_datao) + printk("got data to send (bytes=%d, buffers=%d), ", + CURRENT_SC->SCp.this_residual, + CURRENT_SC->SCp.buffers_residual); #endif - if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT)) - { - printk("%d(%d) left in FIFO, ", - GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT)); - aha152x_panic(shpnt, "FIFO should be empty"); - } + if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT)) { + printk("%d(%d) left in FIFO, ", + GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT)); + aha152x_panic(shpnt, "FIFO should be empty"); + } - SETPORT(SXFRCTL0, CH1|CLRSTCNT|CLRCH1); - SETPORT(SXFRCTL0, SCSIEN|DMAEN|CH1); + SETPORT(SXFRCTL0, CH1|CLRSTCNT|CLRCH1); + SETPORT(SXFRCTL0, SCSIEN|DMAEN|CH1); - SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO); - SETPORT(DMACNTRL0, ENDMA|WRITE_READ); + SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO); + SETPORT(DMACNTRL0, ENDMA|WRITE_READ); - SETPORT(SIMODE0, 0); - SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); + SETPORT(SIMODE0, 0); + SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); - /* while current buffer is not empty or - there are more buffers to transfer */ - while(TESTLO(SSTAT1, PHASEMIS) && - (CURRENT_SC->SCp.this_residual || - CURRENT_SC->SCp.buffers_residual)) - { + /* while current buffer is not empty or + there are more buffers to transfer */ + while(TESTLO(SSTAT1, PHASEMIS) && + (CURRENT_SC->SCp.this_residual || + CURRENT_SC->SCp.buffers_residual)) { #if defined(DEBUG_DATAO) - if(HOSTDATA(shpnt)->debug & debug_datao) - printk("sending data (left: bytes=%d, buffers=%d), waiting, ", - CURRENT_SC->SCp.this_residual, - CURRENT_SC->SCp.buffers_residual); -#endif - /* transfer rest of buffer, but max. 128 byte */ - data_count = - CURRENT_SC->SCp.this_residual > 128 ? - 128 : CURRENT_SC->SCp.this_residual ; + if(HOSTDATA(shpnt)->debug & debug_datao) + printk("sending data (left: bytes=%d, buffers=%d), waiting, ", + CURRENT_SC->SCp.this_residual, + CURRENT_SC->SCp.buffers_residual); +#endif + /* transfer rest of buffer, but max. 128 byte */ + data_count = + CURRENT_SC->SCp.this_residual > 128 ? + 128 : CURRENT_SC->SCp.this_residual ; #if defined(DEBUG_DATAO) - if(HOSTDATA(shpnt)->debug & debug_datao) - printk("data_count=%d, ", data_count); + if(HOSTDATA(shpnt)->debug & debug_datao) + printk("data_count=%d, ", data_count); #endif - if(data_count&1) - { - /* put a single byte in byte mode */ - SETBITS(DMACNTRL0, _8BIT); - SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++); - CURRENT_SC->SCp.this_residual--; - } - if(data_count>1) - { - CLRBITS(DMACNTRL0, _8BIT); - data_count >>= 1; /* number of words */ - outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count); - CURRENT_SC->SCp.ptr += 2 * data_count; - CURRENT_SC->SCp.this_residual -= 2 * data_count; - } - - /* wait for FIFO to get empty */ - while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT)) - barrier(); + if(data_count&1) { + /* put a single byte in byte mode */ + SETBITS(DMACNTRL0, _8BIT); + SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++); + CURRENT_SC->SCp.this_residual--; + } + if(data_count>1) { + CLRBITS(DMACNTRL0, _8BIT); + data_count >>= 1; /* number of words */ + outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count); + CURRENT_SC->SCp.ptr += 2 * data_count; + CURRENT_SC->SCp.this_residual -= 2 * data_count; + } + + /* wait for FIFO to get empty */ + while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT)) + barrier(); #if defined(DEBUG_DATAO) - if(HOSTDATA(shpnt)->debug & debug_datao) - printk("fifo (%d bytes), transfered (%d bytes), ", - GETPORT(FIFOSTAT), GETSTCNT()); -#endif - - /* if this buffer is empty and there are more buffers left */ - if (TESTLO(SSTAT1, PHASEMIS) && - !CURRENT_SC->SCp.this_residual && - CURRENT_SC->SCp.buffers_residual) - { - /* advance to next buffer */ - CURRENT_SC->SCp.buffers_residual--; - CURRENT_SC->SCp.buffer++; - CURRENT_SC->SCp.ptr = - CURRENT_SC->SCp.buffer->address; - CURRENT_SC->SCp.this_residual = - CURRENT_SC->SCp.buffer->length; - } - } - - if (CURRENT_SC->SCp.this_residual || CURRENT_SC->SCp.buffers_residual) - { - /* target leaves DATA OUT for an other phase - (perhaps disconnect) */ - - /* data in fifos has to be resend */ - data_count = GETPORT(SSTAT2) & (SFULL|SFCNT); - - data_count += GETPORT(FIFOSTAT) ; - CURRENT_SC->SCp.ptr -= data_count; - CURRENT_SC->SCp.this_residual += data_count; + if(HOSTDATA(shpnt)->debug & debug_datao) + printk("fifo (%d bytes), transfered (%d bytes), ", + GETPORT(FIFOSTAT), GETSTCNT()); +#endif + + /* if this buffer is empty and there are more buffers left */ + if(TESTLO(SSTAT1, PHASEMIS) && + !CURRENT_SC->SCp.this_residual && + CURRENT_SC->SCp.buffers_residual) { + /* advance to next buffer */ + CURRENT_SC->SCp.buffers_residual--; + CURRENT_SC->SCp.buffer++; + CURRENT_SC->SCp.ptr = CURRENT_SC->SCp.buffer->address; + CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length; + } + } + + if(CURRENT_SC->SCp.this_residual || CURRENT_SC->SCp.buffers_residual) { + /* target leaves DATA OUT for an other phase (perhaps disconnect) */ + + /* data in fifos has to be resend */ + data_count = GETPORT(SSTAT2) & (SFULL|SFCNT); + + data_count += GETPORT(FIFOSTAT) ; + CURRENT_SC->SCp.ptr -= data_count; + CURRENT_SC->SCp.this_residual += data_count; #if defined(DEBUG_DATAO) - if(HOSTDATA(shpnt)->debug & debug_datao) - printk("left data (bytes=%d, buffers=%d), fifos (bytes=%d), " - "transfer incomplete, resetting fifo, ", - CURRENT_SC->SCp.this_residual, - CURRENT_SC->SCp.buffers_residual, - data_count); -#endif - SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO); - CLRBITS(SXFRCTL0, SCSIEN|DMAEN); - CLRBITS(DMACNTRL0, ENDMA); - } - else - { + if(HOSTDATA(shpnt)->debug & debug_datao) + printk("left data (bytes=%d, buffers=%d), fifos (bytes=%d), " + "transfer incomplete, resetting fifo, ", + CURRENT_SC->SCp.this_residual, + CURRENT_SC->SCp.buffers_residual, + data_count); +#endif + SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO); + CLRBITS(SXFRCTL0, SCSIEN|DMAEN); + CLRBITS(DMACNTRL0, ENDMA); + } else { #if defined(DEBUG_DATAO) - if(HOSTDATA(shpnt)->debug & debug_datao) - printk("waiting for SCSI fifo to get empty, "); + if(HOSTDATA(shpnt)->debug & debug_datao) + printk("waiting for SCSI fifo to get empty, "); #endif - /* wait for SCSI fifo to get empty */ - while(TESTLO(SSTAT2, SEMPTY)) - barrier(); + /* wait for SCSI fifo to get empty */ + while(TESTLO(SSTAT2, SEMPTY)) + barrier(); #if defined(DEBUG_DATAO) - if(HOSTDATA(shpnt)->debug & debug_datao) - printk("ok, left data (bytes=%d, buffers=%d) ", - CURRENT_SC->SCp.this_residual, - CURRENT_SC->SCp.buffers_residual); -#endif - CLRBITS(SXFRCTL0, SCSIEN|DMAEN); - - /* transfer can be considered ended, when SCSIEN reads back zero */ - while(TESTHI(SXFRCTL0, SCSIEN)) - barrier(); + if(HOSTDATA(shpnt)->debug & debug_datao) + printk("ok, left data (bytes=%d, buffers=%d) ", + CURRENT_SC->SCp.this_residual, + CURRENT_SC->SCp.buffers_residual); +#endif + CLRBITS(SXFRCTL0, SCSIEN|DMAEN); - CLRBITS(DMACNTRL0, ENDMA); - } + /* transfer can be considered ended, when SCSIEN reads back zero */ + while(TESTHI(SXFRCTL0, SCSIEN)) + barrier(); + + CLRBITS(DMACNTRL0, ENDMA); + } #if defined(DEBUG_DATAO) || defined(DEBUG_INTR) - if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr)) - printk("sent %d data bytes, ", GETSTCNT()); + if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr)) + printk("sent %d data bytes, ", GETSTCNT()); #endif - } - break; + } + break; - case P_BUSFREE: /* BUSFREE */ + case P_BUSFREE: /* BUSFREE */ #if defined(DEBUG_RACE) - leave_driver("(BUSFREE) intr"); + leave_driver("(BUSFREE) intr"); #endif #if defined(DEBUG_PHASES) - if(HOSTDATA(shpnt)->debug & debug_phases) - printk("unexpected BUS FREE, "); + if(HOSTDATA(shpnt)->debug & debug_phases) + printk("unexpected BUS FREE, "); #endif - CURRENT_SC->SCp.phase &= ~(P_MASK<<16); + CURRENT_SC->SCp.phase &= ~(P_MASK<<16); - aha152x_done(shpnt, DID_ERROR << 16); /* Don't know any better */ - return; - break; + aha152x_done(shpnt, DID_ERROR << 16); /* Don't know any better */ + return; + break; - case P_PARITY: /* parity error in DATA phase */ + case P_PARITY: /* parity error in DATA phase */ #if defined(DEBUG_RACE) - leave_driver("(DID_PARITY) intr"); + leave_driver("(DID_PARITY) intr"); #endif - printk("PARITY error in DATA phase, "); + printk("PARITY error in DATA phase, "); - CURRENT_SC->SCp.phase &= ~(P_MASK<<16); + CURRENT_SC->SCp.phase &= ~(P_MASK<<16); - SETBITS(DMACNTRL0, INTEN); - aha152x_done(shpnt, DID_PARITY << 16); - return; - break; + SETBITS(DMACNTRL0, INTEN); + aha152x_done(shpnt, DID_PARITY << 16); + return; + break; - default: - printk("aha152x: unexpected phase\n"); - break; - } + default: + printk("aha152x: unexpected phase\n"); + break; + } - if(done) - { + if(done) { #if defined(DEBUG_INTR) - if(HOSTDATA(shpnt)->debug & debug_intr) - printk("command done.\n"); + if(HOSTDATA(shpnt)->debug & debug_intr) + printk("command done.\n"); #endif #if defined(DEBUG_RACE) - leave_driver("(done) intr"); + leave_driver("(done) intr"); #endif - SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); - SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); - SETPORT(SCSISEQ, DISCONNECTED_SC ? ENRESELI : 0); + SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); + SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); + SETPORT(SCSISEQ, DISCONNECTED_SC ? ENRESELI : 0); + + SETBITS(DMACNTRL0, INTEN); - SETBITS(DMACNTRL0, INTEN); - - aha152x_done(shpnt, - (CURRENT_SC->SCp.Status & 0xff) - | ((CURRENT_SC->SCp.Message & 0xff) << 8) - | (DID_OK << 16)); + aha152x_done(shpnt, + (CURRENT_SC->SCp.Status & 0xff) + | ((CURRENT_SC->SCp.Message & 0xff) << 8) + | (DID_OK << 16)); #if defined(DEBUG_RACE) - printk("done returned (DID_OK: Status=%x; Message=%x).\n", - CURRENT_SC->SCp.Status, CURRENT_SC->SCp.Message); + printk("done returned (DID_OK: Status=%x; Message=%x).\n", + CURRENT_SC->SCp.Status, CURRENT_SC->SCp.Message); #endif - return; - } + return; + } if(CURRENT_SC) - CURRENT_SC->SCp.phase |= 1<<16 ; + CURRENT_SC->SCp.phase |= 1<<16; SETPORT(SIMODE0, 0); SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); @@ -2490,7 +2585,7 @@ #ifdef SKIP_PORTS if(HOSTDATA(shpnt)->debug & debug_skipports) - return; + return; #endif printk("\n%s: ", CURRENT_SC ? "on bus" : "waiting"); @@ -2509,30 +2604,29 @@ printk(" SCSISIG ("); s=GETPORT(SCSISIG); - switch(s & P_MASK) - { - case P_DATAO: - printk("DATA OUT"); - break; - case P_DATAI: - printk("DATA IN"); - break; - case P_CMD: - printk("COMMAND"); - break; - case P_STATUS: - printk("STATUS"); - break; - case P_MSGO: - printk("MESSAGE OUT"); - break; - case P_MSGI: - printk("MESSAGE IN"); - break; - default: - printk("*illegal*"); - break; - } + switch(s & P_MASK) { + case P_DATAO: + printk("DATA OUT"); + break; + case P_DATAI: + printk("DATA IN"); + break; + case P_CMD: + printk("COMMAND"); + break; + case P_STATUS: + printk("STATUS"); + break; + case P_MSGO: + printk("MESSAGE OUT"); + break; + case P_MSGI: + printk("MESSAGE IN"); + break; + default: + printk("*illegal*"); + break; + } printk("); "); @@ -2638,19 +2732,6 @@ if(s & SWINT) printk("SWINT "); printk("); "); - -#if 0 - printk("DMACNTRL1 ("); - - s=GETPORT(DMACNTRL1); - if(s & PWRDWN) printk("PWRDN "); - printk("); "); - - - printk("STK (%d); ", s & 0xf); - -#endif - printk("DMASTAT ("); s=GETPORT(DMASTAT); if(s & ATDONE) printk("ATDONE "); @@ -2707,11 +2788,10 @@ save_flags(flags); cli(); printk("aha152x: entering %s() (%x)\n", func, jiffies); - if(in_driver) - { - printk("%s should leave first.\n", should_leave); - panic("aha152x: already in driver\n"); - } + if(in_driver) { + printk("%s should leave first.\n", should_leave); + panic("aha152x: already in driver\n"); + } in_driver++; should_leave=func; @@ -2725,11 +2805,10 @@ save_flags(flags); cli(); printk("\naha152x: leaving %s() (%x)\n", func, jiffies); - if(!in_driver) - { - printk("aha152x: %s already left.\n", should_leave); - panic("aha152x: %s already left driver.\n"); - } + if(!in_driver) { + printk("aha152x: %s already left.\n", should_leave); + panic("aha152x: %s already left driver.\n"); + } in_driver--; should_leave=func; @@ -2743,49 +2822,47 @@ static void show_command(Scsi_Cmnd *ptr) { printk("0x%08x: target=%d; lun=%d; cmnd=(", - (unsigned int) ptr, ptr->target, ptr->lun); + (unsigned int) ptr, ptr->target, ptr->lun); print_command(ptr->cmnd); printk("); residual=%d; buffers=%d; phase |", - ptr->SCp.this_residual, ptr->SCp.buffers_residual); + ptr->SCp.this_residual, ptr->SCp.buffers_residual); if(ptr->SCp.phase & not_issued ) printk("not issued|"); if(ptr->SCp.phase & in_selection) printk("in selection|"); if(ptr->SCp.phase & disconnected) printk("disconnected|"); if(ptr->SCp.phase & aborted ) printk("aborted|"); if(ptr->SCp.phase & sent_ident ) printk("send_ident|"); - if(ptr->SCp.phase & in_other) - { - printk("; in other("); - switch((ptr->SCp.phase >> 16) & P_MASK) - { - case P_DATAO: - printk("DATA OUT"); - break; - case P_DATAI: - printk("DATA IN"); - break; - case P_CMD: - printk("COMMAND"); - break; - case P_STATUS: - printk("STATUS"); - break; - case P_MSGO: - printk("MESSAGE OUT"); - break; - case P_MSGI: - printk("MESSAGE IN"); - break; - default: - printk("*illegal*"); - break; - } - printk(")"); - if(ptr->SCp.phase & (1<<16)) - printk("; phaseend"); + if(ptr->SCp.phase & in_other) { + printk("; in other("); + switch((ptr->SCp.phase >> 16) & P_MASK) { + case P_DATAO: + printk("DATA OUT"); + break; + case P_DATAI: + printk("DATA IN"); + break; + case P_CMD: + printk("COMMAND"); + break; + case P_STATUS: + printk("STATUS"); + break; + case P_MSGO: + printk("MESSAGE OUT"); + break; + case P_MSGI: + printk("MESSAGE IN"); + break; + default: + printk("*illegal*"); + break; } + printk(")"); + if(ptr->SCp.phase & (1<<16)) + printk("; phaseend"); + } printk("; next=0x%08x\n", (unsigned int) ptr->host_scribble); } @@ -2845,57 +2922,234 @@ if(ptr->SCp.phase & disconnected) SPRINTF("disconnected|"); if(ptr->SCp.phase & aborted ) SPRINTF("aborted|"); if(ptr->SCp.phase & sent_ident ) SPRINTF("send_ident|"); - if(ptr->SCp.phase & in_other) - { - SPRINTF("; in other("); - switch((ptr->SCp.phase >> 16) & P_MASK) - { - case P_DATAO: - SPRINTF("DATA OUT"); - break; - case P_DATAI: - SPRINTF("DATA IN"); - break; - case P_CMD: - SPRINTF("COMMAND"); - break; - case P_STATUS: - SPRINTF("STATUS"); - break; - case P_MSGO: - SPRINTF("MESSAGE OUT"); - break; - case P_MSGI: - SPRINTF("MESSAGE IN"); - break; - default: - SPRINTF("*illegal*"); - break; - } - SPRINTF(")"); - if(ptr->SCp.phase & (1<<16)) - SPRINTF("; phaseend"); + if(ptr->SCp.phase & in_other) { + SPRINTF("; in other("); + switch((ptr->SCp.phase >> 16) & P_MASK) { + case P_DATAO: + SPRINTF("DATA OUT"); + break; + case P_DATAI: + SPRINTF("DATA IN"); + break; + case P_CMD: + SPRINTF("COMMAND"); + break; + case P_STATUS: + SPRINTF("STATUS"); + break; + case P_MSGO: + SPRINTF("MESSAGE OUT"); + break; + case P_MSGI: + SPRINTF("MESSAGE IN"); + break; + default: + SPRINTF("*illegal*"); + break; } + SPRINTF(")"); + if(ptr->SCp.phase & (1<<16)) + SPRINTF("; phaseend"); + } SPRINTF("; next=0x%08x\n", (unsigned int) ptr->host_scribble); return(pos-start); } +static int get_ports(struct Scsi_Host *shpnt, char *pos) +{ + char *start = pos; + int s; + +#ifdef SKIP_PORTS + if(HOSTDATA(shpnt)->debug & debug_skipports) + return; +#endif + + SPRINTF("\n%s: ", CURRENT_SC ? "on bus" : "waiting"); + + s=GETPORT(SCSISEQ); + SPRINTF("SCSISEQ ("); + if(s & TEMODEO) SPRINTF("TARGET MODE "); + if(s & ENSELO) SPRINTF("SELO "); + if(s & ENSELI) SPRINTF("SELI "); + if(s & ENRESELI) SPRINTF("RESELI "); + if(s & ENAUTOATNO) SPRINTF("AUTOATNO "); + if(s & ENAUTOATNI) SPRINTF("AUTOATNI "); + if(s & ENAUTOATNP) SPRINTF("AUTOATNP "); + if(s & SCSIRSTO) SPRINTF("SCSIRSTO "); + SPRINTF(");"); + + SPRINTF(" SCSISIG ("); + s=GETPORT(SCSISIG); + switch(s & P_MASK) { + case P_DATAO: + SPRINTF("DATA OUT"); + break; + case P_DATAI: + SPRINTF("DATA IN"); + break; + case P_CMD: + SPRINTF("COMMAND"); + break; + case P_STATUS: + SPRINTF("STATUS"); + break; + case P_MSGO: + SPRINTF("MESSAGE OUT"); + break; + case P_MSGI: + SPRINTF("MESSAGE IN"); + break; + default: + SPRINTF("*illegal*"); + break; + } + + SPRINTF("); "); + + SPRINTF("INTSTAT (%s); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo"); + + SPRINTF("SSTAT ("); + s=GETPORT(SSTAT0); + if(s & TARGET) SPRINTF("TARGET "); + if(s & SELDO) SPRINTF("SELDO "); + if(s & SELDI) SPRINTF("SELDI "); + if(s & SELINGO) SPRINTF("SELINGO "); + if(s & SWRAP) SPRINTF("SWRAP "); + if(s & SDONE) SPRINTF("SDONE "); + if(s & SPIORDY) SPRINTF("SPIORDY "); + if(s & DMADONE) SPRINTF("DMADONE "); + + s=GETPORT(SSTAT1); + if(s & SELTO) SPRINTF("SELTO "); + if(s & ATNTARG) SPRINTF("ATNTARG "); + if(s & SCSIRSTI) SPRINTF("SCSIRSTI "); + if(s & PHASEMIS) SPRINTF("PHASEMIS "); + if(s & BUSFREE) SPRINTF("BUSFREE "); + if(s & SCSIPERR) SPRINTF("SCSIPERR "); + if(s & PHASECHG) SPRINTF("PHASECHG "); + if(s & REQINIT) SPRINTF("REQINIT "); + SPRINTF("); "); + + + SPRINTF("SSTAT ("); + + s=GETPORT(SSTAT0) & GETPORT(SIMODE0); + + if(s & TARGET) SPRINTF("TARGET "); + if(s & SELDO) SPRINTF("SELDO "); + if(s & SELDI) SPRINTF("SELDI "); + if(s & SELINGO) SPRINTF("SELINGO "); + if(s & SWRAP) SPRINTF("SWRAP "); + if(s & SDONE) SPRINTF("SDONE "); + if(s & SPIORDY) SPRINTF("SPIORDY "); + if(s & DMADONE) SPRINTF("DMADONE "); + + s=GETPORT(SSTAT1) & GETPORT(SIMODE1); + + if(s & SELTO) SPRINTF("SELTO "); + if(s & ATNTARG) SPRINTF("ATNTARG "); + if(s & SCSIRSTI) SPRINTF("SCSIRSTI "); + if(s & PHASEMIS) SPRINTF("PHASEMIS "); + if(s & BUSFREE) SPRINTF("BUSFREE "); + if(s & SCSIPERR) SPRINTF("SCSIPERR "); + if(s & PHASECHG) SPRINTF("PHASECHG "); + if(s & REQINIT) SPRINTF("REQINIT "); + SPRINTF("); "); + + SPRINTF("SXFRCTL0 ("); + + s=GETPORT(SXFRCTL0); + if(s & SCSIEN) SPRINTF("SCSIEN "); + if(s & DMAEN) SPRINTF("DMAEN "); + if(s & CH1) SPRINTF("CH1 "); + if(s & CLRSTCNT) SPRINTF("CLRSTCNT "); + if(s & SPIOEN) SPRINTF("SPIOEN "); + if(s & CLRCH1) SPRINTF("CLRCH1 "); + SPRINTF("); "); + + SPRINTF("SIGNAL ("); + + s=GETPORT(SCSISIG); + if(s & ATNI) SPRINTF("ATNI "); + if(s & SELI) SPRINTF("SELI "); + if(s & BSYI) SPRINTF("BSYI "); + if(s & REQI) SPRINTF("REQI "); + if(s & ACKI) SPRINTF("ACKI "); + SPRINTF("); "); + + SPRINTF("SELID (%02x), ", GETPORT(SELID)); + + SPRINTF("SSTAT2 ("); + + s=GETPORT(SSTAT2); + if(s & SOFFSET) SPRINTF("SOFFSET "); + if(s & SEMPTY) SPRINTF("SEMPTY "); + if(s & SFULL) SPRINTF("SFULL "); + SPRINTF("); SFCNT (%d); ", s & (SFULL|SFCNT)); + + s=GETPORT(SSTAT3); + SPRINTF("SCSICNT (%d), OFFCNT(%d), ", (s&0xf0)>>4, s&0x0f); + + SPRINTF("SSTAT4 ("); + s=GETPORT(SSTAT4); + if(s & SYNCERR) SPRINTF("SYNCERR "); + if(s & FWERR) SPRINTF("FWERR "); + if(s & FRERR) SPRINTF("FRERR "); + SPRINTF("); "); + + SPRINTF("DMACNTRL0 ("); + s=GETPORT(DMACNTRL0); + SPRINTF("%s ", s & _8BIT ? "8BIT" : "16BIT"); + SPRINTF("%s ", s & DMA ? "DMA" : "PIO" ); + SPRINTF("%s ", s & WRITE_READ ? "WRITE" : "READ" ); + if(s & ENDMA) SPRINTF("ENDMA "); + if(s & INTEN) SPRINTF("INTEN "); + if(s & RSTFIFO) SPRINTF("RSTFIFO "); + if(s & SWINT) SPRINTF("SWINT "); + SPRINTF("); "); + + SPRINTF("DMASTAT ("); + s=GETPORT(DMASTAT); + if(s & ATDONE) SPRINTF("ATDONE "); + if(s & WORDRDY) SPRINTF("WORDRDY "); + if(s & DFIFOFULL) SPRINTF("DFIFOFULL "); + if(s & DFIFOEMP) SPRINTF("DFIFOEMP "); + SPRINTF(")\n\n"); + + SPRINTF("enabled interrupts ("); + + s=GETPORT(SIMODE0); + if(s & ENSELDO) SPRINTF("ENSELDO "); + if(s & ENSELDI) SPRINTF("ENSELDI "); + if(s & ENSELINGO) SPRINTF("ENSELINGO "); + if(s & ENSWRAP) SPRINTF("ENSWRAP "); + if(s & ENSDONE) SPRINTF("ENSDONE "); + if(s & ENSPIORDY) SPRINTF("ENSPIORDY "); + if(s & ENDMADONE) SPRINTF("ENDMADONE "); + + s=GETPORT(SIMODE1); + if(s & ENSELTIMO) SPRINTF("ENSELTIMO "); + if(s & ENATNTARG) SPRINTF("ENATNTARG "); + if(s & ENPHASEMIS) SPRINTF("ENPHASEMIS "); + if(s & ENBUSFREE) SPRINTF("ENBUSFREE "); + if(s & ENSCSIPERR) SPRINTF("ENSCSIPERR "); + if(s & ENPHASECHG) SPRINTF("ENPHASECHG "); + if(s & ENREQINIT) SPRINTF("ENREQINIT "); + SPRINTF(")\n"); + + return (pos-start); +} + #undef SPRINTF #define SPRINTF(args...) do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0) -int aha152x_proc_info( - char *buffer, - char **start, - off_t offset, - int length, - int hostno, - int inout - ) +int aha152x_proc_info(char *buffer, char **start, + off_t offset, int length, int hostno, int inout) { int i; char *pos = buffer; - Scsi_Device *scd; struct Scsi_Host *shpnt; unsigned long flags; Scsi_Cmnd *ptr; @@ -2915,7 +3169,7 @@ save_flags(flags); cli(); - SPRINTF("vital data:\nioports 0x%04x to 0x%04x\n", + SPRINTF("ioports 0x%04x to 0x%04x\n", shpnt->io_port, shpnt->io_port+shpnt->n_io_port-1); SPRINTF("interrupt 0x%02x\n", shpnt->irq); SPRINTF("disconnection/reconnection %s\n", @@ -2924,35 +3178,36 @@ HOSTDATA(shpnt)->parity ? "enabled" : "disabled"); SPRINTF("synchronous transfers %s\n", HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled"); - SPRINTF("current queued %d commands\n", - HOSTDATA(shpnt)->commands); + SPRINTF("%d commands currently queued\n", HOSTDATA(shpnt)->commands); + if(HOSTDATA(shpnt)->synchronous) { #if 0 - SPRINTF("synchronously operating targets (tick=%ld ns):\n", - 250000000/loops_per_sec); - for(i=0; i<8; i++) - if(HOSTDATA(shpnt)->syncrate[i]&0x7f) - SPRINTF("target %d: period %dT/%ldns; req/ack offset %d\n", - i, - (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2), - (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)* - 250000000/loops_per_sec, - HOSTDATA(shpnt)->syncrate[i]&0x0f); + SPRINTF("synchronously operating targets (tick=%ld ns):\n", + 250000000/loops_per_sec); + for(i=0; i<8; i++) + if(HOSTDATA(shpnt)->syncrate[i]&0x7f) + SPRINTF("target %d: period %dT/%ldns; req/ack offset %d\n", + i, + (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2), + (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)* + 250000000/loops_per_sec, + HOSTDATA(shpnt)->syncrate[i]&0x0f); #else - SPRINTF("synchronously operating targets (tick=50 ns):\n"); - for(i=0; i<8; i++) - if(HOSTDATA(shpnt)->syncrate[i]&0x7f) - SPRINTF("target %d: period %dT/%dns; req/ack offset %d\n", - i, - (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2), - (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)*50, - HOSTDATA(shpnt)->syncrate[i]&0x0f); + SPRINTF("synchronously operating targets (tick=50 ns):\n"); + for(i=0; i<8; i++) + if(HOSTDATA(shpnt)->syncrate[i]&0x7f) + SPRINTF("target %d: period %dT/%dns; req/ack offset %d\n", + i, + (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2), + (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)*50, + HOSTDATA(shpnt)->syncrate[i]&0x0f); #endif + } #ifdef DEBUG_AHA152X #define PDEBUG(flags,txt) if(HOSTDATA(shpnt)->debug & flags) SPRINTF("(%s) ", txt); - SPRINTF("enabled debugging options:\n"); + SPRINTF("enabled debugging options: "); PDEBUG(debug_skipports, "skip ports"); PDEBUG(debug_queue, "queue"); @@ -2974,64 +3229,30 @@ SPRINTF("\n"); #endif - SPRINTF("queue status:\nnot yet issued commands:\n"); - for(ptr=ISSUE_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) - pos += get_command(pos, ptr); - - if(CURRENT_SC) - { - SPRINTF("current command:\n"); - pos += get_command(pos, CURRENT_SC); - } - - SPRINTF("disconnected commands:\n"); - for(ptr=DISCONNECTED_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) - pos += get_command(pos, ptr); + SPRINTF("\nqueue status:\n"); + if(ISSUE_SC) { + SPRINTF("not yet issued commands:\n"); + for(ptr=ISSUE_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) + pos += get_command(pos, ptr); + } else + SPRINTF("no not yet issued commands\n"); + + if(CURRENT_SC) { + SPRINTF("current command:\n"); + pos += get_command(pos, CURRENT_SC); + } else + SPRINTF("no current command\n"); + + if(DISCONNECTED_SC) { + SPRINTF("disconnected commands:\n"); + for(ptr=DISCONNECTED_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) + pos += get_command(pos, ptr); + } else + SPRINTF("no disconnected commands\n"); restore_flags(flags); - - scd = scsi_devices; - - SPRINTF("Attached devices: %s\n", (scd)?"":"none"); - - while (scd) { - if (scd->host == shpnt) { - - SPRINTF("Channel: %02d Id: %02d Lun: %02d\n Vendor: ", - scd->channel, scd->id, scd->lun); - for (i=0; i<8; i++) { - if (scd->vendor[i] >= 0x20) - SPRINTF("%c", scd->vendor[i]); - else - SPRINTF(" "); - } - SPRINTF(" Model: "); - for (i = 0; i < 16; i++) { - if (scd->model[i] >= 0x20) - SPRINTF("%c", scd->model[i]); - else - SPRINTF(" "); - } - SPRINTF(" Rev: "); - for (i = 0; i < 4; i++) { - if (scd->rev[i] >= 0x20) - SPRINTF("%c", scd->rev[i]); - else - SPRINTF(" "); - } - SPRINTF("\n"); - - SPRINTF(" Type: %d ", scd->type); - SPRINTF(" ANSI SCSI revision: %02x", - (scd->scsi_level < 3)?1:2); - - if (scd->scsi_level == 2) - SPRINTF(" CCS\n"); - else - SPRINTF("\n"); - } - scd = scd->next; - } + + pos += get_ports(shpnt, pos); *start=buffer+offset; if (pos - buffer < offset) diff -u --recursive --new-file v2.0.13/linux/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h --- v2.0.13/linux/drivers/scsi/aha152x.h Sun Jun 9 12:48:07 1996 +++ linux/drivers/scsi/aha152x.h Sat Aug 17 21:02:50 1996 @@ -2,7 +2,7 @@ #define _AHA152X_H /* - * $Id: aha152x.h,v 1.16 1996/06/09 00:08:30 fischer Exp $ + * $Id: aha152x.h,v 1.17 1996/08/17 16:07:38 fischer Exp fischer $ */ #if defined(__KERNEL__) @@ -11,362 +11,346 @@ #include "scsi.h" #include -int aha152x_detect(Scsi_Host_Template *); -int aha152x_command(Scsi_Cmnd *); -int aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -int aha152x_abort(Scsi_Cmnd *); -int aha152x_reset(Scsi_Cmnd *); -int aha152x_biosparam(Disk *, kdev_t, int*); +int aha152x_detect(Scsi_Host_Template *); +int aha152x_command(Scsi_Cmnd *); +int aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +int aha152x_abort(Scsi_Cmnd *); +int aha152x_reset(Scsi_Cmnd *, unsigned int); +int aha152x_biosparam(Disk *, kdev_t, int*); int aha152x_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); /* number of queueable commands (unless we support more than 1 cmd_per_lun this should do) */ -#define AHA152X_MAXQUEUE 7 +#define AHA152X_MAXQUEUE 7 -#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.16 $" +#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.17 $" extern struct proc_dir_entry proc_scsi_aha152x; /* Initial value of Scsi_Host entry */ -#define AHA152X { /* next */ NULL, \ - /* usage_count */ NULL, \ - /* proc_dir */ &proc_scsi_aha152x, \ - /* proc_info */ aha152x_proc_info, \ - /* name */ AHA152X_REVID, \ - /* detect */ aha152x_detect, \ - /* release */ NULL, \ - /* info */ NULL, \ - /* command */ aha152x_command, \ - /* queuecommand */ aha152x_queue, \ - /* abort */ aha152x_abort, \ - /* reset */ aha152x_reset, \ - /* slave_attach */ /* NULL */ 0, \ - /* bios_param */ aha152x_biosparam, \ - /* can_queue */ 1, \ - /* this_id */ 7, \ - /* sg_tablesize */ SG_ALL, \ - /* cmd_per_lun */ 1, \ - /* present */ 0, \ - /* unchecked_isa_dma */ 0, \ - /* use_clustering */ DISABLE_CLUSTERING } +#define AHA152X { /* next */ 0, \ + /* usage_count */ 0, \ + /* proc_dir */ &proc_scsi_aha152x, \ + /* proc_info */ aha152x_proc_info, \ + /* name */ AHA152X_REVID, \ + /* detect */ aha152x_detect, \ + /* release */ 0, \ + /* info */ 0, \ + /* command */ aha152x_command, \ + /* queuecommand */ aha152x_queue, \ + /* abort */ aha152x_abort, \ + /* reset */ aha152x_reset, \ + /* slave_attach */ 0, \ + /* bios_param */ aha152x_biosparam, \ + /* can_queue */ 1, \ + /* this_id */ 7, \ + /* sg_tablesize */ SG_ALL, \ + /* cmd_per_lun */ 1, \ + /* present */ 0, \ + /* unchecked_isa_dma */ 0, \ + /* use_clustering */ DISABLE_CLUSTERING } #endif /* port addresses */ -#define SCSISEQ (shpnt->io_port+0x00) /* SCSI sequence control */ -#define SXFRCTL0 (shpnt->io_port+0x01) /* SCSI transfer control 0 */ -#define SXFRCTL1 (shpnt->io_port+0x02) /* SCSI transfer control 1 */ -#define SCSISIG (shpnt->io_port+0x03) /* SCSI signal in/out */ -#define SCSIRATE (shpnt->io_port+0x04) /* SCSI rate control */ -#define SELID (shpnt->io_port+0x05) /* selection/reselection ID */ -#define SCSIID SELID /* SCSI ID */ -#define SCSIDAT (shpnt->io_port+0x06) /* SCSI latched data */ -#define SCSIBUS (shpnt->io_port+0x07) /* SCSI data bus */ -#define STCNT0 (shpnt->io_port+0x08) /* SCSI transfer count 0 */ -#define STCNT1 (shpnt->io_port+0x09) /* SCSI transfer count 1 */ -#define STCNT2 (shpnt->io_port+0x0a) /* SCSI transfer count 2 */ -#define SSTAT0 (shpnt->io_port+0x0b) /* SCSI interrupt status 0 */ -#define SSTAT1 (shpnt->io_port+0x0c) /* SCSI interrupt status 1 */ -#define SSTAT2 (shpnt->io_port+0x0d) /* SCSI interrupt status 2 */ -#define SCSITEST (shpnt->io_port+0x0e) /* SCSI test control */ -#define SSTAT3 SCSITEST /* SCSI interrupt status 3 */ -#define SSTAT4 (shpnt->io_port+0x0f) /* SCSI status 4 */ -#define SIMODE0 (shpnt->io_port+0x10) /* SCSI interrupt mode 0 */ -#define SIMODE1 (shpnt->io_port+0x11) /* SCSI interrupt mode 1 */ -#define DMACNTRL0 (shpnt->io_port+0x12) /* DMA control 0 */ -#define DMACNTRL1 (shpnt->io_port+0x13) /* DMA control 1 */ -#define DMASTAT (shpnt->io_port+0x14) /* DMA status */ -#define FIFOSTAT (shpnt->io_port+0x15) /* FIFO status */ -#define DATAPORT (shpnt->io_port+0x16) /* DATA port */ -#define BRSTCNTRL (shpnt->io_port+0x18) /* burst control */ -#define PORTA (shpnt->io_port+0x1a) /* PORT A */ -#define PORTB (shpnt->io_port+0x1b) /* PORT B */ -#define REV (shpnt->io_port+0x1c) /* revision */ -#define STACK (shpnt->io_port+0x1d) /* stack */ -#define TEST (shpnt->io_port+0x1e) /* test register */ +#define SCSISEQ (shpnt->io_port+0x00) /* SCSI sequence control */ +#define SXFRCTL0 (shpnt->io_port+0x01) /* SCSI transfer control 0 */ +#define SXFRCTL1 (shpnt->io_port+0x02) /* SCSI transfer control 1 */ +#define SCSISIG (shpnt->io_port+0x03) /* SCSI signal in/out */ +#define SCSIRATE (shpnt->io_port+0x04) /* SCSI rate control */ +#define SELID (shpnt->io_port+0x05) /* selection/reselection ID */ +#define SCSIID SELID /* SCSI ID */ +#define SCSIDAT (shpnt->io_port+0x06) /* SCSI latched data */ +#define SCSIBUS (shpnt->io_port+0x07) /* SCSI data bus */ +#define STCNT0 (shpnt->io_port+0x08) /* SCSI transfer count 0 */ +#define STCNT1 (shpnt->io_port+0x09) /* SCSI transfer count 1 */ +#define STCNT2 (shpnt->io_port+0x0a) /* SCSI transfer count 2 */ +#define SSTAT0 (shpnt->io_port+0x0b) /* SCSI interrupt status 0 */ +#define SSTAT1 (shpnt->io_port+0x0c) /* SCSI interrupt status 1 */ +#define SSTAT2 (shpnt->io_port+0x0d) /* SCSI interrupt status 2 */ +#define SCSITEST (shpnt->io_port+0x0e) /* SCSI test control */ +#define SSTAT3 SCSITEST /* SCSI interrupt status 3 */ +#define SSTAT4 (shpnt->io_port+0x0f) /* SCSI status 4 */ +#define SIMODE0 (shpnt->io_port+0x10) /* SCSI interrupt mode 0 */ +#define SIMODE1 (shpnt->io_port+0x11) /* SCSI interrupt mode 1 */ +#define DMACNTRL0 (shpnt->io_port+0x12) /* DMA control 0 */ +#define DMACNTRL1 (shpnt->io_port+0x13) /* DMA control 1 */ +#define DMASTAT (shpnt->io_port+0x14) /* DMA status */ +#define FIFOSTAT (shpnt->io_port+0x15) /* FIFO status */ +#define DATAPORT (shpnt->io_port+0x16) /* DATA port */ +#define BRSTCNTRL (shpnt->io_port+0x18) /* burst control */ +#define PORTA (shpnt->io_port+0x1a) /* PORT A */ +#define PORTB (shpnt->io_port+0x1b) /* PORT B */ +#define REV (shpnt->io_port+0x1c) /* revision */ +#define STACK (shpnt->io_port+0x1d) /* stack */ +#define TEST (shpnt->io_port+0x1e) /* test register */ /* used in aha152x_porttest */ -#define O_PORTA (0x1a) /* PORT A */ -#define O_PORTB (0x1b) /* PORT B */ -#define O_DMACNTRL1 (0x13) /* DMA control 1 */ -#define O_STACK (0x1d) /* stack */ -#define IO_RANGE 0x20 +#define O_PORTA 0x1a /* PORT A */ +#define O_PORTB 0x1b /* PORT B */ +#define O_DMACNTRL1 0x13 /* DMA control 1 */ +#define O_STACK 0x1d /* stack */ +#define IO_RANGE 0x20 /* bits and bitmasks to ports */ /* SCSI sequence control */ -#define TEMODEO 0x80 -#define ENSELO 0x40 -#define ENSELI 0x20 -#define ENRESELI 0x10 -#define ENAUTOATNO 0x08 -#define ENAUTOATNI 0x04 -#define ENAUTOATNP 0x02 -#define SCSIRSTO 0x01 +#define TEMODEO 0x80 +#define ENSELO 0x40 +#define ENSELI 0x20 +#define ENRESELI 0x10 +#define ENAUTOATNO 0x08 +#define ENAUTOATNI 0x04 +#define ENAUTOATNP 0x02 +#define SCSIRSTO 0x01 /* SCSI transfer control 0 */ -#define SCSIEN 0x80 -#define DMAEN 0x40 -#define CH1 0x20 -#define CLRSTCNT 0x10 -#define SPIOEN 0x08 -#define CLRCH1 0x02 +#define SCSIEN 0x80 +#define DMAEN 0x40 +#define CH1 0x20 +#define CLRSTCNT 0x10 +#define SPIOEN 0x08 +#define CLRCH1 0x02 /* SCSI transfer control 1 */ -#define BITBUCKET 0x80 -#define SWRAPEN 0x40 -#define ENSPCHK 0x20 -#define STIMESEL 0x18 /* mask */ -#define STIMESEL_ 3 -#define ENSTIMER 0x04 -#define BYTEALIGN 0x02 +#define BITBUCKET 0x80 +#define SWRAPEN 0x40 +#define ENSPCHK 0x20 +#define STIMESEL 0x18 /* mask */ +#define STIMESEL_ 3 +#define ENSTIMER 0x04 +#define BYTEALIGN 0x02 /* SCSI signal IN */ -#define CDI 0x80 -#define IOI 0x40 -#define MSGI 0x20 -#define ATNI 0x10 -#define SELI 0x08 -#define BSYI 0x04 -#define REQI 0x02 -#define ACKI 0x01 +#define CDI 0x80 +#define IOI 0x40 +#define MSGI 0x20 +#define ATNI 0x10 +#define SELI 0x08 +#define BSYI 0x04 +#define REQI 0x02 +#define ACKI 0x01 /* SCSI Phases */ -#define P_MASK (MSGI|CDI|IOI) -#define P_DATAO (0) -#define P_DATAI (IOI) -#define P_CMD (CDI) -#define P_STATUS (CDI|IOI) -#define P_MSGO (MSGI|CDI) -#define P_MSGI (MSGI|CDI|IOI) +#define P_MASK (MSGI|CDI|IOI) +#define P_DATAO (0) +#define P_DATAI (IOI) +#define P_CMD (CDI) +#define P_STATUS (CDI|IOI) +#define P_MSGO (MSGI|CDI) +#define P_MSGI (MSGI|CDI|IOI) /* SCSI signal OUT */ -#define CDO 0x80 -#define IOO 0x40 -#define MSGO 0x20 -#define ATNO 0x10 -#define SELO 0x08 -#define BSYO 0x04 -#define REQO 0x02 -#define ACKO 0x01 +#define CDO 0x80 +#define IOO 0x40 +#define MSGO 0x20 +#define ATNO 0x10 +#define SELO 0x08 +#define BSYO 0x04 +#define REQO 0x02 +#define ACKO 0x01 /* SCSI rate control */ -#define SXFR 0x70 /* mask */ -#define SXFR_ 4 -#define SOFS 0x0f /* mask */ +#define SXFR 0x70 /* mask */ +#define SXFR_ 4 +#define SOFS 0x0f /* mask */ /* SCSI ID */ -#define OID 0x70 -#define OID_ 4 -#define TID 0x07 +#define OID 0x70 +#define OID_ 4 +#define TID 0x07 /* SCSI transfer count */ -#define GETSTCNT() ( (GETPORT(STCNT2)<<16) \ - + (GETPORT(STCNT1)<< 8) \ - + GETPORT(STCNT0) ) - -#define SETSTCNT(X) { SETPORT(STCNT2, ((X) & 0xFF0000) >> 16); \ - SETPORT(STCNT1, ((X) & 0x00FF00) >> 8); \ - SETPORT(STCNT0, ((X) & 0x0000FF) ); } +#define GETSTCNT() ( (GETPORT(STCNT2)<<16) \ + + (GETPORT(STCNT1)<< 8) \ + + GETPORT(STCNT0) ) + +#define SETSTCNT(X) { SETPORT(STCNT2, ((X) & 0xFF0000) >> 16); \ + SETPORT(STCNT1, ((X) & 0x00FF00) >> 8); \ + SETPORT(STCNT0, ((X) & 0x0000FF) ); } /* SCSI interrupt status */ -#define TARGET 0x80 -#define SELDO 0x40 -#define SELDI 0x20 -#define SELINGO 0x10 -#define SWRAP 0x08 -#define SDONE 0x04 -#define SPIORDY 0x02 -#define DMADONE 0x01 - -#define SETSDONE 0x80 -#define CLRSELDO 0x40 -#define CLRSELDI 0x20 -#define CLRSELINGO 0x10 -#define CLRSWRAP 0x08 -#define CLRSDONE 0x04 -#define CLRSPIORDY 0x02 -#define CLRDMADONE 0x01 +#define TARGET 0x80 +#define SELDO 0x40 +#define SELDI 0x20 +#define SELINGO 0x10 +#define SWRAP 0x08 +#define SDONE 0x04 +#define SPIORDY 0x02 +#define DMADONE 0x01 + +#define SETSDONE 0x80 +#define CLRSELDO 0x40 +#define CLRSELDI 0x20 +#define CLRSELINGO 0x10 +#define CLRSWRAP 0x08 +#define CLRSDONE 0x04 +#define CLRSPIORDY 0x02 +#define CLRDMADONE 0x01 /* SCSI status 1 */ -#define SELTO 0x80 -#define ATNTARG 0x40 -#define SCSIRSTI 0x20 -#define PHASEMIS 0x10 -#define BUSFREE 0x08 -#define SCSIPERR 0x04 -#define PHASECHG 0x02 -#define REQINIT 0x01 - -#define CLRSELTIMO 0x80 -#define CLRATNO 0x40 -#define CLRSCSIRSTI 0x20 -#define CLRBUSFREE 0x08 -#define CLRSCSIPERR 0x04 -#define CLRPHASECHG 0x02 -#define CLRREQINIT 0x01 +#define SELTO 0x80 +#define ATNTARG 0x40 +#define SCSIRSTI 0x20 +#define PHASEMIS 0x10 +#define BUSFREE 0x08 +#define SCSIPERR 0x04 +#define PHASECHG 0x02 +#define REQINIT 0x01 + +#define CLRSELTIMO 0x80 +#define CLRATNO 0x40 +#define CLRSCSIRSTI 0x20 +#define CLRBUSFREE 0x08 +#define CLRSCSIPERR 0x04 +#define CLRPHASECHG 0x02 +#define CLRREQINIT 0x01 /* SCSI status 2 */ -#define SOFFSET 0x20 -#define SEMPTY 0x10 -#define SFULL 0x08 -#define SFCNT 0x07 /* mask */ +#define SOFFSET 0x20 +#define SEMPTY 0x10 +#define SFULL 0x08 +#define SFCNT 0x07 /* mask */ /* SCSI status 3 */ -#define SCSICNT 0xf0 /* mask */ -#define SCSICNT_ 4 -#define OFFCNT 0x0f /* mask */ +#define SCSICNT 0xf0 /* mask */ +#define SCSICNT_ 4 +#define OFFCNT 0x0f /* mask */ /* SCSI TEST control */ -#define SCTESTU 0x08 -#define SCTESTD 0x04 -#define STCTEST 0x01 +#define SCTESTU 0x08 +#define SCTESTD 0x04 +#define STCTEST 0x01 /* SCSI status 4 */ -#define SYNCERR 0x04 -#define FWERR 0x02 -#define FRERR 0x01 - -#define CLRSYNCERR 0x04 -#define CLRFWERR 0x02 -#define CLRFRERR 0x01 +#define SYNCERR 0x04 +#define FWERR 0x02 +#define FRERR 0x01 + +#define CLRSYNCERR 0x04 +#define CLRFWERR 0x02 +#define CLRFRERR 0x01 /* SCSI interrupt mode 0 */ -#define ENSELDO 0x40 -#define ENSELDI 0x20 -#define ENSELINGO 0x10 -#define ENSWRAP 0x08 -#define ENSDONE 0x04 -#define ENSPIORDY 0x02 -#define ENDMADONE 0x01 +#define ENSELDO 0x40 +#define ENSELDI 0x20 +#define ENSELINGO 0x10 +#define ENSWRAP 0x08 +#define ENSDONE 0x04 +#define ENSPIORDY 0x02 +#define ENDMADONE 0x01 /* SCSI interrupt mode 1 */ -#define ENSELTIMO 0x80 -#define ENATNTARG 0x40 -#define ENSCSIRST 0x20 -#define ENPHASEMIS 0x10 -#define ENBUSFREE 0x08 -#define ENSCSIPERR 0x04 -#define ENPHASECHG 0x02 -#define ENREQINIT 0x01 +#define ENSELTIMO 0x80 +#define ENATNTARG 0x40 +#define ENSCSIRST 0x20 +#define ENPHASEMIS 0x10 +#define ENBUSFREE 0x08 +#define ENSCSIPERR 0x04 +#define ENPHASECHG 0x02 +#define ENREQINIT 0x01 /* DMA control 0 */ -#define ENDMA 0x80 -#define _8BIT 0x40 -#define DMA 0x20 -#define WRITE_READ 0x08 -#define INTEN 0x04 -#define RSTFIFO 0x02 -#define SWINT 0x01 +#define ENDMA 0x80 +#define _8BIT 0x40 +#define DMA 0x20 +#define WRITE_READ 0x08 +#define INTEN 0x04 +#define RSTFIFO 0x02 +#define SWINT 0x01 /* DMA control 1 */ -#define PWRDWN 0x80 -#define STK 0x07 /* mask */ +#define PWRDWN 0x80 +#define STK 0x07 /* mask */ /* DMA status */ -#define ATDONE 0x80 -#define WORDRDY 0x40 -#define INTSTAT 0x20 -#define DFIFOFULL 0x10 -#define DFIFOEMP 0x08 +#define ATDONE 0x80 +#define WORDRDY 0x40 +#define INTSTAT 0x20 +#define DFIFOFULL 0x10 +#define DFIFOEMP 0x08 /* BURST control */ -#define BON 0xf0 -#define BOFF 0x0f +#define BON 0xf0 +#define BOFF 0x0f /* TEST REGISTER */ -#define BOFFTMR 0x40 -#define BONTMR 0x20 -#define STCNTH 0x10 -#define STCNTM 0x08 -#define STCNTL 0x04 -#define SCSIBLK 0x02 -#define DMABLK 0x01 +#define BOFFTMR 0x40 +#define BONTMR 0x20 +#define STCNTH 0x10 +#define STCNTM 0x08 +#define STCNTL 0x04 +#define SCSIBLK 0x02 +#define DMABLK 0x01 /* On the AHA-152x board PORTA and PORTB contain some information about the board's configuration. */ typedef union { struct { - unsigned reserved:2; /* reserved */ - unsigned tardisc:1; /* Target disconnect: 0=disabled, 1=enabled */ - unsigned syncneg:1; /* Initial sync neg: 0=disabled, 1=enabled */ - unsigned msgclasses:2; /* Message classes - 0=#4 - 1=#0, #1, #2, #3, #4 - 2=#0, #3, #4 - 3=#0, #4 - */ - unsigned boot:1; /* boot: 0=disabled, 1=enabled */ - unsigned dma:1; /* Transfer mode: 0=PIO; 1=DMA */ - unsigned id:3; /* SCSI-id */ - unsigned irq:2; /* IRQ-Channel: 0,3=12, 1=10, 2=11 */ - unsigned dmachan:2; /* DMA-Channel: 0=0, 1=5, 2=6, 3=7 */ - unsigned parity:1; /* SCSI-parity: 1=enabled 0=disabled */ + unsigned reserved:2; /* reserved */ + unsigned tardisc:1; /* Target disconnect: 0=disabled, 1=enabled */ + unsigned syncneg:1; /* Initial sync neg: 0=disabled, 1=enabled */ + unsigned msgclasses:2; /* Message classes + 0=#4 + 1=#0, #1, #2, #3, #4 + 2=#0, #3, #4 + 3=#0, #4 + */ + unsigned boot:1; /* boot: 0=disabled, 1=enabled */ + unsigned dma:1; /* Transfer mode: 0=PIO; 1=DMA */ + unsigned id:3; /* SCSI-id */ + unsigned irq:2; /* IRQ-Channel: 0,3=12, 1=10, 2=11 */ + unsigned dmachan:2; /* DMA-Channel: 0=0, 1=5, 2=6, 3=7 */ + unsigned parity:1; /* SCSI-parity: 1=enabled 0=disabled */ } fields; unsigned short port; } aha152x_config ; -#define cf_parity fields.parity -#define cf_dmachan fields.dmachan -#define cf_irq fields.irq -#define cf_id fields.id -#define cf_dma fields.dma -#define cf_boot fields.boot -#define cf_msgclasses fields.msgclasses -#define cf_syncneg fields.syncneg -#define cf_tardisc fields.tardisc -#define cf_port port +#define cf_parity fields.parity +#define cf_dmachan fields.dmachan +#define cf_irq fields.irq +#define cf_id fields.id +#define cf_dma fields.dma +#define cf_boot fields.boot +#define cf_msgclasses fields.msgclasses +#define cf_syncneg fields.syncneg +#define cf_tardisc fields.tardisc +#define cf_port port /* Some macros to manipulate ports and their bits */ -#define SETPORT(PORT, VAL) \ - outb( (VAL), (PORT) ) +#define SETPORT(PORT, VAL) outb( (VAL), (PORT) ) +#define SETPORTP(PORT, VAL) outb_p( (VAL), (PORT) ) +#define SETPORTW(PORT, VAL) outw( (VAL), (PORT) ) + +#define GETPORT(PORT) inb( PORT ) +#define GETPORTW(PORT) inw( PORT ) + +#define SETBITS(PORT, BITS) outb( (inb(PORT) | (BITS)), (PORT) ) +#define CLRBITS(PORT, BITS) outb( (inb(PORT) & ~(BITS)), (PORT) ) +#define CLRSETBITS(PORT, CLR, SET) outb( (inb(PORT) & ~(CLR)) | (SET) , (PORT) ) -#define SETPORTP(PORT, VAL) \ - outb_p( (VAL), (PORT) ) - -#define SETPORTW(PORT, VAL) \ - outw( (VAL), (PORT) ) - -#define GETPORT(PORT) \ - inb( PORT ) - -#define GETPORTW(PORT) \ - inw( PORT ) - -#define SETBITS(PORT, BITS) \ - outb( (inb(PORT) | (BITS)), (PORT) ) - -#define CLRBITS(PORT, BITS) \ - outb( (inb(PORT) & ~(BITS)), (PORT) ) - -#define CLRSETBITS(PORT, CLR, SET) \ - outb( (inb(PORT) & ~(CLR)) | (SET) , (PORT) ) - -#define TESTHI(PORT, BITS) \ - ((inb(PORT) & (BITS)) == BITS) - -#define TESTLO(PORT, BITS) \ - ((inb(PORT) & (BITS)) == 0) +#define TESTHI(PORT, BITS) ((inb(PORT) & (BITS)) == BITS) +#define TESTLO(PORT, BITS) ((inb(PORT) & (BITS)) == 0) #ifdef DEBUG_AHA152X enum { - debug_skipports =0x0001, - debug_queue =0x0002, - debug_intr =0x0004, - debug_selection =0x0008, - debug_msgo =0x0010, - debug_msgi =0x0020, - debug_status =0x0040, - debug_cmd =0x0080, - debug_datai =0x0100, - debug_datao =0x0200, - debug_abort =0x0400, - debug_done =0x0800, - debug_biosparam =0x1000, - debug_phases =0x2000, - debug_queues =0x4000, - debug_reset =0x8000, + debug_skipports = 0x0001, + debug_queue = 0x0002, + debug_intr = 0x0004, + debug_selection = 0x0008, + debug_msgo = 0x0010, + debug_msgi = 0x0020, + debug_status = 0x0040, + debug_cmd = 0x0080, + debug_datai = 0x0100, + debug_datao = 0x0200, + debug_abort = 0x0400, + debug_done = 0x0800, + debug_biosparam = 0x1000, + debug_phases = 0x2000, + debug_queues = 0x4000, + debug_reset = 0x8000, }; #endif diff -u --recursive --new-file v2.0.13/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c --- v2.0.13/linux/drivers/sound/ad1848.c Sat Jul 6 11:31:42 1996 +++ linux/drivers/sound/ad1848.c Sun Aug 18 10:46:48 1996 @@ -477,11 +477,11 @@ switch (cmd & 0xff) { case SOUND_MIXER_RECSRC: - return snd_ioctl_return ((int *) arg, ad1848_set_recmask (devc, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, ad1848_set_recmask (devc, get_user ((int *) arg))); break; default: - return snd_ioctl_return ((int *) arg, ad1848_mixer_set (devc, cmd & 0xff, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, ad1848_mixer_set (devc, cmd & 0xff, get_user ((int *) arg))); } else switch (cmd & 0xff) /* diff -u --recursive --new-file v2.0.13/linux/drivers/sound/audio.c linux/drivers/sound/audio.c --- v2.0.13/linux/drivers/sound/audio.c Sat Jul 6 11:31:42 1996 +++ linux/drivers/sound/audio.c Sun Aug 18 10:46:48 1996 @@ -35,7 +35,7 @@ static int local_conversion[MAX_AUDIO_DEV]; static int -set_format (int dev, int fmt) +set_format (int dev, long fmt) { if (fmt != AFMT_QUERY) { @@ -64,7 +64,7 @@ audio_open (int dev, struct fileinfo *file) { int ret; - int bits; + long bits; int dev_type = dev & 0x0f; int mode = file->mode & O_ACCMODE; @@ -381,7 +381,7 @@ break; case SNDCTL_DSP_SETFMT: - return snd_ioctl_return ((int *) arg, set_format (dev, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, set_format (dev, get_user ((int *) arg))); case SNDCTL_DSP_GETISPACE: if (!(audio_devs[dev]->open_mode & OPEN_READ)) diff -u --recursive --new-file v2.0.13/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c --- v2.0.13/linux/drivers/sound/dmabuf.c Tue Jul 23 10:26:49 1996 +++ linux/drivers/sound/dmabuf.c Sun Aug 18 10:46:48 1996 @@ -227,13 +227,13 @@ static unsigned int default_set_bits (int dev, unsigned int bits) { - return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_SETFMT, (caddr_t) bits, 1); + return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_SETFMT, (caddr_t) (long) bits, 1); } static int default_set_speed (int dev, int speed) { - return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_SPEED, (caddr_t) speed, 1); + return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_SPEED, (caddr_t) (long) speed, 1); } static short @@ -241,7 +241,7 @@ { int c = channels; - return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_CHANNELS, (caddr_t) c, 1); + return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_CHANNELS, (caddr_t) (long) c, 1); } static void @@ -761,14 +761,14 @@ { struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out; struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in; - int iarg = (int) arg; + long larg = (long) arg; switch (cmd) { case SOUND_PCM_WRITE_RATE: if (local) - return audio_devs[dev]->d->set_speed (dev, (int) arg); - return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_speed (dev, get_fs_long ((long *) arg))); + return audio_devs[dev]->d->set_speed (dev, larg); + return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_speed (dev, get_user ((int *) arg))); case SOUND_PCM_READ_RATE: if (local) @@ -777,13 +777,13 @@ case SNDCTL_DSP_STEREO: if (local) - return audio_devs[dev]->d->set_channels (dev, (int) arg + 1) - 1; - return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_channels (dev, get_fs_long ((long *) arg) + 1) - 1); + return audio_devs[dev]->d->set_channels (dev, larg + 1) - 1; + return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_channels (dev, get_user ((int *) arg) + 1) - 1); case SOUND_PCM_WRITE_CHANNELS: if (local) - return audio_devs[dev]->d->set_channels (dev, (short) iarg); - return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_channels (dev, get_fs_long ((long *) arg))); + return audio_devs[dev]->d->set_channels (dev, (short) larg); + return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_channels (dev, get_user ((int *) arg))); case SOUND_PCM_READ_CHANNELS: if (local) @@ -792,8 +792,8 @@ case SNDCTL_DSP_SAMPLESIZE: if (local) - return audio_devs[dev]->d->set_bits (dev, (unsigned int) arg); - return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_bits (dev, get_fs_long ((long *) arg))); + return audio_devs[dev]->d->set_bits (dev, larg); + return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_bits (dev, get_user ((int *) arg))); case SOUND_PCM_READ_BITS: if (local) @@ -827,7 +827,7 @@ case SNDCTL_DSP_SUBDIVIDE: { - int fact = get_fs_long ((long *) arg); + int fact = get_user ((int *) arg); int ret; ret = dma_subdivide (dev, dmap_out, arg, fact); @@ -851,7 +851,7 @@ case SNDCTL_DSP_SETFRAGMENT: { - int fact = get_fs_long ((long *) arg); + int fact = get_user ((int *) arg); int ret; ret = dma_set_fragment (dev, dmap_out, arg, fact); @@ -930,7 +930,7 @@ { unsigned long flags; - int bits = get_fs_long ((long *) arg) & audio_devs[dev]->open_mode; + int bits = get_user ((int *) arg) & audio_devs[dev]->open_mode; int changed; if (audio_devs[dev]->d->trigger == NULL) diff -u --recursive --new-file v2.0.13/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c --- v2.0.13/linux/drivers/sound/gus_wave.c Wed Jul 10 13:11:15 1996 +++ linux/drivers/sound/gus_wave.c Sun Aug 18 10:46:49 1996 @@ -2195,7 +2195,7 @@ case SOUND_PCM_WRITE_RATE: if (local) return gus_audio_set_speed ((int) arg); - return snd_ioctl_return ((int *) arg, gus_audio_set_speed (get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, gus_audio_set_speed (get_user ((int *) arg))); break; case SOUND_PCM_READ_RATE: @@ -2207,13 +2207,13 @@ case SNDCTL_DSP_STEREO: if (local) return gus_audio_set_channels ((int) arg + 1) - 1; - return snd_ioctl_return ((int *) arg, gus_audio_set_channels (get_fs_long ((long *) arg) + 1) - 1); + return snd_ioctl_return ((int *) arg, gus_audio_set_channels (get_user ((int *) arg) + 1) - 1); break; case SOUND_PCM_WRITE_CHANNELS: if (local) return gus_audio_set_channels ((int) arg); - return snd_ioctl_return ((int *) arg, gus_audio_set_channels (get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, gus_audio_set_channels (get_user ((int *) arg))); break; case SOUND_PCM_READ_CHANNELS: @@ -2225,7 +2225,7 @@ case SNDCTL_DSP_SETFMT: if (local) return gus_audio_set_bits ((int) arg); - return snd_ioctl_return ((int *) arg, gus_audio_set_bits (get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, gus_audio_set_bits (get_user ((int *) arg))); break; case SOUND_PCM_READ_BITS: @@ -3046,7 +3046,7 @@ switch (cmd & 0xff) { case SOUND_MIXER_RECSRC: - gus_recmask = get_fs_long ((long *) arg) & MIX_DEVS; + gus_recmask = get_user ((int *) arg) & MIX_DEVS; if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE))) gus_recmask = SOUND_MASK_MIC; /* Note! Input volumes are updated during next open for recording */ @@ -3055,7 +3055,7 @@ case SOUND_MIXER_MIC: { - int vol = get_fs_long ((long *) arg) & 0xff; + int vol = get_user ((int *) arg) & 0xff; if (vol < 0) vol = 0; @@ -3069,7 +3069,7 @@ case SOUND_MIXER_LINE: { - int vol = get_fs_long ((long *) arg) & 0xff; + int vol = get_user ((int *) arg) & 0xff; if (vol < 0) vol = 0; @@ -3082,7 +3082,7 @@ break; case SOUND_MIXER_PCM: - gus_pcm_volume = get_fs_long ((long *) arg) & 0xff; + gus_pcm_volume = get_user ((int *) arg) & 0xff; if (gus_pcm_volume < 0) gus_pcm_volume = 0; if (gus_pcm_volume > 100) @@ -3095,7 +3095,7 @@ { int voice; - gus_wave_volume = get_fs_long ((long *) arg) & 0xff; + gus_wave_volume = get_user ((int *) arg) & 0xff; if (gus_wave_volume < 0) gus_wave_volume = 0; diff -u --recursive --new-file v2.0.13/linux/drivers/sound/ics2101.c linux/drivers/sound/ics2101.c --- v2.0.13/linux/drivers/sound/ics2101.c Sun Jun 30 11:44:01 1996 +++ linux/drivers/sound/ics2101.c Sun Aug 18 10:46:49 1996 @@ -128,23 +128,23 @@ break; case SOUND_MIXER_MIC: - return snd_ioctl_return ((int *) arg, set_volumes (DEV_MIC, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, set_volumes (DEV_MIC, get_user ((int *) arg))); break; case SOUND_MIXER_CD: - return snd_ioctl_return ((int *) arg, set_volumes (DEV_CD, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, set_volumes (DEV_CD, get_user ((int *) arg))); break; case SOUND_MIXER_LINE: - return snd_ioctl_return ((int *) arg, set_volumes (DEV_LINE, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, set_volumes (DEV_LINE, get_user ((int *) arg))); break; case SOUND_MIXER_SYNTH: - return snd_ioctl_return ((int *) arg, set_volumes (DEV_GF1, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, set_volumes (DEV_GF1, get_user ((int *) arg))); break; case SOUND_MIXER_VOLUME: - return snd_ioctl_return ((int *) arg, set_volumes (DEV_VOL, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, set_volumes (DEV_VOL, get_user ((int *) arg))); break; default: diff -u --recursive --new-file v2.0.13/linux/drivers/sound/midibuf.c linux/drivers/sound/midibuf.c --- v2.0.13/linux/drivers/sound/midibuf.c Sun Jun 30 11:44:04 1996 +++ linux/drivers/sound/midibuf.c Sun Aug 18 10:46:49 1996 @@ -473,7 +473,7 @@ { case SNDCTL_MIDI_PRETIME: - val = (int) get_fs_long ((long *) arg); + val = (int) get_user ((int *) arg); if (val < 0) val = 0; diff -u --recursive --new-file v2.0.13/linux/drivers/sound/mpu401.c linux/drivers/sound/mpu401.c --- v2.0.13/linux/drivers/sound/mpu401.c Sat Jul 6 11:31:42 1996 +++ linux/drivers/sound/mpu401.c Sun Aug 18 10:46:49 1996 @@ -790,7 +790,7 @@ printk ("MPU-401: Intelligent mode not supported by the HW\n"); return -(EINVAL); } - set_uart_mode (dev, devc, !get_fs_long ((long *) arg)); + set_uart_mode (dev, devc, !get_user ((int *) arg)); return 0; break; @@ -1590,7 +1590,7 @@ { case SNDCTL_TMR_SOURCE: { - int parm = (int) get_fs_long ((long *) arg) & timer_caps; + int parm = (int) get_user ((int *) arg) & timer_caps; if (parm != 0) { @@ -1628,7 +1628,7 @@ case SNDCTL_TMR_TIMEBASE: { - int val = (int) get_fs_long ((long *) arg); + int val = (int) get_user ((int *) arg); if (val) set_timebase (midi_dev, val); @@ -1639,7 +1639,7 @@ case SNDCTL_TMR_TEMPO: { - int val = (int) get_fs_long ((long *) arg); + int val = (int) get_user ((int *) arg); int ret; if (val) @@ -1662,14 +1662,14 @@ break; case SNDCTL_SEQ_CTRLRATE: - if (get_fs_long ((long *) arg) != 0) /* Can't change */ + if (get_user ((int *) arg) != 0) /* Can't change */ return -(EINVAL); return snd_ioctl_return ((int *) arg, ((curr_tempo * curr_timebase) + 30) / 60); break; case SNDCTL_TMR_METRONOME: - metronome_mode = (int) get_fs_long ((long *) arg); + metronome_mode = (int) get_user ((int *) arg); setup_metronome (midi_dev); return 0; break; diff -u --recursive --new-file v2.0.13/linux/drivers/sound/pas2_mixer.c linux/drivers/sound/pas2_mixer.c --- v2.0.13/linux/drivers/sound/pas2_mixer.c Sat Jul 6 11:31:42 1996 +++ linux/drivers/sound/pas2_mixer.c Sun Aug 18 10:46:49 1996 @@ -218,7 +218,7 @@ if (cmd == SOUND_MIXER_PRIVATE1) /* Set loudness bit */ { - int level = get_fs_long ((long *) arg); + int level = get_user ((int *) arg); if (level == -1) /* Return current settings */ { @@ -240,7 +240,7 @@ if (cmd == SOUND_MIXER_PRIVATE2) /* Set enhance bit */ { - int level = get_fs_long ((long *) arg); + int level = get_user ((int *) arg); if (level == -1) /* Return current settings */ { @@ -269,7 +269,7 @@ if (cmd == SOUND_MIXER_PRIVATE3) /* Set mute bit */ { - int level = get_fs_long ((long *) arg); + int level = get_user ((int *) arg); if (level == -1) /* Return current settings */ { @@ -293,7 +293,7 @@ if (((cmd >> 8) & 0xff) == 'M') { if (_IOC_DIR (cmd) & _IOC_WRITE) - return snd_ioctl_return ((int *) arg, pas_mixer_set (cmd & 0xff, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, pas_mixer_set (cmd & 0xff, get_user ((int *) arg))); else { /* * Read parameters diff -u --recursive --new-file v2.0.13/linux/drivers/sound/pas2_pcm.c linux/drivers/sound/pas2_pcm.c --- v2.0.13/linux/drivers/sound/pas2_pcm.c Mon Jul 8 10:53:14 1996 +++ linux/drivers/sound/pas2_pcm.c Sun Aug 18 10:46:49 1996 @@ -156,7 +156,7 @@ case SOUND_PCM_WRITE_RATE: if (local) return pcm_set_speed ((int) arg); - return snd_ioctl_return ((int *) arg, pcm_set_speed (get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, pcm_set_speed (get_user ((int *) arg))); break; case SOUND_PCM_READ_RATE: @@ -168,13 +168,13 @@ case SNDCTL_DSP_STEREO: if (local) return pcm_set_channels ((int) arg + 1) - 1; - return snd_ioctl_return ((int *) arg, pcm_set_channels (get_fs_long ((long *) arg) + 1) - 1); + return snd_ioctl_return ((int *) arg, pcm_set_channels (get_user ((int *) arg) + 1) - 1); break; case SOUND_PCM_WRITE_CHANNELS: if (local) return pcm_set_channels ((int) arg); - return snd_ioctl_return ((int *) arg, pcm_set_channels (get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, pcm_set_channels (get_user ((int *) arg))); break; case SOUND_PCM_READ_CHANNELS: @@ -186,7 +186,7 @@ case SNDCTL_DSP_SETFMT: if (local) return pcm_set_bits ((int) arg); - return snd_ioctl_return ((int *) arg, pcm_set_bits (get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, pcm_set_bits (get_user ((int *) arg))); break; case SOUND_PCM_READ_BITS: @@ -197,9 +197,9 @@ case SOUND_PCM_WRITE_FILTER: /* * NOT YET IMPLEMENTED */ - if (get_fs_long ((long *) arg) > 1) + if (get_user ((int *) arg) > 1) return -(EINVAL); - pcm_filter = get_fs_long ((long *) arg); + pcm_filter = get_user ((int *) arg); break; case SOUND_PCM_READ_FILTER: diff -u --recursive --new-file v2.0.13/linux/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c --- v2.0.13/linux/drivers/sound/sb_mixer.c Sat Jul 6 11:31:43 1996 +++ linux/drivers/sound/sb_mixer.c Sun Aug 18 10:46:49 1996 @@ -307,12 +307,12 @@ switch (cmd & 0xff) { case SOUND_MIXER_RECSRC: - return snd_ioctl_return ((int *) arg, set_recmask (devc, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, set_recmask (devc, get_user ((int *) arg))); break; default: - return snd_ioctl_return ((int *) arg, sb_mixer_set (devc, cmd & 0xff, get_fs_long ((long *) arg))); + return snd_ioctl_return ((int *) arg, sb_mixer_set (devc, cmd & 0xff, get_user ((int *) arg))); } else switch (cmd & 0xff) diff -u --recursive --new-file v2.0.13/linux/drivers/sound/sequencer.c linux/drivers/sound/sequencer.c --- v2.0.13/linux/drivers/sound/sequencer.c Mon Aug 5 10:13:53 1996 +++ linux/drivers/sound/sequencer.c Sun Aug 18 10:46:49 1996 @@ -1544,7 +1544,7 @@ if (seq_mode != SEQ_2) return -(EINVAL); - pending_timer = get_fs_long ((long *) arg); + pending_timer = get_user ((int *) arg); if (pending_timer < 0 || pending_timer >= num_sound_timers) { @@ -1591,7 +1591,7 @@ */ return -(EIO); - midi_dev = get_fs_long ((long *) arg); + midi_dev = get_user ((int *) arg); if (midi_dev >= max_mididev) return -(ENXIO); @@ -1639,7 +1639,7 @@ if (seq_mode == SEQ_2) return tmr->ioctl (tmr_no, cmd, arg); - if (get_fs_long ((long *) arg) != 0) + if (get_user ((int *) arg) != 0) return -(EINVAL); return snd_ioctl_return ((int *) arg, HZ); @@ -1649,7 +1649,7 @@ { int err; - dev = get_fs_long ((long *) arg); + dev = get_user ((int *) arg); if (dev < 0 || dev >= num_synths) { return -(ENXIO); @@ -1678,7 +1678,7 @@ case SNDCTL_SYNTH_MEMAVL: { - int dev = get_fs_long ((long *) arg); + int dev = get_user ((int *) arg); if (dev < 0 || dev >= num_synths) return -(ENXIO); @@ -1692,7 +1692,7 @@ case SNDCTL_FM_4OP_ENABLE: { - int dev = get_fs_long ((long *) arg); + int dev = get_user ((int *) arg); if (dev < 0 || dev >= num_synths) return -(ENXIO); @@ -1833,7 +1833,7 @@ case SNDCTL_SEQ_THRESHOLD: { - int tmp = get_fs_long ((long *) arg); + int tmp = get_user ((int *) arg); if (dev) /* * Patch manager @@ -1851,7 +1851,7 @@ case SNDCTL_MIDI_PRETIME: { - int val = get_fs_long ((long *) arg); + int val = get_user ((int *) arg); if (val < 0) val = 0; diff -u --recursive --new-file v2.0.13/linux/drivers/sound/sound_timer.c linux/drivers/sound/sound_timer.c --- v2.0.13/linux/drivers/sound/sound_timer.c Sun Jun 30 11:44:18 1996 +++ linux/drivers/sound/sound_timer.c Sun Aug 18 10:46:49 1996 @@ -214,7 +214,7 @@ case SNDCTL_TMR_TIMEBASE: { - int val = get_fs_long ((long *) arg); + int val = get_user ((int *) arg); if (val) { @@ -231,7 +231,7 @@ case SNDCTL_TMR_TEMPO: { - int val = get_fs_long ((long *) arg); + int val = get_user ((int *) arg); if (val) { @@ -251,7 +251,7 @@ break; case SNDCTL_SEQ_CTRLRATE: - if (get_fs_long ((long *) arg) != 0) /* Can't change */ + if (get_user ((int *) arg) != 0) /* Can't change */ return -(EINVAL); return snd_ioctl_return ((int *) arg, ((curr_tempo * curr_timebase) + 30) / 60); diff -u --recursive --new-file v2.0.13/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- v2.0.13/linux/drivers/sound/soundcard.c Sat Aug 10 10:03:15 1996 +++ linux/drivers/sound/soundcard.c Tue Aug 20 13:49:01 1996 @@ -48,7 +48,7 @@ if (value < 0) return value; - put_fs_long (value, (long *) &((addr)[0])); + put_user (value, addr); return 0; } @@ -668,7 +668,7 @@ audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz); - if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL) + if ((start_addr = (char *) __get_dma_pages (GFP_ATOMIC, sz)) == NULL) audio_devs[dev]->buffsize /= 2; } diff -u --recursive --new-file v2.0.13/linux/drivers/sound/sys_timer.c linux/drivers/sound/sys_timer.c --- v2.0.13/linux/drivers/sound/sys_timer.c Sun Jun 30 11:44:21 1996 +++ linux/drivers/sound/sys_timer.c Sun Aug 18 10:46:49 1996 @@ -213,7 +213,7 @@ case SNDCTL_TMR_TIMEBASE: { - int val = get_fs_long ((long *) arg); + int val = get_user ((int *) arg); if (val) { @@ -230,7 +230,7 @@ case SNDCTL_TMR_TEMPO: { - int val = get_fs_long ((long *) arg); + int val = get_user ((int *) arg); if (val) { @@ -249,7 +249,7 @@ break; case SNDCTL_SEQ_CTRLRATE: - if (get_fs_long ((long *) arg) != 0) /* Can't change */ + if (get_user ((int *) arg) != 0) /* Can't change */ return -(EINVAL); return snd_ioctl_return ((int *) arg, ((curr_tempo * curr_timebase) + 30) / 60); diff -u --recursive --new-file v2.0.13/linux/fs/open.c linux/fs/open.c --- v2.0.13/linux/fs/open.c Sun Jul 7 20:27:04 1996 +++ linux/fs/open.c Tue Aug 20 11:59:19 1996 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -602,6 +603,16 @@ #endif +void __fput(struct file *filp, struct inode *inode) +{ + if (filp->f_op && filp->f_op->release) + filp->f_op->release(inode,filp); + filp->f_inode = NULL; + if (filp->f_mode & FMODE_WRITE) + put_write_access(inode); + iput(inode); +} + int close_fp(struct file *filp) { struct inode *inode; @@ -613,17 +624,7 @@ inode = filp->f_inode; if (inode) locks_remove_locks(current, filp); - if (filp->f_count > 1) { - filp->f_count--; - return 0; - } - if (filp->f_op && filp->f_op->release) - filp->f_op->release(inode,filp); - filp->f_count--; - filp->f_inode = NULL; - if (filp->f_mode & FMODE_WRITE) - put_write_access(inode); - iput(inode); + fput(filp, inode); return 0; } diff -u --recursive --new-file v2.0.13/linux/fs/read_write.c linux/fs/read_write.c --- v2.0.13/linux/fs/read_write.c Thu Jun 6 21:22:24 1996 +++ linux/fs/read_write.c Tue Aug 20 11:43:57 1996 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -106,21 +107,33 @@ struct file * file; struct inode * inode; - if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode)) - return -EBADF; + error = -EBADF; + file = fget(fd); + if (!file) + goto bad_file; + inode = file->f_inode; + if (!inode) + goto out; + error = -EBADF; if (!(file->f_mode & 1)) - return -EBADF; + goto out; + error = -EINVAL; if (!file->f_op || !file->f_op->read) - return -EINVAL; + goto out; + error = 0; if (count <= 0) - return 0; + goto out; error = locks_verify_area(FLOCK_VERIFY_READ,inode,file,file->f_pos,count); if (error) - return error; + goto out; error = verify_area(VERIFY_WRITE,buf,count); if (error) - return error; - return file->f_op->read(inode,file,buf,count); + goto out; + error = file->f_op->read(inode,file,buf,count); +out: + fput(file, inode); +bad_file: + return error; } asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count) @@ -128,22 +141,28 @@ int error; struct file * file; struct inode * inode; - int written; - - if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode)) - return -EBADF; + + error = -EBADF; + file = fget(fd); + if (!file) + goto bad_file; + inode = file->f_inode; + if (!inode) + goto out; if (!(file->f_mode & 2)) - return -EBADF; + goto out; + error = -EINVAL; if (!file->f_op || !file->f_op->write) - return -EINVAL; + goto out; + error = 0; if (!count) - return 0; + goto out; error = locks_verify_area(FLOCK_VERIFY_WRITE,inode,file,file->f_pos,count); if (error) - return error; + goto out; error = verify_area(VERIFY_READ,buf,count); if (error) - return error; + goto out; /* * If data has been written to the file, remove the setuid and * the setgid bits. We do it anyway otherwise there is an @@ -164,9 +183,12 @@ } down(&inode->i_sem); - written = file->f_op->write(inode,file,buf,count); + error = file->f_op->write(inode,file,buf,count); up(&inode->i_sem); - return written; +out: + fput(file, inode); +bad_file: + return error; } static int sock_readv_writev(int type, struct inode * inode, struct file * file, diff -u --recursive --new-file v2.0.13/linux/include/asm-alpha/elf.h linux/include/asm-alpha/elf.h --- v2.0.13/linux/include/asm-alpha/elf.h Sat Aug 10 10:03:15 1996 +++ linux/include/asm-alpha/elf.h Sun Aug 18 10:37:57 1996 @@ -5,8 +5,10 @@ * ELF register definitions.. */ -/* - * Note: ELF_NGREG must ben the same as EF_SIZE/8. +/* + * The OSF/1 version of makes gregset_t 46 entries long. + * I have no idea why that is so. For now, we just leave it at 33 + * (32 general regs + processor status word). */ #define ELF_NGREG 33 #define ELF_NFPREG 32 @@ -32,12 +34,6 @@ #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 8192 -#define ELF_CORE_COPY_REGS(_dest,_regs) \ -{ struct user _dump; \ - dump_thread(_regs, &_dump); \ - memcpy((char *) &_dest, (char *) &_dump.regs, \ - sizeof(elf_gregset_t)); } - /* $0 is set by ld.so to a pointer to a function which might be registered using atexit. This provides a mean for the dynamic linker to call DT_FINI functions for shared libraries that have @@ -48,5 +44,51 @@ such function. */ #define ELF_PLAT_INIT(_r) _r->r0 = 0 + +/* Use the same format as the OSF/1 procfs interface. The register + layout is sane. However, since dump_thread() creates the funky + layout that ECOFF coredumps want, we need to undo that layout here. + Eventually, it would be nice if the ECOFF core-dump had to do the + translation, then ELF_CORE_COPY_REGS() would become trivial and + faster. */ +#define ELF_CORE_COPY_REGS(_dest,_regs) \ +{ \ + struct user _dump; \ + \ + dump_thread(_regs, &_dump); \ + _dest[ 0] = _dump.regs[EF_V0]; \ + _dest[ 1] = _dump.regs[EF_T0]; \ + _dest[ 2] = _dump.regs[EF_T1]; \ + _dest[ 3] = _dump.regs[EF_T2]; \ + _dest[ 4] = _dump.regs[EF_T3]; \ + _dest[ 5] = _dump.regs[EF_T4]; \ + _dest[ 6] = _dump.regs[EF_T5]; \ + _dest[ 7] = _dump.regs[EF_T6]; \ + _dest[ 8] = _dump.regs[EF_T7]; \ + _dest[ 9] = _dump.regs[EF_S0]; \ + _dest[10] = _dump.regs[EF_S1]; \ + _dest[11] = _dump.regs[EF_S2]; \ + _dest[12] = _dump.regs[EF_S3]; \ + _dest[13] = _dump.regs[EF_S4]; \ + _dest[14] = _dump.regs[EF_S5]; \ + _dest[15] = _dump.regs[EF_S6]; \ + _dest[16] = _dump.regs[EF_A0]; \ + _dest[17] = _dump.regs[EF_A1]; \ + _dest[18] = _dump.regs[EF_A2]; \ + _dest[19] = _dump.regs[EF_A3]; \ + _dest[20] = _dump.regs[EF_A4]; \ + _dest[21] = _dump.regs[EF_A5]; \ + _dest[22] = _dump.regs[EF_T8]; \ + _dest[23] = _dump.regs[EF_T9]; \ + _dest[24] = _dump.regs[EF_T10]; \ + _dest[25] = _dump.regs[EF_T11]; \ + _dest[26] = _dump.regs[EF_RA]; \ + _dest[27] = _dump.regs[EF_T12]; \ + _dest[28] = _dump.regs[EF_AT]; \ + _dest[29] = _dump.regs[EF_GP]; \ + _dest[30] = _dump.regs[EF_SP]; \ + _dest[31] = _dump.regs[EF_PC]; /* store PC here */ \ + _dest[32] = _dump.regs[EF_PS]; \ +} #endif diff -u --recursive --new-file v2.0.13/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h --- v2.0.13/linux/include/asm-alpha/processor.h Sat Aug 17 21:19:28 1996 +++ linux/include/asm-alpha/processor.h Sun Aug 18 10:37:57 1996 @@ -27,6 +27,7 @@ #define wp_works_ok__is_a_macro /* for versions in ksyms.c */ struct thread_struct { + /* the fields below are used by PALcode and must match struct pcb: */ unsigned long ksp; unsigned long usp; unsigned long ptbr; @@ -34,12 +35,18 @@ unsigned int asn; unsigned long unique; /* - * bit 0.. 0: floating point enable (used by PALcode) - * bit 1.. 5: IEEE_TRAP_ENABLE bits (see fpu.h) + * bit 0: floating point enable + * bit 62: performance monitor enable */ - unsigned long flags; + unsigned long pal_flags; unsigned long res1, res2; - unsigned long segment; + + /* the fields below are Linux-specific: */ + /* + * bit 0: perform syscall argument validation (get/set_fs) + * bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h) + */ + unsigned long flags; }; #define INIT_MMAP { &init_mm, 0xfffffc0000000000, 0xfffffc0010000000, \ @@ -48,7 +55,8 @@ #define INIT_TSS { \ 0, 0, 0, \ 0, 0, 0, \ - 0, 0, 0, KERNEL_DS, \ + 0, 0, 0, \ + 0 \ } #define alloc_kernel_stack() get_free_page(GFP_KERNEL) diff -u --recursive --new-file v2.0.13/linux/include/asm-alpha/segment.h linux/include/asm-alpha/segment.h --- v2.0.13/linux/include/asm-alpha/segment.h Sat Aug 17 21:19:28 1996 +++ linux/include/asm-alpha/segment.h Sun Aug 18 10:37:57 1996 @@ -102,17 +102,18 @@ } /* - * For segmented architectures, these are used to specify which segment - * to use for the above functions. + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. * - * The alpha is not segmented, so these are just dummies. + * For historical reasons, these macros are grossly misnamed. */ -#define KERNEL_DS 0 -#define USER_DS 1 +#define KERNEL_DS 0 +#define USER_DS 1 -#define get_fs() (current->tss.segment) -#define set_fs(x) (current->tss.segment=(x)) +#define get_fs() (current->tss.flags & 0x1) +#define set_fs(x) (current->tss.flags = (current->tss.flags & ~0x1) | ((x) & 0x1)) static inline unsigned long get_ds(void) { diff -u --recursive --new-file v2.0.13/linux/include/asm-alpha/statfs.h linux/include/asm-alpha/statfs.h --- v2.0.13/linux/include/asm-alpha/statfs.h Sat Jun 1 09:33:54 1996 +++ linux/include/asm-alpha/statfs.h Sun Aug 18 10:42:02 1996 @@ -3,29 +3,23 @@ #ifndef __KERNEL_STRICT_NAMES -#include +#include typedef __kernel_fsid_t fsid_t; #endif -/* - * The OSF/1 statfs structure is much larger, but this should - * match the beginning, at least. - */ struct statfs { - short f_type; - short f_flags; - int f_fsize; - int f_bsize; - int f_blocks; - int f_bfree; - int f_bavail; - int f_files; - int f_ffree; + int f_type; + int f_bsize; + int f_blocks; + int f_bfree; + int f_bavail; + int f_files; + int f_ffree; __kernel_fsid_t f_fsid; - /* linux-specific entries start here.. */ - int f_namelen; + int f_namelen; + int f_spare[6]; }; #endif diff -u --recursive --new-file v2.0.13/linux/include/linux/file.h linux/include/linux/file.h --- v2.0.13/linux/include/linux/file.h Thu Jan 1 02:00:00 1970 +++ linux/include/linux/file.h Tue Aug 20 12:14:31 1996 @@ -0,0 +1,25 @@ +#ifndef __LINUX_FILE_H +#define __LINUX_FILE_H + +extern inline struct file * fget(unsigned long fd) +{ + struct file * file = NULL; + if (fd < NR_OPEN) { + file = current->files->fd[fd]; + if (file) + file->f_count++; + } + return file; +} + +extern void __fput(struct file *, struct inode *); + +extern inline void fput(struct file *file, struct inode *inode) +{ + int count = file->f_count-1; + if (!count) + __fput(file, inode); + file->f_count = count; +} + +#endif diff -u --recursive --new-file v2.0.13/linux/include/linux/igmp.h linux/include/linux/igmp.h --- v2.0.13/linux/include/linux/igmp.h Thu Nov 30 11:15:53 1995 +++ linux/include/linux/igmp.h Sat Aug 17 20:28:10 1996 @@ -1,5 +1,5 @@ /* - * Linux NET3: Internet Gateway Management Protocol [IGMP] + * Linux NET3: Internet Group Management Protocol [IGMP] * * Authors: * Alan Cox diff -u --recursive --new-file v2.0.13/linux/include/linux/in.h linux/include/linux/in.h --- v2.0.13/linux/include/linux/in.h Thu Jul 18 14:54:04 1996 +++ linux/include/linux/in.h Sat Aug 17 20:28:10 1996 @@ -24,7 +24,7 @@ enum { IPPROTO_IP = 0, /* Dummy protocol for TCP */ IPPROTO_ICMP = 1, /* Internet Control Message Protocol */ - IPPROTO_IGMP = 2, /* Internet Gateway Management Protocol */ + IPPROTO_IGMP = 2, /* Internet Group Management Protocol */ IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */ IPPROTO_TCP = 6, /* Transmission Control Protocol */ IPPROTO_EGP = 8, /* Exterior Gateway Protocol */ diff -u --recursive --new-file v2.0.13/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.0.13/linux/include/linux/pci.h Sat Aug 17 21:19:28 1996 +++ linux/include/linux/pci.h Sat Aug 17 21:03:34 1996 @@ -521,10 +521,14 @@ #define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 +#define PCI_VENDOR_ID_3DLABS 0x3D3D +#define PCI_DEVICE_ID_3DLABS_300SX 0x0001 + #define PCI_VENDOR_ID_AVANCE 0x4005 #define PCI_DEVICE_ID_AVANCE_2302 0x2302 #define PCI_VENDOR_ID_S3 0x5333 +#define PCI_DEVICE_ID_S3_ViRGE 0x5631 #define PCI_DEVICE_ID_S3_811 0x8811 #define PCI_DEVICE_ID_S3_868 0x8880 #define PCI_DEVICE_ID_S3_928 0x88b0 diff -u --recursive --new-file v2.0.13/linux/include/linux/personality.h linux/include/linux/personality.h --- v2.0.13/linux/include/linux/personality.h Fri Mar 15 15:22:59 1996 +++ linux/include/linux/personality.h Sun Aug 18 09:57:49 1996 @@ -46,6 +46,6 @@ extern struct exec_domain *lookup_exec_domain(unsigned long personality); extern int register_exec_domain(struct exec_domain *it); extern int unregister_exec_domain(struct exec_domain *it); -extern asmlinkage int sys_personality(unsigned long personality); +asmlinkage int sys_personality(unsigned long personality); #endif /* _PERSONALITY_H */ diff -u --recursive --new-file v2.0.13/linux/kernel/sched.c linux/kernel/sched.c --- v2.0.13/linux/kernel/sched.c Mon Aug 5 10:13:54 1996 +++ linux/kernel/sched.c Sun Aug 18 10:37:57 1996 @@ -997,23 +997,11 @@ run_timer_list(); } -/* - * Run the bottom half stuff only about 100 times a second, - * we'd just use up unnecessary CPU time for timer handling - * otherwise - */ -#if HZ > 100 -#define should_run_timers(x) ((x) >= HZ/100) -#else -#define should_run_timers(x) (1) -#endif - void do_timer(struct pt_regs * regs) { (*(unsigned long *)&jiffies)++; lost_ticks++; - if (should_run_timers(lost_ticks)) - mark_bh(TIMER_BH); + mark_bh(TIMER_BH); if (!user_mode(regs)) { lost_ticks_system++; if (prof_buffer && current->pid) { diff -u --recursive --new-file v2.0.13/linux/net/core/sock.c linux/net/core/sock.c --- v2.0.13/linux/net/core/sock.c Mon Aug 5 10:13:55 1996 +++ linux/net/core/sock.c Sat Aug 17 20:28:10 1996 @@ -70,6 +70,7 @@ * Alan Cox : Allow NULL arguments on some SO_ opts * Alan Cox : Generic socket allocation to make hooks * easier (suggested by Craig Metz). + * Michael Pall : SO_ERROR returns positive errno again * * To Fix: * @@ -280,7 +281,7 @@ break; case SO_ERROR: - val = sock_error(sk); + val = -sock_error(sk); if(val==0) val=xchg(&sk->err_soft,0); break; diff -u --recursive --new-file v2.0.13/linux/net/ipv4/igmp.c linux/net/ipv4/igmp.c --- v2.0.13/linux/net/ipv4/igmp.c Thu Aug 1 15:53:34 1996 +++ linux/net/ipv4/igmp.c Sat Aug 17 20:28:10 1996 @@ -1,7 +1,7 @@ /* - * Linux NET3: Internet Gateway Management Protocol [IGMP] + * Linux NET3: Internet Group Management Protocol [IGMP] * - * This code implements the IGMP protocol as defined in RFC1122. There has + * This code implements the IGMP protocol as defined in RFC1112. There has * been a further revision of this protocol since which is now supported. * * If you have trouble with this module be careful what gcc you have used,