History log of /freebsd-9.3-release/sys/dev/aic7xxx/aic79xx.reg
Revision Date Author Comments
(<<< Hide modified files)
(Show modified files >>>)
# 267654 19-Jun-2014 gjb

Copy stable/9 to releng/9.3 as part of the 9.3-RELEASE cycle.

Approved by: re (implicit)
Sponsored by: The FreeBSD Foundation

# 225736 22-Sep-2011 kensmith

Copy head to stable/9 as part of 9.0-RELEASE release cycle.

Approved by: re (implicit)


# 210055 14-Jul-2010 gibbs

Correct logic bug in aicasm's undefined register bit access detection code.

The code in question verifies that all register write operations only change
bits that are defined (in the register definition file) for that effected
register. The bug effectively disabled this checking.

o Fix the check by testing the opcode against all supported read ("and" based)
operands.

o Add missing bit definitions to the aic7xxx and aic79xx register definition
files so that the warning (treated as a fatal error) does not spuriously
fire.

Reported by: Pawel Worach <pawel.worach@gmail.com>
MFC after: 1 week


# 139749 05-Jan-2005 imp

Start each of the license/copyright comments with /*-, minor shuffle of lines


# 133122 04-Aug-2004 gibbs

Correct a very rare case where command ordering could be compromised
by a transaction performing a driver handled message sequence (an
scb with the MK_MESSAGE flag set).

SCBs that perform host managed messaging must always be
at the head of their per-target selection queue so that
the firmware knows to manually assert ATN if the current
negotiation agreement is packetized. In the past we
guaranteed this by queuing these SCBs separarately in
the execution queue. This exposes the system to potential
command reordering in two cases:

1) Another SCB for the same ITL nexus is queued that does
not have the MK_MESSAGE flag set. This SCB will be
queued to the per-target list which can be serviced
before the MK_MESSAGE scb that preceeded it.

2) If the target cannot accept all of the commands in the
per-target selection queue in one selection, the remainder
is queued to the tail of the selection queues so as to
effect round-robin scheduling. This could allow the
MK_MESSAGE scb to be sent to the target before the
requeued commands.

This commit changes the firmware policy to defer queuing
MK_MESSAGE SCBs into the selection queues until this can
be done without affecting order. This means that the
target's selection queue is either empty, or the last
SCB on the execution queue is also a MK_MESSAGE SCB.
During any wait, the firmware halts the download of new
SCBs so only a single "holding location" is required.

Luckily, MK_MESSAGE SCBs are rare and typically occur only
during CAM's bus probe where only one command is outstanding
at a time. However, during some recovery scenarios, the
reordering *could* occur.

aic79xx.c:
Update ahd_search_qinfifo() and helper routines to
search for pending MK_MESSAGE scbs and properly
restitch the execution queue if either the MK_MESSAGE
SCB is being aborted, or the MK_MESSAGE SCB can be
queued due to the execution queue draining due to
aborts.

Enable LQOBUSFREE status to assert an interrupt.
This should be redundant since a BUSFREE interrupt
should always occur along with an LQOBUSFREE event,
but on the Rev A, this doesn't seem to be guaranteed.

When a PPR request is rejected when a previously
existing packetized agreement is in place, assume
that the target has been reset without our knowledge
and revert to async/narrow transfers. This corrects
two issues: the stale ENATNO setting that was used
to send the PPR is cleared so the firmware is not
confused by a future packetized selection with
ATN asserted but no MK_MESSAGE flag in the SCB and
it speeds up recovery by aborting any pending
packetized transactions that by definition are now
dead.

When re-queueing SCBs after a failed negotiation
attempt, ensure command ordering by freezing the
device queue first.

Traverse the list of pending SCBs rather than the
whole SCB array on the controller when pushing
MK_MESSAGE flag changes out to the controller.
The original code was optimized for the aic7xxx
controllers where there are fewer controller slots
then pending SCBs and the firmware picks SCB
slots. For the U320 controller, the hope is
that we have fewer pending SCBs then the 512
slots on the controller.

Enhance some diagnostics.

Factor out some common code.

aic79xx.h:
Add prototype for new ahd_done_with_status() that is
used to factor out some commone code.

aic79xx.reg:
Add definisions for the pending MK_MESSAGE SCB.

aic79xx.seq:
Defer MK_MESSAGE SCB queing to the execution queue
so as to preserve command ordering. Re-arrange some
of the selection processing code so the above change
had no performance impact on the common code path.

Close a few critical section holes.

When entering a non-packetized phase, manually enable
busfree interrupts, since the controller hardware
does not do this automatically.

aic79xx_inline.h:
Enhance logging for queued SCBs.

aic79xx_osm.c:
Add new a new DDB ahd command, ahd_dump, which
invokes the ahd_dump_card_state() routine on the
unit specified with the ahd_sunit DDB command.

aic79xx_pci.c:
Turn on the BUSFREEREV bug for the Rev B. controller.
This is required to close the busfree during non-packetized
phase hole.


# 129134 11-May-2004 gibbs

aic79xx.c:
Allow 500us between pauses in ahd_pause_and_flushwork().
The maximum we will wait is now 500ms.

In the same routine, remove any attempt to clear ENSELO.
Let the firmware do it once the current selection has
completed. This avoids some race conditions having to
do with non-packetized completions and the auto-clearing
of ENSELO on packetized completions.

Also avoid attempts to clear critical sections when
interrups are pending. We are going to loop again
anyway, so clearing critical sections is a waste of
time. It also may not be possible to clear a critical
section if the source of the interrupt was a SEQINT.

aic79xx_pci.c:
Use the Generic 9005 mask when looking for generic 7901B
parts. This allows the driver to attach to 7901B parts
on motherboards using a non-Adaptec subvendor ID.

aic79xx_inline.h:
Test for the SCBRAM_RD_BUG against the bugs
field, not the flags field in the softc.

aic79xx.c:
Cancel pending transactions on devices that
respond with a selection timeout. This decreases
the duration of timeout recovery when a device
disappears.

aic79xx.c:
Don't bother forcing renegotiation on a selection
timeout now that we use the device reset handler
to abort any pending commands on the target.
The device reset handler already takes us down
to async narrow and forces a renegotiation.

In the device reset handlers, only send a
BDR sent async event if the status is not
CAM_SEL_TIMEOUT. This avoids sending this
event in the selection timeout case

aic79xx.c:
Modify the Core timeout handler to verify that another
command has the potential to timeout before passing off
a command timeout as due to some other command. This
safety measure is added in response to a timeout recovery
failure on H2B where it appears that incoming reselection
status was lost during a drive pull test. In that case,
the recovery handler continued to wait for the command
that was active on the bus indefinetly. While the root
cause of the above issue is still being determined seems
a prudent safeguard.

aic79xx_pci.c:
Add a specific probe entry for the Dell OEM 39320(B).

aic79xx.c:
aic79xx.h:
aic79xx.reg:
aic79xx.seq:
Modify the aic79xx firmware to never cross a cacheline or
ADB boundary when DMA'ing completion entries to the host.
In PCI mode, at least in 32/33 configurations, the SCB
DMA engine may lose its place in the data-stream should
the target force a retry on something other than an
8byte aligned boundary. In PCI-X mode, we do this to
avoid split transactions since many chipsets seem to be
unable to format proper split completions to continue
the data transfer.

The above change allows us to drop our completion entries
from 8 bytes to 4. We were using 8 byte entries to ensure
that PCI retries could only occur on an 8byte aligned
boundary. Now that the sequencer guarantees this by splitting
up completions, we can safely drop the size to 4 bytes (2
byte tag, one byte SG_RESID, one byte pad).

Both the split-completion and PCI retry problems only show
up under high tag load when interrupt coalescing is being
especially effective. The switch from a 2byte completion
entry to an 8 byte entry to solve the PCI problem increased
the chance of incurring a split in PCI-X mode when multiple
transactions were completed at once. Dropping the completion
size to 4 bytes also means that we can complete more commands
in a single DMA (128byte FIFO -> 32 commands instead of 16).

aic79xx.c:
Modify the SCSIINT handler to defer clearing
sequencer critical sections to the individual
interrupt handlers. This allows us to
immediately disable any outgoing selections in
the case of an unexpected busfree so we don't
inadvertantly clear ENSELO *after* a new selection
has started. Doing so may cause the sequencer
to miss a successful selection.

In ahd_update_pending_scbs(), only clear ENSELO if
the bus is currently busy and a selection is not
already in progress or the sequencer has yet to
handle a pending selection. While we want to ensure
that the selection for the SCB at the head of the
selection queue is restarted so that any change in
negotiation request can take effect, we can't clobber
pending selection state without confusing the sequencer
into missing a selection.


# 125448 04-Feb-2004 gibbs

aic79xx.c:
aic79xx.seq:
Convert the COMPLETE_DMA_SCB list to an "stailq". This allows us to
safely keep the SCB that is currently being DMA'ed back the host on
the head of the list while processing completions off of the bus. The
newly completed SCBs are appended to the tail of the queue. In the
past, we just dequeued the SCB that was in flight from the list, but
this could result in a lost completion should the host perform certain
types of error recovery that must cancel all in-flight SCB DMA operations.

Switch from using a 16bit completion entry, holding just the tag and the
completion valid bit, to a 64bit completion entry that also contains a
"status packet valid" indicator. This solves two problems:
o The SCB DMA engine on at least Rev B. silicon does not properly deal
with a PCI disconnect that occurs at a non-64bit aligned offset in the
chips "source buffer". When the transfer is resumed, the DMA engine
continues at the correct offset, but may wrap to the head of the buffer
causing duplicate completions to be reported to the host. By using a
completion buffer in host memory that is 64bit aligned and using 64bit
completion entries, such disconnects should only occur at aligned addresses.
This assumes that the host bridge will only disconnect on cache-line
boundaries and that cache-lines are multpiles of 64bits.

o By embedding the status information in the completion entry we can avoid
an extra memory reference to the HSCB for commands that complete without
error.

Use the comparison of a "host freeze count" and a "sequencer freeze count"
to allow the host to process most SCBs that complete with non-zero status
without having to clear critical sections. Instead the host can just pause the
sequencer, performs any necessary cleanup in the waiting for selection list,
increments its freeze count on the controller, and unpauses. This is only
possible because the sequencer defers completions of SCBs with bad status
until after all pending selections have completed. The sequencer then avoids
referencing any data structures the host may touch during completion of the
SCB until the freeze counts match.

aic79xx.c:
Change the strategy for allocating our sentinal HSCB for the QINFIFO. In
the past, this allocation was tacked onto the QOUTFIFO allocation. Now that
the qoutfifo has grown to accomodate larger completion entries, the old
approach will result in a 64byte allocation that costs an extra page of
coherent memory. We now do this extra allocation via ahd_alloc_scbs()
where the "unused space" can be used to allocate "normal" HSCBs.

In our packetized busfree handler, use the ENSELO bit to differentiate
between packetized and non-packetized unexpected busfree events that
occur just after selection, but before the sequencer has had the oportunity
to service the selection.

When cleaning out the waiting for selection list, use the SCSI mode
instead of the command channel mode. The SCB pointer in the command
channel mode may be referenced by the SCB dma engine even while the
sequencer is paused, whereas the SCSI mode SCB pointer is only accessed
by the sequencer.

Print the "complete on qfreeze" sequencer SCB completion list in
ahd_dump_card_state(). This list holds all SCB completions that are deferred
until a pending select-out qfreeze event has taken effect.

aic79xx.h:
Add definitions and structures to handle the new SCB completion scheme.

Add a controller flag that indicates if the controller is in HostRAID
mode.

aic79xx.reg:
Remove macros used for toggling from one data fifo mode to the other.
They have not been in use for some time.

Add scratch ram fields for our new qfreeze count scheme, converting
the complete dma list into an "stailq", and providing for the "complete
on qfreeze" SCB completion list. Some other fields were moved to retain
proper field alignment (alignment >= field size in bytes).

aic79xx.seq:
Add code to our idle loop to:
o Process deferred completions once a qfreeze event has taken full
effect.
o Thaw the queue once the sequencer and host qfreeze counts match.

Generate 64bit completion entries passing the SCB_SGPTR field as the
"good status" indicator. The first bit in this field is only set if
we have a valid status packet to send to the host.

Convert the COMPLETE_DMA_SCB list to an "stailq".

When using "setjmp" to register an idle loop handler, do not combine
the "ret" with the block move to pop the stack address in the same
instruction. At least on the A, this results in a return to the setjmp
caller, not to the new address at the top of the stack. Since we want
the latter (we want the newly registered handler to only be invoked from
the idle loop), we must use a separate ret instruction.

Add a few missing critical sections.

Close a race condition that can occur on Rev A. silicon. If both FIFOs
happen to be allocated before the sequencer has a chance to service the
FIFO that was allocated first, we must take special care to service the
FIFO that is not active on the SCSI bus first. This guarantees that a
FIFO will be freed to handle any snapshot requests for the FIFO that is
still on the bus. Chosing the incorrect FIFO will result in deadlock.

Update comments.

aic79xx_inline.h
Correct the offset calculation for the syncing of our qoutfifo.

Update ahd_check_cmdcmpltqueues() for the larger completion entries.

aic79xx_pci.c:
Attach to HostRAID controllers by default. In the future I may add a
sysctl to modify the behavior, but since FreeBSD does not have any
HostRAID drivers, failing to attach just results in more email and
bug reports for the author.

MFC After: 1week


# 116142 10-Jun-2003 gibbs

Sync perforce IDs.


# 115407 30-May-2003 scottl

Fix a reported case of severe data corruption:

aic79xx.h:
aic79xx.reg:
Return the SCB_TAG field to 16byte alignment.
It seems that on some PCI systems, SCBs are not
transferred correctly to the controller with
the previous placement of the SCB_TAG field.

Approved by: re (rwatson)


# 115335 26-May-2003 gibbs

Correct/Simplify ignore wide residue message handling

aic79xx.c:
In ahd_handle_ign_wide_residue():
o Use SCB_XFERLEN_ODD SCB field to determine transfer
"oddness" rather than the DATA_COUNT_ODD logic.
SCB_XFERLEN_ODD is toggled on every ignore wide
residue message so that multiple ignore wide residue
messages for the same transaction are properly supported.
o If the sg list has been exausted, the sequencer
doesn't bother to update the residual data count
since it is known to be zero. Perform the zeroing
manually before calculating the remaining data count.
o Use multibyte in/out macros instead of shifting/masking
by hand.

aic79xx_inline.h:
In ahd_setup_scb_common(), setup the SCB_XFERLEN_ODD field.

aic79xx.reg:
Use the SCB_TASK_ATTRIBUTE field as a bit field in the
non-packetized case. We currently only define one bit,
SCB_XFERLEN_ODD.

Remove the ODD_SEG bit field that was used to carry the odd
transfer length information through the SG cache. This
is obviated by SCB_XFERLEN_ODD field.

Remove the DATA_COUNT_ODD scratch ram byte that was used
dynamicaly compute data transfer oddness. This is obviated
by SCB_XFERLEN_ODD field.

aic79xx.seq:
Remove all updates to the DATA_COUNT_ODD scratch ram field.
Remove all uses of ODD_SEG. These two save quite a few
sequencer instructions.

Use SCB_XFERLEN_ODD to validate the end of transfer
ignore wide residue message case.


# 115329 26-May-2003 gibbs

Fixup spelling of "coalesce" and derivatives.

Approved by: RE


# 114623 03-May-2003 gibbs

Correct spelling errors.

Switch to handling bad SCSI status as a sequencer interrupt
instead of having the kernel proccess these failures via
the completion queue. This is done because:

o The old scheme required us to pause the sequencer and clear
critical sections for each SCB. It seems that these pause
actions, if coincident with a sequencer FIFO interrupt, would
result in a FIFO interrupt getting lost or directing to the
wrong FIFO. This caused hangs when the driver was stressed
under high "queue full" loads.
o The completion code assumed that it was always called with
the sequencer running. This may not be the case in timeout
processing where completions occur manually via
ahd_pause_and_flushwork().
o With this scheme, the extra expense of clearing critical
sections is avoided since the sequencer will only self pause
once all pending selections have cleared and it is not in
a critical section.

aic79xx.c
Add code to handle the new BAD_SCB_STATUS sequencer
interrupt code. This just redirects the SCB through
the already existing ahd_complete_scb() code path.
Remove code in ahd_handle_scsi_status() that paused
the sequencer, made sure that no selections where
pending, and cleared critical sections. Bad
status SCBs are now only processed when all of these
conditions are true.

aic79xx.reg:
Add the BAD_SCB_STATUS sequencer interrupt code.

aic79xx.seq:
When completing an SCB upload to the host, if
we are doing this because the SCB contains non-zero
SCSI status, defer completing the SCB until there
are no pending selection events. When completing
these SCBs, use the new BAD_SCB_STATUS sequencer
interrupt. For all other uploaded SCBs (currently
only for underruns), the SCB is completed via the
normal done queue. Additionally, keep the SCB that
is currently being uploaded on the COMPLETE_DMA_SCB
list until the dma is completed, not just until the
DMA is started. This ensures that the DMA is restarted
properly should the host disable the DMA transfer for
some reason.

In our RevA workaround for Maxtor drives, guard against
the host pausing us while trying to pause I/O until the
first data-valid REQ by clearing the current snapshot
so that we can tell if the transfer has completed prior
to us noticing the REQINIT status.

In cfg4data_intr, shave off an instruction before getting
the data path running by adding an entrypoint to the
overrun handler to also increment the FIFO use count.

In the overrun handler, be sure to clear our LONGJMP
address in both exit paths.

Perform a few sequencer optimizations.

aic79xx.c:
Print the full path from the SCB when a packetized
status overrun occurs.

Remove references to LONGJMP_SCB which is being
removed from firmware usage.

Print the new SCB_FIFO_USE_COUNT field in the
per-SCB section of ahd_dump_card_state(). The
SCB_TAG field is now re-used by the sequencer,
so it no longer makes sense to reference this
field in the kernel driver.

aic79xx.h:
Re-arrange fields in the hardware SCB from largest
size type to smallest. This makes it easier to
move fields without changing field alignment.

The hardware scb tag field is now down near the
"spare" portion of the SCB to facilitate reuse
by the sequencer.

aic79xx.reg:
Remove LONGJMP_ADDR.

Rearrange SCB fields to match aic79xx.h.
Add SCB_FIFO_USE_COUNT as the first byte
of the SCB_TAG field.

aic79xx.seq:
Add a per-SCB "Fifos in use count" field and use
it to determine when it is safe (all data posted)
to deliver status back to the host. The old method
involved polling one or both FIFOs to verify that
the current task did not have pending data. This
makes running down the GSFIFO very cheap, so we
will empty the GSFIFO in one idle loop pass in
all cases.

Use this simplification of the completion process
to prune down the data FIFO teardown sequencer for
packetized transfers. Much more code is now shared
between the data residual and transfer complete cases.

Correct some issues in the packetized status handler.
It used to be possible to CLRCHN our FIFO before status
had fully transferred to the host. We also failed to
handle NONPACKREQ phases that could occur should a CRC
error occur during transmission of the status data packet.

Correct a few big endian issues:

aic79xx.c:
aic79xx_inline.h:
aic79xx_pci.c:
aic79xx_osm.c:
o Always get the SCB's tag via the SCB_GET_TAG acccessor
o Add missing use of byte swapping macros when touching
hscb fields.
o Don't double swap SEEPROM data when it is printed.
Correct a big-endian bug. We cannot assign a
o When assigning a 32bit LE variable to a 64bit LE
variable, we must be explict about how the words
of the 64bit LE variable are initialized. Cast to
(uint32_t*) to do this.

aic79xx.c:
In ahd_clear_critical_section(), hit CRLSCSIINT
after restoring the interrupt masks to avoid what
appears to be a glitch on SCSIINT. Any real SCSIINT
status will be persistent and will immidiately
reset SCSIINT. This clear should only get rid of
spurious SCSIINTs.

This glitch was the cause of the "Unexpected PKT busfree"
status that occurred under high queue full loads

Call ahd_fini_scbdata() after shutdown so that
any ahd_chip_init() routine that might access
SCB data will not access free'd memory.

Reset the bus on an IOERR since the chip doesn't
seem to reset to the new voltage level without
this.

Change offset calculation for scatter gather maps
so that the calculation is correct if an integral
multiple of sg lists does not fit in the allocation
size.

Adjust bus dma tag for data buffers based on 39BIT
addressing flag in our softc.

Use the QFREEZE count to simplify ahd_pause_and_flushworkd().
We can thus rely on the sequencer eventually clearing ENSELO.

In ahd_abort_scbs(), fix a bug that could potentially
corrupt sequencer state. The saved SCB was being
restored in the SCSI mode instead of the saved mode.
It turns out that the SCB did not need to be saved at all
as the scbptr is already restored by all subroutines
called during this function that modify that register.

aic79xx.c:
aic79xx.h:
aic79xx_pci.c:
Add support for parsing the seeprom vital product
data. The VPD data are currently unused.

aic79xx.h:
aic79xx.seq:
aic79xx_pci.c:
Add a firmware workaround to make the LED blink
brighter during packetized operations on the H2A.

aic79xx_inline.h:
The host does not use timer interrupts, so don't
gate our decision on whether or not to unpause
the sequencer on whether or not a timer interrupt
is pending.


# 112641 25-Mar-2003 scottl

aic79xx.reg:
Correct default precompensation value for RevA hardware.


# 111653 27-Feb-2003 gibbs

aic79xx.c:
Clear the LQICRC_NLQ status should it pop up after we have
already handled the SCSIPERR. During some streaming operations
this status can be delayed until the stream ends. Without this
change, the driver would complain about a "Missing case in
ahd_handle_scsiint".

In the LQOBUSFREE handler...

Don't return the LQOMGR back to the idle state until after
we have cleaned up ENSELO and any status related to this
selection. The last thing we need is the LQO manager starting
another select-out before we have updated the execution queue.
It is not clear whether the LQOMGR would, or would not
start a new selection early.

Make sure ENSELO is off prior to clearing SELDO by flushing
device writes.

Move assignment of the next target SCB pointer inside of
an if to make the code clearer. The effect is the same.

Dump card state in both "Unexpected PKT busfree" paths.

In ahd_reset(), set the chip to SCSI mode before reading SXFRCTL1.
That register only exists in the SCSI mode. Also set the mode
explicitly to the SCSI mode after chip reset due to paranoia.
Re-arrange code so that SXFRCTL1 is restored as quickly after the
chip reset as possible.

S/G structurs must be 8byte aligned. Make this official by saying
so in our DMA tag.

Disable CIO bus stretch on MDFFSTAT if SHVALID is about to come
true. This can cause a CIO bus lockup if a PCI or PCI-X error
occurs while the stretch is occurring - the host cannot service
the PCI-X error since the CIO bus is locked out and SHVALID will
never resolve. The stretch was added in the Rev B to simplify the
wait for SHVALID to resolve, but the code to do this in the open
source sequencer is so simple it was never removed.

Consistently use MAX_OFFSET for the user max syncrate set from
non-volatile storage. This ensures that the offset does not
conflict with AH?_OFFSET_UNKNOWN.

Have ahd_pause_and_flushwork set the mode to ensure that it has
access to the registers it checks. Also modify the checking of
intstat so that the check against 0xFF can actually succeed if
the INT_PEND mask is something other than 0xFF. Although there
are no cardbus U320 controllers, this check may be needed to
recover from a hot-plug PCI removal that occurs without informing
the driver.

Fix a typo. sg_prefetch_cnt -> sg_prefetch_align. This fixes
an infinite loop at card initialization if the cacheline size is 0.

aic79xx.h:
Add AHD_EARLY_REQ_BUG bug flag.

Fix spelling errors.

Include the CDB's length just after the CDB pointer in the DMA'ed
CDB case.

Change AH?_OFFSET_UNKNOWN to 0xFF. This is a value that the
curr->offset can never be, unlike '0' which we previously used.
This fixes code that only checks for a non-zero offset to
determine if a sync negotiation is required since it will fire
in the unknown case even if the goal is async.

aic79xx.reg:
Add comments for LQISTAT bits indicating their names in the 7902
data book. We use slightly different and more descriptive names
in the firmware.

Fix spelling errors.

Include the CDB's length just after the CDB pointer in the DMA'ed
CDB case.

aic79xx.seq:
Update comments regarding rundown of the GSFIFO to reflect reality.

Fix spelling errors.

Since we use an 8byte address and 1 byte length, shorten the size
of a block move for the legacy DMA'ed CDB case from 11 to 9 bytes.

Remove code that, assuming the abort pending feature worked, would
set MK_MESSAGE in the SCB's control byte on completion to catch
invalid reselections. Since we don't see interrupts for completed
selections, this status update could occur prior to us noticing the
SELDO. The "select-out" queue logic will get confused by the
MK_MESSAGE bit being set as this is used to catch packatized
connections where we select-out with ATN. Since the abort pending
feature doesn't work on any released controllers yet, this code was
never executed.

Add support for the AHD_EARLY_REQ_BUG. Don't ignore persistent REQ
assertions just because they were asserted within the bus settle delay
window. This allows us to tolerate devices like the GEM318 that
violate the SCSI spec.

Remove unintentional settnig of SG_CACHE_AVAIL. Writing this bit
should have no effect, but who knows...

On the Rev A, we must wait for HDMAENACK before loading additional
segments to avoid clobbering the address of the first segment in
the S/G FIFO. This resolves data-corruption issues with certain
IBM (now Hitachi) and Fujitsu U320 drives.

Rearrange calc_residual to avoid an extra jmp instruction.

On RevA Silicon, if the target returns us to data-out after we
have already trained for data-out, it is possible for us to
transition the free running clock to data-valid before the required
100ns P1 setup time (8 P1 assertions in fast-160 mode). This will
only happen if this L-Q is a continuation of a data transfer for
which we have already prefetched data into our FIFO (LQ/Data
followed by LQ/Data for the same write transaction). This can
cause some target implementations to miss the first few data
transfers on the bus. We detect this situation by noticing that
this is the first data transfer after an LQ (LQIWORKONLQ true),
that the data transfer is a continuation of a transfer already
setup in our FIFO (SAVEPTRS interrupt), and that the transaction
is a write (DIRECTION set in DFCNTRL). The delay is performed by
disabling SCSIEN until we see the first REQ from the target.

Only compile in snapshot savepointers handler for RevA silicon
where it is enabled.

Handle the cfg4icmd packetized interrupt. We just need to load
the address and count, start the DMA, and CLRCHN once the transfer
is complete.

Fix an oversight in the overrun handler for packetized status
operations. We need to wait for either CTXTDONE or an overrun
when checking for an overrun. The previous code did not wait
and thus could decide that no overrun had occurred even though
an overrun will occur on the next data-valid req. Add some
comment to this section for clarity.

Use LAST_SEG_DONE instead of LASTSDONE for testing transfer
completion in the packetized status case. LASTSDONE may come up
more quickly since it only records completion on the SCSI side,
but since LAST_SEG_DONE is used everywhere else (and needs to be),
this is less confusing.

Add a missing invalidation of the longjmp address in the non-pack
handler. This code needs additional review.

aic79xx_inline.h:
Fix spelling error.

aic79xx_osm.c:
Set the cdb length for CDBs dma'ed from host memory.

Add a comment indicating that, should CAM start supporting cdbs
larger than 16bytes, the driver could store the CDB in the status
buffer.

aic79xx_pci.c:
Add a table entry for the 39320A.

Added a missing comma to an error string table.

Fix spelling errors.


# 109709 22-Jan-2003 gibbs

Revert AHD_TIMER_MAX_US to its original definition now that the
ahc and ahd modules have correct dependencies on the assembler.


# 109628 21-Jan-2003 phk

Bandaid to make the kernel compile until the scsi-crew can find out what
is happening.


# 109588 20-Jan-2003 gibbs

aic79xx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.

Save and restore the NEGOADDR address when setting
new transfer settings. The sequencer performs lookups
in the negotiation table too and it expects NEGOADDR
to remain consistent across pause/unpause sessions.

Consistently use "offset" instead of "period" to determine
if we are running sync or not.

Add a SHOW_MESSAGES diagnostic for when we assert ATN
during message processing.

Print out IU, QAS, and RTI features when showing transfer options.

Limit the syncrate after all option conformance
changes have taken place in ahd_devlimited_syncrate.
Changes in options may change the final syncrate we
accept.

Keep a copy of the hs_mailbox in our softc so that
we can perform read/modify/write operations on the
hs_mailbox without having to pause the sequencer to
read the last written value. Use the ENINT_COALESS
flag in the hs_mailbox to toggle interrupt coalessing.

Add entrypoints for enabling interrupt coalessing and
setting both a timeout (how long to wait for commands
to be coalessed) and a maximum commands to coaless value.
Add a statistics timer that decides when to enable or
disable interrupt coalessing based on load.

Add a routine, ahd_reset_cmds_pending() which is used
to update the CMDS_PENDING sequencer variable whenever
error recovery compeltes SCBs without notifying the
sequencer. Since ahd_reset_cmds_pending is called
during ahd_unpause() only if we've aborted SCBs, its
call to ahd_flush_qoutfifo should not cause recursion
through ahd_run_qoutfifo(). A panic has been added to
ensure that this recursion does not occur.

In ahd_search_qinfifo, update the CMDS_PENDING sequencer
variable directly. ahd_search_qinififo can be called
in situations where using ahd_reset_cmds_pending() might
cause recursion. Since we can safely determine the
exact number to reduce CMDS_PENDING by in this scenario
without running the qoutfifo, the manual update is sufficient.

Clean up diagnostics.
Add ahd_flush_qoutfifo() which will run the qoutfifo
as well as complete any commands sitting on the
sequencer's COMPLETE_SCB lists or the good status FIFO.
Use this routine in several places that did similar
things in an add-hoc, but incomplete, fashion. A call
to this routine was also added to ahd_abort_scbs() to
close a race.

In ahd_pause_and_flushwork() only return once selections
are safely disabled. Flush all completed commands via
ahd_flush_qoutfifo().

Remove "Now packetized" diagnostic now that this
information is incorperated into the actual negotiation
messages that are displayed.

When forcing renegotiation, don't clober the current
ppr_options. Much of the driver uses this information
to determine if we are currently packetized or not.

Remove some stray spaces at column 1 in ahd_set_tags.

When complaining about getting a host message loop
request with no pending messages, print out the
SCB_CONTROL register down on the card.

Modify the ahd_sent_msg() routine to handle a search
for an outgoing identify message. Use this to detect
a msg reject on an identify message which typically
indicates that the target thought we were packetized.
Force a renegotiation in this case.

In ahd_search_qinfifo(), wait more effectively for SCB
DMA activities to cease. We also disable SCB fetch
operations since we are about to change the qinfifo
and any fetch in progress will likely be invalidated.

In ahd_qinfifo_count(), fix the qinfifo empty case.

In ahd_dump_card_state(), print out CCSCBCTL in the
correct mode.

If we are a narrow controller, don't set the current
width to unknown when forcing a future negotiation.
This just confuses the code into attempting a wide
negotiation on a narrow bus.

Add support for task management function completions.

Modify ahd_handle_devreset so that it can handle
lun resets in addition to target resets. Use
ahd_handle_devreset for lun and target reset task
management functions.

Handle the abort task TMF race case better. We now
wait until any current selections are over and then
set the TMF back to zero. This should cause the sequencer
to ignore the abort TMF completion should it occur.

Correct a bug in the illegal phase handler that
caused us to drop down to narrow when handling the
unexpected command phase case after 3rd party
reset of a packetized device.

Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.

aic79xx.h:
Add coalessing and HS_MAILBOX fields.

Add per-softc variables for the stats "daemon".

Add a debug option for interrupt coalessing activities.

Add two new softc flags:
o AHD_UPDATE_PEND_CMDS
Run ahd_reset_cmds_pending() on the next unpause.

o AHD_RUNNING_QOUTFIFO
Used to catch recursion through ahd_run_qoutfifo().

aic79xx.reg:
Correct register addresses related to the software timer
and the DFDBCTL register.

Add constants paramaterizing the software timer.

Add scratch ram locations for storing interrupt coalessing
tunables.

Break INTMASK in SEQITNCTL out into INTMASK1 and INTMASK2.
In at least the REV A, these are writable bits. We make
use of that for a swtimer workaround in the sequencer.

Since HS_MAILBOX autoclears, provide a sequencer variable
to store its contents.

Add SEQINT codes for handling task management completions.

aic79xx.seq:
Correct ignore wide residue processing check for
a wide negotiation being in effect. We must be
in the SCSI register window in order to access the
negotiation table.

Use the software timer and a commands completed count to
implement interrupt coalessing. The command complete is
deferred until either the maximum command threshold or a
the expiration of a command deferral timer. If we have
more SCBs to complete to the host (sitting in COMPLETE_SCB
lists), always try to coaless them up to our coalessing limit.
If coalessing is enabled, but we have fewer commands oustanting
than the host's min coalessing limit, complete the command
immediately.

Add code to track the number of commands outstanding.
Commands are outstanding from the time they are placed
into the execution queue until the DMA to post completion
is setup.

Add a workaround for intvec_2 interrupts on the H2A4.
In H2A4, the mode pointer is not saved for intvec2, but
is restored on iret. This can lead to the restoration
of a bogus mode ptr. Manually clear the intmask bits and
do a normal return to compensate. We use intvec_2 to
track interrupt coalessing timeouts.

Since we cannot disable the swtimer's countdown, simply
mask its interrupt once we no longer care about it firing.

In idle_loop_cchan, update LOCAL_HS_MAILBOX everytime
we are notified of an HS_MAILBOX update via the
HS_MAILBOX_ACT bit in QOFF_CTLSTA. We have to use a
local copy of persistant portions of the HS_MAILBOX as
the mailbox auto-clears on any read.

Move the test for the cfg4istat interrupt up an instruction
to hopefully close a race between the next outgoing selection
and our disabling of selections.

Add a missing ret to the last instruction in load_overrun_buf.

Add notifications to the host of task management
completions as well as the completions for commands
that completed successfully before their corresponding
TMF could be sent.

Hold a critical section during select-out processing
until we have a fully identified connection. This
removes a race condition with the legacy abort handler.

Correct a few spelling errors in some comments.

aic79xx_inline.h:
Call ahd_reset_cmds_pending() in ahd_unpause if required.

Update cmdcmplt interrupt statistics in our interrupt
handler.

Allow callers to ahd_send_scb() to set the task management
function.

aic79xx_pci.c:
Disable SERR and pause the controller prior to performing
our mmapped I/O test. The U320 controllers do not support
"auto-access-pause".

aic79xx_osm.c:
Set the task management function now that
ahd_send_scb() doesn't do it for us. We
also perform a lun reset in response to BDR
requests to packetized devices.


# 107623 04-Dec-2002 scottl

Last minute fixes to ahc and ahd:

ahd_pci.c:
Retrieve the allow_memio hint from the resource manager to
determine whether or not to try PCI MEMIO.

aic79xx_osm.h:
aic7xxx_osm.h:
Don't wrongly abuse the callout_reset() interface when trying
to abuse timeouts generated from the CAM layer. This fixes the
console freeze and lost timeout problem that many have reported,
especially on SMP systems.

aic79xx_pci.c
aic7xxx_pci.c
Rewrite the MEMIO test routine to prevent certain broken chipsets
from trying to burst multiple DWORDs to the registers. Also make
the routine better detect byte merging by the host bridge and
deal with it.

aic79xx.reg:
Correct an incorrect register definition.

Approved by: re (rwatson, jhb)


# 107441 01-Dec-2002 scottl

Major update to the ahd driver to fix many bugs found in the previous
version, plus add support for the new features found in the Rev B
version of the chip. The changelog is quite long and can be provided
on request. Major features include vastly improved protocol violation
handling, full support for the 7902 Rev B, better parity error
handling, and better packetized overrun handling, to name a few.

Approved by: re (blanket)


# 104023 26-Sep-2002 gibbs

Upgrade to version 1.1 of the aic79xx U320 driver.

aic79xx.c:
o Remove redundant ahd_update_modes() call.
o Correct panic in diagnostic should state corruption cause
the SCB Id to be invalid during a selection timeout.
o Add workaround for missing BUSFREEREV feature in Rev A silicon.
o Corect formatting nits.
o Use register pretty printing in more places.
o Save and restore our SCB pointer when updating the waiting queue
list for an "expected" LQ-out busfree.
o In ahd_clear_intstat, deal with the missing autoclear in the
CLRLQO* registers.
o BE fixup in a diagnostic printf.
o Make sure that we are in the proper mode before disabling
selections in ahd_update_pending_scbs.
o Add more diagnostics.
o task_attribute_nonpkt_tag -> task_attribute: we don't need a
nonpkt_tag field anymore for allowing all 512 SCBs to be
used in non-packetized connections.
o Negotiate HOLD_MCS to U320 devices.
o Add a few additional mode assertions.
o Restore the chip mode after clearing out the qinfifo so that
code using ahd_abort_scbs sees a consistent mode.
o Simplify the DMA engine shutdown routine prior to performing
a bus reset.
o Perform the sequencer restart after a chip reset prior to
setting up our timer to poll for the reset to be complete.
On some OSes, the timer could actually pre-empt us and order
is important here.
o Have our "reset poller" set the expected mode since there is
no guarantee of what mode will be in force when we are called
from the OS timer.
o Save and restore the SCB pointer in ahd_dump_card_state(). This
routine must not modify card state.
o Ditto for ahd_dump_scbs().

aic79xx.h:
o Add a few more chip bug definitions.
o Align our tag on a 32bit boundary.

aic79xx.reg:
aic79xx.seq:
o Start work on removing workarounds for Rev B.
o Use a special location in scratch from for stroring
our SCBPTR during legacy FIFO allocations. This corrects
problems in mixed packetized/non-packetized configurations
where calling into a FIFO task corrupted our SCBPTR.
o Don't rely on DMA priority to guarantee that all data in
our FIFOs will flush prior to a command completion notification
going out of the command channel. We've never seen this assumption
fail, but better safe than sorry.
o Deal with missing BUSFREEREV feature in H2A.
o Simplify disconnect list code now that the list will always
have only a single entry.
o Implement the AHD_REG_SLOW_SETTLE_BUG workaround.
o Swith to using "REG_ISR" for local mode scratch during
our ISR.
o Add a missing jmp to the data_group_dma_loop after our
data pointers have been re-initialized by the kernel.
o Correct test in the bitbucket code so that we actually
wait for the bitbucket to complete before signaling the
kernel of the overrun condition.
o Reposition pkt_saveptrs to avoid a jmp instruction.
o Update a comment to reflect that the code now waits for
a FIFO to drain prior to issuing a CLRCHN.

aic79xx_inline.h:
o Remove unused untagged queue handling code.
o Don't attempt to htole64 what could be a 32bit value.

aic79xx_pci.c:
o Set additional bug flags for rev A chips.


# 102681 31-Aug-2002 gibbs

Convert to new assembler field syntax.

Add preliminary Rev B definitions.

Add QOUTFIFO_ENTRY_VALID_TAG for new qoufifo scheme.

Reserve SCB space for large luns.


# 97883 05-Jun-2002 gibbs

Enter the ahd driver which supports the Adaptec AIC7902 Ultra320, PCI-X
SCSI Controller chip.