Commit 40820e9a authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.90

parent 004b42c6
...@@ -719,8 +719,8 @@ D: Dosemu ...@@ -719,8 +719,8 @@ D: Dosemu
N: Hannu Savolainen N: Hannu Savolainen
E: hannu@voxware.pp.fi E: hannu@voxware.pp.fi
D: Kernel sound drivers D: Kernel sound drivers
S: Pallaksentie 4 A 2 S: Hiekkalaiturintie 3 A 8
S: 00970 Helsinki S: 00980 Helsinki
S: Finland S: Finland
N: Peter De Schrijver N: Peter De Schrijver
......
VERSION = 1 VERSION = 1
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 89 SUBLEVEL = 90
ARCH = i386 ARCH = i386
...@@ -217,7 +217,7 @@ modules_install: ...@@ -217,7 +217,7 @@ modules_install:
\ \
ls *.o > .allmods; \ ls *.o > .allmods; \
echo $$MODULES | tr ' ' '\n' | sort | comm -23 .allmods - > .misc; \ echo $$MODULES | tr ' ' '\n' | sort | comm -23 .allmods - > .misc; \
inst_mod .misc misc; \ if [ -s .misc ]; then inst_mod .misc misc; fi; \
rm -f .misc .allmods; \ rm -f .misc .allmods; \
) )
......
...@@ -210,7 +210,7 @@ bool '/proc filesystem support' CONFIG_PROC_FS y ...@@ -210,7 +210,7 @@ bool '/proc filesystem support' CONFIG_PROC_FS y
if [ "$CONFIG_INET" = "y" ]; then if [ "$CONFIG_INET" = "y" ]; then
bool 'NFS filesystem support' CONFIG_NFS_FS y bool 'NFS filesystem support' CONFIG_NFS_FS y
fi fi
if [ "$CONFIG_BLK_DEV_SR" = "y" -o "$CONFIG_CDU31A" = "y" -o "$CONFIG_MCD" = "y" -o "$CONFIG_SBPCD" = "y" -o "$CONFIG_BLK_DEV_IDECD" = "y" ]; then if [ "$CONFIG_BLK_DEV_SR" = "y" -o "$CONFIG_CDU31A" = "y" -o "$CONFIG_MCD" = "y" -o "$CONFIG_SBPCD" = "y" -o "$CONFIG_BLK_DEV_IDECD" = "y" -o "$CONFIG_AZTCD" = "y" ]; then
bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y
else else
bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS n bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS n
......
...@@ -66,6 +66,7 @@ static int write_ldt(void * ptr, unsigned long bytecount) ...@@ -66,6 +66,7 @@ static int write_ldt(void * ptr, unsigned long bytecount)
if (task[i] == current) { if (task[i] == current) {
if (!(current->ldt = (struct desc_struct*) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE))) if (!(current->ldt = (struct desc_struct*) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE)))
return -ENOMEM; return -ENOMEM;
memset(current->ldt, 0, LDT_ENTRIES*LDT_ENTRY_SIZE);
set_ldt_desc(gdt+(i<<1)+FIRST_LDT_ENTRY, current->ldt, LDT_ENTRIES); set_ldt_desc(gdt+(i<<1)+FIRST_LDT_ENTRY, current->ldt, LDT_ENTRIES);
load_ldt(i); load_ldt(i);
} }
......
...@@ -254,6 +254,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs) ...@@ -254,6 +254,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
} }
regs->esp = (unsigned long) frame; regs->esp = (unsigned long) frame;
regs->eip = eip; /* "return" to the first handler */ regs->eip = eip; /* "return" to the first handler */
regs->eflags &= ~TF_MASK;
current->tss.trap_no = current->tss.error_code = 0; current->tss.trap_no = current->tss.error_code = 0;
return 1; return 1;
} }
...@@ -178,23 +178,14 @@ DO_ERROR(17, SIGSEGV, "alignment check", alignment_check, current) ...@@ -178,23 +178,14 @@ DO_ERROR(17, SIGSEGV, "alignment check", alignment_check, current)
asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
{ {
int signr = SIGSEGV;
if (regs->eflags & VM_MASK) { if (regs->eflags & VM_MASK) {
handle_vm86_fault((struct vm86_regs *) regs, error_code); handle_vm86_fault((struct vm86_regs *) regs, error_code);
return; return;
} }
die_if_kernel("general protection",regs,error_code); die_if_kernel("general protection",regs,error_code);
switch (get_seg_byte(regs->cs, (char *)regs->eip)) {
case 0xCD: /* INT */
case 0xF4: /* HLT */
case 0xFA: /* CLI */
case 0xFB: /* STI */
signr = SIGILL;
}
current->tss.error_code = error_code; current->tss.error_code = error_code;
current->tss.trap_no = 13; current->tss.trap_no = 13;
send_sig(signr, current, 1); send_sig(SIGSEGV, current, 1);
} }
asmlinkage void do_nmi(struct pt_regs * regs, long error_code) asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
......
/* ioport.c: I/O access on the Sparc. Work in progress.. Most of the things /* ioport.c: I/O access on the Sparc. Work in progress.. Most of the things
* in this file are for the sole purpose of getting the kernel * in this file are for the sole purpose of getting the kernel
* throught the compiler. :-) * through the compiler. :-)
* *
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/ */
......
...@@ -97,7 +97,7 @@ extern unsigned long free_area_init(unsigned long, unsigned long); ...@@ -97,7 +97,7 @@ extern unsigned long free_area_init(unsigned long, unsigned long);
* unmaps the bootup page table (as we're now in KSEG, so we don't need it). * unmaps the bootup page table (as we're now in KSEG, so we don't need it).
* *
* The bootup sequence put the virtual page table into high memory: that * The bootup sequence put the virtual page table into high memory: that
* means that we cah change the L1 page table by just using VL1p below. * means that we can change the L1 page table by just using VL1p below.
*/ */
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
......
...@@ -35,16 +35,70 @@ restore the default behaviour. ...@@ -35,16 +35,70 @@ restore the default behaviour.
Sets the bitmask of allowed drives to <mask>. By default, only units Sets the bitmask of allowed drives to <mask>. By default, only units
0 and 1 of each floppy controller are allowed. This is done because 0 and 1 of each floppy controller are allowed. This is done because
certain non-standard hardware (ASUS PCI motherboards) mess up the certain non-standard hardware (ASUS PCI motherboards) mess up the
keyboard when accessing units 2 or 3. keyboard when accessing units 2 or 3. This option is somewhat
obsoleted by the cmos option.
floppy=all_drives
Sets the bitmask of allowed drives to all drives. Use this if you have
more than two drives connected to a floppy controller.
floppy=asus_pci
Sets the bitmask to allow only units 0 and 1. (The default)
floppy=daring
Tells the floppy driver that you have a well behaved floppy controller.
This allows more efficient and smoother operation, but may fail on
certain controllers. This may speed up certain operations.
floppy=0,daring
Tells the floppy driver that your floppy controller should be used
with caution.
floppy=one_fdc
Tells the floppy driver that you have only floppy controller (default)
floppy=two_fdc floppy=two_fdc
floppy=<address>,two_fdc
Tells the floppy driver that you have two floppy controllers. The Tells the floppy driver that you have two floppy controllers. The
second floppy controller is assumed to be at io address 0x370. second floppy controller is assumed to be at <address>. If <address>
is not given, 0x370 is assumed.
floppy=thinkpad floppy=thinkpad
Tells the floppy driver that you have a Thinkpad. Thinkpads use an Tells the floppy driver that you have a Thinkpad. Thinkpads use an
inverted convention for the disk change line. inverted convention for the disk change line.
floppy=0,thinkpad
Tells the floppy driver that you don't have a Thinkpad.
floppy=<drive>,<type>,cmos
Sets the cmos type of <drive> to <type>. Additionnaly, this drive is
allowed in the bitmask. This is useful if you have more than two
floppy drives (only two can be described in the physical cmos), or if
your BIOS uses non-standard CMOS types. The CMOS types are:
0 - unknown or not installed
1 - 5 1/4 DD
2 - 5 1/4 HD
3 - 3 1/2 DD
4 - 3 1/2 HD
5 - 3 1/2 ED
6 - 3 1/2 ED
(Note: there are two valid types for ED drives. This is because 5 was
initially chosen to represent floppy *tapes*, and 6 for ED drives.
AMI ignored this, and used 5 for ED drives. That's why the floppy
driver handles both)
Setting the CMOS to 0 for the first two drives (default) makes the
floppy driver read the physical cmos for those drives.
floppy=unexpected_interrupts
Print a warning message when an unexpected interrupt is received
(default behaviour)
floppy=no_unexpected_interrupts
floppy=L40SX
Don't print a message when an unexpected interrupt is received. This
is needed on IBM L40SX laptops in certain video modes. (There seems
to be an interaction between video and floppy. The unexpected interrupts
only affect performance, and can safely be ignored.)
Supporting utilities and additional documentation: Supporting utilities and additional documentation:
......
...@@ -638,7 +638,7 @@ azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame); ...@@ -638,7 +638,7 @@ azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
break; break;
case CDROMVOLCTRL: /* Volume control case CDROMVOLCTRL: /* Volume control
* With my Aztech CD268-01A volume control does not work, I can only * With my Aztech CD268-01A volume control does not work, I can only
turn the cannels on (any value !=0) or off (value==0). Maybe it turn the channels on (any value !=0) or off (value==0). Maybe it
works better with your drive */ works better with your drive */
st=verify_area(VERIFY_READ,(void *) arg, sizeof(volctrl)); st=verify_area(VERIFY_READ,(void *) arg, sizeof(volctrl));
if (st) return (st); if (st) return (st);
......
...@@ -82,7 +82,6 @@ ...@@ -82,7 +82,6 @@
*/ */
#define CONFIG_FLOPPY_SANITY #define CONFIG_FLOPPY_SANITY
#define CONFIG_FLOPPY_2_FDC
#undef CONFIG_FLOPPY_SILENT_DCL_CLEAR #undef CONFIG_FLOPPY_SILENT_DCL_CLEAR
#define REALLY_SLOW_IO #define REALLY_SLOW_IO
...@@ -92,6 +91,9 @@ ...@@ -92,6 +91,9 @@
#include <linux/config.h> #include <linux/config.h>
/* do print messages for unexpected interupts */
static int print_unex=1;
#ifndef FD_MODULE #ifndef FD_MODULE
/* the following is the mask of allowed drives. By default units 2 and /* the following is the mask of allowed drives. By default units 2 and
* 3 of both floppy controllers are disabled, because switching on the * 3 of both floppy controllers are disabled, because switching on the
...@@ -148,14 +150,8 @@ static int initialising=1; ...@@ -148,14 +150,8 @@ static int initialising=1;
#define FLOPPY1_TYPE 0 #define FLOPPY1_TYPE 0
#endif #endif
#ifdef CONFIG_FLOPPY_2_FDC
#define N_FDC 2 #define N_FDC 2
#define N_DRIVE 8 #define N_DRIVE 8
#else
#define N_FDC 1
#define N_DRIVE 4
#endif
#define TYPE(x) ( ((x)>>2) & 0x1f ) #define TYPE(x) ( ((x)>>2) & 0x1f )
#define DRIVE(x) ( ((x)&0x03) | (((x)&0x80 ) >> 5)) #define DRIVE(x) ( ((x)&0x03) | (((x)&0x80 ) >> 5))
...@@ -179,16 +175,16 @@ static int initialising=1; ...@@ -179,16 +175,16 @@ static int initialising=1;
#define USETF(x) (set_bit(x##_BIT, &UDRS->flags)) #define USETF(x) (set_bit(x##_BIT, &UDRS->flags))
#define UTESTF(x) (test_bit(x##_BIT, &UDRS->flags)) #define UTESTF(x) (test_bit(x##_BIT, &UDRS->flags))
#define DPRINT(x) printk(DEVICE_NAME "%d: " x,current_drive); #define DPRINT(x) printk(DEVICE_NAME "%d: " x,current_drive)
#define DPRINT1(x,x1) \ #define DPRINT1(x,x1) \
printk(DEVICE_NAME "%d: " x,current_drive,(x1)); printk(DEVICE_NAME "%d: " x,current_drive,(x1))
#define DPRINT2(x,x1,x2) \ #define DPRINT2(x,x1,x2) \
printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2)); printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2))
#define DPRINT3(x,x1,x2,x3) \ #define DPRINT3(x,x1,x2,x3) \
printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2),(x3)); printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2),(x3))
/* read/write */ /* read/write */
#define COMMAND raw_cmd.cmd[0] #define COMMAND raw_cmd.cmd[0]
...@@ -348,11 +344,8 @@ static struct floppy_struct floppy_type[32] = { ...@@ -348,11 +344,8 @@ static struct floppy_struct floppy_type[32] = {
/* Auto-detection: Disk type used until the next media change occurs. */ /* Auto-detection: Disk type used until the next media change occurs. */
struct floppy_struct *current_type[N_DRIVE] = { struct floppy_struct *current_type[N_DRIVE] = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL NULL, NULL, NULL, NULL
#ifdef CONFIG_FLOPPY_2_FDC
,
NULL, NULL, NULL, NULL
#endif
}; };
/* /*
...@@ -645,9 +638,7 @@ static void set_fdc(int drive) ...@@ -645,9 +638,7 @@ static void set_fdc(int drive)
current_drive = drive; current_drive = drive;
} }
set_dor(fdc,~0,8); set_dor(fdc,~0,8);
#ifdef CONFIG_FLOPPY_2_FDC
set_dor(1-fdc, ~8, 0); set_dor(1-fdc, ~8, 0);
#endif
if ( FDCS->rawcmd == 2 ) if ( FDCS->rawcmd == 2 )
reset_fdc_info(1); reset_fdc_info(1);
if( inb_p(FD_STATUS) != STATUS_READY ) if( inb_p(FD_STATUS) != STATUS_READY )
...@@ -713,14 +704,11 @@ static struct timer_list motor_off_timer[N_DRIVE] = { ...@@ -713,14 +704,11 @@ static struct timer_list motor_off_timer[N_DRIVE] = {
{ NULL, NULL, 0, 0, motor_off_callback }, { NULL, NULL, 0, 0, motor_off_callback },
{ NULL, NULL, 0, 1, motor_off_callback }, { NULL, NULL, 0, 1, motor_off_callback },
{ NULL, NULL, 0, 2, motor_off_callback }, { NULL, NULL, 0, 2, motor_off_callback },
{ NULL, NULL, 0, 3, motor_off_callback } { NULL, NULL, 0, 3, motor_off_callback },
#ifdef CONFIG_FLOPPY_2_FDC
,
{ NULL, NULL, 0, 4, motor_off_callback }, { NULL, NULL, 0, 4, motor_off_callback },
{ NULL, NULL, 0, 5, motor_off_callback }, { NULL, NULL, 0, 5, motor_off_callback },
{ NULL, NULL, 0, 6, motor_off_callback }, { NULL, NULL, 0, 6, motor_off_callback },
{ NULL, NULL, 0, 7, motor_off_callback } { NULL, NULL, 0, 7, motor_off_callback }
#endif
}; };
/* schedules motor off */ /* schedules motor off */
...@@ -1438,18 +1426,22 @@ static void unexpected_floppy_interrupt(void) ...@@ -1438,18 +1426,22 @@ static void unexpected_floppy_interrupt(void)
int i; int i;
if ( initialising ) if ( initialising )
return; return;
DPRINT("unexpected interrupt\n"); if(print_unex){
if ( inr >= 0 ) DPRINT("unexpected interrupt\n");
for(i=0; i<inr; i++) if ( inr >= 0 )
printk("%d %x\n", i, reply_buffer[i] ); for(i=0; i<inr; i++)
printk("%d %x\n", i, reply_buffer[i] );
}
while(1){ while(1){
output_byte(FD_SENSEI); output_byte(FD_SENSEI);
inr=result(); inr=result();
if ( inr != 2 ) if ( inr != 2 )
break; break;
printk("sensei\n"); if(print_unex){
for(i=0; i<inr; i++) printk("sensei\n");
printk("%d %x\n", i, reply_buffer[i] ); for(i=0; i<inr; i++)
printk("%d %x\n", i, reply_buffer[i] );
}
} }
FDCS->reset = 1; FDCS->reset = 1;
} }
...@@ -2829,9 +2821,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ...@@ -2829,9 +2821,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
cnt < (type << 2 ) + 4 ; cnt < (type << 2 ) + 4 ;
cnt++) cnt++)
floppy_sizes[cnt]= floppy_sizes[cnt]=
#ifdef CONFIG_FLOPPY_2_FDC
floppy_sizes[cnt+0x80]= floppy_sizes[cnt+0x80]=
#endif
floppy_type[type].size>>1; floppy_type[type].size>>1;
process_fd_request(); process_fd_request();
for ( cnt = 0; cnt < N_DRIVE; cnt++){ for ( cnt = 0; cnt < N_DRIVE; cnt++){
...@@ -2899,36 +2889,44 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ...@@ -2899,36 +2889,44 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
#undef IOCTL_ALLOWED #undef IOCTL_ALLOWED
} }
static void set_base_type(int drive,int code)
{
if (code > 0 && code <= NUMBER(default_drive_params)) {
memcpy((char *) UDP,
(char *) (&default_drive_params[code].params),
sizeof( struct floppy_drive_params ));
printk("fd%d is %s", drive, default_drive_params[code].name);
return;
} else if (!code)
printk("fd%d is not installed", drive);
else
printk("fd%d is unknown type %d",drive,code);
}
static void config_types(void) static void config_types(void)
{ {
int first=1;
int drive; int drive;
for (drive=0; drive<N_DRIVE ; drive++){ /* read drive info out of physical cmos */
/* default type for unidentifiable drives */ drive=0;
memcpy((char *) UDP, (char *) (&default_drive_params->params), if (!UDP->cmos )
sizeof( struct floppy_drive_params )); UDP->cmos= FLOPPY0_TYPE;
} drive=1;
printk("Floppy drive(s): "); if (!UDP->cmos && FLOPPY1_TYPE)
set_base_type(0, FLOPPY0_TYPE); UDP->cmos = FLOPPY1_TYPE;
if (FLOPPY1_TYPE) {
printk(", "); /* XXX */
set_base_type(1, FLOPPY1_TYPE); /* additional physical CMOS drive detection should go here */
for (drive=0; drive < N_DRIVE; drive++){
if (UDP->cmos >= 0 && UDP->cmos <= NUMBER(default_drive_params))
memcpy((char *) UDP,
(char *) (&default_drive_params[(int)UDP->cmos].params),
sizeof(struct floppy_drive_params));
if (UDP->cmos){
if (first)
printk("Floppy drive(s): ");
else
printk(", ");
first=0;
if (UDP->cmos > 0 ){
ALLOWED_DRIVE_MASK |= 1 << drive;
printk("fd%d is %s", drive,
default_drive_params[(int)UDP->cmos].name);
} else
printk("fd%d is unknown type %d",drive,
UDP->cmos);
}
} }
printk("\n"); if(!first)
printk("\n");
} }
static int floppy_read(struct inode * inode, struct file * filp, static int floppy_read(struct inode * inode, struct file * filp,
...@@ -3204,56 +3202,128 @@ static char get_fdc_version(void) ...@@ -3204,56 +3202,128 @@ static char get_fdc_version(void)
} /* get_fdc_version */ } /* get_fdc_version */
/* lilo configuration */ /* lilo configuration */
static void invert_dcl(int *ints)
/* we make the invert_dcl function global. One day, somebody might
want to centralize all thinkpad related options into one lilo option,
there are just so many thinpad related quirks! */
void floppy_invert_dcl(int *ints,int param)
{ {
int i; int i;
for (i=0; i < ARRAY_SIZE(default_drive_params); i++) for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
default_drive_params[i].params.flags |= 0x80; if (param)
default_drive_params[i].params.flags |= 0x80;
else
default_drive_params[i].params.flags &= ~0x80;
}
DPRINT("Configuring drives for inverted dcl\n"); DPRINT("Configuring drives for inverted dcl\n");
} }
static void allow_drives(int *ints) static void daring(int *ints,int param)
{ {
if (ints[1] >= 1 ){ int i;
ALLOWED_DRIVE_MASK=ints[1];
DPRINT1("setting allowed_drive_mask to 0x%x\n", ints[1]); for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
} else if (param){
DPRINT("allowed_drive_mask needs a parameter\n"); default_drive_params[i].params.select_delay = 0;
default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR;
} else {
default_drive_params[i].params.select_delay = 2;
default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
}
}
DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
} }
#ifdef CONFIG_FLOPPY_2_FDC static void allow_drives(int *ints, int param)
static void twofdc(int *ints)
{ {
FDC2 = 0x370; ALLOWED_DRIVE_MASK=param;
DPRINT("enabling second fdc at address 0x370\n"); DPRINT1("setting allowed_drive_mask to 0x%x\n", param);
} }
#endif
static void fdc2_adr(int *ints, int param)
{
FDC2 = param;
if(param)
DPRINT1("enabling second fdc at address 0x%3x\n", FDC2);
else
DPRINT("disabling second fdc\n");
}
static void unex(int *ints,int param)
{
print_unex = param;
DPRINT1("%sprinting messages for unexpected interrupts\n",
param ? "" : "not ");
}
static void set_cmos(int *ints, int dummy)
{
int current_drive=0;
if ( ints[0] != 2 ){
DPRINT("wrong number of parameter for cmos\n");
return;
}
current_drive = ints[1];
if (current_drive < 0 || current_drive >= 8 ){
DPRINT("bad drive for set_cmos\n");
return;
}
if(ints[2] <= 0 || ints[2] >= NUMBER(default_drive_params)){
DPRINT1("bad cmos code %d\n", ints[2]);
return;
}
DP->cmos = ints[2];
DPRINT1("setting cmos code to %d\n", ints[2]);
}
static struct param_table { static struct param_table {
char *name; char *name;
void (*fn)(int *ints); void (*fn)(int *ints, int param);
int def_param;
} config_params[]={ } config_params[]={
{ "allowed_drive_mask", allow_drives }, { "allowed_drive_mask", allow_drives, 0xff },
#ifdef CONFIG_FLOPPY_2_FDC { "all_drives", allow_drives, 0xff },
{ "two_fdc", twofdc }, { "asus_pci", allow_drives, 0x33 },
#endif
{ "thinkpad", invert_dcl } }; { "daring", daring, 1},
{ "two_fdc", fdc2_adr, 0x370 },
{ "one_fdc", fdc2_adr, 0 },
{ "thinkpad", floppy_invert_dcl, 1 },
{ "cmos", set_cmos, 0 },
{ "unexpected_interrupts", unex, 1 },
{ "no_unexpected_interrupts", unex, 0 },
{ "L40SX", unex, 0 } };
#define FLOPPY_SETUP
void floppy_setup(char *str, int *ints) void floppy_setup(char *str, int *ints)
{ {
int i; int i;
int param;
if(!str) if(!str)
return; return;
for(i=0; i< ARRAY_SIZE(config_params); i++){ for(i=0; i< ARRAY_SIZE(config_params); i++){
if (strcmp(str,config_params[i].name) == 0 ){ if (strcmp(str,config_params[i].name) == 0 ){
config_params[i].fn(ints); if (ints[0] )
param = ints[1];
else
param = config_params[i].def_param;
config_params[i].fn(ints,param);
return; return;
} }
} }
printk("unknown floppy parameter %s\n", str); DPRINT1("unknown floppy option %s\n", str);
DPRINT("allowed options are:");
for(i=0; i< ARRAY_SIZE(config_params); i++)
printk(" %s",config_params[i].name);
printk("\n");
DPRINT("Read linux/drivers/block/README.fd\n");
} }
#define FLOPPY_SETUP
#ifdef FD_MODULE #ifdef FD_MODULE
static static
......
Thu Jan 26 09:02:49 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_init, set_serial_info, get_serial_info, rs_close):
Support close_wait and close_wait2 in the serial driver.
This is helpful for slow devices (like serial plotters) so
that their outputs don't get flushed upon device close.
This has to be configurable because normally we don't want
ports to be hung up for long periods of time during a
close when they are not connected to a device, or the
device is powered off.
The default is to wait 30 seconds after shutting down the
receiver (to prevent echo wars). This is done by setting
close_wait=ASYNC_CLOSE_WAIT_NONE, close_wait2 = 3000. If
XON/XOFF handshaking is used, then the 30 second timeout
should happen before the receiver is shutdown; this is
done by reversing the values of close_wait and
close_wait2. In the case of a very slow device, the
timeouts for close_wait or close_wait2 should be lengthened.
If either value is set to 0, the kernel will wait forever
for all of the data to be transmitted.
Thu Jan 17 01:17:20 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (startup, change_speed, rs_init): Add support to detect
the StarTech 16650 chip. Treat it as a 16450 for now,
because of its FIFO bugs.
Thu Jan 5 21:21:57 1995 <dhinds@allegro.stanford.edu> Thu Jan 5 21:21:57 1995 <dhinds@allegro.stanford.edu>
* serial.c: (receive_char): Added counter to prevent infinite loop * serial.c: (receive_char): Added counter to prevent infinite loop
......
...@@ -1909,7 +1909,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file, ...@@ -1909,7 +1909,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
ret_val = tty_check_change(tty); ret_val = tty_check_change(tty);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
wait_until_sent(tty,0); tty_wait_until_sent(tty,0);
if (!arg) if (!arg)
send_break(info, HZ/4); /* 1/4 second */ send_break(info, HZ/4); /* 1/4 second */
break; break;
...@@ -1917,7 +1917,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file, ...@@ -1917,7 +1917,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
ret_val = tty_check_change(tty); ret_val = tty_check_change(tty);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
wait_until_sent(tty,0); tty_wait_until_sent(tty,0);
send_break(info, arg ? arg*(HZ/10) : HZ/4); send_break(info, arg ? arg*(HZ/10) : HZ/4);
break; break;
case TIOCMBIS: case TIOCMBIS:
...@@ -2060,7 +2060,7 @@ cy_close(struct tty_struct * tty, struct file * filp) ...@@ -2060,7 +2060,7 @@ cy_close(struct tty_struct * tty, struct file * filp)
if (info->flags & ASYNC_CALLOUT_ACTIVE) if (info->flags & ASYNC_CALLOUT_ACTIVE)
info->callout_termios = *tty->termios; info->callout_termios = *tty->termios;
if (info->flags & ASYNC_INITIALIZED) if (info->flags & ASYNC_INITIALIZED)
wait_until_sent(tty, 3000); /* 30 seconds timeout */ tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
shutdown(info); shutdown(info);
if (tty->driver.flush_buffer) if (tty->driver.flush_buffer)
tty->driver.flush_buffer(tty); tty->driver.flush_buffer(tty);
......
...@@ -164,9 +164,10 @@ static inline void kb_wait(void) ...@@ -164,9 +164,10 @@ static inline void kb_wait(void)
{ {
int i; int i;
for (i=0; i<0x10000; i++) for (i=0; i<0x100000; i++)
if ((inb_p(0x64) & 0x02) == 0) if ((inb_p(0x64) & 0x02) == 0)
break; return;
printk("Keyboard timed out\n");
} }
static inline void send_cmd(unsigned char c) static inline void send_cmd(unsigned char c)
...@@ -1164,15 +1165,14 @@ unsigned long kbd_init(unsigned long kmem_start) ...@@ -1164,15 +1165,14 @@ unsigned long kbd_init(unsigned long kmem_start)
bh_base[KEYBOARD_BH].routine = kbd_bh; bh_base[KEYBOARD_BH].routine = kbd_bh;
request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard"); request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard");
#ifdef __alpha__ #ifdef __alpha__
/* enable keyboard interrupts */ /* enable keyboard interrupts, PC/AT mode */
outb(0x60,0x64); kb_wait();
while (inb(0x64) & 2) outb(0x60,0x64); /* write PS/2 Mode Register */
/* nothing */; kb_wait();
outb(0x1,0x60); outb(0x41,0x60); /* KCC | EKI */
while (inb(0x64) & 2) kb_wait();
/* nothing */; if (!send_data(0xf0) || !send_data(0x02))
if (!send_data(0xf0) || !send_data(0x01)) printk("Scanmode 2 change failed\n");
printk("Scanmode 1 change failed\n");
#endif #endif
mark_bh(KEYBOARD_BH); mark_bh(KEYBOARD_BH);
enable_bh(KEYBOARD_BH); enable_bh(KEYBOARD_BH);
......
...@@ -666,7 +666,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) ...@@ -666,7 +666,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old)
static void n_tty_close(struct tty_struct *tty) static void n_tty_close(struct tty_struct *tty)
{ {
wait_until_sent(tty, 0); tty_wait_until_sent(tty, 0);
n_tty_flush_buffer(tty); n_tty_flush_buffer(tty);
if (tty->read_buf) { if (tty->read_buf) {
free_page((unsigned long) tty->read_buf); free_page((unsigned long) tty->read_buf);
......
...@@ -877,15 +877,7 @@ static int startup(struct async_struct * info) ...@@ -877,15 +877,7 @@ static int startup(struct async_struct * info)
* Clear the FIFO buffers and disable them * Clear the FIFO buffers and disable them
* (they will be reenabled in change_speed()) * (they will be reenabled in change_speed())
*/ */
if (info->type == PORT_16650) { if (info->type == PORT_16550A) {
serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT));
#if 0
info->xmit_fifo_size = 32;
#else
info->xmit_fifo_size = 1;
#endif
} else if (info->type == PORT_16550A) {
serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR | serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT)); UART_FCR_CLEAR_XMIT));
info->xmit_fifo_size = 16; info->xmit_fifo_size = 16;
...@@ -1156,18 +1148,6 @@ static void change_speed(struct async_struct *info) ...@@ -1156,18 +1148,6 @@ static void change_speed(struct async_struct *info)
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
else else
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8; fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
} else if (info->type == PORT_16650) {
/*
* On the 16650, we disable the FIFOs altogether
* because of a design bug in how the implement
* things. We could support it by completely changing
* how we handle the interrupt driver, but not today....
*
* N.B. Because there's no way to set a FIFO trigger
* at 1 char, we'd probably disable at speed below
* 2400 baud anyway...
*/
fcr = 0;
} else } else
fcr = 0; fcr = 0;
...@@ -1424,8 +1404,6 @@ static int get_serial_info(struct async_struct * info, ...@@ -1424,8 +1404,6 @@ static int get_serial_info(struct async_struct * info,
tmp.flags = info->flags; tmp.flags = info->flags;
tmp.baud_base = info->baud_base; tmp.baud_base = info->baud_base;
tmp.close_delay = info->close_delay; tmp.close_delay = info->close_delay;
tmp.closing_wait = info->closing_wait;
tmp.closing_wait2 = info->closing_wait2;
tmp.custom_divisor = info->custom_divisor; tmp.custom_divisor = info->custom_divisor;
tmp.hub6 = info->hub6; tmp.hub6 = info->hub6;
memcpy_tofs(retinfo,&tmp,sizeof(*retinfo)); memcpy_tofs(retinfo,&tmp,sizeof(*retinfo));
...@@ -1493,8 +1471,6 @@ static int set_serial_info(struct async_struct * info, ...@@ -1493,8 +1471,6 @@ static int set_serial_info(struct async_struct * info,
info->custom_divisor = new_serial.custom_divisor; info->custom_divisor = new_serial.custom_divisor;
info->type = new_serial.type; info->type = new_serial.type;
info->close_delay = new_serial.close_delay; info->close_delay = new_serial.close_delay;
info->closing_wait = new_serial.closing_wait;
info->closing_wait2 = new_serial.closing_wait2;
release_region(info->port,8); release_region(info->port,8);
if (change_port || change_irq) { if (change_port || change_irq) {
...@@ -1722,7 +1698,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, ...@@ -1722,7 +1698,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
retval = tty_check_change(tty); retval = tty_check_change(tty);
if (retval) if (retval)
return retval; return retval;
wait_until_sent(tty, 0); tty_wait_until_sent(tty, 0);
if (!arg) if (!arg)
send_break(info, HZ/4); /* 1/4 second */ send_break(info, HZ/4); /* 1/4 second */
return 0; return 0;
...@@ -1730,7 +1706,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, ...@@ -1730,7 +1706,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
retval = tty_check_change(tty); retval = tty_check_change(tty);
if (retval) if (retval)
return retval; return retval;
wait_until_sent(tty, 0); tty_wait_until_sent(tty, 0);
send_break(info, arg ? arg*(HZ/10) : HZ/4); send_break(info, arg ? arg*(HZ/10) : HZ/4);
return 0; return 0;
case TIOCGSOFTCAR: case TIOCGSOFTCAR:
...@@ -1895,8 +1871,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp) ...@@ -1895,8 +1871,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
info->normal_termios = *tty->termios; info->normal_termios = *tty->termios;
if (info->flags & ASYNC_CALLOUT_ACTIVE) if (info->flags & ASYNC_CALLOUT_ACTIVE)
info->callout_termios = *tty->termios; info->callout_termios = *tty->termios;
if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
wait_until_sent(tty, info->closing_wait);
/* /*
* At this point we stop accepting input. To do this, we * At this point we stop accepting input. To do this, we
* disable the receive line status interrupts, and tell the * disable the receive line status interrupts, and tell the
...@@ -1907,7 +1881,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) ...@@ -1907,7 +1881,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
info->read_status_mask &= ~UART_LSR_DR; info->read_status_mask &= ~UART_LSR_DR;
if (info->flags & ASYNC_INITIALIZED) { if (info->flags & ASYNC_INITIALIZED) {
serial_out(info, UART_IER, info->IER); serial_out(info, UART_IER, info->IER);
wait_until_sent(tty, info->closing_wait2); tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
/* /*
* Before we drop DTR, make sure the UART transmitter * Before we drop DTR, make sure the UART transmitter
* has completely drained; this is especially * has completely drained; this is especially
...@@ -2355,10 +2329,6 @@ static void autoconfig(struct async_struct * info) ...@@ -2355,10 +2329,6 @@ static void autoconfig(struct async_struct * info)
if (info->flags & ASYNC_AUTO_IRQ) if (info->flags & ASYNC_AUTO_IRQ)
info->irq = do_auto_irq(info); info->irq = do_auto_irq(info);
scratch2 = serial_in(info, UART_LCR);
serial_outp(info, UART_LCR, scratch2 | UART_LCR_DLAB);
serial_outp(info, UART_EFR, 0); /* EFR is the same as FCR */
serial_outp(info, UART_LCR, scratch2);
serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
scratch = serial_in(info, UART_IIR) >> 6; scratch = serial_in(info, UART_IIR) >> 6;
info->xmit_fifo_size = 1; info->xmit_fifo_size = 1;
...@@ -2373,15 +2343,8 @@ static void autoconfig(struct async_struct * info) ...@@ -2373,15 +2343,8 @@ static void autoconfig(struct async_struct * info)
info->type = PORT_16550; info->type = PORT_16550;
break; break;
case 3: case 3:
serial_outp(info, UART_LCR, scratch2 | UART_LCR_DLAB); info->type = PORT_16550A;
if (serial_in(info, UART_EFR) == 0) { info->xmit_fifo_size = 16;
info->type = PORT_16650;
info->xmit_fifo_size = 32;
} else {
info->type = PORT_16550A;
info->xmit_fifo_size = 16;
}
serial_outp(info, UART_LCR, scratch2);
break; break;
} }
if (info->type == PORT_16450) { if (info->type == PORT_16450) {
...@@ -2495,8 +2458,6 @@ long rs_init(long kmem_start) ...@@ -2495,8 +2458,6 @@ long rs_init(long kmem_start)
info->type = PORT_UNKNOWN; info->type = PORT_UNKNOWN;
info->custom_divisor = 0; info->custom_divisor = 0;
info->close_delay = 50; info->close_delay = 50;
info->closing_wait = ASYNC_CLOSING_WAIT_NONE;
info->closing_wait2 = 3000;
info->x_char = 0; info->x_char = 0;
info->event = 0; info->event = 0;
info->count = 0; info->count = 0;
...@@ -2532,9 +2493,6 @@ long rs_init(long kmem_start) ...@@ -2532,9 +2493,6 @@ long rs_init(long kmem_start)
case PORT_16550A: case PORT_16550A:
printk(" is a 16550A\n"); printk(" is a 16550A\n");
break; break;
case PORT_16650:
printk(" is a 16650\n");
break;
default: default:
printk("\n"); printk("\n");
break; break;
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#define TERMIOS_WAIT 2 #define TERMIOS_WAIT 2
#define TERMIOS_TERMIO 4 #define TERMIOS_TERMIO 4
void wait_until_sent(struct tty_struct * tty, int timeout) void tty_wait_until_sent(struct tty_struct * tty, int timeout)
{ {
struct wait_queue wait = { current, NULL }; struct wait_queue wait = { current, NULL };
...@@ -132,7 +132,7 @@ static int set_termios(struct tty_struct * tty, unsigned long arg, int opt) ...@@ -132,7 +132,7 @@ static int set_termios(struct tty_struct * tty, unsigned long arg, int opt)
tty->ldisc.flush_buffer(tty); tty->ldisc.flush_buffer(tty);
if (opt & TERMIOS_WAIT) if (opt & TERMIOS_WAIT)
wait_until_sent(tty, 0); tty_wait_until_sent(tty, 0);
cli(); cli();
*tty->termios = tmp_termios; *tty->termios = tmp_termios;
...@@ -363,7 +363,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file, ...@@ -363,7 +363,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
retval = tty_check_change(tty); retval = tty_check_change(tty);
if (retval) if (retval)
return retval; return retval;
wait_until_sent(tty, 0); tty_wait_until_sent(tty, 0);
if (!tty->driver.ioctl) if (!tty->driver.ioctl)
return 0; return 0;
tty->driver.ioctl(tty, file, cmd, arg); tty->driver.ioctl(tty, file, cmd, arg);
......
...@@ -61,6 +61,12 @@ ...@@ -61,6 +61,12 @@
in group 224.0.0.1 and you will therefore be listening to all multicasts. in group 224.0.0.1 and you will therefore be listening to all multicasts.
One nv conference running over that ethernet and you can give up. One nv conference running over that ethernet and you can give up.
2/8/95 (invid@msen.com)
Removed calls to init_etherdev since they are no longer needed, and
cleaned up modularization just a bit. The driver still allows only
the default address for cards when loaded as a module, but that's
really less braindead than anyone using a 3c501 board. :)
*/ */
static char *version = static char *version =
...@@ -75,6 +81,9 @@ static char *version = ...@@ -75,6 +81,9 @@ static char *version =
#ifdef MODULE #ifdef MODULE
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h> #include <linux/version.h>
#else
#define MOD_INC_USE_COUNT
#define MOD_DEC_USE_COUNT
#endif #endif
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -95,9 +104,6 @@ static char *version = ...@@ -95,9 +104,6 @@ static char *version =
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
extern struct device *init_etherdev(struct device *dev, int sizeof_private,
unsigned long *mem_startp);
/* A zero-terminated list of I/O addresses to be probed. /* A zero-terminated list of I/O addresses to be probed.
The 3c501 can be at many locations, but here are the popular ones. */ The 3c501 can be at many locations, but here are the popular ones. */
static unsigned int netcard_portlist[] = static unsigned int netcard_portlist[] =
...@@ -208,6 +214,8 @@ el1_probe(struct device *dev) ...@@ -208,6 +214,8 @@ el1_probe(struct device *dev)
static int static int
el1_probe1(struct device *dev, int ioaddr) el1_probe1(struct device *dev, int ioaddr)
{ {
#ifndef MODULE
char *mname; /* Vendor name */ char *mname; /* Vendor name */
unsigned char station_addr[6]; unsigned char station_addr[6];
int autoirq = 0; int autoirq = 0;
...@@ -232,9 +240,6 @@ el1_probe1(struct device *dev, int ioaddr) ...@@ -232,9 +240,6 @@ el1_probe1(struct device *dev, int ioaddr)
/* Grab the region so we can find the another board if autoIRQ fails. */ /* Grab the region so we can find the another board if autoIRQ fails. */
request_region(ioaddr, EL1_IO_EXTENT,"3c501"); request_region(ioaddr, EL1_IO_EXTENT,"3c501");
if (dev == NULL)
dev = init_etherdev(0, sizeof(struct net_local), 0);
/* We auto-IRQ by shutting off the interrupt line and letting it float /* We auto-IRQ by shutting off the interrupt line and letting it float
high. */ high. */
if (dev->irq < 2) { if (dev->irq < 2) {
...@@ -290,6 +295,7 @@ el1_probe1(struct device *dev, int ioaddr) ...@@ -290,6 +295,7 @@ el1_probe1(struct device *dev, int ioaddr)
/* Setup the generic properties */ /* Setup the generic properties */
ether_setup(dev); ether_setup(dev);
#endif /* !MODULE */
return 0; return 0;
} }
...@@ -312,9 +318,7 @@ el_open(struct device *dev) ...@@ -312,9 +318,7 @@ el_open(struct device *dev)
dev->start = 1; dev->start = 1;
outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */ outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */
#ifdef MODULE
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
#endif
return 0; return 0;
} }
...@@ -618,9 +622,7 @@ el1_close(struct device *dev) ...@@ -618,9 +622,7 @@ el1_close(struct device *dev)
outb(AX_RESET, AX_CMD); /* Reset the chip */ outb(AX_RESET, AX_CMD); /* Reset the chip */
irq2dev_map[dev->irq] = 0; irq2dev_map[dev->irq] = 0;
#ifdef MODULE
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return 0; return 0;
} }
......
...@@ -115,7 +115,7 @@ ethif_probe(struct device *dev) ...@@ -115,7 +115,7 @@ ethif_probe(struct device *dev)
#ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */ #ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */
&& ewrk3_probe(dev) && ewrk3_probe(dev)
#endif #endif
#ifdef CONFIG_DE4X5 /* DEC DE425, DE434, DE435 adapters */ #ifdef CONFIG_DE4x5 /* DEC DE425, DE434, DE435 adapters */
&& de4x5_probe(dev) && de4x5_probe(dev)
#endif #endif
#ifdef CONFIG_APRICOT /* Apricot I82596 */ #ifdef CONFIG_APRICOT /* Apricot I82596 */
......
...@@ -686,10 +686,12 @@ de600_probe(struct device *dev) ...@@ -686,10 +686,12 @@ de600_probe(struct device *dev)
return ENODEV; return ENODEV;
} }
#if 0 /* Not yet */
if (check_region(DE600_IO, 3)) { if (check_region(DE600_IO, 3)) {
printk(", port 0x%x busy\n", DE600_IO); printk(", port 0x%x busy\n", DE600_IO);
return EBUSY; return EBUSY;
} }
#endif
request_region(DE600_IO, 3, "de600"); request_region(DE600_IO, 3, "de600");
printk(", Ethernet Address: %02X", dev->dev_addr[0]); printk(", Ethernet Address: %02X", dev->dev_addr[0]);
...@@ -840,10 +842,7 @@ init_module(void) ...@@ -840,10 +842,7 @@ init_module(void)
void void
cleanup_module(void) cleanup_module(void)
{ {
if (MOD_IN_USE) unregister_netdev(&de600_dev);
printk("de600: device busy, remove delayed\n");
else
unregister_netdev(&de600_dev);
release_region(DE600_IO, 3); release_region(DE600_IO, 3);
} }
#endif /* MODULE */ #endif /* MODULE */
...@@ -824,10 +824,12 @@ de620_probe(struct device *dev) ...@@ -824,10 +824,12 @@ de620_probe(struct device *dev)
return ENODEV; return ENODEV;
} }
#if 0 /* Not yet */
if (check_region(DE620_IO, 3)) { if (check_region(DE620_IO, 3)) {
printk(", port 0x%x busy\n", DE620_IO); printk(", port 0x%x busy\n", DE620_IO);
return EBUSY; return EBUSY;
} }
#endif
request_region(DE620_IO, 3, "de620"); request_region(DE620_IO, 3, "de620");
/* else, got it! */ /* else, got it! */
...@@ -987,10 +989,7 @@ init_module(void) ...@@ -987,10 +989,7 @@ init_module(void)
void void
cleanup_module(void) cleanup_module(void)
{ {
if (MOD_IN_USE) unregister_netdev(&de620_dev);
printk("de620: device busy, remove delayed\n");
else
unregister_netdev(&de620_dev);
release_region(DE620_IO, 3); release_region(DE620_IO, 3);
} }
#endif /* MODULE */ #endif /* MODULE */
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* CAN YOU PLEASE REPORT ME YOUR PERFORMANCE EXPERIENCES !!. * CAN YOU PLEASE REPORT ME YOUR PERFORMANCE EXPERIENCES !!.
* *
* If you find a bug, please report me: * If you find a bug, please report me:
* The kernelpanic output and any kmsg from the ni52 driver * The kernel panic output and any kmsg from the ni52 driver
* the ni5210-driver-version and the linux-kernel version * the ni5210-driver-version and the linux-kernel version
* how many shared memory (memsize) on the netcard, * how many shared memory (memsize) on the netcard,
* bootprom: yes/no, base_addr, mem_start * bootprom: yes/no, base_addr, mem_start
...@@ -55,10 +55,10 @@ ...@@ -55,10 +55,10 @@
* *
* 19.Sep.94: Added Multicast support (not tested yet) (MH) * 19.Sep.94: Added Multicast support (not tested yet) (MH)
* *
* 18.Sep.94: Workarround for 'EL-Bug'. Removed flexible RBD-handling. * 18.Sep.94: Workaround for 'EL-Bug'. Removed flexible RBD-handling.
* Now, every RFD has exact one RBD. (MH) * Now, every RFD has exact one RBD. (MH)
* *
* 14.Sep.94: added promiscous mode, a few cleanups (MH) * 14.Sep.94: added promiscuous mode, a few cleanups (MH)
* *
* 19.Aug.94: changed request_irq() parameter (MH) * 19.Aug.94: changed request_irq() parameter (MH)
* *
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
* IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
* --------------- in a different (more stable?) mode. Only in this mode it's * --------------- in a different (more stable?) mode. Only in this mode it's
* possbile to configure the driver with 'NO_NOPCOMMANDS' * possible to configure the driver with 'NO_NOPCOMMANDS'
sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8; sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
...@@ -272,7 +272,7 @@ static int check586(struct device *dev,char *where,unsigned size) ...@@ -272,7 +272,7 @@ static int check586(struct device *dev,char *where,unsigned size)
ni_attn586(); ni_attn586();
DELAY(2); /* wait a while... */ DELAY(2); /* wait a while... */
if(p->iscp->busy) /* i82586 clears 'busy' after succesful init */ if(p->iscp->busy) /* i82586 clears 'busy' after successful init */
return 0; return 0;
} }
return 1; return 1;
...@@ -611,7 +611,7 @@ static int init586(struct device *dev,int num_addrs,void *addrs) ...@@ -611,7 +611,7 @@ static int init586(struct device *dev,int num_addrs,void *addrs)
if(len < num_addrs) if(len < num_addrs)
{ {
num_addrs = len; num_addrs = len;
printk("%s: Sorry, can only apply %d MC-Addresse(s).\n",dev->name,num_addrs); printk("%s: Sorry, can only apply %d MC-Address(es).\n",dev->name,num_addrs);
} }
mc_cmd = (struct mcsetup_cmd_struct *) ptr; mc_cmd = (struct mcsetup_cmd_struct *) ptr;
mc_cmd->cmd_status = 0; mc_cmd->cmd_status = 0;
...@@ -845,7 +845,7 @@ static void ni52_rnr_int(struct device *dev) ...@@ -845,7 +845,7 @@ static void ni52_rnr_int(struct device *dev)
p->stats.rx_errors++; p->stats.rx_errors++;
WAIT_4_SCB_CMD(); /* wait for the last cmd */ WAIT_4_SCB_CMD(); /* wait for the last cmd */
p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no ressource'-state .. abort it now. */ p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
ni_attn586(); ni_attn586();
WAIT_4_SCB_CMD(); /* wait for accept cmd. */ WAIT_4_SCB_CMD(); /* wait for accept cmd. */
...@@ -1081,7 +1081,7 @@ static void set_multicast_list(struct device *dev, int num_addrs, void *addrs) ...@@ -1081,7 +1081,7 @@ static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
{ {
if(!dev->start && !num_addrs) if(!dev->start && !num_addrs)
{ {
printk("%s: Can't apply promiscous/multicastmode to a not running interface.\n",dev->name); printk("%s: Can't apply promiscuous/multicastmode to a not running interface.\n",dev->name);
return; return;
} }
......
This diff is collapsed.
/* /*
* eata.c - Low-level driver for EATA/DMA SCSI host adapters. * eata.c - Low-level driver for EATA/DMA SCSI host adapters.
* *
* 8 Feb 1995 rev. 1.15 for linux 1.1.89
* Cleared target_time_out counter while preforming a reset.
* All external symbols renamed to avoid possible name conflicts.
*
* 28 Jan 1995 rev. 1.14 for linux 1.1.86 * 28 Jan 1995 rev. 1.14 for linux 1.1.86
* Added module support. * Added module support.
* Log and do a retry when a disk drive returns a target status * Log and do a retry when a disk drive returns a target status
...@@ -41,7 +45,7 @@ ...@@ -41,7 +45,7 @@
* This driver is based on the CAM (Common Access Method Committee) * This driver is based on the CAM (Common Access Method Committee)
* EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol. * EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
* *
* Released by Dario Ballabio (Dario_Ballabio@milano.europe.dg.com) * Copyright (C) 1994, 1995 Dario Ballabio (dario@milano.europe.dg.com)
* *
*/ */
...@@ -89,6 +93,7 @@ ...@@ -89,6 +93,7 @@
#if defined(MODULE) #if defined(MODULE)
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h>
#endif #endif
#include <linux/string.h> #include <linux/string.h>
...@@ -288,7 +293,7 @@ static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ]; ...@@ -288,7 +293,7 @@ static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
#define HD(board) ((struct hostdata *) &sh[board]->hostdata) #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
#define BN(board) (HD(board)->board_name) #define BN(board) (HD(board)->board_name)
static void eata_interrupt_handler(int, struct pt_regs *); static void eata2x_interrupt_handler(int, struct pt_regs *);
static int do_trace = FALSE; static int do_trace = FALSE;
static inline unchar wait_on_busy(ushort iobase) { static inline unchar wait_on_busy(ushort iobase) {
...@@ -411,7 +416,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, ...@@ -411,7 +416,7 @@ static inline int port_detect(ushort *port_base, unsigned int j,
/* Board detected, allocate its IRQ if not already done */ /* Board detected, allocate its IRQ if not already done */
if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
(irq, eata_interrupt_handler, SA_INTERRUPT, driver_name))) { (irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name))) {
printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq); printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
return FALSE; return FALSE;
} }
...@@ -461,12 +466,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, ...@@ -461,12 +466,7 @@ static inline int port_detect(ushort *port_base, unsigned int j,
if (HD(j)->subversion == ESA) if (HD(j)->subversion == ESA)
sh[j]->unchecked_isa_dma = FALSE; sh[j]->unchecked_isa_dma = FALSE;
else { else {
#if !defined(MODULE)
/* The module code does not checkin/checkout in the blocking list yet */
sh[j]->block = sh[j]; sh[j]->block = sh[j];
#endif
sh[j]->unchecked_isa_dma = TRUE; sh[j]->unchecked_isa_dma = TRUE;
disable_dma(dma_channel); disable_dma(dma_channel);
clear_dma_ff(dma_channel); clear_dma_ff(dma_channel);
...@@ -507,7 +507,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, ...@@ -507,7 +507,7 @@ static inline int port_detect(ushort *port_base, unsigned int j,
return TRUE; return TRUE;
} }
int eata_detect (Scsi_Host_Template * tpnt) { int eata2x_detect (Scsi_Host_Template * tpnt) {
unsigned int j = 0, k, flags; unsigned int j = 0, k, flags;
ushort io_port[] = { ushort io_port[] = {
...@@ -535,6 +535,9 @@ int eata_detect (Scsi_Host_Template * tpnt) { ...@@ -535,6 +535,9 @@ int eata_detect (Scsi_Host_Template * tpnt) {
port_base++; port_base++;
} }
if (j > 0)
printk("EATA/DMA 2.0x: Copyright (C) 1994, 1995 Dario Ballabio.\n");
restore_flags(flags); restore_flags(flags);
return j; return j;
} }
...@@ -554,7 +557,7 @@ static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) { ...@@ -554,7 +557,7 @@ static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
cpp->data_len = htonl((SCpnt->use_sg * sizeof(struct sg_list))); cpp->data_len = htonl((SCpnt->use_sg * sizeof(struct sg_list)));
} }
int eata_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
unsigned int i, j, k, flags; unsigned int i, j, k, flags;
struct mscp *cpp; struct mscp *cpp;
struct mssp *spp; struct mssp *spp;
...@@ -585,7 +588,7 @@ int eata_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { ...@@ -585,7 +588,7 @@ int eata_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
if (HD(j)->in_reset) if (HD(j)->in_reset)
printk("%s: qcomm, already in reset.\n", BN(j)); printk("%s: qcomm, already in reset.\n", BN(j));
else if (eata_reset(SCpnt) == SCSI_RESET_SUCCESS) else if (eata2x_reset(SCpnt) == SCSI_RESET_SUCCESS)
panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j)); panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j));
SCpnt->result = DID_BUS_BUSY << 16; SCpnt->result = DID_BUS_BUSY << 16;
...@@ -657,7 +660,7 @@ int eata_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { ...@@ -657,7 +660,7 @@ int eata_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
return 0; return 0;
} }
int eata_abort (Scsi_Cmnd *SCarg) { int eata2x_abort (Scsi_Cmnd *SCarg) {
unsigned int i, j, flags; unsigned int i, j, flags;
save_flags(flags); save_flags(flags);
...@@ -715,7 +718,7 @@ int eata_abort (Scsi_Cmnd *SCarg) { ...@@ -715,7 +718,7 @@ int eata_abort (Scsi_Cmnd *SCarg) {
panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
} }
int eata_reset (Scsi_Cmnd *SCarg) { int eata2x_reset (Scsi_Cmnd *SCarg) {
unsigned int i, j, flags, time, k, limit = 0; unsigned int i, j, flags, time, k, limit = 0;
int arg_done = FALSE; int arg_done = FALSE;
Scsi_Cmnd *SCpnt; Scsi_Cmnd *SCpnt;
...@@ -743,6 +746,8 @@ int eata_reset (Scsi_Cmnd *SCarg) { ...@@ -743,6 +746,8 @@ int eata_reset (Scsi_Cmnd *SCarg) {
for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE; for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
for (i = 0; i < sh[j]->can_queue; i++) { for (i = 0; i < sh[j]->can_queue; i++) {
if (HD(j)->cp_stat[i] == FREE) continue; if (HD(j)->cp_stat[i] == FREE) continue;
...@@ -784,7 +789,7 @@ int eata_reset (Scsi_Cmnd *SCarg) { ...@@ -784,7 +789,7 @@ int eata_reset (Scsi_Cmnd *SCarg) {
HD(j)->in_reset = TRUE; HD(j)->in_reset = TRUE;
sti(); sti();
time = jiffies; time = jiffies;
while (jiffies < (time + 200) && limit++ < 100000000) sti(); while (jiffies < (time + 100) && limit++ < 100000000);
cli(); cli();
printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
...@@ -821,7 +826,7 @@ int eata_reset (Scsi_Cmnd *SCarg) { ...@@ -821,7 +826,7 @@ int eata_reset (Scsi_Cmnd *SCarg) {
} }
} }
static void eata_interrupt_handler(int irq, struct pt_regs * regs) { static void eata2x_interrupt_handler(int irq, struct pt_regs * regs) {
Scsi_Cmnd *SCpnt; Scsi_Cmnd *SCpnt;
unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0; unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
struct mssp *spp; struct mssp *spp;
...@@ -928,8 +933,7 @@ static void eata_interrupt_handler(int irq, struct pt_regs * regs) { ...@@ -928,8 +933,7 @@ static void eata_interrupt_handler(int irq, struct pt_regs * regs) {
status = DID_BUS_BUSY << 16; status = DID_BUS_BUSY << 16;
else if (tstatus == CHECK_CONDITION else if (tstatus == CHECK_CONDITION
&& (SCpnt->device->type == TYPE_DISK && SCpnt->device->type == TYPE_DISK
|| SCpnt->device->type == TYPE_ROM)
&& (SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) && (SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION)
status = DID_ERROR << 16; status = DID_ERROR << 16;
...@@ -939,8 +943,7 @@ static void eata_interrupt_handler(int irq, struct pt_regs * regs) { ...@@ -939,8 +943,7 @@ static void eata_interrupt_handler(int irq, struct pt_regs * regs) {
if (tstatus == GOOD) if (tstatus == GOOD)
HD(j)->target_reset[SCpnt->target] = FALSE; HD(j)->target_reset[SCpnt->target] = FALSE;
if (spp->target_status && (SCpnt->device->type == TYPE_DISK if (spp->target_status && SCpnt->device->type == TYPE_DISK)
|| SCpnt->device->type == TYPE_ROM))
printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\ printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
"0x%x, sense key 0x%x.\n", BN(j), "0x%x, sense key 0x%x.\n", BN(j),
SCpnt->target, SCpnt->lun, SCpnt->pid, SCpnt->target, SCpnt->lun, SCpnt->pid,
......
...@@ -7,24 +7,24 @@ ...@@ -7,24 +7,24 @@
#include <linux/scsicam.h> #include <linux/scsicam.h>
#define EATA_VERSION "1.14.03" #define EATA_VERSION "1.15.00"
int eata_detect(Scsi_Host_Template *); int eata2x_detect(Scsi_Host_Template *);
int eata_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int eata_abort(Scsi_Cmnd *); int eata2x_abort(Scsi_Cmnd *);
int eata_reset(Scsi_Cmnd *); int eata2x_reset(Scsi_Cmnd *);
#define EATA { NULL, /* Ptr for modules */ \ #define EATA { \
NULL, /* Ptr for modules */ \
NULL, /* usage count for modules */ \ NULL, /* usage count for modules */ \
"EATA/DMA 2.0 rev. " EATA_VERSION " by " \ "EATA/DMA 2.0x rev. " EATA_VERSION " ", \
"Dario_Ballabio@milano.europe.dg.com.", \ eata2x_detect, \
eata_detect, \
NULL, /* Release */ \ NULL, /* Release */ \
NULL, \ NULL, \
NULL, \ NULL, \
eata_queuecommand, \ eata2x_queuecommand, \
eata_abort, \ eata2x_abort, \
eata_reset, \ eata2x_reset, \
NULL, \ NULL, \
scsicam_bios_param, \ scsicam_bios_param, \
0, /* can_queue, reset by detect */ \ 0, /* can_queue, reset by detect */ \
......
...@@ -137,7 +137,7 @@ int eata_release(struct Scsi_Host *); ...@@ -137,7 +137,7 @@ int eata_release(struct Scsi_Host *);
#define C_P_L_DIV 4 /* 1 <= C_P_L_DIV <= 8 #define C_P_L_DIV 4 /* 1 <= C_P_L_DIV <= 8
* You can use this parameter to fine-tune * You can use this parameter to fine-tune
* the driver. Depending on the number of * the driver. Depending on the number of
* devices and their ablilty to queue commands * devices and their ability to queue commands
* you will get the best results with a value * you will get the best results with a value
* ~= numdevices-(devices_unable_to_queue_commands/2) * ~= numdevices-(devices_unable_to_queue_commands/2)
* The reason for this is that the disk driver tents * The reason for this is that the disk driver tents
......
...@@ -221,7 +221,7 @@ scsi_unregister(struct Scsi_Host * sh){ ...@@ -221,7 +221,7 @@ scsi_unregister(struct Scsi_Host * sh){
j = sh->extra_bytes; j = sh->extra_bytes;
if(scsi_hostlist == sh) if(scsi_hostlist == sh)
scsi_hostlist = NULL; scsi_hostlist = sh->next;
else { else {
shpnt = scsi_hostlist; shpnt = scsi_hostlist;
while(shpnt->next != sh) shpnt = shpnt->next; while(shpnt->next != sh) shpnt = shpnt->next;
...@@ -244,7 +244,8 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){ ...@@ -244,7 +244,8 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
if(j > 0xffff) panic("Too many extra bytes requested\n"); if(j > 0xffff) panic("Too many extra bytes requested\n");
retval->extra_bytes = j; retval->extra_bytes = j;
retval->loaded_as_module = scsi_loadable_module_flag; retval->loaded_as_module = scsi_loadable_module_flag;
retval->host_no = next_scsi_host++; retval->host_no = max_scsi_hosts++; /* never reuse host_no (DB) */
next_scsi_host++;
retval->host_queue = NULL; retval->host_queue = NULL;
retval->host_wait = NULL; retval->host_wait = NULL;
retval->last_reset = 0; retval->last_reset = 0;
...@@ -339,29 +340,7 @@ unsigned int scsi_init() ...@@ -339,29 +340,7 @@ unsigned int scsi_init()
printk ("scsi : %d host%s.\n", next_scsi_host, printk ("scsi : %d host%s.\n", next_scsi_host,
(next_scsi_host == 1) ? "" : "s"); (next_scsi_host == 1) ? "" : "s");
{ scsi_make_blocked_list();
int block_count = 0, index;
struct Scsi_Host * sh[128], * shpnt;
for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next)
if (shpnt->block) sh[block_count++] = shpnt;
if (block_count == 1) sh[0]->block = NULL;
else if (block_count > 1) {
for(index = 0; index < block_count - 1; index++) {
sh[index]->block = sh[index + 1];
printk("scsi%d : added to blocked host list.\n",
sh[index]->host_no);
}
sh[block_count - 1]->block = sh[0];
printk("scsi%d : added to blocked host list.\n",
sh[index]->host_no);
}
}
/* Now attach the high level drivers */ /* Now attach the high level drivers */
#ifdef CONFIG_BLK_DEV_SD #ifdef CONFIG_BLK_DEV_SD
...@@ -377,7 +356,9 @@ unsigned int scsi_init() ...@@ -377,7 +356,9 @@ unsigned int scsi_init()
scsi_register_device(&sg_template); scsi_register_device(&sg_template);
#endif #endif
#if 0
max_scsi_hosts = next_scsi_host; max_scsi_hosts = next_scsi_host;
#endif
return 0; return 0;
} }
......
...@@ -280,11 +280,11 @@ sub parse_conditional { ...@@ -280,11 +280,11 @@ sub parse_conditional {
$conditional = $1; $conditional = $1;
print STDERR "$0 : parsed ATN\n" if ($debug); print STDERR "$0 : parsed ATN\n" if ($debug);
} elsif ($conditional =~ /^($phase)\s*(.*)/i) { } elsif ($conditional =~ /^($phase)\s*(.*)/i) {
$1 = "\U$1\E"; $phase_index = "\U$1\E";
$p = $scsi_phases{$1}; $p = $scsi_phases{$phase_index};
$code[$address] |= $p | 0x00_02_00_00; $code[$address] |= $p | 0x00_02_00_00;
$conditional = $2; $conditional = $2;
print STDERR "$0 : parsed phase $1\n" if ($debug); print STDERR "$0 : parsed phase $phase_index\n" if ($debug);
} else { } else {
$other = ''; $other = '';
$need_data = 1; $need_data = 1;
...@@ -378,16 +378,17 @@ while (<STDIN>) { ...@@ -378,16 +378,17 @@ while (<STDIN>) {
$rest = $2; $rest = $2;
foreach $rest (split (/\s*,\s*/, $rest)) { foreach $rest (split (/\s*,\s*/, $rest)) {
if ($rest =~ /^($identifier)\s*=\s*($constant)\s*$/) { if ($rest =~ /^($identifier)\s*=\s*($constant)\s*$/) {
if ($symbol_values{$1} eq undef) { local ($id, $cnst) = ($1, $2);
$symbol_values{$1} = eval $2; if ($symbol_values{$id} eq undef) {
delete $forward{$1}; $symbol_values{$id} = eval $cnst;
delete $forward{$id};
if ($is_absolute =~ /ABSOLUTE/i) { if ($is_absolute =~ /ABSOLUTE/i) {
push (@absolute , $1); push (@absolute , $id);
} else { } else {
push (@relative, $1); push (@relative, $id);
} }
} else { } else {
die "$0 : redefinition of symbol $1 in line $lineno : $_\n"; die "$0 : redefinition of symbol $id in line $lineno : $_\n";
} }
} else { } else {
die die
......
This diff is collapsed.
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
#define MODE_SELECT_10 0x55 #define MODE_SELECT_10 0x55
#define MODE_SENSE_10 0x5a #define MODE_SENSE_10 0x5a
extern void scsi_make_blocked_list(void);
extern volatile int in_scan_scsis; extern volatile int in_scan_scsis;
extern const unsigned char scsi_command_size[8]; extern const unsigned char scsi_command_size[8];
#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7] #define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
...@@ -528,6 +529,7 @@ extern int scsi_reset (Scsi_Cmnd *); ...@@ -528,6 +529,7 @@ extern int scsi_reset (Scsi_Cmnd *);
extern int max_scsi_hosts; extern int max_scsi_hosts;
#if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR) #if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR)
#include "hosts.h"
static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors) static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
{ {
struct request * req; struct request * req;
...@@ -566,6 +568,15 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors ...@@ -566,6 +568,15 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors
if (req->sem != NULL) { if (req->sem != NULL) {
up(req->sem); up(req->sem);
} }
if (SCpnt->host->block) {
struct Scsi_Host * next;
for (next = SCpnt->host->block; next != SCpnt->host;
next = next->block)
wake_up(&next->host_wait);
}
req->dev = -1; req->dev = -1;
wake_up(&wait_for_request); wake_up(&wait_for_request);
wake_up(&SCpnt->device->device_wait); wake_up(&SCpnt->device->device_wait);
...@@ -595,11 +606,16 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors ...@@ -595,11 +606,16 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors
if (CONDITION) { \ if (CONDITION) { \
struct wait_queue wait = { current, NULL}; \ struct wait_queue wait = { current, NULL}; \
add_wait_queue(QUEUE, &wait); \ add_wait_queue(QUEUE, &wait); \
sleep_repeat: \ for(;;) { \
current->state = TASK_UNINTERRUPTIBLE; \ current->state = TASK_UNINTERRUPTIBLE; \
if (CONDITION) { \ if (CONDITION) { \
schedule(); \ if (intr_count) \
goto sleep_repeat; \ panic("scsi: trying to call schedule() in interrupt" \
", file %s, line %d.\n", __FILE__, __LINE__); \
schedule(); \
} \
else \
break; \
} \ } \
remove_wait_queue(QUEUE, &wait); \ remove_wait_queue(QUEUE, &wait); \
current->state = TASK_RUNNING; \ current->state = TASK_RUNNING; \
......
...@@ -293,19 +293,11 @@ static void rw_intr (Scsi_Cmnd * SCpnt) ...@@ -293,19 +293,11 @@ static void rw_intr (Scsi_Cmnd * SCpnt)
* *
* - TOSHIBA: setting density is done here now, mounting PhotoCD's should * - TOSHIBA: setting density is done here now, mounting PhotoCD's should
* work now without running the program "set_density" * work now without running the program "set_density"
* People reported that it is necessary to eject and reinsert
* the CD after the set-density call to get this working for
* old drives.
* And some very new drives don't need this call any more...
* Multisession CD's are supported too. * Multisession CD's are supported too.
* *
* Dec 1994: completely rewritten, uses kernel_scsi_ioctl() now
*
* kraxel@cs.tu-berlin.de (Gerd Knorr) * kraxel@cs.tu-berlin.de (Gerd Knorr)
*/ */
#define DEBUG
static void sr_photocd(struct inode *inode) static void sr_photocd(struct inode *inode)
{ {
unsigned long sector,min,sec,frame; unsigned long sector,min,sec,frame;
...@@ -345,12 +337,14 @@ static void sr_photocd(struct inode *inode) ...@@ -345,12 +337,14 @@ static void sr_photocd(struct inode *inode)
if (rc != 0) { if (rc != 0) {
printk("sr_photocd: ioctl error (NEC): 0x%x\n",rc); printk("sr_photocd: ioctl error (NEC): 0x%x\n",rc);
sector = 0; sector = 0;
is_xa = 0;
} else { } else {
min = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16; min = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16;
sec = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16; sec = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16;
frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16; frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16;
/* if rec[14] isn't 0xb0, the drive does not support multisession CD's, use zero */ /* if rec[14] isn't 0xb0, the drive does not support multisession CD's, use zero */
sector = (0xb0 == rec[14]) ? min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame : 0; sector = (0xb0 == rec[14]) ? min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame : 0;
is_xa = (rec[14] == 0xb0);
#ifdef DEBUG #ifdef DEBUG
printk("NEC: (%2x) %2li:%02li:%02li = %li\n",buf[8+14],min,sec,frame,sector); printk("NEC: (%2x) %2li:%02li:%02li = %li\n",buf[8+14],min,sec,frame,sector);
if (sector) { if (sector) {
...@@ -377,6 +371,7 @@ static void sr_photocd(struct inode *inode) ...@@ -377,6 +371,7 @@ static void sr_photocd(struct inode *inode)
if (rc != 0) { if (rc != 0) {
printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc); printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
sector = 0; sector = 0;
is_xa = 0;
break; /* if the first ioctl fails, we don't call the second one */ break; /* if the first ioctl fails, we don't call the second one */
} }
is_xa = (rec[0] == 0x20); is_xa = (rec[0] == 0x20);
...@@ -431,6 +426,8 @@ static void sr_photocd(struct inode *inode) ...@@ -431,6 +426,8 @@ static void sr_photocd(struct inode *inode)
if (rc != 0) { if (rc != 0) {
printk("sr_photocd: ioctl error (TOSHIBA #3): 0x%x\n",rc); printk("sr_photocd: ioctl error (TOSHIBA #3): 0x%x\n",rc);
} }
/* The set_density command may have changed the sector size or capacity. */
scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size = 1;
} }
break; break;
...@@ -440,16 +437,14 @@ static void sr_photocd(struct inode *inode) ...@@ -440,16 +437,14 @@ static void sr_photocd(struct inode *inode)
printk("sr_photocd: unknown drive, no special multisession code\n"); printk("sr_photocd: unknown drive, no special multisession code\n");
#endif #endif
sector = 0; sector = 0;
is_xa = 0;
break; } break; }
scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector; scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
/* The code above may have changed the sector size or capacity. */ scsi_CDs[MINOR(inode->i_rdev)].is_xa = is_xa;
scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size = 1;
return; return;
} }
#undef DEBUG
static int sr_open(struct inode * inode, struct file * filp) static int sr_open(struct inode * inode, struct file * filp)
{ {
if(MINOR(inode->i_rdev) >= sr_template.nr_dev || if(MINOR(inode->i_rdev) >= sr_template.nr_dev ||
......
...@@ -25,6 +25,7 @@ typedef struct ...@@ -25,6 +25,7 @@ typedef struct
unsigned sector_size; /* size in bytes */ unsigned sector_size; /* size in bytes */
Scsi_Device *device; Scsi_Device *device;
unsigned long mpcd_sector; /* for reading multisession-CD's */ unsigned long mpcd_sector; /* for reading multisession-CD's */
char is_xa; /* is it an XA-CD ? */
unsigned char sector_bit_size; /* sector size = 2^sector_bit_size */ unsigned char sector_bit_size; /* sector size = 2^sector_bit_size */
unsigned char sector_bit_shift; /* sectors/FS block = 2^sector_bit_shift*/ unsigned char sector_bit_shift; /* sectors/FS block = 2^sector_bit_shift*/
unsigned needs_sector_size:1; /* needs to get sector size */ unsigned needs_sector_size:1; /* needs to get sector size */
......
...@@ -408,11 +408,8 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne ...@@ -408,11 +408,8 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne
ms_info.addr.lba=scsi_CDs[target].mpcd_sector; ms_info.addr.lba=scsi_CDs[target].mpcd_sector;
else return (-EINVAL); else return (-EINVAL);
if (scsi_CDs[target].mpcd_sector) ms_info.xa_flag=scsi_CDs[target].is_xa;
ms_info.xa_flag=1; /* valid redirection address */
else
ms_info.xa_flag=0; /* invalid redirection address */
err=verify_area(VERIFY_WRITE,(void *) arg, err=verify_area(VERIFY_WRITE,(void *) arg,
sizeof(struct cdrom_multisession)); sizeof(struct cdrom_multisession));
if (err) return (err); if (err) return (err);
......
This diff is collapsed.
...@@ -10,15 +10,14 @@ int u14_34f_abort(Scsi_Cmnd *); ...@@ -10,15 +10,14 @@ int u14_34f_abort(Scsi_Cmnd *);
int u14_34f_reset(Scsi_Cmnd *); int u14_34f_reset(Scsi_Cmnd *);
int u14_34f_biosparam(Disk *, int, int *); int u14_34f_biosparam(Disk *, int, int *);
#define U14_34F_VERSION "1.14.05" #define U14_34F_VERSION "1.15.00"
#define ULTRASTOR_14_34F { \ #define ULTRASTOR_14_34F { \
NULL, \ NULL, /* Ptr for modules */ \
NULL, \ NULL, /* usage count for modules */ \
"UltraStor 14F/34F rev. " U14_34F_VERSION " by " \ "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \
"Dario_Ballabio@milano.europe.dg.com.", \
u14_34f_detect, \ u14_34f_detect, \
NULL, \ NULL, /* Release */ \
NULL, \ NULL, \
NULL, \ NULL, \
u14_34f_queuecommand, \ u14_34f_queuecommand, \
......
...@@ -74,7 +74,13 @@ Hannu Savolainen ...@@ -74,7 +74,13 @@ Hannu Savolainen
hannu@voxware.pp.fi hannu@voxware.pp.fi
Snail mail: Hannu Savolainen Snail mail: Hannu Savolainen
Pallaksentie 4 A 2 Hiekkalaiturintie 3 A 8
00970 Helsinki 00980 Helsinki
Finland Finland
FAX: +358 0 395 1968 (usually not connected) FAX: +358 0 341 6272 (answers if I have my machine (mgetty) on).
NOTE! I propably don't answer to Snail mail or FAX messages. Sending answer
to each of them is simply too expensive and time consuming. However I
try to reply every email message I get (within a week). If you don't
get response, please check how your address is written in the message
header. I can't answer if I don't have a valid reply address.
This diff is collapsed.
...@@ -37,9 +37,6 @@ ...@@ -37,9 +37,6 @@
* ***FIXME*** should probably put this in nfs_fs.h */ * ***FIXME*** should probably put this in nfs_fs.h */
#define NFS_SLACK_SPACE 1024 #define NFS_SLACK_SPACE 1024
extern struct socket *socki_lookup(struct inode *inode);
#define _S(nr) (1<<((nr)-1)) #define _S(nr) (1<<((nr)-1))
/* /*
...@@ -81,7 +78,7 @@ static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end, int ...@@ -81,7 +78,7 @@ static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end, int
file = server->file; file = server->file;
inode = file->f_inode; inode = file->f_inode;
select = file->f_op->select; select = file->f_op->select;
sock = socki_lookup(inode); sock = &inode->u.socket_i;
if (!sock) { if (!sock) {
printk("nfs_rpc_call: socki_lookup failed\n"); printk("nfs_rpc_call: socki_lookup failed\n");
return -EBADF; return -EBADF;
......
...@@ -94,7 +94,7 @@ static void check_fpu(void) ...@@ -94,7 +94,7 @@ static void check_fpu(void)
return; return;
} }
printk("Ok, FDIV bug i%c86 system\n", '0'+x86); printk("Hmm, FDIV bug i%c86 system\n", '0'+x86);
} }
static void check_hlt(void) static void check_hlt(void)
......
/* cprefix.h: This file is included by assembly source which needs /* cprefix.h: This file is included by assembly source which needs
* to know what the c-label prefixes are. The newer versions * to know what the c-label prefixes are. The newer versions
* of cpp that come with gcc predefine such things to help * of cpp that come with gcc predefine such things to help
* us out. The reason this stuff is neaded is to make * us out. The reason this stuff is needed is to make
* solaris compiles of the kernel work. * solaris compiles of the kernel work.
* *
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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