aic7xxx_pci.c:
When performing our register test, be careful
to avoid resetting the chip when pausing the
controller. The test reads the HCNTRL register
and then writes it back with the PAUSE bit
explicitly set. If the last write to the controller
before our probe is to reset it, the CHIPRST
bit will still be set, so we must mask it off
before the PAUSE operation. On some chip versions,
we cannot access registers for a few 100us after
a reset, so this inadvertant reset was causing PCI
errors to occur on the read to check for paused
status.
Submitted by: gibbs
Add two new arguments to bus_dma_tag_create(): lockfunc and lockfuncarg.
Lockfunc allows a driver to provide a function for managing its locking
semantics while using busdma. At the moment, this is used for the
asynchronous busdma_swi and callback mechanism. Two lockfunc implementations
are provided: busdma_lock_mutex() performs standard mutex operations on the
mutex that is specified from lockfuncarg. dftl_lock() is a panic
implementation and is defaulted to when NULL, NULL are passed to
bus_dma_tag_create(). The only time that NULL, NULL should ever be used is
when the driver ensures that bus_dmamap_load() will not be deferred.
Drivers that do not provide their own locking can pass
busdma_lock_mutex,&Giant args in order to preserve the former behaviour.
sparc64 and powerpc do not provide real busdma_swi functions, so this is
largely a noop on those platforms. The busdma_swi on is64 is not properly
locked yet, so warnings will be emitted on this platform when busdma
callback deferrals happen.
If anyone gets panics or warnings from dflt_lock() being called, please
let me know right away.
Reviewed by: tmm, gibbs
have completed across the bus but not to the host before
processing of an exception condition (busfree, bus reset,
etc.). When flushing the controller of completed commands,
we also look for packetized commands that have completed
with good status and are stored in the "good status fifo".
The hardware will post to the good status fifo even if
data for that command is still active in a FIFO. In
one particular failure case, a command outstanding on the
bus reconnected, transferred data into a FIFO, and provided
good status while the host driver was processing an expected
busfree event (PPR message negotiation). This resulted in
an entry in the good status fifo that we completed, but
since the sequencer was paused, the data in the data FIFO
for this command had never been transferred to the host.
Once the busfree processing was complete, the sequencer
was unpaused, and the data completed its transfer to the
host. In some instances, the client for the data was notified
of the completion and attempted to view the data before
it arrived. This case only occurred during FreeBSD's
multi-target probe of the SCSI bus while some devices are
negotiating to go packetized and some devices are already
running in packetized.
The fix is to run and FIFOs active with a context in the
good status fifo to completion before completing the command
to the SCSI layer. This requies duplicating the FIFO rundown
operations in the host driver that would usually be handled
by the firmware, but there is no other alternative.
Don't blindly shutdown the SCB dma engine when restarting
the sequencer. We may be killing an operation that is
not supposed to be cancelled. The cases where we need to
shutdown these dma engines are already handled elsewhere in
the driver.
Fix a few more ahd_in?() -> ahd_in?_scbram() instances.
Add softc flag to indicate that we have seen at
least one selection since the last bus reset or
SE/LVD bus change.
aic79xx.c:
Fix a few style nits.
In ahd_update_pending_scbs(), only touch card registers
once we have found an SCB that needs to be updated.
This removes lots of clutter from PCI traces taken of
error recovery performed by the driver.
Short circuit the first selection iocell workaround handler
if we've run once since the last bus reset or iocell change.
This also removes clutter from PCI traces.
Note if completions are pending in the qoutfifo when we dump
card state.
Add a comment in ahd_clear_critical_sections() about
our need to leave ENBUSFREE set in SIMODE1 while single
stepping.
Re-arrange some delay loops so that we always perform
a read after any register write and before the delay.
This should make the delay loop more accurate.
When completing message processing for a packetized
commention, return the controller to a state where
invalid non-packetized phases will still cause protocol
violations. These are the same operations as those
performed in the clear_target_state routine in the
firmware.
Now that we have a chip with working ABORTPENDING
support (the 7901B), comment out the automatic use
of this feature until we can adequately test it.
The previous checkin updated the bug mask for the
7901B so this code was exercised.
When resetting the bus, perform an ahd_flush_device_writes()
call so that our reset assertion delay is acurately
timed from when the reset bit is written to the controller.
Remove an old comment that no longer applies.
Fix a jump in our unexpected non-packetized phase
handler to use an explicit lable. The old code
had a hardcoded jump offset that was off by one
instruction.
Add a 7901A specific feature definition.
aic79xx_pci.c:
Split out the general aic790X setup into it's own
setup handler that works on single and dual controllers.
Adjust all other PCI setup handlers to initialize the
chips basic features and type before calling the generic
handler.
Turn off a few Rev B workarounds that are not required
on the 7901B.
of the contents of the CCSCBCTL register into our
local varaible. The other bits are used in later tests.
This avoids a potential deadlock in ahd_run_qoutfifo()
if we happen to catch the DMA engine in just the right
state.
Devices below may experience a change in geometry.
* Due to a bug, aic(4) never used extended geometry. Changes all drives
>1G to now use extended translation.
* sbp(4) drives exactly 1 GB in size now no longer use extended geometry.
* umass(4) drives exactly 1 GB in size now no longer use extended geometry.
For all other controllers in this commit, this should be a no-op.
Looked over by: scottl
if it was already enabled. We don't want to set it
when it shouldn't be set, we just don't want to
inadvertantly turn it off. This should fix a recent
report of the aic7xxx driver repeatedly complaining of
"unexpected busfree while idle" in one configuration.
successfully mapping our registers. This
avoids the disabling of memory mapped I/O
just because some other driver probe happened
to touch our registers.
This drive delays going async after receiving a WDTR
message. We now send an SDTR message after a WDTR even
if our goal is to go async. This should work even for
confused devices.
If we get an unexpected busfree when attempting a WDTR
or SDTR, only set the goal negotiation parameters we were
trying to negotiate to off. This means that should a WDTR
message fail, we will still try an SDTR if our goal is
non-async.
Fix a few more places where we were looking at goal.period
instead of goal.offset for determining if we should be
negotiating sync. This should not have any impact on
our behavior, but the offset is more definitive and should
be used.
aic79xx.c:
aic79xx.h:
aic79xx_pci.c:
aic7xxx.c:
aic7xxx.h:
aic7xxx_pci.c:
Switch ah?_reset() to take an additional "reinit" argument.
Use this instead of init_level to determin if the chip
should be fully reinitialized after a chip reset. This
is required so that ah?_shutdown() can reset the chip
without side-effects.
aic79xx.c:
Implement ahd_suspend() and ahd_resume().
aic7xxx.c:
Change ahc_loadseq() to *not* restart the sequencer.
This brings the loadseq behavior in line with that
of the 7902 driver and also simplifies the init routine.
Correct the resume routine to enable interrupts and
restart the sequencer.
Use the special LUNLEN_SINGLE_LEVEL constant for
post Rev A4 hardware for single byte luns. Without
this change, Rev B hardware would place the single
byte of lun data in byte 0 of the lun structure when
it should be in byte 1. Since there are few if any
devices on the market that support multiple luns in
target mode, the corrupted lun field (which was only
corrupted for non-zero luns) wasn't hurting us.
Approved by: re (rwatson)
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)
BUS_DMASYNC_ definitions remain as before. The does not change the ABI,
and reverts the API to be a bit more compatible and flexible. This has
survived a full 'make universe'.
Approved by: re (bmah)
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.
aic7xxx.c:
In ahc_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 Ensure that SG_LIST_NULL is cleared in the
residual sg pointer for "mid-transfer" ignore
wide residue cases.
o Use multibyte in/out macros instead of shifting/masking
by hand.
aic7xxx.h:
Modify the SCB_GET_LUN() macro to mask the lun hardware
SCB field with LID. This leaves two bits in the LUN
field that can be used for other purposes.
aic7xxx.reg:
Change LID to be 0x3F. This is the maximum supported
lun size for non-packetized SCSI. Map the top bit
of the lun to SCB_XFERLEN_ODD. The host must set
this bit whenever a transfer is an odd length.
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.
aic7xxx.seq:
Be more careful in our handling of the SCB_LUN field. It
must be masked with LID if only lun information is desired.
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.
aic7xxx_inline.h:
In ahc_queue_scb(), setup the SCB_XFERLEN_ODD field.
Approved by: RE
FAILDIS in the SEQCTL register, not the HCNTRL register.
aic7xxx.c:
Remeber SEQCTL settings in the "seqctl" field of our
softc. seqctl defaults to just having FASTMODE set,
but the bus attachments can override this.
aic7xxx.h:
Add the seqctl softc field.
aic7xxx_pci.c:
Update the seqctl softc field and manually update SEQCTL
when to many PCI errors occur
Approved by: RE
to be more efficient by having the sequencer copy the
single byte of valid lun data into the long lun field.
aic79xx.c:
Memset our hardware SCB to 0 so that untouched
fields don't confuse diagnostic output. With the
old method for handling the Rev A bug, if the long
lun field was not 0, this could result in bogus
lun information being sent to drives.
Use the same SCB transfer size for all chip types
now that the long lun is not DMA'ed to the chip.
aic79xx.seq:
Add code to copy lun information for Rev.A hardware.
aic79xx_inline.h:
Remove host update of the long_lun field on every
packetized command.
Sort IDs based on chip type.
Remove IROC IDs. We'll switch to using the IROC masks
if/when we want to start attaching to IROC controllers.
Approved by: RE
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.
aic7xxx.h:
Split out core chip initialization into ahc_chip_init().
This will allow us to reset the chip correctly at times
other than initial chip setup.
aic7770.c
aic7xxx_pci.c:
Flesh out bus chip init methods for our two
bus attachments and use these, in addition to
bus suspend/resume hooks to get the core in
better shape for handling these events.
When disabling PCI parity error checking, use FAILDIS.
Although the chip docs indicate that clearing PERRESPEN
should also work, it does not.
Auto-disable pci parity error checking after informing
the user of AHC_PCI_TARGET_PERR_THRESH number of parity
errors observed as a target.
aic7xxx.h:
aic7xxx_pci.c
aic7770.c
aic7xxx.c
Add the instruction_ram_size softc field.
Remove the now unused stack_size softc field.
Modify ahc_loadseq to return a failure code
and to actually check the downloaded instruction
count against the limit set in our softc.
Modify callers of ahc_loadseq to handle load
failures as appropriate.
Set instruction RAM sizes for each chip type.
aic7xxx_pci.c:
Add some delay in the aic785X termination
control code. This may fix problems with
the 2930.
Be consistent in how we access config space
registers. 16bit registers are accessed using
16bit ops.
aic7xxx.c:
Correct spelling errors.
Have ahc_force_renegotiation() take a devinfo as is done
in the U320 driver. Use this argument to correct a bug
in the selection timeout handler where we forced a renegotiation
with the last device that had set SAVED_SCSIID. SAVED_SCSIID
is only updated once a selection is *sucessfull* and so is
stale for any selection timeout.
Cleanup the setup of the devinfo for busfree events. We
now use this devinfo for a call to ahc_force_renegotiation()
at the bottom of the routine, so it must be initialized in
all cases.
In ahc_pause_and_flushwork(), adjust the loop so that it
will exit in the hot-eject case even if the INT_PEND mask
is something other than 0xFF (as it is in this driver).
Correct a wrapping string constant.
Call ahc_fini_scbdata() after shutdown so that
any ahc_chip_init() routine that might access
SCB data will not access free'd memory.
Correctly setup our buffer tag to indicate that 39bit
addressing is available if in 39bit addressing mode.
Rearrange some variable declarations based on
type size.
aic7xxx.c
aic7xxx.h:
aic7xxx.reg:
Consistently use MAX_OFFSET for the user max syncrate
set from non-volatile storage. This ensures that the
offset does not conflict with AHC_OFFSET_UNKNOWN.
Change AHC_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.
Change MAX_OFFSET to 0x7f which is the max
offset U160 aic7xxx controllers can negotiate.
This ensures that curr->offset will not
match AHC_OFFSET_UNKNOWN.
aic7xxx_inline.h:
Have our inline interrupt handler return with a value
indicating whether we serviced a real interrupt. This
is required for Linux support.
Return earlier if the interrupt is not for us.
Include read streaming in the PPR flags we display in diagnostics.
In ahd_reset(), set the known mode after our initial pause prior to
setting the mode. We can't just set the mode directly because the
current mode, after the pause, is most likely unknown and setting the
mode when the saved mode is unknown will trigger an assertion in
the mode debug code.
Complete an audit for SCB RAM reads. These reads must be performed
via the special ahd_in?_scbram() methods so we can perform a
Rev A. PCI-X workaround.
Remove a superfluous mode save operation that was performed just
prior to a call to ahd_clear_critical_section(). The saved mode
was never restored and wouldn't have been valid anyway since the
mode could change while single stepping out of a critical section.
aic79xx.h:
Add new BUG definition AHD_PCIX_SCBRAM_RD_BUG.
aic79xx_inline.h:
Update ahd_inb_scbram routine to check for AHD_PCIX_SCBRAM_RD_BUG
and only apply the workaround if this bug is active. The old code
applied the workaround in all cases.
aic79xx_pci.c:
Set AHD_PCIX_SCBRAM_RD_BUG for the A4.
Remove an attempted saved_modes call in ahd_pci_test_register_access().
Saving the modes can only occur when we are paused, but the call was
happening before the chip was known to be paused. Restoring the
modes doesn't make sense either since the code makes no assumptions
about the state of the sequencer until the first time the mode is set
by the driver. This happens after the registers are successfully
mapped.
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.
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.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.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
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.
Use BUS_SPACE_MAXSIZE_32BIT for the parent dma tags, and
(NSEGS - 1) * PAGE_SIZE for the data buffer tags. FreeBSD/sparc64 is
more strict about checking these values that other arches.
labels are acurate in relation to a fully compiled
sequencer program (all patches downloaded). Correct
a few occurances of a relative jump across a macro
that ended up jumping us into the last instruction
of the macro.
Spproved by: re (bmah)
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)
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)
HP -> CPQ
Rearrange IDs to better match which chips they use.
Convert to uniform product description strings.
Simplify 7901A setup function.
Add the NONPACKFIFO_BUG and PACED_NEGTABLE_BUG entries
for the A.
Add rev B bugs and features.
The double write workaround for CURRSCB is only required if
abort pending is set. Remove this work around and set the
abort pending bug bit on the B at least until we have better
confirmation that the double write is always safe.
Add updated H2B identifiers
Move IOCell paramters into softc and add a hook for the
OSM to modify these as well as other settings prior to
committing them to the chip.
SLEW -> SLEWRATE
PREQDIS in DEVCONFIG1 went away after the A2.
Remove all code that references this bit. This
is especially important since this bit was reused
in the B for a different HW fix workaround.
Properly set the AHD_NEW_IOCELL_OPTS and
AHD_NEW_DFCNTRL_OPTS features for the B.
Remove stray/random extra 7901A generic PCI
table entry. Also switch the correct 7901A
generic entry to use ID_ALL_MASK since we
can only differentiate the 7901A from the
7902 by checking for a "type field" of 0xE.
Set AHD_INTCOLLISIONT_BUG for the Rev B.
Set the PREQDIS bit in DEVCONFIG1 for the B. The
bit is misnamed, but seems to disable a work-around
that breaks on the B on PCI busses.
Add a routine for testing memory mapped register access.
This will hopefully detect things like buggy via chipsets
so that the OSM can fallback to using I/O mapped access
when memory mapped I/O simply will not work.
Approved by: re (blanket)
diagnostic "Setting Mode" messages.
Use a read of HCNTRL to flush our write to CLRCMDCMPLT
on the RevB. This allows us to check to see if the sequencer
is paused and to initiate the interrupt collision workaround
without incuring an extra read.
Approved by: re (blanket)
PCI-X only workarounds are automatically masked out
if we are operating in PCI mode.
Make use of ahd_pci_test_register_access()
Approved by: re (blanket)
Move IOCell paramters into softc and add a hook for the
OSM to modify these as well as other settings prior to
committing them to the chip.
Approved by: re (blanket)
aic7xxx.c:
aic7xxx.h:
aic7xxx.reg:
aic7xxx.seq:
Bring in the protocol violation handler from the U320
driver and replace the NO_IDENT sequencer interrupt code
with the PROTO_VIOLATION code. Support for this code
required the following changes:
SEQ_FLAGS:
IDENTIFY_SEEN -> NOT_IDENTIFIED
Added NO_CDB_SENT
SCB_CONTROL:
TARGET_SCB == STATUS_RCVD for initiator mode
scb->flags:
Added SCB_TARGET_SCB since we cannot rely on
TARGET_SCB as a target/initiator differentiator
due to it being overloaded in initiator mode to
indicate that status has been received.
aic7xxx.seq:
Move data fifo CLRCHN to mesgin_rdptrs which is a safer
location for doing this operation. This also saves a
sequencer instruction.
aic7xxx.c:
aic7xxx.h:
Change ahc/ahd_upate_neg_request() to take a "negotiation
type" enum that allows us to negotiate:
o only if the goal and current parameters differ.
o only if the goal is non-async
o always - even if the negotiation will be for async.
aic7xxx.seq:
Reset the FIFO whenever a short CDB transfer occurs
so that the FIFO contents do not corrupt a future CDB
transfer retry.
Add support for catching the various protocol violations
handled by ahc_handle_protocol_violation.
Reformat some comments.
aic7xxx.c:
aic7xxx.h:
Just for safety, have the aic7xxx driver probe
the stack depth.
aic7xxx.c:
aic7xxx.h:
Save and restore stack contents during diagnostics.
Some chip variants overwrite stale entries on a
stack "pop".
Don't use 0 to probe the stack depth. 0 is the typical
value used to backfill the stack if entries are overwritten
on a "pop".
aic7xxx.h:
Add a missing typedef.
Collapse SCB flag entries so they are bit contiguous.
Add AHD_ULTRA2_XFER_PERIOD for narrow fallback calculations
aic7xxx.c:
Don't panic (as a diagnostic to catch bugs) if we decided to
force the renegotiation of async even if we believe we are
already async. This should allow us to negotiate async instead
of the full user goal rate during startup if bus resets are
disabled.
Add a space to the end of the ahc/ahd_print_devinfo routines
so that it behaves as expected by the code that uses it.
Only force a renegotiation on a selection timeout
if the SCB was valid. Doing otherwise may be dangerous
as the connection was not valid for an unknown reason.
Add additional diagnostic output to ahc_dump_card_state(),
and have it use the register pretty printing functions.
Update ahc_reg_print() to handle a NULL cur_col.
Add a newline to ahc_dump_card_state() output.
Bring back "use_ppr". We need to use_ppr anytime
doppr is true or we have non-zero protocol options.
The later case was not handled in the recent removal
of use_ppr.
Move a comment and remove a useless clearing of use_ppr.
Don't disable ENBUSFREE when single stepping on
a DT capable controller. We cannot re-enable unexpected
busfree detection, so we must clear BUSFREE on each
step instead.
Correct the lookup of the SCB ID in ahc_handle_proto_error.
Remove a diagnostic printf.
Remove unecessary restoration of the STACK for older
chips.
Approved by: re (blanket)
This will hopefully detect things like buggy via chipsets
so that the OSM can fallback to using I/O mapped access
when memory mapped I/O simply will not work.
Approved by: re (blanket)
AHC_ALLOW_MEMIO is set, or the hint hint.ahc.N.allow_memio=1 is
set in the bootloader.
Make use of ah?_pci_test_register_access().
Approved by: re (blanket)
aicasm_gram.y:
Use a direct move from allzeros to emulate a
mvi of 0.
aicasm_insformat.h:
sync $Id$
aicasm_symbol.c:
Minor header change.
Approved by: re (blanket)
alpha. This will take the file out of sync with the private version
that we maintain, but alpha tinderbox has been broken for too long.
Tested on: i386, sparc64, alpha
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.
This ensures that we don't enter our interrupt handler until
all OSM components it might reference have been fully initialized
during attach.
Remove vestiges of untagged queue handling.
Add hints to ahd_get_scb() so it knows what type of SCB collision
management to perform for each new transaction.
Properly disable/enable IU_REQ with changes in tagged queuing and
disconnection settings passed in by CAM.
Uninline some routines that are just too big to be inlined.
Add some helper macros for SCB ID collision management.
Use a hardware SCB rather than a full SCB for the "next
SCB to queue" sentinal.
Update for new "high SCBID bit" qoutfifo delivery scheme.
If interrupts are disabled on the card, don't bother running
our interrupt handler. Our handler was called due to a shared
interrupt, and the card's interrupts are explicitly disabled
to prevent entry into our interrupt handler.
functions for register pretty-printing.
Implement "top bit of SCBID is valid bit" qoutfifo delivery scheme.
"the the" -> "the".
Remove old and never used tag collision chain handling in the
sequencer. Tag collisions are never allowed to get as far as
on the controller.
Simplify busy target table handling routines.
Update comments to reflect reality.
Add support for catching more protocol violations.
Correct a bug in data fifo handling in mixed packetized and
non-packetized environments. SG_STATE must be cleared even
if an SG fetch is not in progress at the time of FIFO shutdown
or we may confuse the non-packetized transaction idle-loop.
busy target table addressing changes, our qoufifo scheme,
and long lun support.
Drop bus reset hold delay to 25us.
Remove chip workarounds for revisions that never went to
production.
Add aic7901A identification information.
Remove untagged queue logic.
Push protocol violation handler to its own routine. We now
properly detect and recovery from the following target induced
protocol violations:
o Unexpected or invalid non-packetized Relesection
o Command complete with no status message
o Good Status after incomplete cdb transfer
Add an SCB collision avoidance algorithm that allows us to
use all 512 SCBs for non-packetized operations. There is
still the possibility of running out of SCBs with non-colliding
tag identifiers, but the algorithm ensures that the stall will
be rare and short lived.
Convert to a read-only algorithm for validing entries in the
qoufifo. The sequencer now toggles the high bit of the SCB
identifier on each wrap around of the qinfifo. If the high
bit doesn't match the expected value for this pass of the
qoufifo, the entry is not valid. This has the benefit of
working on machines that have large granularity cache write
back semantics without requiring any additional memory.
Remove lots of code related to untagged SCB queues. Since
these controllers can keep a fully busy target table, we
will never have untagged SCB queues.
Lots of improvements to diagnostic logging.
Clarify some comments.
Don't clear BUSFREE interrupt enable in SIMODE1 in the SELTO
handler. Just clearing the interrupt status is sufficient and
this avoids the chance of disabling busfree detection in connection
that occurs while we are handling the busfree interrupt.
Clear all possible interrupt sources when handling a busfree
interrupt. The hardware clears some but not all of them.
Don't panic if we get into the default SCSIINT handler.
Dump the card state and clear all interrupt sources in the
hope that we can continue.
LASTPHASE != PREVPHASE. Use the correct PREVPHASE for testing
against values in the PERRDIAG register.
According to SPI4, the bus free that is required after certain
PPR negotiations will only occur at the end of all message phases.
Handle the bus free if it occurs after a transaction in either
the message-in or message-out phases. The busfree can also occur
if the status of IU_REQ changes due to a WDTR or SDTR message.
We now set the expect busfree flag in ahd_set_syncrate so that
it works regardless of message type.
Correct a problem with missing certain busfree events. The
chip supports single-stepping even if a SCSIINT is pending.
This obviates the need to clear all of the SCSI interrupt enables
prior to single stepping. Since ENBUSFREE can only be disabled
manually and not re-enabled, avoiding touching this bit in the
single-step case yields reliable bus free detection.
Enhance ahd_clear_intstat to clear all SCSIINT sources.
Only use ahd_update_pending_scbs() if we are active on the
bus. We cannot modify the "MK_MESSAGE" bits on SCBs in the
execution queue if a selection might be in process since
the sequencer uses this bit to detect PPR negotiation to
a target with an outstanding IU_REQ agreement.
Allocate the SCB delivery mechansim's sentinal SCB specially
so we don't waste a valid SCB for this task.
Move tranceive state settle logic to ahd_chip_init() since
this needs to occur after every chip reset, not just the
chip reset that happens during primary driver initialization.
Correct a bug with transmitting lun information in packetized
connections.
Restrict busy target table operations to the range of luns
that can be used for non-packetized connections. Larger luns
can only be accessed in packetized mode.
Correct a busy target table addressing bug.
Be more careful about how we shutdown the DMA engines during
bus reset events.
Only freeze the SIMQ once regardless of the number of bus
reset events that occur while we are polling for the resets
to stop.
Don't rely on the sequencer remaining paused() during our
reset poll. It is safe for the sequencer to run during this
time, and many callers to the bus reset code would need to
be modified to make this assumption universally true.
Even if we are not going to clobber SCB state when an auto-request
sense SCB has a check condition, we must still unfreeze the queue.
Re-arrange the BAD STATUS handler to handle this case appropriately.
Modify the SCB download size depending on whether long luns are
being stored in the SCB.
Add ahd_print_register() for pretty printing register diagnostics.
Don't trust that the flexport logic to detect the presence of
a seeprom is available. It may not be on some motherboard
implementations.
"the the" -> "the"
our interrupt handler. Our handler was called due to a shared
interrupt, and the card's interrupts are explicitly disabled
to prevent entry into our interrupt handler.
Set the AHC_LSCBS_ENABLED softc flag appropriately.
Convert to using softc storage for our seeprom data.
Break seeprom parsing out into a separate routine.
Change our policy in regards to AHC_SPIOCAP so that we
will allow auto-termination to take place on some aic7855
based cards.
Remove initialized but never really used variables.
Use "offset == 0" not "period == 0" to denote async trasnfers.
Implement TARG_IMMEDIATE_SCB non-disconnected target mode
SCB delivery scheme.
In our timeout handler, don't rely on the phase already being
set to denote an active connection. IDENTIFY_SEEN is more
than sufficient.
Verify that the softc passed in ahc_detach is still known
to the driver before blindly using it.
functions for register pretty-printing.
Only clear SELDO once we've recorded enough information for
the host to understand that the connection is valid. The
host uses the SELDO status as a handshake to close this
race window.
Correct a bug in target mode handling of non-disconnected
transactions. The host would indicate the correct SCB to
DMA by setting the SCB id in the currently selected hardware
SCB. Unfortunately, we would then immediated allocate a
hardware SCB which, depending on the access patern might not
be the same hardware SCB that the host setup for us. Avoid
this by having the host put the SCBID into scratch ram.
Document the SXFRCTL2 register found on U2 and U160 controllers.
Overload the MWI_RESIDUAL field for use as the SCB to be downloaded
for "immediate" (or those without the disconnect privledge)
transactions.
Add scratch ram locations for the 274X that give us a bit more
information including whether to enable extended translation.
value slipped in from a debugging session.
Add AHC_LSCBS_ENABLED and AHC_SCB_CONFIG_USED ahc_flags which
allow for some code to move to the core.
Remove extern for ahc_syncrates[]. The OSMs no longer need
direct access to this array.
Add serial eeprom field to the ahc softc.
Prototype ahc_search_untagged_queues() and ahc_print_register().
Convert to AHC_SHOW_XXX debug option format.
Switch to using the same AHC_SHOW_XXX format as the ahd driver.
Always give the target a MSG_INITIATOR_DET_ERR for unexpected
DT or ST phase errors.
Add AHC_SHOW_SELTO diagnostics.
Force renegotiation whenever an unexpected bus free occurs
to rule out a negotiation mismatch as the cause for the error.
Use "offset != 0" as an intenal indicator of "async" rather than
using a period of 0.
In ahc_fetch_devinfo(), correct a bug in getting "our id" as
target. We weren't looking at all the SEQ_FLAGS that indicate
that we are still in a selected rather than reselected state.
Add support for the AHC_SHOW_MESSAGES debugging option.
If ahc_parse_msg() tells us to terminate the message loop,
do so without acking the message. The message may be one
that the sequencer needs to handle on its own.
In ahc_parse_msg() return MSGLOOP_TERMINATED for all messages
the sequencer handles.
Allocate storage for, and track, seeprom contents in our softc.
Touch all SCB bytes to avoid parity errors should one of our
debugging routines read an otherwise uninitiatlized byte.
S/G lists must be 8 byte aligned. Reflect this in our DMA tag.
"the the" -> "the" in a comment
When pausing the card to perform error recovery, ensure that we
are not in the process of being selected or have just been selected
but have not yet handled that selection. This leaves only one other
race window, in the command complete handler, that needs to be fixed
to make recovery 100% bullet proof.
Convert a few straglers from bsd u_intX_t to inttypes uintX_t.
Remove unused variables.
Split out searching of the untagged holding queues to its own
routine. In certain recovery scenarios, we want to just
remove entries in the untagged queue without touching related
transactions that are in the QINFIFO or WAITING queues that are
searched by ahc_search_qinfifo().
Add an implementation of the ahc_print_register() routine which
"pretty prints" registers. The extra bloat in the form of string
tables for this feature is controlled by the AHC_REG_PRETTY_PRINT
option.
Fix a few bugs in ahc_enable_lun() that could prevent controllers
lacking the multiple-target-id feature from changing "our id" on
the fly. Add a large comment to this section while I'm here
describing the restrictions on "id switching".
Honor the extended translation setting for EISA cards now that
I've determined where this information is kept.
Defer card interrupt enabling to the OSM since it may have
some initialization to perform that must occur before interrupts
can be enabled.
ahc_eisa.c:
ahc_pci.c:
Conform to new aic7xxx IRQ API.
Adapt to aic7xxx_freebsd -> aic7xxx_osm changes.
aic7770.c:
Disable card generated interrupt early in our probe for
"extra safety"
Commonize some seeprom code with the PCI side of the driver.
aic7xxx.c:
Correctly initialize a few scratch ram locations during
a sequencer restart. This avoids spurious sequencer ram
parity errors in some configurations.
Include the softc in ahc_update_residual calls. We need it
for some diagnostics in this code path.
Flag a data overrun on an auto-request sense failure as a
CAM_AUTOSENSE_FAIL rather than a CAM_DATA_RUN_ERR.
Force a renegotiation after noticing a parity error. This
covers targets that lose our negotiation settings but don't
bother to give us a unit attention condition. This can happen
if a target fails during a reselection of us during a cable
pull.
Convert some code to using constants.
Fix some typos.
Correct target mode message loop handling. ahc_clear_msg_state
was not clearing the "need to go to message out phase" bit once
our loop was over.
Simplify some abort handling code.
Include tag information in target mode immediate notify events.
When shutting down EISA controllers, don't EISA BIOS settings in
the high portions of scratch ram. This fixes warm boot issues on
some systems.
Save a bit of space by only allocating the SCBs that we can use.
Avoid some code paths in ahc_abort_scbs() if we are currently
acting as a target.
Correctly cleanup stranded SCBs in the card's SCB array. These
are SCBs who's mapping has already been torn down by code that
aborted the SCB by seeing it in another list first.
Add a comment about some potential bus reset issues for target
mode on Twin (EISA only) controllers.
aic7xxx.h:
Cleanup the hardware scb definitions a bit.
Allocate a ful 256 byte scb mapping index. This simplifies
the lookup code since the table covers all possible (and potentially
bogus) values.
Make AHC_DEBUG work again.
aic7xxx.reg:
Updates to hardware SCB definition.
New definitions for target mode fixes.
aic7xxx.seq:
In target mode, initialize SAVED_LUN just after we receive
the identify message. It may be required in the error recovery
path when a normal cdb packet (includes lun) is not sent up to
the host for processing.
Respond to irregular messages during a selection in target mode.
Defer looking for space for a cdb packet until we are about to
enter command phase. We want to be able to handle irregular messages
even if we would otherwise return QUEUE_FULL or BUSY.
Add support for sending Ignore Wide Residue messages as a target.
In the disable disconnect case in target mode, set our transfer
rate correctly once data are availble.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Add the ability to write and erase the seeprom.
aic7xxx_inline.h:
Correct Big Endian handling of large cdb sizes (> 12 bytes).
Adaptec to changes in the calc_residual API.
Correct a target mode bug where we always attempted to service
the input queue even if no progress could be made due to lack
of ATIOs.
aic7xxx_osm.c:
Adaptec to new IRQ mapping API. The new API allows the core
to only enable our IRQ mapping once it is safe (sufficient
initialization) to do so.
Slap bootverbose protection around some diagnostics.
Only attempt DT phases if we are wide.
aic7xxx_osm.h:
Enable big endian support.
Adjust for IRQ API change.
aic7xxx_pci.c:
Be more careful about relying on subvendor 9005 information.
We now only trust it for HBAs. This should allow the driver
to attach to some MBs where the subvendor/device information
does not follow the Adaptec spec.
Only enable interrupts on the card once we are fully setup.
Disable external SCB ram usage on the aic7895. I have not
been able to make it 100% reliable.
Adjust to seeprom routines being properly prefixed with "ahc".
Fix a few bugs in the external SCB ram probing routine. We
need to clear any parity errors we've triggered during the
probe to avoid future, fatal, interrupts.
If we detect an invalid cable combination, pretent there are
no cable at all. This will enable all of the terminators
which is probably the safest configuration we can "guess".
MFC after: 4 days
should be initialized to 0 for PCI adapters which was a side-effect of
the memset in ahc_alloc(). EISA/VL adapters require our unpause value to
include the "levelness" of our interrupt.
This change allows EISA adapters to work again.
PR: 29689, 29471
Correct an off by one in our critical section handling.
SEQADDR always reads the next instruction to execute,
so we must subtract one from its value before making
comparisons with entries in the critical section table.
Print a few additional registers whenever we dump
card state.
Show the SCB_CONTROL and SCB_TAG values for all pending
SCBs in card SCB ram when dumping card state.
aic7xxx.seq:
Fix a bug introduced while optimizing the SDPTR path.
We would ack the SDPTR message twice on Ultra2 or better
chips if it occurred after all data had been transferred
for a transaction.
Change our workaround for the PCI2.1 retry bug on some
chips. Although the previous workaround was logically
correct, its faster method of draining the FIFO seemed
to occassionally confuse the FIFO state. We now drain
the FIFO at half the speed which avoids the problem.
aic7xxx_pci.c:
Chips with the PCI 2.1 retry bug can't handle a 16byte
cachesize. If the cachesize is set to 16bytes, drop
it to 0.
If bus_dma will give us addresses > 32 bits, setup our dma tag
to accept up to 39bit addresses.
aic7770.c:
Update the softc directly rather than use an intermediate
"probe_config" structure.
aic7xxx.c:
Complete core work to support 39bit addresses for bulk data
dma operations. Controller data structures still must reside
under the 4GB boundary to reduce code/data size in the sequencer
and related data structures. This has been tested under Linux
IA64 and will be tested on IA64 for FreeBSD as soon as our port
can run there.
Add bus dmamap synchronization calls around manipulation of
all controller/kernel shared host data structures.
Implement data pointer reinitialation for a second data phase
in a single connection in the kernel rather than bloat the
sequencer. This is an extremely rare operation (does it ever
happen?) and the sequencer implementation was flawed for some
of the newest chips.
Don't ever allow our target role to initiate a PPR. This
is forbidden by the SCSI spec.
Add a few missing endian conversions in the ignore wide pointers
code. The core has been tested on the PPC under Linux and should
work for FreeBSD PPC. As soon as I can test the OSM layer for
FreeBSD PPC, I will.
Move some of ahc_softc_init() into ahc_alloc() now that the
probe_config structure is gone.
Add a 4GB boundary condition on all of our dma tags. 32bit
DAC under PCI only works on a single 4GB "page". Although
we can cross 4GB on a true 64bit bus, the card won't always
be installed in one and we can save code space and cost in
implementing high address support by assuming the high DWORD
address will never change.
Add diagnostics to ahc_search_qinfifo().
Correct a target mode issue with bus resets. To avoid an
interrupt storm from a malicious third party holding the
reset line, the sequencer would defer re-enabling the reset
interrupt until either a select-out or select-in. Unfortunately,
the select-in enable bit is cleared by a bus reset, so a second
reset will render the card deaf to an initiator's attempts to
contact it. We now re-enable bus reset interrupts immediately
if the target role is enabled.
aic7xxx.h:
Remove struct ahc_probe_config.
SCB's now contain a pointer to the sg_map_node so we can perfrom
bus dma sync operations on the SG list prior to queuing a command.
aic7xxx.reg:
Register the Perforce ID for this file with the VERSION keyword
so it is printed in generated files.
Add the DSCOMMAND1 register which is used to access the high
DWORD of address bits.
Add the data pointer reinitialize sequencer interrupt code.
aic7xxx.seq:
Register the Perforce ID for this file with the VERSION keyword
so it is printed in generated files.
Remove code to re-enable the bus reset interrupt after a select-in.
In target mode we cannot defer this operation as ENSELI is cleared
by a bus reset.
Complete 39bit support.
Generate a sequencer inteerrupt rather than handle the data
pointers re-initialitation in the sequencer.
Inline the "seen identify" assertion to save a few cycles.
Short circuit the update of our residual data if we have
fully completed a transfer. The residual is correct from
our last S/G load operation.
Short circuit full SDPTR processing if the residual is 0.
Just mark the transfer as complete.
aic7xxx_93cx6.c:
Synchronize perforce IDs.
aic7xxx_freebsd.c:
Complete untested 39bit support.
Add missing endia conversions.
Clear our residuals prior to starting a command. The
update residual code in the core only sets the residual
if there is one.
aic7xxx_freebsd.h:
Modeify ahc_dmamap_sync() macros to take an offset and a length.
This is how sync operations are performed in NetBSD, and we should
update our bus dma implementation to match.
aic7xxx_inline.h:
Add data structure synchronization helper functions.
Fix a bug in ahc_intr() where we would not clear our unsolicited
interrupt counter after running our PCI interrupt handler. This
may have been the cause of the spurious PCI interrupt messages.
aic7xxx_pci.c:
Adjust for loss of probe_config structure.
Guard against bogus 9005 subdevice information as seen on some
IBM MB configurations.
Add 39bit address support.
MFC after: 10 days
and outputing them in generated files.
Fixed a few other scanner bugs that for some reason didn't show up until
these modifications were made.
MFC after: 10 days
ahc_pci.c:
Prepare for making ahc a module by adding module dependency
and version info.
aic7770.c:
Remove linux header ifdefs. The headers are handled differently
in Linux where local includes (those using "'s instead of <>'s)
are allowed.
Don't map our interrupt until after we are fully setup to
handle interrupts. Our interrupt line may be shared so
an interrupt could occur at any time.
aic7xxx.c:
Remove linux header ifdefs.
current->curr to avoid Linux's use of current as a
#define for the current task on some architectures.
Add a helper function, ahc_assert_atn(), for use in
message phases we handle manually. This hides the fact
that U160 chips with the expected phase matching disabled
need to have SCSISIGO updated differently.
if (ahc_check_residual(scb) != 0)
ahc_calc_residual(scb);
else
ahc_set_residual(scb, 0);
becomes:
ahc_update_residual(scb);
Modify scsi parity error (or CRC error) handling to
reflect expected phase being disabled on U160 chips.
Move SELTO handling above BUSFREE handling so we can
use the new busfree interrupt behavior on U160 chips.
In ahc_build_transfer_msg() filter the period and ppr_options
prior to deciding whether a PPR message is required.
ppr_options may be forced to zero which will effect our
decision.
Correct a long standing but latent bug in ahc_find_syncrate().
We could choose a DT only rate even though DT transfers were
disabled. In the CAM environment this was unlikely as CAM
filters our rate to a non-DT value if the device does not
support such rates.
When displaing controller characteristics, include the
speed of the chip. This way we can modify the transfer
speed based on optional features that are enabled/disabled
in a particular application.
Add support for switching from fully blown tagged queing
to just using simple queue tags should the device reject
an ordered tag.
Remove per-target "current" disconnect and tag queuing
enable flags. These should be per-device and are not
referenced internally be the driver, so we let the OSM
track this state if it needs to.
Use SCSI-3 message terminology.
aic7xxx.h:
The real 7850 does not support Ultra modes, but there are
several cards that use the generic 7850 PCI ID even though
they are using an Ultra capable chip (7859/7860). We start
out with the AHC_ULTRA feature set and then check the
DEVSTATUS register to determine if the capability is really
present.
current -> curr
ahc_calc_residual() is no longer static allowing it to
be called from ahc_update_residual() in aic7xxx_inline.h.
Update some serial eeprom definitions for the latest
BIOS versions.
aic7xxx.reg:
Add a combined DATA_PHASE mask to the SCSIPHASE register
definition to simplify some sequencer code.
aic7xxx.seq:
Take advantage of some performance features available only
on the U160 chips. The auto-ack feature allows us to ack
data-in phases up to the data-fifo size while the sequencer
is still setting up the DMA engine. This greatly reduces
read transfer latency and simplifies testing for transfer
complete (check SCSIEN only). We also disable the expected
phase feature, and enable the new bus free interrupt behavior,
to avoid a few instructions.
Re-arrange the Ultra2+ data phase handling to allow us to
do more work in parallel with the data fifo flushing on a
read.
On an SDTR, ack the message immediately so the target can
prepare the next phase or message byte in parallel with
our work to honor the message.
aic7xxx_93cx6.c:
Remove linux header ifdefs.
aic7xxx_freebsd.c:
current -> curr
Add a module event handler.
Handle tag downgrades in our ahc_send_async() handler.
We won't be able to downgrade to "basic queuing" until
CAM is made aware of this queuing type.
aic7xxx_freebsd.h:
Include cleanups.
Define offsetof if required.
Correct a few comments.
Update prototype of ahc_send_async().
aic7xxx_inline.h:
Implement ahc_update_residual().
aic7xxx_pci.c:
Remove linux header ifdefs.
Correct a few product strings.
Enable several U160 performance enhancing features.
Modify Ultra capability determination so we will enable
Ultra speeds on devices with a 7850 PCI id that happen
to really be a 7859 or 7860.
Don't map our interrupt until after we are fully setup to
handle interrupts. Our interrupt line may be shared so
an interrupt could occur at any time.
immediate value or the accumulator. 0 is the chip's internal
representation for the accumulator, and so 0 is an invalid immediate value
when the accumulator can also be specified as an argument.
Submitted by: gibbs
aic7xxx_pci.c:
Enable board generation of interrupts only once our handler is
in place and all other setup has occurred.
aic7xxx.c:
More conversion of data types to ahc_* names. tmode_tstate and
tmode_lstate are the latest victims.
Clean up the check condition path by branching early rather
than indenting a giant block of code.
Add support for target mode initiated sync negotiation.
The code has been tested by forcing the feature on for
all devices, but for the moment is left inaccesible until
a decent mechanism for controlling the behavior is complete.
Implementing this feature required the removal of the
old "target message request" mechanism. The old method
required setting one of the 16 bit fields to initiate
negotiation with a particular target. This had the nice
effect of being easy to change the request and have it
effect the next command. We now set the MK_MESSAGE bit
on any new command when negotiation is required. When
the negotiation is successful, we walk through and clean
up the bit on any pending commands. Since we have to walk
the commands to reset the SCSI syncrate values so no additional
work is required. The only drawback of this approach is that
the negotiation is deferred until the next command is queued to
the controller. On the plus side, we regain two bytes of
sequencer scratch ram and 6 sequencer instructions.
When cleaning up a target mode instance, never remove the
"master" target mode state object. The master contains
all of the saved SEEPROM settings that control things like
transfer negotiations. This data will be cloned as the
defaults if a target mode instance is re-instantiated.
Correct a bug in ahc_set_width(). We neglected to update
the pending scbs to reflect the new parameters. Since
wide negotiation is almost always followed by sync
negotiation it is doubtful that this had any real
effect.
When in the target role, don't complain about
"Target Initiated" negotiation requests when an initiator
negotiates with us.
Defer enabling board interrupts until after ahc_intr_enable()
is called.
Pull all info that used to be in ahc_timeout for the FreeBSD
OSM into ahc_dump_card_state(). This info should be printed
out on all platforms.
aic7xxx.h:
Add the SCB_AUTO_NEGOITATE scb flag. This allows us to
discern the reason the MK_MESSAGE flag is set in the hscb
control byte. We only want to clear MK_MESSAGE in
ahc_update_pending_scbs() if the MK_MESSAGE was set due
to an auto transfer negotiation.
Add the auto_negotiate bitfield for each tstate so that
behavior can be controlled for each of our enabled SCSI
IDs.
Use a bus interrupt handler vector in our softc rather
than hard coding the PCI interrupt handler. This makes
it easier to build the different bus attachments to
the aic7xxx driver as modules.
aic7xxx.reg:
Remove the TARGET_MSG_REQUEST definition for sequencer ram.
aic7xxx.seq:
Fix a few target mode bugs:
o If MK_MESSAGE is set in an SCB, transition to
message in phase and notify the kernel so that
message delivery can occur. This is currently
only used for target mode initiated transfer
negotiation.
o Allow a continue target I/O to compile without
executing a status phase or disconnecting. If
we have not been granted the disconnect privledge
but this transfer is larger than MAXPHYS, it may
take several CTIOs to get the job done.
Remove the tests of the TARGET_MSG_REQUEST field in scratch ram.
aic7xxx_freebsd.c:
Add support for CTIOs that don't disconnect. We now defer
the clearing of our pending target state until we see a
CTIO for that device that has completed sucessfully.
Be sure to return early if we are in a target only role
and see an initiator only CCB type in our action routine.
If a CTIO has the CAM_DIS_DISCONNECT flag set, propogate
this flag to the SCB. This flag has no effect if we've
been asked to deliver status as well. We will complete
the command and release the bus in that case.
Handle the new auto_negotiate field in the tstate correctly.
Make sure that SCBs for "immediate" (i.e. to continue a non
disconnected transaction) CTIO requests get a proper mapping
in the SCB lookup table. Without this, we'll complain when
the transaction completes.
Update ahc_timeout() to reflect the changes to ahc_dump_card_state().
aic7xxx_inline.h:
Use ahc->bus_intr rather than ahc_pci_intr.
Some of the major changes include:
- The SCSI error handling portion of cam_periph_error() has
been broken out into a number of subfunctions to better
modularize the code that handles the hierarchy of SCSI errors.
As a result, the code is now much easier to read.
- String handling and error printing has been significantly
revamped. We now use sbufs to do string formatting instead
of using printfs (for the kernel) and snprintf/strncat (for
userland) as before.
There is a new catchall error printing routine,
cam_error_print() and its string-based counterpart,
cam_error_string() that allow the kernel and userland
applications to pass in a CCB and have errors printed out
properly, whether or not they're SCSI errors. Among other
things, this helped eliminate a fair amount of duplicate code
in camcontrol.
We now print out more information than before, including
the CAM status and SCSI status and the error recovery action
taken to remedy the problem.
- sbufs are now available in userland, via libsbuf. This
change was necessary since most of the error printing code
is shared between libcam and the kernel.
- A new transfer settings interface is included in this checkin.
This code is #ifdef'ed out, and is primarily intended to aid
discussion with HBA driver authors on the final form the
interface should take. There is example code in the ahc(4)
driver that implements the HBA driver side of the new
interface. The new transfer settings code won't be enabled
until we're ready to switch all HBA drivers over to the new
interface.
src/Makefile.inc1,
lib/Makefile: Add libsbuf. It must be built before libcam,
since libcam uses sbuf routines.
libcam/Makefile: libcam now depends on libsbuf.
libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the
sbuf sources from sys/kern.
bsd.libnames.mk: Add LIBSBUF.
camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically
linked, we can't depend on the dynamic linker
to pull in libsbuf.
camcontrol.c: Use cam_error_print() instead of checking for
CAM_SCSI_STATUS_ERROR on every failed CCB.
sbuf.9: Change the prototypes for sbuf_cat() and
sbuf_cpy() so that the source string is now a
const char *. This is more in line wth the
standard system string functions, and helps
eliminate warnings when dealing with a const
source buffer.
Fix a typo.
cam.c: Add description strings for the various CAM
error status values, as well as routines to
look up those strings.
Add new cam_error_string() and
cam_error_print() routines for userland and
the kernel.
cam.h: Add a new CAM flag, CAM_RETRY_SELTO.
Add enumerated types for the various options
available with cam_error_print() and
cam_error_string().
cam_ccb.h: Add new transfer negotiation structures/types.
Change inq_len in the ccb_getdev structure to
be "reserved". This field has never been
filled in, and will be removed when we next
bump the CAM version.
cam_debug.h: Fix typo.
cam_periph.c: Modularize cam_periph_error(). The SCSI error
handling part of cam_periph_error() is now
in camperiphscsistatuserror() and
camperiphscsisenseerror().
In cam_periph_lock(), increase the reference
count on the periph while we wait for our lock
attempt to succeed so that the periph won't go
away while we're sleeping.
cam_xpt.c: Add new transfer negotiation code. (ifdefed
out)
Add a new function, xpt_path_string(). This
is a string/sbuf analog to xpt_print_path().
scsi_all.c: Revamp string handing and error printing code.
We now use sbufs for much of the string
formatting code. More of that code is shared
between userland the kernel.
scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly
useful in the first place.
Add a new error action, SS_REQSENSE. (Send a
request sense and then retry the command.)
This is useful when the controller hasn't
performed autosense for some reason.
Change the default actions around a bit.
scsi_cd.c,
scsi_da.c,
scsi_pt.c,
scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection
timeouts shouldn't be covered by a sense flag.
scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO.
Get rid of the last vestiges of a read/write
interface.
libkern/bsearch.c,
sys/libkern.h,
conf/files: Add bsearch.c, which is needed for some of the
new table lookup routines.
aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if
CAM_NEW_TRAN_CODE is defined.
sbuf.h,
subr_sbuf.c: Add the appropriate #ifdefs so sbufs can
compile and run in userland.
Change sbuf_printf() to use vsnprintf()
instead of kvprintf(), which is only available
in the kernel.
Change the source string for sbuf_cpy() and
sbuf_cat() to be a const char *.
Add __BEGIN_DECLS and __END_DECLS around
function prototypes since they're now exported
to userland.
kdump/mkioctls: Include stdio.h before cam.h since cam.h now
includes a function with a FILE * argument.
Submitted by: gibbs (mostly)
Reviewed by: jdp, marcel (libsbuf makefile changes)
Reviewed by: des (sbuf changes)
Reviewed by: ken
In our idle loop, use an or instruction to set PRELOADEN rather
than rewriting the contents of DMAPARAMS to DFCNTRL. The later
may re-enable the DMA engine if the idle loop is called to complete
the preload of at least one segment when a target disconnects on
an S/G segment boundary but before we have completed fetching the
next segment. This correts a hang, usually in message out phase,
when this situation occurs. This bug has been here for a long
time, so the situation is rare, but not impossible to reproduce.
It only affected Ultra2/U160 controllers.
Correct a few comments.
Extra Sanity. Make sure that SCSIEN is also turned off, along with
HDMAEN, at the end of the data phase.
aic7xxx.c:
Correct code that traverses the phase table. A much too quick
push to staticize this structure resulted in non-functional
lookup code. This corrects the printing of the phase where
a timeout occurred.
aic7xxx.reg:
Use FIFOQWDEMP as the name for bit 5 of DFSTATUS just like
the Adaptec data books.
aic7xxx.seq:
Refine the 2.1 PCI retry bug workaround for certain, non-ULTRA2,
controllers. When the DMA of an SCB completes, it can take
some time for HDONE to come true after MREQPEN (PCI memory request
pending) falls. If HDONE never comes true, we are in the hung
state and must manually drain the FIFO. We used to test HDONE for
3 clock cycles to detect this condition. This works on all of the
hardware I can personally test. Some controllers were reported
to take 4 clock cycles, so the last version of this code waited
4 clock cycles. This still didn't work for everyone. To fix this,
I've adjusted the work around so that even if the hardware hasn't
hung, but we run the work-around code, the result is a long winded
way to complete the transfer, rather than a hang.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
Use the target offset rather than the target Id to reference
the untagged SCB array. The offset and id are identical save
in the twin channel case. This should correct several issues
with the 2742T.
Set the user and goal settings prior to setting the current
settings. This allows the async update routine to filter out
intermediate transfer negotiation updates that may be less
than interesting. The Linux OSM uses this to reduce the amount
of stuff printed to the console.
aic7xxx.seq:
Correct an issue with the aic7770 in twin channel mode.
We could continually attempt to start a selection even
though a selection was already occurring on one channel.
This might have the side effect of hanging our selection
or causing us to select the wrong device.
While here, create a separate polling loop for when we
have already started a selection. This should reduce
the latency of our response to a (re)selection. The diffs
look larger than they really are due to some code rearrangement
to optimize out a jmp.
aic7xxx_freebsd.c:
Use the target offset rather than the target Id to reference
the untagged SCB array. The offset and id are identical save
in the twin channel case. This should correct several issues
with the 2742T.
aic7xxx_inline.h:
Get back in sync with perforce revision ID.
aic7xxx_pci.c:
Identify adapters in ARO mode as such.
Ensure that not only the subvendor ID is correct (9005)
but also that the controller type field is valid before
looking at other information in the subdevice id. Intel
seems to have decided that their subdevice id of 8086
is more appropriate for some of their MBs with aic7xxx
parts than Adaptec's sanctioned scheme.
Add an exclusion entry for SISL (AAC on MB based adapters).
Adapters in SISL mode are owned by the RAID controller, so
even if a driver for the RAID controller is not present,
it isn't safe for us to touch them.
register our sub-busses in the reversed order. In the future, we may provide
a hint to CAM on how to order the scans for multi-function adapters that also
set this flag, but trying to do it the "twin channel" way will lead to
a panic.
Style nits.
Make sure that our selection hardware is disabled
as soon as possible after detecting a busfree and
even go so far as to disable the selection hardware
in advance of an event that will cause a busfree
(ABORT or BUS DEVICE RESET message). The concern
is that the selection hardware will select a target
for which, after processing the bus free, there
will be no commands pending. The sequencer idle
loop will re-enable the selection should it still be
necessary.
In ahc_handle_scsiint(), clear SSTAT0 events several
PCI transactions (most notably reads) prior to clearing
SCSIINT. The newer chips seem to take a bit of time to
see the change which can make the clearing of SCSIINT
ineffective.
Don't bother panicing at the end of ahc_handle_scsiint().
Getting to the final else just means we lost the race
with clearing SCSIINT.
In ahc_free(), handle init-level 0. This can happen when we
fail the attach for RAID devices. While I'm here, also kill
the parent dma tag.
In ahc_match_scb(), consider initiator ccbs to be any
that are not from the target mode group. This fixes
a bug where an external target reset CCB was not getting
cleaned up by the reset code.
Don't bother freezing a ccb in any of our "abort" routines
when the status is set to CAM_REQ_CMP. This can happen
for a target reset ccb.
aic7xxx.reg:
Reserve space for a completion queue. This will be used
to enhance performance in the near future.
aic7xxx.seq:
Remove an optimization for the 7890 autoflush bug that
turned out to allow, in rare cases, some data to get
lost.
Implement a simpler, faster, fix for the PCI_2_1 retry
bug that hangs the sequencer on an SCB dma for certain chips.
Test against SAVED_SCSIID rather than SELID during target
reselections. This is how we always did it in the past,
but the code was modified while trying to work around an
issue with the 7895. SAVED_SCSIID takes into account
twin channel adapters such as the 2742T, whereas SELID
does not have the channel bit. This caused invalid
selection warnings and other strangeness on these cards.
aic7xxx_pci.c
Use the correct mask for checking the generic aic7892
entry.
we must also inform the card of this change. Otherwise the sequencer
will traverse a corrupt list of SCBS. The side effects of this problem
were unknown SCBs completing in the qoutfifo or worse yet, panics due
to sequencer interrupts that referenced what, to the kernel, were invalid
SCB ids.
Initialize rid to 0. This doesn't seem to make any difference
(the driver doesn't care what rid it gets and no-one seems to
check rid's value), but follows standard conventions.
Pass in our device_t to ahc_alloc(). We now use device_T
softc storage, so passing NULL results in a panic.
Set the unit number in our softc so that the driver core
can retrieve it.
ahc_pci.c:
Set the unit number in our softc so that the driver core
can retrieve it.
aic7770.c:
Insert our softc into the list of softcs when initialization
is successful.
aic7xxx.c:
Remove a workaround for an aic7895 bug we will never trigger.
Add additional diagnostic info to ahc_dump_card_state().
Always panic the system if a sequencer assertion fails.
AHC_SCB_BTT is a "flag" not a "feature". Check the right
field in the softc.
Replace a hard coded number with a constant.
Guard against looping forever in ahc_pause_and_flushwork().
A hot eject or card failure may make the intstat register
return 0xFF, so limit the number of interrupts we'll process.
Correct the code in ahc_search_qinfifo() that guarantees that
the sequencer will see an abort collision if the qinfifo is
modified when a DMA is in progress. We now do this fixup
after modifying the queue. This guarantees that the HSCB
we place at the head of the queue is not the same as the
old head. Using "next hscb" (guaranteed not to be the
same as the first SCB) before clearing the queue could free
up the original head hscb to be used during a remove operation
placing it again at the head of the qinfifo.
aic7xxx.h:
Reduce the maximum number of outstanding commands to 253 from
254. To handle our output queue correctly on machines that only
support 32bit stores, we must clear the array 4 bytes at a
time. To avoid colliding with a DMA write from the sequencer,
we must be sure that 4 slots are empty when we write to clear
the queue. This reduces us to 253 SCBs: 1 that just completed
and the known three additional empty slots in the queue that
preceed it. Yahoo was able to force this race on one of their
systems. Interrupts were disabled for such a time that the
entire output queue was filled (254 entries complete without
any processing), and our 32bit write to clear the status clobbered
one entry.
Add a feature tag for devices that are removable.
aic7xxx.reg:
Never use the sequencer interrupt value of 0xF0. We need
to guanrantee that an INTSTAT value of 0xFF can only occur
during card failure or a hot-eject.
Align the busy targets table with the begining of scratch
space. This seems to appease a chip bug in the aic7895.
aic7xxx.seq:
Be sure to disable select-out after a bus free event that occurs
early in a selection. If we don't disable select-out, we will
believe that it is enabled even though a new selection will never
occur.
Move the clearing of SELDI to just before a jump. This appeases
another chip bug of the aic7895.
Make the target mode command loop a bit more efficient.
AHC_SCB_BTT is a "flag" not a "feature". Check the right
field in the softc.
Properly cleanup the last SCB we tested against should we
fail to properly find an SCB for a reselection.
Add some additional sequencer debugging code.
aic7xxx_freebsd.c:
Limit the driver to 253 outstanding commands per adapter.
Guard against overflow in timeout handling.
aic7xxx_inline.h:
AHC_SCB_BTT is a "flag" not a "feature". Check the right
field in the softc.
aic7xxx_pci.c:
Set the removable feature for the apa1480 cardbus and the 29160C
Compact PCI card.
Don't report high byte termination information for narrow cards.
Use a PCI read rather than a questionable delay when fetching/setting
termination settings.
hscbs may be traded during error recovery due to the way
we manage the qinfifo. This has the effect of changing the
index to the sense buffer even though the request sense command
references the original buffer. SCBs don't play this swapping
game and so serve as a more consistent reference.
aic7xxx.h:
First pass at big-endian support in the Core.
Capture state for second channel on TWIN channel adapters
for suspend and resume.
aic7xxx_freebsd.h:
Stubs for endian conversion functions. These will get filled
out once we get an official kernel api for this kind of thing
that is something more elegant and efficient than a bunch of
manual swaps #ifdefed by platform.
aic7xxx_pci.c
Allow the second channel of motherboard aic7896 chips to be attached.
It turns out that the encoding of the subdevice id differs between
PCI cards and MB based controllers and our check to see, via
the subvendor id, if the second channel was "stuffed" always
turned out negative.
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.