freebsd-skq/sys/dev/aic7xxx/aic7xxx_osm.h

310 lines
9.6 KiB
C
Raw Normal View History

/*
* FreeBSD platform specific driver option settings, data structures,
* function declarations and includes.
*
* Copyright (c) 1994-2001 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU Public License ("GPL").
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
ahc_eisa.c: ahc_pci.c: ahd_pci.c: aic7xxx.c: aic79xx.c: aic_osm_lib.c: aic_osm_lib.h: Use common OSM routines from aic_osm_lib for bus dma operations, delay routines, accessing CCBs, byte swapping, etc. aic7xxx_pci.c: Provide a better description for the 2915/30LP on attach. aic7xxx.c: aic79xx.c: aic7770.c: aic79xx_pci.c: aic7xxx_pci.c: aic7xxx_93cx6.c: Move FBSDID behind an ifdef so that these core files will still compile under other OSes. aic79xx.h: aic79xx_pci.c: aic79xx.seq: To speed up non-packetized CDB delivery in Rev B, all CDB acks are "released" to the output sync as soon as the command phase starts. There is only one problem with this approach. If the target changes phase before all data are sent, we have left over acks that can go out on the bus in a data phase. Due to other chip contraints, this only happens if the target goes to data-in, but if the acks go out before we can test SDONE, we'll think that the transfer has completed successfully. Work around this by taking advantage of the 400ns or 800ns dead time between command phase and the REQ of the new phase. If the transfer has completed successfully, SCSIEN should fall *long* before we see a phase change. We thus treat any phasemiss that occurs before SCSIEN falls as an incomplete transfer. aic79xx.h: Add the AHD_FAST_CDB_DELIVERY feature. aic79xx_pci.c: Set AHD_FAST_CDB_DELIVERY for all Rev. B parts. aic79xx.seq: Test for PHASEMIS in the command phase for all AHD_FAST_CDB_DELIVERY controlelrs. ahd_pci.c: ahc_pci.c: aic7xxx.h: aic79xx.h: Move definition of controller BAR offsets to core header files. aic7xxx.c: aic79xx.c: In the softc free routine, leave removal of a softc from the global list of softcs to the OSM (the caller of this routine). This allows us to avoid holding the softc list_lock during device destruction where we may have to sleep waiting for our recovery thread to halt. ahc_pci.c: Use ahc_pci_test_register access to validate I/O mapped in addition to the tests already performed for memory mapped access. Remove unused ahc_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. ahd_pci.c: Remove reduntant definition of controller BAR offsets. These are also defined in aic79xx.h. Remove unused ahd_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. aic7xxx.c: aic79xx.c: aic79xx.h: aic7xxx.h: aic7xxx_osm.c: aic79xx_osm.c: Move timeout handling to the driver cores. In the case of the aic79xx driver, the algorithm has been enhanced to try target resets before performing a bus reset. For the aic7xxx driver, the algorithm is unchanged. Although the drivers do not currently sleep during recovery (recovery is timeout driven), the cores do expect all processing to be performed via a recovery thread. Our timeout handlers are now little stubs that wakeup the recovery thread. aic79xx.c: aic79xx.h: aic79xx_inline.h: Change shared_data allocation to use a map_node so that the sentinel hscb can use this map node in ahd_swap_with_next_hscb. This routine now swaps the hscb_map pointer in additon to the hscb contents so that any sync operations occur on the correct map. physaddr -> busaddr Pointed out by: Jason Thorpe <thorpej@wasabisystems.com> aic79xx.c: Make more use of the in/out/w/l/q macros for accessing byte registers in the chip. Correct some issues in the ahd_flush_qoutfifo() routine. o Run the qoutfifo only once the command channel DMA engine has been halted. This closes a window where we might have missed some entries. o Change ahd_run_data_fifo() to not loop to completion. If we happen to start on the wrong FIFO and the other FIFO has a snapshot savepointers, we might deadlock. This required our delay between FIFO tests to be moved to the ahd_flush_qoutfifo() routine. o Update/add comments. o Remove spurious test for COMPLETE_DMA list being empty when completing transactions from the GSFIFO with residuals. The SCB must be put on the COMPLETE_DMA scb list unconditionally. o When halting command channel DMA activity, we must disable the DMA channel in all cases but an update of the QOUTFIFO. The latter case is required so that the sequencer will update its position in the QOUTFIFO. Previously, we left the channel enabled for all "push" DMAs. This left us vulnerable to the sequencer handling an SCB push long after that SCB was already processed manually by this routine. o Correct the polarity of tests involving ahd_scb_active_in_fifo(). This routine returns non-zero for true. Return to processing bad status completions through the qoutfifo. This reduces the time that the sequencer is kept paused when handling transactions with bad status or underruns. When waiting for the controller to quiece selections, add a delay to our loop. Otherwise we may fail to wait long enough for the sequencer to comply. On H2A4 hardware, use the slow slewrate for non-paced transfers. This mirrors what the Adaptec Windows drivers do. On the Rev B. only slow down the CRC timing for older U160 devices that might need the slower timing. We define "older" as devices that do not support packetized protocol. Wait up to 5000 * 5us for the SEEPROM to become unbusy. Write ops seem to take much longer than read ops. aic79xx.seq: For controllers with the FAINT_LED bug, turn the diagnostic led feature on during selection and reselection. This covers the non-packetized case. The LED will be disabled for non-packetized transfers once we return to the top level idle loop. Add more comments about the busy LED workaround. Extend a critical section around the entire command channel idle loop process. Previously the portion of this handler that directly manipulated the linked list of completed SCBs was not protected. This is the likely cause of the recent reports of commands being completed twice by the driver. Extend critical sections across the test for, and the longjump to, longjump routines. This prevents the firmware from trying to jump to a longjmp handler that was just cleared by the host. Improve the locations of several critical section begin and end points. Typically these changes remove instructions that did not need to be inside a critical section. Close the "busfree after selection, but before busfree interrupts can be enabled" race to just a single sequencer instruction. We now test the BSY line explicitly before clearing the busfree status and enabling the busfree interrupt. Close a race condition in the processing of HS_MAILBOX updates. We now clear the "updated" status before the copy. This ensures that we don't accidentally clear the status incorrectly when the host sneaks in an update just after our last copy, but before we clear the status. This race has never been observed. Don't re-enable SCSIEN if we lose the race to disable SCSIEN in our interrupt handler's workaround for the RevA data-valid too early issue. aic79xx_inline.h: Add comments indicating that the order in which bytes are read or written in ahd_inw and ahd_outw is important. This allows us to use these inlines when accessing registers with side-effects. aic79xx_pci.c: The 29320 and the 29320B are 7902 not 7901 based products. Correct the driver banner. aic7xxx.h: Enable the use of the auto-access pause feature on the aic7870 and aic7880. It was disabled due to an oversight. aic7xxx.reg: Move TARG_IMMEDIATE_SCB to alias LAST_MSG to avoid leaving garbage in MWI_RESIDUAL. This prevents spurious overflows whn operating target mode on controllers that require the MWI_RESIDUAL work-around. aic7xxx.seq: AHC_TMODE_WIDEODD_BUG is a bug, not a softc flag. Reference the correct softc field when testing for its presence. Set the NOT_IDENTIFIED and NO_CDB_SENT bits in SEQ_FLAGS to indicate that the nexus is invalid in await busfree. aic7xxx_93cx6.c: Add support for the C56/C66 versions of the EWEN and EWDS commands. aic7xxx.c: aic7xxx_pci.c: Move test for the validity of left over BIOS data to ahc_test_register_access(). This guarantees that any left over CHIPRST value is not clobbered by our register access test and lost to the test that was in ahc_reset.
2003-12-17 00:02:10 +00:00
* $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#18 $
*
* $FreeBSD$
*/
#ifndef _AIC7XXX_FREEBSD_H_
#define _AIC7XXX_FREEBSD_H_
#include <opt_aic7xxx.h> /* for config options */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h> /* For device_t */
#if __FreeBSD_version >= 500000
#include <sys/endian.h>
#endif
ahc_eisa.c: 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.
2000-12-20 01:11:37 +00:00
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#if __FreeBSD_version < 500000
#include <pci.h>
#else
#define NPCI 1
#endif
#if NPCI > 0
ahc_eisa.c: ahc_pci.c: ahd_pci.c: aic7xxx.c: aic79xx.c: aic_osm_lib.c: aic_osm_lib.h: Use common OSM routines from aic_osm_lib for bus dma operations, delay routines, accessing CCBs, byte swapping, etc. aic7xxx_pci.c: Provide a better description for the 2915/30LP on attach. aic7xxx.c: aic79xx.c: aic7770.c: aic79xx_pci.c: aic7xxx_pci.c: aic7xxx_93cx6.c: Move FBSDID behind an ifdef so that these core files will still compile under other OSes. aic79xx.h: aic79xx_pci.c: aic79xx.seq: To speed up non-packetized CDB delivery in Rev B, all CDB acks are "released" to the output sync as soon as the command phase starts. There is only one problem with this approach. If the target changes phase before all data are sent, we have left over acks that can go out on the bus in a data phase. Due to other chip contraints, this only happens if the target goes to data-in, but if the acks go out before we can test SDONE, we'll think that the transfer has completed successfully. Work around this by taking advantage of the 400ns or 800ns dead time between command phase and the REQ of the new phase. If the transfer has completed successfully, SCSIEN should fall *long* before we see a phase change. We thus treat any phasemiss that occurs before SCSIEN falls as an incomplete transfer. aic79xx.h: Add the AHD_FAST_CDB_DELIVERY feature. aic79xx_pci.c: Set AHD_FAST_CDB_DELIVERY for all Rev. B parts. aic79xx.seq: Test for PHASEMIS in the command phase for all AHD_FAST_CDB_DELIVERY controlelrs. ahd_pci.c: ahc_pci.c: aic7xxx.h: aic79xx.h: Move definition of controller BAR offsets to core header files. aic7xxx.c: aic79xx.c: In the softc free routine, leave removal of a softc from the global list of softcs to the OSM (the caller of this routine). This allows us to avoid holding the softc list_lock during device destruction where we may have to sleep waiting for our recovery thread to halt. ahc_pci.c: Use ahc_pci_test_register access to validate I/O mapped in addition to the tests already performed for memory mapped access. Remove unused ahc_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. ahd_pci.c: Remove reduntant definition of controller BAR offsets. These are also defined in aic79xx.h. Remove unused ahd_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. aic7xxx.c: aic79xx.c: aic79xx.h: aic7xxx.h: aic7xxx_osm.c: aic79xx_osm.c: Move timeout handling to the driver cores. In the case of the aic79xx driver, the algorithm has been enhanced to try target resets before performing a bus reset. For the aic7xxx driver, the algorithm is unchanged. Although the drivers do not currently sleep during recovery (recovery is timeout driven), the cores do expect all processing to be performed via a recovery thread. Our timeout handlers are now little stubs that wakeup the recovery thread. aic79xx.c: aic79xx.h: aic79xx_inline.h: Change shared_data allocation to use a map_node so that the sentinel hscb can use this map node in ahd_swap_with_next_hscb. This routine now swaps the hscb_map pointer in additon to the hscb contents so that any sync operations occur on the correct map. physaddr -> busaddr Pointed out by: Jason Thorpe <thorpej@wasabisystems.com> aic79xx.c: Make more use of the in/out/w/l/q macros for accessing byte registers in the chip. Correct some issues in the ahd_flush_qoutfifo() routine. o Run the qoutfifo only once the command channel DMA engine has been halted. This closes a window where we might have missed some entries. o Change ahd_run_data_fifo() to not loop to completion. If we happen to start on the wrong FIFO and the other FIFO has a snapshot savepointers, we might deadlock. This required our delay between FIFO tests to be moved to the ahd_flush_qoutfifo() routine. o Update/add comments. o Remove spurious test for COMPLETE_DMA list being empty when completing transactions from the GSFIFO with residuals. The SCB must be put on the COMPLETE_DMA scb list unconditionally. o When halting command channel DMA activity, we must disable the DMA channel in all cases but an update of the QOUTFIFO. The latter case is required so that the sequencer will update its position in the QOUTFIFO. Previously, we left the channel enabled for all "push" DMAs. This left us vulnerable to the sequencer handling an SCB push long after that SCB was already processed manually by this routine. o Correct the polarity of tests involving ahd_scb_active_in_fifo(). This routine returns non-zero for true. Return to processing bad status completions through the qoutfifo. This reduces the time that the sequencer is kept paused when handling transactions with bad status or underruns. When waiting for the controller to quiece selections, add a delay to our loop. Otherwise we may fail to wait long enough for the sequencer to comply. On H2A4 hardware, use the slow slewrate for non-paced transfers. This mirrors what the Adaptec Windows drivers do. On the Rev B. only slow down the CRC timing for older U160 devices that might need the slower timing. We define "older" as devices that do not support packetized protocol. Wait up to 5000 * 5us for the SEEPROM to become unbusy. Write ops seem to take much longer than read ops. aic79xx.seq: For controllers with the FAINT_LED bug, turn the diagnostic led feature on during selection and reselection. This covers the non-packetized case. The LED will be disabled for non-packetized transfers once we return to the top level idle loop. Add more comments about the busy LED workaround. Extend a critical section around the entire command channel idle loop process. Previously the portion of this handler that directly manipulated the linked list of completed SCBs was not protected. This is the likely cause of the recent reports of commands being completed twice by the driver. Extend critical sections across the test for, and the longjump to, longjump routines. This prevents the firmware from trying to jump to a longjmp handler that was just cleared by the host. Improve the locations of several critical section begin and end points. Typically these changes remove instructions that did not need to be inside a critical section. Close the "busfree after selection, but before busfree interrupts can be enabled" race to just a single sequencer instruction. We now test the BSY line explicitly before clearing the busfree status and enabling the busfree interrupt. Close a race condition in the processing of HS_MAILBOX updates. We now clear the "updated" status before the copy. This ensures that we don't accidentally clear the status incorrectly when the host sneaks in an update just after our last copy, but before we clear the status. This race has never been observed. Don't re-enable SCSIEN if we lose the race to disable SCSIEN in our interrupt handler's workaround for the RevA data-valid too early issue. aic79xx_inline.h: Add comments indicating that the order in which bytes are read or written in ahd_inw and ahd_outw is important. This allows us to use these inlines when accessing registers with side-effects. aic79xx_pci.c: The 29320 and the 29320B are 7902 not 7901 based products. Correct the driver banner. aic7xxx.h: Enable the use of the auto-access pause feature on the aic7870 and aic7880. It was disabled due to an oversight. aic7xxx.reg: Move TARG_IMMEDIATE_SCB to alias LAST_MSG to avoid leaving garbage in MWI_RESIDUAL. This prevents spurious overflows whn operating target mode on controllers that require the MWI_RESIDUAL work-around. aic7xxx.seq: AHC_TMODE_WIDEODD_BUG is a bug, not a softc flag. Reference the correct softc field when testing for its presence. Set the NOT_IDENTIFIED and NO_CDB_SENT bits in SEQ_FLAGS to indicate that the nexus is invalid in await busfree. aic7xxx_93cx6.c: Add support for the C56/C66 versions of the EWEN and EWDS commands. aic7xxx.c: aic7xxx_pci.c: Move test for the validity of left over BIOS data to ahc_test_register_access(). This guarantees that any left over CHIPRST value is not clobbered by our register access test and lost to the test that was in ahc_reset.
2003-12-17 00:02:10 +00:00
#define AIC_PCI_CONFIG 1
#include <machine/bus_memio.h>
#endif
#include <machine/bus_pio.h>
#include <machine/bus.h>
Major update to the aic7xxx driver: 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
2002-04-24 16:58:51 +00:00
#include <machine/endian.h>
#include <machine/clock.h>
#include <machine/resource.h>
#include <sys/rman.h>
#if NPCI > 0
ahc_eisa.c: ahc_pci.c: ahd_pci.c: aic7xxx.c: aic79xx.c: aic_osm_lib.c: aic_osm_lib.h: Use common OSM routines from aic_osm_lib for bus dma operations, delay routines, accessing CCBs, byte swapping, etc. aic7xxx_pci.c: Provide a better description for the 2915/30LP on attach. aic7xxx.c: aic79xx.c: aic7770.c: aic79xx_pci.c: aic7xxx_pci.c: aic7xxx_93cx6.c: Move FBSDID behind an ifdef so that these core files will still compile under other OSes. aic79xx.h: aic79xx_pci.c: aic79xx.seq: To speed up non-packetized CDB delivery in Rev B, all CDB acks are "released" to the output sync as soon as the command phase starts. There is only one problem with this approach. If the target changes phase before all data are sent, we have left over acks that can go out on the bus in a data phase. Due to other chip contraints, this only happens if the target goes to data-in, but if the acks go out before we can test SDONE, we'll think that the transfer has completed successfully. Work around this by taking advantage of the 400ns or 800ns dead time between command phase and the REQ of the new phase. If the transfer has completed successfully, SCSIEN should fall *long* before we see a phase change. We thus treat any phasemiss that occurs before SCSIEN falls as an incomplete transfer. aic79xx.h: Add the AHD_FAST_CDB_DELIVERY feature. aic79xx_pci.c: Set AHD_FAST_CDB_DELIVERY for all Rev. B parts. aic79xx.seq: Test for PHASEMIS in the command phase for all AHD_FAST_CDB_DELIVERY controlelrs. ahd_pci.c: ahc_pci.c: aic7xxx.h: aic79xx.h: Move definition of controller BAR offsets to core header files. aic7xxx.c: aic79xx.c: In the softc free routine, leave removal of a softc from the global list of softcs to the OSM (the caller of this routine). This allows us to avoid holding the softc list_lock during device destruction where we may have to sleep waiting for our recovery thread to halt. ahc_pci.c: Use ahc_pci_test_register access to validate I/O mapped in addition to the tests already performed for memory mapped access. Remove unused ahc_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. ahd_pci.c: Remove reduntant definition of controller BAR offsets. These are also defined in aic79xx.h. Remove unused ahd_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. aic7xxx.c: aic79xx.c: aic79xx.h: aic7xxx.h: aic7xxx_osm.c: aic79xx_osm.c: Move timeout handling to the driver cores. In the case of the aic79xx driver, the algorithm has been enhanced to try target resets before performing a bus reset. For the aic7xxx driver, the algorithm is unchanged. Although the drivers do not currently sleep during recovery (recovery is timeout driven), the cores do expect all processing to be performed via a recovery thread. Our timeout handlers are now little stubs that wakeup the recovery thread. aic79xx.c: aic79xx.h: aic79xx_inline.h: Change shared_data allocation to use a map_node so that the sentinel hscb can use this map node in ahd_swap_with_next_hscb. This routine now swaps the hscb_map pointer in additon to the hscb contents so that any sync operations occur on the correct map. physaddr -> busaddr Pointed out by: Jason Thorpe <thorpej@wasabisystems.com> aic79xx.c: Make more use of the in/out/w/l/q macros for accessing byte registers in the chip. Correct some issues in the ahd_flush_qoutfifo() routine. o Run the qoutfifo only once the command channel DMA engine has been halted. This closes a window where we might have missed some entries. o Change ahd_run_data_fifo() to not loop to completion. If we happen to start on the wrong FIFO and the other FIFO has a snapshot savepointers, we might deadlock. This required our delay between FIFO tests to be moved to the ahd_flush_qoutfifo() routine. o Update/add comments. o Remove spurious test for COMPLETE_DMA list being empty when completing transactions from the GSFIFO with residuals. The SCB must be put on the COMPLETE_DMA scb list unconditionally. o When halting command channel DMA activity, we must disable the DMA channel in all cases but an update of the QOUTFIFO. The latter case is required so that the sequencer will update its position in the QOUTFIFO. Previously, we left the channel enabled for all "push" DMAs. This left us vulnerable to the sequencer handling an SCB push long after that SCB was already processed manually by this routine. o Correct the polarity of tests involving ahd_scb_active_in_fifo(). This routine returns non-zero for true. Return to processing bad status completions through the qoutfifo. This reduces the time that the sequencer is kept paused when handling transactions with bad status or underruns. When waiting for the controller to quiece selections, add a delay to our loop. Otherwise we may fail to wait long enough for the sequencer to comply. On H2A4 hardware, use the slow slewrate for non-paced transfers. This mirrors what the Adaptec Windows drivers do. On the Rev B. only slow down the CRC timing for older U160 devices that might need the slower timing. We define "older" as devices that do not support packetized protocol. Wait up to 5000 * 5us for the SEEPROM to become unbusy. Write ops seem to take much longer than read ops. aic79xx.seq: For controllers with the FAINT_LED bug, turn the diagnostic led feature on during selection and reselection. This covers the non-packetized case. The LED will be disabled for non-packetized transfers once we return to the top level idle loop. Add more comments about the busy LED workaround. Extend a critical section around the entire command channel idle loop process. Previously the portion of this handler that directly manipulated the linked list of completed SCBs was not protected. This is the likely cause of the recent reports of commands being completed twice by the driver. Extend critical sections across the test for, and the longjump to, longjump routines. This prevents the firmware from trying to jump to a longjmp handler that was just cleared by the host. Improve the locations of several critical section begin and end points. Typically these changes remove instructions that did not need to be inside a critical section. Close the "busfree after selection, but before busfree interrupts can be enabled" race to just a single sequencer instruction. We now test the BSY line explicitly before clearing the busfree status and enabling the busfree interrupt. Close a race condition in the processing of HS_MAILBOX updates. We now clear the "updated" status before the copy. This ensures that we don't accidentally clear the status incorrectly when the host sneaks in an update just after our last copy, but before we clear the status. This race has never been observed. Don't re-enable SCSIEN if we lose the race to disable SCSIEN in our interrupt handler's workaround for the RevA data-valid too early issue. aic79xx_inline.h: Add comments indicating that the order in which bytes are read or written in ahd_inw and ahd_outw is important. This allows us to use these inlines when accessing registers with side-effects. aic79xx_pci.c: The 29320 and the 29320B are 7902 not 7901 based products. Correct the driver banner. aic7xxx.h: Enable the use of the auto-access pause feature on the aic7870 and aic7880. It was disabled due to an oversight. aic7xxx.reg: Move TARG_IMMEDIATE_SCB to alias LAST_MSG to avoid leaving garbage in MWI_RESIDUAL. This prevents spurious overflows whn operating target mode on controllers that require the MWI_RESIDUAL work-around. aic7xxx.seq: AHC_TMODE_WIDEODD_BUG is a bug, not a softc flag. Reference the correct softc field when testing for its presence. Set the NOT_IDENTIFIED and NO_CDB_SENT bits in SEQ_FLAGS to indicate that the nexus is invalid in await busfree. aic7xxx_93cx6.c: Add support for the C56/C66 versions of the EWEN and EWDS commands. aic7xxx.c: aic7xxx_pci.c: Move test for the validity of left over BIOS data to ahc_test_register_access(). This guarantees that any left over CHIPRST value is not clobbered by our register access test and lost to the test that was in ahc_reset.
2003-12-17 00:02:10 +00:00
#if __FreeBSD_version >= 500000
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
ahc_eisa.c: ahc_pci.c: ahd_pci.c: aic7xxx.c: aic79xx.c: aic_osm_lib.c: aic_osm_lib.h: Use common OSM routines from aic_osm_lib for bus dma operations, delay routines, accessing CCBs, byte swapping, etc. aic7xxx_pci.c: Provide a better description for the 2915/30LP on attach. aic7xxx.c: aic79xx.c: aic7770.c: aic79xx_pci.c: aic7xxx_pci.c: aic7xxx_93cx6.c: Move FBSDID behind an ifdef so that these core files will still compile under other OSes. aic79xx.h: aic79xx_pci.c: aic79xx.seq: To speed up non-packetized CDB delivery in Rev B, all CDB acks are "released" to the output sync as soon as the command phase starts. There is only one problem with this approach. If the target changes phase before all data are sent, we have left over acks that can go out on the bus in a data phase. Due to other chip contraints, this only happens if the target goes to data-in, but if the acks go out before we can test SDONE, we'll think that the transfer has completed successfully. Work around this by taking advantage of the 400ns or 800ns dead time between command phase and the REQ of the new phase. If the transfer has completed successfully, SCSIEN should fall *long* before we see a phase change. We thus treat any phasemiss that occurs before SCSIEN falls as an incomplete transfer. aic79xx.h: Add the AHD_FAST_CDB_DELIVERY feature. aic79xx_pci.c: Set AHD_FAST_CDB_DELIVERY for all Rev. B parts. aic79xx.seq: Test for PHASEMIS in the command phase for all AHD_FAST_CDB_DELIVERY controlelrs. ahd_pci.c: ahc_pci.c: aic7xxx.h: aic79xx.h: Move definition of controller BAR offsets to core header files. aic7xxx.c: aic79xx.c: In the softc free routine, leave removal of a softc from the global list of softcs to the OSM (the caller of this routine). This allows us to avoid holding the softc list_lock during device destruction where we may have to sleep waiting for our recovery thread to halt. ahc_pci.c: Use ahc_pci_test_register access to validate I/O mapped in addition to the tests already performed for memory mapped access. Remove unused ahc_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. ahd_pci.c: Remove reduntant definition of controller BAR offsets. These are also defined in aic79xx.h. Remove unused ahd_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. aic7xxx.c: aic79xx.c: aic79xx.h: aic7xxx.h: aic7xxx_osm.c: aic79xx_osm.c: Move timeout handling to the driver cores. In the case of the aic79xx driver, the algorithm has been enhanced to try target resets before performing a bus reset. For the aic7xxx driver, the algorithm is unchanged. Although the drivers do not currently sleep during recovery (recovery is timeout driven), the cores do expect all processing to be performed via a recovery thread. Our timeout handlers are now little stubs that wakeup the recovery thread. aic79xx.c: aic79xx.h: aic79xx_inline.h: Change shared_data allocation to use a map_node so that the sentinel hscb can use this map node in ahd_swap_with_next_hscb. This routine now swaps the hscb_map pointer in additon to the hscb contents so that any sync operations occur on the correct map. physaddr -> busaddr Pointed out by: Jason Thorpe <thorpej@wasabisystems.com> aic79xx.c: Make more use of the in/out/w/l/q macros for accessing byte registers in the chip. Correct some issues in the ahd_flush_qoutfifo() routine. o Run the qoutfifo only once the command channel DMA engine has been halted. This closes a window where we might have missed some entries. o Change ahd_run_data_fifo() to not loop to completion. If we happen to start on the wrong FIFO and the other FIFO has a snapshot savepointers, we might deadlock. This required our delay between FIFO tests to be moved to the ahd_flush_qoutfifo() routine. o Update/add comments. o Remove spurious test for COMPLETE_DMA list being empty when completing transactions from the GSFIFO with residuals. The SCB must be put on the COMPLETE_DMA scb list unconditionally. o When halting command channel DMA activity, we must disable the DMA channel in all cases but an update of the QOUTFIFO. The latter case is required so that the sequencer will update its position in the QOUTFIFO. Previously, we left the channel enabled for all "push" DMAs. This left us vulnerable to the sequencer handling an SCB push long after that SCB was already processed manually by this routine. o Correct the polarity of tests involving ahd_scb_active_in_fifo(). This routine returns non-zero for true. Return to processing bad status completions through the qoutfifo. This reduces the time that the sequencer is kept paused when handling transactions with bad status or underruns. When waiting for the controller to quiece selections, add a delay to our loop. Otherwise we may fail to wait long enough for the sequencer to comply. On H2A4 hardware, use the slow slewrate for non-paced transfers. This mirrors what the Adaptec Windows drivers do. On the Rev B. only slow down the CRC timing for older U160 devices that might need the slower timing. We define "older" as devices that do not support packetized protocol. Wait up to 5000 * 5us for the SEEPROM to become unbusy. Write ops seem to take much longer than read ops. aic79xx.seq: For controllers with the FAINT_LED bug, turn the diagnostic led feature on during selection and reselection. This covers the non-packetized case. The LED will be disabled for non-packetized transfers once we return to the top level idle loop. Add more comments about the busy LED workaround. Extend a critical section around the entire command channel idle loop process. Previously the portion of this handler that directly manipulated the linked list of completed SCBs was not protected. This is the likely cause of the recent reports of commands being completed twice by the driver. Extend critical sections across the test for, and the longjump to, longjump routines. This prevents the firmware from trying to jump to a longjmp handler that was just cleared by the host. Improve the locations of several critical section begin and end points. Typically these changes remove instructions that did not need to be inside a critical section. Close the "busfree after selection, but before busfree interrupts can be enabled" race to just a single sequencer instruction. We now test the BSY line explicitly before clearing the busfree status and enabling the busfree interrupt. Close a race condition in the processing of HS_MAILBOX updates. We now clear the "updated" status before the copy. This ensures that we don't accidentally clear the status incorrectly when the host sneaks in an update just after our last copy, but before we clear the status. This race has never been observed. Don't re-enable SCSIEN if we lose the race to disable SCSIEN in our interrupt handler's workaround for the RevA data-valid too early issue. aic79xx_inline.h: Add comments indicating that the order in which bytes are read or written in ahd_inw and ahd_outw is important. This allows us to use these inlines when accessing registers with side-effects. aic79xx_pci.c: The 29320 and the 29320B are 7902 not 7901 based products. Correct the driver banner. aic7xxx.h: Enable the use of the auto-access pause feature on the aic7870 and aic7880. It was disabled due to an oversight. aic7xxx.reg: Move TARG_IMMEDIATE_SCB to alias LAST_MSG to avoid leaving garbage in MWI_RESIDUAL. This prevents spurious overflows whn operating target mode on controllers that require the MWI_RESIDUAL work-around. aic7xxx.seq: AHC_TMODE_WIDEODD_BUG is a bug, not a softc flag. Reference the correct softc field when testing for its presence. Set the NOT_IDENTIFIED and NO_CDB_SENT bits in SEQ_FLAGS to indicate that the nexus is invalid in await busfree. aic7xxx_93cx6.c: Add support for the C56/C66 versions of the EWEN and EWDS commands. aic7xxx.c: aic7xxx_pci.c: Move test for the validity of left over BIOS data to ahc_test_register_access(). This guarantees that any left over CHIPRST value is not clobbered by our register access test and lost to the test that was in ahc_reset.
2003-12-17 00:02:10 +00:00
#else
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#endif
#endif
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#include <cam/cam_debug.h>
#include <cam/cam_sim.h>
#include <cam/cam_xpt_sim.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
#ifdef CAM_NEW_TRAN_CODE
#define AHC_NEW_TRAN_SETTINGS
#endif /* CAM_NEW_TRAN_CODE */
/*************************** Attachment Bookkeeping ***************************/
extern devclass_t ahc_devclass;
/****************************** Platform Macros *******************************/
#define SIM_IS_SCSIBUS_B(ahc, sim) \
((sim) == ahc->platform_data->sim_b)
#define SIM_CHANNEL(ahc, sim) \
(((sim) == ahc->platform_data->sim_b) ? 'B' : 'A')
#define SIM_SCSI_ID(ahc, sim) \
(((sim) == ahc->platform_data->sim_b) ? ahc->our_id_b : ahc->our_id)
#define SIM_PATH(ahc, sim) \
(((sim) == ahc->platform_data->sim_b) ? ahc->platform_data->path_b \
: ahc->platform_data->path)
#define BUILD_SCSIID(ahc, sim, target_id, our_id) \
((((target_id) << TID_SHIFT) & TID) | (our_id) \
| (SIM_IS_SCSIBUS_B(ahc, sim) ? TWIN_CHNLB : 0))
#define SCB_GET_SIM(ahc, scb) \
(SCB_GET_CHANNEL(ahc, scb) == 'A' ? (ahc)->platform_data->sim \
: (ahc)->platform_data->sim_b)
ahc_eisa.c: 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.
2001-05-15 19:41:12 +00:00
#ifndef offsetof
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
#endif
/************************ Tunable Driver Parameters **************************/
/*
* The number of dma segments supported. The sequencer can handle any number
* of physically contiguous S/G entrys. To reduce the driver's memory
* consumption, we limit the number supported to be sufficient to handle
* the largest mapping supported by the kernel, MAXPHYS. Assuming the
* transfer is as fragmented as possible and unaligned, this turns out to
* be the number of paged sized transfers in MAXPHYS plus an extra element
* to handle any unaligned residual. The sequencer fetches SG elements
ahc_eisa.c: 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.
2001-05-15 19:41:12 +00:00
* in cacheline sized chucks, so make the number per-transaction an even
* multiple of 16 which should align us on even the largest of cacheline
* boundaries.
*/
#define AHC_NSEG (roundup(btoc(MAXPHYS) + 1, 16))
/* This driver supports target mode */
#define AHC_TARGET_MODE 1
/************************** Softc/SCB Platform Data ***************************/
struct ahc_platform_data {
/*
* Hooks into the XPT.
*/
struct cam_sim *sim;
struct cam_sim *sim_b;
struct cam_path *path;
struct cam_path *path_b;
int regs_res_type;
int regs_res_id;
int irq_res_type;
struct resource *regs;
struct resource *irq;
void *ih;
ahc_eisa.c: 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.
2000-12-20 01:11:37 +00:00
eventhandler_tag eh;
ahc_eisa.c: ahc_pci.c: ahd_pci.c: aic7xxx.c: aic79xx.c: aic_osm_lib.c: aic_osm_lib.h: Use common OSM routines from aic_osm_lib for bus dma operations, delay routines, accessing CCBs, byte swapping, etc. aic7xxx_pci.c: Provide a better description for the 2915/30LP on attach. aic7xxx.c: aic79xx.c: aic7770.c: aic79xx_pci.c: aic7xxx_pci.c: aic7xxx_93cx6.c: Move FBSDID behind an ifdef so that these core files will still compile under other OSes. aic79xx.h: aic79xx_pci.c: aic79xx.seq: To speed up non-packetized CDB delivery in Rev B, all CDB acks are "released" to the output sync as soon as the command phase starts. There is only one problem with this approach. If the target changes phase before all data are sent, we have left over acks that can go out on the bus in a data phase. Due to other chip contraints, this only happens if the target goes to data-in, but if the acks go out before we can test SDONE, we'll think that the transfer has completed successfully. Work around this by taking advantage of the 400ns or 800ns dead time between command phase and the REQ of the new phase. If the transfer has completed successfully, SCSIEN should fall *long* before we see a phase change. We thus treat any phasemiss that occurs before SCSIEN falls as an incomplete transfer. aic79xx.h: Add the AHD_FAST_CDB_DELIVERY feature. aic79xx_pci.c: Set AHD_FAST_CDB_DELIVERY for all Rev. B parts. aic79xx.seq: Test for PHASEMIS in the command phase for all AHD_FAST_CDB_DELIVERY controlelrs. ahd_pci.c: ahc_pci.c: aic7xxx.h: aic79xx.h: Move definition of controller BAR offsets to core header files. aic7xxx.c: aic79xx.c: In the softc free routine, leave removal of a softc from the global list of softcs to the OSM (the caller of this routine). This allows us to avoid holding the softc list_lock during device destruction where we may have to sleep waiting for our recovery thread to halt. ahc_pci.c: Use ahc_pci_test_register access to validate I/O mapped in addition to the tests already performed for memory mapped access. Remove unused ahc_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. ahd_pci.c: Remove reduntant definition of controller BAR offsets. These are also defined in aic79xx.h. Remove unused ahd_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. aic7xxx.c: aic79xx.c: aic79xx.h: aic7xxx.h: aic7xxx_osm.c: aic79xx_osm.c: Move timeout handling to the driver cores. In the case of the aic79xx driver, the algorithm has been enhanced to try target resets before performing a bus reset. For the aic7xxx driver, the algorithm is unchanged. Although the drivers do not currently sleep during recovery (recovery is timeout driven), the cores do expect all processing to be performed via a recovery thread. Our timeout handlers are now little stubs that wakeup the recovery thread. aic79xx.c: aic79xx.h: aic79xx_inline.h: Change shared_data allocation to use a map_node so that the sentinel hscb can use this map node in ahd_swap_with_next_hscb. This routine now swaps the hscb_map pointer in additon to the hscb contents so that any sync operations occur on the correct map. physaddr -> busaddr Pointed out by: Jason Thorpe <thorpej@wasabisystems.com> aic79xx.c: Make more use of the in/out/w/l/q macros for accessing byte registers in the chip. Correct some issues in the ahd_flush_qoutfifo() routine. o Run the qoutfifo only once the command channel DMA engine has been halted. This closes a window where we might have missed some entries. o Change ahd_run_data_fifo() to not loop to completion. If we happen to start on the wrong FIFO and the other FIFO has a snapshot savepointers, we might deadlock. This required our delay between FIFO tests to be moved to the ahd_flush_qoutfifo() routine. o Update/add comments. o Remove spurious test for COMPLETE_DMA list being empty when completing transactions from the GSFIFO with residuals. The SCB must be put on the COMPLETE_DMA scb list unconditionally. o When halting command channel DMA activity, we must disable the DMA channel in all cases but an update of the QOUTFIFO. The latter case is required so that the sequencer will update its position in the QOUTFIFO. Previously, we left the channel enabled for all "push" DMAs. This left us vulnerable to the sequencer handling an SCB push long after that SCB was already processed manually by this routine. o Correct the polarity of tests involving ahd_scb_active_in_fifo(). This routine returns non-zero for true. Return to processing bad status completions through the qoutfifo. This reduces the time that the sequencer is kept paused when handling transactions with bad status or underruns. When waiting for the controller to quiece selections, add a delay to our loop. Otherwise we may fail to wait long enough for the sequencer to comply. On H2A4 hardware, use the slow slewrate for non-paced transfers. This mirrors what the Adaptec Windows drivers do. On the Rev B. only slow down the CRC timing for older U160 devices that might need the slower timing. We define "older" as devices that do not support packetized protocol. Wait up to 5000 * 5us for the SEEPROM to become unbusy. Write ops seem to take much longer than read ops. aic79xx.seq: For controllers with the FAINT_LED bug, turn the diagnostic led feature on during selection and reselection. This covers the non-packetized case. The LED will be disabled for non-packetized transfers once we return to the top level idle loop. Add more comments about the busy LED workaround. Extend a critical section around the entire command channel idle loop process. Previously the portion of this handler that directly manipulated the linked list of completed SCBs was not protected. This is the likely cause of the recent reports of commands being completed twice by the driver. Extend critical sections across the test for, and the longjump to, longjump routines. This prevents the firmware from trying to jump to a longjmp handler that was just cleared by the host. Improve the locations of several critical section begin and end points. Typically these changes remove instructions that did not need to be inside a critical section. Close the "busfree after selection, but before busfree interrupts can be enabled" race to just a single sequencer instruction. We now test the BSY line explicitly before clearing the busfree status and enabling the busfree interrupt. Close a race condition in the processing of HS_MAILBOX updates. We now clear the "updated" status before the copy. This ensures that we don't accidentally clear the status incorrectly when the host sneaks in an update just after our last copy, but before we clear the status. This race has never been observed. Don't re-enable SCSIEN if we lose the race to disable SCSIEN in our interrupt handler's workaround for the RevA data-valid too early issue. aic79xx_inline.h: Add comments indicating that the order in which bytes are read or written in ahd_inw and ahd_outw is important. This allows us to use these inlines when accessing registers with side-effects. aic79xx_pci.c: The 29320 and the 29320B are 7902 not 7901 based products. Correct the driver banner. aic7xxx.h: Enable the use of the auto-access pause feature on the aic7870 and aic7880. It was disabled due to an oversight. aic7xxx.reg: Move TARG_IMMEDIATE_SCB to alias LAST_MSG to avoid leaving garbage in MWI_RESIDUAL. This prevents spurious overflows whn operating target mode on controllers that require the MWI_RESIDUAL work-around. aic7xxx.seq: AHC_TMODE_WIDEODD_BUG is a bug, not a softc flag. Reference the correct softc field when testing for its presence. Set the NOT_IDENTIFIED and NO_CDB_SENT bits in SEQ_FLAGS to indicate that the nexus is invalid in await busfree. aic7xxx_93cx6.c: Add support for the C56/C66 versions of the EWEN and EWDS commands. aic7xxx.c: aic7xxx_pci.c: Move test for the validity of left over BIOS data to ahc_test_register_access(). This guarantees that any left over CHIPRST value is not clobbered by our register access test and lost to the test that was in ahc_reset.
2003-12-17 00:02:10 +00:00
struct proc *recovery_thread;
};
struct scb_platform_data {
};
/***************************** Core Includes **********************************/
#if AHC_REG_PRETTY_PRINT
#define AIC_DEBUG_REGISTERS 1
#else
#define AIC_DEBUG_REGISTERS 0
#endif
ahc_eisa.c: ahc_pci.c: ahd_pci.c: aic7xxx.c: aic79xx.c: aic_osm_lib.c: aic_osm_lib.h: Use common OSM routines from aic_osm_lib for bus dma operations, delay routines, accessing CCBs, byte swapping, etc. aic7xxx_pci.c: Provide a better description for the 2915/30LP on attach. aic7xxx.c: aic79xx.c: aic7770.c: aic79xx_pci.c: aic7xxx_pci.c: aic7xxx_93cx6.c: Move FBSDID behind an ifdef so that these core files will still compile under other OSes. aic79xx.h: aic79xx_pci.c: aic79xx.seq: To speed up non-packetized CDB delivery in Rev B, all CDB acks are "released" to the output sync as soon as the command phase starts. There is only one problem with this approach. If the target changes phase before all data are sent, we have left over acks that can go out on the bus in a data phase. Due to other chip contraints, this only happens if the target goes to data-in, but if the acks go out before we can test SDONE, we'll think that the transfer has completed successfully. Work around this by taking advantage of the 400ns or 800ns dead time between command phase and the REQ of the new phase. If the transfer has completed successfully, SCSIEN should fall *long* before we see a phase change. We thus treat any phasemiss that occurs before SCSIEN falls as an incomplete transfer. aic79xx.h: Add the AHD_FAST_CDB_DELIVERY feature. aic79xx_pci.c: Set AHD_FAST_CDB_DELIVERY for all Rev. B parts. aic79xx.seq: Test for PHASEMIS in the command phase for all AHD_FAST_CDB_DELIVERY controlelrs. ahd_pci.c: ahc_pci.c: aic7xxx.h: aic79xx.h: Move definition of controller BAR offsets to core header files. aic7xxx.c: aic79xx.c: In the softc free routine, leave removal of a softc from the global list of softcs to the OSM (the caller of this routine). This allows us to avoid holding the softc list_lock during device destruction where we may have to sleep waiting for our recovery thread to halt. ahc_pci.c: Use ahc_pci_test_register access to validate I/O mapped in addition to the tests already performed for memory mapped access. Remove unused ahc_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. ahd_pci.c: Remove reduntant definition of controller BAR offsets. These are also defined in aic79xx.h. Remove unused ahd_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. aic7xxx.c: aic79xx.c: aic79xx.h: aic7xxx.h: aic7xxx_osm.c: aic79xx_osm.c: Move timeout handling to the driver cores. In the case of the aic79xx driver, the algorithm has been enhanced to try target resets before performing a bus reset. For the aic7xxx driver, the algorithm is unchanged. Although the drivers do not currently sleep during recovery (recovery is timeout driven), the cores do expect all processing to be performed via a recovery thread. Our timeout handlers are now little stubs that wakeup the recovery thread. aic79xx.c: aic79xx.h: aic79xx_inline.h: Change shared_data allocation to use a map_node so that the sentinel hscb can use this map node in ahd_swap_with_next_hscb. This routine now swaps the hscb_map pointer in additon to the hscb contents so that any sync operations occur on the correct map. physaddr -> busaddr Pointed out by: Jason Thorpe <thorpej@wasabisystems.com> aic79xx.c: Make more use of the in/out/w/l/q macros for accessing byte registers in the chip. Correct some issues in the ahd_flush_qoutfifo() routine. o Run the qoutfifo only once the command channel DMA engine has been halted. This closes a window where we might have missed some entries. o Change ahd_run_data_fifo() to not loop to completion. If we happen to start on the wrong FIFO and the other FIFO has a snapshot savepointers, we might deadlock. This required our delay between FIFO tests to be moved to the ahd_flush_qoutfifo() routine. o Update/add comments. o Remove spurious test for COMPLETE_DMA list being empty when completing transactions from the GSFIFO with residuals. The SCB must be put on the COMPLETE_DMA scb list unconditionally. o When halting command channel DMA activity, we must disable the DMA channel in all cases but an update of the QOUTFIFO. The latter case is required so that the sequencer will update its position in the QOUTFIFO. Previously, we left the channel enabled for all "push" DMAs. This left us vulnerable to the sequencer handling an SCB push long after that SCB was already processed manually by this routine. o Correct the polarity of tests involving ahd_scb_active_in_fifo(). This routine returns non-zero for true. Return to processing bad status completions through the qoutfifo. This reduces the time that the sequencer is kept paused when handling transactions with bad status or underruns. When waiting for the controller to quiece selections, add a delay to our loop. Otherwise we may fail to wait long enough for the sequencer to comply. On H2A4 hardware, use the slow slewrate for non-paced transfers. This mirrors what the Adaptec Windows drivers do. On the Rev B. only slow down the CRC timing for older U160 devices that might need the slower timing. We define "older" as devices that do not support packetized protocol. Wait up to 5000 * 5us for the SEEPROM to become unbusy. Write ops seem to take much longer than read ops. aic79xx.seq: For controllers with the FAINT_LED bug, turn the diagnostic led feature on during selection and reselection. This covers the non-packetized case. The LED will be disabled for non-packetized transfers once we return to the top level idle loop. Add more comments about the busy LED workaround. Extend a critical section around the entire command channel idle loop process. Previously the portion of this handler that directly manipulated the linked list of completed SCBs was not protected. This is the likely cause of the recent reports of commands being completed twice by the driver. Extend critical sections across the test for, and the longjump to, longjump routines. This prevents the firmware from trying to jump to a longjmp handler that was just cleared by the host. Improve the locations of several critical section begin and end points. Typically these changes remove instructions that did not need to be inside a critical section. Close the "busfree after selection, but before busfree interrupts can be enabled" race to just a single sequencer instruction. We now test the BSY line explicitly before clearing the busfree status and enabling the busfree interrupt. Close a race condition in the processing of HS_MAILBOX updates. We now clear the "updated" status before the copy. This ensures that we don't accidentally clear the status incorrectly when the host sneaks in an update just after our last copy, but before we clear the status. This race has never been observed. Don't re-enable SCSIEN if we lose the race to disable SCSIEN in our interrupt handler's workaround for the RevA data-valid too early issue. aic79xx_inline.h: Add comments indicating that the order in which bytes are read or written in ahd_inw and ahd_outw is important. This allows us to use these inlines when accessing registers with side-effects. aic79xx_pci.c: The 29320 and the 29320B are 7902 not 7901 based products. Correct the driver banner. aic7xxx.h: Enable the use of the auto-access pause feature on the aic7870 and aic7880. It was disabled due to an oversight. aic7xxx.reg: Move TARG_IMMEDIATE_SCB to alias LAST_MSG to avoid leaving garbage in MWI_RESIDUAL. This prevents spurious overflows whn operating target mode on controllers that require the MWI_RESIDUAL work-around. aic7xxx.seq: AHC_TMODE_WIDEODD_BUG is a bug, not a softc flag. Reference the correct softc field when testing for its presence. Set the NOT_IDENTIFIED and NO_CDB_SENT bits in SEQ_FLAGS to indicate that the nexus is invalid in await busfree. aic7xxx_93cx6.c: Add support for the C56/C66 versions of the EWEN and EWDS commands. aic7xxx.c: aic7xxx_pci.c: Move test for the validity of left over BIOS data to ahc_test_register_access(). This guarantees that any left over CHIPRST value is not clobbered by our register access test and lost to the test that was in ahc_reset.
2003-12-17 00:02:10 +00:00
#define AIC_CORE_INCLUDE <dev/aic7xxx/aic7xxx.h>
#define AIC_LIB_PREFIX ahc
#define AIC_CONST_PREFIX AHC
#include <dev/aic7xxx/aic_osm_lib.h>
/*************************** Device Access ************************************/
#define ahc_inb(ahc, port) \
bus_space_read_1((ahc)->tag, (ahc)->bsh, port)
#define ahc_outb(ahc, port, value) \
bus_space_write_1((ahc)->tag, (ahc)->bsh, port, value)
#define ahc_outsb(ahc, port, valp, count) \
bus_space_write_multi_1((ahc)->tag, (ahc)->bsh, port, valp, count)
#define ahc_insb(ahc, port, valp, count) \
bus_space_read_multi_1((ahc)->tag, (ahc)->bsh, port, valp, count)
static __inline void ahc_flush_device_writes(struct ahc_softc *);
static __inline void
ahc_flush_device_writes(struct ahc_softc *ahc)
{
/* XXX Is this sufficient for all architectures??? */
ahc_inb(ahc, INTSTAT);
}
/**************************** Locking Primitives ******************************/
/* Lock protecting internal data structures */
static __inline void ahc_lockinit(struct ahc_softc *);
static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags);
static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags);
/* Lock held during command compeletion to the upper layer */
static __inline void ahc_done_lockinit(struct ahc_softc *);
static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags);
static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags);
/* Lock held during ahc_list manipulation and ahc softc frees */
static __inline void ahc_list_lockinit(void);
static __inline void ahc_list_lock(unsigned long *flags);
static __inline void ahc_list_unlock(unsigned long *flags);
static __inline void
ahc_lockinit(struct ahc_softc *ahc)
{
}
static __inline void
ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
{
*flags = splcam();
}
static __inline void
ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
{
splx(*flags);
}
/* Lock held during command compeletion to the upper layer */
static __inline void
ahc_done_lockinit(struct ahc_softc *ahc)
{
}
static __inline void
ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags)
{
}
static __inline void
ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags)
{
}
/* Lock held during ahc_list manipulation and ahc softc frees */
static __inline void
ahc_list_lockinit(void)
{
}
static __inline void
ahc_list_lock(unsigned long *flags)
{
}
static __inline void
ahc_list_unlock(unsigned long *flags)
{
}
/********************************** PCI ***************************************/
ahc_eisa.c: ahc_pci.c: ahd_pci.c: aic7xxx.c: aic79xx.c: aic_osm_lib.c: aic_osm_lib.h: Use common OSM routines from aic_osm_lib for bus dma operations, delay routines, accessing CCBs, byte swapping, etc. aic7xxx_pci.c: Provide a better description for the 2915/30LP on attach. aic7xxx.c: aic79xx.c: aic7770.c: aic79xx_pci.c: aic7xxx_pci.c: aic7xxx_93cx6.c: Move FBSDID behind an ifdef so that these core files will still compile under other OSes. aic79xx.h: aic79xx_pci.c: aic79xx.seq: To speed up non-packetized CDB delivery in Rev B, all CDB acks are "released" to the output sync as soon as the command phase starts. There is only one problem with this approach. If the target changes phase before all data are sent, we have left over acks that can go out on the bus in a data phase. Due to other chip contraints, this only happens if the target goes to data-in, but if the acks go out before we can test SDONE, we'll think that the transfer has completed successfully. Work around this by taking advantage of the 400ns or 800ns dead time between command phase and the REQ of the new phase. If the transfer has completed successfully, SCSIEN should fall *long* before we see a phase change. We thus treat any phasemiss that occurs before SCSIEN falls as an incomplete transfer. aic79xx.h: Add the AHD_FAST_CDB_DELIVERY feature. aic79xx_pci.c: Set AHD_FAST_CDB_DELIVERY for all Rev. B parts. aic79xx.seq: Test for PHASEMIS in the command phase for all AHD_FAST_CDB_DELIVERY controlelrs. ahd_pci.c: ahc_pci.c: aic7xxx.h: aic79xx.h: Move definition of controller BAR offsets to core header files. aic7xxx.c: aic79xx.c: In the softc free routine, leave removal of a softc from the global list of softcs to the OSM (the caller of this routine). This allows us to avoid holding the softc list_lock during device destruction where we may have to sleep waiting for our recovery thread to halt. ahc_pci.c: Use ahc_pci_test_register access to validate I/O mapped in addition to the tests already performed for memory mapped access. Remove unused ahc_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. ahd_pci.c: Remove reduntant definition of controller BAR offsets. These are also defined in aic79xx.h. Remove unused ahd_power_state_change() function. The PCI layer in both 4.X and 5.X now offer this functionality. aic7xxx.c: aic79xx.c: aic79xx.h: aic7xxx.h: aic7xxx_osm.c: aic79xx_osm.c: Move timeout handling to the driver cores. In the case of the aic79xx driver, the algorithm has been enhanced to try target resets before performing a bus reset. For the aic7xxx driver, the algorithm is unchanged. Although the drivers do not currently sleep during recovery (recovery is timeout driven), the cores do expect all processing to be performed via a recovery thread. Our timeout handlers are now little stubs that wakeup the recovery thread. aic79xx.c: aic79xx.h: aic79xx_inline.h: Change shared_data allocation to use a map_node so that the sentinel hscb can use this map node in ahd_swap_with_next_hscb. This routine now swaps the hscb_map pointer in additon to the hscb contents so that any sync operations occur on the correct map. physaddr -> busaddr Pointed out by: Jason Thorpe <thorpej@wasabisystems.com> aic79xx.c: Make more use of the in/out/w/l/q macros for accessing byte registers in the chip. Correct some issues in the ahd_flush_qoutfifo() routine. o Run the qoutfifo only once the command channel DMA engine has been halted. This closes a window where we might have missed some entries. o Change ahd_run_data_fifo() to not loop to completion. If we happen to start on the wrong FIFO and the other FIFO has a snapshot savepointers, we might deadlock. This required our delay between FIFO tests to be moved to the ahd_flush_qoutfifo() routine. o Update/add comments. o Remove spurious test for COMPLETE_DMA list being empty when completing transactions from the GSFIFO with residuals. The SCB must be put on the COMPLETE_DMA scb list unconditionally. o When halting command channel DMA activity, we must disable the DMA channel in all cases but an update of the QOUTFIFO. The latter case is required so that the sequencer will update its position in the QOUTFIFO. Previously, we left the channel enabled for all "push" DMAs. This left us vulnerable to the sequencer handling an SCB push long after that SCB was already processed manually by this routine. o Correct the polarity of tests involving ahd_scb_active_in_fifo(). This routine returns non-zero for true. Return to processing bad status completions through the qoutfifo. This reduces the time that the sequencer is kept paused when handling transactions with bad status or underruns. When waiting for the controller to quiece selections, add a delay to our loop. Otherwise we may fail to wait long enough for the sequencer to comply. On H2A4 hardware, use the slow slewrate for non-paced transfers. This mirrors what the Adaptec Windows drivers do. On the Rev B. only slow down the CRC timing for older U160 devices that might need the slower timing. We define "older" as devices that do not support packetized protocol. Wait up to 5000 * 5us for the SEEPROM to become unbusy. Write ops seem to take much longer than read ops. aic79xx.seq: For controllers with the FAINT_LED bug, turn the diagnostic led feature on during selection and reselection. This covers the non-packetized case. The LED will be disabled for non-packetized transfers once we return to the top level idle loop. Add more comments about the busy LED workaround. Extend a critical section around the entire command channel idle loop process. Previously the portion of this handler that directly manipulated the linked list of completed SCBs was not protected. This is the likely cause of the recent reports of commands being completed twice by the driver. Extend critical sections across the test for, and the longjump to, longjump routines. This prevents the firmware from trying to jump to a longjmp handler that was just cleared by the host. Improve the locations of several critical section begin and end points. Typically these changes remove instructions that did not need to be inside a critical section. Close the "busfree after selection, but before busfree interrupts can be enabled" race to just a single sequencer instruction. We now test the BSY line explicitly before clearing the busfree status and enabling the busfree interrupt. Close a race condition in the processing of HS_MAILBOX updates. We now clear the "updated" status before the copy. This ensures that we don't accidentally clear the status incorrectly when the host sneaks in an update just after our last copy, but before we clear the status. This race has never been observed. Don't re-enable SCSIEN if we lose the race to disable SCSIEN in our interrupt handler's workaround for the RevA data-valid too early issue. aic79xx_inline.h: Add comments indicating that the order in which bytes are read or written in ahd_inw and ahd_outw is important. This allows us to use these inlines when accessing registers with side-effects. aic79xx_pci.c: The 29320 and the 29320B are 7902 not 7901 based products. Correct the driver banner. aic7xxx.h: Enable the use of the auto-access pause feature on the aic7870 and aic7880. It was disabled due to an oversight. aic7xxx.reg: Move TARG_IMMEDIATE_SCB to alias LAST_MSG to avoid leaving garbage in MWI_RESIDUAL. This prevents spurious overflows whn operating target mode on controllers that require the MWI_RESIDUAL work-around. aic7xxx.seq: AHC_TMODE_WIDEODD_BUG is a bug, not a softc flag. Reference the correct softc field when testing for its presence. Set the NOT_IDENTIFIED and NO_CDB_SENT bits in SEQ_FLAGS to indicate that the nexus is invalid in await busfree. aic7xxx_93cx6.c: Add support for the C56/C66 versions of the EWEN and EWDS commands. aic7xxx.c: aic7xxx_pci.c: Move test for the validity of left over BIOS data to ahc_test_register_access(). This guarantees that any left over CHIPRST value is not clobbered by our register access test and lost to the test that was in ahc_reset.
2003-12-17 00:02:10 +00:00
#ifdef AIC_PCI_CONFIG
int ahc_pci_map_registers(struct ahc_softc *ahc);
int ahc_pci_map_int(struct ahc_softc *ahc);
#endif /*AIC_PCI_CONFIG*/
/******************************** VL/EISA *************************************/
Major update to the aic7xxx driver: 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
2002-04-24 16:58:51 +00:00
int aic7770_map_registers(struct ahc_softc *ahc, u_int port);
This is an MFC candidate. 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.
2001-03-11 06:34:17 +00:00
int aic7770_map_int(struct ahc_softc *ahc, int irq);
/********************************* Debug **************************************/
static __inline void ahc_print_path(struct ahc_softc *, struct scb *);
static __inline void ahc_platform_dump_card_state(struct ahc_softc *ahc);
static __inline void
ahc_print_path(struct ahc_softc *ahc, struct scb *scb)
{
xpt_print_path(scb->io_ctx->ccb_h.path);
}
static __inline void
ahc_platform_dump_card_state(struct ahc_softc *ahc)
{
/* Nothing to do here for FreeBSD */
}
/**************************** Transfer Settings *******************************/
void ahc_notify_xfer_settings_change(struct ahc_softc *,
struct ahc_devinfo *);
void ahc_platform_set_tags(struct ahc_softc *, struct ahc_devinfo *,
int /*enable*/);
ahc_eisa.c: 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.
2000-12-20 01:11:37 +00:00
/************************* Initialization/Teardown ****************************/
int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
void ahc_platform_free(struct ahc_softc *ahc);
Major update to the aic7xxx driver: 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
2002-04-24 16:58:51 +00:00
int ahc_map_int(struct ahc_softc *ahc);
int ahc_attach(struct ahc_softc *);
int ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc);
ahc_eisa.c: 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.
2000-12-20 01:11:37 +00:00
int ahc_detach(device_t);
/****************************** Interrupts ************************************/
void ahc_platform_intr(void *);
static __inline void ahc_platform_flushwork(struct ahc_softc *ahc);
static __inline void
ahc_platform_flushwork(struct ahc_softc *ahc)
{
}
/************************ Misc Function Declarations **************************/
void ahc_done(struct ahc_softc *ahc, struct scb *scb);
Add Perforce RCSIDs for easy revision correlation to my local tree. ahc_pci.c: Bring back the AHC_ALLOW_MEMIO option at least until the memory mapped I/O problem on the SuperMicro 370DR3 is better understood. aic7xxx.c: If we see a spurious SCSI interrupt, attempt to clear it and continue by unpausing the sequencer. Change the interface to ahc_send_async(). Some async messages need to be broadcast to all the luns of a target or all the targets of a bus. This is easier to achieve by passing explicit channel, target, and lun parameters instead of attempting to construct a device info struct to match. Filter the sync parameters for the PPR message in exactly the same way we do for an old fashioned SDTR message. Correct some typos and correct a panic message. Handle rejected PPR messages. In ahc_handle_msg_reject(), let ahc_build_transfer_msg() build any additional transfer messages instead of doing this inline. aic7xxx.h: Increase the size of both msgout_buf and msgin_buf to better accomodate PPR messages. aic7xxx_freebsd.c: Update for change in ahc_send_async() parameters. aic7xxx_freebsd.h Update for change in ahc_send_async() parameters. Honor AHC_ALLOW_MEMIO. aic7xxx_pci.c: Check the error register before going into full blown PCI interrupt handling. This avoids a few costly PCI configuration space reads when we run our PCI interrupt handler because another device sharing our interrupt line is more active than we are. Also unpause the sequencer after processing a PCI interrupt.
2000-09-22 22:18:05 +00:00
void ahc_send_async(struct ahc_softc *, char /*channel*/,
ahc_eisa.c: 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.
2001-05-15 19:41:12 +00:00
u_int /*target*/, u_int /*lun*/, ac_code, void *arg);
#endif /* _AIC7XXX_FREEBSD_H_ */