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 ...@@ -88,7 +88,7 @@ LD86 =ld86 -0
# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode. # 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. # The number is the same as you would ordinarily press at bootup.
# #
SVGA_MODE= -DSVGA_MODE=1 SVGA_MODE=# -DSVGA_MODE=1
AS =as AS =as
LD =ld LD =ld
...@@ -127,7 +127,7 @@ linuxsubdirs: dummy ...@@ -127,7 +127,7 @@ linuxsubdirs: dummy
Version: Version:
@./makever.sh @./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 UTS_VERSION \"`date +%D`\" >> tools/version.h
@echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h
@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h
......
...@@ -293,12 +293,10 @@ flush: in al,#0x60 ! Flush the keyboard buffer ...@@ -293,12 +293,10 @@ flush: in al,#0x60 ! Flush the keyboard buffer
jb nokey jb nokey
jmp flush jmp flush
nokey: call getkey nokey: call getkey
cmp al,#0x82 cmp al,#0x9c ! enter ?
jb nokey je svga ! yes - svga selection
cmp al,#0xe0 cmp al,#0xb9 ! space ?
ja nokey jne nokey ! no - repeat
cmp al,#0x9c
je svga
#endif #endif
#if !defined(SVGA_MODE) || SVGA_MODE == NORMAL_VGA #if !defined(SVGA_MODE) || SVGA_MODE == NORMAL_VGA
mov ax,#0x5019 mov ax,#0x5019
...@@ -694,7 +692,7 @@ gdt_48: ...@@ -694,7 +692,7 @@ gdt_48:
.word 0x800 ! gdt limit=2048, 256 GDT entries .word 0x800 ! gdt limit=2048, 256 GDT entries
.word 512+gdt,0x9 ! gdt base = 0X9xxxx .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 db 0x0d, 0x0a, 0x0a, 0x00
msg2: .ascii "Mode: COLSxROWS:" msg2: .ascii "Mode: COLSxROWS:"
db 0x0d, 0x0a, 0x0a, 0x00 db 0x0d, 0x0a, 0x0a, 0x00
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/ctype.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <asm/segment.h> #include <asm/segment.h>
...@@ -54,12 +55,32 @@ static struct super_operations msdos_sops = { ...@@ -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; char *this,*value;
*check = 'n'; *check = 'n';
*conversion = 'b'; *conversion = 'b';
*uid = current->uid;
*gid = current->gid;
*umask = current->umask;
if (!options) return 1; if (!options) return 1;
for (this = strtok(options,","); this; this = strtok(NULL,",")) { for (this = strtok(options,","); this; this = strtok(NULL,",")) {
if (value = strchr(this,'=')) *value++ = 0; if (value = strchr(this,'=')) *value++ = 0;
...@@ -79,6 +100,27 @@ static int parse_options(char *options,char *check,char *conversion) ...@@ -79,6 +100,27 @@ static int parse_options(char *options,char *check,char *conversion)
else if (!strcmp(value,"auto")) *conversion = 'a'; else if (!strcmp(value,"auto")) *conversion = 'a';
else return 0; 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; else return 0;
} }
return 1; return 1;
...@@ -93,8 +135,11 @@ struct super_block *msdos_read_super(struct super_block *s,void *data) ...@@ -93,8 +135,11 @@ struct super_block *msdos_read_super(struct super_block *s,void *data)
struct msdos_boot_sector *b; struct msdos_boot_sector *b;
int data_sectors; int data_sectors;
char check,conversion; 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; s->s_dev = 0;
return NULL; return NULL;
} }
...@@ -123,8 +168,8 @@ struct super_block *msdos_read_super(struct super_block *s,void *data) ...@@ -123,8 +168,8 @@ struct super_block *msdos_read_super(struct super_block *s,void *data)
0; 0;
MSDOS_SB(s)->fat_bits = MSDOS_SB(s)->clusters > MSDOS_FAT12 ? 16 : 12; MSDOS_SB(s)->fat_bits = MSDOS_SB(s)->clusters > MSDOS_FAT12 ? 16 : 12;
brelse(bh); brelse(bh);
printk("[MS-DOS FS Rel. alpha.8, FAT %d, check=%c, conv=%c]\n", 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); 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", 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, 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, 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", ...@@ -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; MSDOS_SB(s)->conversion = conversion;
/* set up enough so that it can read an inode */ /* set up enough so that it can read an inode */
s->s_op = &msdos_sops; s->s_op = &msdos_sops;
MSDOS_SB(s)->fs_uid = current->uid; MSDOS_SB(s)->fs_uid = uid;
MSDOS_SB(s)->fs_gid = current->gid; MSDOS_SB(s)->fs_gid = gid;
MSDOS_SB(s)->fs_umask = current->umask; MSDOS_SB(s)->fs_umask = umask;
MSDOS_SB(s)->free_clusters = -1; /* don't know yet */ MSDOS_SB(s)->free_clusters = -1; /* don't know yet */
MSDOS_SB(s)->fat_wait = NULL; MSDOS_SB(s)->fat_wait = NULL;
MSDOS_SB(s)->fat_lock = 0; MSDOS_SB(s)->fat_lock = 0;
......
...@@ -511,11 +511,12 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name, ...@@ -511,11 +511,12 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
MSDOS_I(new_dir)->i_start; MSDOS_I(new_dir)->i_start;
dotdot_inode->i_dirt = 1; dotdot_inode->i_dirt = 1;
dotdot_bh->b_dirt = 1; dotdot_bh->b_dirt = 1;
iput(dotdot_inode);
brelse(dotdot_bh);
old_dir->i_nlink--; old_dir->i_nlink--;
new_dir->i_nlink++; new_dir->i_nlink++;
/* no need to mark them dirty */ /* no need to mark them dirty */
dotdot_inode->i_nlink = new_dir->i_nlink;
iput(dotdot_inode);
brelse(dotdot_bh);
} }
error = 0; error = 0;
rename_done: rename_done:
......
...@@ -126,9 +126,6 @@ static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int ...@@ -126,9 +126,6 @@ static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int
default: default:
return -EINVAL; return -EINVAL;
} }
if (file->f_pos < 0)
return 0;
return file->f_pos;
} }
static struct file_operations proc_mem_operations = { static struct file_operations proc_mem_operations = {
......
...@@ -82,27 +82,19 @@ ...@@ -82,27 +82,19 @@
outb(MS_MSE_ENABLE_INTERRUPTS, MS_MSE_DATA_PORT);} outb(MS_MSE_ENABLE_INTERRUPTS, MS_MSE_DATA_PORT);}
struct mouse_status struct mouse_status {
{
char buttons; char buttons;
char latch_buttons; char latch_buttons;
int dx; int dx;
int dy; int dy;
int present; int present;
int ready; int ready;
int active; int active;
struct wait_queue *wait;
struct inode *inode; };
};
/* Variable Definitions */
extern int mse_busmouse_type; /* to distinguish what type mouse we're working with */
/* Function Prototypes */ /* Function Prototypes */
extern long mouse_init(long); extern long mouse_init(long);
#endif #endif
#if !defined _LINUX_MOUSE_H #ifndef _LINUX_MOUSE_H
#define _LINUX_MOUSE_H #define _LINUX_MOUSE_H
#define BUSMOUSE_MINOR 0 #define BUSMOUSE_MINOR 0
#define PSMOUSE_MINOR 1 #define PSMOUSE_MINOR 1
#define MS_BUSMOUSE_MINOR 2 #define MS_BUSMOUSE_MINOR 2
#define ATIXL_BUSMOUSE_MINOR 3
long mouse_init(long); long mouse_init(long);
......
...@@ -17,21 +17,28 @@ ...@@ -17,21 +17,28 @@
* library, the executable area etc). * library, the executable area etc).
*/ */
struct vm_area_struct { 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; unsigned long vm_end;
struct vm_area_struct * vm_next; /* ordered linked list */ struct vm_area_struct * vm_next; /* ordered linked list */
struct vm_area_struct * vm_share; /* circular linked list */ struct vm_area_struct * vm_share; /* circular linked list */
struct inode * vm_inode; struct inode * vm_inode;
unsigned long vm_offset; unsigned long vm_offset;
struct vm_operations_struct * vm_ops; 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 { struct vm_operations_struct {
void (*open)(struct task_struct * tsk, struct vm_area_struct * area); void (*open)(struct vm_area_struct * area);
void (*close)(struct task_struct * tsk, struct vm_area_struct * area); void (*close)(struct vm_area_struct * area);
void (*nopage)(struct task_struct * tsk, struct vm_area_struct * area, unsigned long address); void (*nopage)(struct vm_area_struct * area, unsigned long address);
void (*wppage)(struct task_struct * tsk, 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 #endif
...@@ -45,6 +45,16 @@ ...@@ -45,6 +45,16 @@
* TODO: Errors are still not counted properly. * 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 REALLY_SLOW_IO
#define FLOPPY_IRQ 6 #define FLOPPY_IRQ 6
...@@ -271,7 +281,7 @@ struct wait_queue * wait_on_floppy_select = NULL; ...@@ -271,7 +281,7 @@ struct wait_queue * wait_on_floppy_select = NULL;
void floppy_deselect(unsigned int nr) void floppy_deselect(unsigned int nr)
{ {
if (nr != (current_DOR & 3)) if (nr != (current_DOR & 3))
printk("floppy_deselect: drive not selected\n\r"); printk("floppy_deselect: drive not selected\n");
selected = 0; selected = 0;
wake_up(&wait_on_floppy_select); wake_up(&wait_on_floppy_select);
} }
...@@ -297,7 +307,7 @@ int floppy_change(struct buffer_head * bh) ...@@ -297,7 +307,7 @@ int floppy_change(struct buffer_head * bh)
unsigned int mask = 1 << (bh->b_dev & 0x03); unsigned int mask = 1 << (bh->b_dev & 0x03);
if (MAJOR(bh->b_dev) != 2) { if (MAJOR(bh->b_dev) != 2) {
printk("floppy_changed: not a floppy\r\n"); printk("floppy_changed: not a floppy\n");
return 0; return 0;
} }
if (fake_change & mask) { if (fake_change & mask) {
...@@ -413,7 +423,7 @@ static void output_byte(char byte) ...@@ -413,7 +423,7 @@ static void output_byte(char byte)
} }
current_track = NO_TRACK; current_track = NO_TRACK;
reset = 1; reset = 1;
printk("Unable to send byte to FDC\n\r"); printk("Unable to send byte to FDC\n");
} }
static int result(void) static int result(void)
...@@ -437,7 +447,7 @@ static int result(void) ...@@ -437,7 +447,7 @@ static int result(void)
} }
reset = 1; reset = 1;
current_track = NO_TRACK; current_track = NO_TRACK;
printk("Getstatus times out\n\r"); printk("Getstatus times out\n");
return -1; return -1;
} }
...@@ -557,7 +567,7 @@ static void rw_interrupt(void) ...@@ -557,7 +567,7 @@ static void rw_interrupt(void)
int drive = MINOR(CURRENT->dev); int drive = MINOR(CURRENT->dev);
if (ftd_msg[drive]) 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); floppy->name,drive);
current_type[drive] = floppy; current_type[drive] = floppy;
floppy_sizes[drive] = floppy->size >> 1; floppy_sizes[drive] = floppy->size >> 1;
...@@ -777,7 +787,7 @@ static void reset_floppy(void) ...@@ -777,7 +787,7 @@ static void reset_floppy(void)
cur_spec1 = -1; cur_spec1 = -1;
cur_rate = -1; cur_rate = -1;
recalibrate = 1; recalibrate = 1;
printk("Reset-floppy called\n\r"); printk("Reset-floppy called\n");
cli(); cli();
outb_p(current_DOR & ~0x04,FD_DOR); outb_p(current_DOR & ~0x04,FD_DOR);
for (i=0 ; i<1000 ; i++) for (i=0 ; i<1000 ; i++)
...@@ -839,7 +849,7 @@ static void floppy_on_interrupt(void) ...@@ -839,7 +849,7 @@ static void floppy_on_interrupt(void)
if (ftd_msg[current_drive] && current_type[ if (ftd_msg[current_drive] && current_type[
current_drive] != NULL) current_drive] != NULL)
printk("Disk type is undefined after disk " 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; current_type[current_drive] = NULL;
floppy_sizes[current_drive] = MAX_DISK_SIZE; floppy_sizes[current_drive] = MAX_DISK_SIZE;
} }
...@@ -878,13 +888,21 @@ static void floppy_on_interrupt(void) ...@@ -878,13 +888,21 @@ static void floppy_on_interrupt(void)
static void setup_format_params(void) static void setup_format_params(void)
{ {
unsigned char *here = (unsigned char *) tmp_floppy_area; 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!! */ /* 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++ = track;
*here++ = head; *here++ = head;
*here++ = count; *here++ = 1 + (( count + total_shift ) % floppy->sect);
*here++ = 2; /* 512 bytes */ *here++ = 2; /* 512 bytes */
} }
} }
...@@ -1136,7 +1154,7 @@ static void config_types(void) ...@@ -1136,7 +1154,7 @@ static void config_types(void)
base_type[1] = find_base(1,CMOS_READ(0x10) & 15); base_type[1] = find_base(1,CMOS_READ(0x10) & 15);
} }
base_type[2] = base_type[3] = NULL; base_type[2] = base_type[3] = NULL;
printk("\r\n"); printk("\n");
} }
/* /*
......
...@@ -289,6 +289,7 @@ static void read_intr(void) ...@@ -289,6 +289,7 @@ static void read_intr(void)
sti(); sti();
return; return;
} }
(void) inb_p(HD_STATUS);
#if (HD_DELAY > 0) #if (HD_DELAY > 0)
last_req = read_timer(); last_req = read_timer();
#endif #endif
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
$(CC) $(CFLAGS) $(DEBUG) -c $< $(CC) $(CFLAGS) $(DEBUG) -c $<
LOWLEVELSSRC = seagate2.s
LOWLEVELCSRC = aha1542.c fdomain.c seagate.c ultrastor.c 7000fasst.c LOWLEVELCSRC = aha1542.c fdomain.c seagate.c ultrastor.c 7000fasst.c
LOWLEVELHSRC = aha1542.h fdomain.h seagate.h ultrastor.h 7000fasst.o 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) ...@@ -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 \ OBJS = scsi.o hosts.o scsi_ioctl.o sd.o sd_ioctl.o st.o st_ioctl.o \
sr.o sr_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 all: scsi.a
...@@ -48,8 +47,6 @@ scsi.a: $(OBJS) ...@@ -48,8 +47,6 @@ scsi.a: $(OBJS)
clean: clean:
rm -f core *.o *.a tmp_make tmp_max figure max_hosts.h rm -f core *.o *.a tmp_make tmp_max figure max_hosts.h
seagate2.o : seagate2.s
seagate.o: seagate.c seagate.o: seagate.c
$(CC) -Wall -c 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 ...@@ -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 mailbox mb[2];
static struct ccb ccb; static struct ccb ccb;
extern int slow_scsi_io;
long WAITtimeout, WAITnexttimeout = 3000000; long WAITtimeout, WAITnexttimeout = 3000000;
void (*do_done)(int, int) = NULL; void (*do_done)(int, int) = NULL;
...@@ -389,7 +391,7 @@ void call_buh() ...@@ -389,7 +391,7 @@ void call_buh()
} }
/* Query the board to find out if it is a 1542 or a 1740, or whatever. */ /* 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_cmd[] = {CMD_INQUIRY };
static unchar inquiry_result[4]; static unchar inquiry_result[4];
...@@ -397,7 +399,6 @@ static void aha1542_query() ...@@ -397,7 +399,6 @@ static void aha1542_query()
i = inb(STATUS); i = inb(STATUS);
if (i & DF) { if (i & DF) {
i = inb(DATA); i = inb(DATA);
printk("Stale data:%x ");
}; };
aha1542_out(inquiry_cmd, 1); aha1542_out(inquiry_cmd, 1);
aha1542_in(inquiry_result, 4); aha1542_in(inquiry_result, 4);
...@@ -406,9 +407,18 @@ static void aha1542_query() ...@@ -406,9 +407,18 @@ static void aha1542_query()
fail: fail:
printk("aha1542_detect: query card type\n"); printk("aha1542_detect: query card type\n");
} }
aha1542_intr_reset(); aha1542_intr_reset();
printk("Inquiry:");
for(i=0;i<4;i++) printk("%x ",inquiry_result[i]); /* 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 */ /* return non-zero on detection */
int aha1542_detect(int hostnum) int aha1542_detect(int hostnum)
...@@ -421,11 +431,16 @@ int aha1542_detect(int hostnum) ...@@ -421,11 +431,16 @@ int aha1542_detect(int hostnum)
return 0; 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 */ /* Set the Bus on/off-times as not to ruin floppy performens */
{ {
static unchar oncmd[] = {CMD_BUSON_TIME, 5}; static unchar oncmd[] = {CMD_BUSON_TIME, 5};
static unchar offcmd[] = {CMD_BUSOFF_TIME, 9}; static unchar offcmd[] = {CMD_BUSOFF_TIME, 9};
aha1542_intr_reset(); aha1542_intr_reset();
aha1542_out(oncmd, 2); aha1542_out(oncmd, 2);
WAIT(INTRFLAGS, INTRMASK, HACC, 0); WAIT(INTRFLAGS, INTRMASK, HACC, 0);
...@@ -438,7 +453,7 @@ int aha1542_detect(int hostnum) ...@@ -438,7 +453,7 @@ int aha1542_detect(int hostnum)
} }
aha1542_intr_reset(); aha1542_intr_reset();
} }
aha1542_query(); aha1542_query(hostnum);
DEB(aha1542_stat()); DEB(aha1542_stat());
setup_mailboxes(); 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; ...@@ -43,6 +43,8 @@ static int this_count, total_count = 0;
static int the_result; static int the_result;
static char sense_buffer[255]; 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); extern int sd_ioctl(struct inode *, struct file *, unsigned long, unsigned long);
...@@ -108,12 +110,14 @@ static void rw_intr (int host, int result) ...@@ -108,12 +110,14 @@ static void rw_intr (int host, int result)
if (!result) { if (!result) {
CURRENT->nr_sectors -= this_count; CURRENT->nr_sectors -= this_count;
total_count -= this_count; if (slow_scsi_io == host) {
if(total_count){ total_count -= this_count;
CURRENT->sector += this_count; if(total_count){
CURRENT->buffer += (this_count << 9); CURRENT->sector += this_count;
do_sd_request(); CURRENT->buffer += (this_count << 9);
return; do_sd_request();
return;
};
}; };
#ifdef DEBUG #ifdef DEBUG
...@@ -255,10 +259,14 @@ static void do_sd_request (void) ...@@ -255,10 +259,14 @@ static void do_sd_request (void)
this_count = CURRENT->nr_sectors; this_count = CURRENT->nr_sectors;
else else
this_count = (BLOCK_SIZE / 512); this_count = (BLOCK_SIZE / 512);
/* This is a temporary hack for the AHA1742. */ /* This is a temporary hack for the AHA1742. */
if(total_count == 0) if(slow_scsi_io == HOST) {
total_count = this_count; if(total_count == 0)
this_count = 1; /* Take only 512 bytes at a time */ total_count = this_count;
this_count = 1; /* Take only 512 bytes at a time */
};
#ifdef DEBUG #ifdef DEBUG
printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(CURRENT->dev), printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(CURRENT->dev),
......
...@@ -11,15 +11,15 @@ ...@@ -11,15 +11,15 @@
#if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_88x) #if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_88x)
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <linux/signal.h>
#include <linux/sched.h> #include <linux/sched.h>
#include "seagate.h" #include "seagate.h"
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
extern void seagate_intr(void);
static int internal_command(unsigned char target, const void *cmnd, static int internal_command(unsigned char target, const void *cmnd,
void *buff, int bufflen, int reselect); void *buff, int bufflen, int reselect);
void (*do_seagate)(void) = NULL;
static int incommand; /* static int incommand; /*
set if arbitration has finished and we are set if arbitration has finished and we are
...@@ -121,12 +121,19 @@ SEAGATE SCSI BIOS REVISION 3.2 ...@@ -121,12 +121,19 @@ SEAGATE SCSI BIOS REVISION 3.2
*/ */
static int hostno = -1; static int hostno = -1;
static void seagate_reconnect_intr(int);
int seagate_st0x_detect (int hostnum) int seagate_st0x_detect (int hostnum)
{ {
#ifndef OVERRIDE #ifndef OVERRIDE
int i,j; int i,j;
#endif #endif
static struct sigaction seagate_sigaction = {
&seagate_reconnect_intr,
0,
SA_INTERRUPT,
NULL
};
/* /*
* First, we try for the manual override. * First, we try for the manual override.
...@@ -170,19 +177,14 @@ int seagate_st0x_detect (int hostnum) ...@@ -170,19 +177,14 @@ int seagate_st0x_detect (int hostnum)
#ifdef DEBUG #ifdef DEBUG
printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr); printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
#endif #endif
hostno = hostnum;
/* /*
* At all times, we will use IRQ 5. * At all times, we will use IRQ 5.
*/ */
hostno = hostnum;
#if 1 if (irqaction(5, &seagate_sigaction)) {
set_intr_gate (0x25, seagate_intr); printk("Unable to allocate IRQ5 for ST0x driver\n");
__asm__(" return 0;
inb $0x21, %%al }
andb $0xdf, %%al
outb %%al, $0x21"::);
#endif
return -1; return -1;
} }
else else
...@@ -212,7 +214,7 @@ static int current_bufflen; ...@@ -212,7 +214,7 @@ static int current_bufflen;
static void (*done_fn)(int, int) = NULL; 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. * or are being attempted.
*/ */
...@@ -226,27 +228,24 @@ static void (*done_fn)(int, int) = NULL; ...@@ -226,27 +228,24 @@ static void (*done_fn)(int, int) = NULL;
static int should_reconnect = 0; 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 * The seagate_reconnect_intr routine is called when a target reselects the
* host adapter. This occurs on the interrupt triggered by the target * host adapter. This occurs on the interrupt triggered by the target
* asserting SEL. * asserting SEL.
*/ */
void seagate_reconnect_intr (void) static void seagate_reconnect_intr (int unused)
{ {
int temp; int temp;
/* enable all other interrupts. */
sti();
#if (DEBUG & PHASE_RESELECT) #if (DEBUG & PHASE_RESELECT)
printk("scsi%d : seagate_reconnect_intr() called\n", hostno); printk("scsi%d : seagate_reconnect_intr() called\n", hostno);
#endif #endif
if (!should_reconnect) if (!should_reconnect)
seagate_unexpected_intr(); printk("scsi%d: unexpected interrupt.\n", hostno);
else else
{ {
should_reconnect = 0; should_reconnect = 0;
...@@ -336,8 +335,6 @@ static int internal_command(unsigned char target, const void *cmnd, ...@@ -336,8 +335,6 @@ static int internal_command(unsigned char target, const void *cmnd,
unsigned char message = 0; unsigned char message = 0;
register unsigned char status_read; register unsigned char status_read;
do_seagate = seagate_unexpected_intr;
len=bufflen; len=bufflen;
data=(unsigned char *) buff; data=(unsigned char *) buff;
...@@ -369,7 +366,6 @@ static int internal_command(unsigned char target, const void *cmnd, ...@@ -369,7 +366,6 @@ static int internal_command(unsigned char target, const void *cmnd,
if (target > 6) if (target > 6)
{ {
if (reselect == RECONNECT_NOW) if (reselect == RECONNECT_NOW)
eoi();
return DID_BAD_TARGET; return DID_BAD_TARGET;
} }
...@@ -403,7 +399,6 @@ static int internal_command(unsigned char target, const void *cmnd, ...@@ -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", printk("scsi%d : RESELECT timed out while waiting for IO .\n",
hostno); hostno);
#endif #endif
eoi();
return (DID_BAD_INTR << 16); return (DID_BAD_INTR << 16);
} }
...@@ -418,7 +413,6 @@ static int internal_command(unsigned char target, const void *cmnd, ...@@ -418,7 +413,6 @@ static int internal_command(unsigned char target, const void *cmnd,
printk("scsi%d : detected reconnect request to different target.\n" printk("scsi%d : detected reconnect request to different target.\n"
"\tData bus = %d\n", hostno, temp); "\tData bus = %d\n", hostno, temp);
#endif #endif
eoi();
return (DID_BAD_INTR << 16); return (DID_BAD_INTR << 16);
} }
...@@ -426,7 +420,6 @@ static int internal_command(unsigned char target, const void *cmnd, ...@@ -426,7 +420,6 @@ static int internal_command(unsigned char target, const void *cmnd,
{ {
printk("scsi%d : Unexpected reselect interrupt. Data bus = %d\n", printk("scsi%d : Unexpected reselect interrupt. Data bus = %d\n",
hostno, temp); hostno, temp);
eoi();
return (DID_BAD_INTR << 16); return (DID_BAD_INTR << 16);
} }
data=current_data; /* WDE add */ data=current_data; /* WDE add */
...@@ -454,7 +447,6 @@ static int internal_command(unsigned char target, const void *cmnd, ...@@ -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", printk("scsi%d : RESELECT timed out while waiting for SEL.\n",
hostno); hostno);
#endif #endif
eoi();
return (DID_BAD_INTR << 16); return (DID_BAD_INTR << 16);
} }
...@@ -464,7 +456,6 @@ static int internal_command(unsigned char target, const void *cmnd, ...@@ -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 * At this point, we have connected with the target and can get
* on with our lives. * on with our lives.
*/ */
eoi();
} }
else else
{ {
...@@ -927,7 +918,6 @@ static int internal_command(unsigned char target, const void *cmnd, ...@@ -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", printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
hostno); hostno);
#endif #endif
do_seagate = seagate_reconnect_intr;
CONTROL = BASE_CMD | CMD_INTR ; CONTROL = BASE_CMD | CMD_INTR ;
} }
else 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 @@ ...@@ -17,7 +17,8 @@
$(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
OBJS = tty_io.o console.o keyboard.o serial.o \ 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) chr_drv.a: $(OBJS)
$(AR) rcs 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 * Logitech Bus Mouse Driver for Linux
* by James Banks * by James Banks
* *
* Heavily modified by David Giller * Heavily modified by David Giller
* changed from queue- to counter- driven * changed from queue- to counter- driven
* hacked out a (probably incorrect) mouse_select * hacked out a (probably incorrect) mouse_select
...@@ -17,40 +17,19 @@ ...@@ -17,40 +17,19 @@
* removed assignment chr_fops[10] = &mouse_fops; see mouse.c * removed assignment chr_fops[10] = &mouse_fops; see mouse.c
* renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public. * renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public.
* renamed this file mouse.c => busmouse.c * 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/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/busmouse.h> #include <linux/busmouse.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
static struct mouse_status mouse; static struct mouse_status mouse;
...@@ -59,111 +38,49 @@ static void mouse_interrupt(int unused) ...@@ -59,111 +38,49 @@ static void mouse_interrupt(int unused)
char dx, dy, buttons; char dx, dy, buttons;
MSE_INT_OFF(); MSE_INT_OFF();
outb(MSE_READ_X_LOW, MSE_CONTROL_PORT); outb(MSE_READ_X_LOW, MSE_CONTROL_PORT);
dx = (inb(MSE_DATA_PORT) & 0xf); dx = (inb(MSE_DATA_PORT) & 0xf);
outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT); outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT);
dx |= (inb(MSE_DATA_PORT) & 0xf) << 4; dx |= (inb(MSE_DATA_PORT) & 0xf) << 4;
outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT ); outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT );
dy = (inb(MSE_DATA_PORT) & 0xf); dy = (inb(MSE_DATA_PORT) & 0xf);
outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT); outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT);
buttons = inb(MSE_DATA_PORT); buttons = inb(MSE_DATA_PORT);
dy |= (buttons & 0xf) << 4; dy |= (buttons & 0xf) << 4;
buttons = ((buttons >> 5) & 0x07); buttons = ((buttons >> 5) & 0x07);
mouse.buttons = buttons; mouse.buttons = buttons;
mouse.latch_buttons |= buttons; mouse.latch_buttons |= buttons;
mouse.dx += dx; mouse.dx += dx;
mouse.dy += dy; mouse.dy += dy;
mouse.ready = 1; mouse.ready = 1;
if (mouse.inode && mouse.inode->i_wait) wake_up(&mouse.wait);
wake_up(&mouse.inode->i_wait);
MSE_INT_ON(); 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) static void release_mouse(struct inode * inode, struct file * file)
{ {
if (mse_busmouse_type == LOGITECH_BUSMOUSE) { MSE_INT_OFF();
MSE_INT_OFF();
} else if (mse_busmouse_type == MICROSOFT_BUSMOUSE) {
MS_MSE_INT_OFF();
} /* else if next mouse type, etc. */
mouse.active = 0; mouse.active = 0;
mouse.ready = 0; mouse.ready = 0;
mouse.inode = NULL;
free_irq(MOUSE_IRQ); free_irq(MOUSE_IRQ);
} }
static int open_mouse(struct inode * inode, struct file * file) static int open_mouse(struct inode * inode, struct file * file)
{ {
if (mouse.active)
return -EBUSY;
if (!mouse.present) if (!mouse.present)
return -EINVAL; return -EINVAL;
if (mouse.active)
return -EBUSY;
mouse.active = 1; mouse.active = 1;
mouse.ready = 0; mouse.ready = 0;
mouse.inode = inode;
mouse.dx = 0; mouse.dx = 0;
mouse.dy = 0; mouse.dy = 0;
mouse.buttons = mouse.latch_buttons = 0x80; mouse.buttons = mouse.latch_buttons = 0x80;
if (request_irq(MOUSE_IRQ, mouse_interrupt)) {
if (mse_busmouse_type == LOGITECH_BUSMOUSE) { mouse.active = 0;
if (request_irq(MOUSE_IRQ, mouse_interrupt)) { return -EBUSY;
/* 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();
} }
MSE_INT_ON();
return 0; return 0;
} }
...@@ -177,47 +94,39 @@ static int read_mouse(struct inode * inode, struct file * file, char * buffer, i ...@@ -177,47 +94,39 @@ static int read_mouse(struct inode * inode, struct file * file, char * buffer, i
{ {
int i; int i;
if (count < 3) return -EINVAL; if (count < 3)
if (!mouse.ready) return -EAGAIN; return -EINVAL;
if (!mouse.ready)
if (mse_busmouse_type == LOGITECH_BUSMOUSE) { return -EAGAIN;
MSE_INT_OFF(); MSE_INT_OFF();
}
put_fs_byte(mouse.latch_buttons | 0x80, buffer); put_fs_byte(mouse.latch_buttons | 0x80, buffer);
if (mouse.dx < -127)
if (mouse.dx < -127) 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); put_fs_byte((char)mouse.dx, buffer + 1);
if (mouse.dy < -127)
if (mouse.dy < -127) 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); put_fs_byte((char) -mouse.dy, buffer + 2);
for (i = 3; i < count; i++) for (i = 3; i < count; i++)
put_fs_byte(0x00, buffer + i); put_fs_byte(0x00, buffer + i);
mouse.dx = 0; mouse.dx = 0;
mouse.dy = 0; mouse.dy = 0;
mouse.latch_buttons = mouse.buttons; mouse.latch_buttons = mouse.buttons;
mouse.ready = 0; mouse.ready = 0;
MSE_INT_ON();
if (mse_busmouse_type == LOGITECH_BUSMOUSE) { return i;
MSE_INT_ON();
}
return i;
} }
static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
{ {
if (sel_type != SEL_IN) if (sel_type != SEL_IN)
return 0; return 0;
if (mouse.ready) if (mouse.ready)
return 1; return 1;
select_wait(&inode->i_wait,wait); select_wait(&mouse.wait, wait);
return 0; return 0;
} }
...@@ -233,22 +142,20 @@ struct file_operations bus_mouse_fops = { ...@@ -233,22 +142,20 @@ struct file_operations bus_mouse_fops = {
}; };
long bus_mouse_init(long kmem_start) long bus_mouse_init(long kmem_start)
{ {
int i; int i;
outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT); outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT); outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
for (i = 0; i < 100000; i++)
for (i = 0; i < 100000; i++); /* busy loop */ /* busy loop */;
if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) { if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
printk("No Logitech bus mouse detected.\n"); printk("No Logitech bus mouse detected.\n");
mouse.present = 0; mouse.present = 0;
return kmem_start; return kmem_start;
} }
outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT); outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
MSE_INT_OFF(); MSE_INT_OFF();
mouse.present = 1; mouse.present = 1;
mouse.active = 0; mouse.active = 0;
mouse.ready = 0; mouse.ready = 0;
...@@ -258,47 +165,3 @@ long bus_mouse_init(long kmem_start) ...@@ -258,47 +165,3 @@ long bus_mouse_init(long kmem_start)
printk("Logitech Bus mouse detected and installed.\n"); printk("Logitech Bus mouse detected and installed.\n");
return kmem_start; 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 @@ ...@@ -17,23 +17,42 @@
extern struct file_operations bus_mouse_fops; extern struct file_operations bus_mouse_fops;
extern struct file_operations psaux_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 bus_mouse_init(long);
extern long psaux_init(long); extern long psaux_init(long);
extern long ms_bus_mouse_init(long); extern long ms_bus_mouse_init(long);
extern long atixl_busmouse_init(long);
int mse_busmouse_type;
static int mouse_open(struct inode * inode, struct file * file) static int mouse_open(struct inode * inode, struct file * file)
{ {
if (MINOR(inode->i_rdev) == BUSMOUSE_MINOR) int minor = MINOR(inode->i_rdev);
file->f_op = &bus_mouse_fops;
else if (MINOR(inode->i_rdev) == PSMOUSE_MINOR) switch (minor) {
file->f_op = &psaux_fops; #ifdef BUSMOUSE_MINOR
else if (MINOR(inode->i_rdev) == MS_BUSMOUSE_MINOR) case BUSMOUSE_MINOR:
file->f_op = &bus_mouse_fops; file->f_op = &bus_mouse_fops;
else break;
return -ENODEV; #endif
mse_busmouse_type = (int) MINOR(inode->i_rdev); #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); return file->f_op->open(inode,file);
} }
...@@ -53,7 +72,7 @@ long mouse_init(long kmem_start) ...@@ -53,7 +72,7 @@ long mouse_init(long kmem_start)
kmem_start = bus_mouse_init(kmem_start); kmem_start = bus_mouse_init(kmem_start);
kmem_start = psaux_init(kmem_start); kmem_start = psaux_init(kmem_start);
kmem_start = ms_bus_mouse_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; chrdev_fops[10] = &mouse_fops;
return kmem_start; 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) ...@@ -197,7 +197,7 @@ int kill_pg(int pgrp, int sig, int priv)
return -EINVAL; return -EINVAL;
for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) for (p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if (*p && (*p)->pgrp == pgrp) { if (*p && (*p)->pgrp == pgrp) {
if (sig && (err = send_sig(sig,*p,priv))) if (err = send_sig(sig,*p,priv))
retval = err; retval = err;
else else
found++; found++;
...@@ -237,7 +237,7 @@ int kill_proc(int pid, int sig, int priv) ...@@ -237,7 +237,7 @@ int kill_proc(int pid, int sig, int priv)
return -EINVAL; return -EINVAL;
for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) for (p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if (*p && (*p)->pid == pid) if (*p && (*p)->pid == pid)
return(sig ? send_sig(sig,*p,priv) : 0); return send_sig(sig,*p,priv);
return(-ESRCH); return(-ESRCH);
} }
......
#define UTS_RELEASE "0.98-21" #define UTS_RELEASE "0.98-22"
#define UTS_VERSION "09/29/92" #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_BY "root"
#define LINUX_COMPILE_HOST "home" #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