Home | History | Annotate | Line # | Download | only in ic
aic7xxx.c revision 1.4
      1  1.4  mycroft /*	$NetBSD: aic7xxx.c,v 1.4 1996/03/28 22:39:08 mycroft Exp $	*/
      2  1.1  mycroft 
      3  1.1  mycroft /*
      4  1.1  mycroft  * Generic driver for the aic7xxx based adaptec SCSI controllers
      5  1.1  mycroft  * Copyright (c) 1994, 1995 Justin T. Gibbs.
      6  1.1  mycroft  * All rights reserved.
      7  1.1  mycroft  *
      8  1.1  mycroft  * Product specific probe and attach routines can be found in:
      9  1.1  mycroft  * i386/isa/aic7770.c	27/284X and aic7770 motherboard controllers
     10  1.1  mycroft  * /pci/aic7870.c	294x and aic7870 motherboard controllers
     11  1.1  mycroft  *
     12  1.1  mycroft  * Portions of this driver are based on the FreeBSD 1742 Driver:
     13  1.1  mycroft  *
     14  1.1  mycroft  * Written by Julian Elischer (julian (at) tfs.com)
     15  1.1  mycroft  * for TRW Financial Systems for use under the MACH(2.5) operating system.
     16  1.1  mycroft  *
     17  1.1  mycroft  * TRW Financial Systems, in accordance with their agreement with Carnegie
     18  1.1  mycroft  * Mellon University, makes this software available to CMU to distribute
     19  1.1  mycroft  * or use in any manner that they see fit as long as this message is kept with
     20  1.1  mycroft  * the software. For this reason TFS also grants any other persons or
     21  1.1  mycroft  * organisations permission to use or modify this software.
     22  1.1  mycroft  *
     23  1.1  mycroft  * TFS supplies this software to be publicly redistributed
     24  1.1  mycroft  * on the understanding that TFS is not responsible for the correct
     25  1.1  mycroft  * functioning of this software in any circumstances.
     26  1.1  mycroft  *
     27  1.1  mycroft  * commenced: Sun Sep 27 18:14:01 PDT 1992
     28  1.1  mycroft  */
     29  1.1  mycroft /*
     30  1.1  mycroft  * TODO:
     31  1.1  mycroft  *	Add target reset capabilities
     32  1.1  mycroft  *	Implement Target Mode
     33  1.1  mycroft  */
     34  1.1  mycroft 
     35  1.1  mycroft #include <sys/types.h>
     36  1.1  mycroft #include <sys/param.h>
     37  1.1  mycroft #include <sys/systm.h>
     38  1.1  mycroft #include <sys/kernel.h>
     39  1.1  mycroft #include <sys/device.h>
     40  1.1  mycroft #include <sys/malloc.h>
     41  1.1  mycroft #include <sys/buf.h>
     42  1.1  mycroft #include <sys/proc.h>
     43  1.1  mycroft #include <sys/user.h>
     44  1.1  mycroft 
     45  1.1  mycroft #include <machine/pio.h>
     46  1.1  mycroft 
     47  1.1  mycroft #include <scsi/scsi_all.h>
     48  1.1  mycroft #include <scsi/scsi_debug.h>
     49  1.1  mycroft #include <scsi/scsiconf.h>
     50  1.1  mycroft 
     51  1.1  mycroft #include <dev/ic/aic7xxxvar.h>
     52  1.1  mycroft 
     53  1.1  mycroft int     ahc_init __P((struct ahc_softc *));
     54  1.1  mycroft void    ahc_loadseq __P((int));
     55  1.1  mycroft int     ahc_scsi_cmd __P((struct scsi_xfer *));
     56  1.1  mycroft void    ahc_timeout __P((void *));
     57  1.1  mycroft void    ahc_done __P((struct ahc_softc *, struct ahc_scb *));
     58  1.1  mycroft struct  ahc_scb *ahc_get_scb __P((struct ahc_softc *, int));
     59  1.1  mycroft void    ahc_free_scb __P((struct ahc_softc *, struct ahc_scb *, int));
     60  1.1  mycroft void	ahc_abort_scb __P((struct ahc_softc *, struct ahc_scb *));
     61  1.1  mycroft void    ahcminphys __P((struct buf *));
     62  1.1  mycroft int	ahc_poll __P((struct ahc_softc *, struct scsi_xfer *, int));
     63  1.1  mycroft 
     64  1.1  mycroft /* Different debugging levels */
     65  1.1  mycroft #define AHC_SHOWMISC 0x0001
     66  1.1  mycroft #define AHC_SHOWCMDS 0x0002
     67  1.1  mycroft #define AHC_SHOWSCBS 0x0004
     68  1.1  mycroft /*#define AHC_DEBUG /**/
     69  1.1  mycroft int     ahc_debug = AHC_SHOWMISC;
     70  1.1  mycroft 
     71  1.1  mycroft /*#define AHC_MORE_DEBUG /**/
     72  1.1  mycroft 
     73  1.1  mycroft #ifdef AHC_MORE_DEBUG
     74  1.1  mycroft #define DEBUGLEVEL  -1
     75  1.1  mycroft #define DEBUGTARGET 0x0
     76  1.1  mycroft #endif
     77  1.1  mycroft 
     78  1.1  mycroft /**** bit definitions for SCSIDEF ****/
     79  1.1  mycroft #define	HSCSIID		0x07		/* our SCSI ID */
     80  1.1  mycroft #define HWSCSIID	0x0f		/* our SCSI ID if Wide Bus */
     81  1.1  mycroft 
     82  1.1  mycroft struct scsi_adapter ahc_switch = {
     83  1.1  mycroft 	ahc_scsi_cmd,
     84  1.1  mycroft 	ahcminphys,
     85  1.1  mycroft 	0,
     86  1.1  mycroft 	0,
     87  1.1  mycroft };
     88  1.1  mycroft 
     89  1.1  mycroft 
     90  1.1  mycroft /* the below structure is so we have a default dev struct for our link struct */
     91  1.1  mycroft struct scsi_device ahc_dev = {
     92  1.1  mycroft 	NULL,				/* Use default error handler */
     93  1.1  mycroft 	NULL,				/* have a queue, served by this */
     94  1.1  mycroft 	NULL,				/* have no async handler */
     95  1.1  mycroft 	NULL,				/* Use default 'done' routine */
     96  1.1  mycroft };
     97  1.1  mycroft 
     98  1.1  mycroft 
     99  1.1  mycroft /*
    100  1.1  mycroft  * All of these should be in a separate header file shared by the sequencer
    101  1.1  mycroft  * code and the kernel level driver.  The only catch is that we would need to
    102  1.1  mycroft  * add an additional 0xc00 offset when using them in the kernel driver.  The
    103  1.1  mycroft  * aic7770 assembler must be modified to allow include files as well.  All
    104  1.1  mycroft  * page numbers refer to the Adaptec AIC-7770 Data Book available from
    105  1.1  mycroft  * Adaptec's Technical Documents Department 1-800-934-2766
    106  1.1  mycroft  */
    107  1.1  mycroft 
    108  1.1  mycroft /* -------------------- AIC-7770 offset definitions ----------------------- */
    109  1.1  mycroft 
    110  1.1  mycroft /*
    111  1.1  mycroft  * SCSI Sequence Control (p. 3-11).
    112  1.1  mycroft  * Each bit, when set starts a specific SCSI sequence on the bus
    113  1.1  mycroft  */
    114  1.1  mycroft #define SCSISEQ			0xc00ul
    115  1.1  mycroft #define		TEMODEO		0x80
    116  1.1  mycroft #define		ENSELO		0x40
    117  1.1  mycroft #define		ENSELI		0x20
    118  1.1  mycroft #define		ENRSELI		0x10
    119  1.1  mycroft #define		ENAUTOATNO	0x08
    120  1.1  mycroft #define		ENAUTOATNI	0x04
    121  1.1  mycroft #define		ENAUTOATNP	0x02
    122  1.1  mycroft #define		SCSIRSTO	0x01
    123  1.1  mycroft 
    124  1.1  mycroft /*
    125  1.1  mycroft  * SCSI Transfer Control 1 Register (pp. 3-14,15).
    126  1.1  mycroft  * Controls the SCSI module data path.
    127  1.1  mycroft  */
    128  1.1  mycroft #define	SXFRCTL1		0xc02ul
    129  1.1  mycroft #define		BITBUCKET	0x80
    130  1.1  mycroft #define		SWRAPEN		0x40
    131  1.1  mycroft #define		ENSPCHK		0x20
    132  1.1  mycroft #define		STIMESEL	0x18
    133  1.1  mycroft #define		ENSTIMER	0x04
    134  1.1  mycroft #define		ACTNEGEN	0x02
    135  1.1  mycroft #define		STPWEN		0x01	/* Powered Termination */
    136  1.1  mycroft 
    137  1.1  mycroft /*
    138  1.1  mycroft  * SCSI Interrrupt Mode 1 (pp. 3-28,29).
    139  1.1  mycroft  * Set bits in this register enable the corresponding
    140  1.1  mycroft  * interrupt source.
    141  1.1  mycroft  */
    142  1.1  mycroft #define	SIMODE1			0xc11ul
    143  1.1  mycroft #define		ENSELTIMO	0x80
    144  1.1  mycroft #define		ENATNTARG	0x40
    145  1.1  mycroft #define		ENSCSIRST	0x20
    146  1.1  mycroft #define		ENPHASEMIS	0x10
    147  1.1  mycroft #define		ENBUSFREE	0x08
    148  1.1  mycroft #define		ENSCSIPERR	0x04
    149  1.1  mycroft #define		ENPHASECHG	0x02
    150  1.1  mycroft #define		ENREQINIT	0x01
    151  1.1  mycroft 
    152  1.1  mycroft /*
    153  1.1  mycroft  * SCSI Control Signal Read Register (p. 3-15).
    154  1.1  mycroft  * Reads the actual state of the SCSI bus pins
    155  1.1  mycroft  */
    156  1.1  mycroft #define SCSISIGI		0xc03ul
    157  1.1  mycroft #define		CDI		0x80
    158  1.1  mycroft #define		IOI		0x40
    159  1.1  mycroft #define		MSGI		0x20
    160  1.1  mycroft #define		ATNI		0x10
    161  1.1  mycroft #define		SELI		0x08
    162  1.1  mycroft #define		BSYI		0x04
    163  1.1  mycroft #define		REQI		0x02
    164  1.1  mycroft #define		ACKI		0x01
    165  1.1  mycroft 
    166  1.1  mycroft /*
    167  1.1  mycroft  * SCSI Contol Signal Write Register (p. 3-16).
    168  1.1  mycroft  * Writing to this register modifies the control signals on the bus.  Only
    169  1.1  mycroft  * those signals that are allowed in the current mode (Initiator/Target) are
    170  1.1  mycroft  * asserted.
    171  1.1  mycroft  */
    172  1.1  mycroft #define SCSISIGO		0xc03ul
    173  1.1  mycroft #define		CDO		0x80
    174  1.1  mycroft #define		IOO		0x40
    175  1.1  mycroft #define		MSGO		0x20
    176  1.1  mycroft #define		ATNO		0x10
    177  1.1  mycroft #define		SELO		0x08
    178  1.1  mycroft #define		BSYO		0x04
    179  1.1  mycroft #define		REQO		0x02
    180  1.1  mycroft #define		ACKO		0x01
    181  1.1  mycroft 
    182  1.1  mycroft /* XXX document this thing */
    183  1.1  mycroft #define SCSIRATE		0xc04ul
    184  1.1  mycroft 
    185  1.1  mycroft /*
    186  1.1  mycroft  * SCSI ID (p. 3-18).
    187  1.1  mycroft  * Contains the ID of the board and the current target on the
    188  1.1  mycroft  * selected channel
    189  1.1  mycroft  */
    190  1.1  mycroft #define SCSIID			0xc05ul
    191  1.1  mycroft #define		TID		0xf0		/* Target ID mask */
    192  1.1  mycroft #define		OID		0x0f		/* Our ID mask */
    193  1.1  mycroft 
    194  1.1  mycroft /*
    195  1.1  mycroft  * SCSI Status 0 (p. 3-21)
    196  1.1  mycroft  * Contains one set of SCSI Interrupt codes
    197  1.1  mycroft  * These are most likely of interest to the sequencer
    198  1.1  mycroft  */
    199  1.1  mycroft #define SSTAT0			0xc0bul
    200  1.1  mycroft #define		TARGET		0x80		/* Board is a target */
    201  1.1  mycroft #define		SELDO		0x40		/* Selection Done */
    202  1.1  mycroft #define		SELDI		0x20		/* Board has been selected */
    203  1.1  mycroft #define		SELINGO		0x10		/* Selection In Progress */
    204  1.1  mycroft #define		SWRAP		0x08		/* 24bit counter wrap */
    205  1.1  mycroft #define		SDONE		0x04		/* STCNT = 0x000000 */
    206  1.1  mycroft #define		SPIORDY		0x02		/* SCSI PIO Ready */
    207  1.1  mycroft #define		DMADONE		0x01		/* DMA transfer completed */
    208  1.1  mycroft 
    209  1.1  mycroft /*
    210  1.1  mycroft  * Clear SCSI Interrupt 1 (p. 3-23)
    211  1.1  mycroft  * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT1.
    212  1.1  mycroft  */
    213  1.1  mycroft #define CLRSINT1		0xc0cul
    214  1.1  mycroft #define		CLRSELTIMEO	0x80
    215  1.1  mycroft #define		CLRATNO		0x40
    216  1.1  mycroft #define		CLRSCSIRSTI	0x20
    217  1.1  mycroft /*  UNUSED			0x10 */
    218  1.1  mycroft #define		CLRBUSFREE	0x08
    219  1.1  mycroft #define		CLRSCSIPERR	0x04
    220  1.1  mycroft #define		CLRPHASECHG	0x02
    221  1.1  mycroft #define		CLRREQINIT	0x01
    222  1.1  mycroft 
    223  1.1  mycroft /*
    224  1.1  mycroft  * SCSI Status 1 (p. 3-24)
    225  1.1  mycroft  * These interrupt bits are of interest to the kernel driver
    226  1.1  mycroft  */
    227  1.1  mycroft #define SSTAT1			0xc0cul
    228  1.1  mycroft #define		SELTO		0x80
    229  1.1  mycroft #define		ATNTARG		0x40
    230  1.1  mycroft #define		SCSIRSTI	0x20
    231  1.1  mycroft #define		PHASEMIS	0x10
    232  1.1  mycroft #define		BUSFREE		0x08
    233  1.1  mycroft #define		SCSIPERR	0x04
    234  1.1  mycroft #define		PHASECHG	0x02
    235  1.1  mycroft #define		REQINIT		0x01
    236  1.1  mycroft 
    237  1.1  mycroft /*
    238  1.1  mycroft  * Selection/Reselection ID (p. 3-31)
    239  1.1  mycroft  * Upper four bits are the device id.  The ONEBIT is set when the re/selecting
    240  1.1  mycroft  * device did not set its own ID.
    241  1.1  mycroft  */
    242  1.1  mycroft #define SELID			0xc19ul
    243  1.1  mycroft #define		SELID_MASK	0xf0
    244  1.1  mycroft #define		ONEBIT		0x08
    245  1.1  mycroft /*  UNUSED			0x07 */
    246  1.1  mycroft 
    247  1.1  mycroft /*
    248  1.1  mycroft  * SCSI Block Control (p. 3-32)
    249  1.1  mycroft  * Controls Bus type and channel selection.  In a twin channel configuration
    250  1.1  mycroft  * addresses 0x00-0x1e are gated to the appropriate channel based on this
    251  1.1  mycroft  * register.  SELWIDE allows for the coexistence of 8bit and 16bit devices
    252  1.1  mycroft  * on a wide bus.
    253  1.1  mycroft  */
    254  1.1  mycroft #define SBLKCTL			0xc1ful
    255  1.1  mycroft /*  UNUSED			0xc0 */
    256  1.1  mycroft #define		AUTOFLUSHDIS	0x20
    257  1.1  mycroft /*  UNUSED			0x10 */
    258  1.1  mycroft #define		SELBUSB		0x08
    259  1.1  mycroft /*  UNUSED			0x04 */
    260  1.1  mycroft #define		SELWIDE		0x02
    261  1.1  mycroft /*  UNUSED			0x01 */
    262  1.1  mycroft 
    263  1.1  mycroft /*
    264  1.1  mycroft  * Sequencer Control (p. 3-33)
    265  1.1  mycroft  * Error detection mode and speed configuration
    266  1.1  mycroft  */
    267  1.1  mycroft #define SEQCTL			0xc60ul
    268  1.1  mycroft #define		PERRORDIS	0x80
    269  1.1  mycroft #define		PAUSEDIS	0x40
    270  1.1  mycroft #define		FAILDIS		0x20
    271  1.1  mycroft #define		FASTMODE	0x10
    272  1.1  mycroft #define		BRKADRINTEN	0x08
    273  1.1  mycroft #define		STEP		0x04
    274  1.1  mycroft #define		SEQRESET	0x02
    275  1.1  mycroft #define		LOADRAM		0x01
    276  1.1  mycroft 
    277  1.1  mycroft /*
    278  1.1  mycroft  * Sequencer RAM Data (p. 3-34)
    279  1.1  mycroft  * Single byte window into the Scratch Ram area starting at the address
    280  1.1  mycroft  * specified by SEQADDR0 and SEQADDR1.  To write a full word, simply write
    281  1.1  mycroft  * four bytes in sucessesion.  The SEQADDRs will increment after the most
    282  1.1  mycroft  * significant byte is written
    283  1.1  mycroft  */
    284  1.1  mycroft #define SEQRAM			0xc61ul
    285  1.1  mycroft 
    286  1.1  mycroft /*
    287  1.1  mycroft  * Sequencer Address Registers (p. 3-35)
    288  1.1  mycroft  * Only the first bit of SEQADDR1 holds addressing information
    289  1.1  mycroft  */
    290  1.1  mycroft #define SEQADDR0		0xc62ul
    291  1.1  mycroft #define SEQADDR1		0xc63ul
    292  1.1  mycroft #define		SEQADDR1_MASK	0x01
    293  1.1  mycroft 
    294  1.1  mycroft /*
    295  1.1  mycroft  * Accumulator
    296  1.1  mycroft  * We cheat by passing arguments in the Accumulator up to the kernel driver
    297  1.1  mycroft  */
    298  1.1  mycroft #define ACCUM			0xc64ul
    299  1.1  mycroft 
    300  1.1  mycroft #define SINDEX			0xc65ul
    301  1.1  mycroft 
    302  1.1  mycroft /*
    303  1.1  mycroft  * Board Control (p. 3-43)
    304  1.1  mycroft  */
    305  1.1  mycroft #define BCTL			0xc84ul
    306  1.1  mycroft /*   RSVD			0xf0 */
    307  1.1  mycroft #define		ACE		0x08	/* Support for external processors */
    308  1.1  mycroft /*   RSVD			0x06 */
    309  1.1  mycroft #define		ENABLE		0x01
    310  1.1  mycroft 
    311  1.1  mycroft /*
    312  1.1  mycroft  * Host Control (p. 3-47) R/W
    313  1.1  mycroft  * Overal host control of the device.
    314  1.1  mycroft  */
    315  1.1  mycroft #define HCNTRL			0xc87ul
    316  1.1  mycroft /*    UNUSED			0x80 */
    317  1.1  mycroft #define		POWRDN		0x40
    318  1.1  mycroft /*    UNUSED			0x20 */
    319  1.1  mycroft #define		SWINT		0x10
    320  1.1  mycroft #define		IRQMS		0x08
    321  1.1  mycroft #define		PAUSE		0x04
    322  1.1  mycroft #define		INTEN		0x02
    323  1.1  mycroft #define		CHIPRST		0x01
    324  1.1  mycroft 
    325  1.1  mycroft /*
    326  1.1  mycroft  * SCB Pointer (p. 3-49)
    327  1.1  mycroft  * Gate one of the four SCBs into the SCBARRAY window.
    328  1.1  mycroft  */
    329  1.1  mycroft #define SCBPTR			0xc90ul
    330  1.1  mycroft 
    331  1.1  mycroft /*
    332  1.1  mycroft  * Interrupt Status (p. 3-50)
    333  1.1  mycroft  * Status for system interrupts
    334  1.1  mycroft  */
    335  1.1  mycroft #define INTSTAT			0xc91ul
    336  1.1  mycroft #define		SEQINT_MASK	0xf0		/* SEQINT Status Codes */
    337  1.1  mycroft #define			BAD_PHASE	0x00
    338  1.1  mycroft #define			SEND_REJECT	0x10
    339  1.1  mycroft #define			NO_IDENT	0x20
    340  1.1  mycroft #define			NO_MATCH	0x30
    341  1.1  mycroft #define			MSG_SDTR	0x40
    342  1.1  mycroft #define			MSG_WDTR	0x50
    343  1.1  mycroft #define			MSG_REJECT	0x60
    344  1.1  mycroft #define			BAD_STATUS	0x70
    345  1.1  mycroft #define			RESIDUAL	0x80
    346  1.1  mycroft #define			ABORT_TAG	0x90
    347  1.1  mycroft #define		BRKADRINT 0x08
    348  1.1  mycroft #define		SCSIINT	  0x04
    349  1.1  mycroft #define		CMDCMPLT  0x02
    350  1.1  mycroft #define		SEQINT    0x01
    351  1.1  mycroft #define		INT_PEND  (BRKADRINT | SEQINT | SCSIINT | CMDCMPLT)
    352  1.1  mycroft 
    353  1.1  mycroft /*
    354  1.1  mycroft  * Hard Error (p. 3-53)
    355  1.1  mycroft  * Reporting of catastrophic errors.  You usually cannot recover from
    356  1.1  mycroft  * these without a full board reset.
    357  1.1  mycroft  */
    358  1.1  mycroft #define ERROR			0xc92ul
    359  1.1  mycroft /*    UNUSED			0xf0 */
    360  1.1  mycroft #define		PARERR		0x08
    361  1.1  mycroft #define		ILLOPCODE	0x04
    362  1.1  mycroft #define		ILLSADDR	0x02
    363  1.1  mycroft #define		ILLHADDR	0x01
    364  1.1  mycroft 
    365  1.1  mycroft /*
    366  1.1  mycroft  * Clear Interrupt Status (p. 3-52)
    367  1.1  mycroft  */
    368  1.1  mycroft #define CLRINT			0xc92ul
    369  1.1  mycroft #define		CLRBRKADRINT	0x08
    370  1.1  mycroft #define		CLRSCSIINT      0x04
    371  1.1  mycroft #define		CLRCMDINT	0x02
    372  1.1  mycroft #define		CLRSEQINT	0x01
    373  1.1  mycroft 
    374  1.1  mycroft /*
    375  1.1  mycroft  * SCB Auto Increment (p. 3-59)
    376  1.1  mycroft  * Byte offset into the SCB Array and an optional bit to allow auto
    377  1.1  mycroft  * incrementing of the address during download and upload operations
    378  1.1  mycroft  */
    379  1.1  mycroft #define SCBCNT			0xc9aul
    380  1.1  mycroft #define		SCBAUTO		0x80
    381  1.1  mycroft #define		SCBCNT_MASK	0x1f
    382  1.1  mycroft 
    383  1.1  mycroft /*
    384  1.1  mycroft  * Queue In FIFO (p. 3-60)
    385  1.1  mycroft  * Input queue for queued SCBs (commands that the seqencer has yet to start)
    386  1.1  mycroft  */
    387  1.1  mycroft #define QINFIFO			0xc9bul
    388  1.1  mycroft 
    389  1.1  mycroft /*
    390  1.1  mycroft  * Queue In Count (p. 3-60)
    391  1.1  mycroft  * Number of queued SCBs
    392  1.1  mycroft  */
    393  1.1  mycroft #define QINCNT			0xc9cul
    394  1.1  mycroft 
    395  1.1  mycroft /*
    396  1.1  mycroft  * Queue Out FIFO (p. 3-61)
    397  1.1  mycroft  * Queue of SCBs that have completed and await the host
    398  1.1  mycroft  */
    399  1.1  mycroft #define QOUTFIFO		0xc9dul
    400  1.1  mycroft 
    401  1.1  mycroft /*
    402  1.1  mycroft  * Queue Out Count (p. 3-61)
    403  1.1  mycroft  * Number of queued SCBs in the Out FIFO
    404  1.1  mycroft  */
    405  1.1  mycroft #define QOUTCNT			0xc9eul
    406  1.1  mycroft 
    407  1.1  mycroft #define SCBARRAY		0xca0ul
    408  1.1  mycroft 
    409  1.1  mycroft /* ---------------- END AIC-7770 Register Definitions ----------------- */
    410  1.1  mycroft 
    411  1.1  mycroft /* --------------------- AIC-7870-only definitions -------------------- */
    412  1.1  mycroft 
    413  1.1  mycroft #define DSPCISTATUS		0xc86ul
    414  1.1  mycroft 
    415  1.1  mycroft /* ---------------------- Scratch RAM Offsets ------------------------- */
    416  1.1  mycroft /* These offsets are either to values that are initialized by the board's
    417  1.1  mycroft  * BIOS or are specified by the Linux sequencer code.  If I can figure out
    418  1.1  mycroft  * how to read the EISA configuration info at probe time, the cards could
    419  1.1  mycroft  * be run without BIOS support installed
    420  1.1  mycroft  */
    421  1.1  mycroft 
    422  1.1  mycroft /*
    423  1.1  mycroft  * 1 byte per target starting at this address for configuration values
    424  1.1  mycroft  */
    425  1.1  mycroft #define HA_TARG_SCRATCH		0xc20ul
    426  1.1  mycroft 
    427  1.1  mycroft /*
    428  1.1  mycroft  * The sequencer will stick the frist byte of any rejected message here so
    429  1.1  mycroft  * we can see what is getting thrown away.
    430  1.1  mycroft  */
    431  1.1  mycroft #define HA_REJBYTE		0xc31ul
    432  1.1  mycroft 
    433  1.1  mycroft /*
    434  1.1  mycroft  * Length of pending message
    435  1.1  mycroft  */
    436  1.1  mycroft #define HA_MSG_LEN		0xc34ul
    437  1.1  mycroft 
    438  1.1  mycroft /*
    439  1.1  mycroft  * message body
    440  1.1  mycroft  */
    441  1.1  mycroft #define HA_MSG_START		0xc35ul	/* outgoing message body */
    442  1.1  mycroft 
    443  1.1  mycroft /*
    444  1.1  mycroft  * These are offsets into the card's scratch ram.  Some of the values are
    445  1.1  mycroft  * specified in the AHA2742 technical reference manual and are initialized
    446  1.1  mycroft  * by the BIOS at boot time.
    447  1.1  mycroft  */
    448  1.1  mycroft #define HA_ARG_1		0xc4aul
    449  1.1  mycroft #define HA_RETURN_1		0xc4aul
    450  1.1  mycroft #define		SEND_SENSE	0x80
    451  1.1  mycroft #define		SEND_WDTR	0x80
    452  1.1  mycroft #define		SEND_SDTR	0x80
    453  1.1  mycroft #define		SEND_REJ	0x40
    454  1.1  mycroft 
    455  1.1  mycroft #define HA_SIGSTATE		0xc4bul
    456  1.1  mycroft 
    457  1.1  mycroft #define HA_SCBCOUNT		0xc52ul
    458  1.1  mycroft #define HA_FLAGS		0xc53ul
    459  1.1  mycroft #define		SINGLE_BUS	0x00
    460  1.1  mycroft #define		TWIN_BUS	0x01
    461  1.1  mycroft #define		WIDE_BUS	0x02
    462  1.1  mycroft #define		ACTIVE_MSG	0x20
    463  1.1  mycroft #define		IDENTIFY_SEEN	0x40
    464  1.1  mycroft #define		RESELECTING	0x80
    465  1.1  mycroft 
    466  1.1  mycroft #define	HA_ACTIVE0		0xc54ul
    467  1.1  mycroft #define	HA_ACTIVE1		0xc55ul
    468  1.1  mycroft #define	SAVED_TCL		0xc56ul
    469  1.1  mycroft #define WAITING_SCBH		0xc57ul
    470  1.1  mycroft #define WAITING_SCBT		0xc58ul
    471  1.1  mycroft 
    472  1.1  mycroft #define HA_SCSICONF		0xc5aul
    473  1.1  mycroft #define INTDEF			0xc5cul
    474  1.1  mycroft #define HA_HOSTCONF		0xc5dul
    475  1.1  mycroft 
    476  1.1  mycroft #define MSG_ABORT               0x06
    477  1.1  mycroft #define	BUS_8_BIT		0x00
    478  1.1  mycroft #define BUS_16_BIT		0x01
    479  1.1  mycroft #define BUS_32_BIT		0x02
    480  1.1  mycroft 
    481  1.1  mycroft /*
    482  1.1  mycroft  * Since the sequencer can disable pausing in a critical section, we
    483  1.1  mycroft  * must loop until it actually stops.
    484  1.1  mycroft  * XXX Should add a timeout in here??
    485  1.1  mycroft  */
    486  1.1  mycroft #define PAUSE_SEQUENCER(ahc) \
    487  1.1  mycroft 	do {								\
    488  1.1  mycroft 		outb(HCNTRL + ahc->sc_iobase, ahc->pause);		\
    489  1.1  mycroft 		while ((inb(HCNTRL + ahc->sc_iobase) & PAUSE) == 0)	\
    490  1.1  mycroft 			;						\
    491  1.1  mycroft 	} while (0)
    492  1.1  mycroft 
    493  1.1  mycroft #define UNPAUSE_SEQUENCER(ahc) \
    494  1.1  mycroft 	do {								\
    495  1.1  mycroft 		outb(HCNTRL + ahc->sc_iobase, ahc->unpause);		\
    496  1.1  mycroft 	} while (0)
    497  1.1  mycroft 
    498  1.1  mycroft /*
    499  1.1  mycroft  * Restart the sequencer program from address zero
    500  1.1  mycroft  * XXX Should add a timeout in here??
    501  1.1  mycroft  */
    502  1.1  mycroft #define RESET_SEQUENCER(ahc) \
    503  1.1  mycroft 	do {								\
    504  1.1  mycroft 		do {							\
    505  1.1  mycroft 			outb(SEQCTL + ahc->sc_iobase, SEQRESET|FASTMODE); \
    506  1.1  mycroft 		} while (inb(SEQADDR0 + ahc->sc_iobase) != 0 &&		\
    507  1.1  mycroft 			 inb(SEQADDR1 + ahc->sc_iobase) != 0);		\
    508  1.1  mycroft 	} while (0)
    509  1.1  mycroft 
    510  1.1  mycroft #define RESTART_SEQUENCER(ahc) \
    511  1.1  mycroft 	do {								\
    512  1.1  mycroft 		RESET_SEQUENCER(ahc);					\
    513  1.1  mycroft 		UNPAUSE_SEQUENCER(ahc);					\
    514  1.1  mycroft 	} while (0)
    515  1.1  mycroft 
    516  1.1  mycroft #ifdef  AHC_DEBUG
    517  1.1  mycroft void
    518  1.1  mycroft ahc_print_scb(scb)
    519  1.1  mycroft 	struct ahc_scb *scb;
    520  1.1  mycroft {
    521  1.1  mycroft 
    522  1.1  mycroft 	printf("scb:0x%x control:0x%x tcl:0x%x cmdlen:%d cmdpointer:0x%x\n",
    523  1.1  mycroft 	    scb,
    524  1.1  mycroft 	    scb->control,
    525  1.1  mycroft 	    scb->target_channel_lun,
    526  1.1  mycroft 	    scb->cmdlen,
    527  1.1  mycroft 	    scb->cmdpointer);
    528  1.1  mycroft 	printf("\tdatlen:%d data:0x%x res:0x%x segs:0x%x segp:0x%x\n",
    529  1.1  mycroft 	    scb->datalen[2] << 16 | scb->datalen[1] << 8 | scb->datalen[0],
    530  1.1  mycroft 	    scb->data,
    531  1.1  mycroft 	    scb->RESERVED[1] << 8 | scb->RESERVED[0],
    532  1.1  mycroft 	    scb->SG_segment_count,
    533  1.1  mycroft 	    scb->SG_list_pointer);
    534  1.1  mycroft 	printf("\tsg_addr:%x sg_len:%d\n",
    535  1.2  thorpej 	    scb->ahc_dma[0].seg_addr,
    536  1.2  thorpej 	    scb->ahc_dma[0].seg_len);
    537  1.1  mycroft 	printf("	size:%d\n",
    538  1.2  thorpej 	    (int)&scb->next_waiting - (int)scb);
    539  1.1  mycroft }
    540  1.1  mycroft 
    541  1.1  mycroft void
    542  1.1  mycroft ahc_print_active_scb(ahc)
    543  1.1  mycroft 	struct ahc_softc *ahc;
    544  1.1  mycroft {
    545  1.1  mycroft 	int iobase = ahc->sc_iobase;
    546  1.1  mycroft 	int scb_index;
    547  1.1  mycroft 
    548  1.1  mycroft 	PAUSE_SEQUENCER(ahc);
    549  1.1  mycroft 	scb_index = inb(SCBPTR + iobase);
    550  1.1  mycroft 	UNPAUSE_SEQUENCER(ahc);
    551  1.1  mycroft 
    552  1.1  mycroft 	ahc_print_scb(ahc->scbarray[scb_index]);
    553  1.1  mycroft }
    554  1.1  mycroft #endif
    555  1.1  mycroft 
    556  1.1  mycroft #define         PARERR          0x08
    557  1.1  mycroft #define         ILLOPCODE       0x04
    558  1.1  mycroft #define         ILLSADDR        0x02
    559  1.1  mycroft #define         ILLHADDR        0x01
    560  1.1  mycroft 
    561  1.1  mycroft static struct {
    562  1.1  mycroft 	u_char errno;
    563  1.1  mycroft 	char *errmesg;
    564  1.1  mycroft } hard_error[] = {
    565  1.1  mycroft 	{ ILLHADDR,  "Illegal Host Access" },
    566  1.1  mycroft 	{ ILLSADDR,  "Illegal Sequencer Address referrenced" },
    567  1.1  mycroft 	{ ILLOPCODE, "Illegal Opcode in sequencer program" },
    568  1.1  mycroft 	{ PARERR,    "Sequencer Ram Parity Error" }
    569  1.1  mycroft };
    570  1.1  mycroft 
    571  1.1  mycroft 
    572  1.1  mycroft /*
    573  1.1  mycroft  * Valid SCSIRATE values.  (p. 3-17)
    574  1.1  mycroft  * Provides a mapping of tranfer periods in ns to the proper value to
    575  1.1  mycroft  * stick in the scsiscfr reg to use that transfer rate.
    576  1.1  mycroft  */
    577  1.1  mycroft static struct {
    578  1.1  mycroft 	u_char sxfr;
    579  1.1  mycroft 	int period; /* in ns */
    580  1.1  mycroft 	char *rate;
    581  1.1  mycroft } ahc_syncrates[] = {
    582  1.1  mycroft 	{ 0x00, 100, "10.0"  },
    583  1.1  mycroft 	{ 0x10, 125,  "8.0"  },
    584  1.1  mycroft 	{ 0x20, 150,  "6.67" },
    585  1.1  mycroft 	{ 0x30, 175,  "5.7"  },
    586  1.1  mycroft 	{ 0x40, 200,  "5.0"  },
    587  1.1  mycroft 	{ 0x50, 225,  "4.4"  },
    588  1.1  mycroft 	{ 0x60, 250,  "4.0"  },
    589  1.1  mycroft 	{ 0x70, 275,  "3.6"  }
    590  1.1  mycroft };
    591  1.1  mycroft 
    592  1.1  mycroft static int ahc_num_syncrates =
    593  1.1  mycroft 	sizeof(ahc_syncrates) / sizeof(ahc_syncrates[0]);
    594  1.1  mycroft 
    595  1.1  mycroft /*
    596  1.1  mycroft  * Check if the device can be found at the port given
    597  1.1  mycroft  * and if so, determine configuration and set it up for further work.
    598  1.1  mycroft  */
    599  1.1  mycroft 
    600  1.1  mycroft int
    601  1.1  mycroft ahcprobe(ahc, iobase)
    602  1.1  mycroft 	struct ahc_softc *ahc;
    603  1.1  mycroft 	int iobase;
    604  1.1  mycroft {
    605  1.1  mycroft 
    606  1.1  mycroft 	ahc->sc_iobase = iobase;
    607  1.1  mycroft 
    608  1.1  mycroft 	/*
    609  1.1  mycroft 	 * Try to initialize a unit at this location
    610  1.1  mycroft 	 * reset the AIC-7770, read its registers,
    611  1.1  mycroft 	 * and fill in the dev structure accordingly
    612  1.1  mycroft 	 */
    613  1.1  mycroft 
    614  1.1  mycroft 	if (ahc_init(ahc) != 0)
    615  1.1  mycroft 		return (0);
    616  1.1  mycroft 
    617  1.1  mycroft 	return (1);
    618  1.1  mycroft }
    619  1.1  mycroft 
    620  1.1  mycroft 
    621  1.1  mycroft /*
    622  1.1  mycroft  * Look up the valid period to SCSIRATE conversion in our table.
    623  1.1  mycroft  */
    624  1.1  mycroft static u_char
    625  1.1  mycroft ahc_scsirate(offset, period, ahc, target)
    626  1.1  mycroft 	u_char offset;
    627  1.1  mycroft 	int period;
    628  1.1  mycroft 	struct ahc_softc *ahc;
    629  1.1  mycroft 	int target;
    630  1.1  mycroft {
    631  1.1  mycroft 	u_char scsirate;
    632  1.1  mycroft 	int i;
    633  1.1  mycroft 
    634  1.1  mycroft 	for (i = 0; i < ahc_num_syncrates; i++) {
    635  1.1  mycroft 		if ((ahc_syncrates[i].period - period) >= 0) {
    636  1.1  mycroft 			printf("%s: target %d synchronous at %sMB/s, "
    637  1.1  mycroft 			       "offset = %d\n",
    638  1.1  mycroft 			    ahc->sc_dev.dv_xname, target,
    639  1.1  mycroft 			    ahc_syncrates[i].rate, offset);
    640  1.1  mycroft #ifdef AHC_DEBUG
    641  1.1  mycroft #endif /* AHC_DEBUG */
    642  1.1  mycroft 			return ((ahc_syncrates[i].sxfr) | (offset & 0x0f));
    643  1.1  mycroft 		}
    644  1.1  mycroft 	}
    645  1.1  mycroft 
    646  1.1  mycroft 	/* Default to asyncronous transfers.  Also reject this SDTR request. */
    647  1.1  mycroft 	printf("%s: target %d using asyncronous transfers\n",
    648  1.1  mycroft 	    ahc->sc_dev.dv_xname, target);
    649  1.1  mycroft 	return (0);
    650  1.1  mycroft #ifdef AHC_DEBUG
    651  1.1  mycroft #endif /* AHC_DEBUG */
    652  1.1  mycroft }
    653  1.1  mycroft 
    654  1.4  mycroft int
    655  1.4  mycroft ahcprint(aux, name)
    656  1.4  mycroft 	void *aux;
    657  1.4  mycroft 	char *name;
    658  1.1  mycroft {
    659  1.1  mycroft 
    660  1.4  mycroft 	if (name != NULL)
    661  1.4  mycroft 		printf("%s: scsibus ", name);
    662  1.4  mycroft 	return UNCONF;
    663  1.1  mycroft }
    664  1.1  mycroft 
    665  1.1  mycroft /*
    666  1.1  mycroft  * Attach all the sub-devices we can find
    667  1.1  mycroft  */
    668  1.1  mycroft int
    669  1.1  mycroft ahcattach(ahc)
    670  1.1  mycroft 	struct ahc_softc *ahc;
    671  1.1  mycroft {
    672  1.1  mycroft 
    673  1.1  mycroft 	TAILQ_INIT(&ahc->free_scb);
    674  1.1  mycroft 
    675  1.1  mycroft 	/*
    676  1.1  mycroft 	 * fill in the prototype scsi_link.
    677  1.1  mycroft 	 */
    678  1.1  mycroft 	ahc->sc_link.adapter_softc = ahc;
    679  1.1  mycroft 	ahc->sc_link.adapter_target = ahc->ahc_scsi_dev;
    680  1.1  mycroft 	ahc->sc_link.adapter = &ahc_switch;
    681  1.1  mycroft 	ahc->sc_link.device = &ahc_dev;
    682  1.1  mycroft 	ahc->sc_link.openings = 1;
    683  1.1  mycroft 	ahc->sc_link.flags = DEBUGLEVEL;
    684  1.1  mycroft 	ahc->sc_link.quirks = 0;
    685  1.1  mycroft 
    686  1.1  mycroft 	/*
    687  1.1  mycroft 	 * ask the adapter what subunits are present
    688  1.1  mycroft 	 */
    689  1.1  mycroft 	printf("%s: Probing channel A\n", ahc->sc_dev.dv_xname);
    690  1.1  mycroft 	config_found((void *)ahc, &ahc->sc_link, ahcprint);
    691  1.1  mycroft 	if (ahc->type & AHC_TWIN) {
    692  1.1  mycroft 		/* Configure the second scsi bus */
    693  1.1  mycroft 		ahc->sc_link_b = ahc->sc_link;
    694  1.1  mycroft 		/* XXXX Didn't do this before. */
    695  1.1  mycroft 		ahc->sc_link_b.adapter_target = ahc->ahc_scsi_dev_b;
    696  1.1  mycroft 		ahc->sc_link_b.quirks = 0x0008;	/**/
    697  1.1  mycroft 		printf("%s: Probing channel B\n", ahc->sc_dev.dv_xname);
    698  1.1  mycroft 		config_found((void *)ahc, &ahc->sc_link_b, ahcprint);
    699  1.1  mycroft 	}
    700  1.1  mycroft 
    701  1.1  mycroft 	return 1;
    702  1.1  mycroft }
    703  1.1  mycroft 
    704  1.1  mycroft void
    705  1.1  mycroft ahc_send_scb(ahc, scb)
    706  1.1  mycroft 	struct ahc_softc *ahc;
    707  1.1  mycroft 	struct ahc_scb *scb;
    708  1.1  mycroft {
    709  1.1  mycroft 	int iobase = ahc->sc_iobase;
    710  1.1  mycroft 
    711  1.1  mycroft 	PAUSE_SEQUENCER(ahc);
    712  1.1  mycroft 	outb(QINFIFO + iobase, scb->position);
    713  1.1  mycroft 	UNPAUSE_SEQUENCER(ahc);
    714  1.1  mycroft }
    715  1.1  mycroft 
    716  1.1  mycroft static void
    717  1.1  mycroft ahc_getscb(iobase, scb)
    718  1.1  mycroft 	int iobase;
    719  1.1  mycroft 	struct ahc_scb *scb;
    720  1.1  mycroft {
    721  1.1  mycroft 
    722  1.1  mycroft 	outb(SCBCNT + iobase, SCBAUTO);
    723  1.1  mycroft 	insb(SCBARRAY + iobase, scb, SCB_UP_SIZE);
    724  1.1  mycroft 	outb(SCBCNT + iobase, 0);
    725  1.1  mycroft }
    726  1.1  mycroft 
    727  1.1  mycroft /*
    728  1.1  mycroft  * Catch an interrupt from the adaptor
    729  1.1  mycroft  */
    730  1.1  mycroft int
    731  1.1  mycroft ahcintr(ahc)
    732  1.1  mycroft 	struct ahc_softc *ahc;
    733  1.1  mycroft {
    734  1.1  mycroft 	int iobase = ahc->sc_iobase;
    735  1.1  mycroft 	u_char intstat = inb(INTSTAT + iobase);
    736  1.1  mycroft 	u_char status;
    737  1.1  mycroft 	struct ahc_scb *scb = NULL;
    738  1.1  mycroft 	struct scsi_xfer *xs = NULL;
    739  1.1  mycroft 
    740  1.1  mycroft 	/*
    741  1.1  mycroft 	 * Is this interrupt for me? or for
    742  1.1  mycroft 	 * someone who is sharing my interrupt
    743  1.1  mycroft 	 */
    744  1.1  mycroft 	if ((intstat & INT_PEND) == 0)
    745  1.1  mycroft 		return 0;
    746  1.1  mycroft 
    747  1.1  mycroft 	if (intstat & BRKADRINT) {
    748  1.1  mycroft 		/* We upset the sequencer :-( */
    749  1.1  mycroft 
    750  1.1  mycroft 		/* Lookup the error message */
    751  1.1  mycroft 		int i, error = inb(ERROR + iobase);
    752  1.1  mycroft 		int num_errors =  sizeof(hard_error)/sizeof(hard_error[0]);
    753  1.1  mycroft 		for (i = 0; error != 1 && i < num_errors; i++)
    754  1.1  mycroft 			error >>= 1;
    755  1.1  mycroft 		panic("%s: brkadrint, %s at seqaddr = 0x%x\n",
    756  1.1  mycroft 		    ahc->sc_dev.dv_xname, hard_error[i].errmesg,
    757  1.1  mycroft 		    (inb(SEQADDR1 + iobase) << 8) |
    758  1.1  mycroft 		    (inb(SEQADDR0 + iobase) << 0));
    759  1.1  mycroft 	}
    760  1.1  mycroft 
    761  1.1  mycroft 	if (intstat & SEQINT) {
    762  1.1  mycroft 		switch (intstat & SEQINT_MASK) {
    763  1.1  mycroft 		case BAD_PHASE:
    764  1.1  mycroft 			panic("%s: unknown scsi bus phase.  "
    765  1.1  mycroft 			      "Attempting to continue\n",
    766  1.1  mycroft 			    ahc->sc_dev.dv_xname);
    767  1.1  mycroft 			break;
    768  1.1  mycroft 		case SEND_REJECT:
    769  1.1  mycroft 			printf("%s: Warning - "
    770  1.1  mycroft 			       "message reject, message type: 0x%x\n",
    771  1.1  mycroft 			    ahc->sc_dev.dv_xname,
    772  1.1  mycroft 			    inb(HA_REJBYTE + iobase));
    773  1.1  mycroft 			break;
    774  1.1  mycroft 		case NO_IDENT:
    775  1.1  mycroft 			panic("%s: No IDENTIFY message from reconnecting "
    776  1.1  mycroft 			      "target %d at seqaddr = 0x%lx "
    777  1.1  mycroft 			      "SAVED_TCL == 0x%x\n",
    778  1.1  mycroft 			    ahc->sc_dev.dv_xname,
    779  1.1  mycroft 			    (inb(SELID + iobase) >> 4) & 0xf,
    780  1.1  mycroft 			    (inb(SEQADDR1 + iobase) << 8) |
    781  1.1  mycroft 			    (inb(SEQADDR0 + iobase) << 0),
    782  1.1  mycroft 			    inb(SAVED_TCL + iobase));
    783  1.1  mycroft 			break;
    784  1.1  mycroft 		case NO_MATCH: {
    785  1.1  mycroft 			u_char active;
    786  1.1  mycroft 			int active_port = HA_ACTIVE0 + iobase;
    787  1.1  mycroft 			int tcl = inb(SCBARRAY+1 + iobase);
    788  1.1  mycroft 			int target = (tcl >> 4) & 0x0f;
    789  1.1  mycroft 			printf("%s: no active SCB for reconnecting "
    790  1.1  mycroft 			       "target %d, channel %c - issuing ABORT\n",
    791  1.1  mycroft 			    ahc->sc_dev.dv_xname,
    792  1.1  mycroft 			    target, tcl & 0x08 ? 'B' : 'A');
    793  1.1  mycroft 			printf("SAVED_TCL == 0x%x\n", inb(SAVED_TCL + iobase));
    794  1.1  mycroft 			if (tcl & 0x88) {
    795  1.1  mycroft 				/* Second channel stores its info
    796  1.1  mycroft 				 * in byte two of HA_ACTIVE
    797  1.1  mycroft 				 */
    798  1.1  mycroft 				active_port++;
    799  1.1  mycroft 			}
    800  1.1  mycroft 			active = inb(active_port);
    801  1.1  mycroft 			active &= ~(0x01 << (target & 0x07));
    802  1.1  mycroft 			outb(SCBARRAY + iobase, SCB_NEEDDMA);
    803  1.1  mycroft 			outb(active_port, active);
    804  1.1  mycroft 			outb(CLRSINT1 + iobase, CLRSELTIMEO);
    805  1.1  mycroft 			RESTART_SEQUENCER(ahc);
    806  1.1  mycroft 			break;
    807  1.1  mycroft 		}
    808  1.1  mycroft 		case MSG_SDTR: {
    809  1.1  mycroft 			u_char scsi_id =
    810  1.1  mycroft 			    (inb(SCSIID + iobase) >> 0x4) |
    811  1.1  mycroft 			    (inb(SBLKCTL + iobase) & 0x08);
    812  1.1  mycroft 			u_char scratch, offset;
    813  1.1  mycroft 			int period;
    814  1.1  mycroft 
    815  1.1  mycroft 			/*
    816  1.1  mycroft 			 * Help the sequencer to translate the
    817  1.1  mycroft 			 * negotiated transfer rate.  Transfer is
    818  1.1  mycroft 			 * 1/4 the period in ns as is returned by
    819  1.1  mycroft 			 * the sync negotiation message.  So, we must
    820  1.1  mycroft 			 * multiply by four
    821  1.1  mycroft 			 */
    822  1.1  mycroft 			period = inb(HA_ARG_1 + iobase) << 2;
    823  1.1  mycroft 			/* The bottom half of SCSIXFER */
    824  1.1  mycroft 			offset = inb(ACCUM + iobase);
    825  1.1  mycroft 
    826  1.1  mycroft 			printf("%s: SDTR, target %d period %d offset %d\n",
    827  1.1  mycroft 			    ahc->sc_dev.dv_xname, scsi_id, period, offset);
    828  1.1  mycroft 			scratch = inb(HA_TARG_SCRATCH + iobase + scsi_id);
    829  1.1  mycroft 			scratch &= 0x80;
    830  1.1  mycroft 			scratch |= ahc_scsirate(offset, period, ahc, scsi_id);
    831  1.1  mycroft 
    832  1.1  mycroft 			if ((scratch & 0x7f) == 0) {
    833  1.1  mycroft 				/*
    834  1.1  mycroft 				 * The requested rate was so low
    835  1.1  mycroft 				 * that asyncronous transfers are
    836  1.1  mycroft 				 * faster (not to mention the
    837  1.1  mycroft 				 * controller won't support them),
    838  1.1  mycroft 				 * so we issue a message reject to
    839  1.1  mycroft 				 * ensure we go to asyncronous
    840  1.1  mycroft 				 * transfers.
    841  1.1  mycroft 				 */
    842  1.1  mycroft 				outb(HA_RETURN_1 + iobase, SEND_REJ);
    843  1.1  mycroft 			} else if (ahc->sdtrpending & (0x01 << scsi_id)) {
    844  1.1  mycroft 				/*
    845  1.1  mycroft 				 * Don't send an SDTR back to the
    846  1.1  mycroft 				 * target, since we asked first.
    847  1.1  mycroft 				 */
    848  1.1  mycroft 				outb(HA_RETURN_1 + iobase, 0);
    849  1.1  mycroft 			} else {
    850  1.1  mycroft 				/*
    851  1.1  mycroft 				 * Send our own SDTR in reply
    852  1.1  mycroft 				 */
    853  1.1  mycroft #ifdef AHC_DEBUG
    854  1.1  mycroft 				if (ahc_debug & AHC_SHOWMISC)
    855  1.1  mycroft 				    printf("Sending SDTR!!\n");
    856  1.1  mycroft #endif
    857  1.1  mycroft 				outb(HA_RETURN_1 + iobase, SEND_SDTR);
    858  1.1  mycroft 			}
    859  1.1  mycroft 			/*
    860  1.1  mycroft 			 * Negate the flags
    861  1.1  mycroft 			 */
    862  1.1  mycroft 			ahc->needsdtr &= ~(0x01 << scsi_id);
    863  1.1  mycroft 			ahc->sdtrpending &= ~(0x01 << scsi_id);
    864  1.1  mycroft 
    865  1.1  mycroft 			outb(HA_TARG_SCRATCH + iobase + scsi_id, scratch);
    866  1.1  mycroft 			outb(SCSIRATE + iobase, scratch);
    867  1.1  mycroft 			break;
    868  1.1  mycroft 		}
    869  1.1  mycroft 		case MSG_WDTR: {
    870  1.1  mycroft 			u_char scsi_id =
    871  1.1  mycroft 			    (inb(SCSIID + iobase) >> 0x4) |
    872  1.1  mycroft 			    (inb(SBLKCTL + iobase) & 0x08);
    873  1.1  mycroft 			u_char scratch, width;
    874  1.1  mycroft 
    875  1.1  mycroft 			width = inb(ACCUM + iobase);
    876  1.1  mycroft 
    877  1.1  mycroft 			scratch = inb(HA_TARG_SCRATCH + iobase + scsi_id);
    878  1.1  mycroft 
    879  1.1  mycroft 			if (ahc->wdtrpending & (0x01 << scsi_id)) {
    880  1.1  mycroft 				/*
    881  1.1  mycroft 				 * Don't send a WDTR back to the
    882  1.1  mycroft 				 * target, since we asked first.
    883  1.1  mycroft 				 */
    884  1.1  mycroft 				outb(HA_RETURN_1 + iobase, 0);
    885  1.1  mycroft 				switch (width) {
    886  1.1  mycroft 				case BUS_8_BIT:
    887  1.1  mycroft 					scratch &= 0x7f;
    888  1.1  mycroft 					break;
    889  1.1  mycroft 				case BUS_16_BIT:
    890  1.1  mycroft 					printf("%s: target %d using 16Bit "
    891  1.1  mycroft 					       "transfers\n",
    892  1.1  mycroft 					    ahc->sc_dev.dv_xname, scsi_id);
    893  1.1  mycroft 					scratch &= 0xf8;
    894  1.1  mycroft 					scratch |= 0x88;
    895  1.1  mycroft 					break;
    896  1.1  mycroft 				case BUS_32_BIT:
    897  1.1  mycroft 					/* XXXX */
    898  1.1  mycroft 				}
    899  1.1  mycroft 			} else {
    900  1.1  mycroft 				/*
    901  1.1  mycroft 				 * Send our own WDTR in reply
    902  1.1  mycroft 				 */
    903  1.1  mycroft 				switch (width) {
    904  1.1  mycroft 				case BUS_8_BIT:
    905  1.1  mycroft 					scratch &= 0x7f;
    906  1.1  mycroft 					break;
    907  1.1  mycroft 				case BUS_32_BIT:
    908  1.1  mycroft 					/* Negotiate 16_BITS */
    909  1.1  mycroft 					width = BUS_16_BIT;
    910  1.1  mycroft 				case BUS_16_BIT:
    911  1.1  mycroft 					printf("%s: target %d using 16Bit "
    912  1.1  mycroft 					       "transfers\n",
    913  1.1  mycroft 					    ahc->sc_dev.dv_xname, scsi_id);
    914  1.1  mycroft 					scratch &= 0xf8;
    915  1.1  mycroft 					scratch |= 0x88;
    916  1.1  mycroft 					break;
    917  1.1  mycroft 				}
    918  1.1  mycroft 				outb(HA_RETURN_1 + iobase,
    919  1.1  mycroft 				     width | SEND_WDTR);
    920  1.1  mycroft 			}
    921  1.1  mycroft 			ahc->needwdtr &= ~(0x01 << scsi_id);
    922  1.1  mycroft 			ahc->wdtrpending &= ~(0x01 << scsi_id);
    923  1.1  mycroft 
    924  1.1  mycroft 			outb(HA_TARG_SCRATCH + iobase + scsi_id, scratch);
    925  1.1  mycroft 			outb(SCSIRATE + iobase, scratch);
    926  1.1  mycroft 			break;
    927  1.1  mycroft 		}
    928  1.1  mycroft 		case MSG_REJECT: {
    929  1.1  mycroft 			/*
    930  1.1  mycroft 			 * What we care about here is if we had an
    931  1.1  mycroft 			 * outstanding SDTR or WDTR message for this
    932  1.1  mycroft 			 * target.  If we did, this is a signal that
    933  1.1  mycroft 			 * the target is refusing negotiation.
    934  1.1  mycroft 			 */
    935  1.1  mycroft 
    936  1.1  mycroft 			u_char scsi_id =
    937  1.1  mycroft 			    (inb(SCSIID + iobase) >> 0x4) |
    938  1.1  mycroft 			    (inb(SBLKCTL + iobase) & 0x08);
    939  1.1  mycroft 			u_char scratch;
    940  1.1  mycroft 			u_short mask;
    941  1.1  mycroft 
    942  1.1  mycroft 			scratch = inb(HA_TARG_SCRATCH + iobase + scsi_id);
    943  1.1  mycroft 
    944  1.1  mycroft 			mask = (0x01 << scsi_id);
    945  1.1  mycroft 			if (ahc->wdtrpending & mask) {
    946  1.1  mycroft 				/* note 8bit xfers and clear flag */
    947  1.1  mycroft 				scratch &= 0x7f;
    948  1.1  mycroft 				ahc->needwdtr &= ~mask;
    949  1.1  mycroft 				ahc->wdtrpending &= ~mask;
    950  1.1  mycroft 				printf("%s: target %d refusing "
    951  1.1  mycroft 				       "WIDE negotiation.  Using "
    952  1.1  mycroft 				       "8bit transfers\n",
    953  1.1  mycroft 				    ahc->sc_dev.dv_xname, scsi_id);
    954  1.1  mycroft 			} else if (ahc->sdtrpending & mask) {
    955  1.1  mycroft 				/* note asynch xfers and clear flag */
    956  1.1  mycroft 				scratch &= 0xf0;
    957  1.1  mycroft 				ahc->needsdtr &= ~mask;
    958  1.1  mycroft 				ahc->sdtrpending &= ~mask;
    959  1.1  mycroft 				printf("%s: target %d refusing "
    960  1.1  mycroft 				       "syncronous negotiation; using "
    961  1.1  mycroft 				       "asyncronous transfers\n",
    962  1.1  mycroft 				    ahc->sc_dev.dv_xname, scsi_id);
    963  1.1  mycroft 			} else {
    964  1.1  mycroft 				/*
    965  1.1  mycroft 				 * Otherwise, we ignore it.
    966  1.1  mycroft 				 */
    967  1.1  mycroft #ifdef AHC_DEBUG
    968  1.1  mycroft 				if (ahc_debug & AHC_SHOWMISC)
    969  1.1  mycroft 					printf("Message reject -- ignored\n");
    970  1.1  mycroft #endif
    971  1.1  mycroft 				break;
    972  1.1  mycroft 			}
    973  1.1  mycroft 
    974  1.1  mycroft 			outb(HA_TARG_SCRATCH + iobase + scsi_id, scratch);
    975  1.1  mycroft 			outb(SCSIRATE + iobase, scratch);
    976  1.1  mycroft 			break;
    977  1.1  mycroft 		}
    978  1.1  mycroft 		case BAD_STATUS: {
    979  1.1  mycroft 			int scb_index = inb(SCBPTR + iobase);
    980  1.1  mycroft 			scb = ahc->scbarray[scb_index];
    981  1.1  mycroft 
    982  1.1  mycroft 			/*
    983  1.1  mycroft 			 * The sequencer will notify us when a command
    984  1.1  mycroft 			 * has an error that would be of interest to
    985  1.1  mycroft 			 * the kernel.  This allows us to leave the sequencer
    986  1.1  mycroft 			 * running in the common case of command completes
    987  1.1  mycroft 			 * without error.
    988  1.1  mycroft 			 */
    989  1.1  mycroft 
    990  1.1  mycroft 			/*
    991  1.1  mycroft 			 * Set the default return value to 0 (don't
    992  1.1  mycroft 			 * send sense).  The sense code with change
    993  1.1  mycroft 			 * this if needed and this reduces code
    994  1.1  mycroft 			 * duplication.
    995  1.1  mycroft 			 */
    996  1.1  mycroft 			outb(HA_RETURN_1 + iobase, 0);
    997  1.1  mycroft 			if (!scb || scb->flags == SCB_FREE) {
    998  1.1  mycroft 				printf("%s: ahcintr: referenced scb not "
    999  1.1  mycroft 				       "valid during seqint 0x%x scb(%d)\n",
   1000  1.1  mycroft 				    ahc->sc_dev.dv_xname, intstat, scb_index);
   1001  1.1  mycroft 				goto clear;
   1002  1.1  mycroft 			}
   1003  1.1  mycroft 
   1004  1.1  mycroft 			xs = scb->xs;
   1005  1.1  mycroft 
   1006  1.1  mycroft 			ahc_getscb(iobase, scb);
   1007  1.1  mycroft 
   1008  1.2  thorpej #ifdef AHC_MORE_DEBUG
   1009  1.1  mycroft 			if (xs->sc_link->target == DEBUGTARGET)
   1010  1.1  mycroft 				ahc_print_scb(scb);
   1011  1.1  mycroft #endif
   1012  1.1  mycroft 			xs->status = scb->target_status;
   1013  1.1  mycroft 			switch (scb->target_status) {
   1014  1.1  mycroft 			case SCSI_OK:
   1015  1.1  mycroft 				printf("%s: Interrupted for status of 0???\n",
   1016  1.1  mycroft 				    ahc->sc_dev.dv_xname);
   1017  1.1  mycroft 				break;
   1018  1.1  mycroft 			case SCSI_CHECK:
   1019  1.1  mycroft #ifdef AHC_DEBUG
   1020  1.1  mycroft 				sc_print_addr(xs->sc_link);
   1021  1.1  mycroft 				printf("requests Check Status\n");
   1022  1.1  mycroft #endif
   1023  1.1  mycroft 
   1024  1.1  mycroft 				if (xs->error == XS_NOERROR &&
   1025  1.1  mycroft 				    scb->flags != SCB_CHKSENSE) {
   1026  1.1  mycroft 					u_char flags;
   1027  1.1  mycroft 					u_char head;
   1028  1.1  mycroft 					u_char tail;
   1029  1.1  mycroft 					struct ahc_dma_seg *sg = scb->ahc_dma;
   1030  1.1  mycroft 					struct scsi_sense *sc = &(scb->sense_cmd);
   1031  1.1  mycroft 					u_char control = scb->control;
   1032  1.1  mycroft 					u_char tcl = scb->target_channel_lun;
   1033  1.1  mycroft #ifdef AHC_DEBUG
   1034  1.1  mycroft 					sc_print_addr(xs->sc_link);
   1035  1.1  mycroft 					printf("Sending Sense\n");
   1036  1.1  mycroft #endif
   1037  1.1  mycroft 					bzero(scb, SCB_DOWN_SIZE);
   1038  1.1  mycroft 					scb->flags = SCB_CHKSENSE;
   1039  1.1  mycroft 					scb->control = (control & SCB_TE);
   1040  1.1  mycroft 					sc->opcode = REQUEST_SENSE;
   1041  1.1  mycroft 					sc->byte2 =  xs->sc_link->lun << 5;
   1042  1.1  mycroft 					sc->length = sizeof(struct scsi_sense_data);
   1043  1.1  mycroft 					sc->control = 0;
   1044  1.1  mycroft 
   1045  1.1  mycroft 					sg->seg_addr = vtophys(&xs->sense);
   1046  1.1  mycroft 					sg->seg_len = sizeof(struct scsi_sense_data);
   1047  1.1  mycroft 
   1048  1.1  mycroft 					scb->target_channel_lun = tcl;
   1049  1.1  mycroft 					scb->SG_segment_count = 1;
   1050  1.1  mycroft 					scb->SG_list_pointer = vtophys(sg);
   1051  1.1  mycroft 					scb->cmdpointer = vtophys(sc);
   1052  1.1  mycroft 					scb->cmdlen = sizeof(*sc);
   1053  1.1  mycroft 
   1054  1.1  mycroft 					outb(SCBCNT + iobase, SCBAUTO);
   1055  1.1  mycroft 					outsb(SCBARRAY + iobase, scb,
   1056  1.1  mycroft 					    SCB_DOWN_SIZE);
   1057  1.1  mycroft 					outb(SCBCNT + iobase, 0);
   1058  1.1  mycroft 					outb(SCBARRAY + iobase + 30,
   1059  1.1  mycroft 					    SCB_LIST_NULL);
   1060  1.1  mycroft 
   1061  1.1  mycroft 					/*
   1062  1.1  mycroft 					 * Add this SCB to the "waiting for
   1063  1.1  mycroft 					 * selection" list.
   1064  1.1  mycroft 					 */
   1065  1.1  mycroft 					head = inb(WAITING_SCBH + iobase);
   1066  1.1  mycroft 					tail = inb(WAITING_SCBT + iobase);
   1067  1.1  mycroft 					if (head & SCB_LIST_NULL) {
   1068  1.1  mycroft 						/* List was empty */
   1069  1.1  mycroft 						head = scb->position;
   1070  1.1  mycroft 						tail = SCB_LIST_NULL;
   1071  1.1  mycroft 					} else if (tail & SCB_LIST_NULL) {
   1072  1.1  mycroft 						/* List had one element */
   1073  1.1  mycroft 						tail = scb->position;
   1074  1.1  mycroft 						outb(SCBPTR + iobase, head);
   1075  1.1  mycroft 						outb(SCBARRAY + iobase + 30,
   1076  1.1  mycroft 						    tail);
   1077  1.1  mycroft 					} else {
   1078  1.1  mycroft 						outb(SCBPTR + iobase, tail);
   1079  1.1  mycroft 						tail = scb->position;
   1080  1.1  mycroft 						outb(SCBARRAY + iobase + 30,
   1081  1.1  mycroft 						    tail);
   1082  1.1  mycroft 					}
   1083  1.1  mycroft 					outb(WAITING_SCBH + iobase, head);
   1084  1.1  mycroft 					outb(WAITING_SCBT + iobase, tail);
   1085  1.1  mycroft 					outb(HA_RETURN_1 + iobase, SEND_SENSE);
   1086  1.1  mycroft 					break;
   1087  1.1  mycroft 				}
   1088  1.1  mycroft 				/*
   1089  1.1  mycroft 				 * Have the sequencer do a normal command
   1090  1.1  mycroft 				 * complete with either a "DRIVER_STUFFUP"
   1091  1.1  mycroft 				 * error or whatever other error condition
   1092  1.1  mycroft 				 * we already had.
   1093  1.1  mycroft 				 */
   1094  1.1  mycroft 				if (xs->error == XS_NOERROR)
   1095  1.1  mycroft 					xs->error = XS_DRIVER_STUFFUP;
   1096  1.1  mycroft 				break;
   1097  1.1  mycroft 			case SCSI_BUSY:
   1098  1.1  mycroft 				sc_print_addr(xs->sc_link);
   1099  1.1  mycroft 				printf("Target Busy\n");
   1100  1.1  mycroft 				xs->error = XS_BUSY;
   1101  1.1  mycroft 				break;
   1102  1.1  mycroft #if 0
   1103  1.1  mycroft 			case SCSI_QUEUE_FULL:
   1104  1.1  mycroft 				/*
   1105  1.1  mycroft 				 * The upper level SCSI code will eventually
   1106  1.1  mycroft 				 * handle this properly.
   1107  1.1  mycroft 				 */
   1108  1.1  mycroft 				sc_print_addr(xs->sc_link);
   1109  1.1  mycroft 				printf("Queue Full\n");
   1110  1.1  mycroft 				xs->error = XS_BUSY;
   1111  1.1  mycroft 				break;
   1112  1.1  mycroft #endif
   1113  1.1  mycroft 			default:
   1114  1.1  mycroft 				sc_print_addr(xs->sc_link);
   1115  1.1  mycroft 				printf("unexpected targ_status: %x\n",
   1116  1.1  mycroft 				    scb->target_status);
   1117  1.1  mycroft 				xs->error = XS_DRIVER_STUFFUP;
   1118  1.1  mycroft 				break;
   1119  1.1  mycroft 			}
   1120  1.1  mycroft 			break;
   1121  1.1  mycroft 		}
   1122  1.1  mycroft 		case RESIDUAL: {
   1123  1.1  mycroft 			int scb_index = inb(SCBPTR + iobase);
   1124  1.1  mycroft 			scb = ahc->scbarray[scb_index];
   1125  1.1  mycroft 
   1126  1.1  mycroft 			/*
   1127  1.1  mycroft 			 * Don't clobber valid resid info with
   1128  1.1  mycroft 			 * a resid coming from a check sense
   1129  1.1  mycroft 			 * operation.
   1130  1.1  mycroft 			 */
   1131  1.1  mycroft 			if (scb->flags != SCB_CHKSENSE)
   1132  1.1  mycroft 				scb->xs->resid =
   1133  1.1  mycroft 				    (inb(iobase + SCBARRAY + 17) << 16) |
   1134  1.1  mycroft 				    (inb(iobase + SCBARRAY + 16) <<  8) |
   1135  1.1  mycroft 				    (inb(iobase + SCBARRAY + 15) <<  0);
   1136  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1137  1.1  mycroft 			printf("ahc: Handled Residual\n");
   1138  1.1  mycroft #endif
   1139  1.1  mycroft 			break;
   1140  1.1  mycroft 		}
   1141  1.1  mycroft 		case ABORT_TAG: {
   1142  1.1  mycroft 			int scb_index = inb(SCBPTR + iobase);
   1143  1.1  mycroft 			scb = ahc->scbarray[scb_index];
   1144  1.1  mycroft 
   1145  1.1  mycroft 			/*
   1146  1.1  mycroft 			 * We didn't recieve a valid tag back from
   1147  1.1  mycroft 			 * the target on a reconnect.
   1148  1.1  mycroft 			 */
   1149  1.1  mycroft 			sc_print_addr(xs->sc_link);
   1150  1.1  mycroft 			printf("invalid tag recieved on channel %c "
   1151  1.1  mycroft 			       "-- sending ABORT_TAG\n",
   1152  1.1  mycroft 			    (xs->sc_link->quirks & 0x08) ? 'B' : 'A');
   1153  1.1  mycroft 			scb->xs->error = XS_DRIVER_STUFFUP;
   1154  1.1  mycroft 			untimeout(ahc_timeout, scb);
   1155  1.1  mycroft 			ahc_done(ahc, scb);
   1156  1.1  mycroft 			break;
   1157  1.1  mycroft 		}
   1158  1.1  mycroft 		default:
   1159  1.1  mycroft 			printf("%s: seqint, intstat == 0x%x, scsisigi = 0x%x\n",
   1160  1.1  mycroft 			    ahc->sc_dev.dv_xname,
   1161  1.1  mycroft 			    intstat, inb(SCSISIGI + iobase));
   1162  1.1  mycroft 			break;
   1163  1.1  mycroft 		}
   1164  1.1  mycroft 
   1165  1.1  mycroft 	clear:
   1166  1.1  mycroft 		/*
   1167  1.1  mycroft 		 * Clear the upper byte that holds SEQINT status
   1168  1.1  mycroft 		 * codes and clear the SEQINT bit.
   1169  1.1  mycroft 		 */
   1170  1.1  mycroft 		outb(CLRINT + iobase, CLRSEQINT);
   1171  1.1  mycroft 
   1172  1.1  mycroft 		/*
   1173  1.1  mycroft 		 *  The sequencer is paused immediately on
   1174  1.1  mycroft 		 *  a SEQINT, so we should restart it when
   1175  1.1  mycroft 		 *  we leave this section.
   1176  1.1  mycroft 		 */
   1177  1.1  mycroft 		UNPAUSE_SEQUENCER(ahc);
   1178  1.1  mycroft 	}
   1179  1.1  mycroft 
   1180  1.1  mycroft 	if (intstat & SCSIINT) {
   1181  1.1  mycroft 		int scb_index = inb(SCBPTR + iobase);
   1182  1.1  mycroft 		scb = ahc->scbarray[scb_index];
   1183  1.1  mycroft 
   1184  1.1  mycroft 		status = inb(SSTAT1 + iobase);
   1185  1.1  mycroft 
   1186  1.1  mycroft 		if (!scb || scb->flags == SCB_FREE) {
   1187  1.1  mycroft 			printf("%s: ahcintr - referenced scb not "
   1188  1.1  mycroft 			       "valid during scsiint 0x%x scb(%d)\n",
   1189  1.1  mycroft 			    ahc->sc_dev.dv_xname, status, scb_index);
   1190  1.1  mycroft 			outb(CLRSINT1 + iobase, status);
   1191  1.1  mycroft 			UNPAUSE_SEQUENCER(ahc);
   1192  1.1  mycroft 			outb(CLRINT + iobase, CLRSCSIINT);
   1193  1.1  mycroft 			scb = NULL;
   1194  1.1  mycroft 			goto cmdcomplete;
   1195  1.1  mycroft 		}
   1196  1.1  mycroft 		xs = scb->xs;
   1197  1.1  mycroft 
   1198  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1199  1.1  mycroft 		if ((xs->sc_link->target & 0xf) == DEBUGTARGET)
   1200  1.1  mycroft 			printf("Intr status %x\n", status);
   1201  1.1  mycroft #endif
   1202  1.1  mycroft 
   1203  1.1  mycroft 		if (status & SELTO) {
   1204  1.1  mycroft 			u_char active;
   1205  1.1  mycroft 			u_char waiting;
   1206  1.1  mycroft 			u_char flags;
   1207  1.1  mycroft 			int active_port = HA_ACTIVE0 + iobase;
   1208  1.1  mycroft 
   1209  1.1  mycroft 			outb(SCSISEQ + iobase, ENRSELI);
   1210  1.1  mycroft 			xs->error = XS_SELTIMEOUT;
   1211  1.1  mycroft 			/*
   1212  1.1  mycroft 			 * Clear any pending messages for the timed out
   1213  1.1  mycroft 			 * target, and mark the target as free
   1214  1.1  mycroft 			 */
   1215  1.1  mycroft 			flags = inb(HA_FLAGS + iobase);
   1216  1.1  mycroft 			outb(HA_FLAGS + iobase, flags & ~ACTIVE_MSG);
   1217  1.1  mycroft 
   1218  1.1  mycroft 			if (scb->target_channel_lun & 0x88)
   1219  1.1  mycroft 			    active_port++;
   1220  1.1  mycroft 
   1221  1.1  mycroft 			active = inb(active_port) &
   1222  1.1  mycroft 			    ~(0x01 << (xs->sc_link->target & 0x07));
   1223  1.1  mycroft 			outb(active_port, active);
   1224  1.1  mycroft 
   1225  1.1  mycroft 			outb(SCBARRAY + iobase, SCB_NEEDDMA);
   1226  1.1  mycroft 
   1227  1.1  mycroft 			outb(CLRSINT1 + iobase, CLRSELTIMEO);
   1228  1.1  mycroft 
   1229  1.1  mycroft 			outb(CLRINT + iobase, CLRSCSIINT);
   1230  1.1  mycroft 
   1231  1.1  mycroft 			/* Shift the waiting for selection queue forward */
   1232  1.1  mycroft 			waiting = inb(WAITING_SCBH + iobase);
   1233  1.1  mycroft 			outb(SCBPTR + iobase, waiting);
   1234  1.1  mycroft 			waiting = inb(SCBARRAY + iobase + 30);
   1235  1.1  mycroft 			outb(WAITING_SCBH + iobase, waiting);
   1236  1.1  mycroft 
   1237  1.1  mycroft 			RESTART_SEQUENCER(ahc);
   1238  1.1  mycroft 		}
   1239  1.1  mycroft 
   1240  1.1  mycroft 		if (status & SCSIPERR) {
   1241  1.1  mycroft 			sc_print_addr(xs->sc_link);
   1242  1.1  mycroft 			printf("parity error on channel %c\n",
   1243  1.1  mycroft 			    (xs->sc_link->quirks & 0x08) ? 'B' : 'A');
   1244  1.1  mycroft 			xs->error = XS_DRIVER_STUFFUP;
   1245  1.1  mycroft 
   1246  1.1  mycroft 			outb(CLRSINT1 + iobase, CLRSCSIPERR);
   1247  1.1  mycroft 			UNPAUSE_SEQUENCER(ahc);
   1248  1.1  mycroft 
   1249  1.1  mycroft 			outb(CLRINT + iobase, CLRSCSIINT);
   1250  1.1  mycroft 			scb = NULL;
   1251  1.1  mycroft 		}
   1252  1.1  mycroft 		if (status & BUSFREE) {
   1253  1.1  mycroft #if 0
   1254  1.1  mycroft 			/*
   1255  1.1  mycroft 			 * Has seen busfree since selection, i.e.
   1256  1.1  mycroft 			 * a "spurious" selection. Shouldn't happen.
   1257  1.1  mycroft 			 */
   1258  1.1  mycroft 			printf("ahc: unexpected busfree\n");
   1259  1.1  mycroft #if 0
   1260  1.1  mycroft 			xs->error = XS_DRIVER_STUFFUP;
   1261  1.1  mycroft 			outb(CLRSINT1 + iobase, BUSFREE); /* CLRBUSFREE */
   1262  1.1  mycroft #endif
   1263  1.1  mycroft #endif
   1264  1.1  mycroft 		} else {
   1265  1.1  mycroft 			printf("%s: Unknown SCSIINT. Status = 0x%x\n",
   1266  1.1  mycroft 			    ahc->sc_dev.dv_xname, status);
   1267  1.1  mycroft 			outb(CLRSINT1 + iobase, status);
   1268  1.1  mycroft 			UNPAUSE_SEQUENCER(ahc);
   1269  1.1  mycroft 			outb(CLRINT + iobase, CLRSCSIINT);
   1270  1.1  mycroft 			scb = NULL;
   1271  1.1  mycroft 		}
   1272  1.1  mycroft 		if (scb != NULL) {
   1273  1.1  mycroft 			/* We want to process the command */
   1274  1.1  mycroft 			untimeout(ahc_timeout, scb);
   1275  1.1  mycroft 			ahc_done(ahc, scb);
   1276  1.1  mycroft 		}
   1277  1.1  mycroft 	}
   1278  1.1  mycroft 
   1279  1.1  mycroft cmdcomplete:
   1280  1.1  mycroft 	if (intstat & CMDCMPLT) {
   1281  1.1  mycroft 		int scb_index;
   1282  1.1  mycroft 
   1283  1.1  mycroft 		do {
   1284  1.1  mycroft 			scb_index = inb(QOUTFIFO + iobase);
   1285  1.1  mycroft 			scb = ahc->scbarray[scb_index];
   1286  1.1  mycroft 
   1287  1.1  mycroft 			if (!scb || scb->flags == SCB_FREE) {
   1288  1.1  mycroft 				printf("%s: WARNING "
   1289  1.1  mycroft 			               "no command for scb %d (cmdcmplt)\n"
   1290  1.1  mycroft 				       "QOUTCNT == %d\n",
   1291  1.1  mycroft 				    ahc->sc_dev.dv_xname,
   1292  1.1  mycroft 				    scb_index, inb(QOUTCNT + iobase));
   1293  1.1  mycroft 				outb(CLRINT + iobase, CLRCMDINT);
   1294  1.1  mycroft 				continue;
   1295  1.1  mycroft 			}
   1296  1.1  mycroft 
   1297  1.1  mycroft 			/* XXXX Should do this before reading FIFO? */
   1298  1.1  mycroft 			outb(CLRINT + iobase, CLRCMDINT);
   1299  1.1  mycroft 			untimeout(ahc_timeout, scb);
   1300  1.1  mycroft 			ahc_done(ahc, scb);
   1301  1.1  mycroft 		} while (inb(QOUTCNT + iobase));
   1302  1.1  mycroft 	}
   1303  1.1  mycroft 
   1304  1.1  mycroft 	return 1;
   1305  1.1  mycroft }
   1306  1.1  mycroft 
   1307  1.1  mycroft /*
   1308  1.1  mycroft  * We have a scb which has been processed by the
   1309  1.1  mycroft  * adaptor, now we look to see how the operation
   1310  1.1  mycroft  * went.
   1311  1.1  mycroft  */
   1312  1.1  mycroft void
   1313  1.1  mycroft ahc_done(ahc, scb)
   1314  1.1  mycroft 	struct ahc_softc *ahc;
   1315  1.1  mycroft 	struct ahc_scb *scb;
   1316  1.1  mycroft {
   1317  1.1  mycroft 	struct scsi_xfer *xs = scb->xs;
   1318  1.1  mycroft 
   1319  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1320  1.1  mycroft 	if ((xs->sc_link->target & 0xf) == DEBUGTARGET) {
   1321  1.1  mycroft 		xs->sc_link->flags |= 0xf0;
   1322  1.1  mycroft 		SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahc_done\n"));
   1323  1.1  mycroft 		printf("%x %x %x %x\n",
   1324  1.1  mycroft 		    scb->flags,
   1325  1.1  mycroft 		    scb->target_status,
   1326  1.1  mycroft 		    xs->flags,
   1327  1.1  mycroft 		    xs->error);
   1328  1.1  mycroft 	}
   1329  1.1  mycroft #endif
   1330  1.1  mycroft 
   1331  1.1  mycroft 	/*
   1332  1.1  mycroft 	 * Put the results of the operation
   1333  1.1  mycroft 	 * into the xfer and call whoever started it
   1334  1.1  mycroft 	 */
   1335  1.1  mycroft 	if (xs->error == XS_NOERROR) {
   1336  1.1  mycroft 		if (scb->flags == SCB_ABORTED)
   1337  1.1  mycroft 			xs->error = XS_DRIVER_STUFFUP;
   1338  1.1  mycroft 		else if (scb->flags == SCB_CHKSENSE)
   1339  1.1  mycroft 			xs->error = XS_SENSE;
   1340  1.1  mycroft 	}
   1341  1.1  mycroft 
   1342  1.1  mycroft 	xs->flags |= ITSDONE;
   1343  1.1  mycroft 
   1344  1.1  mycroft #ifdef AHC_TAGENABLE
   1345  1.1  mycroft 	if (xs->cmd->opcode == 0x12 && xs->error == XS_NOERROR) {
   1346  1.1  mycroft 		struct scsi_inquiry_data *inq_data;
   1347  1.1  mycroft 		u_short mask = 0x01 << (xs->sc_link->target |
   1348  1.1  mycroft 					(scb->target_channel_lun & 0x08));
   1349  1.1  mycroft 		/*
   1350  1.1  mycroft 		 * Sneak a look at the results of the SCSI Inquiry
   1351  1.1  mycroft 		 * command and see if we can do Tagged queing.  XXX This
   1352  1.1  mycroft 		 * should really be done by the higher level drivers.
   1353  1.1  mycroft 		 */
   1354  1.1  mycroft 		inq_data = (struct scsi_inquiry_data *)xs->data;
   1355  1.1  mycroft 		if (((inq_data->device & SID_TYPE) == 0)
   1356  1.1  mycroft 		    && (inq_data->flags & SID_CmdQue)
   1357  1.1  mycroft 		    && !(ahc->tagenable & mask)) {
   1358  1.1  mycroft 			/*
   1359  1.1  mycroft 			 * Disk type device and can tag
   1360  1.1  mycroft 			 */
   1361  1.1  mycroft 			sc_print_addr(xs->sc_link);
   1362  1.1  mycroft 			printf("Tagged Queuing Device\n");
   1363  1.1  mycroft 			ahc->tagenable |= mask;
   1364  1.1  mycroft #ifdef QUEUE_FULL_SUPPORTED
   1365  1.1  mycroft 			xs->sc_link->openings += 2; */
   1366  1.1  mycroft #endif
   1367  1.1  mycroft 		}
   1368  1.1  mycroft 	}
   1369  1.1  mycroft #endif
   1370  1.1  mycroft 
   1371  1.1  mycroft 	ahc_free_scb(ahc, scb, xs->flags);
   1372  1.1  mycroft 	scsi_done(xs);
   1373  1.1  mycroft }
   1374  1.1  mycroft 
   1375  1.1  mycroft /*
   1376  1.1  mycroft  * Start the board, ready for normal operation
   1377  1.1  mycroft  */
   1378  1.1  mycroft /* XXXX clean */
   1379  1.1  mycroft int
   1380  1.1  mycroft ahc_init(ahc)
   1381  1.1  mycroft 	struct ahc_softc *ahc;
   1382  1.1  mycroft {
   1383  1.1  mycroft 	int iobase = ahc->sc_iobase;
   1384  1.1  mycroft 	u_char scsi_conf, sblkctl, i;
   1385  1.1  mycroft 	int intdef, max_targ = 16, wait;
   1386  1.1  mycroft 
   1387  1.1  mycroft 	/*
   1388  1.1  mycroft 	 * Assume we have a board at this stage
   1389  1.1  mycroft 	 * Find out the configured interupt and the card type.
   1390  1.1  mycroft 	 */
   1391  1.1  mycroft 
   1392  1.1  mycroft #ifdef AHC_DEBUG
   1393  1.1  mycroft 	printf("%s: scb %d bytes; SCB_SIZE %d bytes, ahc_dma %d bytes\n",
   1394  1.1  mycroft 	    ahc->sc_dev.dv_xname, sizeof(struct ahc_scb), SCB_DOWN_SIZE,
   1395  1.1  mycroft 	    sizeof(struct ahc_dma_seg));
   1396  1.1  mycroft #endif /* AHC_DEBUG */
   1397  1.1  mycroft 	/*printf("%s: reading board settings\n", ahc->sc_dev.dv_xname);/**/
   1398  1.1  mycroft 
   1399  1.1  mycroft 	/* Save the IRQ type before we do a chip reset */
   1400  1.1  mycroft 
   1401  1.1  mycroft 	ahc->unpause = (inb(HCNTRL + iobase) & IRQMS) | INTEN;
   1402  1.1  mycroft 	ahc->pause = ahc->unpause | PAUSE;
   1403  1.1  mycroft 	outb(HCNTRL + iobase, CHIPRST | ahc->pause);
   1404  1.1  mycroft 
   1405  1.1  mycroft 	/*
   1406  1.1  mycroft 	 * Ensure that the reset has finished
   1407  1.1  mycroft 	 */
   1408  1.1  mycroft 	wait = 1000;
   1409  1.1  mycroft 	while (wait--) {
   1410  1.1  mycroft 		delay(1000);
   1411  1.1  mycroft 		if (!(inb(HCNTRL + iobase) & CHIPRST))
   1412  1.1  mycroft 		    break;
   1413  1.1  mycroft 	}
   1414  1.1  mycroft 	if (wait == 0) {
   1415  1.1  mycroft 		printf("\n%s: WARNING - Failed chip reset!  "
   1416  1.1  mycroft 		       "Trying to initialize anyway.\n", ahc->sc_dev.dv_xname);
   1417  1.1  mycroft 		/* Forcibly clear CHIPRST */
   1418  1.1  mycroft 		outb(HCNTRL + iobase, ahc->pause);
   1419  1.1  mycroft 	}
   1420  1.1  mycroft 
   1421  1.1  mycroft 	switch (ahc->type) {
   1422  1.1  mycroft 	case AHC_274:
   1423  1.2  thorpej 		printf("%s: 274x ", ahc->sc_dev.dv_xname);
   1424  1.1  mycroft 		ahc->maxscbs = 0x4;
   1425  1.1  mycroft 		break;
   1426  1.1  mycroft 	case AHC_284:
   1427  1.2  thorpej 		printf("%s: 284x ", ahc->sc_dev.dv_xname);
   1428  1.1  mycroft 		ahc->maxscbs = 0x4;
   1429  1.1  mycroft 		break;
   1430  1.1  mycroft 	case AHC_AIC7870:
   1431  1.1  mycroft 	case AHC_294:
   1432  1.1  mycroft 		if (ahc->type == AHC_AIC7870)
   1433  1.2  thorpej 			printf("%s: aic7870 ", ahc->sc_dev.dv_xname);
   1434  1.1  mycroft 		else
   1435  1.2  thorpej 			printf("%s: 294x ", ahc->sc_dev.dv_xname);
   1436  1.1  mycroft 		ahc->maxscbs = 0x10;
   1437  1.1  mycroft 		#define DFTHRESH        3
   1438  1.1  mycroft 		outb(DSPCISTATUS + iobase, DFTHRESH << 6);
   1439  1.1  mycroft 		/*
   1440  1.1  mycroft 		 * XXX Hard coded SCSI ID until we can read it from the
   1441  1.1  mycroft 		 * SEEPROM or NVRAM.
   1442  1.1  mycroft 		 */
   1443  1.1  mycroft 		outb(HA_SCSICONF + iobase, 0x07 | (DFTHRESH << 6));
   1444  1.1  mycroft 		/* In case we are a wide card */
   1445  1.1  mycroft 		outb(HA_SCSICONF + 1 + iobase, 0x07);
   1446  1.1  mycroft 		break;
   1447  1.2  thorpej 	default:
   1448  1.2  thorpej 	        printf("%s: unknown(0x%x) ", ahc->sc_dev.dv_xname, ahc->type);
   1449  1.2  thorpej 		break;
   1450  1.1  mycroft 	}
   1451  1.1  mycroft 
   1452  1.1  mycroft 	/* Determine channel configuration and who we are on the scsi bus. */
   1453  1.1  mycroft 	switch ((sblkctl = inb(SBLKCTL + iobase) & 0x0f)) {
   1454  1.1  mycroft 	case 0:
   1455  1.1  mycroft 		ahc->ahc_scsi_dev = (inb(HA_SCSICONF + iobase) & HSCSIID);
   1456  1.1  mycroft 		printf("Single Channel, SCSI Id=%d, ", ahc->ahc_scsi_dev);
   1457  1.1  mycroft 		outb(HA_FLAGS + iobase, SINGLE_BUS);
   1458  1.1  mycroft 		break;
   1459  1.1  mycroft 	case 2:
   1460  1.1  mycroft 		ahc->ahc_scsi_dev = (inb(HA_SCSICONF + 1 + iobase) & HWSCSIID);
   1461  1.1  mycroft 		printf("Wide Channel, SCSI Id=%d, ", ahc->ahc_scsi_dev);
   1462  1.1  mycroft 		ahc->type |= AHC_WIDE;
   1463  1.1  mycroft 		outb(HA_FLAGS + iobase, WIDE_BUS);
   1464  1.1  mycroft 		break;
   1465  1.1  mycroft 	case 8:
   1466  1.1  mycroft 		ahc->ahc_scsi_dev = (inb(HA_SCSICONF + iobase) & HSCSIID);
   1467  1.1  mycroft 		ahc->ahc_scsi_dev_b = (inb(HA_SCSICONF + 1 + iobase) & HSCSIID);
   1468  1.1  mycroft 		printf("Twin Channel, A SCSI Id=%d, B SCSI Id=%d, ",
   1469  1.1  mycroft 		    ahc->ahc_scsi_dev, ahc->ahc_scsi_dev_b);
   1470  1.1  mycroft 		ahc->type |= AHC_TWIN;
   1471  1.1  mycroft 		outb(HA_FLAGS + iobase, TWIN_BUS);
   1472  1.1  mycroft 		break;
   1473  1.1  mycroft 	default:
   1474  1.2  thorpej 		printf(" Unsupported adapter type.  %x Ignoring\n", sblkctl);
   1475  1.1  mycroft 		return(-1);
   1476  1.1  mycroft 	}
   1477  1.1  mycroft 
   1478  1.1  mycroft 	/*
   1479  1.1  mycroft 	 * Take the bus led out of diagnostic mode
   1480  1.1  mycroft 	 */
   1481  1.1  mycroft 	outb(SBLKCTL + iobase, sblkctl);
   1482  1.1  mycroft 
   1483  1.1  mycroft 	/*
   1484  1.1  mycroft 	 * Number of SCBs that will be used. Rev E aic7770s and
   1485  1.1  mycroft 	 * aic7870s have 16.  The rest have 4.
   1486  1.1  mycroft 	 */
   1487  1.1  mycroft 	if (!(ahc->type & AHC_AIC7870)) {
   1488  1.1  mycroft 		/*
   1489  1.1  mycroft 		 * See if we have a Rev E or higher
   1490  1.1  mycroft 		 * aic7770. Anything below a Rev E will
   1491  1.1  mycroft 		 * have a R/O autoflush disable configuration
   1492  1.1  mycroft 		 * bit.
   1493  1.1  mycroft 		 */
   1494  1.1  mycroft 		u_char sblkctl_orig;
   1495  1.1  mycroft 		sblkctl_orig = inb(SBLKCTL + iobase);
   1496  1.1  mycroft 		sblkctl = sblkctl_orig ^ AUTOFLUSHDIS;
   1497  1.1  mycroft 		outb(SBLKCTL + iobase, sblkctl);
   1498  1.1  mycroft 		sblkctl = inb(SBLKCTL + iobase);
   1499  1.1  mycroft 		if (sblkctl != sblkctl_orig) {
   1500  1.1  mycroft 			printf("aic7770 >= Rev E, ");
   1501  1.1  mycroft 			/*
   1502  1.1  mycroft 			 * Ensure autoflush is enabled
   1503  1.1  mycroft 			 */
   1504  1.1  mycroft 			sblkctl &= ~AUTOFLUSHDIS;
   1505  1.1  mycroft 			outb(SBLKCTL + iobase, sblkctl);
   1506  1.1  mycroft 		} else
   1507  1.1  mycroft 			printf("aic7770 <= Rev C, ");
   1508  1.1  mycroft 	} else
   1509  1.1  mycroft 		printf("aic7870, ");
   1510  1.1  mycroft 	printf("%d SCBs\n", ahc->maxscbs);
   1511  1.1  mycroft 
   1512  1.1  mycroft 	if (ahc->pause & IRQMS)
   1513  1.1  mycroft 		printf("%s: Using Level Sensitive Interrupts\n",
   1514  1.1  mycroft 		    ahc->sc_dev.dv_xname);
   1515  1.1  mycroft 	else
   1516  1.1  mycroft 		printf("%s: Using Edge Triggered Interrupts\n",
   1517  1.1  mycroft 		    ahc->sc_dev.dv_xname);
   1518  1.1  mycroft 
   1519  1.1  mycroft 	if (!(ahc->type & AHC_AIC7870)) {
   1520  1.1  mycroft 		/*
   1521  1.1  mycroft 		 * The 294x cards are PCI, so we get their interrupt from the
   1522  1.1  mycroft 		 * PCI BIOS.
   1523  1.1  mycroft 		 */
   1524  1.1  mycroft 
   1525  1.1  mycroft 		intdef = inb(INTDEF + iobase);
   1526  1.1  mycroft 		switch (intdef & 0xf) {
   1527  1.1  mycroft 		case 9:
   1528  1.1  mycroft 			ahc->sc_irq = 9;
   1529  1.1  mycroft 			break;
   1530  1.1  mycroft 		case 10:
   1531  1.1  mycroft 			ahc->sc_irq = 10;
   1532  1.1  mycroft 			break;
   1533  1.1  mycroft 		case 11:
   1534  1.1  mycroft 			ahc->sc_irq = 11;
   1535  1.1  mycroft 			break;
   1536  1.1  mycroft 		case 12:
   1537  1.1  mycroft 			ahc->sc_irq = 12;
   1538  1.1  mycroft 			break;
   1539  1.1  mycroft 		case 14:
   1540  1.1  mycroft 			ahc->sc_irq = 14;
   1541  1.1  mycroft 			break;
   1542  1.1  mycroft 		case 15:
   1543  1.1  mycroft 			ahc->sc_irq = 15;
   1544  1.1  mycroft 			break;
   1545  1.1  mycroft 		default:
   1546  1.1  mycroft 			printf("illegal irq setting\n");
   1547  1.1  mycroft 			return (EIO);
   1548  1.1  mycroft 		}
   1549  1.1  mycroft 	}
   1550  1.1  mycroft 
   1551  1.1  mycroft 	/* Set the SCSI Id, SXFRCTL1, and SIMODE1, for both channels */
   1552  1.1  mycroft 	if (ahc->type & AHC_TWIN) {
   1553  1.1  mycroft 		/*
   1554  1.1  mycroft 		 * The device is gated to channel B after a chip reset,
   1555  1.1  mycroft 		 * so set those values first
   1556  1.1  mycroft 		 */
   1557  1.1  mycroft 		outb(SCSIID + iobase, ahc->ahc_scsi_dev_b);
   1558  1.1  mycroft 		scsi_conf = inb(HA_SCSICONF + 1 + iobase) & (ENSPCHK|STIMESEL);
   1559  1.1  mycroft 		outb(SXFRCTL1 + iobase, scsi_conf|ENSTIMER|ACTNEGEN|STPWEN);
   1560  1.1  mycroft 		outb(SIMODE1 + iobase, ENSELTIMO|ENSCSIPERR);
   1561  1.1  mycroft 		/* Select Channel A */
   1562  1.1  mycroft 		outb(SBLKCTL + iobase, 0);
   1563  1.1  mycroft 	}
   1564  1.1  mycroft 	outb(SCSIID + iobase, ahc->ahc_scsi_dev);
   1565  1.1  mycroft 	scsi_conf = inb(HA_SCSICONF + iobase) & (ENSPCHK|STIMESEL);
   1566  1.1  mycroft 	outb(SXFRCTL1 + iobase, scsi_conf|ENSTIMER|ACTNEGEN|STPWEN);
   1567  1.1  mycroft 	outb(SIMODE1 + iobase, ENSELTIMO|ENSCSIPERR);
   1568  1.1  mycroft 
   1569  1.1  mycroft 	/*
   1570  1.1  mycroft 	 * Look at the information that board initialization or
   1571  1.1  mycroft 	 * the board bios has left us.  In the lower four bits of each
   1572  1.1  mycroft 	 * target's scratch space any value other than 0 indicates
   1573  1.1  mycroft 	 * that we should initiate syncronous transfers.  If it's zero,
   1574  1.1  mycroft 	 * the user or the BIOS has decided to disable syncronous
   1575  1.1  mycroft 	 * negotiation to that target so we don't activate the needsdr
   1576  1.1  mycroft 	 * flag.
   1577  1.1  mycroft 	 */
   1578  1.1  mycroft 	ahc->needsdtr_orig = 0;
   1579  1.1  mycroft 	ahc->needwdtr_orig = 0;
   1580  1.1  mycroft 	if (!(ahc->type & AHC_WIDE))
   1581  1.1  mycroft 		max_targ = 8;
   1582  1.1  mycroft 
   1583  1.1  mycroft 	for (i = 0; i < max_targ; i++) {
   1584  1.1  mycroft 		u_char target_settings = inb(HA_TARG_SCRATCH + i + iobase);
   1585  1.1  mycroft #if 0 /* XXXX */
   1586  1.1  mycroft 		target_settings |= 0x8f;
   1587  1.1  mycroft #endif
   1588  1.1  mycroft 		if (target_settings & 0x0f) {
   1589  1.1  mycroft 			ahc->needsdtr_orig |= (0x01 << i);
   1590  1.1  mycroft 			/* Default to a asyncronous transfers (0 offset) */
   1591  1.1  mycroft 			target_settings &= 0xf0;
   1592  1.1  mycroft 		}
   1593  1.1  mycroft 		if (target_settings & 0x80) {
   1594  1.1  mycroft 			ahc->needwdtr_orig |= (0x01 << i);
   1595  1.1  mycroft 			/*
   1596  1.1  mycroft 			 * We'll set the Wide flag when we
   1597  1.1  mycroft 			 * are successful with Wide negotiation,
   1598  1.1  mycroft 			 * so turn it off for now so we aren't
   1599  1.1  mycroft 			 * confused.
   1600  1.1  mycroft 			 */
   1601  1.1  mycroft 			target_settings &= 0x7f;
   1602  1.1  mycroft 		}
   1603  1.1  mycroft 		outb(HA_TARG_SCRATCH + i + iobase, target_settings);
   1604  1.1  mycroft 	}
   1605  1.1  mycroft 	/*
   1606  1.1  mycroft 	 * If we are not a WIDE device, forget WDTR.  This
   1607  1.1  mycroft 	 * makes the driver work on some cards that don't
   1608  1.1  mycroft 	 * leave these fields cleared when the BIOS is not
   1609  1.1  mycroft 	 * installed.
   1610  1.1  mycroft 	 */
   1611  1.1  mycroft 	if (!(ahc->type & AHC_WIDE))
   1612  1.1  mycroft 		ahc->needwdtr_orig = 0;
   1613  1.1  mycroft 	ahc->needsdtr = ahc->needsdtr_orig;
   1614  1.1  mycroft 	ahc->needwdtr = ahc->needwdtr_orig;
   1615  1.1  mycroft 	ahc->sdtrpending = 0;
   1616  1.1  mycroft 	ahc->wdtrpending = 0;
   1617  1.1  mycroft 	ahc->tagenable = 0;
   1618  1.1  mycroft 
   1619  1.1  mycroft 	/*
   1620  1.1  mycroft 	 * Clear the control byte for every SCB so that the sequencer
   1621  1.1  mycroft 	 * doesn't get confused and think that one of them is valid
   1622  1.1  mycroft 	 */
   1623  1.1  mycroft 	for (i = 0; i < ahc->maxscbs; i++) {
   1624  1.1  mycroft 		outb(SCBPTR + iobase, i);
   1625  1.1  mycroft 		outb(SCBARRAY + iobase, 0);
   1626  1.1  mycroft 	}
   1627  1.1  mycroft 
   1628  1.1  mycroft #ifdef AHC_DEBUG
   1629  1.1  mycroft 	printf("NEEDSDTR == 0x%x\nNEEDWDTR == 0x%x\n", ahc->needsdtr,
   1630  1.1  mycroft 		ahc->needwdtr);
   1631  1.1  mycroft #endif
   1632  1.1  mycroft 
   1633  1.1  mycroft 	/*
   1634  1.1  mycroft 	 * Set the number of availible SCBs
   1635  1.1  mycroft 	 */
   1636  1.1  mycroft 	outb(HA_SCBCOUNT + iobase, ahc->maxscbs);
   1637  1.1  mycroft 
   1638  1.1  mycroft 	/* We don't have any busy targets right now */
   1639  1.1  mycroft 	outb(HA_ACTIVE0 + iobase, 0);
   1640  1.1  mycroft 	outb(HA_ACTIVE1 + iobase, 0);
   1641  1.1  mycroft 
   1642  1.1  mycroft 	/* We don't have any waiting selections */
   1643  1.1  mycroft 	outb(WAITING_SCBH + iobase, SCB_LIST_NULL);
   1644  1.1  mycroft 	outb(WAITING_SCBT + iobase, SCB_LIST_NULL);
   1645  1.1  mycroft 	/*
   1646  1.1  mycroft 	 * Load the Sequencer program and Enable the adapter.
   1647  1.1  mycroft 	 * Place the aic7770 in fastmode which makes a big
   1648  1.1  mycroft 	 * difference when doing many small block transfers.
   1649  1.1  mycroft 	 */
   1650  1.1  mycroft 
   1651  1.1  mycroft 	printf("%s: Downloading Sequencer Program...", ahc->sc_dev.dv_xname);
   1652  1.1  mycroft 	ahc_loadseq(iobase);
   1653  1.1  mycroft 	printf("Done\n");
   1654  1.1  mycroft 
   1655  1.1  mycroft 	if (!(ahc->type & AHC_AIC7870))
   1656  1.1  mycroft 		outb(BCTL + iobase, ENABLE);
   1657  1.1  mycroft 
   1658  1.1  mycroft 	/* Reset the bus */
   1659  1.1  mycroft 	outb(SCSISEQ + iobase, SCSIRSTO);
   1660  1.1  mycroft 	delay(1000);
   1661  1.1  mycroft 	outb(SCSISEQ + iobase, 0);
   1662  1.1  mycroft 
   1663  1.1  mycroft 	RESTART_SEQUENCER(ahc);
   1664  1.1  mycroft 
   1665  1.1  mycroft 	return (0);
   1666  1.1  mycroft }
   1667  1.1  mycroft 
   1668  1.1  mycroft void
   1669  1.1  mycroft ahcminphys(bp)
   1670  1.1  mycroft 	struct buf *bp;
   1671  1.1  mycroft {
   1672  1.1  mycroft 
   1673  1.1  mycroft 	if (bp->b_bcount > ((AHC_NSEG - 1) << PGSHIFT))
   1674  1.1  mycroft 		bp->b_bcount = ((AHC_NSEG - 1) << PGSHIFT);
   1675  1.1  mycroft 	minphys(bp);
   1676  1.1  mycroft }
   1677  1.1  mycroft 
   1678  1.1  mycroft /*
   1679  1.1  mycroft  * start a scsi operation given the command and
   1680  1.1  mycroft  * the data address, target, and lun all of which
   1681  1.1  mycroft  * are stored in the scsi_xfer struct
   1682  1.1  mycroft  */
   1683  1.1  mycroft int
   1684  1.1  mycroft ahc_scsi_cmd(xs)
   1685  1.1  mycroft 	struct scsi_xfer *xs;
   1686  1.1  mycroft {
   1687  1.1  mycroft 	struct scsi_link *sc_link = xs->sc_link;
   1688  1.1  mycroft 	struct ahc_softc *ahc = sc_link->adapter_softc;
   1689  1.1  mycroft 	struct ahc_scb *scb;
   1690  1.1  mycroft 	struct ahc_dma_seg *sg;
   1691  1.1  mycroft 	int seg;            /* scatter gather seg being worked on */
   1692  1.1  mycroft 	u_long thiskv, thisphys, nextphys;
   1693  1.1  mycroft 	int bytes_this_seg, bytes_this_page, datalen, flags;
   1694  1.1  mycroft 	int s;
   1695  1.1  mycroft 	u_short	mask = (0x01 << (sc_link->target | (sc_link->quirks & 0x08)));
   1696  1.1  mycroft 
   1697  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1698  1.1  mycroft 	if ((sc_link->target & 0xf) == DEBUGTARGET) {
   1699  1.1  mycroft 		printf("ahc ahc_scsi_cmd for %x\n", sc_link->target);
   1700  1.1  mycroft 		sc_link->flags = 0xf0;
   1701  1.1  mycroft 		SC_DEBUG(sc_link, SDEV_DB2, ("ahc_scsi_cmd\n"));
   1702  1.1  mycroft 	}
   1703  1.1  mycroft #endif
   1704  1.1  mycroft 
   1705  1.1  mycroft 	/*
   1706  1.1  mycroft 	 * get a scb to use. If the transfer
   1707  1.1  mycroft 	 * is from a buf (possibly from interrupt time)
   1708  1.1  mycroft 	 * then we can't allow it to sleep
   1709  1.1  mycroft 	 */
   1710  1.1  mycroft 	flags = xs->flags;
   1711  1.1  mycroft 	if ((flags & (ITSDONE|INUSE)) != INUSE) {
   1712  1.1  mycroft 		printf("%s: done or not in use?\n", ahc->sc_dev.dv_xname);
   1713  1.1  mycroft 		xs->flags &= ~ITSDONE;
   1714  1.1  mycroft 		xs->flags |= INUSE;
   1715  1.1  mycroft 	}
   1716  1.1  mycroft 	if ((scb = ahc_get_scb(ahc, flags)) == NULL) {
   1717  1.1  mycroft 		xs->error = XS_DRIVER_STUFFUP;
   1718  1.1  mycroft 		return (TRY_AGAIN_LATER);
   1719  1.1  mycroft 	}
   1720  1.1  mycroft 	scb->xs = xs;
   1721  1.1  mycroft 
   1722  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1723  1.1  mycroft 	if ((sc_link->target & 0xf) == DEBUGTARGET) {
   1724  1.1  mycroft 		sc_link->flags = 0xf0;
   1725  1.1  mycroft 		SC_DEBUG(sc_link, SDEV_DB3, ("start scb(%x)\n", scb));
   1726  1.1  mycroft 	}
   1727  1.1  mycroft #endif
   1728  1.1  mycroft 
   1729  1.1  mycroft 	if (flags & SCSI_RESET) {
   1730  1.1  mycroft 		/* XXX: Needs Implementation */
   1731  1.1  mycroft 		printf("ahc: SCSI_RESET called.\n");
   1732  1.1  mycroft 	}
   1733  1.1  mycroft 
   1734  1.1  mycroft 	/*
   1735  1.1  mycroft 	 * Put all the arguments for the xfer in the scb
   1736  1.1  mycroft 	 */
   1737  1.1  mycroft 	scb->control = 0;
   1738  1.1  mycroft 	if (ahc->tagenable & mask)
   1739  1.1  mycroft 		scb->control |= SCB_TE;
   1740  1.1  mycroft 	if ((ahc->needwdtr & mask) && !(ahc->wdtrpending & mask)) {
   1741  1.1  mycroft 		scb->control |= SCB_NEEDWDTR;
   1742  1.1  mycroft 		ahc->wdtrpending |= mask;
   1743  1.1  mycroft 	}
   1744  1.1  mycroft 	if ((ahc->needsdtr & mask) && !(ahc->sdtrpending & mask)) {
   1745  1.1  mycroft 		scb->control |= SCB_NEEDSDTR;
   1746  1.1  mycroft 		ahc->sdtrpending |= mask;
   1747  1.1  mycroft 	}
   1748  1.1  mycroft 	scb->target_channel_lun = ((sc_link->target << 4) & 0xF0) |
   1749  1.1  mycroft 	    (sc_link->quirks & 0x08) | (sc_link->lun & 0x07);
   1750  1.1  mycroft 	scb->cmdlen = xs->cmdlen;
   1751  1.1  mycroft 	scb->cmdpointer = vtophys(xs->cmd);
   1752  1.1  mycroft 
   1753  1.1  mycroft 	xs->resid = 0;
   1754  1.1  mycroft 	if (xs->datalen) {
   1755  1.1  mycroft 		scb->SG_list_pointer = vtophys(scb->ahc_dma);
   1756  1.1  mycroft 		sg = scb->ahc_dma;
   1757  1.1  mycroft 		seg = 0;
   1758  1.1  mycroft 		{
   1759  1.1  mycroft 			/*
   1760  1.1  mycroft 			 * Set up the scatter gather block
   1761  1.1  mycroft 			 */
   1762  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1763  1.1  mycroft 			if ((sc_link->target & 0xf) == DEBUGTARGET) {
   1764  1.1  mycroft 				sc_link->flags = 0xf0;
   1765  1.1  mycroft 				SC_DEBUG(sc_link, SDEV_DB4,
   1766  1.1  mycroft 				     ("%ld @%x:- ", xs->datalen, xs->data));
   1767  1.1  mycroft 			}
   1768  1.1  mycroft #endif
   1769  1.1  mycroft 			datalen = xs->datalen;
   1770  1.1  mycroft 			thiskv = (long) xs->data;
   1771  1.1  mycroft 			thisphys = vtophys(thiskv);
   1772  1.1  mycroft 
   1773  1.1  mycroft 			while (datalen && seg < AHC_NSEG) {
   1774  1.1  mycroft 				bytes_this_seg = 0;
   1775  1.1  mycroft 
   1776  1.1  mycroft 				/* put in the base address */
   1777  1.1  mycroft 				sg->seg_addr = thisphys;
   1778  1.1  mycroft 
   1779  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1780  1.1  mycroft 				if ((sc_link->target & 0xf) == DEBUGTARGET) {
   1781  1.1  mycroft 					sc_link->flags = 0xf0;
   1782  1.1  mycroft 					SC_DEBUGN(sc_link, SDEV_DB4, ("0x%lx",
   1783  1.1  mycroft 					    thisphys));
   1784  1.1  mycroft 				}
   1785  1.1  mycroft #endif
   1786  1.1  mycroft 
   1787  1.1  mycroft 				/* do it at least once */
   1788  1.1  mycroft 				nextphys = thisphys;
   1789  1.1  mycroft 				while (datalen && thisphys == nextphys) {
   1790  1.1  mycroft 					/*
   1791  1.1  mycroft 					 * This page is contiguous (physically)
   1792  1.1  mycroft 					 * with the the last, just extend the
   1793  1.1  mycroft 					 * length
   1794  1.1  mycroft 					 */
   1795  1.1  mycroft 					/* how far to the end of the page */
   1796  1.1  mycroft 					nextphys = (thisphys & ~PGOFSET) + NBPG;
   1797  1.1  mycroft 					bytes_this_page = nextphys - thisphys;
   1798  1.1  mycroft 					/**** or the data ****/
   1799  1.1  mycroft 					bytes_this_page = min(bytes_this_page,
   1800  1.1  mycroft 							      datalen);
   1801  1.1  mycroft 					bytes_this_seg += bytes_this_page;
   1802  1.1  mycroft 					datalen -= bytes_this_page;
   1803  1.1  mycroft 
   1804  1.1  mycroft 					/* get more ready for the next page */
   1805  1.1  mycroft 					thiskv = (thiskv & ~PGOFSET) + NBPG;
   1806  1.1  mycroft 					if (datalen)
   1807  1.1  mycroft 						thisphys = vtophys(thiskv);
   1808  1.1  mycroft 				}
   1809  1.1  mycroft 				/*
   1810  1.1  mycroft 				 * next page isn't contiguous, finish the seg
   1811  1.1  mycroft 				 */
   1812  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1813  1.1  mycroft 				if ((sc_link->target & 0xf) == DEBUGTARGET) {
   1814  1.1  mycroft 					sc_link->flags = 0xf0;
   1815  1.1  mycroft 					SC_DEBUGN(sc_link, SDEV_DB4, ("(0x%x)",
   1816  1.1  mycroft 					    bytes_this_seg));
   1817  1.1  mycroft 				}
   1818  1.1  mycroft #endif
   1819  1.1  mycroft 				sg->seg_len = bytes_this_seg;
   1820  1.1  mycroft 				sg++;
   1821  1.1  mycroft 				seg++;
   1822  1.1  mycroft 			}
   1823  1.1  mycroft 		}
   1824  1.1  mycroft 		/*end of iov/kv decision */
   1825  1.1  mycroft 		scb->SG_segment_count = seg;
   1826  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1827  1.1  mycroft 		if ((sc_link->target & 0xf) == DEBUGTARGET) {
   1828  1.1  mycroft 			sc_link->flags = 0xf0;
   1829  1.1  mycroft 			SC_DEBUGN(sc_link, SDEV_DB4, ("\n"));
   1830  1.1  mycroft 		}
   1831  1.1  mycroft #endif
   1832  1.1  mycroft 		if (datalen) {
   1833  1.1  mycroft 			/*
   1834  1.1  mycroft 			 * there's still data, must have run out of segs!
   1835  1.1  mycroft 			 */
   1836  1.1  mycroft 			printf("%s: ahc_scsi_cmd: more than %d dma segs\n",
   1837  1.1  mycroft 			    ahc->sc_dev.dv_xname, AHC_NSEG);
   1838  1.1  mycroft 			xs->error = XS_DRIVER_STUFFUP;
   1839  1.1  mycroft 			ahc_free_scb(ahc, scb, flags);
   1840  1.1  mycroft 			return (COMPLETE);
   1841  1.1  mycroft 		}
   1842  1.1  mycroft 	} else {
   1843  1.1  mycroft 		scb->SG_list_pointer = (physaddr)0;
   1844  1.1  mycroft 		scb->SG_segment_count = 0;
   1845  1.1  mycroft 	}
   1846  1.1  mycroft 
   1847  1.2  thorpej #ifdef AHC_MORE_DEBUG
   1848  1.1  mycroft 	if (sc_link->target == DEBUGTARGET)
   1849  1.1  mycroft 		ahc_print_scb(scb);
   1850  1.1  mycroft #endif
   1851  1.1  mycroft 
   1852  1.1  mycroft 	s = splbio();
   1853  1.1  mycroft 
   1854  1.1  mycroft 	ahc_send_scb(ahc, scb);
   1855  1.1  mycroft 
   1856  1.1  mycroft 	/*
   1857  1.1  mycroft 	 * Usually return SUCCESSFULLY QUEUED
   1858  1.1  mycroft 	 */
   1859  1.1  mycroft 	if ((flags & SCSI_POLL) == 0) {
   1860  1.1  mycroft 		timeout(ahc_timeout, scb, (xs->timeout * hz) / 1000);
   1861  1.1  mycroft 		splx(s);
   1862  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1863  1.1  mycroft 		if ((sc_link->target & 0xf) == DEBUGTARGET) {
   1864  1.1  mycroft 			sc_link->flags = 0xf0;
   1865  1.1  mycroft 			SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
   1866  1.1  mycroft 		}
   1867  1.1  mycroft #endif
   1868  1.1  mycroft 		return (SUCCESSFULLY_QUEUED);
   1869  1.1  mycroft 	}
   1870  1.1  mycroft 
   1871  1.1  mycroft 	splx(s);
   1872  1.1  mycroft 
   1873  1.1  mycroft 	/*
   1874  1.1  mycroft 	 * If we can't use interrupts, poll on completion
   1875  1.1  mycroft 	 */
   1876  1.1  mycroft #ifdef AHC_MORE_DEBUG
   1877  1.1  mycroft 	if ((sc_link->target & 0xf) == DEBUGTARGET) {
   1878  1.1  mycroft 		sc_link->flags = 0xf0;
   1879  1.1  mycroft 		SC_DEBUG(sc_link, SDEV_DB3, ("cmd_wait\n"));
   1880  1.1  mycroft 	}
   1881  1.1  mycroft #endif
   1882  1.1  mycroft 	if (ahc_poll(ahc, xs, xs->timeout)) {
   1883  1.1  mycroft 		ahc_timeout(scb);
   1884  1.1  mycroft 		if (ahc_poll(ahc, xs, 2000))
   1885  1.1  mycroft 			ahc_timeout(scb);
   1886  1.1  mycroft 	}
   1887  1.1  mycroft 	return (COMPLETE);
   1888  1.1  mycroft }
   1889  1.1  mycroft 
   1890  1.1  mycroft 
   1891  1.1  mycroft /*
   1892  1.1  mycroft  * A scb (and hence an scb entry on the board is put onto the
   1893  1.1  mycroft  * free list.
   1894  1.1  mycroft  */
   1895  1.1  mycroft void
   1896  1.1  mycroft ahc_free_scb(ahc, scb, flags)
   1897  1.1  mycroft 	struct ahc_softc *ahc;
   1898  1.1  mycroft 	struct  ahc_scb *scb;
   1899  1.1  mycroft 	int flags;
   1900  1.1  mycroft {
   1901  1.1  mycroft 	int s;
   1902  1.1  mycroft 
   1903  1.1  mycroft 	s = splbio();
   1904  1.1  mycroft 
   1905  1.1  mycroft 	scb->flags = SCB_FREE;
   1906  1.1  mycroft 	TAILQ_INSERT_TAIL(&ahc->free_scb, scb, chain);
   1907  1.1  mycroft #ifdef AHC_DEBUG
   1908  1.1  mycroft 	ahc->activescbs--;
   1909  1.1  mycroft #endif
   1910  1.1  mycroft 
   1911  1.1  mycroft 	/*
   1912  1.1  mycroft 	 * If there were none, wake anybody waiting for one to come free,
   1913  1.1  mycroft 	 * starting with queued entries.
   1914  1.1  mycroft 	 */
   1915  1.1  mycroft 	if (scb->chain.tqe_next == 0)
   1916  1.1  mycroft 		wakeup(&ahc->free_scb);
   1917  1.1  mycroft 
   1918  1.1  mycroft 	splx(s);
   1919  1.1  mycroft }
   1920  1.1  mycroft 
   1921  1.1  mycroft /* XXXX check */
   1922  1.1  mycroft static inline void
   1923  1.1  mycroft ahc_init_scb(ahc, scb)
   1924  1.1  mycroft 	struct ahc_softc *ahc;
   1925  1.1  mycroft 	struct ahc_scb *scb;
   1926  1.1  mycroft {
   1927  1.1  mycroft 	int iobase = ahc->sc_iobase;
   1928  1.1  mycroft 	u_char scb_index;
   1929  1.1  mycroft 
   1930  1.1  mycroft 	bzero(scb, sizeof(struct ahc_scb));
   1931  1.1  mycroft 	scb->position = ahc->numscbs;
   1932  1.1  mycroft 	/*
   1933  1.1  mycroft 	 * Place in the scbarray
   1934  1.1  mycroft 	 * Never is removed.  Position
   1935  1.1  mycroft 	 * in ahc->scbarray is the scbarray
   1936  1.1  mycroft 	 * position on the board we will
   1937  1.1  mycroft 	 * load it into.
   1938  1.1  mycroft 	 */
   1939  1.1  mycroft 	ahc->scbarray[scb->position] = scb;
   1940  1.1  mycroft 
   1941  1.1  mycroft 	/*
   1942  1.1  mycroft 	 * Initialize the host memory location
   1943  1.1  mycroft 	 * of this SCB down on the board and
   1944  1.1  mycroft 	 * flag that it should be DMA's before
   1945  1.1  mycroft 	 * reference.  Also set its psuedo
   1946  1.1  mycroft 	 * next pointer (for use in the psuedo
   1947  1.1  mycroft 	 * list of SCBs waiting for selection)
   1948  1.1  mycroft 	 * to SCB_LIST_NULL.
   1949  1.1  mycroft 	 */
   1950  1.1  mycroft 	scb->control = SCB_NEEDDMA;
   1951  1.1  mycroft 	scb->host_scb = vtophys(scb);
   1952  1.1  mycroft 	scb->next_waiting = SCB_LIST_NULL;
   1953  1.1  mycroft 	PAUSE_SEQUENCER(ahc);
   1954  1.1  mycroft 	scb_index = inb(SCBPTR + iobase);
   1955  1.1  mycroft 	outb(SCBPTR + iobase, scb->position);
   1956  1.1  mycroft 	outb(SCBCNT + iobase, SCBAUTO);
   1957  1.1  mycroft 	outsb(SCBARRAY + iobase, scb, 31);
   1958  1.1  mycroft 	outb(SCBCNT + iobase, 0);
   1959  1.1  mycroft 	outb(SCBPTR + iobase, scb_index);
   1960  1.1  mycroft 	UNPAUSE_SEQUENCER(ahc);
   1961  1.1  mycroft 	scb->control = 0;
   1962  1.1  mycroft }
   1963  1.1  mycroft 
   1964  1.1  mycroft static inline void
   1965  1.1  mycroft ahc_reset_scb(ahc, scb)
   1966  1.1  mycroft 	struct ahc_softc *ahc;
   1967  1.1  mycroft 	struct ahc_scb *scb;
   1968  1.1  mycroft {
   1969  1.1  mycroft 
   1970  1.1  mycroft 	bzero(scb, SCB_BZERO_SIZE);
   1971  1.1  mycroft }
   1972  1.1  mycroft 
   1973  1.1  mycroft /*
   1974  1.1  mycroft  * Get a free scb
   1975  1.1  mycroft  *
   1976  1.1  mycroft  * If there are none, see if we can allocate a new one.
   1977  1.1  mycroft  */
   1978  1.1  mycroft struct ahc_scb *
   1979  1.1  mycroft ahc_get_scb(ahc, flags)
   1980  1.1  mycroft 	struct ahc_softc *ahc;
   1981  1.1  mycroft 	int flags;
   1982  1.1  mycroft {
   1983  1.1  mycroft 	struct ahc_scb *scb;
   1984  1.1  mycroft 	int s;
   1985  1.1  mycroft 
   1986  1.1  mycroft 	s = splbio();
   1987  1.1  mycroft 
   1988  1.1  mycroft 	/*
   1989  1.1  mycroft 	 * If we can and have to, sleep waiting for one to come free
   1990  1.1  mycroft 	 * but only if we can't allocate a new one.
   1991  1.1  mycroft 	 */
   1992  1.1  mycroft 	for (;;) {
   1993  1.1  mycroft 		scb = ahc->free_scb.tqh_first;
   1994  1.1  mycroft 		if (scb) {
   1995  1.1  mycroft 			TAILQ_REMOVE(&ahc->free_scb, scb, chain);
   1996  1.1  mycroft 			break;
   1997  1.1  mycroft 		}
   1998  1.1  mycroft 		if (ahc->numscbs < ahc->maxscbs) {
   1999  1.1  mycroft 			if (scb = (struct ahc_scb *) malloc(sizeof(struct ahc_scb),
   2000  1.1  mycroft 			    M_TEMP, M_NOWAIT)) {
   2001  1.1  mycroft 				ahc_init_scb(ahc, scb);
   2002  1.1  mycroft 				ahc->numscbs++;
   2003  1.1  mycroft 			} else {
   2004  1.1  mycroft 				printf("%s: can't malloc scb\n",
   2005  1.1  mycroft 				    ahc->sc_dev.dv_xname);
   2006  1.1  mycroft 				goto out;
   2007  1.1  mycroft 			}
   2008  1.1  mycroft 			break;
   2009  1.1  mycroft 		}
   2010  1.1  mycroft 		if ((flags & SCSI_NOSLEEP) != 0)
   2011  1.1  mycroft 			goto out;
   2012  1.1  mycroft 		tsleep(&ahc->free_scb, PRIBIO, "ahcscb", 0);
   2013  1.1  mycroft 	}
   2014  1.1  mycroft 
   2015  1.1  mycroft 	ahc_reset_scb(ahc, scb);
   2016  1.1  mycroft 	scb->flags = SCB_ACTIVE;
   2017  1.1  mycroft #ifdef AHC_DEBUG
   2018  1.1  mycroft 	ahc->activescbs++;
   2019  1.1  mycroft 	if (ahc->activescbs == ahc->maxscbs)
   2020  1.1  mycroft 		printf("%s: Max SCBs active\n", ahc->sc_dev.dv_xname);
   2021  1.1  mycroft #endif
   2022  1.1  mycroft 
   2023  1.1  mycroft out:
   2024  1.1  mycroft 	splx(s);
   2025  1.1  mycroft 	return (scb);
   2026  1.1  mycroft }
   2027  1.1  mycroft 
   2028  1.1  mycroft /* XXXX check */
   2029  1.1  mycroft void
   2030  1.1  mycroft ahc_loadseq(iobase)
   2031  1.1  mycroft 	int iobase;
   2032  1.1  mycroft {
   2033  1.1  mycroft 	static u_char seqprog[] = {
   2034  1.1  mycroft #               include "aic7xxx_seq.h"
   2035  1.1  mycroft 	};
   2036  1.1  mycroft 
   2037  1.1  mycroft 	outb(SEQCTL + iobase, PERRORDIS|SEQRESET|LOADRAM);
   2038  1.1  mycroft 	outsb(SEQRAM + iobase, seqprog, sizeof(seqprog));
   2039  1.1  mycroft 	outb(SEQCTL + iobase, FASTMODE|SEQRESET);
   2040  1.1  mycroft }
   2041  1.1  mycroft 
   2042  1.1  mycroft /*
   2043  1.1  mycroft  * Function to poll for command completion when in poll mode
   2044  1.1  mycroft  */
   2045  1.1  mycroft int
   2046  1.1  mycroft ahc_poll(ahc, xs, count)
   2047  1.1  mycroft 	struct ahc_softc *ahc;
   2048  1.1  mycroft 	struct scsi_xfer *xs;
   2049  1.1  mycroft 	int count;
   2050  1.1  mycroft {                               /* in msec  */
   2051  1.1  mycroft 	int iobase = ahc->sc_iobase;
   2052  1.1  mycroft 	int stport = INTSTAT + iobase;
   2053  1.1  mycroft 
   2054  1.1  mycroft 	while (count) {
   2055  1.1  mycroft 		/*
   2056  1.1  mycroft 		 * If we had interrupts enabled, would we
   2057  1.1  mycroft 		 * have got an interrupt?
   2058  1.1  mycroft 		 */
   2059  1.1  mycroft 		if (inb(stport) & INT_PEND)
   2060  1.1  mycroft 			ahcintr(ahc);
   2061  1.1  mycroft 		if (xs->flags & ITSDONE)
   2062  1.1  mycroft 			return 0;
   2063  1.1  mycroft 		delay(1000);
   2064  1.1  mycroft 		count--;
   2065  1.1  mycroft 	}
   2066  1.1  mycroft 	return 1;
   2067  1.1  mycroft }
   2068  1.1  mycroft 
   2069  1.1  mycroft /* XXXX check */
   2070  1.1  mycroft void
   2071  1.1  mycroft ahc_abort_scb(ahc, scb)
   2072  1.1  mycroft 	struct ahc_softc *ahc;
   2073  1.1  mycroft 	struct ahc_scb *scb;
   2074  1.1  mycroft {
   2075  1.1  mycroft 	int iobase = ahc->sc_iobase;
   2076  1.1  mycroft 	int found = 0;
   2077  1.1  mycroft 	int scb_index;
   2078  1.1  mycroft 	u_char flags;
   2079  1.1  mycroft 	u_char scb_control;
   2080  1.1  mycroft 
   2081  1.1  mycroft 	PAUSE_SEQUENCER(ahc);
   2082  1.1  mycroft 	/*
   2083  1.1  mycroft 	 * Case 1: In the QINFIFO
   2084  1.1  mycroft 	 */
   2085  1.1  mycroft 	{
   2086  1.1  mycroft 		int saved_queue[AHC_SCB_MAX];
   2087  1.1  mycroft 		int i;
   2088  1.1  mycroft 		int queued = inb(QINCNT + iobase);
   2089  1.1  mycroft 
   2090  1.1  mycroft 		for (i = 0; i < (queued - found); i++) {
   2091  1.1  mycroft 			saved_queue[i] = inb(QINFIFO + iobase);
   2092  1.1  mycroft 			if (saved_queue[i] == scb->position) {
   2093  1.1  mycroft 				i--;
   2094  1.1  mycroft 				found = 1;
   2095  1.1  mycroft 			}
   2096  1.1  mycroft 		}
   2097  1.1  mycroft 		/* Re-insert entries back into the queue */
   2098  1.1  mycroft 		for (queued = 0; queued < i; queued++)
   2099  1.1  mycroft 			outb(QINFIFO + iobase, saved_queue[queued]);
   2100  1.1  mycroft 
   2101  1.1  mycroft 		if (found)
   2102  1.1  mycroft 			goto done;
   2103  1.1  mycroft 	}
   2104  1.1  mycroft 
   2105  1.1  mycroft 	scb_index = inb(SCBPTR + iobase);
   2106  1.1  mycroft 	/*
   2107  1.1  mycroft 	 * Case 2: Not the active command
   2108  1.1  mycroft 	 */
   2109  1.1  mycroft 	if (scb_index != scb->position) {
   2110  1.1  mycroft 		/*
   2111  1.1  mycroft 		 * Select the SCB we want to abort
   2112  1.1  mycroft 		 * and turn off the disconnected bit.
   2113  1.1  mycroft 		 * the driver will then abort the command
   2114  1.1  mycroft 		 * and notify us of the abort.
   2115  1.1  mycroft 		 */
   2116  1.1  mycroft 		outb(SCBPTR + iobase, scb->position);
   2117  1.1  mycroft 		scb_control = inb(SCBARRAY + iobase);
   2118  1.1  mycroft 		scb_control &= ~SCB_DIS;
   2119  1.1  mycroft 		outb(SCBARRAY + iobase, scb_control);
   2120  1.1  mycroft 		outb(SCBPTR + iobase, scb_index);
   2121  1.1  mycroft 		goto done;
   2122  1.1  mycroft 	}
   2123  1.1  mycroft 	scb_control = inb(SCBARRAY + iobase);
   2124  1.1  mycroft 	if (scb_control & SCB_DIS) {
   2125  1.1  mycroft 		scb_control &= ~SCB_DIS;
   2126  1.1  mycroft 		outb(SCBARRAY + iobase, scb_control);
   2127  1.1  mycroft 		goto done;
   2128  1.1  mycroft 	}
   2129  1.1  mycroft 	/*
   2130  1.1  mycroft 	 * Case 3: Currently active command
   2131  1.1  mycroft 	 */
   2132  1.1  mycroft 	if ((flags = inb(HA_FLAGS + iobase)) & ACTIVE_MSG) {
   2133  1.1  mycroft 		/*
   2134  1.1  mycroft 		 * If there's a message in progress,
   2135  1.1  mycroft 		 * reset the bus and have all devices renegotiate.
   2136  1.1  mycroft 		 */
   2137  1.1  mycroft 		if (scb->target_channel_lun & 0x08) {
   2138  1.1  mycroft 			ahc->needsdtr |= (ahc->needsdtr_orig & 0xff00);
   2139  1.1  mycroft 			ahc->sdtrpending &= 0x00ff;
   2140  1.1  mycroft 			outb(HA_ACTIVE1, 0);
   2141  1.1  mycroft 		} else if (ahc->type & AHC_WIDE) {
   2142  1.1  mycroft 			ahc->needsdtr = ahc->needsdtr_orig;
   2143  1.1  mycroft 			ahc->needwdtr = ahc->needwdtr_orig;
   2144  1.1  mycroft 			ahc->sdtrpending = 0;
   2145  1.1  mycroft 			ahc->wdtrpending = 0;
   2146  1.1  mycroft 			outb(HA_ACTIVE0, 0);
   2147  1.1  mycroft 			outb(HA_ACTIVE1, 0);
   2148  1.1  mycroft 		} else {
   2149  1.1  mycroft 			ahc->needsdtr |= (ahc->needsdtr_orig & 0x00ff);
   2150  1.1  mycroft 			ahc->sdtrpending &= 0xff00;
   2151  1.1  mycroft 			outb(HA_ACTIVE0, 0);
   2152  1.1  mycroft 		}
   2153  1.1  mycroft 
   2154  1.1  mycroft 		/* Reset the bus */
   2155  1.1  mycroft 		outb(SCSISEQ + iobase, SCSIRSTO);
   2156  1.1  mycroft 		delay(1000);
   2157  1.1  mycroft 		outb(SCSISEQ + iobase, 0);
   2158  1.1  mycroft 		goto done;
   2159  1.1  mycroft 	}
   2160  1.1  mycroft 
   2161  1.1  mycroft 	/*
   2162  1.1  mycroft 	 * Otherwise, set up an abort message and have the sequencer
   2163  1.1  mycroft 	 * clean up
   2164  1.1  mycroft 	 */
   2165  1.1  mycroft 	outb(HA_FLAGS + iobase, flags | ACTIVE_MSG);
   2166  1.1  mycroft 	outb(HA_MSG_LEN + iobase, 1);
   2167  1.1  mycroft 	outb(HA_MSG_START + iobase, MSG_ABORT);
   2168  1.1  mycroft 
   2169  1.1  mycroft 	outb(SCSISIGO + iobase, inb(HA_SIGSTATE + iobase) | 0x10);
   2170  1.1  mycroft 
   2171  1.1  mycroft done:
   2172  1.1  mycroft 	scb->flags = SCB_ABORTED;
   2173  1.1  mycroft 	UNPAUSE_SEQUENCER(ahc);
   2174  1.1  mycroft 	ahc_done(ahc, scb);
   2175  1.1  mycroft 	return;
   2176  1.1  mycroft }
   2177  1.1  mycroft 
   2178  1.1  mycroft void
   2179  1.1  mycroft ahc_timeout(arg)
   2180  1.1  mycroft 	void *arg;
   2181  1.1  mycroft {
   2182  1.1  mycroft 	struct ahc_scb *scb = arg;
   2183  1.1  mycroft 	struct scsi_xfer *xs = scb->xs;
   2184  1.1  mycroft 	struct scsi_link *sc_link = xs->sc_link;
   2185  1.1  mycroft 	struct ahc_softc *ahc = sc_link->adapter_softc;
   2186  1.1  mycroft 	int s;
   2187  1.1  mycroft 
   2188  1.1  mycroft 	sc_print_addr(sc_link);
   2189  1.1  mycroft 	printf("timed out");
   2190  1.1  mycroft 
   2191  1.1  mycroft 	s = splbio();
   2192  1.1  mycroft 
   2193  1.1  mycroft #ifdef SCSIDEBUG
   2194  1.1  mycroft 	show_scsi_cmd(scb->xs);
   2195  1.1  mycroft #endif
   2196  1.1  mycroft #ifdef  AHC_DEBUG
   2197  1.1  mycroft 	if (ahc_debug & AHC_SHOWSCBS)
   2198  1.1  mycroft 		ahc_print_active_scb(ahc);
   2199  1.1  mycroft #endif /*AHC_DEBUG */
   2200  1.1  mycroft 
   2201  1.1  mycroft 	if (scb->flags & SCB_IMMED) {
   2202  1.1  mycroft 		printf("\n");
   2203  1.1  mycroft 		scb->xs->retries = 0;   /* I MEAN IT ! */
   2204  1.1  mycroft 		scb->flags |= SCB_IMMED_FAIL;
   2205  1.1  mycroft 		ahc_done(ahc, scb);
   2206  1.1  mycroft 		splx(s);
   2207  1.1  mycroft 		return;
   2208  1.1  mycroft 	}
   2209  1.1  mycroft 
   2210  1.1  mycroft 	/*
   2211  1.1  mycroft 	 * If it has been through before, then
   2212  1.1  mycroft 	 * a previous abort has failed, don't
   2213  1.1  mycroft 	 * try abort again
   2214  1.1  mycroft 	 */
   2215  1.1  mycroft 	if (scb->flags == SCB_ABORTED) {
   2216  1.1  mycroft 		/* abort timed out */
   2217  1.1  mycroft 		printf(" AGAIN\n");
   2218  1.1  mycroft 		scb->xs->retries = 0;	/* I MEAN IT ! */
   2219  1.1  mycroft 		ahc_done(ahc, scb);
   2220  1.1  mycroft 	} else {
   2221  1.1  mycroft 		/* abort the operation that has timed out */
   2222  1.1  mycroft 		printf("\n");
   2223  1.1  mycroft 		scb->xs->error = XS_TIMEOUT;
   2224  1.1  mycroft 		scb->flags = SCB_ABORTED;
   2225  1.1  mycroft 		ahc_abort_scb(ahc, scb);
   2226  1.1  mycroft 		/* 2 secs for the abort */
   2227  1.1  mycroft 		if ((xs->flags & SCSI_POLL) == 0)
   2228  1.1  mycroft 			timeout(ahc_timeout, scb, 2 * hz);
   2229  1.1  mycroft 	}
   2230  1.1  mycroft 
   2231  1.1  mycroft 	splx(s);
   2232  1.1  mycroft }
   2233