1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

Bring aic7xxx driver bug fixes from 'SCSI' into current.

This commit is contained in:
Justin T. Gibbs 1996-10-06 16:38:45 +00:00
parent 7bea4afad3
commit 2ea8799246
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=18762
6 changed files with 1058 additions and 1078 deletions

View File

@ -39,12 +39,14 @@
*
*-M************************************************************************/
VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.41 1996/06/08 06:54:06 gibbs Exp $"
VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.42 1996/06/09 17:29:11 gibbs Exp $"
#if defined(__NetBSD__)
#include "../../../../dev/ic/aic7xxxreg.h"
#include "../../../../scsi/scsi_message.h"
#elif defined(__FreeBSD__)
#include "../../dev/aic7xxx/aic7xxx_reg.h"
#include "../../scsi/scsi_message.h"
#endif
/*
@ -186,45 +188,36 @@ start_selection:
* Messages are stored in scratch RAM starting with a length byte
* followed by the message itself.
*/
test SCB_CMDLEN,0xff jnz mk_identify /* 0 Length Command? */
/*
* The kernel has sent us an SCB with no command attached. This implies
* that the kernel wants to send a message of some sort to this target,
* so we interrupt the driver, allow it to fill the message buffer, and
* then go back into the arbitration loop
*/
mvi INTSTAT,AWAITING_MSG
jmp wait_for_selection
mk_identify:
and A,DISCENB,SCB_CONTROL /* mask off disconnect privledge */
and MSG0,0x7,SCB_TCL /* lun */
or MSG0,A /* or in disconnect privledge */
or MSG0,MSG_IDENTIFY
or MSG0,MSG_IDENTIFYFLAG
mvi MSG_LEN, 1
test SCB_CONTROL,0xb0 jz !message /* WDTR, SDTR or TAG?? */
/*
* Send a tag message if TAG_ENB is set in the SCB control block.
* Use SCB_TAG (the position in the kernel's SCB array) as the tag value.
*/
mk_tag:
test SCB_CONTROL,TAG_ENB jz mk_message
mvi DINDEX, MSG1
test SCB_CONTROL,TAG_ENB jz mk_tag_done
and DINDIR,0x23,SCB_CONTROL
mov DINDIR,SCB_TAG
add MSG_LEN,COMP_MSG0,DINDEX /* update message length */
mk_tag_done:
/*
* Interrupt the driver, and allow it to tweak the message buffer
* if it asks.
*/
mk_message:
test SCB_CONTROL,MK_MESSAGE jz wait_for_selection
test SCB_CONTROL,0x90 jz !message /* NEEDWDTR|NEEDSDTR */
mov DINDEX call mk_dtr /* build DTR message if needed */
mvi INTSTAT,AWAITING_MSG
!message:
wait_for_selection:
test SSTAT0,SELDO jnz select
test SSTAT0,SELDI jz wait_for_selection
@ -511,7 +504,7 @@ p_status:
*/
p_mesgout:
test MSG_LEN, 0xff jnz p_mesgout_start
mvi MSG_NOP call mk_mesg /* build NOP message */
mvi MSG_NOOP call mk_mesg /* build NOP message */
p_mesgout_start:
/*
@ -569,13 +562,13 @@ p_mesgin:
mvi A call inb_first /* read the 1st message byte */
mov REJBYTE,A /* save it for the driver */
test A,MSG_IDENTIFY jnz mesgin_identify
test A,MSG_IDENTIFYFLAG jnz mesgin_identify
cmp A,MSG_DISCONNECT je mesgin_disconnect
cmp A,MSG_SDPTRS je mesgin_sdptrs
cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs
cmp ALLZEROS,A je mesgin_complete
cmp A,MSG_RDPTRS je mesgin_rdptrs
cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs
cmp A,MSG_EXTENDED je mesgin_extended
cmp A,MSG_REJECT je mesgin_reject
cmp A,MSG_MESSAGE_REJECT je mesgin_reject
rej_mesgin:
/*
@ -589,7 +582,7 @@ rej_mesgin:
or SCSISIGO,ATNO /* turn on ATNO */
mvi INTSTAT,SEND_REJECT /* let driver know */
mvi MSG_REJECT call mk_mesg
mvi MSG_MESSAGE_REJECT call mk_mesg
mesgin_done:
call inb_last /*ack & turn auto PIO back on*/
@ -665,51 +658,38 @@ complete:
/*
* Is it an extended message? We only support the synchronous and wide data
* transfer request messages, which will probably be in response to
* WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it -
* apparently this can be done after any message in byte, according
* to the SCSI-2 spec.
* Is it an extended message? Copy the message to our message buffer and
* notify the host. The host will tell us whether to reject this message,
* respond to it with the message that the host placed in our message buffer,
* or simply to do nothing.
*/
mesgin_extended:
mvi ARG_1 call inb_next /* extended message length */
mvi REJBYTE_EXT call inb_next /* extended message code */
cmp REJBYTE_EXT,MSG_SDTR je p_mesginSDTR
cmp REJBYTE_EXT,MSG_WDTR je p_mesginWDTR
jmp rej_mesgin
p_mesginWDTR:
cmp ARG_1,2 jne rej_mesgin /* extended mesg length=2 */
mvi ARG_1 call inb_next /* Width of bus */
mvi INTSTAT,WDTR_MSG /* let driver know */
test RETURN_1,0xff jz mesgin_done /* Do we need to send WDTR? */
cmp RETURN_1,SEND_REJ je rej_mesgin /*
* Bus width was too large
* Reject it.
*/
/* We didn't initiate the wide negotiation, so we must respond to the request */
and RETURN_1,0x7f /* Clear the SEND_WDTR Flag */
mvi DINDEX,MSG0
mvi MSG0 call mk_wdtr /* build WDTR message */
or SCSISIGO,ATNO /* turn on ATNO */
jmp mesgin_done
p_mesginSDTR:
cmp ARG_1,3 jne rej_mesgin /* extended mesg length=3 */
mvi ARG_1 call inb_next /* xfer period */
mvi A call inb_next /* REQ/ACK offset */
mvi INTSTAT,SDTR_MSG /* call driver to convert */
test RETURN_1,0xff jz mesgin_done /* Do we need to mk_sdtr/rej */
cmp RETURN_1,SEND_REJ je rej_mesgin /*
* Requested SDTR too small
* Reject it.
*/
clr ARG_1 /* Use the scratch ram rate */
mvi DINDEX, MSG0
mvi MSG0 call mk_sdtr
mvi MSGIN_EXT_LEN call inb_next
mvi MSGIN_EXT_OPCODE call inb_next
mov A, MSGIN_EXT_LEN
dec A /* Length counts the op code */
mvi SINDEX, MSGIN_EXT_BYTE0
mesgin_extended_loop:
test A, 0xFF jz mesgin_extended_intr
cmp SINDEX, MSGIN_EXT_LASTBYTE je mesgin_extended_dump
call inb_next
dec A
/*
* We pass the arg to inb in SINDEX, but DINDEX is the one incremented
* so update SINDEX with DINDEX's value before looping again.
*/
mov DINDEX jmp mesgin_extended_loop
mesgin_extended_dump:
/* We have no more storage space, so dump the rest */
test A, 0xFF jz mesgin_extended_intr
mvi NONE call inb_next
dec A
jmp mesgin_extended_dump
mesgin_extended_intr:
mvi INTSTAT,EXTENDED_MSG /* let driver know */
cmp RETURN_1,SEND_REJ je rej_mesgin
cmp RETURN_1,SEND_MSG jne mesgin_done
/* The kernel has setup a message to be sent */
or SCSISIGO,ATNO /* turn on ATNO */
jmp mesgin_done
@ -783,11 +763,11 @@ mesgin_identify:
*/
mvi ARG_1,SCB_LIST_NULL /* Default to no-tag */
snoop_tag_loop:
test SSTAT1,BUSFREE jnz use_findSCB
test SSTAT1,REQINIT jz snoop_tag_loop
test SSTAT1,PHASEMIS jnz use_findSCB
mvi A call inb_first
cmp A,MSG_SIMPLE_TAG jne use_findSCB
test SSTAT1,BUSFREE jnz use_findSCB
test SSTAT1,REQINIT jz snoop_tag_loop
test SSTAT1,PHASEMIS jnz use_findSCB
mvi A call inb_first
cmp A,MSG_SIMPLE_Q_TAG jne use_findSCB
get_tag:
mvi ARG_1 call inb_next /* tag value */
/*
@ -947,7 +927,7 @@ dma5:
and DFCNTRL,WIDEODD
dma6:
test DFCNTRL,0x38 jnz dma6 /* SCSIENACK|SDMAENACK|HDMAENACK */
return:
ret
/*
@ -1087,68 +1067,3 @@ ndx_dtr:
or A,0x08 /* Channel B entries add 8 */
ndx_dtr_2:
add SINDEX,TARG_SCRATCH,A ret
/*
* If we need to negotiate transfer parameters, build the WDTR or SDTR message
* starting at the address passed in SINDEX. DINDEX is modified on return.
* The SCSI-II spec requires that Wide negotiation occur first and you can
* only negotiat one or the other at a time otherwise in the event of a message
* reject, you wouldn't be able to tell which message was the culpret.
*/
mk_dtr:
test SCB_CONTROL,NEEDWDTR jnz mk_wdtr_16bit
mvi ARG_1, MAXOFFSET /* Force an offset of 15 or 8 if WIDE */
mk_sdtr:
mvi DINDIR,1 /* extended message */
mvi DINDIR,3 /* extended message length = 3 */
mvi DINDIR,1 /* SDTR code */
call sdtr_to_rate
mov DINDIR,RETURN_1 /* REQ/ACK transfer period */
cmp ARG_1, MAXOFFSET je mk_sdtr_max_offset
and DINDIR,0x0f,SINDIR /* Sync Offset */
mk_sdtr_done:
add MSG_LEN,COMP_MSG0,DINDEX ret /* update message length */
mk_sdtr_max_offset:
/*
* We're initiating sync negotiation, so request the max offset we can (15 or 8)
*/
/* Talking to a WIDE device? */
test SCSIRATE, WIDEXFER jnz wmax_offset
mvi DINDIR, MAX_OFFSET_8BIT
jmp mk_sdtr_done
wmax_offset:
mvi DINDIR, MAX_OFFSET_16BIT
jmp mk_sdtr_done
mk_wdtr_16bit:
mvi ARG_1,BUS_16_BIT
mk_wdtr:
mvi DINDIR,1 /* extended message */
mvi DINDIR,2 /* extended message length = 2 */
mvi DINDIR,3 /* WDTR code */
mov DINDIR,ARG_1 /* bus width */
add MSG_LEN,COMP_MSG0,DINDEX ret /* update message length */
sdtr_to_rate:
call ndx_dtr /* index scratch space for target */
shr A,SINDIR,0x4
dec SINDEX /* Preserve SINDEX */
and A,0x7
clr RETURN_1
sdtr_to_rate_loop:
test A,0x0f jz sdtr_to_rate_done
add RETURN_1,0x19
dec A
jmp sdtr_to_rate_loop
sdtr_to_rate_done:
shr RETURN_1,0x2
add RETURN_1,0x19
test SXFRCTL0,ULTRAEN jz return
shr RETURN_1,0x1
return:
ret

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: aic7xxx_reg.h,v 1.11 1996/05/21 18:32:23 gibbs Exp $
* $Id: aic7xxx_reg.h,v 1.12 1996/06/09 17:29:12 gibbs Exp $
*/
/*
@ -407,8 +407,7 @@
#define SEND_REJECT 0x11 /* sending a message reject */
#define NO_IDENT 0x21 /* no IDENTIFY after reconnect*/
#define NO_MATCH 0x31 /* no cmd match for reconnect */
#define SDTR_MSG 0x41 /* SDTR message received */
#define WDTR_MSG 0x51 /* WDTR message received */
#define EXTENDED_MSG 0x41 /* Extended message received */
#define REJECT_MSG 0x61 /* Reject message received */
#define BAD_STATUS 0x71 /* Bad status from target */
#define RESIDUAL 0x81 /* Residual byte count != 0 */
@ -527,10 +526,9 @@
*/
#define SCBARRAY 0x0a0
#define SCB_CONTROL 0x0a0
#define NEEDWDTR 0x80
#define MK_MESSAGE 0x80
#define DISCENB 0x40
#define TAG_ENB 0x20
#define NEEDSDTR 0x10
#define DISCONNECTED 0x04
#define SCB_TAG_TYPE 0x03
#define SCB_TCL 0x0a1
@ -682,10 +680,8 @@
*/
#define LASTPHASE 0x03d
#define ARG_1 0x03e
#define MAXOFFSET 0x01
#define RETURN_1 0x03f
#define SEND_WDTR 0x80
#define SEND_SDTR 0x60
#define SEND_MSG 0x80
#define SEND_SENSE 0x40
#define SEND_REJ 0x20
#define SCB_PAGEDIN 0x10
@ -747,6 +743,19 @@
#define ULTRA_ENB 0x052
#define ULTRA_ENB_B 0x053
#define MSGIN_EXT_LEN 0x054
#define MSGIN_EXT_OPCODE 0x055
#define MSGIN_EXT_BYTE0 0x056
#define MSGIN_EXT_BYTE1 0x057
#define MSGIN_EXT_LASTBYTE 0x058 /*
* We don't use this location, but
* continue to store bytes until
* we reach this address (avoids
* a more complicated compare).
* So, we can store at most 2
* bytes for now.
*/
#define SCSICONF 0x05a
#define RESET_SCSI 0x40
@ -757,23 +766,6 @@
#define BIOSDISABLED 0x30
#define CHANNEL_B_PRIMARY 0x08
/* Message codes */
#define MSG_EXTENDED 0x01
#define MSG_SDTR 0x01
#define MSG_WDTR 0x03
#define MSG_SDPTRS 0x02
#define MSG_RDPTRS 0x03
#define MSG_DISCONNECT 0x04
#define MSG_INITIATOR_DET_ERROR 0x05
#define MSG_ABORT 0x06
#define MSG_REJECT 0x07
#define MSG_NOP 0x08
#define MSG_MSG_PARITY_ERROR 0x09
#define MSG_BUS_DEVICE_RESET 0x0c
#define MSG_ABORT_TAG 0x0d
#define MSG_SIMPLE_TAG 0x20
#define MSG_IDENTIFY 0x80
/* WDTR Message values */
#define BUS_8_BIT 0x00
#define BUS_16_BIT 0x01

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: aic7770.c,v 1.30 1996/08/28 18:00:25 bde Exp $
* $Id: aic7770.c,v 1.31 1996/09/06 23:06:55 phk Exp $
*/
#if defined(__FreeBSD__)
@ -133,24 +133,14 @@ aic7770probe(void)
eisa_add_iospace(e_dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE);
intdef = inb(INTDEF + iobase);
switch (intdef & 0xf) {
irq = intdef & 0xf;
switch (irq) {
case 9:
irq = 9;
break;
case 10:
irq = 10;
break;
case 11:
irq = 11;
break;
case 12:
irq = 12;
break;
case 14:
irq = 14;
break;
case 15:
irq = 15;
break;
default:
printf("aic7770 at slot %d: illegal "

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: aic7xxx.h,v 1.27 1996/05/10 16:21:05 gibbs Exp $
* $Id: aic7xxx.h,v 1.28 1996/05/30 07:19:59 gibbs Exp $
*/
#ifndef _AIC7XXX_H_
@ -90,14 +90,14 @@
*/
typedef unsigned long int physaddr;
typedef u_int32_t physaddr;
#if defined(__FreeBSD__)
extern u_long ahc_unit;
#endif
struct ahc_dma_seg {
physaddr addr;
long len;
physaddr addr;
u_int32_t len;
};
typedef enum {
@ -113,6 +113,7 @@ typedef enum {
AHC_AIC78X0 = 0x060, /* PCI Based Controller */
AHC_274 = 0x110, /* EISA Based Controller */
AHC_284 = 0x210, /* VL/ISA Based Controller */
AHC_294AU = 0x421, /* aic7860 based '2940' */
AHC_294 = 0x440, /* PCI Based Controller */
AHC_294U = 0x441, /* ULTRA PCI Based Controller */
AHC_394 = 0x840, /* Twin Channel PCI Controller */
@ -143,18 +144,20 @@ typedef enum {
}ahc_flag;
typedef enum {
SCB_FREE = 0x000,
SCB_ACTIVE = 0x001,
SCB_ABORTED = 0x002,
SCB_DEVICE_RESET = 0x004,
SCB_IMMED = 0x008,
SCB_SENSE = 0x010,
SCB_TIMEDOUT = 0x020,
SCB_QUEUED_FOR_DONE = 0x040,
SCB_PAGED_OUT = 0x080,
SCB_WAITINGQ = 0x100,
SCB_ASSIGNEDQ = 0x200,
SCB_SENTORDEREDTAG = 0x400
SCB_FREE = 0x0000,
SCB_ACTIVE = 0x0001,
SCB_ABORTED = 0x0002,
SCB_DEVICE_RESET = 0x0004,
SCB_IMMED = 0x0008,
SCB_SENSE = 0x0010,
SCB_TIMEDOUT = 0x0020,
SCB_QUEUED_FOR_DONE = 0x0040,
SCB_PAGED_OUT = 0x0080,
SCB_WAITINGQ = 0x0100,
SCB_ASSIGNEDQ = 0x0200,
SCB_SENTORDEREDTAG = 0x0400,
SCB_MSGOUT_SDTR = 0x0800,
SCB_MSGOUT_WDTR = 0x1000
}scb_flag;
/*
@ -173,7 +176,7 @@ struct scb {
/*8*/ u_char residual_SG_segment_count;
/*9*/ u_char residual_data_count[3];
/*12*/ physaddr data;
/*16*/ u_long datalen; /* Really only three bits, but its
/*16*/ u_int32_t datalen; /* Really only three bits, but its
* faster to treat it as a long on
* a quad boundary.
*/

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: aic7870.c,v 1.36 1996/05/30 07:20:17 gibbs Exp $
* $Id: aic7870.c,v 1.37 1996/06/08 06:55:55 gibbs Exp $
*/
#if defined(__FreeBSD__)
@ -81,6 +81,7 @@
#define PCI_DEVICE_ID_ADAPTEC_3940U 0x82789004ul
#define PCI_DEVICE_ID_ADAPTEC_2944U 0x84789004ul
#define PCI_DEVICE_ID_ADAPTEC_2940U 0x81789004ul
#define PCI_DEVICE_ID_ADAPTEC_2940AU 0x61789004ul
#define PCI_DEVICE_ID_ADAPTEC_3940 0x72789004ul
#define PCI_DEVICE_ID_ADAPTEC_2944 0x74789004ul
#define PCI_DEVICE_ID_ADAPTEC_2940 0x71789004ul
@ -216,6 +217,9 @@ aic7870_probe (pcici_t tag, pcidi_t type)
case PCI_DEVICE_ID_ADAPTEC_2940:
return ("Adaptec 2940 SCSI host adapter");
break;
case PCI_DEVICE_ID_ADAPTEC_2940AU:
return ("Adaptec 2940A Ultra SCSI host adapter");
break;
case PCI_DEVICE_ID_ADAPTEC_AIC7880:
return ("Adaptec aic7880 Ultra SCSI host adapter");
break;
@ -258,6 +262,7 @@ ahc_pci_probe(parent, match, aux)
case PCI_DEVICE_ID_ADAPTEC_3940U:
case PCI_DEVICE_ID_ADAPTEC_2944U:
case PCI_DEVICE_ID_ADAPTEC_2940U:
case PCI_DEVICE_ID_ADAPTEC_2940AU:
case PCI_DEVICE_ID_ADAPTEC_3940:
case PCI_DEVICE_ID_ADAPTEC_2944:
case PCI_DEVICE_ID_ADAPTEC_2940:
@ -345,6 +350,9 @@ ahc_pci_attach(parent, self, aux)
case PCI_DEVICE_ID_ADAPTEC_2940:
ahc_t = AHC_294;
break;
case PCI_DEVICE_ID_ADAPTEC_2940AU:
ahc_t = AHC_294AU;
break;
case PCI_DEVICE_ID_ADAPTEC_AIC7880:
ahc_t = AHC_AIC7880;
break;
@ -439,11 +447,12 @@ ahc_pci_attach(parent, self, aux)
return;
}
intrstr = pci_intr_string(pa->pa_pc, ih);
ahc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc
#ifdef __OpenBSD__
, ahc->sc_dev.dv_xname
ahc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc,
ahc->sc_dev.dv_xname);
#else
ahc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc);
#endif
);
if (ahc->sc_ih == NULL) {
printf("%s: couldn't establish interrupt",
ahc->sc_dev.dv_xname);
@ -487,14 +496,11 @@ ahc_pci_attach(parent, self, aux)
load_seeprom(ahc);
break;
}
case AHC_294AU:
case AHC_AIC7860:
{
id_string = "aic7860 ";
/*
* Use defaults, if the chip wasn't initialized by
* a BIOS.
*/
ahc->flags |= AHC_USEDEFAULTS;
load_seeprom(ahc);
break;
}
case AHC_AIC7850: