Commit 7eb2fd0c authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.15

parent 1650f8d3
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 14
SUBLEVEL = 15
all: Version zImage
......
......@@ -50,13 +50,16 @@ comment 'SCSI low-level drivers'
bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n
bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 y
bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n
bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n
bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n
bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n
#bool 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 n
bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n
bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n
bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n
bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n
bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST n
#bool 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n
fi
......
This diff is collapsed.
......@@ -11,6 +11,14 @@
AHA152X = -DDEBUG_AHA152X -DAUTOCONF
ifeq (${CFLAGS},)
CFLAGS = -D__KERNEL__=1 \
-Wall -Wstrict-prototypes -I. -I../../include \
-O2 -fomit-frame-pointer -m486
include ../../.config
endif
SCSI_OBJS =
SCSI_SRCS =
......@@ -54,6 +62,11 @@ SCSI_OBJS := $(SCSI_OBJS) aha1740.o
SCSI_SRCS := $(SCSI_SRCS) aha1740.c
endif
ifdef CONFIG_SCSI_BUSLOGIC
SCSI_OBJS := $(SCSI_OBJS) buslogic.o
SCSI_SRCS := $(SCSI_SRCS) buslogic.c
endif
ifdef CONFIG_SCSI_DEBUG
SCSI_OBJS := $(SCSI_OBJS) scsi_debug.o
SCSI_SRCS := $(SCSI_SRCS) scsi_debug.c
......@@ -64,6 +77,11 @@ SCSI_OBJS := $(SCSI_OBJS) fdomain.o
SCSI_SRCS := $(SCSI_SRCS) fdomain.c
endif
ifdef CONFIG_SCSI_IN2000
SCSI_OBJS := $(SCSI_OBJS) in2000.o
SCSI_SRCS := $(SCSI_SRCS) in2000.c
endif
ifdef CONFIG_SCSI_GENERIC_NCR5380
SCSI_OBJS := $(SCSI_OBJS) g_NCR5380.o
SCSI_SRCS := $(SCSI_SRCS) g_NCR5380.c
......
......@@ -2266,7 +2266,7 @@ static void NCR5380_dma_complete (NCR5380_instance *instance) {
#endif /* def REAL_DMA */
/*
* Function : int NCR5380_abort (Scsi_Cmnd *cmd, int code)
* Function : int NCR5380_abort (Scsi_Cmnd *cmd)
*
* Purpose : abort a command
*
......@@ -2285,7 +2285,7 @@ static void NCR5380_dma_complete (NCR5380_instance *instance) {
#ifndef NCR5380_abort
static
#endif
int NCR5380_abort (Scsi_Cmnd *cmd, int code) {
int NCR5380_abort (Scsi_Cmnd *cmd) {
NCR5380_local_declare();
struct Scsi_Host *instance = cmd->host;
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
......@@ -2313,14 +2313,14 @@ int NCR5380_abort (Scsi_Cmnd *cmd, int code) {
if (cmd == tmp) {
(*prev) = (Scsi_Cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
tmp->result = (code ? code : DID_ABORT) << 16;
tmp->result = DID_ABORT << 16;
sti();
#if (NDEBUG & NDEBUG_ABORT)
printk("scsi%d : abort removed command from issue queue.\n",
instance->host_no);
#endif
tmp->done(tmp);
return 0;
return SCSI_ABORT_SUCCESS;
}
/*
......@@ -2339,7 +2339,7 @@ int NCR5380_abort (Scsi_Cmnd *cmd, int code) {
#if (NDEBUG & NDEBUG_ABORT)
printk("scsi%d : abort failed, command connected.\n", instance->host_no);
#endif
return -1;
return SCSI_ABORT_NOT_RUNNING;
}
/*
......@@ -2376,7 +2376,7 @@ int NCR5380_abort (Scsi_Cmnd *cmd, int code) {
#endif
if (NCR5380_select (instance, cmd, (int) cmd->tag))
return 1;
return SCSI_ABORT_BUSY;
#if (NDEBUG & NDEBUG_ABORT)
printk("scsi%d : nexus restablished.\n", instance->host_no);
......@@ -2397,10 +2397,10 @@ int NCR5380_abort (Scsi_Cmnd *cmd, int code) {
if (cmd == tmp) {
*prev = (Scsi_Cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
tmp->result = (code ? code : DID_ABORT) << 16;
tmp->result = DID_ABORT << 16;
sti();
tmp->done(tmp);
return 0;
return SCSI_ABORT_SUCCESS;
}
}
......@@ -2417,7 +2417,7 @@ int NCR5380_abort (Scsi_Cmnd *cmd, int code) {
sti();
printk("scsi%d : warning : SCSI command probably completed successfully\n"
" before abortion\n", instance->host_no);
return 0;
return SCSI_ABORT_NOT_RUNNING;
}
......
......@@ -249,7 +249,7 @@ static void NCR5380_print_options (struct Scsi_Host *instance);
#ifndef NCR5380_abort
static
#endif
int NCR5380_abort (Scsi_Cmnd *cmd, int code);
int NCR5380_abort (Scsi_Cmnd *cmd);
#ifndef NCR5380_reset
static
#endif
......
......@@ -155,7 +155,7 @@
Drew Eckhardt (drew@cs.colorado.edu)
Eric Youngdale (eric@tantalus.nrl.navy.mil)
Eric Youngdale (ericy@cais.com)
special thanks to Eric Youngdale for the free(!) supplying the
documentation on the chip.
......@@ -781,7 +781,7 @@ int aha152x_command( Scsi_Cmnd *SCpnt )
* Abort a queued command
* (commands that are on the bus can't be aborted easily)
*/
int aha152x_abort( Scsi_Cmnd *SCpnt, int code )
int aha152x_abort( Scsi_Cmnd *SCpnt)
{
Scsi_Cmnd *ptr, *prev;
......@@ -809,16 +809,16 @@ int aha152x_abort( Scsi_Cmnd *SCpnt, int code )
sti();
ptr->host_scribble = NULL;
ptr->result = (code ? code : DID_ABORT ) << 16;
ptr->result = DID_ABORT << 16;
ptr->done(ptr);
return 0;
return SCSI_ABORT_SUCCESS;
}
/* Fail abortion, if we're on the bus */
if (current_SC)
{
sti();
return -1;
return SCSI_ABORT_BUSY;
}
/* look for command in disconnected queue */
......@@ -852,7 +852,7 @@ int aha152x_abort( Scsi_Cmnd *SCpnt, int code )
SETBITS(SCSISEQ, ENSELO | ENAUTOATNO );
SETBITS( DMACNTRL0, INTEN );
abort_result=0;
abort_result=SCSI_ABORT_SUCCESS;
sti();
/* sleep until the abortion is complete */
......@@ -864,7 +864,7 @@ int aha152x_abort( Scsi_Cmnd *SCpnt, int code )
/* command wasn't found */
sti();
return 0;
return SCSI_ABORT_NOT_RUNNING;
}
/*
......@@ -922,6 +922,10 @@ int aha152x_reset(Scsi_Cmnd * __unused)
show_queues();
/* FIXME - if the device implements soft resets, the command will still
be running after the bus reset. In this case we should do nothing
and let the command continue. -ERY */
if(current_SC)
{
current_SC->host_scribble = NULL;
......@@ -951,7 +955,7 @@ int aha152x_reset(Scsi_Cmnd * __unused)
SETPORT( DMACNTRL0, INTEN );
}
return 0;
return SCSI_RESET_SUCCESS;
}
/*
......@@ -1246,7 +1250,7 @@ void aha152x_intr( int irqno )
if(current_SC->SCp.phase & aborted)
{
abort_result=1;
abort_result=SCSI_ABORT_ERROR;
wake_up( &abortion_complete );
}
......@@ -1304,7 +1308,7 @@ void aha152x_intr( int irqno )
#if defined(DEBUG_ABORT)
printk("(ABORT) selection timeout, ");
#endif
abort_result=1;
abort_result=SCSI_ABORT_ERROR;
wake_up( &abortion_complete );
}
......@@ -1390,7 +1394,7 @@ void aha152x_intr( int irqno )
if(message==ABORT)
{
/* revive abort(); abort() enables interrupts */
abort_result=0;
abort_result=SCSI_ABORT_SUCCESS;
wake_up( &abortion_complete );
current_SC->SCp.phase = (current_SC->SCp.phase & ~(P_MASK<<16));
......
......@@ -14,7 +14,7 @@ int aha152x_detect(int);
const char *aha152x_info(void);
int aha152x_command(Scsi_Cmnd *);
int aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int aha152x_abort(Scsi_Cmnd *, int);
int aha152x_abort(Scsi_Cmnd *);
int aha152x_reset(Scsi_Cmnd *);
int aha152x_biosparam(int, int, int*);
......@@ -39,7 +39,8 @@ int aha152x_biosparam(int, int, int*);
/* sg_tablesize */ SG_ALL, \
/* cmd_per_lun */ 1, \
/* present */ 0, \
/* unchecked_isa_dma */ 0 }
/* unchecked_isa_dma */ 0, \
/* use_clustering */ DISABLE_CLUSTERING }
#endif
......
......@@ -2,6 +2,7 @@
* linux/kernel/aha1542.c
*
* Copyright (C) 1992 Tommy Thorn
* Copyright (C) 1993, 1994 Eric Youngdale
*
* Modified by Eric Youngdale
* Use request_irq and request_dma to help prevent unexpected conflicts
......@@ -75,6 +76,7 @@ static struct Scsi_Host * aha_host[7] = {NULL,}; /* One for each IRQ level (9-1
#define WAITnexttimeout 3000000
static void setup_mailboxes(int base_io, struct Scsi_Host * shpnt);
static int aha1542_restart(struct Scsi_Host * shost);
#define aha1542_intr_reset(base) outb(IRST, CONTROL(base))
......@@ -215,7 +217,9 @@ static int aha1542_test_port(int bse, struct Scsi_Host * shpnt)
/* Reset the adapter. I ought to make a hard reset, but it's not really nessesary */
/* DEB(printk("aha1542_test_port called \n")); */
/* In case some other card was probing here, reset interrupts */
aha1542_intr_reset(bse); /* reset interrupts, so they don't block */
outb(SRST|IRST/*|SCRST*/, CONTROL(bse));
i = jiffies + 2;
......@@ -259,7 +263,7 @@ static int aha1542_test_port(int bse, struct Scsi_Host * shpnt)
outb(IRST, CONTROL(bse));
debug = 11;
return debug; /* 1 = ok */
fail:
return 0; /* 0 = not ok */
......@@ -281,7 +285,8 @@ static void aha1542_intr_handle(int foo)
int number_serviced;
struct Scsi_Host * shost;
Scsi_Cmnd * SCtmp;
int irqno, * irqp;
int irqno, * irqp, flag;
int needs_restart;
struct mailbox * mb;
struct ccb *ccb;
......@@ -297,7 +302,7 @@ static void aha1542_intr_handle(int foo)
#ifdef DEBUG
{
int flag = inb(INTRFLAGS(shost->io_port));
flag = inb(INTRFLAGS(shost->io_port));
printk("aha1542_intr_handle: ");
if (!(flag&ANYINTR)) printk("no interrupt?");
if (flag&MBIF) printk("MBIF ");
......@@ -308,8 +313,24 @@ static void aha1542_intr_handle(int foo)
};
#endif
number_serviced = 0;
needs_restart = 0;
while(1==1){
flag = inb(INTRFLAGS(shost->io_port));
/* Check for unusual interrupts. If any of these happen, we should
probably do something special, but for now just printing a message
is sufficient. A SCSI reset detected is something that we really
need to deal with in some way. */
if (flag & ~MBIF) {
if (flag&MBOA) printk("MBOF ");
if (flag&HACC) printk("HACC ");
if (flag&SCRD) {
needs_restart = 1;
printk("SCRD ");
}
}
aha1542_intr_reset(shost->io_port);
cli();
......@@ -325,8 +346,11 @@ static void aha1542_intr_handle(int foo)
if(mb[mbi].status == 0){
sti();
/* Hmm, no mail. Must have read it the last time around */
if (number_serviced) return;
printk("aha1542.c: interrupt received, but no mail.\n");
if (!number_serviced && !needs_restart)
printk("aha1542.c: interrupt received, but no mail.\n");
/* We detected a reset. Restart all pending commands for
devices that use the hard reset option */
if(needs_restart) aha1542_restart(shost);
return;
};
......@@ -354,6 +378,8 @@ static void aha1542_intr_handle(int foo)
if (!SCtmp || !SCtmp->scsi_done) {
printk("aha1542_intr_handle: Unexpected interrupt\n");
printk("tarstat=%x, hastat=%x idlun=%x ccb#=%d \n", ccb[mbo].tarstat,
ccb[mbo].hastat, ccb[mbo].idlun, mbo);
return;
}
......@@ -883,39 +909,156 @@ int aha1542_detect(int hostnum)
return count;
}
static int aha1542_restart(struct Scsi_Host * shost)
{
int i;
int count = 0;
#if 0
unchar ahacmd = CMD_START_SCSI;
#endif
for(i=0; i< AHA1542_MAILBOXES; i++)
if(HOSTDATA(shost)->SCint[i] &&
!(HOSTDATA(shost)->SCint[i]->device->soft_reset))
{
#if 0
HOSTDATA(shost)->mb[i].status = 1; /* Indicate ready to restart... */
#endif
count++;
}
printk("Potential to restart %d stalled commands...\n", count);
#if 0
/* start scsi command */
if (count) aha1542_out(shost->io_port, &ahacmd, 1);
#endif
return 0;
}
/* The abort command does not leave the device in a clean state where
it is available to be used again. Until this gets worked out, we will
leave it commented out. */
int aha1542_abort(Scsi_Cmnd * SCpnt, int i)
int aha1542_abort(Scsi_Cmnd * SCpnt)
{
#if 0
unchar ahacmd = CMD_START_SCSI;
int mbo;
int intval[3];
unchar ahacmd = CMD_START_SCSI;
struct mailbox * mb;
int mbi, mbo, i;
printk("In aha1542_abort: %x %x\n",
inb(STATUS(SCpnt->host->io_port)),
inb(INTRFLAGS(SCpnt->host->io_port)));
cli();
mb = HOSTDATA(SCpnt->host)->mb;
mbi = HOSTDATA(SCpnt->host)->aha1542_last_mbi_used + 1;
if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
do{
if(mb[mbi].status != 0) break;
mbi++;
if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
} while (mbi != HOSTDATA(SCpnt->host)->aha1542_last_mbi_used);
sti();
if(mb[mbi].status) {
printk("Lost interrupt discovered on irq %d - attempting to recover\n",
SCpnt->host->irq);
intval[0] = SCpnt->host->irq;
aha1542_intr_handle((int) &intval[2]);
return 0;
}
/* OK, no lost interrupt. Try looking to see how many pending commands
we think we have. */
for(i=0; i< AHA1542_MAILBOXES; i++)
if(HOSTDATA(SCpnt->host)->SCint[i])
{
if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
printk("Timed out command pending for %4.4x\n", SCpnt->request.dev);
if (HOSTDATA(SCpnt->host)->mb[i].status) {
printk("OGMB still full - restarting\n");
aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
};
} else
printk("Other pending command %4.4x\n", SCpnt->request.dev);
}
#endif
DEB(printk("aha1542_abort\n"));
#if 0
cli();
for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++)
if (SCpnt == HOSTDATA(SCpnt->host)->SCint[mbo]){
mb[mbo].status = 2; /* Abort command */
aha1542_out(&ahacmd, 1); /* start scsi command */
aha1542_out(SCpnt->host->io_port, &ahacmd, 1); /* start scsi command */
sti();
break;
};
#endif
return 0;
return SCSI_ABORT_SNOOZE;
}
/* We do not implement a reset function here, but the upper level code assumes
that it will get some kind of response for the command in SCpnt. We must
oblige, or the command will hang the scsi system */
/* We do not implement a reset function here, but the upper level code
assumes that it will get some kind of response for the command in
SCpnt. We must oblige, or the command will hang the scsi system.
For a first go, we assume that the 1542 notifies us with all of the
pending commands (it does implement soft reset, after all). */
int aha1542_reset(Scsi_Cmnd * SCpnt)
{
unchar ahacmd = CMD_START_SCSI;
int i;
DEB(printk("aha1542_reset called\n"));
if(SCpnt) SCpnt->flags |= NEEDS_JUMPSTART;
return 0;
#if 0
/* This does a scsi reset for all devices on the bus */
outb(SCRST, CONTROL(SCpnt->host->io_port));
#else
/* This does a selective reset of just the one device */
/* First locate the ccb for this command */
for(i=0; i< AHA1542_MAILBOXES; i++)
if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt)
{
HOSTDATA(SCpnt->host)->ccb[i].op = 0x81; /* BUS DEVICE RESET */
/* Now tell the 1542 to flush all pending commands for this target */
aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
/* Here is the tricky part. What to do next. Do we get an interrupt
for the commands that we aborted with the specified target, or
do we generate this on our own? Try it without first and see
what happens */
printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target);
/* If the first does not work, then try the second. I think the
first option is more likely to be correct. Free the command
block for all commands running on this target... */
#if 1
for(i=0; i< AHA1542_MAILBOXES; i++)
if(HOSTDATA(SCpnt->host)->SCint[i] &&
HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target)
{
Scsi_Cmnd * SCtmp;
SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
SCtmp->result = DID_RESET << 16;
if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
printk("Sending DID_RESET for target %d\n", SCpnt->target);
SCtmp->scsi_done(SCpnt);
HOSTDATA(SCpnt->host)->SCint[i] = NULL;
}
return SCSI_RESET_SUCCESS;
#else
return SCSI_RESET_PENDING;
#endif
}
#endif
return SCSI_RESET_PENDING;
}
#ifdef CONFIG_BLK_DEV_SD
......
......@@ -131,7 +131,7 @@ struct ccb { /* Command Control Block 5.3 */
int aha1542_detect(int);
int aha1542_command(Scsi_Cmnd *);
int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int aha1542_abort(Scsi_Cmnd *, int);
int aha1542_abort(Scsi_Cmnd *);
const char *aha1542_info(void);
int aha1542_reset(Scsi_Cmnd *);
int aha1542_biosparam(int, int, int*);
......@@ -152,6 +152,6 @@ int aha1542_biosparam(int, int, int*);
NULL, \
aha1542_biosparam, \
AHA1542_MAILBOXES, 7, AHA1542_SCATTER, AHA1542_CMDLUN \
, 0, 1}
, 0, 1, ENABLE_CLUSTERING}
#endif
......@@ -474,10 +474,10 @@ but it hasn't happened yet, and doing aborts brings the Adaptec to its
knees. I cannot (at this moment in time) think of any reason to reset the
card once it's running. So there. */
int aha1740_abort(Scsi_Cmnd * SCpnt, int i)
int aha1740_abort(Scsi_Cmnd * SCpnt)
{
DEB(printk("aha1740_abort called\n"));
return 0;
return SCSI_ABORT_SNOOZE;
}
/* We do not implement a reset function here, but the upper level code assumes
......@@ -487,8 +487,7 @@ int aha1740_abort(Scsi_Cmnd * SCpnt, int i)
int aha1740_reset(Scsi_Cmnd * SCpnt)
{
DEB(printk("aha1740_reset called\n"));
if (SCpnt) SCpnt->flags |= NEEDS_JUMPSTART;
return 0;
return SCSI_RESET_SNOOZE;
}
int aha1740_biosparam(int size, int dev, int* ip)
......
......@@ -155,7 +155,7 @@ struct ecb { /* Enhanced Control Block 6.1 */
int aha1740_detect(int);
int aha1740_command(Scsi_Cmnd *);
int aha1740_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int aha1740_abort(Scsi_Cmnd *, int);
int aha1740_abort(Scsi_Cmnd *);
const char *aha1740_info(void);
int aha1740_reset(Scsi_Cmnd *);
int aha1740_biosparam(int, int, int*);
......@@ -174,7 +174,7 @@ int aha1740_biosparam(int, int, int*);
aha1740_reset, \
NULL, \
aha1740_biosparam, \
AHA1740_ECBS, 7, AHA1740_SCATTER, 1, 0, 0}
AHA1740_ECBS, 7, AHA1740_SCATTER, 1, 0, 0, ENABLE_CLUSTERING}
#endif
This diff is collapsed.
/*
* buslogic.h (C) 1993 David B. Gentzel
* Low-level scsi driver for BusLogic adapters
* by David B. Gentzel, Whitfield Software Services, Carnegie, PA
* (gentzel@nova.enet.dec.com)
* Thanks to BusLogic for providing the necessary documentation
*
* The original version of this driver was derived from aha1542.[ch] which
* is Copyright (C) 1992 Tommy Thorn. Much has been reworked, but most of
* basic structure and substantial chunks of code still remain.
*/
#ifndef _BUSLOGIC_H
int buslogic_detect(int);
int buslogic_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int buslogic_abort(Scsi_Cmnd *);
const char *buslogic_info(void);
int buslogic_reset(Scsi_Cmnd *);
int buslogic_biosparam(int, int, int *);
#define BUSLOGIC_CMDLUN 1 /* ??? */
#define BUSLOGIC { "BusLogic", \
buslogic_detect, \
buslogic_info, \
0, /* no command func */ \
buslogic_queuecommand, \
buslogic_abort, \
buslogic_reset, \
0, /* slave_attach NYI */ \
buslogic_biosparam, \
0, /* set by driver */ \
0, /* set by driver */ \
0, /* set by driver */ \
BUSLOGIC_CMDLUN, \
0, \
0, /* set by driver */ \
ENABLE_CLUSTERING \
}
#ifdef BUSLOGIC_PRIVATE_H
/* ??? These don't really belong here */
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0])
#define PACKED __attribute__((packed))
#define BD_ABORT 0x0001
#define BD_COMMAND 0x0002
#define BD_DETECT 0x0004
#define BD_INTERRUPT 0x0008
#define BD_RESET 0x0010
/* I/O Port interface */
/* READ */
#define STATUS(base) (base)
#define DACT 0x80 /* Diagnostic Active */
#define DFAIL 0x40 /* Diagonostic Failure */
#define INREQ 0x20 /* Initialization Required */
#define HARDY 0x10 /* Host Adapter Ready */
#define CPRBSY 0x08 /* Command/Parameter Register Busy */
#define DIRRDY 0x04 /* Data In Register Ready */
#define CMDINV 0x01 /* Command Invalid */
#define STATMASK 0xFD /* 0x02 is reserved */
#define DATA_IN(base) (STATUS(base) + 1)
#define INTERRUPT(base) (STATUS(base) + 2)
#define INTV 0x80 /* Interrupt Valid */
#define RSTS 0x08 /* SCSI Reset State */
#define CMDC 0x04 /* Command Complete */
#define MBOR 0x02 /* Mailbox Out Ready */
#define IMBL 0x01 /* Incoming Mailbox Loaded */
#define INTRMASK 0x8F /* 0x70 are reserved */
/* WRITE */
#define CONTROL(base) STATUS(base)
#define RHARD 0x80 /* Hard Reset */
#define RSOFT 0x40 /* Soft Reset */
#define RINT 0x20 /* Interrupt Reset */
#define RSBUS 0x10 /* SCSI Bus Reset */
#define COMMAND_PARAMETER(base) (STATUS(base) + 1)
#define CMD_TSTCMDCINT 0x00 /* Test CMDC Interrupt */
#define CMD_INITMB 0x01 /* Initialize Mailbox */
#define CMD_START_SCSI 0x02 /* Start Mailbox */
#define CMD_START_BIOS 0x03 /* Start BIOS */
#define CMD_INQUIRY 0x04 /* Inquire Board ID */
#define CMD_ENBOMBRINT 0x05 /* Enable OMBR Interrupt */
#define CMD_SETSELTIMOUT 0x06 /* Set SCSI Selection Time-Out */
#define CMD_BUSON_TIME 0x07 /* Set Bus-On Time */
#define CMD_BUSOFF_TIME 0x08 /* Set Bus-Off Time */
#define CMD_BUSXFR_RATE 0x09 /* Set Bus Transfer Rate */
#define CMD_INQ_DEVICES 0x0A /* Inquire Installed Devices */
#define CMD_RETCONF 0x0B /* Return Configuration */
#define CMD_TARGET_MODE 0x0C /* Set Target Mode */
#define CMD_INQ_SETUP_INFO 0x0D /* Inquire Set-up Information */
#define CMD_WRITE_LCL_RAM 0x1A /* Write Adapter Local RAM */
#define CMD_READ_LCL_RAM 0x1B /* Read Adapter Local RAM */
#define CMD_WRITE_BM_FIFO 0x1C /* Write Bus Master Chip FIFO */
#define CMD_READ_BM_FIFO 0x1D /* Read Bus Master Chip FIFO */
#define CMD_ECHO 0x1F /* Echo Data Byte */
#define CMD_HA_DIAG 0x20 /* Host Adapter Diagnostic */
#define CMD_HA_OPTIONS 0x21 /* Host Adapter Options */
#define CMD_INITEXTMB 0x81 /* Initialize Extended Mailbox */
#define CMD_INQEXTSETUP 0x8D /* Inquire Extended Set-up Information */
#define CMD_WRITE_INQ_BUF 0x9A /* Write Inquery Data Buffer
(Target Mode Only) */
#define CMD_READ_INQ_BUF 0x9B /* Read Inquery Data Buffer
(Target Mode Only) */
#define MBX_NOT_IN_USE 0x00
#define MBX_ACTION_START 0x01
#define MBX_ACTION_ABORT 0x02
#define MBX_COMPLETION_OK 0x01
#define MBX_COMPLETION_ABORTED 0x02
#define MBX_COMPLETION_NOT_FOUND 0x03
#define MBX_COMPLETION_ERROR 0x04
/* Mailbox Definition */
struct mailbox {
void *ccbptr; /* lsb, ..., msb */
unsigned char btstat;
unsigned char sdstat;
unsigned char reserved;
unsigned char status; /* Command/Status */
};
/* This is used with scatter-gather */
struct chain {
unsigned long datalen; /* Size of this part of chain */
void *dataptr; /* Location of data */
};
#define MAX_CDB 12
struct ccb { /* Command Control Block */
unsigned char op; /* Command Control Block Operation Code */
unsigned char dir;
unsigned char cdblen; /* SCSI Command Length */
unsigned char rsalen; /* Request Sense Allocation Length/Disable */
unsigned long datalen; /* Data Length (msb, ..., lsb) */
void *dataptr; /* Data Pointer */
unsigned char reserved[2];
unsigned char hastat; /* Host Adapter Status (HASTAT) */
unsigned char tarstat; /* Target Device Status */
unsigned char id;
unsigned char lun;
unsigned char cdb[MAX_CDB];
unsigned char ccbcontrol;
unsigned char commlinkid; /* Command Linking Identifier */
void *linkptr; /* Link Pointer */
void *senseptr;
};
#define CCB_OP_INIT 0x00 /* Initiator CCB */
#define CCB_OP_TARG 0x01 /* Target CCB */
#define CCB_OP_INIT_SG 0x02 /* Initiator CCB with scatter-gather */
#define CCB_OP_INIT_R 0x03 /* Initiator CCB with residual data length
returned */
#define CCB_OP_INIT_SG_R 0x04 /* Initiator CCB with scatter-gather and
residual data length returned */
#define CCB_OP_BUS_RESET 0x81 /* SCSI bus device reset */
#endif
#endif
......@@ -73,7 +73,7 @@ static const char reserved[] = "RESERVED";
static const char vendor[] = "VENDOR SPECIFIC";
static void print_opcode(int opcode) {
char **table = commands[ group(opcode) ];
const char **table = commands[ group(opcode) ];
switch ((int) table) {
case RESERVED_GROUP:
printk("%s(0x%02x) ", reserved, opcode);
......@@ -351,8 +351,8 @@ static struct error_info additional[] =
static char *snstext[] = {
"None","Recovered Error","Not Ready","Medium Error","Hardware Error",
"Illegal Request","Unit Attention","Data Protect","Blank Check",
"Key=E","Key=F","Filemark","End-Of-Medium","Incorrect Block Length",
"14","15"};
"Key=9","Copy Aborted","Aborted Command","End-Of-Medium",
"Volume Overflow", "Miscompare", "Key=15"};
#endif
......@@ -394,9 +394,6 @@ void print_sense(char * devclass, Scsi_Cmnd * SCpnt)
printk("%s error ", error);
#if (CONSTANTS & CONST_SENSE)
if (sense_buffer[2] & 0x80) printk( "FMK ");
if (sense_buffer[2] & 0x40) printk( "EOM ");
if (sense_buffer[2] & 0x20) printk( "ILI ");
printk( "%s%x: sense key %s\n", devclass, dev, snstext[sense_buffer[2] & 0x0f]);
#else
printk("%s%x: sns = %2x %2x\n", devclass, dev, sense_buffer[0], sense_buffer[2]);
......@@ -437,9 +434,12 @@ void print_sense(char * devclass, Scsi_Cmnd * SCpnt)
}
done:
#if !(CONSTANTS & CONST_SENSE)
printk("Raw sense data:");
for (i = 0; i < s; ++i)
printk("0x%02x ", sense_buffer[i]);
printk("\n");
#endif
return;
}
......
......@@ -68,7 +68,7 @@
revision 10h, October 17, 1991)
Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric
Youngdale (eric@tantalus.nrl.navy.mil), 1992.
Youngdale (ericy@cais.com), 1992.
Private communication, Tuong Le (Future Domain Engineering department),
1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
......@@ -1394,9 +1394,8 @@ void print_info( Scsi_Cmnd *SCpnt )
inb( port_base + Configuration2 ) );
}
int fdomain_16x0_abort( Scsi_Cmnd *SCpnt, int code )
int fdomain_16x0_abort( Scsi_Cmnd *SCpnt)
{
#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
printk( "Future Domain: Abort " );
#endif
......@@ -1407,11 +1406,7 @@ int fdomain_16x0_abort( Scsi_Cmnd *SCpnt, int code )
printk( " (not in command)\n" );
#endif
sti();
return 0;
} else {
#if EVERY_ACCESS || ERRORS_ONLY
printk( " code = %d\n", code );
#endif
return SCSI_ABORT_NOT_RUNNING;
}
#if DEBUG_ABORT
......@@ -1422,14 +1417,14 @@ int fdomain_16x0_abort( Scsi_Cmnd *SCpnt, int code )
current_SC->SCp.phase |= aborted;
current_SC->result = code ? code : DID_ABORT;
current_SC->result = DID_ABORT << 16;
sti();
/* Aborts are not done well. . . */
my_done( code << 16 );
my_done( DID_ABORT << 16 );
return 0;
return SCSI_ABORT_SUCCESS;
}
int fdomain_16x0_reset( Scsi_Cmnd *SCpnt )
......@@ -1458,10 +1453,7 @@ int fdomain_16x0_reset( Scsi_Cmnd *SCpnt )
is probably hosed at this point. We will, however, try to keep
things going by informing the high-level code that we need help. */
if (SCpnt)
SCpnt->flags |= NEEDS_JUMPSTART;
return 0;
return SCSI_RESET_WAKEUP;
}
#ifdef CONFIG_BLK_DEV_SD
......
......@@ -27,7 +27,7 @@
int fdomain_16x0_detect( int );
int fdomain_16x0_command( Scsi_Cmnd * );
int fdomain_16x0_abort( Scsi_Cmnd *, int );
int fdomain_16x0_abort( Scsi_Cmnd *);
const char *fdomain_16x0_info( void );
int fdomain_16x0_reset( Scsi_Cmnd * );
int fdomain_16x0_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
......@@ -47,5 +47,5 @@ int fdomain_16x0_biosparam( int, int, int * );
fdomain_16x0_reset, \
NULL, \
fdomain_16x0_biosparam, \
1, 6, 64 /* SG_NONE */, 1 ,0, 0 }
1, 6, 64 /* SG_NONE */, 1 ,0, 0, DISABLE_CLUSTERING}
#endif
......@@ -33,7 +33,7 @@
#ifndef ASM
int generic_NCR5380_abort(Scsi_Cmnd *, int);
int generic_NCR5380_abort(Scsi_Cmnd *);
int generic_NCR5380_detect(int);
const char *generic_NCR5380_info(void);
int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
......@@ -59,7 +59,7 @@ int generic_NCR5380_reset(Scsi_Cmnd *);
generic_NCR5380_queue_command, generic_NCR5380_abort, \
generic_NCR5380_reset, NULL, \
NULL, /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL, \
/* cmd per lun */ CMD_PER_LUN , 0, 0}
/* cmd per lun */ CMD_PER_LUN , 0, 0, DISABLE_CLUSTERING}
#else
#define NCR5380_implementation_fields \
......
......@@ -39,6 +39,10 @@
#include "aha1740.h"
#endif
#ifdef CONFIG_SCSI_BUSLOGIC
#include "buslogic.h"
#endif
#ifdef CONFIG_SCSI_FUTURE_DOMAIN
#include "fdomain.h"
#endif
......@@ -47,6 +51,10 @@
#include "g_NCR5380.h"
#endif
#ifdef CONFIG_SCSI_IN2000
#include "in2000.h"
#endif
#ifdef CONFIG_SCSI_PAS16
#include "pas16.h"
#endif
......@@ -105,6 +113,10 @@ Scsi_Host_Template scsi_hosts[] =
#ifdef CONFIG_SCSI_AHA152X
AHA152X,
#endif
/* Buslogic must come before aha1542.c */
#ifdef CONFIG_SCSI_BUSLOGIC
BUSLOGIC,
#endif
#ifdef CONFIG_SCSI_AHA1542
AHA1542,
#endif
......@@ -114,6 +126,9 @@ Scsi_Host_Template scsi_hosts[] =
#ifdef CONFIG_SCSI_FUTURE_DOMAIN
FDOMAIN_16X0,
#endif
#ifdef CONFIG_SCSI_IN2000
IN2000,
#endif
#ifdef CONFIG_SCSI_GENERIC_NCR5380
GENERIC_NCR5380,
#endif
......@@ -181,6 +196,7 @@ struct Scsi_Host * scsi_register(int i, int j){
retval->host_queue = NULL;
retval->host_wait = NULL;
retval->last_reset = 0;
retval->irq = 0;
retval->hostt = &scsi_hosts[i];
retval->next = NULL;
#ifdef DEBUG
......
......@@ -21,16 +21,11 @@
*/
/* A jumpstart is often required when the reset() function is called -
many host adapters cannot do this cleanly, so they do nothing at all.
To get the command going again, these routines set this bit in the flags
so that a scsi_request_sense() is executed, and the command starts running
again */
#define NEEDS_JUMPSTART 0x20
#define SG_NONE 0
#define SG_ALL 0xff
#define SG_ALL 0x7fff
#define DISABLE_CLUSTERING 0
#define ENABLE_CLUSTERING 1
/* The various choices mean:
NONE: Self evident. Host adapter is not capable of scatter-gather.
......@@ -109,7 +104,11 @@ typedef struct
/*
Since the mid level driver handles time outs, etc, we want to
be able to abort the current command. Abort returns 0 if the
abortion was successful. If non-zero, the code passed to it
abortion was successful. The field SCpnt->abort reason
can be filled in with the appropriate reason why we wanted
the abort in the first place, and this will be used
in the mid-level code instead of the host_byte().
If non-zero, the code passed to it
will be used as the return code, otherwise
DID_ABORT should be returned.
......@@ -117,7 +116,7 @@ typedef struct
resetting the bus, etc. if necessary.
*/
int (* abort)(Scsi_Cmnd *, int);
int (* abort)(Scsi_Cmnd *);
/*
The reset function will reset the SCSI bus. Any executing
......@@ -192,6 +191,15 @@ typedef struct
true if this host adapter uses unchecked DMA onto an ISA bus.
*/
unsigned unchecked_isa_dma:1;
/*
true if this host adapter can make good use of clustering.
I originally thought that if the tablesize was large that it
was a waste of CPU cycles to prepare a cluster list, but
it works out that the Buslogic is faster if you use a smaller
number of segments (i.e. use clustering). I guess it is
inefficient.
*/
unsigned use_clustering:1;
} Scsi_Host_Template;
/*
......
......@@ -114,7 +114,7 @@
#ifndef ASM
int pas16_abort(Scsi_Cmnd *, int);
int pas16_abort(Scsi_Cmnd *);
int pas16_biosparam(int, int, int*);
int pas16_detect(int);
const char *pas16_info(void);
......@@ -145,7 +145,7 @@ int pas16_reset(Scsi_Cmnd *);
NULL, pas16_queue_command, pas16_abort, pas16_reset, NULL, \
pas16_biosparam, \
/* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL, \
/* cmd per lun */ CMD_PER_LUN , 0, 0}
/* cmd per lun */ CMD_PER_LUN , 0, 0, DISABLE_CLUSTERING}
#else
......
This diff is collapsed.
......@@ -276,6 +276,7 @@ typedef struct scsi_device {
unsigned tagged_supported:1; /* Supports SCSI-II tagged queing */
unsigned tagged_queue:1; /*SCSI-II tagged queing enabled */
unsigned disconnect:1; /* can disconnect */
unsigned soft_reset:1; /* Uses soft reset option */
unsigned char current_tag; /* current tag */
} Scsi_Device;
/*
......@@ -315,6 +316,63 @@ struct scatterlist {
#define CONTIGUOUS_BUFFERS(X,Y) ((X->b_data+X->b_size) == Y->b_data)
/*
* These are the return codes for the abort and reset functions. The mid-level
* code uses these to decide what to do next. Each of the low level abort
* and reset functions must correctly indicate what it has done.
*/
/* We did not do anything. Wait
some more for this command to complete, and if this does not work, try
something more serious. */
#define SCSI_ABORT_SNOOZE 0
/* This means that we were able to abort the command. We have already
called the mid-level done function, and do not expect an interrupt that will
lead to another call to the mid-level done function for this command */
#define SCSI_ABORT_SUCCESS 1
/* We called for an abort of this command, and we should get an interrupt
when this succeeds. Thus we should not restore the timer for this
command in the mid-level abort function. */
#define SCSI_ABORT_PENDING 2
/* Unable to abort - command is currently on the bus. Grin and bear it. */
#define SCSI_ABORT_BUSY 3
/* The command is not active in the low level code. Command probably
finished. */
#define SCSI_ABORT_NOT_RUNNING 4
/* Something went wrong. The low level driver will indicate the correct
error condition when it calls scsi_done, so the mid-level abort function
can simply wait until this comes through */
#define SCSI_ABORT_ERROR 5
/* We do not know how to reset the bus, or we do not want to. Bummer.
Anyway, just wait a little more for the command in question, and hope that
it eventually finishes */
#define SCSI_RESET_SNOOZE 0
/* This means that we were able to reset the bus. We have restarted all of
the commands that should be restarted, and we should be able to continue
on normally from here. We do not expect any interrupts that will return
DID_RESET to any of the other commands in the host_queue. */
#define SCSI_RESET_SUCCESS 1
/* We called for an reset of this bus, and we should get an interrupt
when this succeeds. Each command should get it's own status
passed up to scsi_done, but this has not happened yet. */
#define SCSI_RESET_PENDING 2
/* We did a reset, but do not expect an interrupt to signal DID_RESET.
This tells the upper level code to request the sense info, and this
should keep the command alive. */
#define SCSI_RESET_WAKEUP 3
/* Something went wrong, and we do not know how to fix it. */
#define SCSI_RESET_ERROR 4
void * scsi_malloc(unsigned int);
int scsi_free(void *, unsigned int);
extern unsigned int dma_free_sectors; /* How much room do we have left */
......@@ -340,6 +398,7 @@ typedef struct scsi_pointer {
typedef struct scsi_cmnd {
struct Scsi_Host * host;
Scsi_Device * device;
unsigned char target, lun, index;
struct scsi_cmnd *next, *prev;
......@@ -355,6 +414,8 @@ typedef struct scsi_cmnd {
sense info */
unsigned short use_sg; /* Number of pieces of scatter-gather */
unsigned short sglist_len; /* size of malloc'd scatter-gather list */
unsigned short abort_reason; /* If the mid-level code requests an
abort, this is the reason. */
unsigned bufflen; /* Size of data buffer */
void *buffer; /* Data buffer */
......
......@@ -521,7 +521,7 @@ int scsi_debug_detect(int hostnum)
return 1;
}
int scsi_debug_abort(Scsi_Cmnd * SCpnt,int i)
int scsi_debug_abort(Scsi_Cmnd * SCpnt)
{
int j;
void (*my_done)(Scsi_Cmnd *);
......
......@@ -23,5 +23,5 @@ int scsi_debug_reset(Scsi_Cmnd *);
scsi_debug_reset, \
NULL, \
scsi_debug_biosparam, \
SCSI_DEBUG_MAILBOXES, 7, SG_ALL, 1, 0, 1}
SCSI_DEBUG_MAILBOXES, 7, SG_ALL, 1, 0, 1, ENABLE_CLUSTERING}
#endif
/*
* sd.c Copyright (C) 1992 Drew Eckhardt
* Copyright (C) 1993, 1994 Eric Youngdale
* Linux scsi disk driver by
* Drew Eckhardt
*
* <drew@colorado.edu>
*
* Modified by Eric Youngdale eric@tantalus.nrl.navy.mil to
* Modified by Eric Youngdale ericy@cais.com to
* add scatter-gather, multiple outstanding request, and other
* enhancements.
*/
......@@ -40,7 +41,7 @@ static const char RCSid[] = "$Header:";
#define SD_TIMEOUT 300
#define SD_MOD_TIMEOUT 750
#define CLUSTERABLE_DEVICE(SC) (SC->host->sg_tablesize < 64 && \
#define CLUSTERABLE_DEVICE(SC) (SC->host->hostt->use_clustering && \
scsi_devices[SC->index].type != TYPE_MOD)
struct hd_struct * sd;
......
......@@ -1546,14 +1546,11 @@ else {
return retcode (st0x_aborted);
}
int seagate_st0x_abort (Scsi_Cmnd * SCpnt, int code)
int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
{
if (code)
st0x_aborted = code;
else
st0x_aborted = DID_ABORT;
return 0;
st0x_aborted = DID_ABORT;
return SCSI_ABORT_PENDING;
}
/*
......@@ -1590,8 +1587,7 @@ int seagate_st0x_reset (Scsi_Cmnd * SCpnt)
#ifdef DEBUG
printk("SCSI bus reset.\n");
#endif
if(SCpnt) SCpnt->flags |= NEEDS_JUMPSTART;
return 0;
return SCSI_RESET_PENDING;
}
#ifdef CONFIG_BLK_DEV_SD
......
......@@ -16,7 +16,7 @@ int seagate_st0x_detect(int);
int seagate_st0x_command(Scsi_Cmnd *);
int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int seagate_st0x_abort(Scsi_Cmnd *, int);
int seagate_st0x_abort(Scsi_Cmnd *);
const char *seagate_st0x_info(void);
int seagate_st0x_reset(Scsi_Cmnd *);
......@@ -34,7 +34,7 @@ int seagate_st0x_biosparam(int, int, int*);
seagate_st0x_info, seagate_st0x_command, \
seagate_st0x_queue_command, seagate_st0x_abort, \
seagate_st0x_reset, NULL, seagate_st0x_biosparam, \
1, 7, SG_ALL, 1, 0, 0}
1, 7, SG_ALL, 1, 0, 0, DISABLE_CLUSTERING}
#endif
......
/*
* sr.c by David Giller
* sr.c Copyright (C) 1992 David Giller
* Copyright (C) 1993, 1994 Eric Youngdale
*
* adapted from:
* sd.c Copyright (C) 1992 Drew Eckhardt
......@@ -8,7 +9,7 @@
*
* <drew@colorado.edu>
*
* Modified by Eric Youngdale eric@tantalus.nrl.navy.mil to
* Modified by Eric Youngdale ericy@cais.com to
* add scatter-gather, multiple outstanding request, and other
* enhancements.
*/
......
......@@ -91,7 +91,7 @@
#define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */
#ifndef ASM
int t128_abort(Scsi_Cmnd *, int);
int t128_abort(Scsi_Cmnd *);
int t128_biosparam(int, int, int*);
int t128_detect(int);
const char *t128_info(void);
......@@ -122,7 +122,7 @@ int t128_reset(Scsi_Cmnd *);
NULL, t128_queue_command, t128_abort, t128_reset, NULL, \
t128_biosparam, \
/* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL, \
/* cmd per lun */ CMD_PER_LUN , 0, 0}
/* cmd per lun */ CMD_PER_LUN , 0, 0, DISABLE_CLUSTERING}
#else
......
......@@ -6,7 +6,7 @@
* scatter/gather added by Scott Taylor (n217cg@tamuts.tamu.edu)
* 24F and multiple command support by John F. Carr (jfc@athena.mit.edu)
* John's work modified by Caleb Epstein (cae@jpmorgan.com) and
* Eric Youngdale (eric@tantalus.nrl.navy.mil).
* Eric Youngdale (ericy@cais.com).
* Thanks to UltraStor for providing the necessary documentation
*/
......@@ -796,7 +796,7 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
*/
int ultrastor_abort(Scsi_Cmnd *SCpnt, int code)
int ultrastor_abort(Scsi_Cmnd *SCpnt)
{
#if ULTRASTOR_DEBUG & UD_ABORT
char out[108];
......@@ -807,7 +807,8 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt, int code)
unsigned char old_aborted;
void (*done)(Scsi_Cmnd *);
if(config.slot) return 0; /* Do not attempt an abort for the 24f */
if(config.slot)
return SCSI_ABORT_SNOOZE; /* Do not attempt an abort for the 24f */
mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
if (mscp_index >= ULTRASTOR_MAX_CMDS)
......@@ -851,16 +852,16 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt, int code)
cli();
ultrastor_interrupt(0);
restore_flags(flags);
return 0;
return SCSI_ABORT_SUCCESS; /* FIXME - is this correct? -ERY */
}
#endif
old_aborted = xchgb(code ? code : DID_ABORT, &config.aborted[mscp_index]);
old_aborted = xchgb(DID_ABORT, &config.aborted[mscp_index]);
/* aborted == 0xff is the signal that queuecommand has not yet sent
the command. It will notice the new abort flag and fail. */
if (old_aborted == 0xff)
return 0;
return SCSI_ABORT_SUCCESS;
/* On 24F, send an abort MSCP request. The adapter will interrupt
and the interrupt handler will call done. */
......@@ -879,7 +880,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt, int code)
printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
#endif
restore_flags(flags);
return 0;
return SCSI_ABORT_PENDING;
}
#if ULTRASTOR_DEBUG & UD_ABORT
......@@ -891,13 +892,18 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt, int code)
still be using it. Setting SCint = 0 causes the interrupt
handler to ignore the command. */
/* FIXME - devices that implement soft resets will still be running
the command after a bus reset. We would probably rather leave
the command in the queue. The upper level code will automatically
leave the command in the active state instead of requeueing it. ERY */
#if ULTRASTOR_DEBUG & UD_ABORT
if (config.mscp[mscp_index].SCint != SCpnt)
printk("abort: command mismatch, %x != %x\n",
config.mscp[mscp_index].SCint, SCpnt);
#endif
if (config.mscp[mscp_index].SCint == 0)
return 1;
return SCSI_ABORT_NOT_RUNNING;
if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
config.mscp[mscp_index].SCint = 0;
......@@ -908,7 +914,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt, int code)
done(SCpnt);
/* Need to set a timeout here in case command never completes. */
return 0;
return SCSI_ABORT_SUCCESS;
}
......@@ -920,10 +926,8 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt)
printk("US14F: reset: called\n");
#endif
if(config.slot) {
if (SCpnt) SCpnt->flags |= NEEDS_JUMPSTART;
return 0; /* Do not attempt a reset for the 24f */
};
if(config.slot)
return SCSI_RESET_SNOOZE; /* Do not attempt a reset for the 24f */
save_flags(flags);
cli();
......@@ -958,6 +962,9 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt)
}
#endif
/* FIXME - if the device implements soft resets, then the command
will still be running. ERY */
memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
#if ULTRASTOR_MAX_CMDS == 1
config.mscp_busy = 0;
......@@ -966,7 +973,7 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt)
#endif
restore_flags(flags);
return 0;
return SCSI_RESET_SUCCESS;
}
......
......@@ -16,7 +16,7 @@
int ultrastor_detect(int);
const char *ultrastor_info(void);
int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int ultrastor_abort(Scsi_Cmnd *, int);
int ultrastor_abort(Scsi_Cmnd *);
int ultrastor_reset(Scsi_Cmnd *);
int ultrastor_biosparam(int, int, int *);
......@@ -31,7 +31,8 @@ int ultrastor_biosparam(int, int, int *);
{ "UltraStor 14F/24F/34F", ultrastor_detect, ultrastor_info, 0, \
ultrastor_queuecommand, ultrastor_abort, ultrastor_reset, \
0, ultrastor_biosparam, ULTRASTOR_MAX_CMDS, 0, \
ULTRASTOR_14F_MAX_SG, ULTRASTOR_MAX_CMDS_PER_LUN, 0, 1 }
ULTRASTOR_14F_MAX_SG, ULTRASTOR_MAX_CMDS_PER_LUN, 0, 1, \
ENABLE_CLUSTERING }
#ifdef ULTRASTOR_PRIVATE
......
......@@ -1185,18 +1185,17 @@ int wd7000_detect(int hostnum)
/*
* I have absolutely NO idea how to do an abort with the WD7000...
*/
int wd7000_abort(Scsi_Cmnd * SCpnt, int i)
int wd7000_abort(Scsi_Cmnd * SCpnt)
{
#ifdef DEBUG
printk("wd7000_abort: Scsi_Cmnd = 0x%06x, code = %d ", (int) SCpnt, i);
printk("id %d lun %d cdb", SCpnt->target, SCpnt->lun);
{
int j; unchar *cdbj = (unchar *) SCpnt->cmnd;
for (j=0; j < COMMAND_SIZE(*cdbj); j++) printk(" %02x", *(cdbj++));
printk(" result %08x\n", SCpnt->result);
Adapter *host = (Adapter *) SCpnt->host->hostdata;
if (inb(host->iobase+ASC_STAT) & INT_IM) {
printk("wd7000_abort: lost interrupt\n");
wd7000_intr_handle(host->irq);
return SCSI_ABORT_SUCCESS;
}
#endif
return 0;
return SCSI_ABORT_SNOOZE;
}
......@@ -1205,21 +1204,7 @@ int wd7000_abort(Scsi_Cmnd * SCpnt, int i)
*/
int wd7000_reset(Scsi_Cmnd * SCpnt)
{
#ifdef DEBUG
printk("wd7000_reset: Scsi_Cmnd = 0x%06x ", (int) SCpnt);
if (SCpnt) {
printk("id %d lun %d cdb", SCpnt->target, SCpnt->lun);
{
int j; unchar *cdbj = (unchar *) SCpnt->cmnd;
for (j=0; j < COMMAND_SIZE(*cdbj); j++)
printk(" %02x", *(cdbj++));
printk(" result %08x", SCpnt->result);
}
}
printk("\n");
#endif
if (SCpnt) SCpnt->flags |= NEEDS_JUMPSTART;
return 0;
return SCSI_RESET_SNOOZE;
}
......
......@@ -15,7 +15,7 @@
int wd7000_detect(int);
int wd7000_command(Scsi_Cmnd *);
int wd7000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int wd7000_abort(Scsi_Cmnd *, int);
int wd7000_abort(Scsi_Cmnd *);
const char *wd7000_info(void);
int wd7000_reset(Scsi_Cmnd *);
int wd7000_biosparam(int, int, int*);
......@@ -48,5 +48,5 @@ int wd7000_biosparam(int, int, int*);
wd7000_reset, \
NULL, \
wd7000_biosparam, \
WD7000_Q, 7, WD7000_SG, 1, 0, 1}
WD7000_Q, 7, WD7000_SG, 1, 0, 1, ENABLE_CLUSTERING}
#endif
......@@ -572,6 +572,8 @@ void flush_old_exec(struct linux_binprm * bprm)
last_task_used_math = NULL;
current->used_math = 0;
current->personality = 0;
current->lcall7 = no_lcall7;
current->signal_map = current->signal_invmap = ident_map;
}
/*
......@@ -762,6 +764,25 @@ asmlinkage int sys_execve(struct pt_regs regs)
return error;
}
/*
* signal mapping: this is the default identity mapping used for normal
* linux binaries (it's both the reverse and the normal map, of course)
*/
unsigned long ident_map[33] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32
};
/*
* default lcall7 handler.. The native linux stuff doesn't
* use it at all, so we just segfault on it.
*/
asmlinkage void no_lcall7(struct pt_regs * regs)
{
send_sig(SIGSEGV, current, 1);
}
static void set_brk(unsigned long start, unsigned long end)
{
start = PAGE_ALIGN(start);
......
......@@ -543,8 +543,9 @@ int ext_rmdir(struct inode * dir, const char * name, int len)
retval = -EPERM;
if (!(inode = iget(dir->i_sb, de->inode)))
goto end_rmdir;
if ((dir->i_mode & S_ISVTX) && current->euid &&
inode->i_uid != current->euid)
if ((dir->i_mode & S_ISVTX) && !suser() &&
current->euid != inode->i_uid &&
current->euid != dir->i_uid)
goto end_rmdir;
if (inode->i_dev != dir->i_dev)
goto end_rmdir;
......
......@@ -277,10 +277,6 @@ static int ext2_file_write (struct inode * inode, struct file * filp,
}
p = (pos % sb->s_blocksize) + bh->b_data;
pos += c;
if (pos > inode->i_size) {
inode->i_size = pos;
inode->i_dirt = 1;
}
written += c;
memcpy_fromfs (p, buf, c);
buf += c;
......@@ -288,6 +284,8 @@ static int ext2_file_write (struct inode * inode, struct file * filp,
mark_buffer_dirty(bh, 0);
brelse (bh);
}
if (pos > inode->i_size)
inode->i_size = pos;
up(&inode->i_sem);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
filp->f_pos = pos;
......
......@@ -630,8 +630,9 @@ int ext2_rmdir (struct inode * dir, const char * name, int len)
schedule();
goto repeat;
}
if ((dir->i_mode & S_ISVTX) && current->euid &&
inode->i_uid != current->euid)
if ((dir->i_mode & S_ISVTX) && !suser() &&
current->euid != inode->i_uid &&
current->euid != dir->i_uid)
goto end_rmdir;
if (inode == dir) /* we may not delete ".", but "../dir" is ok */
goto end_rmdir;
......
......@@ -410,8 +410,8 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
brelse (bh);
set_blocksize (dev, sb->s_blocksize);
logic_sb_block = sb_block / sb->s_blocksize;
offset = sb_block % sb->s_blocksize;
logic_sb_block = (sb_block*BLOCK_SIZE) / sb->s_blocksize;
offset = (sb_block*BLOCK_SIZE) % sb->s_blocksize;
bh = bread (dev, logic_sb_block, sb->s_blocksize);
if(!bh)
return NULL;
......
......@@ -201,16 +201,13 @@ static int minix_file_write(struct inode * inode, struct file * filp, char * buf
printk("minix_file_write: mode = %07o\n",inode->i_mode);
return -EINVAL;
}
/*
* ok, append may not work when many processes are writing at the same time
* but so what. That way leads to madness anyway.
*/
down(&inode->i_sem);
if (filp->f_flags & O_APPEND)
pos = inode->i_size;
else
pos = filp->f_pos;
written = 0;
while (written<count) {
while (written < count) {
bh = minix_getblk(inode,pos/BLOCK_SIZE,1);
if (!bh) {
if (!written)
......@@ -232,10 +229,6 @@ static int minix_file_write(struct inode * inode, struct file * filp, char * buf
}
p = (pos % BLOCK_SIZE) + bh->b_data;
pos += c;
if (pos > inode->i_size) {
inode->i_size = pos;
inode->i_dirt = 1;
}
written += c;
memcpy_fromfs(p,buf,c);
buf += c;
......@@ -243,6 +236,9 @@ static int minix_file_write(struct inode * inode, struct file * filp, char * buf
mark_buffer_dirty(bh, 0);
brelse(bh);
}
if (pos > inode->i_size)
inode->i_size = pos;
up(&inode->i_sem);
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
filp->f_pos = pos;
inode->i_dirt = 1;
......
......@@ -443,8 +443,9 @@ int minix_rmdir(struct inode * dir, const char * name, int len)
retval = -EPERM;
if (!(inode = iget(dir->i_sb, de->inode)))
goto end_rmdir;
if ((dir->i_mode & S_ISVTX) && current->euid &&
inode->i_uid != current->euid)
if ((dir->i_mode & S_ISVTX) && !suser() &&
current->euid != inode->i_uid &&
current->euid != dir->i_uid)
goto end_rmdir;
if (inode->i_dev != dir->i_dev)
goto end_rmdir;
......
......@@ -447,8 +447,9 @@ int sysv_rmdir(struct inode * dir, const char * name, int len)
retval = -EPERM;
if (!(inode = iget(dir->i_sb, de->inode)))
goto end_rmdir;
if ((dir->i_mode & S_ISVTX) && current->euid &&
inode->i_uid != current->euid)
if ((dir->i_mode & S_ISVTX) && !suser() &&
current->euid != inode->i_uid &&
current->euid != dir->i_uid)
goto end_rmdir;
if (inode->i_dev != dir->i_dev)
goto end_rmdir;
......
......@@ -496,8 +496,9 @@ int xiafs_rmdir(struct inode * dir, const char * name, int len)
retval = -EPERM;
if (!(inode = iget(dir->i_sb, de->d_ino)))
goto end_rmdir;
if ((dir->i_mode & S_ISVTX) && current->euid &&
inode->i_uid != current->euid)
if ((dir->i_mode & S_ISVTX) && !suser() &&
current->euid != inode->i_uid &&
current->euid != dir->i_uid)
goto end_rmdir;
if (inode->i_dev != dir->i_dev)
goto end_rmdir;
......
......@@ -36,4 +36,3 @@ dummy:
ifeq (.depend,$(wildcard .depend))
include .depend
endif
......@@ -5,23 +5,6 @@
*/
/*
* Emulate.c contains the entry point for the 'lcall 7,xxx' handler.
* Yes, sir, this file is completely empty, waiting for some real code..
* I still copyright it, silly me.
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/segment.h>
#include <linux/ptrace.h>
#include <asm/segment.h>
#include <asm/system.h>
asmlinkage void iABI_emulate(struct pt_regs * regs)
{
printk("iBCS2 binaries not supported yet\n");
do_exit(SIGSEGV);
}
......@@ -89,6 +89,7 @@ extern unsigned long avenrun[]; /* Load averages */
#include <linux/resource.h>
#include <linux/vm86.h>
#include <linux/math_emu.h>
#include <linux/ptrace.h>
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
......@@ -251,6 +252,7 @@ struct task_struct {
unsigned long flags; /* per process flags, defined below */
int errno;
int debugreg[8]; /* Hardware debugging registers */
asmlinkage void (*lcall7)(struct pt_regs *);
/* various fields */
struct task_struct *next_task, *prev_task;
struct sigaction sigaction[32];
......@@ -324,6 +326,7 @@ struct task_struct {
#define INIT_TASK \
/* state etc */ { 0,15,15,0,0,0,0, \
/* debugregs */ { 0, }, \
/* lcall 7 */ no_lcall7, \
/* schedlink */ &init_task,&init_task, \
/* signals */ {{ 0, },}, ident_map, ident_map, \
/* stack */ 0,(unsigned long) &init_kernel_stack, \
......@@ -358,6 +361,9 @@ extern unsigned long itimer_next;
extern struct timeval xtime;
extern int need_resched;
extern unsigned long ident_map[33];
extern asmlinkage void no_lcall7(struct pt_regs *);
#define CURRENT_TIME (xtime.tv_sec)
extern void sleep_on(struct wait_queue ** p);
......
......@@ -99,11 +99,10 @@ __asm__("cld\n"
"jne 1b\n\t"
"xorl %%eax,%%eax\n\t"
"jmp 3f\n"
"2:\tmovl $1,%%eax\n\t"
"jb 3f\n\t"
"negl %%eax\n"
"2:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%eax\n"
"3:"
:"=a" (__res):"D" (cs),"S" (ct):"si","di");
:"=a" (__res):"S" (cs),"D" (ct):"si","di");
return __res;
}
......@@ -120,11 +119,10 @@ __asm__("cld\n"
"jne 1b\n"
"2:\txorl %%eax,%%eax\n\t"
"jmp 4f\n"
"3:\tmovl $1,%%eax\n\t"
"jb 4f\n\t"
"negl %%eax\n"
"3:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"4:"
:"=a" (__res):"D" (cs),"S" (ct),"c" (count):"si","di","cx");
:"=a" (__res):"S" (cs),"D" (ct),"c" (count):"si","di","cx");
return __res;
}
......@@ -153,8 +151,7 @@ __asm__("cld\n\t"
"1:\tlodsb\n\t"
"cmpb %%ah,%%al\n\t"
"jne 2f\n\t"
"movl %%esi,%0\n\t"
"decl %0\n"
"leal -1(%%esi),%0\n"
"2:\ttestb %%al,%%al\n\t"
"jne 1b"
:"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
......@@ -384,11 +381,10 @@ __asm__("cld\n\t"
"repe\n\t"
"cmpsb\n\t"
"je 1f\n\t"
"movl $1,%%eax\n\t"
"jb 1f\n\t"
"negl %%eax\n"
"sbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"1:"
:"=a" (__res):"0" (0),"D" (cs),"S" (ct),"c" (count)
:"=a" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count)
:"si","di","cx");
return __res;
}
......
......@@ -282,12 +282,10 @@ int kill_proc(int pid, int sig, int priv)
* POSIX specifies that kill(-1,sig) is unspecified, but what we have
* is probably wrong. Should make it like BSD or SYSV.
*/
asmlinkage int sys_kill(int pid, unsigned int sig)
asmlinkage int sys_kill(int pid,int sig)
{
int err, retval = 0, count = 0;
if (sig > 32)
return -EINVAL;
if (!pid)
return(kill_pg(current->pgrp,sig,0));
if (pid == -1) {
......
......@@ -87,16 +87,6 @@ extern void mem_use(void);
extern int timer_interrupt(void);
asmlinkage int system_call(void);
/*
* signal mapping: this is the default identity mapping used for normal
* linux binaries (it's both the reverse and the normal map, of course)
*/
static unsigned long ident_map[33] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32
};
static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, };
struct task_struct init_task = INIT_TASK;
......
......@@ -78,6 +78,7 @@ flags = 20
errno = 24
dbgreg6 = 52
dbgreg7 = 56
lcall7 = 60
ENOSYS = 38
......@@ -141,8 +142,10 @@ _lcall7:
movl %edx,EIP(%esp) # Now we move them to their "normal" places
movl %ecx,CS(%esp) #
movl %esp,%eax
movl _current,%edx
pushl %eax
call _iABI_emulate
movl lcall7(%edx),%edx
call *%edx
popl %eax
jmp ret_from_sys_call
......
......@@ -1264,7 +1264,7 @@ static void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag)
return;
}
if(memcmp(skb->data,dev->broadcast, dev->addr_len))
if(!memcmp(skb->data,dev->broadcast, dev->addr_len))
return;
......
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