Commit Graph

79 Commits

Author SHA1 Message Date
Justin T. Gibbs
0f39fbdeb5 Correct twin channel operation. 1998-09-21 16:46:13 +00:00
Justin T. Gibbs
3bafc9d432 Massive overhaul of the aic7xxx driver:
- Convert to CAM
 - Use a new DMA based queuing and paging scheme
 - Add preliminary target mode support
 - Add support for the aic789X chips
 - Take advantage of external SRAM on more controllers.
 - Numerous bug fixes and performance improvements.
1998-09-15 07:24:17 +00:00
Justin T. Gibbs
b66655cf37 Some revisions of the aic7880 have a problem where, if the
data fifo is full, but the PCI input latch is not empty,
HDMAEN cannot be cleared.  The fix used here is to attempt
to drain the data fifo until there is space for the input
latch to drain and HDMAEN de-asserts.

This is a 1 instruction fix, so it should have no performance
impact.
1998-06-28 02:58:57 +00:00
Justin T. Gibbs
37507c1bd2 Add support to aicasm for "downloaded constants". These are immediate
operands that are set during seqeuncer program download instead of at
assembly time.

Convert the sequencer code to use" downloaded constants" for four run time
constants that vary depending on the board type.  This frees up 4 bytes
of sequencer scratch ram space where these constants used to be stored and
also removes the additional instructions required to load their values
into the accumulator prior to using them.

Remove the REJBYTE sram variable.  The host driver can just as easly
read the accumulator to get this value.

The scratch ram savings is important as the old code used to clober the
SCSICONF register on 274X cards which sits near the top of scratch ram
space.  The SCSICONF register controls bus termination, and clobbering
it is not a good thing.  Now we have 4 bytes to spare.

This should fix the reported problems with cards that don't have devices
attached to them failing with a stream of "Somone reset bus X" messages.

Doug Ledford determined the cause of the problem, fixes by me.
1997-09-27 19:37:31 +00:00
Justin T. Gibbs
083bc8b2cc Add a spin lock that prevents the sequencer from attempting to add an
entry to the QOUTFIFO when it is full.  This should eliminate the
"Timed out while idle" problems that many have reported.

In truth, this is somewhat of a hack.  Although are interrupt latency is
low enough that we should be able to always service the queue in time,
since each entry must be passed up to the higher SCSI layer for what can
be a large amount of processing (perhaps even resulting in a new command
being queued) with interrupts disabled, we need this mechanism to avoid
overflow.  In the future, these additional tasks will be offloaded to a
software interrupt handler which should make this hack unnecessary.
1997-08-13 17:02:47 +00:00
Justin T. Gibbs
f68f348b20 Modify my copyright notice to allow the sequencer to be used with GPLed
software (aka Linux).

Fix a few bugs in the sequencer assembler.

Make it easy to compiler the assembler with debugging turned on.
1997-06-27 19:38:56 +00:00
Justin T. Gibbs
cd6867d0d3 The following scenario would result in a bogus residual being reported
if SCB Paging was enabled:

    disconnect with more data to transfer
    disconnected SCB gets paged out
    target reconnects so we page SCB back in
    target completes transfer so residual is 0
    target disconnects
    SCB gets reused but not paged out since the residual is 0 (optimization)
    target reconnects so we page the SCB back in
    we report a residual because of stale residual information.

The fix for this is to set a flag that forces the SCB to be paged back
up to the host if we page in an SCB with a residual

Pointed out by: Doug Ledford <dledford@dialnet.net>
1997-04-24 16:52:18 +00:00
Justin T. Gibbs
7bde50c604 Revert some changes to the selection and reselection code that were thought
to fix a selection timeout problem.

If we can't find an SCB for the reconnecting target, issue a bus device
reset as the SCSI2 spec suggests.

Add a missing call to "add_scb_to_free_list" in the non paging case.  In
the non-paging case, the SCBs don't really need to be on the free list,
but putting them there clears the tag field which is something the recovery
code depends on.
1997-04-18 16:31:55 +00:00
Justin T. Gibbs
45b7cf8750 Re-arange the selection and reselection code to hopefully kill the
spurious selection timeouts that have been reported.
1997-04-14 02:26:59 +00:00
Justin T. Gibbs
9ff0e63881 aic7xxx.seq:
Be consistant about testing for parity errors after waiting for a
	REQ on the bus.

	Don't ack the last byte in a transaction until after we've cleared
	all target state.

aic7xxx_asm.c:
	Test the return value of getopt against -1 not EOF. (Yet another
	shameless victum of the style guide being wrong).
1997-04-10 19:13:07 +00:00
Justin T. Gibbs
1961f6e884 Instead of testing for both SELDI and SELDO in SSTAT0 in the poll for work
loop, test for them separately.  The bug report from David Malone showed that
even though we had been reselected (SELDI was true), we sat in the poll for
work loop until the selection timeout timer expired.  It may be that the
SSTAT0 register doesn't like to have more than one bit tested at a time.
I've seen stranger things than this on these parts.
1997-04-05 22:03:47 +00:00
Justin T. Gibbs
bb5d13ea1c Add missing Id that was lost when the sequencer file format changed. 1997-04-04 19:35:30 +00:00
Justin T. Gibbs
5ea0ae111d When not using SCB paging, we can always directly index the SCB of interest
either by looking it up in the array of pending, per target, untagged
transactions, or by using the tag value passed in during the identify.  The
old code only direct indexed for tagged transactions.  This makes the
"findSCB" routine only necessary when SCB paging is enabled, so appropriately
conditionalize it.  This greatly simplifies the non SCB paging code flow.
1997-04-04 04:09:29 +00:00
Justin T. Gibbs
23e11becca Re-arrange the code to upload an SCB to ensure that there is at least
on instruction between the last load into the DFIFO and enabling the DMA.
During back to back SCB DMA, it was possible to hang the card.
1997-03-24 05:02:55 +00:00
Justin T. Gibbs
1c147cc352 aic7xxx.seq:
Stick 4 more, twin channel only, instructions behind
	.if ( TWIN_CHANNEL)

aic7xxx_asm.c:
	Add the -O options which allows the specification of which options
	to include in a program listing.  This makes it possible to easily
	determine the address of any instruction in the program across
	different hardware/option configurations.  Updated usage() as well.
1997-03-18 19:18:39 +00:00
Justin T. Gibbs
c5cb388883 Makefile gram.y scan.l sequencer.h symbol.c symbol.h aic7xxx_asm.c:
New sequencer assembler for the aic7xxx adapters.  This assembler
	performs some amount of register type checking, allows bit
	manipulation of symbolic constants, and generates "patch tables"
	for conditionalized downloading of portions of the program.
	This makes it easier to take full advantage of the different
	features of the aic7xxx cards without imposing run time penalies
	or being bound to the small memory footprints of the low end
	cards for features like target mode.

aic7xxx.reg:
	New, assembler parsed, register definitions fo the aic7xxx cards.
	This was done primarily in anticipation of 7810 support which
	will have a different register layout, but should be able to use
	the same assembler.  The kernel aic7xxx driver consumes a generated
	file in the compile directory to get the definitions of the register
	locations.

aic7xxx.seq:
	Convert to the slighly different syntax of the new assembler.

	Conditionalize SCB_PAGING, ultra, and twin features which shaves
	quite a bit of space once the program is downloaded.

	Add code to leave the selection hardware enabled during reconnects
	that win bus arbitration.  This ensures that we will rearbitrate
	as soon as the bus goes free instead of delaying for a bit.

	When we expect the bus to go free, perform all of the cleanup
	associated with that event "up front" and enter a loop awaiting
	bus free.  If we see a REQ first, complain, but attempt to
	continue.  This will hopefully address, or at least help diagnose,
	the "target didn't send identify" messages that have been reported.

Spelling corrections obtained from NetBSD.
1997-03-16 07:08:19 +00:00
Justin T. Gibbs
9b2a5540ff No longer clear all interrupt status when the sequencer is reset. The only
time that we really want to do this is when a bus reset causes the sequencer
to be reset and the kernel driver now handles this case.

Remove some reordering in the select2 routine that wasn't necessary.
It was an experimental fix for a race condition I fixed elsewhere, and
confused the code flow.

Don't bother looping on a parity error in the mesgout loop since we can't
see parity errors on out phases.

Clean up the mesgin_identify code.  In the old days, we "snooped" for tag
messages and used this as an indicator of whether or not the target was
using tagged transactions.  This forced the sequencer to ack the identify
before determining if a valid SCB matched the target meaning that an abort
message to handle this case might not be seen before the target entered a
data phase.  Since we can determin the "tagged-ness" of a target by looking
it up in the array of busy targets (recently introduced), we can determine
this up front simplifying the search code as well as ensuring we can follow
the SCSI specs method for rejecting a reselection.

When an SCB is placed on the free list, set its SCB_TAG to SCB_LIST_NULL.
This makes it much easier for the kernel driver to find active SCBs on the
card during error recovery.
1997-02-28 03:51:00 +00:00
Justin T. Gibbs
9df674522b Leave reselections on all the time.
If we are aborting an SCB from findSCB, don't add it back to the free list -
	the kernel driver will do this for us.
1997-02-25 03:02:58 +00:00
Peter Wemm
6875d25465 Back out part 1 of the MCFH that changed $Id$ to $FreeBSD$. We are not
ready for it yet.
1997-02-22 09:48:43 +00:00
Justin T. Gibbs
5154778752 Enlarge the message out buffer from 6 to 8 bytes. Now that sync and wide
negotiation messages may be tagged, we were overrunning the old buffer.
The variable that was getting squashed is updated before the message goes
out, causing corrupted SDTR or WDTR messages.  Depending on the phases
traversed before message out, this could cause the wrong offset to be
negotiated allowing data overruns to occur.  The problem is easier to
detect with wide targets on the chain since the allowed offset is smaller.

Also removed the unnecessary  clearing of SPIORDY during the message out
phase.  We don't rely on SPIORDY any more.
1997-02-18 20:22:52 +00:00
Justin T. Gibbs
499c4ce9f6 Clear the DFCNTRL register after every busfree.
When setting the HCNT registers, do so in ascending order.

When performing tagged queueing in non-paging mode, also check the
disconnected bit in the SCB as extra sanity during a reconection.

Make the labels in the DMA routine more sane.

When doing a DMA, if we see the DMADONE condition come true, we can
simply turn of the DMA enable bits in DFCNTRL without testing the FIFO
state as HDONE is true when DMADONE is true and this emplies the FIFO is
empty.

These changes clear up the data overrun error messages and seem to prevent
the "timed out in data-in phase" problems.
1997-02-11 17:07:54 +00:00
Justin T. Gibbs
de1dc306be Clear the channel after (re)selection instead of once we see the bus go
free.

When we clear SCSIRATE, also clear the FAST20 bit in SXFRCTL0.  This also
allowed me to clean up some of the ULTRA code.

ULTRAENB->FAST20 to follow the convention in the Adaptec data books.

Fix the data-overrun code to set both stcnt and hcnt otherwise, the transfer
will just hang until we get a timeout.

Add implicit support for the NOOP message.  I've never heard of the driver
issueing a reject for one, but its silly to reject NOOP and who knows how a
device might react.

In the dma routine, check SDONE before cleaing SDMAEN.  The data books mention
SDONE possibly being cleared when SDMAEN is reset.  Clients of dma now need
to check if SINDEX is cleared to know if a phasemis occured.

Fix some comments to be correct.
1997-02-09 03:23:28 +00:00
Justin T. Gibbs
1d6abdbc6f In dma_finish, don't disturb the direction bit in DFCNTRL when turning off
host DMAs.  The additional test to ensure that the DMA has stopped is also
unnecessary since we've already waited for the DMA to complete.

Update my copyright for the new year.
1997-02-03 02:02:04 +00:00
Justin T. Gibbs
8ebddd1e01 Add 1997 to my copyright.
Expand the boundaries of a pause disabled region to close of possible race
condition.

Revert a portion of the DMA code to fix false overruns.

Add a missing "add_scb_to_free_list" so we don't leak SCBs.
1997-01-29 05:19:46 +00:00
Justin T. Gibbs
ed69a71305 Change the way DMA is handled during the command phase. Only test on
SDONE, not HDONE.

In the data phase dma handler, mask off just the enable bits instead of
clearing the whole register.  Clearing the direction bit could be bad.
Also don't stop a DMA until MREQPEND goes false.  Doing this may cause
an ABORT on the PCI bus although I have yet to see this happen.

Add definitions for MREQPEND and the BRDCTL register.  The BRDCTL register
is used to handle high byte termination and automatic termination testing.
1997-01-24 21:57:47 +00:00
Justin T. Gibbs
6d14c339f6 Clear the SCSI channel after we go to busfree instead of after re/selection.
Only enable reselections once the channel and SCSIRATE have been cleared.

Add a pause block around the test busy code in the non-tagged case to simplify
error recovery in the corner case of aborting an SCB that just got started.

Simplify reselection processing by removing the call to initialize_scsiid.

Clear the scsiseq re/select control bits and setup for catching bogus
busfrees earlier in the re/select process.

Improve the automatic PIO code.  It turns out that SPIORDY is not a reliable
hardware condition bit, so use REQINIT intstead.  Don't rely on PHASEMIS
either since it can take too long to come true.  Use a brute force comparison
instead.

Remove some unnecessary overhead in the command complete processing.  It
should be nearly impossible to overflow the QOUTFIFO (worst case 9 command
have to complete with at least 6 of them requiring paging on an aic7850),
so don't take the additional PIO hit to guard against this condition.  If we
don't see our interrupt in time, the system has bigger problems elsewhere.
If this ever does happen, the timeout handler will notice and retry the
command.
1997-01-22 18:01:07 +00:00
Jordan K. Hubbard
1130b656e5 Make the long-awaited change from $Id$ to $FreeBSD$
This will make a number of things easier in the future, as well as (finally!)
avoiding the Id-smashing problem which has plagued developers for so long.

Boy, I'm glad we're not using sup anymore.  This update would have been
insane otherwise.
1997-01-14 07:20:47 +00:00
Justin T. Gibbs
3d9ab968cd Re-enable reselections as the first thing after we see a bus free. We seem
to miss reselections from some devices and since the reselection response
timeout is only 200ns, enabling reselections too late may be the cause of our
problem.
1996-12-03 17:04:51 +00:00
Justin T. Gibbs
70f6e5521c Conditionally enable the busfree interrupt to catch unexpected busfrees.
Immediate SCBs, since they always send messages that tell the target to
transition to bus free now rely on the busfree interrupt instead of the
IMMEDDONE sequencer interrupt that was generated before.

Rearrange some code in the message out loop to give ATN a little more time
to drop before we ACK the last byte.

Use SPIORDY instead of REQINIT when snooping for a tag message on a reconnect.
This is done for the same reasons we use SPIORDY in the inb functions.

When going into BITBUCKET mode, turn off HDMAEN in the DFCNTRL register so
that we can "not care" what the value of HCNT is.  If HCNT is 0, BITBUCKET
mode won't transfer any data if HDMAEN is set.  Seeing as we don't want the
transfer to even think about touching the host, this seems more sane anyway.
Thanks to "Dan Willis" <dan@plutotech.com> for pointing out that this was
a problem.
1996-11-22 08:25:23 +00:00
Justin T. Gibbs
ad34debda8 Change the way Automatic PIO is performed in the mesgin and mesgout phases.
SPIORDY should go active on any REQ of the bus, so testing for REQINIT is
not necessary.  It also seems that testing for SPIORDY is more robust then
REQINIT since SPIORDY comes active after REQINIT and PHASEMIS seems to take
some time to come true after REQ is asserted if the phase has changed.  Of
course, none of this is documented.

This should give the code savings of my original changes, without breaking the
driver on fast peripherals.
1996-11-21 06:18:33 +00:00
Justin T. Gibbs
bde5245890 Assert that we have seen an identify or have not disconneccted since the
initial selection when entering the status phase.  This is the same assertion
we use for all the other data transfer phases.

Hopefully fix the hangs in the mesgin and mesgout phases that I introduced
last week during some code cleanup.  I need to get some of these 12MB/s
drives so I can reproduce these hangs here...

Add a pause disable in the SCB paging case around our manipulation of the
QOUTQCNT variable.  This is simply extra sanity.

Set LASTPHASE to P_BUSFREE once we see a busfree so that the kernel driver can
differentiate this from a data out phase.
1996-11-16 01:07:35 +00:00
Justin T. Gibbs
8220b8706a Fix two problems with SCB Paging.
1) get_free_or_disc_scb was not being passed its argument correctly
   in one case

2) Add protection in the form of the QOUTQCNT variable to prevent
   overflowing the QOUTFIFO.

This should make SCB Paging work.  Really, I mean it now. 8-)
1996-11-11 05:16:41 +00:00
Justin T. Gibbs
775395aaac index_untagged_scb should rely solely on the argument passed in SINDEX and
not access SCB_TCL directly.  This could have caused problems on twin channel
adapters.

2.2 Candidate.
1996-11-05 07:51:29 +00:00
Justin T. Gibbs
853925d190 In data_phase_reinit when I converted the code to use bcopy, I should have
used mvi instead of mov.  Luckily this code is most likely never executed
since it is only there for sanity should a target goes into the data phase
twice during a single selection or reselection.
1996-10-28 17:00:24 +00:00
Justin T. Gibbs
85772b6529 Fix problems dealing with non-tagged devices when SCB paging is enabled.
Mostly this involved changing the semantics of the findSCB routine so that
it could be used at times other than handling a reconnection.
1996-10-28 06:01:08 +00:00
Justin T. Gibbs
971791f48d Go back to using DMA to get SCBs down to the adapter.
SCB paging is now handled almost entirely by the sequencer and also uses
DMA.  This should make SCB paging at least an order of magnitude more
efficient and vastly simplifies the implementation.

Add a few space optimizations so this code still fits on aic7770 chips.

Update comments.
1996-10-25 06:34:59 +00:00
Justin T. Gibbs
2ea8799246 Bring aic7xxx driver bug fixes from 'SCSI' into current. 1996-10-06 16:38:45 +00:00
Justin T. Gibbs
1ffa43c082 Detect and report dataphase overruns. Put the adapter into 'Bit Bucket'
mode when this occurs and allow the target to complete the transaction.
Force a retry on overruns since they are usually caused by termination or
cable problems.
1996-06-09 17:33:18 +00:00
Justin T. Gibbs
1d40e2f2c5 Hopefully fix the parity problem and the hang on message reject for good. 1996-06-08 06:54:06 +00:00
Justin T. Gibbs
e5442bc690 Don't use the auto ATN on parity error feature. It may be the source
of our parity handling problems.
1996-05-31 06:30:15 +00:00
Justin T. Gibbs
e1ca90bc57 Fix regression. It seems that you need at least one instruction between
seeing SPIORDY and checking for PHASEMIS.  My last change turned out to
be less cosmetic then I thought.

Pointed out by: Satoshi Asami <asami@cs.berkeley.edu>,
		Faried Nawaz <fn@pain.csrv.uidaho.edu
1996-05-30 14:31:08 +00:00
Justin T. Gibbs
56981243dd Merge in changes for NetBSD/OpenBSD.
Cosmetic change to p_mesgout code so that it "looks" the same as what
is done in the inb* routines.
NetBSD/OpenBSD support Submitted by:Noriyuki Soda <soda@sra.co.jp>,
				    Pete Bentley <pete@demon.net>,
				    Charles M. Hannum <mycroft@mit.edu>,
				    Theo de Raadt <deraadt@theos.com>
1996-05-30 07:18:39 +00:00
Justin T. Gibbs
070d32b1a9 Fix a race condition in p_mesgout* and inb* code that could allow a
phasemiss to sneak by without detection.  This should fix the
Wide/Narrow boot problems that have been reported since this bug
caused the driver ignore a narrow target rejecting wide negotiation.
1996-05-27 23:16:55 +00:00
Justin T. Gibbs
087b79e649 Correct a botched commit from yesturday. It helps to bring over the
right patch file.<sigh>
1996-05-23 15:02:18 +00:00
Justin T. Gibbs
61538c3003 Enable/Disable Ultra mode on a per target basis. This allows the driver
to use the full range of settings from 3.6-20MHz on any target.
1996-05-21 18:32:23 +00:00
Justin T. Gibbs
c2278994ed aic7xxx.seq:
Change #ifdef linux to #ifdef __linux__

aic7xxx_reg.h:
Remove unneeded BOFF_60BCLOCKS
define CHIPRSTACK to be the same as CHIPRST
define RESET_SCSI and CHANNEL_B_PRIMARY bits
All of these aer used during the setup of adapters.
1996-05-10 16:11:03 +00:00
Justin T. Gibbs
0a44712261 Implement SCB paging. This allows up to 255 active commands on
aic7770 >= Rev E, aic7850, aic7860, aic7870, and ai7880 based controllers.

Make findSCB safer for non-tagged commands when tagged commands are
active on the controller.  The symptoms of this problem were
"Overlapped commands attempted" messages during error recovery
attempts.

Compact scratch ram usage.  This leaves 8 bytes free for future use.

Clean up some comments.

aic7xxx_reg.h:
Update my copyright.
1996-04-20 21:20:31 +00:00
Justin T. Gibbs
c2c5fd345d aic7xxx.seq:
Fix support for the aic7850 by looking only at the relavent bits of the
    QINCNT.  The 7850 puts random garbage in the high bits and all my attempts
    to determine the cause of this failed.  This approach does seem to work
    around the problem.

    Don't trust SCSIPERR to tell us when there is a parity error.  On
    some revs of the 7870 and the 7880, this bit follows the parity of
    the current byte.  Instead of using a SEQINT to tell the kernel,
    re-enable the standard parity error interrupt since it seems to pause
    the sequencer right at the time of the error which is the effect we were
    looking for anyway.

aic7xxx_reg.h:
    Remove PARITY_ERROR seqeuncer interrupt type, its no longer used.

    Define QCOUNTMASK as the SRAM location for the mask to use on the
    QINCNT register.  QCOUNTMASK is determined by the number of SCBs
    supported by the device we're working on.

aic7xxx_asm.c
    Properly check the return value of fopen, and define the arg list
    in getopt correctly.
    Submitted by: Pete Bentley <pete@demon.net>
1996-03-31 03:02:37 +00:00
Justin T. Gibbs
75f0b9d070 Reset the DMA control register whenever we reset the sequencer.
Clear LASTPHASE on busfree so the kernel driver can tell that the
   sequencer is idle.
Fix some comments to reflect reality.
1996-03-10 07:02:32 +00:00
Justin T. Gibbs
5327d59536 Performance optimizations. Unroll all bcopies. Use PIO to transfer SCBs
since setting up the DMA is too costly.  Restructure for efficiency.

Pause the sequencer when a parity error occurs so that the kernel driver
knows during which phase the error was encountered.
1996-01-29 03:12:06 +00:00