Commit 8ac5a423 authored by Linus Torvalds's avatar Linus Torvalds

[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
parent e25f5340
......@@ -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
......
......@@ -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 <RETURN> to see SVGA-modes available or any other key to continue."
msg1: .ascii "Press <RETURN> to see SVGA-modes available or <SPACE> to continue."
db 0x0d, 0x0a, 0x0a, 0x00
msg2: .ascii "Mode: COLSxROWS:"
db 0x0d, 0x0a, 0x0a, 0x00
......
......@@ -9,6 +9,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/stat.h>
#include <asm/segment.h>
......@@ -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;
......
......@@ -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:
......
......@@ -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 = {
......
......@@ -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
#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);
......
......@@ -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
......@@ -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");
}
/*
......
......@@ -289,6 +289,7 @@ static void read_intr(void)
sti();
return;
}
(void) inb_p(HD_STATUS);
#if (HD_DELAY > 0)
last_req = read_timer();
#endif
......
......@@ -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
......
......@@ -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();
......
*** 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),
......@@ -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 @@ static void do_sd_request (void)
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),
......
......@@ -11,15 +11,15 @@
#if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_88x)
#include <asm/io.h>
#include <asm/system.h>
#include <linux/signal.h>
#include <linux/sched.h>
#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
......
/*
* seagate2.S
* low level scsi driver for ST01/ST02 by
* Drew Eckhardt
*
* <drew@colorado.edu>
*/
.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
......@@ -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)
......
/*
* 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 <linux/kernel.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
#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;
}
/*
* 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 <linux/kernel.h>
#include <linux/sched.h>
#include <linux/busmouse.h>
#include <linux/tty.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/busmouse.h>
#include <linux/tty.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
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_val<MS_DELAY;) delay_val++;
mse_byte = inb(MS_MSE_SIGNATURE_PORT);
for (delay_val=0; delay_val<MS_DELAY; ) delay_val++;
for (i = 0; i < 4; i++) {
for (delay_val=0; delay_val<MS_DELAY;) delay_val++;
if (inb(MS_MSE_SIGNATURE_PORT) == 0xde) {
for (delay_val=0; delay_val<MS_DELAY; ) delay_val++;
if (inb(MS_MSE_SIGNATURE_PORT) == mse_byte)
msfound = 0;
else
msfound = 1;
}
else
msfound = 1;
}
}
if (msfound == 1) {
printk("No Microsoft bus mouse detected.\n");
mouse.present = 0;
return kmem_start;
}
MS_MSE_INT_OFF();
mouse.present = 1;
mouse.active = mouse.ready = 0;
mouse.buttons = mouse.latch_buttons = 0x80;
mouse.dx = mouse.dy = 0;
printk("Microsoft Bus mouse detected and installed.\n");
return kmem_start;
}
......@@ -17,23 +17,42 @@
extern struct file_operations bus_mouse_fops;
extern struct file_operations psaux_fops;
extern struct file_operations ms_bus_mouse_fops;
extern struct file_operations atixl_busmouse_fops;
extern long bus_mouse_init(long);
extern long psaux_init(long);
extern long ms_bus_mouse_init(long);
int mse_busmouse_type;
extern long atixl_busmouse_init(long);
static int mouse_open(struct inode * inode, struct file * file)
{
if (MINOR(inode->i_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;
}
/*
* 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 <linux/kernel.h>
#include <linux/sched.h>
#include <linux/busmouse.h>
#include <linux/tty.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
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<MS_DELAY;)
delay_val++;
mse_byte = inb(MS_MSE_SIGNATURE_PORT);
for (delay_val=0; delay_val<MS_DELAY; )
delay_val++;
for (i = 0; i < 4; i++) {
for (delay_val=0; delay_val<MS_DELAY;)
delay_val++;
if (inb(MS_MSE_SIGNATURE_PORT) == 0xde) {
for (delay_val=0; delay_val<MS_DELAY; )
delay_val++;
if (inb(MS_MSE_SIGNATURE_PORT) == mse_byte)
msfound = 0;
else
msfound = 1;
} else
msfound = 1;
}
}
if (msfound == 1) {
printk("No Microsoft bus mouse detected.\n");
return kmem_start;
}
MS_MSE_INT_OFF();
mouse.present = 1;
printk("Microsoft Bus mouse detected and installed.\n");
return kmem_start;
}
......@@ -197,7 +197,7 @@ int kill_pg(int pgrp, int sig, int priv)
return -EINVAL;
for (p = &LAST_TASK ; p > &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);
}
......
#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"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment