patch-1.3.48 linux/drivers/scsi/aha152x.c
Next file: linux/drivers/scsi/aha152x.h
Previous file: linux/drivers/scsi/README.st
Back to the patch index
Back to the overall index
- Lines: 3471
- Date:
Thu Dec 14 15:45:44 1995
- Orig file:
v1.3.47/linux/drivers/scsi/aha152x.c
- Orig date:
Wed Dec 13 09:02:46 1995
diff -u --recursive --new-file v1.3.47/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
@@ -1,6 +1,6 @@
/* aha152x.c -- Adaptec AHA-152x driver
- * Author: Juergen E. Fischer, fischer@server.et-inf.fho-emden.de
- * Copyright 1993, 1994 Juergen E. Fischer
+ * Author: Juergen E. Fischer, fischer@et-inf.fho-emden.de
+ * Copyright 1993, 1994, 1995 Juergen E. Fischer
*
*
* This driver is based on
@@ -8,22 +8,28 @@
* which is
* Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
*
-
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
-
+ *
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
-
*
- * $Id: aha152x.c,v 1.9 1995/03/18 09:20:24 root Exp root $
*
-
+ * $Id: aha152x.c,v 1.11 1995/12/06 21:18:35 fischer Exp $
+ *
* $Log: aha152x.c,v $
+ * Revision 1.11 1995/12/06 21:18:35 fischer
+ * - some minor updates
+ *
+ * Revision 1.10 1995/07/22 19:18:45 fischer
+ * - support for 2 controllers
+ * - started synchronous data transfers (not working yet)
+ *
* Revision 1.9 1995/03/18 09:20:24 root
* - patches for PCMCIA and modules
*
@@ -145,7 +151,7 @@
* Revision 0.0 1993/08/14 19:54:25 root
* empty function bodies; detect() works.
*
-
+ *
**************************************************************************
@@ -158,23 +164,28 @@
PER-DEFINE CONFIGURABLE OPTIONS:
- AUTOCONF : use configuration the controller reports (only 152x)
- IRQ : override interrupt channel (9,10,11 or 12) (default 11)
- SCSI_ID : override scsiid of AIC-6260 (0-7) (default 7)
- RECONNECT : override target dis-/reconnection/multiple outstanding commands (default on)
- PARITY : override parity check (default on)
- SKIP_BIOSTEST : Don't test for BIOS signature (AHA-1510 or disabled BIOS)
- PORTBASE : Force port base. Don't try to probe
+ AUTOCONF:
+ use configuration the controller reports (only 152x)
+
+ SKIP_BIOSTEST:
+ Don't test for BIOS signature (AHA-1510 or disabled BIOS)
+
+ SETUP0 { IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS }:
+ override for the first controller
+
+ SETUP1 { IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS }:
+ override for the second controller
LILO COMMAND LINE OPTIONS:
- aha152x=<PORTBASE>[,<IRQ>[,<SCSI-ID>[,<RECONNECT>[,<PARITY>]]]]
+ aha152x=<IOPORT>[,<IRQ>[,<SCSI-ID>[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>]]]]]
The normal configuration can be overridden by specifying a command line.
When you do this, the BIOS test is skipped. Entered values have to be
- valid (known). Don't use values that aren't support under normal operation.
- If you think that you need other values: contact me.
+ valid (known). Don't use values that aren't supported under normal operation.
+ If you think that you need other values: contact me. For two controllers
+ use the aha152x statement twice.
REFERENCES USED:
@@ -225,7 +236,7 @@
#include <linux/proc_fs.h>
#include "aha152x.h"
-#include<linux/stat.h>
+#include <linux/stat.h>
struct proc_dir_entry proc_scsi_aha152x = {
PROC_SCSI_AHA152X, 7, "aha152x",
@@ -241,26 +252,10 @@
#endif
#endif
-/* If auto configuration is disabled, IRQ, SCSI_ID and RECONNECT have to
- be predefined */
-#if !defined(AUTOCONF)
-#if !defined(IRQ)
-#error undefined IRQ; define AUTOCONF or IRQ
-#endif
-#if !defined(SCSI_ID)
-#error undefined SCSI_ID; define AUTOCONF or SCSI_ID
-#endif
-#if !defined(RECONNECT)
-#error undefined RECONNECT; define AUTOCONF or RECONNECT
-#endif
-#if !defined(PARITY)
-#error undefined PARITY; define AUTOCONF or PARITY
-#endif
+#if !defined(AUTOCONF) && !defined(SETUP0)
+#error define AUTOCONF or SETUP0
#endif
-/* I use this when I'm looking for weird bugs */
-#define DEBUG_TIMING
-
#if defined(DEBUG_AHA152X)
#undef SKIP_PORTS /* don't display ports */
@@ -287,6 +282,7 @@
#if 0
#endif
+#define DEBUG_SELECTION
#define DEBUG_PHASES
#define DEBUG_RESET
#define DEBUG_ABORT
@@ -297,66 +293,89 @@
/* END OF DEFINES */
+extern long loops_per_sec;
+
/* some additional "phases" for getphase() */
#define P_BUSFREE 1
#define P_PARITY 2
-static int port_base = 0;
-static int this_host = 0;
-static int can_disconnect = 0;
-static int can_doparity = 0;
-static int commands = 0;
+/* possible irq range */
+#define IRQ_MIN 9
+#define IRQ_MAX 12
+#define IRQS IRQ_MAX-IRQ_MIN+1
-#ifdef DEBUG_AHA152X
-unsigned int aha152x_debug = DEBUG_DEFAULT;
-#endif
+enum {
+ not_issued = 0x0001,
+ in_selection = 0x0002,
+ disconnected = 0x0004,
+ aborted = 0x0008,
+ sent_ident = 0x0010,
+ in_other = 0x0020,
+ in_sync = 0x0040,
+ sync_ok = 0x0080,
+};
/* set by aha152x_setup according to the command line */
-static int setup_called = 0;
-static int setup_portbase = 0;
-static int setup_irq = 0;
-static int setup_scsiid = 0;
-static int setup_reconnect = 0;
-static int setup_doparity = 0;
-
+static int setup_count=0;
+static struct aha152x_setup {
+ char *conf;
+ int io_port;
+ int irq;
+ int scsiid;
+ int reconnect;
+ int parity;
+ int synchronous;
#ifdef DEBUG_AHA152X
-static int setup_debug = 0;
+ int debug;
#endif
+} setup[2];
-static char *setup_str = (char *)NULL;
+static struct Scsi_Host *aha152x_host[IRQS];
-enum {
- not_issued = 0x01,
- in_selection = 0x02,
- disconnected = 0x04,
- aborted = 0x08,
- sent_ident = 0x10,
- in_other = 0x20,
-};
+#define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata)
+#define CURRENT_SC (HOSTDATA(shpnt)->current_SC)
+#define ISSUE_SC (HOSTDATA(shpnt)->issue_SC)
+#define DISCONNECTED_SC (HOSTDATA(shpnt)->disconnected_SC)
+#define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->target])
+#define MSG(i) (HOSTDATA(shpnt)->message[i])
+#define MSGLEN (HOSTDATA(shpnt)->message_len)
+#define ADDMSG(x) (MSG(MSGLEN++)=x)
+
+struct aha152x_hostdata {
+ Scsi_Cmnd *issue_SC;
+ Scsi_Cmnd *current_SC;
+ Scsi_Cmnd *disconnected_SC;
+ int aborting;
+ int abortion_complete;
+ int abort_result;
+ int commands;
+
+ int reconnect;
+ int parity;
+ int synchronous;
-/*
- * Command queues:
- * issue_SC : commands that are queued to be issued
- * current_SC : command that's currently using the bus
- * disconnected_SC : commands that that have been disconnected
- */
-static Scsi_Cmnd *issue_SC = NULL;
-static Scsi_Cmnd *current_SC = NULL;
-static Scsi_Cmnd *disconnected_SC = NULL;
+ unsigned char syncrate[8];
+
+ unsigned char message[256];
+ int message_len;
-static int aborting=0, abortion_complete=0, abort_result;
+#ifdef DEBUG_AHA152X
+ int debug;
+#endif
+};
-void aha152x_intr( int irq, struct pt_regs * );
-void aha152x_done( int error );
-void aha152x_setup( char *str, int *ints );
+void aha152x_intr(int irq, struct pt_regs *);
+void aha152x_done(struct Scsi_Host *shpnt, int error);
+void aha152x_setup(char *str, int *ints);
+int aha152x_checksetup(struct aha152x_setup *setup);
-static void aha152x_reset_ports(void);
-static void aha152x_panic(const char *msg);
+static void aha152x_reset_ports(struct Scsi_Host *shpnt);
+static void aha152x_panic(struct Scsi_Host *shpnt, char *msg);
-static void disp_ports(void);
+static void disp_ports(struct Scsi_Host *shpnt);
static void show_command(Scsi_Cmnd *ptr);
-static void show_queues(void);
-static void disp_enintr(void);
+static void show_queues(struct Scsi_Host *shpnt);
+static void disp_enintr(struct Scsi_Host *shpnt);
#if defined(DEBUG_RACE)
static void enter_driver(const char *);
@@ -369,10 +388,7 @@
0x340, /* default first */
0x140
};
-#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
-
-/* possible interrupt channels */
-static unsigned short irqs[] = { 9, 10, 11, 12, 0 };
+#define PORT_COUNT (sizeof(ports) / sizeof(unsigned short))
#if !defined(SKIP_BIOSTEST)
/* possible locations for the Adaptec BIOS */
@@ -385,10 +401,10 @@
(void *) 0xd4000,
(void *) 0xd8000,
(void *) 0xe0000,
- (void *) 0xf0000,
(void *) 0xeb800, /* VTech Platinum SMP */
+ (void *) 0xf0000,
};
-#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( void * ))
+#define ADDRESS_COUNT (sizeof(addresses) / sizeof(void *))
/* signatures for various AIC-6[23]60 based controllers.
The point in detecting signatures is to avoid useless
@@ -408,14 +424,17 @@
{ "Adaptec BIOS: ASW-B626", 0x0f, 22 }, /* on-board controller */
{ "Adaptec ASW-B626 S2", 0x2e6c, 19 }, /* on-board controller */
{ "Adaptec BIOS:AIC-6360", 0xc, 21 }, /* on-board controller */
- { "ScsiPro SP-360 BIOS", 0x2873, 19 }, /* ScsiPro-Controller with AIC-6360 */
+ { "ScsiPro SP-360 BIOS", 0x2873, 19 }, /* ScsiPro-Controller */
{ "GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26 }, /* Gigabyte Local-Bus-SCSI */
+ { "Adaptec BIOS:AVA-282X", 0xc, 21 }, /* Adaptec 282x */
+ { "Adaptec IBM Dock II SCSI", 0x2edd, 24 }, /* IBM Thinkpad Dock II */
+ { "Adaptec BIOS:AHA-1532P", 0x1c, 22 }, /* IBM Thinkpad Dock II SCSI */
};
-#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
+#define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature))
#endif
-static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
+static void do_pause(unsigned amount) /* Pause for amount*10 milliseconds */
{
unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
@@ -426,7 +445,7 @@
/*
* queue services:
*/
-static inline void append_SC( Scsi_Cmnd **SC, Scsi_Cmnd *new_SC)
+static inline void append_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC)
{
Scsi_Cmnd *end;
@@ -435,15 +454,13 @@
*SC=new_SC;
else
{
- for( end=*SC;
- end->host_scribble;
- end = (Scsi_Cmnd *) end->host_scribble )
+ for(end=*SC; end->host_scribble; end = (Scsi_Cmnd *) end->host_scribble)
;
end->host_scribble = (unsigned char *) new_SC;
}
}
-static inline Scsi_Cmnd *remove_first_SC( Scsi_Cmnd **SC )
+static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd **SC)
{
Scsi_Cmnd *ptr;
@@ -453,13 +470,13 @@
return ptr;
}
-static inline Scsi_Cmnd *remove_SC( Scsi_Cmnd **SC, int target, int lun )
+static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, int target, int lun)
{
Scsi_Cmnd *ptr, *prev;
- for( ptr=*SC, prev=NULL;
+ for(ptr=*SC, prev=NULL;
ptr && ((ptr->target!=target) || (ptr->lun!=lun));
- prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble )
+ prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble)
;
if(ptr)
@@ -473,13 +490,13 @@
/*
* read inbound byte and wait for ACK to get low
*/
-static void make_acklow(void)
+static void make_acklow(struct Scsi_Host *shpnt)
{
- SETPORT( SXFRCTL0, CH1|SPIOEN );
+ SETPORT(SXFRCTL0, CH1|SPIOEN);
GETPORT(SCSIDAT);
- SETPORT( SXFRCTL0, CH1 );
+ SETPORT(SXFRCTL0, CH1);
- while( TESTHI( SCSISIG, ACKI ) )
+ while(TESTHI(SCSISIG, ACKI))
;
}
@@ -493,37 +510,36 @@
* P_BUSFREE BUS FREE phase detected
* P_PARITY parity error in DATA phase
*/
-static int getphase(void)
+static int getphase(struct Scsi_Host *shpnt)
{
int phase, sstat1;
- while( 1 )
+ while(1)
{
do
{
- while( !( ( sstat1 = GETPORT( SSTAT1 ) ) & (BUSFREE|SCSIRSTI|REQINIT ) ) )
+ while(!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE|SCSIRSTI|REQINIT)))
;
- if( sstat1 & BUSFREE )
+ if(sstat1 & BUSFREE)
return P_BUSFREE;
- if( sstat1 & SCSIRSTI )
+ if(sstat1 & SCSIRSTI)
{
- /* IBM drive responds with RSTI to RSTO */
printk("aha152x: RESET IN\n");
- SETPORT( SSTAT1, SCSIRSTI );
+ SETPORT(SSTAT1, SCSIRSTI);
}
}
- while( TESTHI( SCSISIG, ACKI ) || TESTLO( SSTAT1, REQINIT ) );
+ while(TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT));
- SETPORT( SSTAT1, CLRSCSIPERR );
+ SETPORT(SSTAT1, CLRSCSIPERR);
- phase = GETPORT( SCSISIG ) & P_MASK ;
+ phase = GETPORT(SCSISIG) & P_MASK ;
- if( TESTHI( SSTAT1, SCSIPERR ) )
+ if(TESTHI(SSTAT1, SCSIPERR))
{
- if( (phase & (CDO|MSGO))==0 ) /* DATA phase */
+ if((phase & (CDO|MSGO))==0) /* DATA phase */
return P_PARITY;
- make_acklow();
+ make_acklow(shpnt);
}
else
return phase;
@@ -531,148 +547,170 @@
}
/* called from init/main.c */
-void aha152x_setup( char *str, int *ints)
+void aha152x_setup(char *str, int *ints)
{
- if(setup_called)
- panic("aha152x: aha152x_setup called twice.\n");
-
- setup_called=ints[0];
- setup_str=str;
+ if(setup_count>2)
+ panic("aha152x: you can only configure up to two controllers\n");
- setup_portbase = ints[0] >= 1 ? ints[1] : 0x340;
- setup_irq = ints[0] >= 2 ? ints[2] : 11;
- setup_scsiid = ints[0] >= 3 ? ints[3] : 7;
- setup_reconnect = ints[0] >= 4 ? ints[4] : 1;
- setup_doparity = ints[0] >= 5 ? ints[5] : 1;
+ setup[setup_count].conf = str;
+ setup[setup_count].io_port = ints[0] >= 1 ? ints[1] : 0x340;
+ setup[setup_count].irq = ints[0] >= 2 ? ints[2] : 11;
+ setup[setup_count].scsiid = ints[0] >= 3 ? ints[3] : 7;
+ setup[setup_count].reconnect = ints[0] >= 4 ? ints[4] : 1;
+ setup[setup_count].parity = ints[0] >= 5 ? ints[5] : 1;
+ setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 0 /* FIXME: 1 */;
#ifdef DEBUG_AHA152X
- setup_debug = ints[0] >= 6 ? ints[6] : DEBUG_DEFAULT;
+ setup[setup_count].debug = ints[0] >= 7 ? ints[7] : DEBUG_DEFAULT;
+ if(ints[0]>7)
+ {
+ printk("aha152x: usage: aha152x=<PORTBASE>[,<IRQ>[,<SCSI ID>"
+ "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>,[,<DEBUG>]]]]]]\n");
+#else
+ if(ints[0]>6)
+ {
+ printk("aha152x: usage: aha152x=<PORTBASE>[,<IRQ>[,<SCSI ID>"
+ "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>]]]]]\n");
#endif
+ }
+ else
+ setup_count++;
}
/*
Test, if port_base is valid.
*/
-static int aha152x_porttest(int port_base)
+static int aha152x_porttest(int io_port)
{
int i;
- if(check_region(port_base, 0x20))
+ if(check_region(io_port, IO_RANGE))
return 0;
- SETPORT( DMACNTRL1, 0 ); /* reset stack pointer */
+ SETPORT(io_port+O_DMACNTRL1, 0); /* reset stack pointer */
for(i=0; i<16; i++)
- SETPORT( STACK, i );
+ SETPORT(io_port+O_STACK, i);
- SETPORT( DMACNTRL1, 0 ); /* reset stack pointer */
- for(i=0; i<16 && GETPORT(STACK)==i; i++)
+ SETPORT(io_port+O_DMACNTRL1, 0); /* reset stack pointer */
+ for(i=0; i<16 && GETPORT(io_port+O_STACK)==i; i++)
;
return(i==16);
}
+int aha152x_checksetup(struct aha152x_setup *setup)
+{
+ int i;
+
+#ifndef PCMCIA
+ for(i=0; i<PORT_COUNT && (setup->io_port != ports[i]); i++)
+ ;
+
+ if(i==PORT_COUNT)
+ return 0;
+#endif
+
+ if(!aha152x_porttest(setup->io_port))
+ return 0;
+
+ if((setup->irq < IRQ_MIN) && (setup->irq > IRQ_MAX))
+ return 0;
+
+ if((setup->scsiid < 0) || (setup->scsiid > 7))
+ return 0;
+
+ if((setup->reconnect < 0) || (setup->reconnect > 1))
+ return 0;
+
+ if((setup->parity < 0) || (setup->parity > 1))
+ return 0;
+
+ if((setup->synchronous < 0) || (setup->synchronous > 1))
+ return 0;
+
+ return 1;
+}
+
+
int aha152x_detect(Scsi_Host_Template * tpnt)
{
- int i, ok;
+ int i, j, ok;
#if defined(AUTOCONF)
aha152x_config conf;
#endif
- int interrupt_level;
- struct Scsi_Host *hreg;
tpnt->proc_dir = &proc_scsi_aha152x;
- if(setup_called)
+ for(i=0; i<IRQS; i++)
+ aha152x_host[i] = (struct Scsi_Host *) NULL;
+
+ if(setup_count)
{
printk("aha152x: processing commandline: ");
-#ifdef DEBUG_AHA152X
- if(setup_called>6)
-#else
- if(setup_called>5)
-#endif
+ for(i=0; i<setup_count; i++)
+ if(!aha152x_checksetup(&setup[i]))
{
- printk("\naha152x: %s\n", setup_str );
-#ifdef DEBUG_AHA152X
- printk("aha152x: usage: aha152x=<PORTBASE>[,<IRQ>[,<SCSI ID>[,<RECONNECT>[,<PARITY>[,<DEBUG>]]]]]\n");
-#else
- printk("aha152x: usage: aha152x=<PORTBASE>[,<IRQ>[,<SCSI ID>[,<RECONNECT>[,<PARITY>]]]]\n");
-#endif
- panic("aha152x panics in line %d", __LINE__);
+ printk("\naha152x: %s\n", setup[i].conf);
+ printk("aha152x: invalid line (controller=%d)\n", i+1);
}
- port_base = setup_portbase;
- interrupt_level = setup_irq;
- this_host = setup_scsiid;
- can_disconnect = setup_reconnect;
- can_doparity = setup_doparity;
-#ifdef DEBUG_AHA152X
- aha152x_debug = setup_debug;
-#endif
-
-#ifndef PCMCIA
- for( i=0; i<PORT_COUNT && (port_base != ports[i]); i++)
- ;
-
- if(i==PORT_COUNT)
- {
- printk("unknown portbase 0x%03x\n", port_base);
- panic("aha152x panics in line %d", __LINE__);
+ printk("ok\n");
}
-#endif
- if(!aha152x_porttest(port_base))
+#ifdef SETUP0
+ if(setup_count<2)
{
- printk("portbase 0x%03x fails probe\n", port_base);
-#ifdef PCMCIA
- return 0;
-#else
- panic("aha152x panics in line %d", __LINE__);
-#endif
- }
+ struct aha152x_setup override = SETUP0;
-#ifndef PCMCIA
- i=0;
- while(irqs[i] && (interrupt_level!=irqs[i]))
- i++;
- if(!irqs[i])
+ if(setup_count==0 || (override.io_port != setup[0].io_port))
+ if(!aha152x_checksetup(&override))
{
- printk("illegal IRQ %d\n", interrupt_level);
- panic("aha152x panics in line %d", __LINE__);
+ printk("\naha152x: SETUP0 (0x%x, %d, %d, %d, %d, %d) invalid\n",
+ override.io_port,
+ override.irq,
+ override.scsiid,
+ override.reconnect,
+ override.parity,
+ override.synchronous);
}
-#endif
-
- if( (this_host < 0) || (this_host > 7) )
- {
- printk("illegal SCSI ID %d\n", this_host);
- panic("aha152x panics in line %d", __LINE__);
+ else
+ setup[setup_count++] = override;
}
+#endif
- if( (can_disconnect < 0) || (can_disconnect > 1) )
+#ifdef SETUP1
+ if(setup_count<2)
{
- printk("reconnect %d should be 0 or 1\n", can_disconnect);
- panic("aha152x panics in line %d", __LINE__);
- }
+ struct aha152x_setup override = SETUP1;
- if( (can_doparity < 0) || (can_doparity > 1) )
+ if(setup_count==0 || (override.io_port != setup[0].io_port))
+ if(!aha152x_checksetup(&override))
{
- printk("parity %d should be 0 or 1\n", can_doparity);
- panic("aha152x panics in line %d", __LINE__);
- }
- printk("ok\n");
+ printk("\naha152x: SETUP1 (0x%x, %d, %d, %d, %d, %d) invalid\n",
+ override.io_port,
+ override.irq,
+ override.scsiid,
+ override.reconnect,
+ override.parity,
+ override.synchronous);
}
else
+ setup[setup_count++] = override;
+ }
+#endif
+
+#if defined(AUTOCONF)
+ if(setup_count<2)
{
#if !defined(SKIP_BIOSTEST)
- int j;
-
ok=0;
- for( i=0; i < ADDRESS_COUNT && !ok; i++)
- for( j=0; (j < SIGNATURE_COUNT) && !ok; j++)
+ for(i=0; i < ADDRESS_COUNT && !ok; i++)
+ for(j=0; (j < SIGNATURE_COUNT) && !ok; j++)
ok=!memcmp((void *) addresses[i]+signatures[j].sig_offset,
(void *) signatures[j].signature,
(int) signatures[j].sig_length);
- if(!ok)
+ if(!ok && setup_count==0)
return 0;
printk("aha152x: BIOS test: passed, ");
@@ -680,137 +718,149 @@
printk("aha152x: ");
#endif /* !SKIP_BIOSTEST */
-#if !defined(PORTBASE)
- printk("porttest: ");
- for( i=0; i<PORT_COUNT && !aha152x_porttest(ports[i]); i++)
- ;
-
- if(i==PORT_COUNT)
- {
- printk("failed\n");
- return 0;
+ for(i=0; i<PORT_COUNT && setup_count<2; i++)
+ {
+ if((setup_count==1) && (setup[0].io_port == ports[i]))
+ continue;
+
+ if(aha152x_porttest(ports[i]))
+ {
+ setup[setup_count].io_port = ports[i];
+
+ conf.cf_port =
+ (GETPORT(ports[i]+O_PORTA)<<8) + GETPORT(ports[i]+O_PORTB);
+
+ setup[setup_count].irq = IRQ_MIN + conf.cf_irq;
+ setup[setup_count].scsiid = conf.cf_id;
+ setup[setup_count].reconnect = conf.cf_tardisc;
+ setup[setup_count].parity = !conf.cf_parity;
+ setup[setup_count].synchronous = 0 /* FIXME: conf.cf_syncneg */;
+ setup[setup_count].debug = DEBUG_DEFAULT;
+ setup_count++;
+ }
}
- else
- port_base=ports[i];
- printk("ok, ");
-#else
- port_base=PORTBASE;
-#endif /* !PORTBASE */
-#if defined(AUTOCONF)
+ printk("auto configuration: ok, ");
+ }
+#endif
- conf.cf_port = (GETPORT(PORTA)<<8) + GETPORT(PORTB);
+ printk("detection complete\n");
- interrupt_level = irqs[conf.cf_irq];
- this_host = conf.cf_id;
- can_disconnect = conf.cf_tardisc;
- can_doparity = !conf.cf_parity;
+ for(i=0; i<setup_count; i++)
+ {
+ struct Scsi_Host *shpnt;
- printk("auto configuration: ok, ");
+ shpnt = aha152x_host[setup[i].irq-IRQ_MIN] =
+ scsi_register(tpnt, sizeof(struct aha152x_hostdata));
-#endif /* AUTOCONF */
+ shpnt->io_port = setup[i].io_port;
+ shpnt->n_io_port = IO_RANGE;
+ shpnt->irq = setup[i].irq;
-#if defined(IRQ)
- interrupt_level = IRQ;
-#endif
+ ISSUE_SC = (Scsi_Cmnd *) NULL;
+ CURRENT_SC = (Scsi_Cmnd *) NULL;
+ DISCONNECTED_SC = (Scsi_Cmnd *) NULL;
-#if defined(SCSI_ID)
- this_host = SCSI_ID;
-#endif
+ HOSTDATA(shpnt)->reconnect = setup[i].reconnect;
+ HOSTDATA(shpnt)->parity = setup[i].parity;
+ HOSTDATA(shpnt)->synchronous = setup[i].synchronous;
+ HOSTDATA(shpnt)->debug = setup[i].debug;
-#if defined(RECONNECT)
- can_disconnect=RECONNECT;
-#endif
+ HOSTDATA(shpnt)->aborting = 0;
+ HOSTDATA(shpnt)->abortion_complete = 0;
+ HOSTDATA(shpnt)->abort_result = 0;
+ HOSTDATA(shpnt)->commands = 0;
-#if defined(PARITY)
- can_doparity=PARITY;
-#endif
- }
+ HOSTDATA(shpnt)->message_len = 0;
- printk("detection complete\n");
+ for(j=0; j<8; j++)
+ HOSTDATA(shpnt)->syncrate[j] = 0;
- ok = request_irq(interrupt_level, aha152x_intr, SA_INTERRUPT, "aha152x");
+ ok = request_irq(setup[i].irq, aha152x_intr, SA_INTERRUPT, "aha152x");
if(ok<0)
{
if(ok == -EINVAL)
{
- printk("aha152x: bad IRQ %d.\n", interrupt_level);
+ printk("aha152x%d: bad IRQ %d.\n", i, setup[i].irq);
printk(" Contact author.\n");
}
else
- if( ok == -EBUSY)
- printk( "aha152x: IRQ %d already in use. Configure another.\n",
- interrupt_level);
+ if(ok == -EBUSY)
+ printk("aha152x%d: IRQ %d already in use. Configure another.\n",
+ i, setup[i].irq);
else
{
- printk( "\naha152x: Unexpected error code on requesting IRQ %d.\n",
- interrupt_level);
+ printk("\naha152x%d: Unexpected error code on"
+ " requesting IRQ %d.\n", i, setup[i].irq);
printk(" Contact author.\n");
}
- panic("aha152x: driver needs an IRQ.\n");
+ printk("aha152x: driver needs an IRQ.\n");
+ continue;
}
- SETPORT( SCSIID, this_host << 4 );
- tpnt->this_id=this_host;
+ SETPORT(SCSIID, setup[i].scsiid << 4);
+ shpnt->this_id=setup[i].scsiid;
- if(can_disconnect)
- tpnt->can_queue=AHA152X_MAXQUEUE;
+ if(setup[i].reconnect)
+ shpnt->hostt->can_queue=AHA152X_MAXQUEUE;
/* RESET OUT */
- SETBITS(SCSISEQ, SCSIRSTO );
+ SETBITS(SCSISEQ, SCSIRSTO);
do_pause(30);
- CLRBITS(SCSISEQ, SCSIRSTO );
+ CLRBITS(SCSISEQ, SCSIRSTO);
do_pause(60);
- aha152x_reset(NULL);
+ aha152x_reset_ports(shpnt);
+
+ printk("aha152x%d: vital data: PORTBASE=0x%03x, IRQ=%d, SCSI ID=%d,"
+ " reconnect=%s, parity=%s, synchronous=%s\n",
+ i,
+ shpnt->io_port,
+ shpnt->irq,
+ shpnt->this_id,
+ HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled",
+ HOSTDATA(shpnt)->parity ? "enabled" : "disabled",
+ HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled");
- printk("aha152x: vital data: PORTBASE=0x%03x, IRQ=%d, SCSI ID=%d, reconnect=%s, parity=%s\n",
- port_base,
- interrupt_level,
- this_host,
- can_disconnect ? "enabled" : "disabled",
- can_doparity ? "enabled" : "disabled");
-
- request_region(port_base, 0x20, "aha152x"); /* Register */
-
- hreg = scsi_register(tpnt, 0);
- hreg->io_port = port_base;
- hreg->n_io_port = 0x20;
- hreg->irq = interrupt_level;
+ request_region(shpnt->io_port, IO_RANGE, "aha152x"); /* Register */
/* not expecting any interrupts */
SETPORT(SIMODE0, 0);
SETPORT(SIMODE1, 0);
- SETBITS( DMACNTRL0, INTEN);
- return 1;
+ SETBITS(DMACNTRL0, INTEN);
+ }
+
+ return (setup_count>0);
}
/*
* Queue a command and setup interrupts for a free bus.
*/
-int aha152x_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
+int aha152x_queue(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{
+ struct Scsi_Host *shpnt = SCpnt->host;
unsigned long flags;
#if defined(DEBUG_RACE)
enter_driver("queue");
#else
#if defined(DEBUG_QUEUE)
- if(aha152x_debug & debug_queue)
+ if(HOSTDATA(shpnt)->debug & debug_queue)
printk("aha152x: queue(), ");
#endif
#endif
#if defined(DEBUG_QUEUE)
- if(aha152x_debug & debug_queue)
+ if(HOSTDATA(shpnt)->debug & debug_queue)
{
- printk( "SCpnt (target = %d lun = %d cmnd = ", SCpnt->target, SCpnt->lun);
+ printk("SCpnt (target = %d lun = %d cmnd = ",
+ SCpnt->target, SCpnt->lun);
print_command(SCpnt->cmnd);
- printk( ", cmd_len=%d, pieces = %d size = %u), ",
- SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen );
- disp_ports();
+ printk(", cmd_len=%d, pieces = %d size = %u), ",
+ SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);
+ disp_ports(shpnt);
}
#endif
@@ -825,7 +875,8 @@
SCpnt->SCp.phase = not_issued;
if (SCpnt->use_sg)
{
- SCpnt->SCp.buffer = (struct scatterlist *)SCpnt->request_buffer;
+ SCpnt->SCp.buffer =
+ (struct scatterlist *) SCpnt->request_buffer;
SCpnt->SCp.ptr = SCpnt->SCp.buffer->address;
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
@@ -846,21 +897,21 @@
/* Turn led on, when this is the first command. */
save_flags(flags);
cli();
- commands++;
- if(commands==1)
- SETPORT( PORTA, 1 );
+ HOSTDATA(shpnt)->commands++;
+ if(HOSTDATA(shpnt)->commands==1)
+ SETPORT(PORTA, 1);
#if defined(DEBUG_QUEUES)
- if(aha152x_debug & debug_queues)
- printk("i+ (%d), ", commands );
+ if(HOSTDATA(shpnt)->debug & debug_queues)
+ printk("i+ (%d), ", HOSTDATA(shpnt)->commands);
#endif
- append_SC( &issue_SC, SCpnt);
+ append_SC(&ISSUE_SC, SCpnt);
/* Enable bus free interrupt, when we aren't currently on the bus */
- if(!current_SC)
+ if(!CURRENT_SC)
{
- SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );
- SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);
+ SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+ SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
}
restore_flags(flags);
@@ -872,11 +923,11 @@
}
/*
- * We only support command in interrupt-driven fashion
+ * We only support commands in interrupt-driven fashion
*/
-int aha152x_command( Scsi_Cmnd *SCpnt )
+int aha152x_command(Scsi_Cmnd *SCpnt)
{
- printk( "aha152x: interrupt driven driver; use aha152x_queue()\n" );
+ printk("aha152x: interrupt driven driver; use aha152x_queue()\n");
return -1;
}
@@ -884,8 +935,9 @@
* Abort a queued command
* (commands that are on the bus can't be aborted easily)
*/
-int aha152x_abort( Scsi_Cmnd *SCpnt)
+int aha152x_abort(Scsi_Cmnd *SCpnt)
{
+ struct Scsi_Host *shpnt = SCpnt->host;
unsigned long flags;
Scsi_Cmnd *ptr, *prev;
@@ -893,16 +945,15 @@
cli();
#if defined(DEBUG_ABORT)
- if(aha152x_debug & debug_abort)
+ if(HOSTDATA(shpnt)->debug & debug_abort)
{
- printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned int) SCpnt );
-
- show_queues();
+ printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned int) SCpnt);
+ show_queues(shpnt);
}
#endif
/* look for command in issue queue */
- for( ptr=issue_SC, prev=NULL;
+ for(ptr=ISSUE_SC, prev=NULL;
ptr && ptr!=SCpnt;
prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)
;
@@ -913,7 +964,7 @@
if(prev)
prev->host_scribble = ptr->host_scribble;
else
- issue_SC = (Scsi_Cmnd *) ptr->host_scribble;
+ ISSUE_SC = (Scsi_Cmnd *) ptr->host_scribble;
restore_flags(flags);
ptr->host_scribble = NULL;
@@ -924,11 +975,11 @@
/* if the bus is busy or a command is currently processed,
we can't do anything more */
- if ( TESTLO(SSTAT1, BUSFREE) || (current_SC && current_SC!=SCpnt))
+ if (TESTLO(SSTAT1, BUSFREE) || (CURRENT_SC && CURRENT_SC!=SCpnt))
{
/* fail abortion, if bus is busy */
- if(!current_SC)
+ if(!CURRENT_SC)
printk("bus busy w/o current command, ");
restore_flags(flags);
@@ -937,56 +988,58 @@
/* bus is free */
- if(current_SC)
+ if(CURRENT_SC)
{
/* target entered bus free before COMMAND COMPLETE, nothing to abort */
restore_flags(flags);
- current_SC->result = DID_ERROR << 16;
- current_SC->scsi_done(current_SC);
- current_SC = (Scsi_Cmnd *) NULL;
+ CURRENT_SC->result = DID_ERROR << 16;
+ CURRENT_SC->scsi_done(CURRENT_SC);
+ CURRENT_SC = (Scsi_Cmnd *) NULL;
return SCSI_ABORT_SUCCESS;
}
/* look for command in disconnected queue */
- for( ptr=disconnected_SC, prev=NULL;
+ for(ptr=DISCONNECTED_SC, prev=NULL;
ptr && ptr!=SCpnt;
prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)
;
if(ptr)
- if(!aborting)
+ if(!HOSTDATA(shpnt)->aborting)
{
/* dequeue */
if(prev)
prev->host_scribble = ptr->host_scribble;
else
- disconnected_SC = (Scsi_Cmnd *) ptr->host_scribble;
+ DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble;
/* set command current and initiate selection,
let the interrupt routine take care of the abortion */
- current_SC = ptr;
+ CURRENT_SC = ptr;
ptr->SCp.phase = in_selection|aborted;
- SETPORT( SCSIID, (this_host << OID_) | current_SC->target );
+ SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);
+
+ ADDMSG(ABORT);
/* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */
- SETPORT( SIMODE0, ENSELDO | (disconnected_SC ? ENSELDI : 0) );
- SETPORT( SIMODE1, ENSELTIMO );
+ SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
+ SETPORT(SIMODE1, ENSELTIMO);
/* Enable SELECTION OUT sequence */
- SETBITS(SCSISEQ, ENSELO | ENAUTOATNO );
+ SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);
- SETBITS( DMACNTRL0, INTEN );
- abort_result=SCSI_ABORT_SUCCESS;
- aborting++;
- abortion_complete=0;
+ SETBITS(DMACNTRL0, INTEN);
+ HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS;
+ HOSTDATA(shpnt)->aborting++;
+ HOSTDATA(shpnt)->abortion_complete=0;
sti(); /* Hi Eric, guess what ;-) */
/* sleep until the abortion is complete */
- while(!abortion_complete)
+ while(!HOSTDATA(shpnt)->abortion_complete)
barrier();
- aborting=0;
- return abort_result;
+ HOSTDATA(shpnt)->aborting=0;
+ return HOSTDATA(shpnt)->abort_result;
}
else
{
@@ -1004,7 +1057,7 @@
/*
* Restore default values to the AIC-6260 registers and reset the fifos
*/
-static void aha152x_reset_ports(void)
+static void aha152x_reset_ports(struct Scsi_Host *shpnt)
{
/* disable interrupts */
SETPORT(DMACNTRL0, RSTFIFO);
@@ -1012,7 +1065,7 @@
SETPORT(SCSISEQ, 0);
SETPORT(SXFRCTL1, 0);
- SETPORT( SCSISIG, 0);
+ SETPORT(SCSISIG, 0);
SETPORT(SCSIRATE, 0);
/* clear all interrupt conditions */
@@ -1031,45 +1084,47 @@
SETPORT(SXFRCTL0, CH1);
/* enable interrupts */
- SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );
- SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);
+ SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+ SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
}
/*
* Reset registers, reset a hanging bus and
* kill active and disconnected commands for target w/o soft reset
*/
-int aha152x_reset(Scsi_Cmnd * __unused)
+int aha152x_reset(Scsi_Cmnd *SCpnt)
{
+ struct Scsi_Host *shpnt = SCpnt->host;
unsigned long flags;
Scsi_Cmnd *ptr, *prev, *next;
- aha152x_reset_ports();
+ aha152x_reset_ports(shpnt);
/* Reset, if bus hangs */
- if( TESTLO( SSTAT1, BUSFREE ) )
+ if(TESTLO(SSTAT1, BUSFREE))
{
- CLRBITS( DMACNTRL0, INTEN );
+ CLRBITS(DMACNTRL0, INTEN);
#if defined(DEBUG_RESET)
- if(aha152x_debug & debug_reset)
+ if(HOSTDATA(shpnt)->debug & debug_reset)
{
printk("aha152x: reset(), bus not free: SCSI RESET OUT\n");
- show_queues();
+ show_queues(shpnt);
}
#endif
- if(current_SC && !current_SC->device->soft_reset)
+ ptr=CURRENT_SC;
+ if(ptr && !ptr->device->soft_reset)
{
- current_SC->host_scribble = NULL;
- current_SC->result = DID_RESET << 16;
- current_SC->scsi_done(current_SC);
- current_SC=NULL;
+ ptr->host_scribble = NULL;
+ ptr->result = DID_RESET << 16;
+ ptr->scsi_done(CURRENT_SC);
+ CURRENT_SC=NULL;
}
save_flags(flags);
cli();
- prev=NULL; ptr=disconnected_SC;
+ prev=NULL; ptr=DISCONNECTED_SC;
while(ptr)
{
if(!ptr->device->soft_reset)
@@ -1077,13 +1132,13 @@
if(prev)
prev->host_scribble = ptr->host_scribble;
else
- disconnected_SC = (Scsi_Cmnd *) ptr->host_scribble;
+ DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble;
next = (Scsi_Cmnd *) ptr->host_scribble;
ptr->host_scribble = NULL;
ptr->result = DID_RESET << 16;
- ptr->scsi_done(ptr);
+ ptr->scsi_done(ptr);
ptr = next;
}
@@ -1095,11 +1150,11 @@
}
restore_flags(flags);
-#if defined( DEBUG_RESET )
- if(aha152x_debug & debug_reset)
+#if defined(DEBUG_RESET)
+ if(HOSTDATA(shpnt)->debug & debug_reset)
{
printk("commands on targets w/ soft-resets:\n");
- show_queues();
+ show_queues(shpnt);
}
#endif
@@ -1109,10 +1164,10 @@
SETPORT(SCSISEQ, 0);
do_pause(60);
- SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );
- SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);
+ SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+ SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
- SETPORT( DMACNTRL0, INTEN );
+ SETPORT(DMACNTRL0, INTEN);
}
return SCSI_RESET_SUCCESS;
@@ -1121,14 +1176,13 @@
/*
* Return the "logical geometry"
*/
-int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array )
+int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array)
{
int size = disk->capacity;
#if defined(DEBUG_BIOSPARAM)
- if(aha152x_debug & debug_biosparam)
- printk("aha152x_biosparam: dev=%s, size=%d, ",
- kdevname(dev), size);
+ if(HOSTDATA(shpnt)->debug & debug_biosparam)
+ printk("aha152x_biosparam: dev=%s, size=%d, ", kdevname(dev), size);
#endif
/* I took this from other SCSI drivers, since it provides
@@ -1138,7 +1192,7 @@
info_array[2]=size>>11;
#if defined(DEBUG_BIOSPARAM)
- if(aha152x_debug & debug_biosparam)
+ if(HOSTDATA(shpnt)->debug & debug_biosparam)
{
printk("bios geometry: head=%d, sec=%d, cyl=%d\n",
info_array[0], info_array[1], info_array[2]);
@@ -1152,54 +1206,54 @@
/*
* Internal done function
*/
-void aha152x_done( int error )
+void aha152x_done(struct Scsi_Host *shpnt, int error)
{
unsigned long flags;
Scsi_Cmnd *done_SC;
#if defined(DEBUG_DONE)
- if(aha152x_debug & debug_done)
+ if(HOSTDATA(shpnt)->debug & debug_done)
{
printk("\naha152x: done(), ");
- disp_ports();
+ disp_ports(shpnt);
}
#endif
- if (current_SC)
+ if (CURRENT_SC)
{
#if defined(DEBUG_DONE)
- if(aha152x_debug & debug_done)
+ if(HOSTDATA(shpnt)->debug & debug_done)
printk("done(%x), ", error);
#endif
save_flags(flags);
cli();
- done_SC = current_SC;
- current_SC = NULL;
+ done_SC = CURRENT_SC;
+ CURRENT_SC = NULL;
/* turn led off, when no commands are in the driver */
- commands--;
- if(!commands)
- SETPORT( PORTA, 0 ); /* turn led off */
+ HOSTDATA(shpnt)->commands--;
+ if(!HOSTDATA(shpnt)->commands)
+ SETPORT(PORTA, 0); /* turn led off */
#if defined(DEBUG_QUEUES)
- if(aha152x_debug & debug_queues)
- printk("ok (%d), ", commands);
+ if(HOSTDATA(shpnt)->debug & debug_queues)
+ printk("ok (%d), ", HOSTDATA(shpnt)->commands);
#endif
restore_flags(flags);
- SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );
- SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);
+ SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+ SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
#if defined(DEBUG_PHASES)
- if(aha152x_debug & debug_phases)
+ if(HOSTDATA(shpnt)->debug & debug_phases)
printk("BUS FREE loop, ");
#endif
- while( TESTLO( SSTAT1, BUSFREE ) )
+ while(TESTLO(SSTAT1, BUSFREE))
;
#if defined(DEBUG_PHASES)
- if(aha152x_debug & debug_phases)
+ if(HOSTDATA(shpnt)->debug & debug_phases)
printk("BUS FREE\n");
#endif
@@ -1207,27 +1261,28 @@
if(done_SC->scsi_done)
{
#if defined(DEBUG_DONE)
- if(aha152x_debug & debug_done)
+ if(HOSTDATA(shpnt)->debug & debug_done)
printk("calling scsi_done, ");
#endif
- done_SC->scsi_done( done_SC );
+ done_SC->scsi_done(done_SC);
#if defined(DEBUG_DONE)
- if(aha152x_debug & debug_done)
+ if(HOSTDATA(shpnt)->debug & debug_done)
printk("done returned, ");
#endif
}
else
- panic( "aha152x: current_SC->scsi_done() == NULL" );
+ panic("aha152x: current_SC->scsi_done() == NULL");
}
else
- aha152x_panic( "done() called outside of command" );
+ aha152x_panic(shpnt, "done() called outside of command");
}
/*
* Interrupts handler (main routine of the driver)
*/
-void aha152x_intr( int irqno, struct pt_regs * regs )
+void aha152x_intr(int irqno, struct pt_regs * regs)
{
+ struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN];
unsigned int flags;
int done=0, phase;
@@ -1235,7 +1290,7 @@
enter_driver("intr");
#else
#if defined(DEBUG_INTR)
- if(aha152x_debug & debug_intr)
+ if(HOSTDATA(shpnt)->debug & debug_intr)
printk("\naha152x: intr(), ");
#endif
#endif
@@ -1244,74 +1299,76 @@
INTEN has to be restored, when we're ready to leave
intr(). To avoid race conditions we have to return
immediately afterwards. */
- CLRBITS( DMACNTRL0, INTEN);
+ CLRBITS(DMACNTRL0, INTEN);
sti(); /* Yes, sti() really needs to be here */
/* disconnected target is trying to reconnect.
Only possible, if we have disconnected nexuses and
nothing is occupying the bus.
*/
- if( TESTHI( SSTAT0, SELDI ) &&
- disconnected_SC &&
- ( !current_SC || ( current_SC->SCp.phase & in_selection ) )
+ if(TESTHI(SSTAT0, SELDI) &&
+ DISCONNECTED_SC &&
+ (!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection))
)
{
int identify_msg, target, i;
/* Avoid conflicts when a target reconnects
while we are trying to connect to another. */
- if(current_SC)
+ if(CURRENT_SC)
{
#if defined(DEBUG_QUEUES)
- if(aha152x_debug & debug_queues)
+ if(HOSTDATA(shpnt)->debug & debug_queues)
printk("i+, ");
#endif
save_flags(flags);
cli();
- append_SC( &issue_SC, current_SC);
- current_SC=NULL;
+ append_SC(&ISSUE_SC, CURRENT_SC);
+ CURRENT_SC=NULL;
restore_flags(flags);
}
/* disable sequences */
- SETPORT( SCSISEQ, 0 );
- SETPORT( SSTAT0, CLRSELDI );
- SETPORT( SSTAT1, CLRBUSFREE );
+ SETPORT(SCSISEQ, 0);
+ SETPORT(SSTAT0, CLRSELDI);
+ SETPORT(SSTAT1, CLRBUSFREE);
#if defined(DEBUG_QUEUES) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_queues|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_queues|debug_phases))
printk("reselected, ");
#endif
- i = GETPORT(SELID) & ~(1 << this_host);
+ i = GETPORT(SELID) & ~(1 << shpnt->this_id);
target=0;
if(i)
- for( ; (i & 1)==0; target++, i>>=1)
+ for(; (i & 1)==0; target++, i>>=1)
;
else
- aha152x_panic("reconnecting target unknown");
+ aha152x_panic(shpnt, "reconnecting target unknown");
#if defined(DEBUG_QUEUES)
- if(aha152x_debug & debug_queues)
- printk("SELID=%02x, target=%d, ", GETPORT(SELID), target );
+ if(HOSTDATA(shpnt)->debug & debug_queues)
+ printk("SELID=%02x, target=%d, ", GETPORT(SELID), target);
#endif
- SETPORT( SCSIID, (this_host << OID_) | target );
- SETPORT( SCSISEQ, ENRESELI );
+ SETPORT(SCSIID, (shpnt->this_id << OID_) | target);
+ SETPORT(SCSISEQ, ENRESELI);
+
+ if(TESTLO(SSTAT0, SELDI))
+ aha152x_panic(shpnt, "RESELI failed");
- if(TESTLO( SSTAT0, SELDI ))
- aha152x_panic("RESELI failed");
+ SETPORT(SCSIRATE, HOSTDATA(shpnt)->syncrate[target]&0x7f);
- SETPORT( SCSISIG, P_MSGI );
+ SETPORT(SCSISIG, P_MSGI);
/* Get identify message */
- if((i=getphase())!=P_MSGI)
+ if((i=getphase(shpnt))!=P_MSGI)
{
printk("target doesn't enter MSGI to identify (phase=%02x)\n", i);
- aha152x_panic("unknown lun");
+ aha152x_panic(shpnt, "unknown lun");
}
- SETPORT( SCSISEQ, 0 );
+ SETPORT(SCSISEQ, 0);
- SETPORT( SXFRCTL0, CH1);
+ SETPORT(SXFRCTL0, CH1);
identify_msg = GETPORT(SCSIBUS);
@@ -1319,87 +1376,87 @@
{
printk("target=%d, inbound message (%02x) != IDENTIFY\n",
target, identify_msg);
- aha152x_panic("unknown lun");
+ aha152x_panic(shpnt, "unknown lun");
}
- make_acklow();
- getphase();
+ make_acklow(shpnt);
+ getphase(shpnt);
#if defined(DEBUG_QUEUES)
- if(aha152x_debug & debug_queues)
- printk("identify=%02x, lun=%d, ", identify_msg, identify_msg & 0x3f );
+ if(HOSTDATA(shpnt)->debug & debug_queues)
+ printk("identify=%02x, lun=%d, ", identify_msg, identify_msg & 0x3f);
#endif
save_flags(flags);
cli();
#if defined(DEBUG_QUEUES)
- if(aha152x_debug & debug_queues)
+ if(HOSTDATA(shpnt)->debug & debug_queues)
printk("d-, ");
#endif
- current_SC = remove_SC( &disconnected_SC,
+ CURRENT_SC = remove_SC(&DISCONNECTED_SC,
target,
- identify_msg & 0x3f );
+ identify_msg & 0x3f);
- if(!current_SC)
+ if(!CURRENT_SC)
{
- printk("lun=%d, ", identify_msg & 0x3f );
- aha152x_panic("no disconnected command for that lun");
+ printk("lun=%d, ", identify_msg & 0x3f);
+ aha152x_panic(shpnt, "no disconnected command for that lun");
}
- current_SC->SCp.phase &= ~disconnected;
+ CURRENT_SC->SCp.phase &= ~disconnected;
restore_flags(flags);
- SETPORT( SIMODE0, 0 );
- SETPORT( SIMODE1, ENPHASEMIS|ENBUSFREE );
+ SETPORT(SIMODE0, 0);
+ SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE);
#if defined(DEBUG_RACE)
leave_driver("(reselected) intr");
#endif
- SETBITS( DMACNTRL0, INTEN);
+ SETBITS(DMACNTRL0, INTEN);
return;
}
/* Check, if we aren't busy with a command */
- if(!current_SC)
+ if(!CURRENT_SC)
{
/* bus is free to issue a queued command */
- if(TESTHI( SSTAT1, BUSFREE) && issue_SC)
+ if(TESTHI(SSTAT1, BUSFREE) && ISSUE_SC)
{
save_flags(flags);
cli();
#if defined(DEBUG_QUEUES)
- if(aha152x_debug & debug_queues)
+ if(HOSTDATA(shpnt)->debug & debug_queues)
printk("i-, ");
#endif
- current_SC = remove_first_SC( &issue_SC );
+ CURRENT_SC = remove_first_SC(&ISSUE_SC);
restore_flags(flags);
#if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_intr|debug_selection|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases))
printk("issuing command, ");
#endif
- current_SC->SCp.phase = in_selection;
+ CURRENT_SC->SCp.phase = in_selection;
- #if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_intr|debug_selection|debug_phases))
- printk("selecting %d, ", current_SC->target);
- #endif
- SETPORT( SCSIID, (this_host << OID_) | current_SC->target );
+#if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
+ if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases))
+ printk("selecting %d, ", CURRENT_SC->target);
+#endif
+ SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);
/* Enable interrupts for SELECTION OUT DONE and SELECTION OUT INITIATED */
- SETPORT( SXFRCTL1, can_doparity ? (ENSPCHK|ENSTIMER) : ENSTIMER);
+ SETPORT(SXFRCTL1, HOSTDATA(shpnt)->parity ? (ENSPCHK|ENSTIMER) : ENSTIMER);
/* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */
- SETPORT( SIMODE0, ENSELDO | (disconnected_SC ? ENSELDI : 0) );
- SETPORT( SIMODE1, ENSELTIMO );
+ SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
+ SETPORT(SIMODE1, ENSELTIMO);
/* Enable SELECTION OUT sequence */
- SETBITS(SCSISEQ, ENSELO | ENAUTOATNO );
+ SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);
- #if defined(DEBUG_RACE)
+#if defined(DEBUG_RACE)
leave_driver("(selecting) intr");
- #endif
- SETBITS( DMACNTRL0, INTEN );
+#endif
+ SETBITS(DMACNTRL0, INTEN);
return;
}
@@ -1411,200 +1468,229 @@
/* the bus is busy with something */
#if defined(DEBUG_INTR)
- if(aha152x_debug & debug_intr)
- disp_ports();
+ if(HOSTDATA(shpnt)->debug & debug_intr)
+ disp_ports(shpnt);
#endif
/* we are waiting for the result of a selection attempt */
- if(current_SC->SCp.phase & in_selection)
+ if(CURRENT_SC->SCp.phase & in_selection)
{
- if( TESTLO( SSTAT1, SELTO ) )
+ if(TESTLO(SSTAT1, SELTO))
/* no timeout */
- if( TESTHI( SSTAT0, SELDO ) )
+ if(TESTHI(SSTAT0, SELDO))
{
/* clear BUS FREE interrupt */
- SETPORT( SSTAT1, CLRBUSFREE);
+ SETPORT(SSTAT1, CLRBUSFREE);
/* Disable SELECTION OUT sequence */
- CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO );
+ CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO);
/* Disable SELECTION OUT DONE interrupt */
CLRBITS(SIMODE0, ENSELDO);
CLRBITS(SIMODE1, ENSELTIMO);
- if( TESTLO(SSTAT0, SELDO) )
+ if(TESTLO(SSTAT0, SELDO))
{
printk("aha152x: passing bus free condition\n");
#if defined(DEBUG_RACE)
leave_driver("(passing bus free) intr");
#endif
- SETBITS( DMACNTRL0, INTEN);
+ SETBITS(DMACNTRL0, INTEN);
- if(current_SC->SCp.phase & aborted)
+ if(CURRENT_SC->SCp.phase & aborted)
{
- abort_result=SCSI_ABORT_ERROR;
- abortion_complete++;
+ HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR;
+ HOSTDATA(shpnt)->abortion_complete++;
}
- aha152x_done( DID_NO_CONNECT << 16 );
+ aha152x_done(shpnt, DID_NO_CONNECT << 16);
return;
}
#if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_selection|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases))
printk("SELDO (SELID=%x), ", GETPORT(SELID));
#endif
/* selection was done */
- SETPORT( SSTAT0, CLRSELDO );
+ SETPORT(SSTAT0, CLRSELDO);
#if defined(DEBUG_ABORT)
- if((aha152x_debug & debug_abort) && (current_SC->SCp.phase & aborted))
+ if((HOSTDATA(shpnt)->debug & debug_abort) && (CURRENT_SC->SCp.phase & aborted))
printk("(ABORT) target selected, ");
#endif
- current_SC->SCp.phase &= ~in_selection;
- current_SC->SCp.phase |= in_other;
+ CURRENT_SC->SCp.phase &= ~in_selection;
+ CURRENT_SC->SCp.phase |= in_other;
+
+ ADDMSG(IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun));
+
+ if(!(SYNCRATE&0x80) && HOSTDATA(shpnt)->synchronous)
+ {
+ ADDMSG(EXTENDED_MESSAGE);
+ ADDMSG(3);
+ ADDMSG(EXTENDED_SDTR);
+ ADDMSG(50);
+ ADDMSG(8);
+
+ printk("outbound SDTR: ");
+ print_msg(&MSG(MSGLEN-5));
+
+ SYNCRATE=0x80;
+ CURRENT_SC->SCp.phase |= in_sync;
+ }
#if defined(DEBUG_RACE)
leave_driver("(SELDO) intr");
#endif
+ SETPORT(SCSIRATE, SYNCRATE&0x7f);
- SETPORT( SCSISIG, P_MSGO );
+ SETPORT(SCSISIG, P_MSGO);
- SETPORT( SIMODE0, 0 );
- SETPORT( SIMODE1, ENREQINIT|ENBUSFREE );
- SETBITS( DMACNTRL0, INTEN);
+ SETPORT(SIMODE0, 0);
+ SETPORT(SIMODE1, ENREQINIT|ENBUSFREE);
+ SETBITS(DMACNTRL0, INTEN);
return;
}
else
- aha152x_panic("neither timeout nor selection\007");
+ aha152x_panic(shpnt, "neither timeout nor selection\007");
else
{
#if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_selection|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases))
printk("SELTO, ");
#endif
/* end selection attempt */
- CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO );
+ CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO);
/* timeout */
- SETPORT( SSTAT1, CLRSELTIMO );
+ SETPORT(SSTAT1, CLRSELTIMO);
- SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );
- SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);
- SETBITS( DMACNTRL0, INTEN );
+ SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+ SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
+ SETBITS(DMACNTRL0, INTEN);
#if defined(DEBUG_RACE)
leave_driver("(SELTO) intr");
#endif
- if(current_SC->SCp.phase & aborted)
+ if(CURRENT_SC->SCp.phase & aborted)
{
#if defined(DEBUG_ABORT)
- if(aha152x_debug & debug_abort)
+ if(HOSTDATA(shpnt)->debug & debug_abort)
printk("(ABORT) selection timeout, ");
#endif
- abort_result=SCSI_ABORT_ERROR;
- abortion_complete++;
+ HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR;
+ HOSTDATA(shpnt)->abortion_complete++;
}
- if( TESTLO( SSTAT0, SELINGO ) )
+ if(TESTLO(SSTAT0, SELINGO))
/* ARBITRATION not won */
- aha152x_done( DID_BUS_BUSY << 16 );
+ aha152x_done(shpnt, DID_BUS_BUSY << 16);
else
/* ARBITRATION won, but SELECTION failed */
- aha152x_done( DID_NO_CONNECT << 16 );
+ aha152x_done(shpnt, DID_NO_CONNECT << 16);
+
return;
}
}
/* enable interrupt, when target leaves current phase */
- phase = getphase();
+ phase = getphase(shpnt);
if(!(phase & ~P_MASK)) /* "real" phase */
SETPORT(SCSISIG, phase);
SETPORT(SSTAT1, CLRPHASECHG);
- current_SC->SCp.phase =
- (current_SC->SCp.phase & ~((P_MASK|1)<<16)) | (phase << 16 );
+ CURRENT_SC->SCp.phase =
+ (CURRENT_SC->SCp.phase & ~((P_MASK|1)<<16)) | (phase << 16);
/* information transfer phase */
- switch( phase )
+ switch(phase)
{
case P_MSGO: /* MESSAGE OUT */
{
- unsigned char message;
+ int i, identify=0, abort=0;
#if defined(DEBUG_INTR) || defined(DEBUG_MSGO) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_intr|debug_msgo|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgo|debug_phases))
printk("MESSAGE OUT, ");
#endif
-
- if( current_SC->SCp.phase & aborted )
+ if(MSGLEN==0)
{
-#if defined(DEBUG_MSGO) || defined(DEBUG_ABORT)
- if(aha152x_debug & (debug_msgo|debug_abort))
- printk("ABORT, ");
+ ADDMSG(MESSAGE_REJECT);
+#if defined(DEBUG_MSGO)
+ if(HOSTDATA(shpnt)->debug & debug_msgo)
+ printk("unexpected MSGO; rejecting, ");
#endif
- message=ABORT;
}
- else
- /* If we didn't identify yet, do it. Otherwise there's nothing to do,
- but reject (probably we got an message before, that we have to
- reject (SDTR, WDTR, etc.) */
- if( !(current_SC->SCp.phase & sent_ident))
- {
- message=IDENTIFY(can_disconnect,current_SC->lun);
+
+
+ CLRBITS(SXFRCTL0, ENDMA);
+
+ SETPORT(SIMODE0, 0);
+ SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE);
+
+ /* wait for data latch to become ready or a phase change */
+ while(TESTLO(DMASTAT, INTSTAT))
+ ;
+
#if defined(DEBUG_MSGO)
- if(aha152x_debug & debug_msgo)
- printk("IDENTIFY (reconnect=%s;lun=%d), ",
- can_disconnect ? "enabled" : "disabled", current_SC->lun);
-#endif
+ if(HOSTDATA(shpnt)->debug & debug_msgo)
+ {
+ int i;
+
+ printk("messages (");
+ for(i=0; i<MSGLEN; i+=print_msg(&MSG(i)), printk(" "))
+ ;
+ printk("), ");
}
- else
+#endif
+
+ for(i=0; i<MSGLEN && TESTLO(SSTAT1, PHASEMIS); i++)
{
- message=MESSAGE_REJECT;
#if defined(DEBUG_MSGO)
- if(aha152x_debug & debug_msgo)
- printk("REJECT, ");
+ if(HOSTDATA(shpnt)->debug & debug_msgo)
+ printk("%x ", MSG(i));
#endif
+ if(i==MSGLEN-1)
+ {
+ /* Leave MESSAGE OUT after transfer */
+ SETPORT(SSTAT1, CLRATNO);
}
- CLRBITS( SXFRCTL0, ENDMA);
+ SETPORT(SCSIDAT, MSG(i));
- SETPORT( SIMODE0, 0 );
- SETPORT( SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE );
+ make_acklow(shpnt);
+ getphase(shpnt);
- /* wait for data latch to become ready or a phase change */
- while( TESTLO( DMASTAT, INTSTAT ) )
- ;
+ if(MSG(i)==IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun))
+ identify++;
- if( TESTHI( SSTAT1, PHASEMIS ) )
- aha152x_panic("unable to send message");
+ if(MSG(i)==ABORT)
+ abort++;
- /* Leave MESSAGE OUT after transfer */
- SETPORT( SSTAT1, CLRATNO);
+ }
- SETPORT( SCSIDAT, message );
+ MSGLEN=0;
- make_acklow();
- getphase();
+ if(MSGLEN>0)
+ aha152x_panic(shpnt, "oops, MSGLEN>0 !?");
- if(message==IDENTIFY(can_disconnect,current_SC->lun))
- current_SC->SCp.phase |= sent_ident;
+ if(identify)
+ CURRENT_SC->SCp.phase |= sent_ident;
- if(message==ABORT)
+ if(abort)
{
/* revive abort(); abort() enables interrupts */
- abort_result=SCSI_ABORT_SUCCESS;
- abortion_complete++;
+ HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS;
+ HOSTDATA(shpnt)->abortion_complete++;
- current_SC->SCp.phase = (current_SC->SCp.phase & ~(P_MASK<<16));
+ CURRENT_SC->SCp.phase &= ~(P_MASK<<16);
/* exit */
- SETBITS( DMACNTRL0, INTEN );
+ SETBITS(DMACNTRL0, INTEN);
#if defined(DEBUG_RACE)
leave_driver("(ABORT) intr");
#endif
- aha152x_done(DID_ABORT<<16);
+ aha152x_done(shpnt, DID_ABORT<<16);
return;
}
}
@@ -1612,291 +1698,263 @@
case P_CMD: /* COMMAND phase */
#if defined(DEBUG_INTR) || defined(DEBUG_CMD) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_intr|debug_cmd|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_intr|debug_cmd|debug_phases))
printk("COMMAND, ");
#endif
- if( !(current_SC->SCp.sent_command) )
+ if(!(CURRENT_SC->SCp.sent_command))
{
- if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT))
- printk("aha152x: P_CMD: %d(%d) bytes left in FIFO, resetting\n",
- GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT));
-
- /* reset fifo and enable writes */
- SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO);
- SETPORT(DMACNTRL0, ENDMA|WRITE_READ);
-
- /* clear transfer count and scsi fifo */
- SETPORT(SXFRCTL0, CH1|CLRSTCNT|CLRCH1 );
- SETPORT(SXFRCTL0, SCSIEN|DMAEN|CH1);
-
- /* missing phase raises INTSTAT */
- SETPORT( SIMODE0, 0 );
- SETPORT( SIMODE1, ENPHASEMIS|ENBUSFREE );
-
-#if defined(DEBUG_CMD)
- if(aha152x_debug & debug_cmd)
- printk("waiting, ");
-#endif
- /* wait for FIFO to get empty */
- while( TESTLO ( DMASTAT, DFIFOEMP|INTSTAT ) )
+ int i;
+
+ CLRBITS(SXFRCTL0, ENDMA);
+
+ SETPORT(SIMODE0, 0);
+ SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE);
+
+ /* wait for data latch to become ready or a phase change */
+ while(TESTLO(DMASTAT, INTSTAT))
;
- if( TESTHI( SSTAT1, PHASEMIS ) )
- aha152x_panic("target left COMMAND phase");
-
-#if defined(DEBUG_CMD)
- if(aha152x_debug & debug_cmd)
+ for(i=0; i<CURRENT_SC->cmd_len && TESTLO(SSTAT1, PHASEMIS); i++)
{
- printk("DFIFOEMP, outsw (%d bytes, %d words), ",
- current_SC->cmd_len, current_SC->cmd_len >> 1 );
- disp_ports();
- }
-#endif
-
- outsw( DATAPORT, ¤t_SC->cmnd, current_SC->cmd_len >> 1 );
+ SETPORT(SCSIDAT, CURRENT_SC->cmnd[i]);
-#if defined(DEBUG_CMD)
- if(aha152x_debug & debug_cmd)
- {
- printk("FCNT=%d, STCNT=%d, ", GETPORT(FIFOSTAT), GETSTCNT() );
- disp_ports();
+ make_acklow(shpnt);
+ getphase(shpnt);
}
-#endif
-
-#if defined(DEBUG_CMD)
- if(aha152x_debug & debug_cmd)
- printk("waiting for SEMPTY, ");
-#endif
-
- /* wait for SCSI FIFO to get empty.
- very important to send complete commands. */
- while( TESTLO ( SSTAT2, SEMPTY ) )
- ;
-#if defined(DEBUG_CMD)
- if(aha152x_debug & debug_cmd)
- printk("SEMPTY, ");
-#endif
-
- CLRBITS(SXFRCTL0, SCSIEN|DMAEN);
- /* transfer can be considered ended, when SCSIEN reads back zero */
- while( TESTHI( SXFRCTL0, SCSIEN ) )
- ;
-
-#if defined(DEBUG_CMD)
- if(aha152x_debug & debug_cmd)
- printk("!SEMPTY, ");
-#endif
-
- CLRBITS(DMACNTRL0, ENDMA);
-
-#if defined(DEBUG_CMD) || defined(DEBUG_INTR)
- if(debug_cmd & debug_intr)
- printk("sent %d/%d command bytes, ", GETSTCNT(),
- current_SC->cmd_len);
-#endif
+ if(i<CURRENT_SC->cmd_len && TESTHI(SSTAT1, PHASEMIS))
+ aha152x_panic(shpnt, "target left COMMAND");
+ CURRENT_SC->SCp.sent_command++;
}
else
- aha152x_panic("Nothing to sent while in COMMAND OUT");
+ aha152x_panic(shpnt, "Nothing to send while in COMMAND");
break;
case P_MSGI: /* MESSAGE IN phase */
+ {
+ int start_sync=0;
+
#if defined(DEBUG_INTR) || defined(DEBUG_MSGI) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_intr|debug_msgi|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgi|debug_phases))
printk("MESSAGE IN, ");
#endif
- SETPORT( SXFRCTL0, CH1);
+ SETPORT(SXFRCTL0, CH1);
- SETPORT( SIMODE0, 0);
- SETPORT( SIMODE1, ENBUSFREE);
+ SETPORT(SIMODE0, 0);
+ SETPORT(SIMODE1, ENBUSFREE);
- while( phase == P_MSGI )
+ while(phase == P_MSGI)
{
- current_SC->SCp.Message = GETPORT( SCSIBUS );
- switch(current_SC->SCp.Message)
+ CURRENT_SC->SCp.Message = GETPORT(SCSIDAT);
+ switch(CURRENT_SC->SCp.Message)
{
case DISCONNECT:
#if defined(DEBUG_MSGI) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_msgi|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases))
printk("target disconnected, ");
#endif
- current_SC->SCp.Message = 0;
- current_SC->SCp.phase |= disconnected;
- if(!can_disconnect)
- aha152x_panic("target was not allowed to disconnect");
+ CURRENT_SC->SCp.Message = 0;
+ CURRENT_SC->SCp.phase |= disconnected;
+ if(!HOSTDATA(shpnt)->reconnect)
+ aha152x_panic(shpnt, "target was not allowed to disconnect");
break;
case COMMAND_COMPLETE:
#if defined(DEBUG_MSGI) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_msgi|debug_phases))
- printk("inbound message ( COMMAND COMPLETE ), ");
+ if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases))
+ printk("inbound message (COMMAND COMPLETE), ");
#endif
done++;
break;
case MESSAGE_REJECT:
+ if(CURRENT_SC->SCp.phase & in_sync)
+ {
+ CURRENT_SC->SCp.phase &= ~in_sync;
+ SYNCRATE=0x80;
+ printk("synchronous rejected, ");
+ }
+ else
+ printk("inbound message (MESSAGE REJECT), ");
#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk("inbound message ( MESSAGE REJECT ), ");
+ if(HOSTDATA(shpnt)->debug & debug_msgi)
+ printk("inbound message (MESSAGE REJECT), ");
#endif
break;
case SAVE_POINTERS:
#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk("inbound message ( SAVE DATA POINTERS ), ");
+ if(HOSTDATA(shpnt)->debug & debug_msgi)
+ printk("inbound message (SAVE DATA POINTERS), ");
#endif
break;
case EXTENDED_MESSAGE:
{
- int i, code;
+ char buffer[16];
+ int i;
#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk("inbound message ( EXTENDED MESSAGE ), ");
+ if(HOSTDATA(shpnt)->debug & debug_msgi)
+ printk("inbound message (EXTENDED MESSAGE), ");
#endif
- make_acklow();
- if(getphase()!=P_MSGI)
+ make_acklow(shpnt);
+ if(getphase(shpnt)!=P_MSGI)
break;
- i=GETPORT(SCSIBUS);
+ buffer[0]=EXTENDED_MESSAGE;
+ buffer[1]=GETPORT(SCSIDAT);
+
+ for(i=0; i<buffer[1] &&
+ (make_acklow(shpnt), getphase(shpnt)==P_MSGI); i++)
+ buffer[2+i]=GETPORT(SCSIDAT);
#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk("length (%d), code ( ", i);
+ if(HOSTDATA(shpnt)->debug & debug_msgi)
+ print_msg(buffer);
#endif
- make_acklow();
- if(getphase()!=P_MSGI)
+ switch(buffer [2])
+ {
+ case EXTENDED_SDTR:
+ {
+ long ticks;
+
+ if(buffer[1]!=3)
+ aha152x_panic(shpnt, "SDTR message length != 3");
+
+ if(!HOSTDATA(shpnt)->synchronous)
break;
- code = GETPORT(SCSIBUS);
+ printk("inbound SDTR: "); print_msg(buffer);
+
+ ticks=(buffer[3]*4+49)/50;
- switch( code )
+ if(CURRENT_SC->SCp.phase & in_sync)
{
- case 0x00:
-#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk("MODIFY DATA POINTER ");
-#endif
- SETPORT(SCSISIG, P_MSGI|ATNO);
- break;
- case 0x01:
-#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk("SYNCHRONOUS DATA TRANSFER REQUEST ");
-#endif
- SETPORT(SCSISIG, P_MSGI|ATNO);
- break;
- case 0x02:
-#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk("EXTENDED IDENTIFY ");
-#endif
- break;
- case 0x03:
-#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk("WIDE DATA TRANSFER REQUEST ");
-#endif
- SETPORT(SCSISIG, P_MSGI|ATNO);
- break;
- default:
-#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- if( code & 0x80 )
- printk("reserved (%d) ", code );
+ /* we initiated SDTR */
+ if(ticks>9 || buffer[4]<1 || buffer[4]>8)
+ aha152x_panic(shpnt, "received SDTR invalid");
+
+ SYNCRATE |= ((ticks-2)<<4) + buffer[4];
+ }
+ else if(ticks<=9 && buffer[4]>=1)
+ {
+ if(buffer[4]>8)
+ buffer[4]=8;
+
+ ADDMSG(EXTENDED_MESSAGE);
+ ADDMSG(3);
+ ADDMSG(EXTENDED_SDTR);
+ if(ticks<4)
+ {
+ ticks=4;
+ ADDMSG(50);
+ }
else
- printk("vendor specific (%d) ", code);
-#endif
- SETPORT(SCSISIG, P_MSGI|ATNO);
- break;
+ ADDMSG(buffer[3]);
+
+ ADDMSG(buffer[4]);
+
+ printk("outbound SDTR: ");
+ print_msg(&MSG(MSGLEN-5));
+
+ CURRENT_SC->SCp.phase |= in_sync;
+
+ SYNCRATE |= ((ticks-2)<<4) + buffer[4];
+
+ start_sync++;
}
-#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk(" ), data ( ");
-#endif
- while( --i && (make_acklow(), getphase()==P_MSGI))
+ else
{
-#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk("%x ", GETPORT(SCSIBUS) );
-#else
- GETPORT(SCSIBUS);
-#endif
+ /* request SDTR is to slow, do it asynchronously */
+ ADDMSG(MESSAGE_REJECT);
+ SYNCRATE = 0;
+ }
+
+ SETPORT(SCSIRATE, SYNCRATE&0x7f);
+ }
+ break;
+
+ case EXTENDED_MODIFY_DATA_POINTER:
+ case EXTENDED_EXTENDED_IDENTIFY:
+ case EXTENDED_WDTR:
+ default:
+ ADDMSG(MESSAGE_REJECT);
+ break;
}
-#if defined(DEBUG_MSGI)
- if(aha152x_debug & debug_msgi)
- printk(" ), ");
-#endif
- /* We reject all extended messages. To do this
- we just enter MSGO by asserting ATN. Since
- we have already identified a REJECT message
- will be sent. */
- SETPORT(SCSISIG, P_MSGI|ATNO);
}
break;
default:
- printk("unsupported inbound message %x, ", current_SC->SCp.Message);
+ printk("unsupported inbound message %x, ",
+ CURRENT_SC->SCp.Message);
break;
}
- make_acklow();
- phase=getphase();
+ make_acklow(shpnt);
+ phase=getphase(shpnt);
}
+ if(start_sync)
+ CURRENT_SC->SCp.phase |= in_sync;
+ else
+ CURRENT_SC->SCp.phase &= ~in_sync;
+
+ if(MSGLEN>0)
+ SETPORT(SCSISIG, P_MSGI|ATNO);
+
/* clear SCSI fifo on BUSFREE */
if(phase==P_BUSFREE)
SETPORT(SXFRCTL0, CH1|CLRCH1);
- if(current_SC->SCp.phase & disconnected)
+ if(CURRENT_SC->SCp.phase & disconnected)
{
save_flags(flags);
cli();
#if defined(DEBUG_QUEUES)
- if(aha152x_debug & debug_queues)
+ if(HOSTDATA(shpnt)->debug & debug_queues)
printk("d+, ");
#endif
- append_SC( &disconnected_SC, current_SC);
- current_SC = NULL;
+ append_SC(&DISCONNECTED_SC, CURRENT_SC);
+ CURRENT_SC = NULL;
restore_flags(flags);
- SETBITS( SCSISEQ, ENRESELI );
+ SETBITS(SCSISEQ, ENRESELI);
- SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );
- SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);
+ SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+ SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
- SETBITS( DMACNTRL0, INTEN );
+ SETBITS(DMACNTRL0, INTEN);
return;
}
+ }
break;
case P_STATUS: /* STATUS IN phase */
#if defined(DEBUG_STATUS) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_status|debug_intr|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_status|debug_intr|debug_phases))
printk("STATUS, ");
#endif
- SETPORT( SXFRCTL0, CH1);
+ SETPORT(SXFRCTL0, CH1);
- SETPORT( SIMODE0, 0 );
- SETPORT( SIMODE1, ENREQINIT|ENBUSFREE );
+ SETPORT(SIMODE0, 0);
+ SETPORT(SIMODE1, ENREQINIT|ENBUSFREE);
- if( TESTHI( SSTAT1, PHASEMIS ) )
+ if(TESTHI(SSTAT1, PHASEMIS))
printk("aha152x: passing STATUS phase");
- current_SC->SCp.Status = GETPORT( SCSIBUS );
- make_acklow();
- getphase();
+ CURRENT_SC->SCp.Status = GETPORT(SCSIBUS);
+ make_acklow(shpnt);
+ getphase(shpnt);
#if defined(DEBUG_STATUS)
- if(aha152x_debug & debug_status)
+ if(HOSTDATA(shpnt)->debug & debug_status)
{
printk("inbound status ");
- print_status( current_SC->SCp.Status );
+ print_status(CURRENT_SC->SCp.Status);
printk(", ");
}
#endif
@@ -1907,117 +1965,130 @@
int fifodata, data_count, done;
#if defined(DEBUG_DATAI) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_datai|debug_intr|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr|debug_phases))
printk("DATA IN, ");
#endif
+#if 0
if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT))
printk("aha152x: P_DATAI: %d(%d) bytes left in FIFO, resetting\n",
GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT));
+#endif
/* reset host fifo */
SETPORT(DMACNTRL0, RSTFIFO);
SETPORT(DMACNTRL0, RSTFIFO|ENDMA);
- SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN );
+ SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN);
- SETPORT( SIMODE0, 0 );
- SETPORT( SIMODE1, ENPHASEMIS|ENBUSFREE );
+ SETPORT(SIMODE0, 0);
+ SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE);
/* done is set when the FIFO is empty after the target left DATA IN */
done=0;
/* while the target stays in DATA to transfer data */
- while ( !done )
+ while (!done)
{
#if defined(DEBUG_DATAI)
- if(aha152x_debug & debug_datai)
+ if(HOSTDATA(shpnt)->debug & debug_datai)
printk("expecting data, ");
#endif
/* wait for PHASEMIS or full FIFO */
- while( TESTLO ( DMASTAT, DFIFOFULL|INTSTAT ) )
+ while(TESTLO (DMASTAT, DFIFOFULL|INTSTAT))
;
- if( TESTHI( DMASTAT, DFIFOFULL ) )
+#if defined(DEBUG_DATAI)
+ if(HOSTDATA(shpnt)->debug & debug_datai)
+ printk("ok, ");
+#endif
+
+ if(TESTHI(DMASTAT, DFIFOFULL))
fifodata=GETPORT(FIFOSTAT);
else
{
/* wait for SCSI fifo to get empty */
- while( TESTLO( SSTAT2, SEMPTY ) )
+ while(TESTLO(SSTAT2, SEMPTY))
;
/* rest of data in FIFO */
fifodata=GETPORT(FIFOSTAT);
#if defined(DEBUG_DATAI)
- if(aha152x_debug & debug_datai)
+ if(HOSTDATA(shpnt)->debug & debug_datai)
printk("last transfer, ");
#endif
done=1;
}
#if defined(DEBUG_DATAI)
- if(aha152x_debug & debug_datai)
+ if(HOSTDATA(shpnt)->debug & debug_datai)
printk("fifodata=%d, ", fifodata);
#endif
- while( fifodata && current_SC->SCp.this_residual )
+ while(fifodata && CURRENT_SC->SCp.this_residual)
{
data_count=fifodata;
/* limit data transfer to size of first sg buffer */
- if (data_count > current_SC->SCp.this_residual)
- data_count = current_SC->SCp.this_residual;
+ if (data_count > CURRENT_SC->SCp.this_residual)
+ data_count = CURRENT_SC->SCp.this_residual;
fifodata -= data_count;
#if defined(DEBUG_DATAI)
- if(aha152x_debug & debug_datai)
+ if(HOSTDATA(shpnt)->debug & debug_datai)
printk("data_count=%d, ", data_count);
#endif
if(data_count&1)
{
/* get a single byte in byte mode */
- SETBITS(DMACNTRL0, _8BIT );
- *current_SC->SCp.ptr++ = GETPORT( DATAPORT );
- current_SC->SCp.this_residual--;
+ SETBITS(DMACNTRL0, _8BIT);
+ *CURRENT_SC->SCp.ptr++ = GETPORT(DATAPORT);
+ CURRENT_SC->SCp.this_residual--;
}
if(data_count>1)
{
- CLRBITS(DMACNTRL0, _8BIT );
+ CLRBITS(DMACNTRL0, _8BIT);
data_count >>= 1; /* Number of words */
- insw( DATAPORT, current_SC->SCp.ptr, data_count );
+ insw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
#if defined(DEBUG_DATAI)
- if(aha152x_debug & debug_datai)
-/* show what comes with the last transfer */
+ if(HOSTDATA(shpnt)->debug & debug_datai)
+ /* show what comes with the last transfer */
if(done)
{
+#ifdef 0
int i;
unsigned char *data;
+#endif
+ printk("data on last transfer (%d bytes) ",
+ 2*data_count);
+#ifdef 0
printk("data on last transfer (%d bytes: ",
2*data_count);
- data = (unsigned char *) current_SC->SCp.ptr;
- for( i=0; i<2*data_count; i++)
+ data = (unsigned char *) CURRENT_SC->SCp.ptr;
+ for(i=0; i<2*data_count; i++)
printk("%2x ", *data++);
printk("), ");
+#endif
}
#endif
- current_SC->SCp.ptr += 2 * data_count;
- current_SC->SCp.this_residual -= 2 * data_count;
+ CURRENT_SC->SCp.ptr += 2 * data_count;
+ CURRENT_SC->SCp.this_residual -= 2 * data_count;
}
/* if this buffer is full and there are more buffers left */
- if (!current_SC->SCp.this_residual &&
- current_SC->SCp.buffers_residual)
+ if (!CURRENT_SC->SCp.this_residual &&
+ CURRENT_SC->SCp.buffers_residual)
{
/* advance to next buffer */
- current_SC->SCp.buffers_residual--;
- current_SC->SCp.buffer++;
- current_SC->SCp.ptr =
- current_SC->SCp.buffer->address;
- current_SC->SCp.this_residual =
- current_SC->SCp.buffer->length;
+ CURRENT_SC->SCp.buffers_residual--;
+ CURRENT_SC->SCp.buffer++;
+ CURRENT_SC->SCp.ptr =
+ CURRENT_SC->SCp.buffer->address;
+ CURRENT_SC->SCp.this_residual =
+ CURRENT_SC->SCp.buffer->length;
}
}
@@ -2028,15 +2099,15 @@
{
printk("aha152x: more data than expected (%d bytes)\n",
GETPORT(FIFOSTAT));
- SETBITS(DMACNTRL0, _8BIT );
- printk("aha152x: data ( ");
+ SETBITS(DMACNTRL0, _8BIT);
+ printk("aha152x: data (");
while(fifodata--)
- printk("%2x ", GETPORT( DATAPORT ));
+ printk("%2x ", GETPORT(DATAPORT));
printk(")\n");
}
#if defined(DEBUG_DATAI)
- if(aha152x_debug & debug_datai)
+ if(HOSTDATA(shpnt)->debug & debug_datai)
if(!fifodata)
printk("fifo empty, ");
else
@@ -2045,23 +2116,25 @@
}
#if defined(DEBUG_DATAI)
- if((aha152x_debug & debug_datai) && (current_SC->SCp.buffers_residual || current_SC->SCp.this_residual))
+ if((HOSTDATA(shpnt)->debug & debug_datai) &&
+ (CURRENT_SC->SCp.buffers_residual ||
+ CURRENT_SC->SCp.this_residual))
printk("left buffers (buffers=%d, bytes=%d), ",
- current_SC->SCp.buffers_residual,
- current_SC->SCp.this_residual);
+ CURRENT_SC->SCp.buffers_residual,
+ CURRENT_SC->SCp.this_residual);
#endif
/* transfer can be considered ended, when SCSIEN reads back zero */
CLRBITS(SXFRCTL0, SCSIEN|DMAEN);
- while( TESTHI( SXFRCTL0, SCSIEN ) )
+ while(TESTHI(SXFRCTL0, SCSIEN))
;
- CLRBITS(DMACNTRL0, ENDMA );
+ CLRBITS(DMACNTRL0, ENDMA);
#if defined(DEBUG_DATAI) || defined(DEBUG_INTR)
- if(aha152x_debug & (debug_datai|debug_intr))
+ if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr))
printk("got %d bytes, ", GETSTCNT());
#endif
- current_SC->SCp.have_data_in++;
+ CURRENT_SC->SCp.have_data_in++;
}
break;
@@ -2070,95 +2143,96 @@
int data_count;
#if defined(DEBUG_DATAO) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)
- if(aha152x_debug & (debug_datao|debug_intr|debug_phases))
+ if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr|debug_phases))
printk("DATA OUT, ");
#endif
#if defined(DEBUG_DATAO)
- if(aha152x_debug & debug_datao)
+ if(HOSTDATA(shpnt)->debug & debug_datao)
printk("got data to send (bytes=%d, buffers=%d), ",
- current_SC->SCp.this_residual,
- current_SC->SCp.buffers_residual );
+ CURRENT_SC->SCp.this_residual,
+ CURRENT_SC->SCp.buffers_residual);
#endif
- if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT) )
+ if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT))
{
- printk("%d(%d) left in FIFO, ", GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT) );
- aha152x_panic("FIFO should be empty");
+ printk("%d(%d) left in FIFO, ",
+ GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT));
+ aha152x_panic(shpnt, "FIFO should be empty");
}
+ SETPORT(SXFRCTL0, CH1|CLRSTCNT|CLRCH1);
+ SETPORT(SXFRCTL0, SCSIEN|DMAEN|CH1);
+
SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO);
SETPORT(DMACNTRL0, ENDMA|WRITE_READ);
- SETPORT(SXFRCTL0, CH1|CLRSTCNT|CLRCH1 );
- SETPORT(SXFRCTL0, SCSIEN|DMAEN|CH1);
-
- SETPORT( SIMODE0, 0 );
- SETPORT( SIMODE1, ENPHASEMIS|ENBUSFREE );
+ SETPORT(SIMODE0, 0);
+ SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE);
/* while current buffer is not empty or
there are more buffers to transfer */
- while( TESTLO( SSTAT1, PHASEMIS ) &&
- (current_SC->SCp.this_residual ||
- current_SC->SCp.buffers_residual) )
+ while(TESTLO(SSTAT1, PHASEMIS) &&
+ (CURRENT_SC->SCp.this_residual ||
+ CURRENT_SC->SCp.buffers_residual))
{
#if defined(DEBUG_DATAO)
- if(aha152x_debug & debug_datao)
+ if(HOSTDATA(shpnt)->debug & debug_datao)
printk("sending data (left: bytes=%d, buffers=%d), waiting, ",
- current_SC->SCp.this_residual,
- current_SC->SCp.buffers_residual);
+ CURRENT_SC->SCp.this_residual,
+ CURRENT_SC->SCp.buffers_residual);
#endif
/* transfer rest of buffer, but max. 128 byte */
- data_count = current_SC->SCp.this_residual > 128 ?
- 128 : current_SC->SCp.this_residual ;
+ data_count =
+ CURRENT_SC->SCp.this_residual > 128 ?
+ 128 : CURRENT_SC->SCp.this_residual ;
#if defined(DEBUG_DATAO)
- if(aha152x_debug & debug_datao)
+ if(HOSTDATA(shpnt)->debug & debug_datao)
printk("data_count=%d, ", data_count);
#endif
if(data_count&1)
{
/* put a single byte in byte mode */
- SETBITS(DMACNTRL0, _8BIT );
- SETPORT(DATAPORT, *current_SC->SCp.ptr++);
- current_SC->SCp.this_residual--;
+ SETBITS(DMACNTRL0, _8BIT);
+ SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++);
+ CURRENT_SC->SCp.this_residual--;
}
if(data_count>1)
{
- CLRBITS(DMACNTRL0, _8BIT );
- data_count >>= 1; /* Number of words */
- outsw( DATAPORT, current_SC->SCp.ptr, data_count );
- current_SC->SCp.ptr += 2 * data_count;
- current_SC->SCp.this_residual -= 2 * data_count;
+ CLRBITS(DMACNTRL0, _8BIT);
+ data_count >>= 1; /* number of words */
+ outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
+ CURRENT_SC->SCp.ptr += 2 * data_count;
+ CURRENT_SC->SCp.this_residual -= 2 * data_count;
}
/* wait for FIFO to get empty */
- while( TESTLO ( DMASTAT, DFIFOEMP|INTSTAT ) )
+ while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT))
;
#if defined(DEBUG_DATAO)
- if(aha152x_debug & debug_datao)
+ if(HOSTDATA(shpnt)->debug & debug_datao)
printk("fifo (%d bytes), transfered (%d bytes), ",
- GETPORT(FIFOSTAT), GETSTCNT() );
+ GETPORT(FIFOSTAT), GETSTCNT());
#endif
/* if this buffer is empty and there are more buffers left */
- if ( TESTLO( SSTAT1, PHASEMIS ) &&
- !current_SC->SCp.this_residual &&
- current_SC->SCp.buffers_residual)
+ if (TESTLO(SSTAT1, PHASEMIS) &&
+ !CURRENT_SC->SCp.this_residual &&
+ CURRENT_SC->SCp.buffers_residual)
{
/* advance to next buffer */
- current_SC->SCp.buffers_residual--;
- current_SC->SCp.buffer++;
- current_SC->SCp.ptr =
- current_SC->SCp.buffer->address;
- current_SC->SCp.this_residual =
- current_SC->SCp.buffer->length;
+ CURRENT_SC->SCp.buffers_residual--;
+ CURRENT_SC->SCp.buffer++;
+ CURRENT_SC->SCp.ptr =
+ CURRENT_SC->SCp.buffer->address;
+ CURRENT_SC->SCp.this_residual =
+ CURRENT_SC->SCp.buffer->length;
}
}
- if ( current_SC->SCp.this_residual ||
- current_SC->SCp.buffers_residual )
+ if (CURRENT_SC->SCp.this_residual || CURRENT_SC->SCp.buffers_residual)
{
/* target leaves DATA OUT for an other phase
(perhaps disconnect) */
@@ -2167,46 +2241,47 @@
data_count = GETPORT(SSTAT2) & (SFULL|SFCNT);
data_count += GETPORT(FIFOSTAT) ;
- current_SC->SCp.ptr -= data_count;
- current_SC->SCp.this_residual += data_count;
+ CURRENT_SC->SCp.ptr -= data_count;
+ CURRENT_SC->SCp.this_residual += data_count;
#if defined(DEBUG_DATAO)
- if(aha152x_debug & debug_datao)
- printk("left data (bytes=%d, buffers=%d), fifos (bytes=%d), transfer incomplete, resetting fifo, ",
- current_SC->SCp.this_residual,
- current_SC->SCp.buffers_residual,
- data_count );
+ if(HOSTDATA(shpnt)->debug & debug_datao)
+ printk("left data (bytes=%d, buffers=%d), fifos (bytes=%d), "
+ "transfer incomplete, resetting fifo, ",
+ CURRENT_SC->SCp.this_residual,
+ CURRENT_SC->SCp.buffers_residual,
+ data_count);
#endif
SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO);
- CLRBITS(SXFRCTL0, SCSIEN|DMAEN );
+ CLRBITS(SXFRCTL0, SCSIEN|DMAEN);
CLRBITS(DMACNTRL0, ENDMA);
}
else
{
#if defined(DEBUG_DATAO)
- if(aha152x_debug & debug_datao)
+ if(HOSTDATA(shpnt)->debug & debug_datao)
printk("waiting for SCSI fifo to get empty, ");
#endif
/* wait for SCSI fifo to get empty */
- while( TESTLO( SSTAT2, SEMPTY ) )
+ while(TESTLO(SSTAT2, SEMPTY))
;
#if defined(DEBUG_DATAO)
- if(aha152x_debug & debug_datao)
+ if(HOSTDATA(shpnt)->debug & debug_datao)
printk("ok, left data (bytes=%d, buffers=%d) ",
- current_SC->SCp.this_residual,
- current_SC->SCp.buffers_residual);
+ CURRENT_SC->SCp.this_residual,
+ CURRENT_SC->SCp.buffers_residual);
#endif
CLRBITS(SXFRCTL0, SCSIEN|DMAEN);
/* transfer can be considered ended, when SCSIEN reads back zero */
- while( TESTHI( SXFRCTL0, SCSIEN ) )
+ while(TESTHI(SXFRCTL0, SCSIEN))
;
CLRBITS(DMACNTRL0, ENDMA);
}
#if defined(DEBUG_DATAO) || defined(DEBUG_INTR)
- if(aha152x_debug & (debug_datao|debug_intr))
- printk("sent %d data bytes, ", GETSTCNT() );
+ if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr))
+ printk("sent %d data bytes, ", GETSTCNT());
#endif
}
break;
@@ -2216,12 +2291,12 @@
leave_driver("(BUSFREE) intr");
#endif
#if defined(DEBUG_PHASES)
- if(aha152x_debug & debug_phases)
+ if(HOSTDATA(shpnt)->debug & debug_phases)
printk("unexpected BUS FREE, ");
#endif
- current_SC->SCp.phase = (current_SC->SCp.phase & ~(P_MASK<<16));
+ CURRENT_SC->SCp.phase &= ~(P_MASK<<16);
- aha152x_done( DID_ERROR << 16 ); /* Don't know any better */
+ aha152x_done(shpnt, DID_ERROR << 16); /* Don't know any better */
return;
break;
@@ -2231,10 +2306,10 @@
#endif
printk("PARITY error in DATA phase, ");
- current_SC->SCp.phase = (current_SC->SCp.phase & ~(P_MASK<<16));
+ CURRENT_SC->SCp.phase &= ~(P_MASK<<16);
- SETBITS( DMACNTRL0, INTEN );
- aha152x_done( DID_PARITY << 16 );
+ SETBITS(DMACNTRL0, INTEN);
+ aha152x_done(shpnt, DID_PARITY << 16);
return;
break;
@@ -2246,85 +2321,86 @@
if(done)
{
#if defined(DEBUG_INTR)
- if(aha152x_debug & debug_intr)
+ if(HOSTDATA(shpnt)->debug & debug_intr)
printk("command done.\n");
#endif
#if defined(DEBUG_RACE)
leave_driver("(done) intr");
#endif
- SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );
- SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);
- SETPORT(SCSISEQ, disconnected_SC ? ENRESELI : 0 );
-
- SETBITS( DMACNTRL0, INTEN );
-
- aha152x_done( (current_SC->SCp.Status & 0xff)
- | ( (current_SC->SCp.Message & 0xff) << 8)
- | ( DID_OK << 16) );
+ SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+ SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
+ SETPORT(SCSISEQ, DISCONNECTED_SC ? ENRESELI : 0);
+
+ SETBITS(DMACNTRL0, INTEN);
+
+ aha152x_done(shpnt,
+ (CURRENT_SC->SCp.Status & 0xff)
+ | ((CURRENT_SC->SCp.Message & 0xff) << 8)
+ | (DID_OK << 16));
#if defined(DEBUG_RACE)
printk("done returned (DID_OK: Status=%x; Message=%x).\n",
- current_SC->SCp.Status, current_SC->SCp.Message);
+ CURRENT_SC->SCp.Status, CURRENT_SC->SCp.Message);
#endif
return;
}
- if(current_SC)
- current_SC->SCp.phase |= 1<<16 ;
+ if(CURRENT_SC)
+ CURRENT_SC->SCp.phase |= 1<<16 ;
- SETPORT( SIMODE0, 0 );
- SETPORT( SIMODE1, ENPHASEMIS|ENBUSFREE );
+ SETPORT(SIMODE0, 0);
+ SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE);
#if defined(DEBUG_INTR)
- if(aha152x_debug & debug_intr)
- disp_enintr();
+ if(HOSTDATA(shpnt)->debug & debug_intr)
+ disp_enintr(shpnt);
#endif
#if defined(DEBUG_RACE)
leave_driver("(PHASEEND) intr");
#endif
- SETBITS( DMACNTRL0, INTEN);
+ SETBITS(DMACNTRL0, INTEN);
return;
}
/*
* Dump the current driver status and panic...
*/
-static void aha152x_panic(const char *msg)
+static void aha152x_panic(struct Scsi_Host *shpnt, char *msg)
{
- printk("\naha152x_panic: %s\n", msg);
- show_queues();
+ printk("\naha152x: %s\n", msg);
+ show_queues(shpnt);
panic("aha152x panic");
}
/*
* Display registers of AIC-6260
*/
-static void disp_ports(void)
+static void disp_ports(struct Scsi_Host *shpnt)
{
#ifdef DEBUG_AHA152X
int s;
#ifdef SKIP_PORTS
- if(aha152x_debug & debug_skipports)
+ if(HOSTDATA(shpnt)->debug & debug_skipports)
return;
#endif
- printk("\n%s: ", current_SC ? "on bus" : "waiting");
+ printk("\n%s: ", CURRENT_SC ? "on bus" : "waiting");
s=GETPORT(SCSISEQ);
- printk("SCSISEQ ( ");
- if( s & TEMODEO ) printk("TARGET MODE ");
- if( s & ENSELO ) printk("SELO ");
- if( s & ENSELI ) printk("SELI ");
- if( s & ENRESELI ) printk("RESELI ");
- if( s & ENAUTOATNO ) printk("AUTOATNO ");
- if( s & ENAUTOATNI ) printk("AUTOATNI ");
- if( s & ENAUTOATNP ) printk("AUTOATNP ");
- if( s & SCSIRSTO ) printk("SCSIRSTO ");
+ printk("SCSISEQ (");
+ if(s & TEMODEO) printk("TARGET MODE ");
+ if(s & ENSELO) printk("SELO ");
+ if(s & ENSELI) printk("SELI ");
+ if(s & ENRESELI) printk("RESELI ");
+ if(s & ENAUTOATNO) printk("AUTOATNO ");
+ if(s & ENAUTOATNI) printk("AUTOATNI ");
+ if(s & ENAUTOATNP) printk("AUTOATNP ");
+ if(s & SCSIRSTO) printk("SCSIRSTO ");
printk(");");
- printk(" SCSISIG ( ");
+ printk(" SCSISIG (");
s=GETPORT(SCSISIG);
switch(s & P_MASK)
{
@@ -2351,132 +2427,131 @@
break;
}
- printk(" ); ");
+ printk("); ");
- printk("INTSTAT ( %s ); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo");
+ printk("INTSTAT (%s); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo");
- printk("SSTAT ( ");
+ printk("SSTAT (");
s=GETPORT(SSTAT0);
- if( s & TARGET ) printk("TARGET ");
- if( s & SELDO ) printk("SELDO ");
- if( s & SELDI ) printk("SELDI ");
- if( s & SELINGO ) printk("SELINGO ");
- if( s & SWRAP ) printk("SWRAP ");
- if( s & SDONE ) printk("SDONE ");
- if( s & SPIORDY ) printk("SPIORDY ");
- if( s & DMADONE ) printk("DMADONE ");
+ if(s & TARGET) printk("TARGET ");
+ if(s & SELDO) printk("SELDO ");
+ if(s & SELDI) printk("SELDI ");
+ if(s & SELINGO) printk("SELINGO ");
+ if(s & SWRAP) printk("SWRAP ");
+ if(s & SDONE) printk("SDONE ");
+ if(s & SPIORDY) printk("SPIORDY ");
+ if(s & DMADONE) printk("DMADONE ");
s=GETPORT(SSTAT1);
- if( s & SELTO ) printk("SELTO ");
- if( s & ATNTARG ) printk("ATNTARG ");
- if( s & SCSIRSTI ) printk("SCSIRSTI ");
- if( s & PHASEMIS ) printk("PHASEMIS ");
- if( s & BUSFREE ) printk("BUSFREE ");
- if( s & SCSIPERR ) printk("SCSIPERR ");
- if( s & PHASECHG ) printk("PHASECHG ");
- if( s & REQINIT ) printk("REQINIT ");
+ if(s & SELTO) printk("SELTO ");
+ if(s & ATNTARG) printk("ATNTARG ");
+ if(s & SCSIRSTI) printk("SCSIRSTI ");
+ if(s & PHASEMIS) printk("PHASEMIS ");
+ if(s & BUSFREE) printk("BUSFREE ");
+ if(s & SCSIPERR) printk("SCSIPERR ");
+ if(s & PHASECHG) printk("PHASECHG ");
+ if(s & REQINIT) printk("REQINIT ");
printk("); ");
- printk("SSTAT ( ");
+ printk("SSTAT (");
s=GETPORT(SSTAT0) & GETPORT(SIMODE0);
- if( s & TARGET ) printk("TARGET ");
- if( s & SELDO ) printk("SELDO ");
- if( s & SELDI ) printk("SELDI ");
- if( s & SELINGO ) printk("SELINGO ");
- if( s & SWRAP ) printk("SWRAP ");
- if( s & SDONE ) printk("SDONE ");
- if( s & SPIORDY ) printk("SPIORDY ");
- if( s & DMADONE ) printk("DMADONE ");
+ if(s & TARGET) printk("TARGET ");
+ if(s & SELDO) printk("SELDO ");
+ if(s & SELDI) printk("SELDI ");
+ if(s & SELINGO) printk("SELINGO ");
+ if(s & SWRAP) printk("SWRAP ");
+ if(s & SDONE) printk("SDONE ");
+ if(s & SPIORDY) printk("SPIORDY ");
+ if(s & DMADONE) printk("DMADONE ");
s=GETPORT(SSTAT1) & GETPORT(SIMODE1);
- if( s & SELTO ) printk("SELTO ");
- if( s & ATNTARG ) printk("ATNTARG ");
- if( s & SCSIRSTI ) printk("SCSIRSTI ");
- if( s & PHASEMIS ) printk("PHASEMIS ");
- if( s & BUSFREE ) printk("BUSFREE ");
- if( s & SCSIPERR ) printk("SCSIPERR ");
- if( s & PHASECHG ) printk("PHASECHG ");
- if( s & REQINIT ) printk("REQINIT ");
+ if(s & SELTO) printk("SELTO ");
+ if(s & ATNTARG) printk("ATNTARG ");
+ if(s & SCSIRSTI) printk("SCSIRSTI ");
+ if(s & PHASEMIS) printk("PHASEMIS ");
+ if(s & BUSFREE) printk("BUSFREE ");
+ if(s & SCSIPERR) printk("SCSIPERR ");
+ if(s & PHASECHG) printk("PHASECHG ");
+ if(s & REQINIT) printk("REQINIT ");
printk("); ");
- printk("SXFRCTL0 ( ");
+ printk("SXFRCTL0 (");
s=GETPORT(SXFRCTL0);
- if( s & SCSIEN ) printk("SCSIEN ");
- if( s & DMAEN ) printk("DMAEN ");
- if( s & CH1 ) printk("CH1 ");
- if( s & CLRSTCNT ) printk("CLRSTCNT ");
- if( s & SPIOEN ) printk("SPIOEN ");
- if( s & CLRCH1 ) printk("CLRCH1 ");
+ if(s & SCSIEN) printk("SCSIEN ");
+ if(s & DMAEN) printk("DMAEN ");
+ if(s & CH1) printk("CH1 ");
+ if(s & CLRSTCNT) printk("CLRSTCNT ");
+ if(s & SPIOEN) printk("SPIOEN ");
+ if(s & CLRCH1) printk("CLRCH1 ");
printk("); ");
- printk("SIGNAL ( ");
+ printk("SIGNAL (");
s=GETPORT(SCSISIG);
- if( s & ATNI ) printk("ATNI ");
- if( s & SELI ) printk("SELI ");
- if( s & BSYI ) printk("BSYI ");
- if( s & REQI ) printk("REQI ");
- if( s & ACKI ) printk("ACKI ");
+ if(s & ATNI) printk("ATNI ");
+ if(s & SELI) printk("SELI ");
+ if(s & BSYI) printk("BSYI ");
+ if(s & REQI) printk("REQI ");
+ if(s & ACKI) printk("ACKI ");
printk("); ");
- printk("SELID ( %02x ), ", GETPORT(SELID) );
+ printk("SELID (%02x), ", GETPORT(SELID));
- printk("SSTAT2 ( ");
+ printk("SSTAT2 (");
s=GETPORT(SSTAT2);
- if( s & SOFFSET) printk("SOFFSET ");
- if( s & SEMPTY) printk("SEMPTY ");
- if( s & SFULL) printk("SFULL ");
- printk("); SFCNT ( %d ); ", s & (SFULL|SFCNT) );
+ if(s & SOFFSET) printk("SOFFSET ");
+ if(s & SEMPTY) printk("SEMPTY ");
+ if(s & SFULL) printk("SFULL ");
+ printk("); SFCNT (%d); ", s & (SFULL|SFCNT));
-#if 0
- printk("SSTAT4 ( ");
+ s=GETPORT(SSTAT3);
+ printk("SCSICNT (%d), OFFCNT(%d), ", (s&0xf0)>>4, s&0x0f);
+
+ printk("SSTAT4 (");
s=GETPORT(SSTAT4);
- if( s & SYNCERR) printk("SYNCERR ");
- if( s & FWERR) printk("FWERR ");
- if( s & FRERR) printk("FRERR ");
+ if(s & SYNCERR) printk("SYNCERR ");
+ if(s & FWERR) printk("FWERR ");
+ if(s & FRERR) printk("FRERR ");
printk("); ");
-#endif
-
- printk("FCNT ( %d ); ", GETPORT(FIFOSTAT) );
- printk("DMACNTRL0 ( ");
+ printk("DMACNTRL0 (");
s=GETPORT(DMACNTRL0);
- printk( "%s ", s & _8BIT ? "8BIT" : "16BIT" );
- printk( "%s ", s & DMA ? "DMA" : "PIO" );
- printk( "%s ", s & WRITE_READ ? "WRITE" : "READ" );
- if( s & ENDMA ) printk("ENDMA ");
- if( s & INTEN ) printk("INTEN ");
- if( s & RSTFIFO ) printk("RSTFIFO ");
- if( s & SWINT ) printk("SWINT ");
+ printk("%s ", s & _8BIT ? "8BIT" : "16BIT");
+ printk("%s ", s & DMA ? "DMA" : "PIO" );
+ printk("%s ", s & WRITE_READ ? "WRITE" : "READ" );
+ if(s & ENDMA) printk("ENDMA ");
+ if(s & INTEN) printk("INTEN ");
+ if(s & RSTFIFO) printk("RSTFIFO ");
+ if(s & SWINT) printk("SWINT ");
printk("); ");
#if 0
- printk("DMACNTRL1 ( ");
+ printk("DMACNTRL1 (");
s=GETPORT(DMACNTRL1);
- if( s & PWRDWN ) printk("PWRDN ");
+ if(s & PWRDWN) printk("PWRDN ");
printk("); ");
- printk("STK ( %d ); ", s & 0xf);
+ printk("STK (%d); ", s & 0xf);
+
+#endif
printk("DMASTAT (");
s=GETPORT(DMASTAT);
- if( s & ATDONE ) printk("ATDONE ");
- if( s & WORDRDY ) printk("WORDRDY ");
- if( s & DFIFOFULL ) printk("DFIFOFULL ");
- if( s & DFIFOEMP ) printk("DFIFOEMP ");
+ if(s & ATDONE) printk("ATDONE ");
+ if(s & WORDRDY) printk("WORDRDY ");
+ if(s & DFIFOFULL) printk("DFIFOFULL ");
+ if(s & DFIFOEMP) printk("DFIFOEMP ");
printk(")");
-#endif
-
printk("\n");
#endif
}
@@ -2484,29 +2559,29 @@
/*
* display enabled interrupts
*/
-static void disp_enintr(void)
+static void disp_enintr(struct Scsi_Host *shpnt)
{
int s;
- printk("enabled interrupts ( ");
+ printk("enabled interrupts (");
s=GETPORT(SIMODE0);
- if( s & ENSELDO ) printk("ENSELDO ");
- if( s & ENSELDI ) printk("ENSELDI ");
- if( s & ENSELINGO ) printk("ENSELINGO ");
- if( s & ENSWRAP ) printk("ENSWRAP ");
- if( s & ENSDONE ) printk("ENSDONE ");
- if( s & ENSPIORDY ) printk("ENSPIORDY ");
- if( s & ENDMADONE ) printk("ENDMADONE ");
+ if(s & ENSELDO) printk("ENSELDO ");
+ if(s & ENSELDI) printk("ENSELDI ");
+ if(s & ENSELINGO) printk("ENSELINGO ");
+ if(s & ENSWRAP) printk("ENSWRAP ");
+ if(s & ENSDONE) printk("ENSDONE ");
+ if(s & ENSPIORDY) printk("ENSPIORDY ");
+ if(s & ENDMADONE) printk("ENDMADONE ");
s=GETPORT(SIMODE1);
- if( s & ENSELTIMO ) printk("ENSELTIMO ");
- if( s & ENATNTARG ) printk("ENATNTARG ");
- if( s & ENPHASEMIS ) printk("ENPHASEMIS ");
- if( s & ENBUSFREE ) printk("ENBUSFREE ");
- if( s & ENSCSIPERR ) printk("ENSCSIPERR ");
- if( s & ENPHASECHG ) printk("ENPHASECHG ");
- if( s & ENREQINIT ) printk("ENREQINIT ");
+ if(s & ENSELTIMO) printk("ENSELTIMO ");
+ if(s & ENATNTARG) printk("ENATNTARG ");
+ if(s & ENPHASEMIS) printk("ENPHASEMIS ");
+ if(s & ENBUSFREE) printk("ENBUSFREE ");
+ if(s & ENSCSIPERR) printk("ENSCSIPERR ");
+ if(s & ENPHASECHG) printk("ENPHASECHG ");
+ if(s & ENREQINIT) printk("ENREQINIT ");
printk(")\n");
}
@@ -2560,7 +2635,7 @@
*/
static void show_command(Scsi_Cmnd *ptr)
{
- printk("0x%08x: target=%d; lun=%d; cmnd=( ",
+ printk("0x%08x: target=%d; lun=%d; cmnd=(",
(unsigned int) ptr, ptr->target, ptr->lun);
print_command(ptr->cmnd);
@@ -2568,15 +2643,15 @@
printk("); residual=%d; buffers=%d; phase |",
ptr->SCp.this_residual, ptr->SCp.buffers_residual);
- if( ptr->SCp.phase & not_issued ) printk("not issued|");
- if( ptr->SCp.phase & in_selection ) printk("in selection|");
- if( ptr->SCp.phase & disconnected ) printk("disconnected|");
- if( ptr->SCp.phase & aborted ) printk("aborted|");
- if( ptr->SCp.phase & sent_ident ) printk("send_ident|");
- if( ptr->SCp.phase & in_other )
+ if(ptr->SCp.phase & not_issued ) printk("not issued|");
+ if(ptr->SCp.phase & in_selection) printk("in selection|");
+ if(ptr->SCp.phase & disconnected) printk("disconnected|");
+ if(ptr->SCp.phase & aborted ) printk("aborted|");
+ if(ptr->SCp.phase & sent_ident ) printk("send_ident|");
+ if(ptr->SCp.phase & in_other)
{
printk("; in other(");
- switch( (ptr->SCp.phase >> 16) & P_MASK )
+ switch((ptr->SCp.phase >> 16) & P_MASK)
{
case P_DATAO:
printk("DATA OUT");
@@ -2610,7 +2685,7 @@
/*
* Dump the queued data
*/
-static void show_queues(void)
+static void show_queues(struct Scsi_Host *shpnt)
{
unsigned long flags;
Scsi_Cmnd *ptr;
@@ -2618,22 +2693,241 @@
save_flags(flags);
cli();
printk("QUEUE STATUS:\nissue_SC:\n");
- for(ptr=issue_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble )
+ for(ptr=ISSUE_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
show_command(ptr);
printk("current_SC:\n");
- if(current_SC)
- show_command(current_SC);
+ if(CURRENT_SC)
+ show_command(CURRENT_SC);
else
printk("none\n");
printk("disconnected_SC:\n");
- for(ptr=disconnected_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble )
+ for(ptr=DISCONNECTED_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
show_command(ptr);
- disp_ports();
- disp_enintr();
+ disp_ports(shpnt);
+ disp_enintr(shpnt);
+ restore_flags(flags);
+}
+
+int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
+{
+ return(-ENOSYS); /* Currently this is a no-op */
+}
+
+#undef SPRINTF
+#define SPRINTF(args...) pos += sprintf(pos, ## args)
+
+static int get_command(char *pos, Scsi_Cmnd *ptr)
+{
+ char *start = pos;
+ int i;
+
+ SPRINTF("0x%08x: target=%d; lun=%d; cmnd=(",
+ (unsigned int) ptr, ptr->target, ptr->lun);
+
+ for(i=0; i<COMMAND_SIZE(ptr->cmnd[0]); i++)
+ SPRINTF("0x%02x", ptr->cmnd[i]);
+
+ SPRINTF("); residual=%d; buffers=%d; phase |",
+ ptr->SCp.this_residual, ptr->SCp.buffers_residual);
+
+ if(ptr->SCp.phase & not_issued ) SPRINTF("not issued|");
+ if(ptr->SCp.phase & in_selection) SPRINTF("in selection|");
+ if(ptr->SCp.phase & disconnected) SPRINTF("disconnected|");
+ if(ptr->SCp.phase & aborted ) SPRINTF("aborted|");
+ if(ptr->SCp.phase & sent_ident ) SPRINTF("send_ident|");
+ if(ptr->SCp.phase & in_other)
+ {
+ SPRINTF("; in other(");
+ switch((ptr->SCp.phase >> 16) & P_MASK)
+ {
+ case P_DATAO:
+ SPRINTF("DATA OUT");
+ break;
+ case P_DATAI:
+ SPRINTF("DATA IN");
+ break;
+ case P_CMD:
+ SPRINTF("COMMAND");
+ break;
+ case P_STATUS:
+ SPRINTF("STATUS");
+ break;
+ case P_MSGO:
+ SPRINTF("MESSAGE OUT");
+ break;
+ case P_MSGI:
+ SPRINTF("MESSAGE IN");
+ break;
+ default:
+ SPRINTF("*illegal*");
+ break;
+ }
+ SPRINTF(")");
+ if(ptr->SCp.phase & (1<<16))
+ SPRINTF("; phaseend");
+ }
+ SPRINTF("; next=0x%08x\n", (unsigned int) ptr->host_scribble);
+
+ return(pos-start);
+}
+
+#undef SPRINTF
+#define SPRINTF(args...) do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
+
+int aha152x_proc_info(
+ char *buffer,
+ char **start,
+ off_t offset,
+ int length,
+ int hostno,
+ int inout
+ )
+{
+ int i;
+ char *pos = buffer;
+ Scsi_Device *scd;
+ struct Scsi_Host *shpnt;
+ unsigned long flags;
+ Scsi_Cmnd *ptr;
+
+ for(i=0, shpnt= (struct Scsi_Host *) NULL; i<IRQS; i++)
+ if(aha152x_host[i] && aha152x_host[i]->host_no == hostno)
+ shpnt=aha152x_host[i];
+
+ if(!shpnt)
+ return(-ESRCH);
+
+ if(inout) /* Has data been written to the file ? */
+ return(aha152x_set_info(buffer, length, shpnt));
+
+ SPRINTF(AHA152X_REVID "\n");
+
+ save_flags(flags);
+ cli();
+
+ SPRINTF("vital data:\nioports 0x%04x to 0x%04x\n",
+ shpnt->io_port, shpnt->io_port+shpnt->n_io_port-1);
+ SPRINTF("interrupt 0x%02x\n", shpnt->irq);
+ SPRINTF("disconnection/reconnection %s\n",
+ HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled");
+ SPRINTF("parity checking %s\n",
+ HOSTDATA(shpnt)->parity ? "enabled" : "disabled");
+ SPRINTF("synchronous transfers %s\n",
+ HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled");
+ SPRINTF("current queued %d commands\n",
+ HOSTDATA(shpnt)->commands);
+
+#if 0
+ SPRINTF("synchronously operating targets (tick=%ld ns):\n",
+ 250000000/loops_per_sec);
+ for(i=0; i<8; i++)
+ if(HOSTDATA(shpnt)->syncrate[i]&0x7f)
+ SPRINTF("target %d: period %dT/%ldns; req/ack offset %d\n",
+ i,
+ (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2),
+ (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)*
+ 250000000/loops_per_sec,
+ HOSTDATA(shpnt)->syncrate[i]&0x0f);
+#else
+ SPRINTF("synchronously operating targets (tick=50 ns):\n");
+ for(i=0; i<8; i++)
+ if(HOSTDATA(shpnt)->syncrate[i]&0x7f)
+ SPRINTF("target %d: period %dT/%dns; req/ack offset %d\n",
+ i,
+ (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2),
+ (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)*50,
+ HOSTDATA(shpnt)->syncrate[i]&0x0f);
+#endif
+
+#ifdef DEBUG_AHA152X
+#define PDEBUG(flags,txt) if(HOSTDATA(shpnt)->debug & flags) SPRINTF("(%s) ", txt);
+
+ SPRINTF("enabled debugging options:\n");
+
+ PDEBUG(debug_skipports, "skip ports");
+ PDEBUG(debug_queue, "queue");
+ PDEBUG(debug_intr, "interrupt");
+ PDEBUG(debug_selection, "selection");
+ PDEBUG(debug_msgo, "message out");
+ PDEBUG(debug_msgi, "message in");
+ PDEBUG(debug_status, "status");
+ PDEBUG(debug_cmd, "command");
+ PDEBUG(debug_datai, "data in");
+ PDEBUG(debug_datao, "data out");
+ PDEBUG(debug_abort, "abort");
+ PDEBUG(debug_done, "done");
+ PDEBUG(debug_biosparam, "bios parameters");
+ PDEBUG(debug_phases, "phases");
+ PDEBUG(debug_queues, "queues");
+ PDEBUG(debug_reset, "reset");
+
+ SPRINTF("\n");
+#endif
+
+ SPRINTF("queue status:\nnot yet issued commands:\n");
+ for(ptr=ISSUE_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
+ pos += get_command(pos, ptr);
+
+ if(CURRENT_SC)
+ {
+ SPRINTF("current command:\n");
+ pos += get_command(pos, CURRENT_SC);
+ }
+
+ SPRINTF("disconnected commands:\n");
+ for(ptr=DISCONNECTED_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
+ pos += get_command(pos, ptr);
+
restore_flags(flags);
+
+ scd = scsi_devices;
+
+ SPRINTF("Attached devices: %s\n", (scd)?"":"none");
+
+ while (scd) {
+ if (scd->host == shpnt) {
+
+ SPRINTF("Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
+ scd->channel, scd->id, scd->lun);
+ for (i=0; i<8; i++) {
+ if (scd->vendor[i] >= 0x20)
+ SPRINTF("%c", scd->vendor[i]);
+ else
+ SPRINTF(" ");
+ }
+ SPRINTF(" Model: ");
+ for (i = 0; i < 16; i++) {
+ if (scd->model[i] >= 0x20)
+ SPRINTF("%c", scd->model[i]);
+ else
+ SPRINTF(" ");
+ }
+ SPRINTF(" Rev: ");
+ for (i = 0; i < 4; i++) {
+ if (scd->rev[i] >= 0x20)
+ SPRINTF("%c", scd->rev[i]);
+ else
+ SPRINTF(" ");
+ }
+ SPRINTF("\n");
+
+ SPRINTF(" Type: %d ", scd->type);
+ SPRINTF(" ANSI SCSI revision: %02x",
+ (scd->scsi_level < 3)?1:2);
+
+ if (scd->scsi_level == 2)
+ SPRINTF(" CCS\n");
+ else
+ SPRINTF("\n");
+ }
+ scd = scd->next;
+ }
+
+ *start=buffer;
+ return (pos-buffer < length ? pos-buffer : length);
}
#ifdef MODULE
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this