From 8ac5a423bc0fb084d3bc51968ed19866a064ceae Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:09:05 -0500 Subject: [PATCH] [PATCH] Linux-0.98.1 (October 5, 1992) Add ATI XL busmouse driver by Bob Harris, split off MS busmouse driver into a driver of its own (rather than a subdriver of the Logitech mouse driver) FAT uid/gid/umask mount options. SCSI driver updates. [Original announcement below] Patch1 to 0.98 mainly corrects some driver problems: it contains the added "inb_p(HD_STATUS)" for hd.c, as well as a changed mouse driver setup (hope it works - I couldn't test it..). There are also some SCSI driver patches: the seagate driver uses irqaction() to get irq's, and the aha1542 driver has the speedup patches. The bootimage should be compiled without the auto-SVGA mode, so people who had problems with linux automatically using a SVGA mode should be ok in this release. Linus --- .version | 1 - Makefile | 4 +- boot/setup.S | 12 +- fs/msdos/inode.c | 59 ++++++++- fs/msdos/namei.c | 5 +- fs/proc/mem.c | 3 - include/linux/busmouse.h | 14 +- include/linux/mouse.h | 3 +- include/linux/vmm.h | 19 ++- kernel/blk_drv/floppy.c | 40 ++++-- kernel/blk_drv/hd.c | 1 + kernel/blk_drv/scsi/Makefile | 5 +- kernel/blk_drv/scsi/aha1542.c | 29 ++++- kernel/blk_drv/scsi/scsi.patch3 | 191 ---------------------------- kernel/blk_drv/scsi/sd.c | 26 ++-- kernel/blk_drv/scsi/seagate.c | 50 +++----- kernel/blk_drv/scsi/seagate2.s | 36 ------ kernel/chr_drv/Makefile | 3 +- kernel/chr_drv/atixlmouse.c | 177 ++++++++++++++++++++++++++ kernel/chr_drv/busmouse.c | 219 ++++++-------------------------- kernel/chr_drv/mouse.c | 43 +++++-- kernel/chr_drv/msbusmouse.c | 190 +++++++++++++++++++++++++++ kernel/exit.c | 4 +- tools/version.h | 4 +- 24 files changed, 615 insertions(+), 523 deletions(-) delete mode 100644 .version delete mode 100644 kernel/blk_drv/scsi/scsi.patch3 delete mode 100644 kernel/blk_drv/scsi/seagate2.s create mode 100644 kernel/chr_drv/atixlmouse.c create mode 100644 kernel/chr_drv/msbusmouse.c diff --git a/.version b/.version deleted file mode 100644 index aabe6ec3909c..000000000000 --- a/.version +++ /dev/null @@ -1 +0,0 @@ -21 diff --git a/Makefile b/Makefile index 3bf497a5a216..357cd041225d 100644 --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ LD86 =ld86 -0 # Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode. # The number is the same as you would ordinarily press at bootup. # -SVGA_MODE= -DSVGA_MODE=1 +SVGA_MODE=# -DSVGA_MODE=1 AS =as LD =ld @@ -127,7 +127,7 @@ linuxsubdirs: dummy Version: @./makever.sh - @echo \#define UTS_RELEASE \"0.98-`cat .version`\" > tools/version.h + @echo \#define UTS_RELEASE \"0.98.pl1-`cat .version`\" > tools/version.h @echo \#define UTS_VERSION \"`date +%D`\" >> tools/version.h @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h diff --git a/boot/setup.S b/boot/setup.S index fde9231387a8..af776d727186 100644 --- a/boot/setup.S +++ b/boot/setup.S @@ -293,12 +293,10 @@ flush: in al,#0x60 ! Flush the keyboard buffer jb nokey jmp flush nokey: call getkey - cmp al,#0x82 - jb nokey - cmp al,#0xe0 - ja nokey - cmp al,#0x9c - je svga + cmp al,#0x9c ! enter ? + je svga ! yes - svga selection + cmp al,#0xb9 ! space ? + jne nokey ! no - repeat #endif #if !defined(SVGA_MODE) || SVGA_MODE == NORMAL_VGA mov ax,#0x5019 @@ -694,7 +692,7 @@ gdt_48: .word 0x800 ! gdt limit=2048, 256 GDT entries .word 512+gdt,0x9 ! gdt base = 0X9xxxx -msg1: .ascii "Press to see SVGA-modes available or any other key to continue." +msg1: .ascii "Press to see SVGA-modes available or to continue." db 0x0d, 0x0a, 0x0a, 0x00 msg2: .ascii "Mode: COLSxROWS:" db 0x0d, 0x0a, 0x0a, 0x00 diff --git a/fs/msdos/inode.c b/fs/msdos/inode.c index fa27ac6564f1..298d9daa0778 100644 --- a/fs/msdos/inode.c +++ b/fs/msdos/inode.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -54,12 +55,32 @@ static struct super_operations msdos_sops = { }; -static int parse_options(char *options,char *check,char *conversion) +static unsigned long simple_strtoul(const char *cp,char **endp) +{ + int base = 10; + unsigned long result = 0; + + if (*cp == '0') { + base = 8; + cp++; + } + while (isdigit(*cp) && (*cp - '0') < base) + result = result*base + *cp++ - '0'; + if (*endp) + *endp = (char *)cp; + return result; +} + + +static int parse_options(char *options,char *check,char *conversion,uid_t *uid, gid_t *gid, int *umask) { char *this,*value; *check = 'n'; *conversion = 'b'; + *uid = current->uid; + *gid = current->gid; + *umask = current->umask; if (!options) return 1; for (this = strtok(options,","); this; this = strtok(NULL,",")) { if (value = strchr(this,'=')) *value++ = 0; @@ -79,6 +100,27 @@ static int parse_options(char *options,char *check,char *conversion) else if (!strcmp(value,"auto")) *conversion = 'a'; else return 0; } + else if (!strcmp(this,"uid")) { + if (!value || !*value) + return 0; + *uid = simple_strtoul(value,&value); + if (*value) + return 0; + } + else if (!strcmp(this,"gid")) { + if (!value || !*value) + return 0; + *gid = simple_strtoul(value,&value); + if (*value) + return 0; + } + else if (!strcmp(this,"umask")) { + if (!value || !*value) + return 0; + *umask = simple_strtoul(value,&value); + if (*value) + return 0; + } else return 0; } return 1; @@ -93,8 +135,11 @@ struct super_block *msdos_read_super(struct super_block *s,void *data) struct msdos_boot_sector *b; int data_sectors; char check,conversion; + uid_t uid; + gid_t gid; + int umask; - if (!parse_options((char *) data,&check,&conversion)) { + if (!parse_options((char *) data,&check,&conversion,&uid,&gid,&umask)) { s->s_dev = 0; return NULL; } @@ -123,8 +168,8 @@ struct super_block *msdos_read_super(struct super_block *s,void *data) 0; MSDOS_SB(s)->fat_bits = MSDOS_SB(s)->clusters > MSDOS_FAT12 ? 16 : 12; brelse(bh); -printk("[MS-DOS FS Rel. alpha.8, FAT %d, check=%c, conv=%c]\n", - MSDOS_SB(s)->fat_bits,check,conversion); +printk("[MS-DOS FS Rel. alpha.8, FAT %d, check=%c, conv=%c, uid=%d, gid=%d, umask=%03o]\n", + MSDOS_SB(s)->fat_bits,check,conversion,uid,gid,umask); printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,se=%d,ts=%d]\n", b->media,MSDOS_SB(s)->cluster_size,MSDOS_SB(s)->fats,MSDOS_SB(s)->fat_start, MSDOS_SB(s)->fat_length,MSDOS_SB(s)->dir_start,MSDOS_SB(s)->dir_entries, @@ -142,9 +187,9 @@ printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,se=%d,ts=%d]\n", MSDOS_SB(s)->conversion = conversion; /* set up enough so that it can read an inode */ s->s_op = &msdos_sops; - MSDOS_SB(s)->fs_uid = current->uid; - MSDOS_SB(s)->fs_gid = current->gid; - MSDOS_SB(s)->fs_umask = current->umask; + MSDOS_SB(s)->fs_uid = uid; + MSDOS_SB(s)->fs_gid = gid; + MSDOS_SB(s)->fs_umask = umask; MSDOS_SB(s)->free_clusters = -1; /* don't know yet */ MSDOS_SB(s)->fat_wait = NULL; MSDOS_SB(s)->fat_lock = 0; diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index 77b0154e80a6..37b4aa338f2f 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -511,11 +511,12 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name, MSDOS_I(new_dir)->i_start; dotdot_inode->i_dirt = 1; dotdot_bh->b_dirt = 1; - iput(dotdot_inode); - brelse(dotdot_bh); old_dir->i_nlink--; new_dir->i_nlink++; /* no need to mark them dirty */ + dotdot_inode->i_nlink = new_dir->i_nlink; + iput(dotdot_inode); + brelse(dotdot_bh); } error = 0; rename_done: diff --git a/fs/proc/mem.c b/fs/proc/mem.c index 4cc5416559cc..f71b83f1134f 100644 --- a/fs/proc/mem.c +++ b/fs/proc/mem.c @@ -126,9 +126,6 @@ static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int default: return -EINVAL; } - if (file->f_pos < 0) - return 0; - return file->f_pos; } static struct file_operations proc_mem_operations = { diff --git a/include/linux/busmouse.h b/include/linux/busmouse.h index fb555c65f94f..2cd45b861ce3 100644 --- a/include/linux/busmouse.h +++ b/include/linux/busmouse.h @@ -82,27 +82,19 @@ outb(MS_MSE_ENABLE_INTERRUPTS, MS_MSE_DATA_PORT);} -struct mouse_status - { +struct mouse_status { char buttons; char latch_buttons; int dx; int dy; - int present; int ready; int active; - - struct inode *inode; - }; - -/* Variable Definitions */ -extern int mse_busmouse_type; /* to distinguish what type mouse we're working with */ - + struct wait_queue *wait; +}; /* Function Prototypes */ extern long mouse_init(long); - #endif diff --git a/include/linux/mouse.h b/include/linux/mouse.h index f50db493ba28..9c5057123b7b 100644 --- a/include/linux/mouse.h +++ b/include/linux/mouse.h @@ -1,9 +1,10 @@ -#if !defined _LINUX_MOUSE_H +#ifndef _LINUX_MOUSE_H #define _LINUX_MOUSE_H #define BUSMOUSE_MINOR 0 #define PSMOUSE_MINOR 1 #define MS_BUSMOUSE_MINOR 2 +#define ATIXL_BUSMOUSE_MINOR 3 long mouse_init(long); diff --git a/include/linux/vmm.h b/include/linux/vmm.h index ad31ddae06f3..0c3de1219560 100644 --- a/include/linux/vmm.h +++ b/include/linux/vmm.h @@ -17,21 +17,28 @@ * library, the executable area etc). */ struct vm_area_struct { - unsigned long vm_start; /* VM area parameters */ + struct task_struct * vm_task; /* VM area parameters */ + unsigned long vm_start; unsigned long vm_end; struct vm_area_struct * vm_next; /* ordered linked list */ struct vm_area_struct * vm_share; /* circular linked list */ struct inode * vm_inode; unsigned long vm_offset; struct vm_operations_struct * vm_ops; - unsigned long vm_flags; }; +/* + * These are the virtual MM functions - opening of an area, closing it (needed to + * keep files on disk up-to-date etc), pointer to the functions called when a + * no-page or a wp-page exception occurs, and the function which decides on sharing + * of pages between different processes. + */ struct vm_operations_struct { - void (*open)(struct task_struct * tsk, struct vm_area_struct * area); - void (*close)(struct task_struct * tsk, struct vm_area_struct * area); - void (*nopage)(struct task_struct * tsk, struct vm_area_struct * area, unsigned long address); - void (*wppage)(struct task_struct * tsk, struct vm_area_struct * area, unsigned long address); + void (*open)(struct vm_area_struct * area); + void (*close)(struct vm_area_struct * area); + void (*nopage)(struct vm_area_struct * area, unsigned long address); + void (*wppage)(struct vm_area_struct * area, unsigned long address); + void (*share)(struct vm_area_struct * old, struct vm_area_struct * new, unsigned long address); }; #endif diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c index da14ab6cebbe..70baaaf5cc4e 100644 --- a/kernel/blk_drv/floppy.c +++ b/kernel/blk_drv/floppy.c @@ -45,6 +45,16 @@ * TODO: Errors are still not counted properly. */ +/* 1992/9/20 + * Modifications for ``Sector Shifting'' by Rob Hooft (hooft@chem.ruu.nl) + * modelled after the freeware MS/DOS program fdformat/88 V1.8 by + * Christoph H. Hochst\"atter. + * I have fixed the shift values to the ones I always use. Maybe a new + * ioctl() should be created to be able to modify them. + * There is a bug in the driver that makes it impossible to format a + * floppy as the first thing after bootup. + */ + #define REALLY_SLOW_IO #define FLOPPY_IRQ 6 @@ -271,7 +281,7 @@ struct wait_queue * wait_on_floppy_select = NULL; void floppy_deselect(unsigned int nr) { if (nr != (current_DOR & 3)) - printk("floppy_deselect: drive not selected\n\r"); + printk("floppy_deselect: drive not selected\n"); selected = 0; wake_up(&wait_on_floppy_select); } @@ -297,7 +307,7 @@ int floppy_change(struct buffer_head * bh) unsigned int mask = 1 << (bh->b_dev & 0x03); if (MAJOR(bh->b_dev) != 2) { - printk("floppy_changed: not a floppy\r\n"); + printk("floppy_changed: not a floppy\n"); return 0; } if (fake_change & mask) { @@ -413,7 +423,7 @@ static void output_byte(char byte) } current_track = NO_TRACK; reset = 1; - printk("Unable to send byte to FDC\n\r"); + printk("Unable to send byte to FDC\n"); } static int result(void) @@ -437,7 +447,7 @@ static int result(void) } reset = 1; current_track = NO_TRACK; - printk("Getstatus times out\n\r"); + printk("Getstatus times out\n"); return -1; } @@ -557,7 +567,7 @@ static void rw_interrupt(void) int drive = MINOR(CURRENT->dev); if (ftd_msg[drive]) - printk("Auto-detected floppy type %s in fd%d\r\n", + printk("Auto-detected floppy type %s in fd%d\n", floppy->name,drive); current_type[drive] = floppy; floppy_sizes[drive] = floppy->size >> 1; @@ -777,7 +787,7 @@ static void reset_floppy(void) cur_spec1 = -1; cur_rate = -1; recalibrate = 1; - printk("Reset-floppy called\n\r"); + printk("Reset-floppy called\n"); cli(); outb_p(current_DOR & ~0x04,FD_DOR); for (i=0 ; i<1000 ; i++) @@ -839,7 +849,7 @@ static void floppy_on_interrupt(void) if (ftd_msg[current_drive] && current_type[ current_drive] != NULL) printk("Disk type is undefined after disk " - "change in fd%d\r\n",current_drive); + "change in fd%d\n",current_drive); current_type[current_drive] = NULL; floppy_sizes[current_drive] = MAX_DISK_SIZE; } @@ -878,13 +888,21 @@ static void floppy_on_interrupt(void) static void setup_format_params(void) { unsigned char *here = (unsigned char *) tmp_floppy_area; - int count; + int count,head_shift,track_shift,total_shift; + + /* allow for about 30ms for data transport per track */ + head_shift = floppy->sect / 6; + /* a ``cylinder'' is two tracks plus a little stepping time */ + track_shift = 2 * head_shift + 1; + /* count backwards */ + total_shift = floppy->sect - + ((track_shift * track + head_shift * head) % floppy->sect); /* XXX: should do a check to see this fits in tmp_floppy_area!! */ - for (count = 1; count <= floppy->sect; count++) { + for (count = 0; count < floppy->sect; count++) { *here++ = track; *here++ = head; - *here++ = count; + *here++ = 1 + (( count + total_shift ) % floppy->sect); *here++ = 2; /* 512 bytes */ } } @@ -1136,7 +1154,7 @@ static void config_types(void) base_type[1] = find_base(1,CMOS_READ(0x10) & 15); } base_type[2] = base_type[3] = NULL; - printk("\r\n"); + printk("\n"); } /* diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c index 39a4fc1923f4..27957fd86333 100644 --- a/kernel/blk_drv/hd.c +++ b/kernel/blk_drv/hd.c @@ -289,6 +289,7 @@ ok_to_read: sti(); return; } + (void) inb_p(HD_STATUS); #if (HD_DELAY > 0) last_req = read_timer(); #endif diff --git a/kernel/blk_drv/scsi/Makefile b/kernel/blk_drv/scsi/Makefile index 2ed72062c2e4..98f96a1b1916 100644 --- a/kernel/blk_drv/scsi/Makefile +++ b/kernel/blk_drv/scsi/Makefile @@ -18,7 +18,6 @@ $(CC) $(CFLAGS) $(DEBUG) -c $< -LOWLEVELSSRC = seagate2.s LOWLEVELCSRC = aha1542.c fdomain.c seagate.c ultrastor.c 7000fasst.c LOWLEVELHSRC = aha1542.h fdomain.h seagate.h ultrastor.h 7000fasst.o @@ -27,7 +26,7 @@ HSRC = hosts.h sd.h st.h sr.h sr_ioctl.h scsi.h scsi_ioctl.h $(LOWLEVELHSRC) OBJS = scsi.o hosts.o scsi_ioctl.o sd.o sd_ioctl.o st.o st_ioctl.o \ sr.o sr_ioctl.o \ - aha1542.o fdomain.o seagate.o seagate2.o ultrastor.o 7000fasst.o + aha1542.o fdomain.o seagate.o ultrastor.o 7000fasst.o all: scsi.a @@ -48,8 +47,6 @@ scsi.a: $(OBJS) clean: rm -f core *.o *.a tmp_make tmp_max figure max_hosts.h -seagate2.o : seagate2.s - seagate.o: seagate.c $(CC) -Wall -c seagate.c diff --git a/kernel/blk_drv/scsi/aha1542.c b/kernel/blk_drv/scsi/aha1542.c index 0646496d60eb..48d8d72109e9 100644 --- a/kernel/blk_drv/scsi/aha1542.c +++ b/kernel/blk_drv/scsi/aha1542.c @@ -32,6 +32,8 @@ static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/aha static struct mailbox mb[2]; static struct ccb ccb; +extern int slow_scsi_io; + long WAITtimeout, WAITnexttimeout = 3000000; void (*do_done)(int, int) = NULL; @@ -389,7 +391,7 @@ void call_buh() } /* Query the board to find out if it is a 1542 or a 1740, or whatever. */ -static void aha1542_query() +static void aha1542_query(int hostnum) { static unchar inquiry_cmd[] = {CMD_INQUIRY }; static unchar inquiry_result[4]; @@ -397,7 +399,6 @@ static void aha1542_query() i = inb(STATUS); if (i & DF) { i = inb(DATA); - printk("Stale data:%x "); }; aha1542_out(inquiry_cmd, 1); aha1542_in(inquiry_result, 4); @@ -406,9 +407,18 @@ static void aha1542_query() fail: printk("aha1542_detect: query card type\n"); } - aha1542_intr_reset(); - printk("Inquiry:"); - for(i=0;i<4;i++) printk("%x ",inquiry_result[i]); + aha1542_intr_reset(); + +/* For an AHA1740 series board, we select slower I/O because there is a + hardware bug which can lead to wrong blocks being returned. The slow + I/O somehow prevents this. Once we have drivers for extended mode + on the aha1740, this will no longer be required. +*/ + + if (inquiry_result[0] == 0x43) { + slow_scsi_io = hostnum; + printk("aha1542.c: Slow SCSI disk I/O selected for AHA 174N hardware.\n"); + }; } /* return non-zero on detection */ int aha1542_detect(int hostnum) @@ -421,11 +431,16 @@ int aha1542_detect(int hostnum) return 0; } +#if MAX_MEGABYTES > 16 + printk("Adaptec 1542 disabled for kernels for which MAX_MEGABYTES > 16.\n"); + return 0; +#endif + /* Set the Bus on/off-times as not to ruin floppy performens */ { static unchar oncmd[] = {CMD_BUSON_TIME, 5}; static unchar offcmd[] = {CMD_BUSOFF_TIME, 9}; - + aha1542_intr_reset(); aha1542_out(oncmd, 2); WAIT(INTRFLAGS, INTRMASK, HACC, 0); @@ -438,7 +453,7 @@ int aha1542_detect(int hostnum) } aha1542_intr_reset(); } - aha1542_query(); + aha1542_query(hostnum); DEB(aha1542_stat()); setup_mailboxes(); diff --git a/kernel/blk_drv/scsi/scsi.patch3 b/kernel/blk_drv/scsi/scsi.patch3 deleted file mode 100644 index ce6d613f82d1..000000000000 --- a/kernel/blk_drv/scsi/scsi.patch3 +++ /dev/null @@ -1,191 +0,0 @@ -*** aha1542.c.~1~ Sat Sep 12 15:29:26 1992 ---- aha1542.c Thu Sep 17 22:11:55 1992 -*************** -*** 72,77 **** ---- 72,90 ---- - return 1; - } - -+ static int aha1542_in(unchar *cmdp, int len) -+ { -+ while (len--) -+ { -+ WAIT(STATUS, DF, DF, 0); -+ *cmdp++ = inb(DATA); -+ } -+ return 0; -+ fail: -+ printk("aha1542_in failed(%d): ", len+1); aha1542_stat(); -+ return 1; -+ } -+ - int makecode(unsigned hosterr, unsigned scsierr) - { - switch (hosterr) { -*************** -*** 259,264 **** ---- 272,278 ---- - int aha1542_queuecommand(unchar target, const void *cmnd, void *buff, int bufflen, void (*done)(int, int)) - { - unchar ahacmd = CMD_START_SCSI; -+ unchar direction; - unchar *cmd = (unchar *) cmnd; - DEB(int i); - -*************** -*** 292,300 **** - - ccb.cdblen = (*cmd<=0x1f)?6:10; /* SCSI Command Descriptor Block Length */ - - memcpy(ccb.cdb, cmd, ccb.cdblen); - ccb.op = 0; /* SCSI Initiator Command */ -! ccb.idlun = (target&7)<<5; /* SCSI Target Id */ - ccb.rsalen = 12; - any2scsi(ccb.datalen, bufflen); - any2scsi(ccb.dataptr, buff); ---- 306,318 ---- - - ccb.cdblen = (*cmd<=0x1f)?6:10; /* SCSI Command Descriptor Block Length */ - - direction = 0; - if (*cmd == READ_10 || *cmd == READ_6) direction = 8; - else if (*cmd == WRITE_10 || *cmd == WRITE_6) direction = 16; - - memcpy(ccb.cdb, cmd, ccb.cdblen); - ccb.op = 0; /* SCSI Initiator Command */ -! ccb.idlun = (target&7)<<5 | direction; /* SCSI Target Id */ - ccb.rsalen = 12; - any2scsi(ccb.datalen, bufflen); - any2scsi(ccb.dataptr, buff); -*************** -*** 369,374 **** ---- 387,416 ---- - set_intr_gate(0x2b,&aha1542_interrupt); - } - -+ -+ /* Query the board to find out if it is a 1542 or a 1740, or whatever. */ -+ static void aha1542_query() -+ { -+ static unchar inquiry_cmd[] = {CMD_INQUIRY }; -+ static unchar inquiry_result[4]; -+ int i; -+ i = inb(STATUS); -+ if (i & DF) { -+ i = inb(DATA); -+ printk("Stale data:%x "); -+ }; -+ aha1542_out(inquiry_cmd, 1); -+ aha1542_in(inquiry_result, 4); -+ WAIT(INTRFLAGS, INTRMASK, HACC, 0); -+ while (0) { -+ fail: -+ printk("aha1542_detect: query card type\n"); -+ } -+ aha1542_intr_reset(); -+ printk("Inquiry:"); -+ for(i=0;i<4;i++) printk("%x ",inquiry_result[i]); -+ } -+ - /* return non-zero on detection */ - int aha1542_detect(int hostnum) - { -*************** -*** 397,402 **** ---- 439,446 ---- - } - aha1542_intr_reset(); - } -+ -+ aha1542_query(); - - DEB(aha1542_stat()); - setup_mailboxes(); -*** scsi.c.~1~ Sat Sep 12 15:29:26 1992 ---- scsi.c Wed Sep 16 01:00:44 1992 -*************** -*** 671,677 **** ---- 671,680 ---- - sti(); - - if (!(last_cmnd[host].flags & WAS_RESET)) -+ { - reset(host); -+ return; -+ } - else - { - exit = (DRIVER_HARD | SUGGEST_ABORT); -*************** -*** 768,773 **** ---- 771,777 ---- - - case RESERVATION_CONFLICT: - reset(host); -+ return; - exit = DRIVER_SOFT | SUGGEST_ABORT; - status = MAYREDO; - break; -*************** -*** 841,848 **** ---- 845,854 ---- - { - if ((last_cmnd[host].retries >= (last_cmnd[host].allowed >> 1)) - && !(last_cmnd[host].flags & WAS_RESET)) -+ { - reset(host); - break; -+ }; - - } - else -*** sd.c.~1~ Sat Sep 12 15:29:26 1992 ---- sd.c Thu Sep 17 23:04:40 1992 -*************** -*** 39,45 **** - int NR_SD=0; - Scsi_Disk rscsi_disks[MAX_SD]; - static int sd_sizes[MAX_SD << 4] = {0, }; -! static int this_count; - static int the_result; - - static char sense_buffer[255]; ---- 39,45 ---- - int NR_SD=0; - Scsi_Disk rscsi_disks[MAX_SD]; - static int sd_sizes[MAX_SD << 4] = {0, }; -! static int this_count, total_count = 0; - static int the_result; - - static char sense_buffer[255]; -*************** -*** 108,113 **** ---- 108,120 ---- - - if (!result) { - CURRENT->nr_sectors -= this_count; -+ total_count -= this_count; -+ if(total_count){ -+ CURRENT->sector += this_count; -+ CURRENT->buffer += (this_count << 9); -+ do_sd_request(); -+ return; -+ }; - - #ifdef DEBUG - printk("sd%d : %d sectors remain.\n", MINOR(CURRENT->dev), CURRENT->nr_sectors); -*************** -*** 248,253 **** ---- 255,266 ---- - this_count = CURRENT->nr_sectors; - else - this_count = (BLOCK_SIZE / 512); -+ -+ -+ /* This is a temporary hack for the AHA1742. */ -+ if(total_count == 0) -+ total_count = this_count; -+ this_count = 1; /* Take only 512 bytes at a time */ - - #ifdef DEBUG - printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(CURRENT->dev), diff --git a/kernel/blk_drv/scsi/sd.c b/kernel/blk_drv/scsi/sd.c index dd3cc985c371..0a47d9c26f99 100644 --- a/kernel/blk_drv/scsi/sd.c +++ b/kernel/blk_drv/scsi/sd.c @@ -43,6 +43,8 @@ static int this_count, total_count = 0; static int the_result; static char sense_buffer[255]; +int slow_scsi_io = -1; /* This is set by aha1542.c, and others, if needed */ + extern int sd_ioctl(struct inode *, struct file *, unsigned long, unsigned long); @@ -108,12 +110,14 @@ static void rw_intr (int host, int result) if (!result) { CURRENT->nr_sectors -= this_count; - total_count -= this_count; - if(total_count){ - CURRENT->sector += this_count; - CURRENT->buffer += (this_count << 9); - do_sd_request(); - return; + if (slow_scsi_io == host) { + total_count -= this_count; + if(total_count){ + CURRENT->sector += this_count; + CURRENT->buffer += (this_count << 9); + do_sd_request(); + return; + }; }; #ifdef DEBUG @@ -255,10 +259,14 @@ repeat: this_count = CURRENT->nr_sectors; else this_count = (BLOCK_SIZE / 512); + + /* This is a temporary hack for the AHA1742. */ - if(total_count == 0) - total_count = this_count; - this_count = 1; /* Take only 512 bytes at a time */ + if(slow_scsi_io == HOST) { + if(total_count == 0) + total_count = this_count; + this_count = 1; /* Take only 512 bytes at a time */ + }; #ifdef DEBUG printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(CURRENT->dev), diff --git a/kernel/blk_drv/scsi/seagate.c b/kernel/blk_drv/scsi/seagate.c index e36dbec15661..aeb04212b60a 100644 --- a/kernel/blk_drv/scsi/seagate.c +++ b/kernel/blk_drv/scsi/seagate.c @@ -11,15 +11,15 @@ #if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_88x) #include #include +#include #include #include "seagate.h" #include "scsi.h" #include "hosts.h" -extern void seagate_intr(void); + static int internal_command(unsigned char target, const void *cmnd, void *buff, int bufflen, int reselect); -void (*do_seagate)(void) = NULL; static int incommand; /* set if arbitration has finished and we are @@ -121,12 +121,19 @@ SEAGATE SCSI BIOS REVISION 3.2 */ static int hostno = -1; +static void seagate_reconnect_intr(int); int seagate_st0x_detect (int hostnum) { #ifndef OVERRIDE int i,j; #endif +static struct sigaction seagate_sigaction = { + &seagate_reconnect_intr, + 0, + SA_INTERRUPT, + NULL +}; /* * First, we try for the manual override. @@ -170,19 +177,14 @@ int seagate_st0x_detect (int hostnum) #ifdef DEBUG printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr); #endif - hostno = hostnum; - /* * At all times, we will use IRQ 5. */ - -#if 1 - set_intr_gate (0x25, seagate_intr); - __asm__(" - inb $0x21, %%al - andb $0xdf, %%al - outb %%al, $0x21"::); -#endif + hostno = hostnum; + if (irqaction(5, &seagate_sigaction)) { + printk("Unable to allocate IRQ5 for ST0x driver\n"); + return 0; + } return -1; } else @@ -212,7 +214,7 @@ static int current_bufflen; static void (*done_fn)(int, int) = NULL; /* - * These control weather or not disconnect / reconnect will be attempted, + * These control whether or not disconnect / reconnect will be attempted, * or are being attempted. */ @@ -226,27 +228,24 @@ static void (*done_fn)(int, int) = NULL; static int should_reconnect = 0; -void seagate_unexpected_intr (void) - { - printk("scsi%d: unexpected interrupt.\n", hostno); - } - /* * The seagate_reconnect_intr routine is called when a target reselects the * host adapter. This occurs on the interrupt triggered by the target * asserting SEL. */ -void seagate_reconnect_intr (void) +static void seagate_reconnect_intr (int unused) { int temp; - + +/* enable all other interrupts. */ + sti(); #if (DEBUG & PHASE_RESELECT) printk("scsi%d : seagate_reconnect_intr() called\n", hostno); #endif if (!should_reconnect) - seagate_unexpected_intr(); + printk("scsi%d: unexpected interrupt.\n", hostno); else { should_reconnect = 0; @@ -336,8 +335,6 @@ static int internal_command(unsigned char target, const void *cmnd, unsigned char message = 0; register unsigned char status_read; - do_seagate = seagate_unexpected_intr; - len=bufflen; data=(unsigned char *) buff; @@ -369,7 +366,6 @@ static int internal_command(unsigned char target, const void *cmnd, if (target > 6) { if (reselect == RECONNECT_NOW) - eoi(); return DID_BAD_TARGET; } @@ -403,7 +399,6 @@ static int internal_command(unsigned char target, const void *cmnd, printk("scsi%d : RESELECT timed out while waiting for IO .\n", hostno); #endif - eoi(); return (DID_BAD_INTR << 16); } @@ -418,7 +413,6 @@ static int internal_command(unsigned char target, const void *cmnd, printk("scsi%d : detected reconnect request to different target.\n" "\tData bus = %d\n", hostno, temp); #endif - eoi(); return (DID_BAD_INTR << 16); } @@ -426,7 +420,6 @@ static int internal_command(unsigned char target, const void *cmnd, { printk("scsi%d : Unexpected reselect interrupt. Data bus = %d\n", hostno, temp); - eoi(); return (DID_BAD_INTR << 16); } data=current_data; /* WDE add */ @@ -454,7 +447,6 @@ static int internal_command(unsigned char target, const void *cmnd, printk("scsi%d : RESELECT timed out while waiting for SEL.\n", hostno); #endif - eoi(); return (DID_BAD_INTR << 16); } @@ -464,7 +456,6 @@ static int internal_command(unsigned char target, const void *cmnd, * At this point, we have connected with the target and can get * on with our lives. */ - eoi(); } else { @@ -927,7 +918,6 @@ static int internal_command(unsigned char target, const void *cmnd, printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n", hostno); #endif - do_seagate = seagate_reconnect_intr; CONTROL = BASE_CMD | CMD_INTR ; } else diff --git a/kernel/blk_drv/scsi/seagate2.s b/kernel/blk_drv/scsi/seagate2.s deleted file mode 100644 index 9b1b6a213d95..000000000000 --- a/kernel/blk_drv/scsi/seagate2.s +++ /dev/null @@ -1,36 +0,0 @@ -/* - * seagate2.S - * low level scsi driver for ST01/ST02 by - * Drew Eckhardt - * - * - */ -.text -.globl _seagate_intr -_seagate_intr: - cld # GCC thing - - pushal - push %ds - push %es - - mov $0x10, %ax # switch to kernel space - mov %ax, %ds - mov %ax, %es - - - - xor %eax, %eax - xchg _do_seagate, %eax - test %eax, %eax - jnz 1f - mov $_seagate_unexpected_intr, %eax -1: call *%eax - - mov $0x20, %al # non-specific EOI - out %al, $0x20 - - pop %es - pop %ds - popal - iret diff --git a/kernel/chr_drv/Makefile b/kernel/chr_drv/Makefile index 740d37750834..9be272f1ea7b 100644 --- a/kernel/chr_drv/Makefile +++ b/kernel/chr_drv/Makefile @@ -17,7 +17,8 @@ $(CC) $(CFLAGS) -c $< OBJS = tty_io.o console.o keyboard.o serial.o \ - tty_ioctl.o pty.o lp.o vt.o mem.o mouse.o busmouse.o psaux.o + tty_ioctl.o pty.o lp.o vt.o mem.o mouse.o \ + busmouse.o psaux.o msbusmouse.o atixlmouse.o chr_drv.a: $(OBJS) $(AR) rcs chr_drv.a $(OBJS) diff --git a/kernel/chr_drv/atixlmouse.c b/kernel/chr_drv/atixlmouse.c new file mode 100644 index 000000000000..085164600307 --- /dev/null +++ b/kernel/chr_drv/atixlmouse.c @@ -0,0 +1,177 @@ +/* + * ATI XL Bus Mouse Driver for Linux + * by Bob Harris (rth@sparta.com) + * + * Uses VFS interface for linux 0.98 (01OCT92) + * + * version 0.3 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define ATIXL_MOUSE_IRQ 5 /* H/W interrupt # set up on ATIXL board */ +#define ATIXL_BUSMOUSE 3 /* Minor device # (mknod c 10 3 /dev/bm) */ + +/* ATI XL Inport Busmouse Definitions */ + +#define ATIXL_MSE_DATA_PORT 0x23d +#define ATIXL_MSE_SIGNATURE_PORT 0x23e +#define ATIXL_MSE_CONTROL_PORT 0x23c + +#define ATIXL_MSE_READ_BUTTONS 0x00 +#define ATIXL_MSE_READ_X 0x01 +#define ATIXL_MSE_READ_Y 0x02 + +/* Some nice ATI XL macros */ + +/* Select IR7, HOLD UPDATES (INT ENABLED), save X,Y */ +#define ATIXL_MSE_DISABLE_UPDATE() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \ + outb( (0x20 | inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); } + +/* Select IR7, Enable updates (INT ENABLED) */ +#define ATIXL_MSE_ENABLE_UPDATE() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \ + outb( (0xdf & inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); } + +/* Select IR7 - Mode Register, NO INTERRUPTS */ +#define ATIXL_MSE_INT_OFF() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \ + outb( (0xe7 & inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); } + +/* Select IR7 - Mode Register, DATA INTERRUPTS ENABLED */ +#define ATIXL_MSE_INT_ON() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \ + outb( (0x08 | inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); } + +/* Same general mouse structure */ + +static struct mouse_status { + char buttons; + char latch_buttons; + int dx; + int dy; + int present; + int ready; + int active; + struct wait_queue *wait; +} mouse; + +void mouse_interrupt(int unused) +{ + ATIXL_MSE_DISABLE_UPDATE(); /* Note that interrupts are still enabled */ + outb(ATIXL_MSE_READ_X, ATIXL_MSE_CONTROL_PORT); /* Select IR1 - X movement */ + mouse.dx += inb( ATIXL_MSE_DATA_PORT); + outb(ATIXL_MSE_READ_Y, ATIXL_MSE_CONTROL_PORT); /* Select IR2 - Y movement */ + mouse.dy += inb( ATIXL_MSE_DATA_PORT); + outb(ATIXL_MSE_READ_BUTTONS, ATIXL_MSE_CONTROL_PORT); /* Select IR0 - Button Status */ + mouse.latch_buttons |= inb( ATIXL_MSE_DATA_PORT); + ATIXL_MSE_ENABLE_UPDATE(); + mouse.ready = 1; + wake_up(&mouse.wait); +} + +static void release_mouse(struct inode * inode, struct file * file) +{ + ATIXL_MSE_INT_OFF(); /* Interrupts are really shut down here */ + mouse.active = 0; + mouse.ready = 0; + free_irq(ATIXL_MOUSE_IRQ); +} + + +static int open_mouse(struct inode * inode, struct file * file) +{ + if (!mouse.present) + return -EINVAL; + if (mouse.active) + return -EBUSY; + mouse.active = 1; + mouse.ready = 0; + mouse.dx = 0; + mouse.dy = 0; + mouse.buttons = mouse.latch_buttons = 0; + if (request_irq(ATIXL_MOUSE_IRQ, mouse_interrupt)) { + mouse.active = 0; + return -EBUSY; + } + ATIXL_MSE_INT_ON(); /* Interrupts are really enabled here */ + return 0; +} + + +static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count) +{ + return -EINVAL; +} + +static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count) +{ + if (count < 3) + return -EINVAL; + if (!mouse.ready) + return -EAGAIN; + ATIXL_MSE_DISABLE_UPDATE(); + /* Allowed interrupts to occur during data gathering - shouldn't hurt */ + put_fs_byte((char)(~mouse.latch_buttons&7) | 0x80 , buffer); + put_fs_byte((char)mouse.dx, buffer + 1); + put_fs_byte((char)-mouse.dy, buffer + 2); + mouse.dx = 0; + mouse.dy = 0; + mouse.latch_buttons = mouse.buttons; + mouse.ready = 0; + ATIXL_MSE_ENABLE_UPDATE(); + return 3; /* 3 data bytes returned */ +} + +static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) +{ + if (sel_type != SEL_IN) + return 0; + if (mouse.ready) + return 1; + select_wait(&mouse.wait,wait); + return 0; +} + +struct file_operations atixl_busmouse_fops = { + NULL, /* mouse_seek */ + read_mouse, + write_mouse, + NULL, /* mouse_readdir */ + mouse_select, /* mouse_select */ + NULL, /* mouse_ioctl */ + open_mouse, + release_mouse, +}; + +long atixl_busmouse_init(long kmem_start) +{ + unsigned char a,b,c; + + a = inb( ATIXL_MSE_SIGNATURE_PORT ); /* Get signature */ + b = inb( ATIXL_MSE_SIGNATURE_PORT ); + c = inb( ATIXL_MSE_SIGNATURE_PORT ); + if (( a != b ) && ( a == c )) + printk("\nATI Inport "); + else{ + printk("No ATI bus mouse detected\n"); + mouse.present = 0; + return kmem_start; + } + outb(0x80, ATIXL_MSE_CONTROL_PORT); /* Reset the Inport device */ + outb(0x07, ATIXL_MSE_CONTROL_PORT); /* Select Internal Register 7 */ + outb(0x0a, ATIXL_MSE_DATA_PORT); /* Data Interrupts 8+, 1=30hz, 2=50hz, 3=100hz, 4=200hz rate */ + mouse.present = 1; + mouse.active = 0; + mouse.ready = 0; + mouse.buttons = mouse.latch_buttons = 0; + mouse.dx = mouse.dy = 0; + printk("Bus mouse detected and installed.\n"); + return kmem_start; +} diff --git a/kernel/chr_drv/busmouse.c b/kernel/chr_drv/busmouse.c index 5b51d7107c21..95126f64caf2 100644 --- a/kernel/chr_drv/busmouse.c +++ b/kernel/chr_drv/busmouse.c @@ -1,7 +1,7 @@ /* * Logitech Bus Mouse Driver for Linux * by James Banks - * + * * Heavily modified by David Giller * changed from queue- to counter- driven * hacked out a (probably incorrect) mouse_select @@ -17,40 +17,19 @@ * removed assignment chr_fops[10] = &mouse_fops; see mouse.c * renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public. * renamed this file mouse.c => busmouse.c - * - * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92) - * - * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net) - * 8/28/92 - * - * Microsoft Bus Mouse support folded into 0.97pl4 code - * by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92) - * Changes: Logitech and Microsoft support in the same kernel. - * Defined new constants in busmouse.h for MS mice. - * Added int mse_busmouse_type to distinguish busmouse types - * Added a couple of new functions to handle differences in using - * MS vs. Logitech (where the int variable wasn't appropriate). - * - * Modified by Peter Cervasio (address above) (26SEP92) - * Changes: Included code to (properly?) detect when a Microsoft mouse is - * really attached to the machine. Don't know what this does to - * Logitech bus mice, but all it does is read ports. - * - * version 0.3 */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include static struct mouse_status mouse; @@ -59,111 +38,49 @@ static void mouse_interrupt(int unused) char dx, dy, buttons; MSE_INT_OFF(); - outb(MSE_READ_X_LOW, MSE_CONTROL_PORT); dx = (inb(MSE_DATA_PORT) & 0xf); - outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT); dx |= (inb(MSE_DATA_PORT) & 0xf) << 4; - outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT ); dy = (inb(MSE_DATA_PORT) & 0xf); - outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT); buttons = inb(MSE_DATA_PORT); - dy |= (buttons & 0xf) << 4; buttons = ((buttons >> 5) & 0x07); - mouse.buttons = buttons; mouse.latch_buttons |= buttons; mouse.dx += dx; mouse.dy += dy; mouse.ready = 1; - if (mouse.inode && mouse.inode->i_wait) - wake_up(&mouse.inode->i_wait); - + wake_up(&mouse.wait); MSE_INT_ON(); - -} - -/* Use separate function for MS mice - keep both short & fast */ -static void ms_mouse_interrupt(int unused) -{ - char dx, dy, buttons; - - outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT); - outb((inb(MS_MSE_DATA_PORT) | 0x20), MS_MSE_DATA_PORT); - - outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT); - dx = inb(MS_MSE_DATA_PORT); - - outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT); - dy = inb(MS_MSE_DATA_PORT); - - outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT); - buttons = ~(inb(MS_MSE_DATA_PORT)) & 0x07; - - outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT); - outb((inb(MS_MSE_DATA_PORT) & 0xdf), MS_MSE_DATA_PORT); - - mouse.buttons = buttons; - mouse.latch_buttons |= buttons; - mouse.dx += dx; - mouse.dy += dy; - mouse.ready = 1; - if (mouse.inode && mouse.inode->i_wait) - wake_up(&mouse.inode->i_wait); - } static void release_mouse(struct inode * inode, struct file * file) { - if (mse_busmouse_type == LOGITECH_BUSMOUSE) { - MSE_INT_OFF(); - } else if (mse_busmouse_type == MICROSOFT_BUSMOUSE) { - MS_MSE_INT_OFF(); - } /* else if next mouse type, etc. */ - + MSE_INT_OFF(); mouse.active = 0; - mouse.ready = 0; - mouse.inode = NULL; + mouse.ready = 0; free_irq(MOUSE_IRQ); } static int open_mouse(struct inode * inode, struct file * file) { - if (mouse.active) - return -EBUSY; if (!mouse.present) return -EINVAL; + if (mouse.active) + return -EBUSY; mouse.active = 1; mouse.ready = 0; - mouse.inode = inode; mouse.dx = 0; - mouse.dy = 0; + mouse.dy = 0; mouse.buttons = mouse.latch_buttons = 0x80; - - if (mse_busmouse_type == LOGITECH_BUSMOUSE) { - if (request_irq(MOUSE_IRQ, mouse_interrupt)) { - /* once we get to here mouse is unused, IRQ is busy */ - mouse.active = 0; /* it's not active, fix it */ - return -EBUSY; /* IRQ is busy, so we're BUSY */ - } /* if we can't get the IRQ and mouse not active */ - MSE_INT_ON(); - - } else if (mse_busmouse_type == MICROSOFT_BUSMOUSE) { - - if (request_irq(MOUSE_IRQ, ms_mouse_interrupt)) { - /* once we get to here mouse is unused, IRQ is busy */ - mouse.active = 0; /* it's not active, fix it */ - return -EBUSY; /* IRQ is busy, so we're BUSY */ - } /* if we can't get the IRQ and mouse not active */ - outb(MS_MSE_START, MS_MSE_CONTROL_PORT); - MS_MSE_INT_ON(); - + if (request_irq(MOUSE_IRQ, mouse_interrupt)) { + mouse.active = 0; + return -EBUSY; } - + MSE_INT_ON(); return 0; } @@ -177,47 +94,39 @@ static int read_mouse(struct inode * inode, struct file * file, char * buffer, i { int i; - if (count < 3) return -EINVAL; - if (!mouse.ready) return -EAGAIN; - - if (mse_busmouse_type == LOGITECH_BUSMOUSE) { - MSE_INT_OFF(); - } - + if (count < 3) + return -EINVAL; + if (!mouse.ready) + return -EAGAIN; + MSE_INT_OFF(); put_fs_byte(mouse.latch_buttons | 0x80, buffer); - - if (mouse.dx < -127) mouse.dx = -127; - if (mouse.dx > 127) mouse.dx = 127; - + if (mouse.dx < -127) + mouse.dx = -127; + if (mouse.dx > 127) + mouse.dx = 127; put_fs_byte((char)mouse.dx, buffer + 1); - - if (mouse.dy < -127) mouse.dy = -127; - if (mouse.dy > 127) mouse.dy = 127; - + if (mouse.dy < -127) + mouse.dy = -127; + if (mouse.dy > 127) + mouse.dy = 127; put_fs_byte((char) -mouse.dy, buffer + 2); - for (i = 3; i < count; i++) put_fs_byte(0x00, buffer + i); - mouse.dx = 0; mouse.dy = 0; mouse.latch_buttons = mouse.buttons; mouse.ready = 0; - - if (mse_busmouse_type == LOGITECH_BUSMOUSE) { - MSE_INT_ON(); - } - - return i; + MSE_INT_ON(); + return i; } static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) { if (sel_type != SEL_IN) return 0; - if (mouse.ready) + if (mouse.ready) return 1; - select_wait(&inode->i_wait,wait); + select_wait(&mouse.wait, wait); return 0; } @@ -233,22 +142,20 @@ struct file_operations bus_mouse_fops = { }; long bus_mouse_init(long kmem_start) -{ +{ int i; outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT); outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT); - - for (i = 0; i < 100000; i++); /* busy loop */ + for (i = 0; i < 100000; i++) + /* busy loop */; if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) { printk("No Logitech bus mouse detected.\n"); mouse.present = 0; return kmem_start; } outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT); - MSE_INT_OFF(); - mouse.present = 1; mouse.active = 0; mouse.ready = 0; @@ -258,47 +165,3 @@ long bus_mouse_init(long kmem_start) printk("Logitech Bus mouse detected and installed.\n"); return kmem_start; } - -#define MS_DELAY 100000 - -long ms_bus_mouse_init(long kmem_start) -{ - register int mse_byte; - int i, delay_val, msfound = 1; - - if (inb(MS_MSE_SIGNATURE_PORT) == 0xde) { - for (delay_val=0; delay_vali_rdev) == BUSMOUSE_MINOR) - file->f_op = &bus_mouse_fops; - else if (MINOR(inode->i_rdev) == PSMOUSE_MINOR) - file->f_op = &psaux_fops; - else if (MINOR(inode->i_rdev) == MS_BUSMOUSE_MINOR) - file->f_op = &bus_mouse_fops; - else - return -ENODEV; - mse_busmouse_type = (int) MINOR(inode->i_rdev); + int minor = MINOR(inode->i_rdev); + + switch (minor) { +#ifdef BUSMOUSE_MINOR + case BUSMOUSE_MINOR: + file->f_op = &bus_mouse_fops; + break; +#endif +#ifdef PSMOUSE_MINOR + case PSMOUSE_MINOR: + file->f_op = &psaux_fops; + break; +#endif +#ifdef MS_BUSMOUSE_MINOR + case MS_BUSMOUSE_MINOR: + file->f_op = &ms_bus_mouse_fops; + break; +#endif +#ifdef ATIXL_BUSMOUSE_MINOR + case ATIXL_BUSMOUSE_MINOR: + file->f_op = &atixl_busmouse_fops; + break; +#endif + default: + return -ENODEV; + } return file->f_op->open(inode,file); } @@ -53,7 +72,7 @@ long mouse_init(long kmem_start) kmem_start = bus_mouse_init(kmem_start); kmem_start = psaux_init(kmem_start); kmem_start = ms_bus_mouse_init(kmem_start); - mse_busmouse_type = -1; + kmem_start = atixl_busmouse_init(kmem_start); chrdev_fops[10] = &mouse_fops; return kmem_start; } diff --git a/kernel/chr_drv/msbusmouse.c b/kernel/chr_drv/msbusmouse.c new file mode 100644 index 000000000000..f5a4b138bbd2 --- /dev/null +++ b/kernel/chr_drv/msbusmouse.c @@ -0,0 +1,190 @@ +/* + * Microsoft busmouse driver based on Logitech driver (see busmouse.c) + * + * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92) + * + * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net) + * 8/28/92 + * + * Microsoft Bus Mouse support folded into 0.97pl4 code + * by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92) + * Changes: Logitech and Microsoft support in the same kernel. + * Defined new constants in busmouse.h for MS mice. + * Added int mse_busmouse_type to distinguish busmouse types + * Added a couple of new functions to handle differences in using + * MS vs. Logitech (where the int variable wasn't appropriate). + * + * Modified by Peter Cervasio (address above) (26SEP92) + * Changes: Included code to (properly?) detect when a Microsoft mouse is + * really attached to the machine. Don't know what this does to + * Logitech bus mice, but all it does is read ports. + * + * version 0.3 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static struct mouse_status mouse; + +static void ms_mouse_interrupt(int unused) +{ + char dx, dy, buttons; + + outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT); + outb((inb(MS_MSE_DATA_PORT) | 0x20), MS_MSE_DATA_PORT); + + outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT); + dx = inb(MS_MSE_DATA_PORT); + + outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT); + dy = inb(MS_MSE_DATA_PORT); + + outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT); + buttons = ~(inb(MS_MSE_DATA_PORT)) & 0x07; + + outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT); + outb((inb(MS_MSE_DATA_PORT) & 0xdf), MS_MSE_DATA_PORT); + + mouse.buttons = buttons; + mouse.latch_buttons |= buttons; + mouse.dx += dx; + mouse.dy += dy; + mouse.ready = 1; + wake_up(&mouse.wait); +} + +static void release_mouse(struct inode * inode, struct file * file) +{ + MS_MSE_INT_OFF(); + mouse.active = 0; + mouse.ready = 0; + free_irq(MOUSE_IRQ); +} + +static int open_mouse(struct inode * inode, struct file * file) +{ + if (!mouse.present) + return -EINVAL; + if (mouse.active) + return -EBUSY; + mouse.active = 1; + mouse.ready = 0; + mouse.dx = 0; + mouse.dy = 0; + mouse.buttons = mouse.latch_buttons = 0x80; + if (request_irq(MOUSE_IRQ, ms_mouse_interrupt)) { + mouse.active = 0; + return -EBUSY; + } + outb(MS_MSE_START, MS_MSE_CONTROL_PORT); + MS_MSE_INT_ON(); + return 0; +} + + +static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count) +{ + return -EINVAL; +} + +static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count) +{ + int i; + + if (count < 3) + return -EINVAL; + if (!mouse.ready) + return -EAGAIN; + put_fs_byte(mouse.latch_buttons | 0x80, buffer); + if (mouse.dx < -127) + mouse.dx = -127; + if (mouse.dx > 127) + mouse.dx = 127; + put_fs_byte((char)mouse.dx, buffer + 1); + if (mouse.dy < -127) + mouse.dy = -127; + if (mouse.dy > 127) + mouse.dy = 127; + put_fs_byte((char) -mouse.dy, buffer + 2); + for (i = 3; i < count; i++) + put_fs_byte(0x00, buffer + i); + mouse.dx = 0; + mouse.dy = 0; + mouse.latch_buttons = mouse.buttons; + mouse.ready = 0; + return i; +} + +static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) +{ + if (sel_type != SEL_IN) + return 0; + if (mouse.ready) + return 1; + select_wait(&mouse.wait,wait); + return 0; +} + +struct file_operations ms_bus_mouse_fops = { + NULL, /* mouse_seek */ + read_mouse, + write_mouse, + NULL, /* mouse_readdir */ + mouse_select, /* mouse_select */ + NULL, /* mouse_ioctl */ + open_mouse, + release_mouse, +}; + +#define MS_DELAY 100000 + +long ms_bus_mouse_init(long kmem_start) +{ + register int mse_byte; + int i, delay_val, msfound = 1; + + mouse.present = 0; + mouse.active = mouse.ready = 0; + mouse.buttons = mouse.latch_buttons = 0x80; + mouse.dx = mouse.dy = 0; + if (inb(MS_MSE_SIGNATURE_PORT) == 0xde) { + for (delay_val=0; delay_val &FIRST_TASK ; --p) if (*p && (*p)->pgrp == pgrp) { - if (sig && (err = send_sig(sig,*p,priv))) + if (err = send_sig(sig,*p,priv)) retval = err; else found++; @@ -237,7 +237,7 @@ int kill_proc(int pid, int sig, int priv) return -EINVAL; for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) if (*p && (*p)->pid == pid) - return(sig ? send_sig(sig,*p,priv) : 0); + return send_sig(sig,*p,priv); return(-ESRCH); } diff --git a/tools/version.h b/tools/version.h index 97a80566df29..80bdb0949426 100644 --- a/tools/version.h +++ b/tools/version.h @@ -1,5 +1,5 @@ -#define UTS_RELEASE "0.98-21" +#define UTS_RELEASE "0.98-22" #define UTS_VERSION "09/29/92" -#define LINUX_COMPILE_TIME "20:36:17" +#define LINUX_COMPILE_TIME "21:12:04" #define LINUX_COMPILE_BY "root" #define LINUX_COMPILE_HOST "home" -- 2.39.5