2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Product specific probe and attach routines for:
|
|
|
|
* 3940, 2940, aic7895, aic7890, aic7880,
|
|
|
|
* aic7870, aic7860 and aic7850 SCSI controllers
|
|
|
|
*
|
2002-04-24 16:58:51 +00:00
|
|
|
* Copyright (c) 1994-2001 Justin T. Gibbs.
|
|
|
|
* Copyright (c) 2000-2001 Adaptec Inc.
|
2000-09-16 20:02:28 +00:00
|
|
|
* 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,
|
2002-04-24 16:58:51 +00:00
|
|
|
* without modification.
|
|
|
|
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
|
|
|
* substantially similar to the "NO WARRANTY" disclaimer below
|
|
|
|
* ("Disclaimer") and any redistribution must be conditioned upon
|
|
|
|
* including a substantially similar Disclaimer requirement for further
|
|
|
|
* binary redistribution.
|
|
|
|
* 3. Neither the names of the above-listed copyright holders nor the names
|
|
|
|
* of any contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
2000-09-16 20:02:28 +00:00
|
|
|
*
|
|
|
|
* Alternatively, this software may be distributed under the terms of the
|
2002-04-24 16:58:51 +00:00
|
|
|
* GNU General Public License ("GPL") version 2 as published by the Free
|
|
|
|
* Software Foundation.
|
2000-09-16 20:02:28 +00:00
|
|
|
*
|
2002-04-24 16:58:51 +00:00
|
|
|
* NO WARRANTY
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
2000-09-16 20:02:28 +00:00
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
2002-04-24 16:58:51 +00:00
|
|
|
* 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 DAMAGES.
|
2000-09-16 20:02:28 +00:00
|
|
|
*
|
2003-06-06 23:48:19 +00:00
|
|
|
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#68 $
|
2000-09-16 20:02:28 +00:00
|
|
|
*
|
|
|
|
* $FreeBSD$
|
|
|
|
*/
|
|
|
|
|
2002-04-24 16:58:51 +00:00
|
|
|
#ifdef __linux__
|
|
|
|
#include "aic7xxx_osm.h"
|
|
|
|
#include "aic7xxx_inline.h"
|
|
|
|
#include "aic7xxx_93cx6.h"
|
|
|
|
#else
|
|
|
|
#include <dev/aic7xxx/aic7xxx_osm.h>
|
2000-09-16 20:02:28 +00:00
|
|
|
#include <dev/aic7xxx/aic7xxx_inline.h>
|
|
|
|
#include <dev/aic7xxx/aic7xxx_93cx6.h>
|
2002-04-24 16:58:51 +00:00
|
|
|
#endif
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
#define AHC_PCI_IOADDR PCIR_MAPS /* I/O Address */
|
|
|
|
#define AHC_PCI_MEMADDR (PCIR_MAPS + 4) /* Mem I/O Address */
|
|
|
|
|
|
|
|
static __inline uint64_t
|
|
|
|
ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
|
|
|
|
{
|
|
|
|
uint64_t id;
|
|
|
|
|
|
|
|
id = subvendor
|
|
|
|
| (subdevice << 16)
|
|
|
|
| ((uint64_t)vendor << 32)
|
|
|
|
| ((uint64_t)device << 48);
|
|
|
|
|
|
|
|
return (id);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull
|
|
|
|
#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
|
|
|
|
#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
|
|
|
|
#define ID_9005_SISL_MASK 0x000FFFFF00000000ull
|
|
|
|
#define ID_9005_SISL_ID 0x0005900500000000ull
|
|
|
|
#define ID_AIC7850 0x5078900400000000ull
|
2003-05-26 21:45:09 +00:00
|
|
|
#define ID_AHA_2902_04_10_15_20C_30C 0x5078900478509004ull
|
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
|
|
|
#define ID_AIC7855 0x5578900400000000ull
|
|
|
|
#define ID_AIC7859 0x3860900400000000ull
|
|
|
|
#define ID_AHA_2930CU 0x3860900438699004ull
|
|
|
|
#define ID_AIC7860 0x6078900400000000ull
|
|
|
|
#define ID_AIC7860C 0x6078900478609004ull
|
|
|
|
#define ID_AHA_1480A 0x6075900400000000ull
|
|
|
|
#define ID_AHA_2940AU_0 0x6178900400000000ull
|
|
|
|
#define ID_AHA_2940AU_1 0x6178900478619004ull
|
|
|
|
#define ID_AHA_2940AU_CN 0x2178900478219004ull
|
|
|
|
#define ID_AHA_2930C_VAR 0x6038900438689004ull
|
|
|
|
|
|
|
|
#define ID_AIC7870 0x7078900400000000ull
|
|
|
|
#define ID_AHA_2940 0x7178900400000000ull
|
|
|
|
#define ID_AHA_3940 0x7278900400000000ull
|
|
|
|
#define ID_AHA_398X 0x7378900400000000ull
|
|
|
|
#define ID_AHA_2944 0x7478900400000000ull
|
|
|
|
#define ID_AHA_3944 0x7578900400000000ull
|
|
|
|
#define ID_AHA_4944 0x7678900400000000ull
|
|
|
|
|
|
|
|
#define ID_AIC7880 0x8078900400000000ull
|
|
|
|
#define ID_AIC7880_B 0x8078900478809004ull
|
|
|
|
#define ID_AHA_2940U 0x8178900400000000ull
|
|
|
|
#define ID_AHA_3940U 0x8278900400000000ull
|
|
|
|
#define ID_AHA_2944U 0x8478900400000000ull
|
|
|
|
#define ID_AHA_3944U 0x8578900400000000ull
|
|
|
|
#define ID_AHA_398XU 0x8378900400000000ull
|
|
|
|
#define ID_AHA_4944U 0x8678900400000000ull
|
|
|
|
#define ID_AHA_2940UB 0x8178900478819004ull
|
|
|
|
#define ID_AHA_2930U 0x8878900478889004ull
|
|
|
|
#define ID_AHA_2940U_PRO 0x8778900478879004ull
|
|
|
|
#define ID_AHA_2940U_CN 0x0078900478009004ull
|
|
|
|
|
|
|
|
#define ID_AIC7895 0x7895900478959004ull
|
|
|
|
#define ID_AIC7895_ARO 0x7890900478939004ull
|
|
|
|
#define ID_AIC7895_ARO_MASK 0xFFF0FFFFFFFFFFFFull
|
|
|
|
#define ID_AHA_2940U_DUAL 0x7895900478919004ull
|
|
|
|
#define ID_AHA_3940AU 0x7895900478929004ull
|
|
|
|
#define ID_AHA_3944AU 0x7895900478949004ull
|
|
|
|
|
|
|
|
#define ID_AIC7890 0x001F9005000F9005ull
|
|
|
|
#define ID_AIC7890_ARO 0x00139005000F9005ull
|
|
|
|
#define ID_AAA_131U2 0x0013900500039005ull
|
|
|
|
#define ID_AHA_2930U2 0x0011900501819005ull
|
|
|
|
#define ID_AHA_2940U2B 0x00109005A1009005ull
|
|
|
|
#define ID_AHA_2940U2_OEM 0x0010900521809005ull
|
|
|
|
#define ID_AHA_2940U2 0x00109005A1809005ull
|
|
|
|
#define ID_AHA_2950U2B 0x00109005E1009005ull
|
|
|
|
|
|
|
|
#define ID_AIC7892 0x008F9005FFFF9005ull
|
|
|
|
#define ID_AIC7892_ARO 0x00839005FFFF9005ull
|
|
|
|
#define ID_AHA_29160 0x00809005E2A09005ull
|
|
|
|
#define ID_AHA_29160_CPQ 0x00809005E2A00E11ull
|
|
|
|
#define ID_AHA_29160N 0x0080900562A09005ull
|
|
|
|
#define ID_AHA_29160C 0x0080900562209005ull
|
|
|
|
#define ID_AHA_29160B 0x00809005E2209005ull
|
|
|
|
#define ID_AHA_19160B 0x0081900562A19005ull
|
|
|
|
|
|
|
|
#define ID_AIC7896 0x005F9005FFFF9005ull
|
|
|
|
#define ID_AIC7896_ARO 0x00539005FFFF9005ull
|
|
|
|
#define ID_AHA_3950U2B_0 0x00509005FFFF9005ull
|
|
|
|
#define ID_AHA_3950U2B_1 0x00509005F5009005ull
|
|
|
|
#define ID_AHA_3950U2D_0 0x00519005FFFF9005ull
|
|
|
|
#define ID_AHA_3950U2D_1 0x00519005B5009005ull
|
|
|
|
|
|
|
|
#define ID_AIC7899 0x00CF9005FFFF9005ull
|
|
|
|
#define ID_AIC7899_ARO 0x00C39005FFFF9005ull
|
|
|
|
#define ID_AHA_3960D 0x00C09005F6209005ull
|
|
|
|
#define ID_AHA_3960D_CPQ 0x00C09005F6200E11ull
|
|
|
|
|
|
|
|
#define ID_AIC7810 0x1078900400000000ull
|
|
|
|
#define ID_AIC7815 0x7815900400000000ull
|
2000-09-16 20:02:28 +00:00
|
|
|
|
aic7xxx.c:
Style nits.
Make sure that our selection hardware is disabled
as soon as possible after detecting a busfree and
even go so far as to disable the selection hardware
in advance of an event that will cause a busfree
(ABORT or BUS DEVICE RESET message). The concern
is that the selection hardware will select a target
for which, after processing the bus free, there
will be no commands pending. The sequencer idle
loop will re-enable the selection should it still be
necessary.
In ahc_handle_scsiint(), clear SSTAT0 events several
PCI transactions (most notably reads) prior to clearing
SCSIINT. The newer chips seem to take a bit of time to
see the change which can make the clearing of SCSIINT
ineffective.
Don't bother panicing at the end of ahc_handle_scsiint().
Getting to the final else just means we lost the race
with clearing SCSIINT.
In ahc_free(), handle init-level 0. This can happen when we
fail the attach for RAID devices. While I'm here, also kill
the parent dma tag.
In ahc_match_scb(), consider initiator ccbs to be any
that are not from the target mode group. This fixes
a bug where an external target reset CCB was not getting
cleaned up by the reset code.
Don't bother freezing a ccb in any of our "abort" routines
when the status is set to CAM_REQ_CMP. This can happen
for a target reset ccb.
aic7xxx.reg:
Reserve space for a completion queue. This will be used
to enhance performance in the near future.
aic7xxx.seq:
Remove an optimization for the 7890 autoflush bug that
turned out to allow, in rare cases, some data to get
lost.
Implement a simpler, faster, fix for the PCI_2_1 retry
bug that hangs the sequencer on an SCB dma for certain chips.
Test against SAVED_SCSIID rather than SELID during target
reselections. This is how we always did it in the past,
but the code was modified while trying to work around an
issue with the 7895. SAVED_SCSIID takes into account
twin channel adapters such as the 2742T, whereas SELID
does not have the channel bit. This caused invalid
selection warnings and other strangeness on these cards.
aic7xxx_pci.c
Use the correct mask for checking the generic aic7892
entry.
2001-02-10 18:04:27 +00:00
|
|
|
#define DEVID_9005_TYPE(id) ((id) & 0xF)
|
|
|
|
#define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
|
|
|
|
#define DEVID_9005_TYPE_AAA 0x3 /* RAID Card */
|
2002-04-24 16:58:51 +00:00
|
|
|
#define DEVID_9005_TYPE_SISL 0x5 /* Container ROMB */
|
aic7xxx.c:
Style nits.
Make sure that our selection hardware is disabled
as soon as possible after detecting a busfree and
even go so far as to disable the selection hardware
in advance of an event that will cause a busfree
(ABORT or BUS DEVICE RESET message). The concern
is that the selection hardware will select a target
for which, after processing the bus free, there
will be no commands pending. The sequencer idle
loop will re-enable the selection should it still be
necessary.
In ahc_handle_scsiint(), clear SSTAT0 events several
PCI transactions (most notably reads) prior to clearing
SCSIINT. The newer chips seem to take a bit of time to
see the change which can make the clearing of SCSIINT
ineffective.
Don't bother panicing at the end of ahc_handle_scsiint().
Getting to the final else just means we lost the race
with clearing SCSIINT.
In ahc_free(), handle init-level 0. This can happen when we
fail the attach for RAID devices. While I'm here, also kill
the parent dma tag.
In ahc_match_scb(), consider initiator ccbs to be any
that are not from the target mode group. This fixes
a bug where an external target reset CCB was not getting
cleaned up by the reset code.
Don't bother freezing a ccb in any of our "abort" routines
when the status is set to CAM_REQ_CMP. This can happen
for a target reset ccb.
aic7xxx.reg:
Reserve space for a completion queue. This will be used
to enhance performance in the near future.
aic7xxx.seq:
Remove an optimization for the 7890 autoflush bug that
turned out to allow, in rare cases, some data to get
lost.
Implement a simpler, faster, fix for the PCI_2_1 retry
bug that hangs the sequencer on an SCB dma for certain chips.
Test against SAVED_SCSIID rather than SELID during target
reselections. This is how we always did it in the past,
but the code was modified while trying to work around an
issue with the 7895. SAVED_SCSIID takes into account
twin channel adapters such as the 2742T, whereas SELID
does not have the channel bit. This caused invalid
selection warnings and other strangeness on these cards.
aic7xxx_pci.c
Use the correct mask for checking the generic aic7892
entry.
2001-02-10 18:04:27 +00:00
|
|
|
#define DEVID_9005_TYPE_MB 0xF /* On Motherboard */
|
|
|
|
|
|
|
|
#define DEVID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
|
|
|
|
#define DEVID_9005_MAXRATE_U160 0x0
|
|
|
|
#define DEVID_9005_MAXRATE_ULTRA2 0x1
|
|
|
|
#define DEVID_9005_MAXRATE_ULTRA 0x2
|
|
|
|
#define DEVID_9005_MAXRATE_FAST 0x3
|
|
|
|
|
|
|
|
#define DEVID_9005_MFUNC(id) (((id) & 0x40) >> 6)
|
|
|
|
|
|
|
|
#define DEVID_9005_CLASS(id) (((id) & 0xFF00) >> 8)
|
|
|
|
#define DEVID_9005_CLASS_SPI 0x0 /* Parallel SCSI */
|
|
|
|
|
2001-01-05 19:15:37 +00:00
|
|
|
#define SUBID_9005_TYPE(id) ((id) & 0xF)
|
|
|
|
#define SUBID_9005_TYPE_MB 0xF /* On Motherboard */
|
|
|
|
#define SUBID_9005_TYPE_CARD 0x0 /* Standard Card */
|
|
|
|
#define SUBID_9005_TYPE_LCCARD 0x1 /* Low Cost Card */
|
|
|
|
#define SUBID_9005_TYPE_RAID 0x3 /* Combined with Raid */
|
|
|
|
|
2001-02-21 20:50:36 +00:00
|
|
|
#define SUBID_9005_TYPE_KNOWN(id) \
|
|
|
|
((((id) & 0xF) == SUBID_9005_TYPE_MB) \
|
|
|
|
|| (((id) & 0xF) == SUBID_9005_TYPE_CARD) \
|
|
|
|
|| (((id) & 0xF) == SUBID_9005_TYPE_LCCARD) \
|
|
|
|
|| (((id) & 0xF) == SUBID_9005_TYPE_RAID))
|
|
|
|
|
2001-01-05 19:15:37 +00:00
|
|
|
#define SUBID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
|
|
|
|
#define SUBID_9005_MAXRATE_ULTRA2 0x0
|
|
|
|
#define SUBID_9005_MAXRATE_ULTRA 0x1
|
|
|
|
#define SUBID_9005_MAXRATE_U160 0x2
|
|
|
|
#define SUBID_9005_MAXRATE_RESERVED 0x3
|
|
|
|
|
|
|
|
#define SUBID_9005_SEEPTYPE(id) \
|
|
|
|
((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
|
|
|
|
? ((id) & 0xC0) >> 6 \
|
|
|
|
: ((id) & 0x300) >> 8)
|
|
|
|
#define SUBID_9005_SEEPTYPE_NONE 0x0
|
|
|
|
#define SUBID_9005_SEEPTYPE_1K 0x1
|
|
|
|
#define SUBID_9005_SEEPTYPE_2K_4K 0x2
|
|
|
|
#define SUBID_9005_SEEPTYPE_RESERVED 0x3
|
|
|
|
#define SUBID_9005_AUTOTERM(id) \
|
|
|
|
((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
|
|
|
|
? (((id) & 0x400) >> 10) == 0 \
|
|
|
|
: (((id) & 0x40) >> 6) == 0)
|
|
|
|
|
|
|
|
#define SUBID_9005_NUMCHAN(id) \
|
|
|
|
((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
|
|
|
|
? ((id) & 0x300) >> 8 \
|
|
|
|
: ((id) & 0xC00) >> 10)
|
|
|
|
|
|
|
|
#define SUBID_9005_LEGACYCONN(id) \
|
|
|
|
((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
|
|
|
|
? 0 \
|
|
|
|
: ((id) & 0x80) >> 7)
|
|
|
|
|
|
|
|
#define SUBID_9005_MFUNCENB(id) \
|
|
|
|
((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
|
|
|
|
? ((id) & 0x800) >> 11 \
|
|
|
|
: ((id) & 0x1000) >> 12)
|
|
|
|
/*
|
|
|
|
* Informational only. Should use chip register to be
|
2002-04-24 16:58:51 +00:00
|
|
|
* certain, but may be use in identification strings.
|
2001-01-05 19:15:37 +00:00
|
|
|
*/
|
|
|
|
#define SUBID_9005_CARD_SCSIWIDTH_MASK 0x2000
|
|
|
|
#define SUBID_9005_CARD_PCIWIDTH_MASK 0x4000
|
|
|
|
#define SUBID_9005_CARD_SEDIFF_MASK 0x8000
|
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
|
|
|
|
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
|
|
|
static ahc_device_setup_t ahc_aic785X_setup;
|
2000-09-16 20:02:28 +00:00
|
|
|
static ahc_device_setup_t ahc_aic7860_setup;
|
2001-01-22 21:03:48 +00:00
|
|
|
static ahc_device_setup_t ahc_apa1480_setup;
|
2000-09-16 20:02:28 +00:00
|
|
|
static ahc_device_setup_t ahc_aic7870_setup;
|
|
|
|
static ahc_device_setup_t ahc_aha394X_setup;
|
|
|
|
static ahc_device_setup_t ahc_aha494X_setup;
|
|
|
|
static ahc_device_setup_t ahc_aha398X_setup;
|
|
|
|
static ahc_device_setup_t ahc_aic7880_setup;
|
2001-01-22 21:03:48 +00:00
|
|
|
static ahc_device_setup_t ahc_aha2940Pro_setup;
|
2000-09-16 20:02:28 +00:00
|
|
|
static ahc_device_setup_t ahc_aha394XU_setup;
|
|
|
|
static ahc_device_setup_t ahc_aha398XU_setup;
|
|
|
|
static ahc_device_setup_t ahc_aic7890_setup;
|
|
|
|
static ahc_device_setup_t ahc_aic7892_setup;
|
|
|
|
static ahc_device_setup_t ahc_aic7895_setup;
|
|
|
|
static ahc_device_setup_t ahc_aic7896_setup;
|
|
|
|
static ahc_device_setup_t ahc_aic7899_setup;
|
2001-01-22 21:03:48 +00:00
|
|
|
static ahc_device_setup_t ahc_aha29160C_setup;
|
2000-09-16 20:02:28 +00:00
|
|
|
static ahc_device_setup_t ahc_raid_setup;
|
|
|
|
static ahc_device_setup_t ahc_aha394XX_setup;
|
|
|
|
static ahc_device_setup_t ahc_aha494XX_setup;
|
|
|
|
static ahc_device_setup_t ahc_aha398XX_setup;
|
|
|
|
|
|
|
|
struct ahc_pci_identity ahc_pci_ident_table [] =
|
|
|
|
{
|
|
|
|
/* aic7850 based controllers */
|
|
|
|
{
|
2003-05-26 21:45:09 +00:00
|
|
|
ID_AHA_2902_04_10_15_20C_30C,
|
2000-09-16 20:02:28 +00:00
|
|
|
ID_ALL_MASK,
|
2003-05-26 21:45:09 +00:00
|
|
|
"Adaptec 2902/04/10/15/20C/30C SCSI adapter",
|
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
|
|
|
ahc_aic785X_setup
|
2000-09-16 20:02:28 +00:00
|
|
|
},
|
|
|
|
/* aic7860 based controllers */
|
|
|
|
{
|
|
|
|
ID_AHA_2930CU,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 2930CU SCSI adapter",
|
|
|
|
ahc_aic7860_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_1480A & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 1480A Ultra SCSI adapter",
|
2001-01-22 21:03:48 +00:00
|
|
|
ahc_apa1480_setup
|
2000-09-16 20:02:28 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 2940A Ultra SCSI adapter",
|
|
|
|
ahc_aic7860_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 2940A/CN Ultra SCSI adapter",
|
|
|
|
ahc_aic7860_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
2001-05-15 19:41:12 +00:00
|
|
|
"Adaptec 2930C Ultra SCSI adapter (VAR)",
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_aic7860_setup
|
|
|
|
},
|
|
|
|
/* aic7870 based controllers */
|
|
|
|
{
|
|
|
|
ID_AHA_2940,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 2940 SCSI adapter",
|
|
|
|
ahc_aic7870_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3940,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 3940 SCSI adapter",
|
|
|
|
ahc_aha394X_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_398X,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 398X SCSI RAID adapter",
|
|
|
|
ahc_aha398X_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2944,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 2944 SCSI adapter",
|
|
|
|
ahc_aic7870_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3944,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 3944 SCSI adapter",
|
|
|
|
ahc_aha394X_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_4944,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 4944 SCSI adapter",
|
|
|
|
ahc_aha494X_setup
|
|
|
|
},
|
|
|
|
/* aic7880 based controllers */
|
|
|
|
{
|
|
|
|
ID_AHA_2940U & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 2940 Ultra SCSI adapter",
|
|
|
|
ahc_aic7880_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3940U & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 3940 Ultra SCSI adapter",
|
|
|
|
ahc_aha394XU_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2944U & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 2944 Ultra SCSI adapter",
|
|
|
|
ahc_aic7880_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3944U & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 3944 Ultra SCSI adapter",
|
|
|
|
ahc_aha394XU_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_398XU & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 398X Ultra SCSI RAID adapter",
|
|
|
|
ahc_aha398XU_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* XXX Don't know the slot numbers
|
|
|
|
* so we can't identify channels
|
|
|
|
*/
|
|
|
|
ID_AHA_4944U & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 4944 Ultra SCSI adapter",
|
|
|
|
ahc_aic7880_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2930U & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 2930 Ultra SCSI adapter",
|
|
|
|
ahc_aic7880_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 2940 Pro Ultra SCSI adapter",
|
2001-01-22 21:03:48 +00:00
|
|
|
ahc_aha2940Pro_setup
|
2000-09-16 20:02:28 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec 2940/CN Ultra SCSI adapter",
|
|
|
|
ahc_aic7880_setup
|
|
|
|
},
|
2001-02-21 20:50:36 +00:00
|
|
|
/* Ignore all SISL (AAC on MB) based controllers. */
|
|
|
|
{
|
|
|
|
ID_9005_SISL_ID,
|
|
|
|
ID_9005_SISL_MASK,
|
|
|
|
NULL,
|
|
|
|
NULL
|
|
|
|
},
|
2000-09-16 20:02:28 +00:00
|
|
|
/* aic7890 based controllers */
|
|
|
|
{
|
|
|
|
ID_AHA_2930U2,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 2930 Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7890_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2940U2B,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 2940B Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7890_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2940U2_OEM,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 2940 Ultra2 SCSI adapter (OEM)",
|
|
|
|
ahc_aic7890_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2940U2,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 2940 Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7890_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_2950U2B,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 2950 Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7890_setup
|
|
|
|
},
|
2001-02-21 20:50:36 +00:00
|
|
|
{
|
|
|
|
ID_AIC7890_ARO,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec aic7890/91 Ultra2 SCSI adapter (ARO)",
|
|
|
|
ahc_aic7890_setup
|
|
|
|
},
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
ID_AAA_131U2,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec AAA-131 Ultra2 RAID adapter",
|
|
|
|
ahc_aic7890_setup
|
|
|
|
},
|
|
|
|
/* aic7892 based controllers */
|
|
|
|
{
|
|
|
|
ID_AHA_29160,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 29160 Ultra160 SCSI adapter",
|
|
|
|
ahc_aic7892_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_29160_CPQ,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec (Compaq OEM) 29160 Ultra160 SCSI adapter",
|
|
|
|
ahc_aic7892_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_29160N,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 29160N Ultra160 SCSI adapter",
|
|
|
|
ahc_aic7892_setup
|
|
|
|
},
|
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
|
|
|
{
|
|
|
|
ID_AHA_29160C,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 29160C Ultra160 SCSI adapter",
|
2001-01-22 21:03:48 +00:00
|
|
|
ahc_aha29160C_setup
|
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
|
|
|
},
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
ID_AHA_29160B,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 29160B Ultra160 SCSI adapter",
|
|
|
|
ahc_aic7892_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_19160B,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 19160B Ultra160 SCSI adapter",
|
|
|
|
ahc_aic7892_setup
|
|
|
|
},
|
2001-02-21 20:50:36 +00:00
|
|
|
{
|
|
|
|
ID_AIC7892_ARO,
|
|
|
|
ID_ALL_MASK,
|
2001-05-15 19:41:12 +00:00
|
|
|
"Adaptec aic7892 Ultra160 SCSI adapter (ARO)",
|
2001-02-21 20:50:36 +00:00
|
|
|
ahc_aic7892_setup
|
|
|
|
},
|
2000-09-16 20:02:28 +00:00
|
|
|
/* aic7895 based controllers */
|
|
|
|
{
|
|
|
|
ID_AHA_2940U_DUAL,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 2940/DUAL Ultra SCSI adapter",
|
|
|
|
ahc_aic7895_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3940AU,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 3940A Ultra SCSI adapter",
|
|
|
|
ahc_aic7895_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3944AU,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 3944A Ultra SCSI adapter",
|
|
|
|
ahc_aic7895_setup
|
|
|
|
},
|
2001-02-21 20:50:36 +00:00
|
|
|
{
|
|
|
|
ID_AIC7895_ARO,
|
|
|
|
ID_AIC7895_ARO_MASK,
|
|
|
|
"Adaptec aic7895 Ultra SCSI adapter (ARO)",
|
|
|
|
ahc_aic7895_setup
|
|
|
|
},
|
2000-09-16 20:02:28 +00:00
|
|
|
/* aic7896/97 based controllers */
|
|
|
|
{
|
|
|
|
ID_AHA_3950U2B_0,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 3950B Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7896_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3950U2B_1,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 3950B Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7896_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3950U2D_0,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 3950D Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7896_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3950U2D_1,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 3950D Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7896_setup
|
|
|
|
},
|
2001-02-21 20:50:36 +00:00
|
|
|
{
|
|
|
|
ID_AIC7896_ARO,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec aic7896/97 Ultra2 SCSI adapter (ARO)",
|
|
|
|
ahc_aic7896_setup
|
|
|
|
},
|
2000-09-16 20:02:28 +00:00
|
|
|
/* aic7899 based controllers */
|
|
|
|
{
|
|
|
|
ID_AHA_3960D,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec 3960D Ultra160 SCSI adapter",
|
|
|
|
ahc_aic7899_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AHA_3960D_CPQ,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec (Compaq OEM) 3960D Ultra160 SCSI adapter",
|
|
|
|
ahc_aic7899_setup
|
|
|
|
},
|
2001-02-21 20:50:36 +00:00
|
|
|
{
|
|
|
|
ID_AIC7899_ARO,
|
|
|
|
ID_ALL_MASK,
|
|
|
|
"Adaptec aic7899 Ultra160 SCSI adapter (ARO)",
|
|
|
|
ahc_aic7899_setup
|
|
|
|
},
|
2000-09-16 20:02:28 +00:00
|
|
|
/* Generic chip probes for devices we don't know 'exactly' */
|
|
|
|
{
|
|
|
|
ID_AIC7850 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec aic7850 SCSI adapter",
|
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
|
|
|
ahc_aic785X_setup
|
2000-09-16 20:02:28 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AIC7855 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec aic7855 SCSI adapter",
|
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
|
|
|
ahc_aic785X_setup
|
2000-09-16 20:02:28 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AIC7859 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
2001-05-15 19:41:12 +00:00
|
|
|
"Adaptec aic7859 SCSI adapter",
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_aic7860_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AIC7860 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
2001-05-15 19:41:12 +00:00
|
|
|
"Adaptec aic7860 Ultra SCSI adapter",
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_aic7860_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AIC7870 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec aic7870 SCSI adapter",
|
|
|
|
ahc_aic7870_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AIC7880 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec aic7880 Ultra SCSI adapter",
|
|
|
|
ahc_aic7880_setup
|
|
|
|
},
|
|
|
|
{
|
aic7xxx.c:
Style nits.
Make sure that our selection hardware is disabled
as soon as possible after detecting a busfree and
even go so far as to disable the selection hardware
in advance of an event that will cause a busfree
(ABORT or BUS DEVICE RESET message). The concern
is that the selection hardware will select a target
for which, after processing the bus free, there
will be no commands pending. The sequencer idle
loop will re-enable the selection should it still be
necessary.
In ahc_handle_scsiint(), clear SSTAT0 events several
PCI transactions (most notably reads) prior to clearing
SCSIINT. The newer chips seem to take a bit of time to
see the change which can make the clearing of SCSIINT
ineffective.
Don't bother panicing at the end of ahc_handle_scsiint().
Getting to the final else just means we lost the race
with clearing SCSIINT.
In ahc_free(), handle init-level 0. This can happen when we
fail the attach for RAID devices. While I'm here, also kill
the parent dma tag.
In ahc_match_scb(), consider initiator ccbs to be any
that are not from the target mode group. This fixes
a bug where an external target reset CCB was not getting
cleaned up by the reset code.
Don't bother freezing a ccb in any of our "abort" routines
when the status is set to CAM_REQ_CMP. This can happen
for a target reset ccb.
aic7xxx.reg:
Reserve space for a completion queue. This will be used
to enhance performance in the near future.
aic7xxx.seq:
Remove an optimization for the 7890 autoflush bug that
turned out to allow, in rare cases, some data to get
lost.
Implement a simpler, faster, fix for the PCI_2_1 retry
bug that hangs the sequencer on an SCB dma for certain chips.
Test against SAVED_SCSIID rather than SELID during target
reselections. This is how we always did it in the past,
but the code was modified while trying to work around an
issue with the 7895. SAVED_SCSIID takes into account
twin channel adapters such as the 2742T, whereas SELID
does not have the channel bit. This caused invalid
selection warnings and other strangeness on these cards.
aic7xxx_pci.c
Use the correct mask for checking the generic aic7892
entry.
2001-02-10 18:04:27 +00:00
|
|
|
ID_AIC7890 & ID_9005_GENERIC_MASK,
|
|
|
|
ID_9005_GENERIC_MASK,
|
2000-09-16 20:02:28 +00:00
|
|
|
"Adaptec aic7890/91 Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7890_setup
|
|
|
|
},
|
|
|
|
{
|
aic7xxx.c:
Style nits.
Make sure that our selection hardware is disabled
as soon as possible after detecting a busfree and
even go so far as to disable the selection hardware
in advance of an event that will cause a busfree
(ABORT or BUS DEVICE RESET message). The concern
is that the selection hardware will select a target
for which, after processing the bus free, there
will be no commands pending. The sequencer idle
loop will re-enable the selection should it still be
necessary.
In ahc_handle_scsiint(), clear SSTAT0 events several
PCI transactions (most notably reads) prior to clearing
SCSIINT. The newer chips seem to take a bit of time to
see the change which can make the clearing of SCSIINT
ineffective.
Don't bother panicing at the end of ahc_handle_scsiint().
Getting to the final else just means we lost the race
with clearing SCSIINT.
In ahc_free(), handle init-level 0. This can happen when we
fail the attach for RAID devices. While I'm here, also kill
the parent dma tag.
In ahc_match_scb(), consider initiator ccbs to be any
that are not from the target mode group. This fixes
a bug where an external target reset CCB was not getting
cleaned up by the reset code.
Don't bother freezing a ccb in any of our "abort" routines
when the status is set to CAM_REQ_CMP. This can happen
for a target reset ccb.
aic7xxx.reg:
Reserve space for a completion queue. This will be used
to enhance performance in the near future.
aic7xxx.seq:
Remove an optimization for the 7890 autoflush bug that
turned out to allow, in rare cases, some data to get
lost.
Implement a simpler, faster, fix for the PCI_2_1 retry
bug that hangs the sequencer on an SCB dma for certain chips.
Test against SAVED_SCSIID rather than SELID during target
reselections. This is how we always did it in the past,
but the code was modified while trying to work around an
issue with the 7895. SAVED_SCSIID takes into account
twin channel adapters such as the 2742T, whereas SELID
does not have the channel bit. This caused invalid
selection warnings and other strangeness on these cards.
aic7xxx_pci.c
Use the correct mask for checking the generic aic7892
entry.
2001-02-10 18:04:27 +00:00
|
|
|
ID_AIC7892 & ID_9005_GENERIC_MASK,
|
|
|
|
ID_9005_GENERIC_MASK,
|
2000-09-16 20:02:28 +00:00
|
|
|
"Adaptec aic7892 Ultra160 SCSI adapter",
|
|
|
|
ahc_aic7892_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AIC7895 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec aic7895 Ultra SCSI adapter",
|
|
|
|
ahc_aic7895_setup
|
|
|
|
},
|
|
|
|
{
|
aic7xxx.c:
Style nits.
Make sure that our selection hardware is disabled
as soon as possible after detecting a busfree and
even go so far as to disable the selection hardware
in advance of an event that will cause a busfree
(ABORT or BUS DEVICE RESET message). The concern
is that the selection hardware will select a target
for which, after processing the bus free, there
will be no commands pending. The sequencer idle
loop will re-enable the selection should it still be
necessary.
In ahc_handle_scsiint(), clear SSTAT0 events several
PCI transactions (most notably reads) prior to clearing
SCSIINT. The newer chips seem to take a bit of time to
see the change which can make the clearing of SCSIINT
ineffective.
Don't bother panicing at the end of ahc_handle_scsiint().
Getting to the final else just means we lost the race
with clearing SCSIINT.
In ahc_free(), handle init-level 0. This can happen when we
fail the attach for RAID devices. While I'm here, also kill
the parent dma tag.
In ahc_match_scb(), consider initiator ccbs to be any
that are not from the target mode group. This fixes
a bug where an external target reset CCB was not getting
cleaned up by the reset code.
Don't bother freezing a ccb in any of our "abort" routines
when the status is set to CAM_REQ_CMP. This can happen
for a target reset ccb.
aic7xxx.reg:
Reserve space for a completion queue. This will be used
to enhance performance in the near future.
aic7xxx.seq:
Remove an optimization for the 7890 autoflush bug that
turned out to allow, in rare cases, some data to get
lost.
Implement a simpler, faster, fix for the PCI_2_1 retry
bug that hangs the sequencer on an SCB dma for certain chips.
Test against SAVED_SCSIID rather than SELID during target
reselections. This is how we always did it in the past,
but the code was modified while trying to work around an
issue with the 7895. SAVED_SCSIID takes into account
twin channel adapters such as the 2742T, whereas SELID
does not have the channel bit. This caused invalid
selection warnings and other strangeness on these cards.
aic7xxx_pci.c
Use the correct mask for checking the generic aic7892
entry.
2001-02-10 18:04:27 +00:00
|
|
|
ID_AIC7896 & ID_9005_GENERIC_MASK,
|
|
|
|
ID_9005_GENERIC_MASK,
|
2000-09-16 20:02:28 +00:00
|
|
|
"Adaptec aic7896/97 Ultra2 SCSI adapter",
|
|
|
|
ahc_aic7896_setup
|
|
|
|
},
|
|
|
|
{
|
aic7xxx.c:
Style nits.
Make sure that our selection hardware is disabled
as soon as possible after detecting a busfree and
even go so far as to disable the selection hardware
in advance of an event that will cause a busfree
(ABORT or BUS DEVICE RESET message). The concern
is that the selection hardware will select a target
for which, after processing the bus free, there
will be no commands pending. The sequencer idle
loop will re-enable the selection should it still be
necessary.
In ahc_handle_scsiint(), clear SSTAT0 events several
PCI transactions (most notably reads) prior to clearing
SCSIINT. The newer chips seem to take a bit of time to
see the change which can make the clearing of SCSIINT
ineffective.
Don't bother panicing at the end of ahc_handle_scsiint().
Getting to the final else just means we lost the race
with clearing SCSIINT.
In ahc_free(), handle init-level 0. This can happen when we
fail the attach for RAID devices. While I'm here, also kill
the parent dma tag.
In ahc_match_scb(), consider initiator ccbs to be any
that are not from the target mode group. This fixes
a bug where an external target reset CCB was not getting
cleaned up by the reset code.
Don't bother freezing a ccb in any of our "abort" routines
when the status is set to CAM_REQ_CMP. This can happen
for a target reset ccb.
aic7xxx.reg:
Reserve space for a completion queue. This will be used
to enhance performance in the near future.
aic7xxx.seq:
Remove an optimization for the 7890 autoflush bug that
turned out to allow, in rare cases, some data to get
lost.
Implement a simpler, faster, fix for the PCI_2_1 retry
bug that hangs the sequencer on an SCB dma for certain chips.
Test against SAVED_SCSIID rather than SELID during target
reselections. This is how we always did it in the past,
but the code was modified while trying to work around an
issue with the 7895. SAVED_SCSIID takes into account
twin channel adapters such as the 2742T, whereas SELID
does not have the channel bit. This caused invalid
selection warnings and other strangeness on these cards.
aic7xxx_pci.c
Use the correct mask for checking the generic aic7892
entry.
2001-02-10 18:04:27 +00:00
|
|
|
ID_AIC7899 & ID_9005_GENERIC_MASK,
|
|
|
|
ID_9005_GENERIC_MASK,
|
2000-09-16 20:02:28 +00:00
|
|
|
"Adaptec aic7899 Ultra160 SCSI adapter",
|
|
|
|
ahc_aic7899_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AIC7810 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec aic7810 RAID memory controller",
|
|
|
|
ahc_raid_setup
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID_AIC7815 & ID_DEV_VENDOR_MASK,
|
|
|
|
ID_DEV_VENDOR_MASK,
|
|
|
|
"Adaptec aic7815 RAID memory controller",
|
|
|
|
ahc_raid_setup
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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
|
|
|
const u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
#define AHC_394X_SLOT_CHANNEL_A 4
|
|
|
|
#define AHC_394X_SLOT_CHANNEL_B 5
|
|
|
|
|
|
|
|
#define AHC_398X_SLOT_CHANNEL_A 4
|
|
|
|
#define AHC_398X_SLOT_CHANNEL_B 8
|
|
|
|
#define AHC_398X_SLOT_CHANNEL_C 12
|
|
|
|
|
|
|
|
#define AHC_494X_SLOT_CHANNEL_A 4
|
|
|
|
#define AHC_494X_SLOT_CHANNEL_B 5
|
|
|
|
#define AHC_494X_SLOT_CHANNEL_C 6
|
|
|
|
#define AHC_494X_SLOT_CHANNEL_D 7
|
|
|
|
|
|
|
|
#define DEVCONFIG 0x40
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
#define PCIERRGENDIS 0x80000000ul
|
2000-09-16 20:02:28 +00:00
|
|
|
#define SCBSIZE32 0x00010000ul /* aic789X only */
|
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
|
|
|
#define REXTVALID 0x00001000ul /* ultra cards only */
|
2001-07-18 21:39:48 +00:00
|
|
|
#define MPORTMODE 0x00000400ul /* aic7870+ only */
|
|
|
|
#define RAMPSM 0x00000200ul /* aic7870+ only */
|
2000-09-16 20:02:28 +00:00
|
|
|
#define VOLSENSE 0x00000100ul
|
2001-07-18 21:39:48 +00:00
|
|
|
#define PCI64BIT 0x00000080ul /* 64Bit PCI bus (Ultra2 Only)*/
|
2000-09-16 20:02:28 +00:00
|
|
|
#define SCBRAMSEL 0x00000080ul
|
|
|
|
#define MRDCEN 0x00000040ul
|
|
|
|
#define EXTSCBTIME 0x00000020ul /* aic7870 only */
|
|
|
|
#define EXTSCBPEN 0x00000010ul /* aic7870 only */
|
|
|
|
#define BERREN 0x00000008ul
|
|
|
|
#define DACEN 0x00000004ul
|
|
|
|
#define STPWLEVEL 0x00000002ul
|
|
|
|
#define DIFACTNEGEN 0x00000001ul /* aic7870 only */
|
|
|
|
|
|
|
|
#define CSIZE_LATTIME 0x0c
|
|
|
|
#define CACHESIZE 0x0000003ful /* only 5 bits */
|
|
|
|
#define LATTIME 0x0000ff00ul
|
|
|
|
|
2002-11-30 19:13:55 +00:00
|
|
|
/* PCI STATUS definitions */
|
|
|
|
#define DPE 0x80
|
|
|
|
#define SSE 0x40
|
|
|
|
#define RMA 0x20
|
|
|
|
#define RTA 0x10
|
|
|
|
#define STA 0x08
|
|
|
|
#define DPR 0x01
|
|
|
|
|
2002-04-24 16:58:51 +00:00
|
|
|
static int ahc_9005_subdevinfo_valid(uint16_t vendor, uint16_t device,
|
|
|
|
uint16_t subvendor, uint16_t subdevice);
|
2000-09-16 20:02:28 +00:00
|
|
|
static int ahc_ext_scbram_present(struct ahc_softc *ahc);
|
|
|
|
static void ahc_scbram_config(struct ahc_softc *ahc, int enable,
|
|
|
|
int pcheck, int fast, int large);
|
|
|
|
static void ahc_probe_ext_scbram(struct ahc_softc *ahc);
|
|
|
|
static void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1);
|
2002-08-31 06:44:56 +00:00
|
|
|
static void ahc_parse_pci_eeprom(struct ahc_softc *ahc,
|
|
|
|
struct seeprom_config *sc);
|
2000-09-16 20:02:28 +00:00
|
|
|
static void configure_termination(struct ahc_softc *ahc,
|
|
|
|
struct seeprom_descriptor *sd,
|
|
|
|
u_int adapter_control,
|
|
|
|
u_int *sxfrctl1);
|
|
|
|
|
|
|
|
static void ahc_new_term_detect(struct ahc_softc *ahc,
|
|
|
|
int *enableSEC_low,
|
|
|
|
int *enableSEC_high,
|
|
|
|
int *enablePRI_low,
|
|
|
|
int *enablePRI_high,
|
|
|
|
int *eeprom_present);
|
|
|
|
static void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
|
|
|
|
int *internal68_present,
|
|
|
|
int *externalcable_present,
|
|
|
|
int *eeprom_present);
|
|
|
|
static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
|
|
|
|
int *externalcable_present,
|
|
|
|
int *eeprom_present);
|
2003-05-03 23:55:38 +00:00
|
|
|
static void write_brdctl(struct ahc_softc *ahc, uint8_t value);
|
2000-09-16 20:02:28 +00:00
|
|
|
static uint8_t read_brdctl(struct ahc_softc *ahc);
|
2003-05-03 23:55:38 +00:00
|
|
|
static void ahc_pci_intr(struct ahc_softc *ahc);
|
|
|
|
static int ahc_pci_chip_init(struct ahc_softc *ahc);
|
|
|
|
static int ahc_pci_suspend(struct ahc_softc *ahc);
|
|
|
|
static int ahc_pci_resume(struct ahc_softc *ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
2002-04-24 16:58:51 +00:00
|
|
|
static int
|
|
|
|
ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor,
|
|
|
|
uint16_t subdevice, uint16_t subvendor)
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
|
|
|
/* Default to invalid. */
|
|
|
|
result = 0;
|
|
|
|
if (vendor == 0x9005
|
|
|
|
&& subvendor == 0x9005
|
|
|
|
&& subdevice != device
|
|
|
|
&& SUBID_9005_TYPE_KNOWN(subdevice) != 0) {
|
|
|
|
|
|
|
|
switch (SUBID_9005_TYPE(subdevice)) {
|
|
|
|
case SUBID_9005_TYPE_MB:
|
|
|
|
break;
|
|
|
|
case SUBID_9005_TYPE_CARD:
|
|
|
|
case SUBID_9005_TYPE_LCCARD:
|
|
|
|
/*
|
|
|
|
* Currently only trust Adaptec cards to
|
|
|
|
* get the sub device info correct.
|
|
|
|
*/
|
|
|
|
if (DEVID_9005_TYPE(device) == DEVID_9005_TYPE_HBA)
|
|
|
|
result = 1;
|
|
|
|
break;
|
|
|
|
case SUBID_9005_TYPE_RAID:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
struct ahc_pci_identity *
|
|
|
|
ahc_find_pci_device(ahc_dev_softc_t pci)
|
|
|
|
{
|
|
|
|
uint64_t full_id;
|
|
|
|
uint16_t device;
|
|
|
|
uint16_t vendor;
|
|
|
|
uint16_t subdevice;
|
|
|
|
uint16_t subvendor;
|
|
|
|
struct ahc_pci_identity *entry;
|
|
|
|
u_int i;
|
|
|
|
|
|
|
|
vendor = ahc_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
|
|
|
|
device = ahc_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
|
|
|
|
subvendor = ahc_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
|
|
|
|
subdevice = ahc_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
|
2003-05-03 23:55:38 +00:00
|
|
|
full_id = ahc_compose_id(device, vendor, subdevice, subvendor);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
/*
|
|
|
|
* If the second function is not hooked up, ignore it.
|
|
|
|
* Unfortunately, not all MB vendors implement the
|
|
|
|
* subdevice ID as per the Adaptec spec, so do our best
|
|
|
|
* to sanity check it prior to accepting the subdevice
|
|
|
|
* ID as valid.
|
|
|
|
*/
|
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
|
|
|
if (ahc_get_pci_function(pci) > 0
|
2002-04-24 16:58:51 +00:00
|
|
|
&& ahc_9005_subdevinfo_valid(vendor, device, subvendor, subdevice)
|
2001-01-05 19:15:37 +00:00
|
|
|
&& SUBID_9005_MFUNCENB(subdevice) == 0)
|
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
|
|
|
return (NULL);
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
for (i = 0; i < ahc_num_pci_devs; i++) {
|
|
|
|
entry = &ahc_pci_ident_table[i];
|
2001-02-21 20:50:36 +00:00
|
|
|
if (entry->full_id == (full_id & entry->id_mask)) {
|
|
|
|
/* Honor exclusion entries. */
|
|
|
|
if (entry->name == NULL)
|
|
|
|
return (NULL);
|
2000-09-16 20:02:28 +00:00
|
|
|
return (entry);
|
2001-02-21 20:50:36 +00:00
|
|
|
}
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
|
|
|
|
{
|
2002-08-31 06:44:56 +00:00
|
|
|
u_long l;
|
|
|
|
u_int command;
|
|
|
|
u_int our_id;
|
|
|
|
u_int sxfrctl1;
|
|
|
|
u_int scsiseq;
|
|
|
|
u_int dscommand0;
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
uint32_t devconfig;
|
2002-08-31 06:44:56 +00:00
|
|
|
int error;
|
|
|
|
uint8_t sblkctl;
|
|
|
|
|
|
|
|
our_id = 0;
|
2001-07-18 21:39:48 +00:00
|
|
|
error = entry->setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
if (error != 0)
|
|
|
|
return (error);
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->chip |= AHC_PCI;
|
|
|
|
ahc->description = entry->name;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
2002-04-24 16:58:51 +00:00
|
|
|
ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
error = ahc_pci_map_registers(ahc);
|
|
|
|
if (error != 0)
|
|
|
|
return (error);
|
|
|
|
|
2002-04-24 16:58:51 +00:00
|
|
|
/*
|
|
|
|
* Before we continue probing the card, ensure that
|
|
|
|
* its interrupts are *disabled*. We don't want
|
|
|
|
* a misstep to hang the machine in an interrupt
|
|
|
|
* storm.
|
|
|
|
*/
|
|
|
|
ahc_intr_enable(ahc, FALSE);
|
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
|
|
|
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
/*
|
|
|
|
* If we need to support high memory, enable dual
|
|
|
|
* address cycles. This bit must be set to enable
|
|
|
|
* high address bit generation even if we are on a
|
|
|
|
* 64bit bus (PCI64BIT set in devconfig).
|
|
|
|
*/
|
|
|
|
if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
|
|
|
|
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: Enabling 39Bit Addressing\n",
|
|
|
|
ahc_name(ahc));
|
|
|
|
devconfig |= DACEN;
|
|
|
|
}
|
|
|
|
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
/* Ensure that pci error generation, a test feature, is disabled. */
|
|
|
|
devconfig |= PCIERRGENDIS;
|
|
|
|
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* Ensure busmastering is enabled */
|
2003-05-03 23:55:38 +00:00
|
|
|
command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
|
2000-09-16 20:02:28 +00:00
|
|
|
command |= PCIM_CMD_BUSMASTEREN;
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/* On all PCI adapters, we allow SCB paging */
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->flags |= AHC_PAGESCBS;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_softc_init(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
if (error != 0)
|
|
|
|
return (error);
|
|
|
|
|
2003-05-03 23:55:38 +00:00
|
|
|
/*
|
|
|
|
* Disable PCI parity error checking. Users typically
|
|
|
|
* do this to work around broken PCI chipsets that get
|
|
|
|
* the parity timing wrong and thus generate lots of spurious
|
|
|
|
* errors. The chip only allows us to disable *all* parity
|
|
|
|
* error reporting when doing this, so CIO bus, scb ram, and
|
|
|
|
* scratch ram parity errors will be ignored too.
|
|
|
|
*/
|
2003-05-26 21:20:47 +00:00
|
|
|
if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
|
|
|
|
ahc->seqctl |= FAILDIS;
|
2003-05-03 23:55:38 +00:00
|
|
|
|
2001-03-29 00:36:35 +00:00
|
|
|
ahc->bus_intr = ahc_pci_intr;
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->bus_chip_init = ahc_pci_chip_init;
|
|
|
|
ahc->bus_suspend = ahc_pci_suspend;
|
|
|
|
ahc->bus_resume = ahc_pci_resume;
|
2001-03-29 00:36:35 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* Remeber how the card was setup in case there is no SEEPROM */
|
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
|
|
|
if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
|
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
|
|
|
ahc_pause(ahc);
|
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
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0)
|
|
|
|
our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
|
|
|
|
else
|
|
|
|
our_id = ahc_inb(ahc, SCSIID) & OID;
|
|
|
|
sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN;
|
|
|
|
scsiseq = ahc_inb(ahc, SCSISEQ);
|
|
|
|
} else {
|
|
|
|
sxfrctl1 = STPWEN;
|
|
|
|
our_id = 7;
|
|
|
|
scsiseq = 0;
|
|
|
|
}
|
2000-09-16 20:02:28 +00:00
|
|
|
|
2003-06-06 23:48:19 +00:00
|
|
|
error = ahc_reset(ahc, /*reinit*/FALSE);
|
2000-09-16 20:02:28 +00:00
|
|
|
if (error != 0)
|
|
|
|
return (ENXIO);
|
|
|
|
|
|
|
|
if ((ahc->features & AHC_DT) != 0) {
|
|
|
|
u_int sfunct;
|
|
|
|
|
|
|
|
/* Perform ALT-Mode Setup */
|
|
|
|
sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
|
|
|
|
ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
|
2001-05-15 19:41:12 +00:00
|
|
|
ahc_outb(ahc, OPTIONMODE,
|
|
|
|
OPTIONMODE_DEFAULTS|AUTOACKEN|BUSFREEREV|EXPPHASEDIS);
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_outb(ahc, SFUNCT, sfunct);
|
|
|
|
|
|
|
|
/* Normal mode setup */
|
|
|
|
ahc_outb(ahc, CRCCONTROL1, CRCVALCHKEN|CRCENDCHKEN|CRCREQCHKEN
|
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
|
|
|
|TARGCRCENDEN);
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dscommand0 = ahc_inb(ahc, DSCOMMAND0);
|
2000-10-05 04:24:14 +00:00
|
|
|
dscommand0 |= MPARCKEN|CACHETHEN;
|
2000-09-16 20:02:28 +00:00
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* DPARCKEN doesn't work correctly on
|
|
|
|
* some MBs so don't use it.
|
|
|
|
*/
|
|
|
|
dscommand0 &= ~DPARCKEN;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Handle chips that must have cache line
|
|
|
|
* streaming (dis/en)abled.
|
|
|
|
*/
|
|
|
|
if ((ahc->bugs & AHC_CACHETHEN_DIS_BUG) != 0)
|
|
|
|
dscommand0 |= CACHETHEN;
|
|
|
|
|
|
|
|
if ((ahc->bugs & AHC_CACHETHEN_BUG) != 0)
|
|
|
|
dscommand0 &= ~CACHETHEN;
|
|
|
|
|
|
|
|
ahc_outb(ahc, DSCOMMAND0, dscommand0);
|
|
|
|
|
|
|
|
ahc->pci_cachesize =
|
|
|
|
ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME,
|
|
|
|
/*bytes*/1) & CACHESIZE;
|
|
|
|
ahc->pci_cachesize *= 4;
|
|
|
|
|
2001-08-05 22:20:12 +00:00
|
|
|
if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0
|
|
|
|
&& ahc->pci_cachesize == 4) {
|
|
|
|
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
|
|
|
|
0, /*bytes*/1);
|
|
|
|
ahc->pci_cachesize = 0;
|
|
|
|
}
|
|
|
|
|
2001-05-15 19:41:12 +00:00
|
|
|
/*
|
|
|
|
* We cannot perform ULTRA speeds without the presense
|
|
|
|
* of the external precision resistor.
|
|
|
|
*/
|
|
|
|
if ((ahc->features & AHC_ULTRA) != 0) {
|
|
|
|
uint32_t devconfig;
|
|
|
|
|
|
|
|
devconfig = ahc_pci_read_config(ahc->dev_softc,
|
|
|
|
DEVCONFIG, /*bytes*/4);
|
|
|
|
if ((devconfig & REXTVALID) == 0)
|
|
|
|
ahc->features &= ~AHC_ULTRA;
|
|
|
|
}
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* See if we have a SEEPROM and perform auto-term */
|
|
|
|
check_extport(ahc, &sxfrctl1);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Take the LED out of diagnostic mode
|
|
|
|
*/
|
|
|
|
sblkctl = ahc_inb(ahc, SBLKCTL);
|
|
|
|
ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
|
|
|
|
|
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0) {
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_MAX|WR_DFTHRSH_MAX);
|
2000-09-16 20:02:28 +00:00
|
|
|
} else {
|
|
|
|
ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ahc->flags & AHC_USEDEFAULTS) {
|
|
|
|
/*
|
|
|
|
* PCI Adapter default setup
|
|
|
|
* Should only be used if the adapter does not have
|
|
|
|
* a SEEPROM.
|
|
|
|
*/
|
|
|
|
/* See if someone else set us up already */
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
if ((ahc->flags & AHC_NO_BIOS_INIT) == 0
|
|
|
|
&& scsiseq != 0) {
|
2000-09-16 20:02:28 +00:00
|
|
|
printf("%s: Using left over BIOS settings\n",
|
|
|
|
ahc_name(ahc));
|
|
|
|
ahc->flags &= ~AHC_USEDEFAULTS;
|
aic7xxx.c:
Style nits.
Make sure that our selection hardware is disabled
as soon as possible after detecting a busfree and
even go so far as to disable the selection hardware
in advance of an event that will cause a busfree
(ABORT or BUS DEVICE RESET message). The concern
is that the selection hardware will select a target
for which, after processing the bus free, there
will be no commands pending. The sequencer idle
loop will re-enable the selection should it still be
necessary.
In ahc_handle_scsiint(), clear SSTAT0 events several
PCI transactions (most notably reads) prior to clearing
SCSIINT. The newer chips seem to take a bit of time to
see the change which can make the clearing of SCSIINT
ineffective.
Don't bother panicing at the end of ahc_handle_scsiint().
Getting to the final else just means we lost the race
with clearing SCSIINT.
In ahc_free(), handle init-level 0. This can happen when we
fail the attach for RAID devices. While I'm here, also kill
the parent dma tag.
In ahc_match_scb(), consider initiator ccbs to be any
that are not from the target mode group. This fixes
a bug where an external target reset CCB was not getting
cleaned up by the reset code.
Don't bother freezing a ccb in any of our "abort" routines
when the status is set to CAM_REQ_CMP. This can happen
for a target reset ccb.
aic7xxx.reg:
Reserve space for a completion queue. This will be used
to enhance performance in the near future.
aic7xxx.seq:
Remove an optimization for the 7890 autoflush bug that
turned out to allow, in rare cases, some data to get
lost.
Implement a simpler, faster, fix for the PCI_2_1 retry
bug that hangs the sequencer on an SCB dma for certain chips.
Test against SAVED_SCSIID rather than SELID during target
reselections. This is how we always did it in the past,
but the code was modified while trying to work around an
issue with the 7895. SAVED_SCSIID takes into account
twin channel adapters such as the 2742T, whereas SELID
does not have the channel bit. This caused invalid
selection warnings and other strangeness on these cards.
aic7xxx_pci.c
Use the correct mask for checking the generic aic7892
entry.
2001-02-10 18:04:27 +00:00
|
|
|
ahc->flags |= AHC_BIOS_ENABLED;
|
2000-09-16 20:02:28 +00:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Assume only one connector and always turn
|
|
|
|
* on termination.
|
|
|
|
*/
|
|
|
|
our_id = 0x07;
|
|
|
|
sxfrctl1 = STPWEN;
|
|
|
|
}
|
|
|
|
ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI);
|
|
|
|
|
|
|
|
ahc->our_id = our_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Take a look to see if we have external SRAM.
|
|
|
|
* We currently do not attempt to use SRAM that is
|
|
|
|
* shared among multiple controllers.
|
|
|
|
*/
|
|
|
|
ahc_probe_ext_scbram(ahc);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Record our termination setting for the
|
|
|
|
* generic initialization routine.
|
|
|
|
*/
|
|
|
|
if ((sxfrctl1 & STPWEN) != 0)
|
|
|
|
ahc->flags |= AHC_TERM_ENB_A;
|
|
|
|
|
2003-05-03 23:55:38 +00:00
|
|
|
/*
|
|
|
|
* Save chip register configuration data for chip resets
|
|
|
|
* that occur during runtime and resume events.
|
|
|
|
*/
|
|
|
|
ahc->bus_softc.pci_softc.devconfig =
|
|
|
|
ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
|
|
|
|
ahc->bus_softc.pci_softc.command =
|
|
|
|
ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
|
|
|
|
ahc->bus_softc.pci_softc.csize_lattime =
|
|
|
|
ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1);
|
|
|
|
ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
|
|
|
|
ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
|
|
|
|
if ((ahc->features & AHC_DT) != 0) {
|
|
|
|
u_int sfunct;
|
|
|
|
|
|
|
|
sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
|
|
|
|
ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
|
|
|
|
ahc->bus_softc.pci_softc.optionmode = ahc_inb(ahc, OPTIONMODE);
|
|
|
|
ahc->bus_softc.pci_softc.targcrccnt = ahc_inw(ahc, TARGCRCCNT);
|
|
|
|
ahc_outb(ahc, SFUNCT, sfunct);
|
|
|
|
ahc->bus_softc.pci_softc.crccontrol1 =
|
|
|
|
ahc_inb(ahc, CRCCONTROL1);
|
|
|
|
}
|
|
|
|
if ((ahc->features & AHC_MULTI_FUNC) != 0)
|
|
|
|
ahc->bus_softc.pci_softc.scbbaddr = ahc_inb(ahc, SCBBADDR);
|
|
|
|
|
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0)
|
|
|
|
ahc->bus_softc.pci_softc.dff_thrsh = ahc_inb(ahc, DFF_THRSH);
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* Core initialization */
|
|
|
|
error = ahc_init(ahc);
|
|
|
|
if (error != 0)
|
|
|
|
return (error);
|
|
|
|
|
2001-03-29 00:36:35 +00:00
|
|
|
/*
|
|
|
|
* Allow interrupts now that we are completely setup.
|
|
|
|
*/
|
2001-05-15 19:41:12 +00:00
|
|
|
error = ahc_pci_map_int(ahc);
|
|
|
|
if (error != 0)
|
|
|
|
return (error);
|
|
|
|
|
2002-08-31 06:44:56 +00:00
|
|
|
ahc_list_lock(&l);
|
|
|
|
/*
|
|
|
|
* Link this softc in with all other ahc instances.
|
|
|
|
*/
|
|
|
|
ahc_softc_insert(ahc);
|
|
|
|
ahc_list_unlock(&l);
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test for the presense of external sram in an
|
|
|
|
* "unshared" configuration.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ahc_ext_scbram_present(struct ahc_softc *ahc)
|
|
|
|
{
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
u_int chip;
|
2000-09-16 20:02:28 +00:00
|
|
|
int ramps;
|
|
|
|
int single_user;
|
|
|
|
uint32_t devconfig;
|
|
|
|
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
chip = ahc->chip & AHC_CHIPID_MASK;
|
2000-09-16 20:02:28 +00:00
|
|
|
devconfig = ahc_pci_read_config(ahc->dev_softc,
|
|
|
|
DEVCONFIG, /*bytes*/4);
|
|
|
|
single_user = (devconfig & MPORTMODE) != 0;
|
|
|
|
|
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0)
|
|
|
|
ramps = (ahc_inb(ahc, DSCOMMAND0) & RAMPS) != 0;
|
2002-04-24 16:58:51 +00:00
|
|
|
else if (chip == AHC_AIC7895 || chip == AHC_AIC7895C)
|
|
|
|
/*
|
|
|
|
* External SCBRAM arbitration is flakey
|
|
|
|
* on these chips. Unfortunately this means
|
|
|
|
* we don't use the extra SCB ram space on the
|
|
|
|
* 3940AUW.
|
|
|
|
*/
|
|
|
|
ramps = 0;
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
else if (chip >= AHC_AIC7870)
|
2000-09-16 20:02:28 +00:00
|
|
|
ramps = (devconfig & RAMPSM) != 0;
|
|
|
|
else
|
|
|
|
ramps = 0;
|
|
|
|
|
|
|
|
if (ramps && single_user)
|
|
|
|
return (1);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Enable external scbram.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
ahc_scbram_config(struct ahc_softc *ahc, int enable, int pcheck,
|
|
|
|
int fast, int large)
|
|
|
|
{
|
|
|
|
uint32_t devconfig;
|
|
|
|
|
|
|
|
if (ahc->features & AHC_MULTI_FUNC) {
|
|
|
|
/*
|
|
|
|
* Set the SCB Base addr (highest address bit)
|
|
|
|
* depending on which channel we are.
|
|
|
|
*/
|
|
|
|
ahc_outb(ahc, SCBBADDR, ahc_get_pci_function(ahc->dev_softc));
|
|
|
|
}
|
|
|
|
|
2002-08-31 06:44:56 +00:00
|
|
|
ahc->flags &= ~AHC_LSCBS_ENABLED;
|
|
|
|
if (large)
|
|
|
|
ahc->flags |= AHC_LSCBS_ENABLED;
|
2000-09-16 20:02:28 +00:00
|
|
|
devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
|
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0) {
|
|
|
|
u_int dscommand0;
|
|
|
|
|
|
|
|
dscommand0 = ahc_inb(ahc, DSCOMMAND0);
|
|
|
|
if (enable)
|
|
|
|
dscommand0 &= ~INTSCBRAMSEL;
|
|
|
|
else
|
|
|
|
dscommand0 |= INTSCBRAMSEL;
|
|
|
|
if (large)
|
|
|
|
dscommand0 &= ~USCBSIZE32;
|
|
|
|
else
|
|
|
|
dscommand0 |= USCBSIZE32;
|
|
|
|
ahc_outb(ahc, DSCOMMAND0, dscommand0);
|
|
|
|
} else {
|
|
|
|
if (fast)
|
|
|
|
devconfig &= ~EXTSCBTIME;
|
|
|
|
else
|
|
|
|
devconfig |= EXTSCBTIME;
|
|
|
|
if (enable)
|
|
|
|
devconfig &= ~SCBRAMSEL;
|
|
|
|
else
|
|
|
|
devconfig |= SCBRAMSEL;
|
|
|
|
if (large)
|
|
|
|
devconfig &= ~SCBSIZE32;
|
|
|
|
else
|
|
|
|
devconfig |= SCBSIZE32;
|
|
|
|
}
|
|
|
|
if (pcheck)
|
|
|
|
devconfig |= EXTSCBPEN;
|
|
|
|
else
|
|
|
|
devconfig &= ~EXTSCBPEN;
|
|
|
|
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Take a look to see if we have external SRAM.
|
|
|
|
* We currently do not attempt to use SRAM that is
|
|
|
|
* shared among multiple controllers.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
ahc_probe_ext_scbram(struct ahc_softc *ahc)
|
|
|
|
{
|
|
|
|
int num_scbs;
|
|
|
|
int test_num_scbs;
|
|
|
|
int enable;
|
|
|
|
int pcheck;
|
|
|
|
int fast;
|
|
|
|
int large;
|
|
|
|
|
|
|
|
enable = FALSE;
|
|
|
|
pcheck = FALSE;
|
|
|
|
fast = FALSE;
|
|
|
|
large = FALSE;
|
|
|
|
num_scbs = 0;
|
|
|
|
|
|
|
|
if (ahc_ext_scbram_present(ahc) == 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Probe for the best parameters to use.
|
|
|
|
*/
|
|
|
|
ahc_scbram_config(ahc, /*enable*/TRUE, pcheck, fast, large);
|
|
|
|
num_scbs = ahc_probe_scbs(ahc);
|
|
|
|
if (num_scbs == 0) {
|
|
|
|
/* The SRAM wasn't really present. */
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
enable = TRUE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Clear any outstanding parity error
|
|
|
|
* and ensure that parity error reporting
|
|
|
|
* is enabled.
|
|
|
|
*/
|
|
|
|
ahc_outb(ahc, SEQCTL, 0);
|
|
|
|
ahc_outb(ahc, CLRINT, CLRPARERR);
|
|
|
|
ahc_outb(ahc, CLRINT, CLRBRKADRINT);
|
|
|
|
|
|
|
|
/* Now see if we can do parity */
|
|
|
|
ahc_scbram_config(ahc, enable, /*pcheck*/TRUE, fast, large);
|
|
|
|
num_scbs = ahc_probe_scbs(ahc);
|
|
|
|
if ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
|
|
|
|
|| (ahc_inb(ahc, ERROR) & MPARERR) == 0)
|
|
|
|
pcheck = TRUE;
|
|
|
|
|
|
|
|
/* Clear any resulting parity error */
|
|
|
|
ahc_outb(ahc, CLRINT, CLRPARERR);
|
|
|
|
ahc_outb(ahc, CLRINT, CLRBRKADRINT);
|
|
|
|
|
|
|
|
/* Now see if we can do fast timing */
|
|
|
|
ahc_scbram_config(ahc, enable, pcheck, /*fast*/TRUE, large);
|
|
|
|
test_num_scbs = ahc_probe_scbs(ahc);
|
|
|
|
if (test_num_scbs == num_scbs
|
|
|
|
&& ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
|
|
|
|
|| (ahc_inb(ahc, ERROR) & MPARERR) == 0))
|
|
|
|
fast = TRUE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* See if we can use large SCBs and still maintain
|
|
|
|
* the same overall count of SCBs.
|
|
|
|
*/
|
|
|
|
if ((ahc->features & AHC_LARGE_SCBS) != 0) {
|
|
|
|
ahc_scbram_config(ahc, enable, pcheck, fast, /*large*/TRUE);
|
|
|
|
test_num_scbs = ahc_probe_scbs(ahc);
|
|
|
|
if (test_num_scbs >= num_scbs) {
|
|
|
|
large = TRUE;
|
|
|
|
num_scbs = test_num_scbs;
|
|
|
|
if (num_scbs >= 64) {
|
|
|
|
/*
|
|
|
|
* We have enough space to move the
|
|
|
|
* "busy targets table" into SCB space
|
|
|
|
* and make it qualify all the way to the
|
|
|
|
* lun level.
|
|
|
|
*/
|
|
|
|
ahc->flags |= AHC_SCB_BTT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
/*
|
|
|
|
* Disable parity error reporting until we
|
|
|
|
* can load instruction ram.
|
|
|
|
*/
|
|
|
|
ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
|
|
|
|
/* Clear any latched parity error */
|
|
|
|
ahc_outb(ahc, CLRINT, CLRPARERR);
|
|
|
|
ahc_outb(ahc, CLRINT, CLRBRKADRINT);
|
|
|
|
if (bootverbose && enable) {
|
|
|
|
printf("%s: External SRAM, %s access%s, %dbytes/SCB\n",
|
|
|
|
ahc_name(ahc), fast ? "fast" : "slow",
|
|
|
|
pcheck ? ", parity checking enabled" : "",
|
|
|
|
large ? 64 : 32);
|
|
|
|
}
|
|
|
|
ahc_scbram_config(ahc, enable, pcheck, fast, large);
|
|
|
|
}
|
|
|
|
|
2002-11-30 19:13:55 +00:00
|
|
|
/*
|
|
|
|
* Perform some simple tests that should catch situations where
|
|
|
|
* our registers are invalidly mapped.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
ahc_pci_test_register_access(struct ahc_softc *ahc)
|
|
|
|
{
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
int error;
|
|
|
|
u_int status1;
|
|
|
|
uint32_t cmd;
|
|
|
|
uint8_t hcntrl;
|
2002-12-04 22:51:29 +00:00
|
|
|
|
|
|
|
error = EIO;
|
|
|
|
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
/*
|
|
|
|
* Enable PCI error interrupt status, but suppress NMIs
|
|
|
|
* generated by SERR raised due to target aborts.
|
|
|
|
*/
|
|
|
|
cmd = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
|
|
|
|
cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
|
2002-11-30 19:13:55 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* First a simple test to see if any
|
|
|
|
* registers can be read. Reading
|
|
|
|
* HCNTRL has no side effects and has
|
|
|
|
* at least one bit that is guaranteed to
|
|
|
|
* be zero so it is a good register to
|
|
|
|
* use for this test.
|
|
|
|
*/
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
hcntrl = ahc_inb(ahc, HCNTRL);
|
|
|
|
if (hcntrl == 0xFF)
|
2002-12-04 22:51:29 +00:00
|
|
|
goto fail;
|
2002-11-30 19:13:55 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Next create a situation where write combining
|
|
|
|
* or read prefetching could be initiated by the
|
|
|
|
* CPU or host bridge. Our device does not support
|
|
|
|
* either, so look for data corruption and/or flagged
|
|
|
|
* PCI errors.
|
|
|
|
*/
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
ahc_outb(ahc, HCNTRL, hcntrl|PAUSE);
|
|
|
|
while (ahc_is_paused(ahc) == 0)
|
|
|
|
;
|
|
|
|
ahc_outb(ahc, SEQCTL, PERRORDIS);
|
|
|
|
ahc_outb(ahc, SCBPTR, 0);
|
|
|
|
ahc_outl(ahc, SCB_BASE, 0x5aa555aa);
|
|
|
|
if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa)
|
2002-12-04 22:51:29 +00:00
|
|
|
goto fail;
|
2002-11-30 19:13:55 +00:00
|
|
|
|
|
|
|
status1 = ahc_pci_read_config(ahc->dev_softc,
|
|
|
|
PCIR_STATUS + 1, /*bytes*/1);
|
2002-12-04 22:51:29 +00:00
|
|
|
if ((status1 & STA) != 0)
|
|
|
|
goto fail;
|
2002-11-30 19:13:55 +00:00
|
|
|
|
2002-12-04 22:51:29 +00:00
|
|
|
error = 0;
|
2002-11-30 19:13:55 +00:00
|
|
|
|
2002-12-04 22:51:29 +00:00
|
|
|
fail:
|
|
|
|
/* Silently clear any latched errors. */
|
|
|
|
status1 = ahc_pci_read_config(ahc->dev_softc,
|
|
|
|
PCIR_STATUS + 1, /*bytes*/1);
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
|
|
|
|
status1, /*bytes*/1);
|
|
|
|
ahc_outb(ahc, CLRINT, CLRPARERR);
|
aic7xxx.reg:
Add a constant for the controller's stack size and the
maximum scsi offset.
aic7xxx.seq:
Style nit. The source is implied to be the destination
unless overridden in an "and" instruction.
Update target mode code for changes in identify seen
sequencer flags.
aic7xxx_pci.c:
Ensure that the PCIERRGENDIS bit is set in the
PCIERRGEN config space register. Perhaps this
is a reason for the spurios parity errors reported
on U160 controllers.
Honor the AHC_NO_BIOS_INIT flag.
Allow PCI interrupt reporting to be disabled,
by clearing the PERRRESEN bit in the command
register. This option is now enabled via a new
softc flag: AHC_DISABLE_PCI_PERR.
Disable SERR and pause the controller prior to performing
our mmapped I/O test. This should handle the case of
controllers that do not "auto-access pause". For legacy
controllers, use SCB ram instead of scratch ram since
the latter may contain settings left over from the BIOS
that we will use if an seeprom is not found.
Make use of new ahc_inl/outl() inlines.
aic7xxx.h:
Reformat a few comments to follow driver style.
Add a controller flags that indicate that a controller
has not been initialized by the BIOS and whether to
disable PCI parity errors..
Remove stack probing softc members.
Add a few more syncrate constants that are useful in speed
fallback calculations.
Add the SHOW_MASKED_ERRORS debug flag.
aic7xxx.h:
aic7xxx.c:
Implement the SCB_SILENT flag. This is useful for
hushing up the driver during DV or other operations
that we expect to cause transmission errors. The
messages will still print if the SHOW_MASKED_ERRORS
debug option is enabled.
aic7xxx_inline.h:
Implement ahc_[in|out][w|l|q]. This removes the need
for manual 'or and shift" type operations throughout
the driver.
aic7xxx.c:
Move SELTO dignostic so that the SCB is still valid
when we use it for printing path information.
If we are narrow, limit syncrate to Ultra2.
Don't clobber ppr_options when forcing a renegotiation.
The current ppr_options may be referenced while queuing
new commands. Don't set our width to unknown when forcing
negotiation on narrow controllers. This will confuse the
negotiation code into negotiating with a wide message on
narrow controllers.
Add an "asserting atn" diagnostic with controller/target
information.
Remove the probe_stack code. The stack is always
4 deep on legacy controllers, so probing is pointless.
This also avoids an issue where probing the stack would
upset the aic7770.
In ahc_reset(), record whether or not we found the
controller in a reset state. If the controller was
already reset, assume that no BIOS has initialized
the controller and ignore left over scratch ram
settings.
Fix an ifdef bug that caused sequencer debugging to
be enabled always.
Clear the ultraenb flag in our tstate during startup.
The ultraenbled'ness of a device is recorded in the user
transfer settings. tstate->ultraenb bitmask indicates
which devices we have negotiated an ultra speed with.
Just after initialization, we are async. Setting the
ultraenb flag while async seems to be harmless, but it
was confusing to see the ULTRAENB flag set in the SCB.
Enhance residual diagnostic to indicate if the residual
if for sense information or normal data transfers.
Indicate the features, bugs, and flags set in the softc
that are used to control firmware patch download when
booting verbose.
In ahc_dump_card_state() fix a logic reversal. The
SCSIPHASE register only exists on U160 controllers.
The SCSISIGI register exists on all controllers. Not
the other way around. Also print out the ERROR register.
Allow ahc_dump_card_state() to be called when the sequencer
is not paused. Add dump card state markers as in the U320
driver.
2003-01-20 20:44:55 +00:00
|
|
|
ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
|
2002-12-04 22:51:29 +00:00
|
|
|
return (error);
|
2002-11-30 19:13:55 +00:00
|
|
|
}
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Check the external port logic for a serial eeprom
|
|
|
|
* and termination/cable detection contrls.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
|
|
|
|
{
|
|
|
|
struct seeprom_descriptor sd;
|
2002-08-31 06:44:56 +00:00
|
|
|
struct seeprom_config *sc;
|
2000-09-16 20:02:28 +00:00
|
|
|
int have_seeprom;
|
|
|
|
int have_autoterm;
|
|
|
|
|
|
|
|
sd.sd_ahc = ahc;
|
|
|
|
sd.sd_control_offset = SEECTL;
|
|
|
|
sd.sd_status_offset = SEECTL;
|
|
|
|
sd.sd_dataout_offset = SEECTL;
|
2002-08-31 06:44:56 +00:00
|
|
|
sc = ahc->seep_config;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* For some multi-channel devices, the c46 is simply too
|
|
|
|
* small to work. For the other controller types, we can
|
|
|
|
* get our information from either SEEPROM type. Set the
|
|
|
|
* type to start our probe with accordingly.
|
|
|
|
*/
|
|
|
|
if (ahc->flags & AHC_LARGE_SEEPROM)
|
|
|
|
sd.sd_chip = C56_66;
|
|
|
|
else
|
|
|
|
sd.sd_chip = C46;
|
|
|
|
|
|
|
|
sd.sd_MS = SEEMS;
|
|
|
|
sd.sd_RDY = SEERDY;
|
|
|
|
sd.sd_CS = SEECS;
|
|
|
|
sd.sd_CK = SEECK;
|
|
|
|
sd.sd_DO = SEEDO;
|
|
|
|
sd.sd_DI = SEEDI;
|
|
|
|
|
2002-04-24 16:58:51 +00:00
|
|
|
have_seeprom = ahc_acquire_seeprom(ahc, &sd);
|
2000-09-16 20:02:28 +00:00
|
|
|
if (have_seeprom) {
|
|
|
|
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: Reading SEEPROM...", ahc_name(ahc));
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
u_int start_addr;
|
|
|
|
|
|
|
|
start_addr = 32 * (ahc->channel - 'A');
|
|
|
|
|
2002-08-31 06:44:56 +00:00
|
|
|
have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc,
|
2002-04-24 16:58:51 +00:00
|
|
|
start_addr,
|
2002-08-31 06:44:56 +00:00
|
|
|
sizeof(*sc)/2);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
if (have_seeprom)
|
2002-08-31 06:44:56 +00:00
|
|
|
have_seeprom = ahc_verify_cksum(sc);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
if (have_seeprom != 0 || sd.sd_chip == C56_66) {
|
|
|
|
if (bootverbose) {
|
|
|
|
if (have_seeprom == 0)
|
|
|
|
printf ("checksum error\n");
|
|
|
|
else
|
|
|
|
printf ("done.\n");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
sd.sd_chip = C56_66;
|
|
|
|
}
|
2002-04-24 16:58:51 +00:00
|
|
|
ahc_release_seeprom(&sd);
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!have_seeprom) {
|
|
|
|
/*
|
|
|
|
* Pull scratch ram settings and treat them as
|
|
|
|
* if they are the contents of an seeprom if
|
|
|
|
* the 'ADPT' signature is found in SCB2.
|
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
|
|
|
* We manually compose the data as 16bit values
|
|
|
|
* to avoid endian issues.
|
2000-09-16 20:02:28 +00:00
|
|
|
*/
|
|
|
|
ahc_outb(ahc, SCBPTR, 2);
|
|
|
|
if (ahc_inb(ahc, SCB_BASE) == 'A'
|
|
|
|
&& ahc_inb(ahc, SCB_BASE + 1) == 'D'
|
|
|
|
&& ahc_inb(ahc, SCB_BASE + 2) == 'P'
|
|
|
|
&& ahc_inb(ahc, SCB_BASE + 3) == 'T') {
|
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
|
|
|
uint16_t *sc_data;
|
2000-09-16 20:02:28 +00:00
|
|
|
int i;
|
|
|
|
|
2002-08-31 06:44:56 +00:00
|
|
|
sc_data = (uint16_t *)sc;
|
|
|
|
for (i = 0; i < 32; i++, sc_data++) {
|
|
|
|
int j;
|
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
|
|
|
|
|
|
|
j = i * 2;
|
2002-08-31 06:44:56 +00:00
|
|
|
*sc_data = ahc_inb(ahc, SRAM_BASE + j)
|
|
|
|
| ahc_inb(ahc, SRAM_BASE + j + 1) << 8;
|
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
|
|
|
}
|
2002-08-31 06:44:56 +00:00
|
|
|
have_seeprom = ahc_verify_cksum(sc);
|
|
|
|
if (have_seeprom)
|
|
|
|
ahc->flags |= AHC_SCB_CONFIG_USED;
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
2002-04-24 16:58:51 +00:00
|
|
|
/*
|
|
|
|
* Clear any SCB parity errors in case this data and
|
|
|
|
* its associated parity was not initialized by the BIOS
|
|
|
|
*/
|
|
|
|
ahc_outb(ahc, CLRINT, CLRPARERR);
|
|
|
|
ahc_outb(ahc, CLRINT, CLRBRKADRINT);
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!have_seeprom) {
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: No SEEPROM available.\n", ahc_name(ahc));
|
|
|
|
ahc->flags |= AHC_USEDEFAULTS;
|
2002-08-31 06:44:56 +00:00
|
|
|
free(ahc->seep_config, M_DEVBUF);
|
|
|
|
ahc->seep_config = NULL;
|
|
|
|
sc = NULL;
|
2000-09-16 20:02:28 +00:00
|
|
|
} else {
|
2002-08-31 06:44:56 +00:00
|
|
|
ahc_parse_pci_eeprom(ahc, sc);
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cards that have the external logic necessary to talk to
|
|
|
|
* a SEEPROM, are almost certain to have the remaining logic
|
|
|
|
* necessary for auto-termination control. This assumption
|
|
|
|
* hasn't failed yet...
|
|
|
|
*/
|
|
|
|
have_autoterm = have_seeprom;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Some low-cost chips have SEEPROM and auto-term control built
|
|
|
|
* in, instead of using a GAL. They can tell us directly
|
|
|
|
* if the termination logic is enabled.
|
|
|
|
*/
|
|
|
|
if ((ahc->features & AHC_SPIOCAP) != 0) {
|
2002-08-31 06:44:56 +00:00
|
|
|
if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) == 0)
|
2000-09-16 20:02:28 +00:00
|
|
|
have_autoterm = FALSE;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
if (have_autoterm) {
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->flags |= AHC_HAS_TERM_LOGIC;
|
2002-04-24 16:58:51 +00:00
|
|
|
ahc_acquire_seeprom(ahc, &sd);
|
2002-08-31 06:44:56 +00:00
|
|
|
configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1);
|
2002-04-24 16:58:51 +00:00
|
|
|
ahc_release_seeprom(&sd);
|
2002-08-31 06:44:56 +00:00
|
|
|
} else if (have_seeprom) {
|
|
|
|
*sxfrctl1 &= ~STPWEN;
|
|
|
|
if ((sc->adapter_control & CFSTERM) != 0)
|
|
|
|
*sxfrctl1 |= STPWEN;
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: Low byte termination %sabled\n",
|
|
|
|
ahc_name(ahc),
|
|
|
|
(*sxfrctl1 & STPWEN) ? "en" : "dis");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
ahc_parse_pci_eeprom(struct ahc_softc *ahc, struct seeprom_config *sc)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Put the data we've collected down into SRAM
|
|
|
|
* where ahc_init will find it.
|
|
|
|
*/
|
|
|
|
int i;
|
|
|
|
int max_targ = sc->max_targets & CFMAXTARG;
|
|
|
|
u_int scsi_conf;
|
|
|
|
uint16_t discenable;
|
|
|
|
uint16_t ultraenb;
|
|
|
|
|
|
|
|
discenable = 0;
|
|
|
|
ultraenb = 0;
|
|
|
|
if ((sc->adapter_control & CFULTRAEN) != 0) {
|
|
|
|
/*
|
|
|
|
* Determine if this adapter has a "newstyle"
|
|
|
|
* SEEPROM format.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < max_targ; i++) {
|
|
|
|
if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0) {
|
|
|
|
ahc->flags |= AHC_NEWEEPROM_FMT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < max_targ; i++) {
|
|
|
|
u_int scsirate;
|
|
|
|
uint16_t target_mask;
|
|
|
|
|
|
|
|
target_mask = 0x01 << i;
|
|
|
|
if (sc->device_flags[i] & CFDISC)
|
|
|
|
discenable |= target_mask;
|
|
|
|
if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) {
|
|
|
|
if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0)
|
|
|
|
ultraenb |= target_mask;
|
|
|
|
} else if ((sc->adapter_control & CFULTRAEN) != 0) {
|
|
|
|
ultraenb |= target_mask;
|
|
|
|
}
|
|
|
|
if ((sc->device_flags[i] & CFXFER) == 0x04
|
|
|
|
&& (ultraenb & target_mask) != 0) {
|
|
|
|
/* Treat 10MHz as a non-ultra speed */
|
|
|
|
sc->device_flags[i] &= ~CFXFER;
|
|
|
|
ultraenb &= ~target_mask;
|
|
|
|
}
|
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0) {
|
|
|
|
u_int offset;
|
|
|
|
|
|
|
|
if (sc->device_flags[i] & CFSYNCH)
|
|
|
|
offset = MAX_OFFSET_ULTRA2;
|
|
|
|
else
|
|
|
|
offset = 0;
|
|
|
|
ahc_outb(ahc, TARG_OFFSET + i, offset);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The ultra enable bits contain the
|
|
|
|
* high bit of the ultra2 sync rate
|
|
|
|
* field.
|
|
|
|
*/
|
|
|
|
scsirate = (sc->device_flags[i] & CFXFER)
|
|
|
|
| ((ultraenb & target_mask) ? 0x8 : 0x0);
|
|
|
|
if (sc->device_flags[i] & CFWIDEB)
|
|
|
|
scsirate |= WIDEXFER;
|
|
|
|
} else {
|
|
|
|
scsirate = (sc->device_flags[i] & CFXFER) << 4;
|
|
|
|
if (sc->device_flags[i] & CFSYNCH)
|
|
|
|
scsirate |= SOFS;
|
|
|
|
if (sc->device_flags[i] & CFWIDEB)
|
|
|
|
scsirate |= WIDEXFER;
|
|
|
|
}
|
|
|
|
ahc_outb(ahc, TARG_SCSIRATE + i, scsirate);
|
|
|
|
}
|
|
|
|
ahc->our_id = sc->brtime_id & CFSCSIID;
|
|
|
|
|
|
|
|
scsi_conf = (ahc->our_id & 0x7);
|
|
|
|
if (sc->adapter_control & CFSPARITY)
|
|
|
|
scsi_conf |= ENSPCHK;
|
|
|
|
if (sc->adapter_control & CFRESETB)
|
|
|
|
scsi_conf |= RESET_SCSI;
|
|
|
|
|
|
|
|
ahc->flags |= (sc->adapter_control & CFBOOTCHAN) >> CFBOOTCHANSHIFT;
|
|
|
|
|
|
|
|
if (sc->bios_control & CFEXTEND)
|
|
|
|
ahc->flags |= AHC_EXTENDED_TRANS_A;
|
|
|
|
|
|
|
|
if (sc->bios_control & CFBIOSEN)
|
|
|
|
ahc->flags |= AHC_BIOS_ENABLED;
|
|
|
|
if (ahc->features & AHC_ULTRA
|
|
|
|
&& (ahc->flags & AHC_NEWEEPROM_FMT) == 0) {
|
|
|
|
/* Should we enable Ultra mode? */
|
|
|
|
if (!(sc->adapter_control & CFULTRAEN))
|
|
|
|
/* Treat us as a non-ultra card */
|
|
|
|
ultraenb = 0;
|
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
|
|
|
}
|
2002-08-31 06:44:56 +00:00
|
|
|
|
|
|
|
if (sc->signature == CFSIGNATURE
|
|
|
|
|| sc->signature == CFSIGNATURE2) {
|
|
|
|
uint32_t devconfig;
|
|
|
|
|
|
|
|
/* Honor the STPWLEVEL settings */
|
|
|
|
devconfig = ahc_pci_read_config(ahc->dev_softc,
|
|
|
|
DEVCONFIG, /*bytes*/4);
|
|
|
|
devconfig &= ~STPWLEVEL;
|
|
|
|
if ((sc->bios_control & CFSTPWLEVEL) != 0)
|
|
|
|
devconfig |= STPWLEVEL;
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
|
|
|
|
devconfig, /*bytes*/4);
|
|
|
|
}
|
|
|
|
/* Set SCSICONF info */
|
|
|
|
ahc_outb(ahc, SCSICONF, scsi_conf);
|
|
|
|
ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
|
|
|
|
ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
|
|
|
|
ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff);
|
|
|
|
ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff);
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
configure_termination(struct ahc_softc *ahc,
|
|
|
|
struct seeprom_descriptor *sd,
|
|
|
|
u_int adapter_control,
|
|
|
|
u_int *sxfrctl1)
|
|
|
|
{
|
|
|
|
uint8_t brddat;
|
|
|
|
|
|
|
|
brddat = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Update the settings in sxfrctl1 to match the
|
|
|
|
* termination settings
|
|
|
|
*/
|
|
|
|
*sxfrctl1 = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SEECS must be on for the GALS to latch
|
|
|
|
* the data properly. Be sure to leave MS
|
|
|
|
* on or we will release the seeprom.
|
|
|
|
*/
|
|
|
|
SEEPROM_OUTB(sd, sd->sd_MS | sd->sd_CS);
|
|
|
|
if ((adapter_control & CFAUTOTERM) != 0
|
|
|
|
|| (ahc->features & AHC_NEW_TERMCTL) != 0) {
|
|
|
|
int internal50_present;
|
|
|
|
int internal68_present;
|
|
|
|
int externalcable_present;
|
|
|
|
int eeprom_present;
|
|
|
|
int enableSEC_low;
|
|
|
|
int enableSEC_high;
|
|
|
|
int enablePRI_low;
|
|
|
|
int enablePRI_high;
|
2001-01-22 21:03:48 +00:00
|
|
|
int sum;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
enableSEC_low = 0;
|
|
|
|
enableSEC_high = 0;
|
|
|
|
enablePRI_low = 0;
|
|
|
|
enablePRI_high = 0;
|
|
|
|
if ((ahc->features & AHC_NEW_TERMCTL) != 0) {
|
|
|
|
ahc_new_term_detect(ahc, &enableSEC_low,
|
2002-08-31 06:44:56 +00:00
|
|
|
&enableSEC_high,
|
|
|
|
&enablePRI_low,
|
|
|
|
&enablePRI_high,
|
|
|
|
&eeprom_present);
|
2000-09-16 20:02:28 +00:00
|
|
|
if ((adapter_control & CFSEAUTOTERM) == 0) {
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: Manual SE Termination\n",
|
|
|
|
ahc_name(ahc));
|
|
|
|
enableSEC_low = (adapter_control & CFSELOWTERM);
|
|
|
|
enableSEC_high =
|
|
|
|
(adapter_control & CFSEHIGHTERM);
|
|
|
|
}
|
|
|
|
if ((adapter_control & CFAUTOTERM) == 0) {
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: Manual LVD Termination\n",
|
|
|
|
ahc_name(ahc));
|
|
|
|
enablePRI_low = (adapter_control & CFSTERM);
|
|
|
|
enablePRI_high = (adapter_control & CFWSTERM);
|
|
|
|
}
|
|
|
|
/* Make the table calculations below happy */
|
|
|
|
internal50_present = 0;
|
|
|
|
internal68_present = 1;
|
|
|
|
externalcable_present = 1;
|
|
|
|
} else if ((ahc->features & AHC_SPIOCAP) != 0) {
|
|
|
|
aic785X_cable_detect(ahc, &internal50_present,
|
|
|
|
&externalcable_present,
|
|
|
|
&eeprom_present);
|
2002-08-31 06:44:56 +00:00
|
|
|
/* Can never support a wide connector. */
|
|
|
|
internal68_present = 0;
|
2000-09-16 20:02:28 +00:00
|
|
|
} else {
|
|
|
|
aic787X_cable_detect(ahc, &internal50_present,
|
|
|
|
&internal68_present,
|
|
|
|
&externalcable_present,
|
|
|
|
&eeprom_present);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ahc->features & AHC_WIDE) == 0)
|
|
|
|
internal68_present = 0;
|
|
|
|
|
2001-01-22 21:03:48 +00:00
|
|
|
if (bootverbose
|
|
|
|
&& (ahc->features & AHC_ULTRA2) == 0) {
|
|
|
|
printf("%s: internal 50 cable %s present",
|
|
|
|
ahc_name(ahc),
|
|
|
|
internal50_present ? "is":"not");
|
2000-09-16 20:02:28 +00:00
|
|
|
|
2001-01-22 21:03:48 +00:00
|
|
|
if ((ahc->features & AHC_WIDE) != 0)
|
|
|
|
printf(", internal 68 cable %s present",
|
|
|
|
internal68_present ? "is":"not");
|
|
|
|
printf("\n%s: external cable %s present\n",
|
|
|
|
ahc_name(ahc),
|
|
|
|
externalcable_present ? "is":"not");
|
|
|
|
}
|
|
|
|
if (bootverbose)
|
2000-09-16 20:02:28 +00:00
|
|
|
printf("%s: BIOS eeprom %s present\n",
|
|
|
|
ahc_name(ahc), eeprom_present ? "is" : "not");
|
|
|
|
|
|
|
|
if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) {
|
|
|
|
/*
|
|
|
|
* The 50 pin connector is a separate bus,
|
|
|
|
* so force it to always be terminated.
|
|
|
|
* In the future, perform current sensing
|
|
|
|
* to determine if we are in the middle of
|
|
|
|
* a properly terminated bus.
|
|
|
|
*/
|
|
|
|
internal50_present = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now set the termination based on what
|
|
|
|
* we found.
|
|
|
|
* Flash Enable = BRDDAT7
|
|
|
|
* Secondary High Term Enable = BRDDAT6
|
|
|
|
* Secondary Low Term Enable = BRDDAT5 (7890)
|
|
|
|
* Primary High Term Enable = BRDDAT4 (7890)
|
|
|
|
*/
|
|
|
|
if ((ahc->features & AHC_ULTRA2) == 0
|
2001-01-22 21:03:48 +00:00
|
|
|
&& (internal50_present != 0)
|
|
|
|
&& (internal68_present != 0)
|
|
|
|
&& (externalcable_present != 0)) {
|
2000-09-16 20:02:28 +00:00
|
|
|
printf("%s: Illegal cable configuration!!. "
|
|
|
|
"Only two connectors on the "
|
|
|
|
"adapter may be used at a "
|
|
|
|
"time!\n", ahc_name(ahc));
|
2002-04-24 16:58:51 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Pretend there are no cables in the hope
|
|
|
|
* that having all of the termination on
|
|
|
|
* gives us a more stable bus.
|
|
|
|
*/
|
|
|
|
internal50_present = 0;
|
|
|
|
internal68_present = 0;
|
|
|
|
externalcable_present = 0;
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((ahc->features & AHC_WIDE) != 0
|
|
|
|
&& ((externalcable_present == 0)
|
|
|
|
|| (internal68_present == 0)
|
|
|
|
|| (enableSEC_high != 0))) {
|
|
|
|
brddat |= BRDDAT6;
|
|
|
|
if (bootverbose) {
|
|
|
|
if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)
|
|
|
|
printf("%s: 68 pin termination "
|
|
|
|
"Enabled\n", ahc_name(ahc));
|
|
|
|
else
|
|
|
|
printf("%s: %sHigh byte termination "
|
|
|
|
"Enabled\n", ahc_name(ahc),
|
|
|
|
enableSEC_high ? "Secondary "
|
|
|
|
: "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-01-22 21:03:48 +00:00
|
|
|
sum = internal50_present + internal68_present
|
|
|
|
+ externalcable_present;
|
|
|
|
if (sum < 2 || (enableSEC_low != 0)) {
|
2000-09-16 20:02:28 +00:00
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0)
|
|
|
|
brddat |= BRDDAT5;
|
|
|
|
else
|
|
|
|
*sxfrctl1 |= STPWEN;
|
|
|
|
if (bootverbose) {
|
|
|
|
if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)
|
|
|
|
printf("%s: 50 pin termination "
|
|
|
|
"Enabled\n", ahc_name(ahc));
|
|
|
|
else
|
|
|
|
printf("%s: %sLow byte termination "
|
|
|
|
"Enabled\n", ahc_name(ahc),
|
|
|
|
enableSEC_low ? "Secondary "
|
|
|
|
: "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (enablePRI_low != 0) {
|
|
|
|
*sxfrctl1 |= STPWEN;
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: Primary Low Byte termination "
|
|
|
|
"Enabled\n", ahc_name(ahc));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Setup STPWEN before setting up the rest of
|
|
|
|
* the termination per the tech note on the U160 cards.
|
|
|
|
*/
|
|
|
|
ahc_outb(ahc, SXFRCTL1, *sxfrctl1);
|
|
|
|
|
|
|
|
if (enablePRI_high != 0) {
|
|
|
|
brddat |= BRDDAT4;
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: Primary High Byte "
|
|
|
|
"termination Enabled\n",
|
|
|
|
ahc_name(ahc));
|
|
|
|
}
|
|
|
|
|
|
|
|
write_brdctl(ahc, brddat);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if ((adapter_control & CFSTERM) != 0) {
|
|
|
|
*sxfrctl1 |= STPWEN;
|
|
|
|
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: %sLow byte termination Enabled\n",
|
|
|
|
ahc_name(ahc),
|
|
|
|
(ahc->features & AHC_ULTRA2) ? "Primary "
|
|
|
|
: "");
|
|
|
|
}
|
|
|
|
|
2001-01-22 21:03:48 +00:00
|
|
|
if ((adapter_control & CFWSTERM) != 0
|
|
|
|
&& (ahc->features & AHC_WIDE) != 0) {
|
2000-09-16 20:02:28 +00:00
|
|
|
brddat |= BRDDAT6;
|
|
|
|
if (bootverbose)
|
|
|
|
printf("%s: %sHigh byte termination Enabled\n",
|
|
|
|
ahc_name(ahc),
|
|
|
|
(ahc->features & AHC_ULTRA2)
|
|
|
|
? "Secondary " : "");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Setup STPWEN before setting up the rest of
|
|
|
|
* the termination per the tech note on the U160 cards.
|
|
|
|
*/
|
|
|
|
ahc_outb(ahc, SXFRCTL1, *sxfrctl1);
|
|
|
|
|
2001-01-22 21:03:48 +00:00
|
|
|
if ((ahc->features & AHC_WIDE) != 0)
|
|
|
|
write_brdctl(ahc, brddat);
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
SEEPROM_OUTB(sd, sd->sd_MS); /* Clear CS */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
ahc_new_term_detect(struct ahc_softc *ahc, int *enableSEC_low,
|
|
|
|
int *enableSEC_high, int *enablePRI_low,
|
|
|
|
int *enablePRI_high, int *eeprom_present)
|
|
|
|
{
|
|
|
|
uint8_t brdctl;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BRDDAT7 = Eeprom
|
|
|
|
* BRDDAT6 = Enable Secondary High Byte termination
|
|
|
|
* BRDDAT5 = Enable Secondary Low Byte termination
|
|
|
|
* BRDDAT4 = Enable Primary high byte termination
|
|
|
|
* BRDDAT3 = Enable Primary low byte termination
|
|
|
|
*/
|
|
|
|
brdctl = read_brdctl(ahc);
|
|
|
|
*eeprom_present = brdctl & BRDDAT7;
|
|
|
|
*enableSEC_high = (brdctl & BRDDAT6);
|
|
|
|
*enableSEC_low = (brdctl & BRDDAT5);
|
|
|
|
*enablePRI_high = (brdctl & BRDDAT4);
|
|
|
|
*enablePRI_low = (brdctl & BRDDAT3);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
|
|
|
|
int *internal68_present, int *externalcable_present,
|
|
|
|
int *eeprom_present)
|
|
|
|
{
|
|
|
|
uint8_t brdctl;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* First read the status of our cables.
|
|
|
|
* Set the rom bank to 0 since the
|
|
|
|
* bank setting serves as a multiplexor
|
|
|
|
* for the cable detection logic.
|
|
|
|
* BRDDAT5 controls the bank switch.
|
|
|
|
*/
|
|
|
|
write_brdctl(ahc, 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now read the state of the internal
|
|
|
|
* connectors. BRDDAT6 is INT50 and
|
|
|
|
* BRDDAT7 is INT68.
|
|
|
|
*/
|
|
|
|
brdctl = read_brdctl(ahc);
|
2001-01-22 21:03:48 +00:00
|
|
|
*internal50_present = (brdctl & BRDDAT6) ? 0 : 1;
|
|
|
|
*internal68_present = (brdctl & BRDDAT7) ? 0 : 1;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the rom bank to 1 and determine
|
|
|
|
* the other signals.
|
|
|
|
*/
|
|
|
|
write_brdctl(ahc, BRDDAT5);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now read the state of the external
|
|
|
|
* connectors. BRDDAT6 is EXT68 and
|
|
|
|
* BRDDAT7 is EPROMPS.
|
|
|
|
*/
|
|
|
|
brdctl = read_brdctl(ahc);
|
2001-01-22 21:03:48 +00:00
|
|
|
*externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;
|
|
|
|
*eeprom_present = (brdctl & BRDDAT7) ? 1 : 0;
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
|
|
|
|
int *externalcable_present, int *eeprom_present)
|
|
|
|
{
|
|
|
|
uint8_t brdctl;
|
2002-08-31 06:44:56 +00:00
|
|
|
uint8_t spiocap;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
2002-08-31 06:44:56 +00:00
|
|
|
spiocap = ahc_inb(ahc, SPIOCAP);
|
|
|
|
spiocap &= ~SOFTCMDEN;
|
|
|
|
spiocap |= EXT_BRDCTL;
|
|
|
|
ahc_outb(ahc, SPIOCAP, spiocap);
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc_flush_device_writes(ahc);
|
|
|
|
ahc_delay(500);
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_outb(ahc, BRDCTL, 0);
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc_flush_device_writes(ahc);
|
|
|
|
ahc_delay(500);
|
2000-09-16 20:02:28 +00:00
|
|
|
brdctl = ahc_inb(ahc, BRDCTL);
|
2001-01-22 21:03:48 +00:00
|
|
|
*internal50_present = (brdctl & BRDDAT5) ? 0 : 1;
|
|
|
|
*externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;
|
|
|
|
*eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0;
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
2002-04-24 16:58:51 +00:00
|
|
|
int
|
|
|
|
ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
int wait;
|
|
|
|
|
|
|
|
if ((ahc->features & AHC_SPIOCAP) != 0
|
|
|
|
&& (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0)
|
|
|
|
return (0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Request access of the memory port. When access is
|
|
|
|
* granted, SEERDY will go high. We use a 1 second
|
|
|
|
* timeout which should be near 1 second more than
|
|
|
|
* is needed. Reason: after the chip reset, there
|
|
|
|
* should be no contention.
|
|
|
|
*/
|
|
|
|
SEEPROM_OUTB(sd, sd->sd_MS);
|
|
|
|
wait = 1000; /* 1 second timeout in msec */
|
|
|
|
while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) {
|
|
|
|
ahc_delay(1000); /* delay 1 msec */
|
|
|
|
}
|
|
|
|
if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) {
|
|
|
|
SEEPROM_OUTB(sd, 0);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
2002-04-24 16:58:51 +00:00
|
|
|
void
|
|
|
|
ahc_release_seeprom(struct seeprom_descriptor *sd)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
/* Release access to the memory port and the serial EEPROM. */
|
|
|
|
SEEPROM_OUTB(sd, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
write_brdctl(struct ahc_softc *ahc, uint8_t value)
|
|
|
|
{
|
|
|
|
uint8_t brdctl;
|
|
|
|
|
|
|
|
if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
|
|
|
|
brdctl = BRDSTB;
|
|
|
|
if (ahc->channel == 'B')
|
|
|
|
brdctl |= BRDCS;
|
|
|
|
} else if ((ahc->features & AHC_ULTRA2) != 0) {
|
|
|
|
brdctl = 0;
|
|
|
|
} else {
|
|
|
|
brdctl = BRDSTB|BRDCS;
|
|
|
|
}
|
|
|
|
ahc_outb(ahc, BRDCTL, brdctl);
|
2001-01-22 21:03:48 +00:00
|
|
|
ahc_flush_device_writes(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
brdctl |= value;
|
|
|
|
ahc_outb(ahc, BRDCTL, brdctl);
|
2001-01-22 21:03:48 +00:00
|
|
|
ahc_flush_device_writes(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0)
|
|
|
|
brdctl |= BRDSTB_ULTRA2;
|
|
|
|
else
|
|
|
|
brdctl &= ~BRDSTB;
|
|
|
|
ahc_outb(ahc, BRDCTL, brdctl);
|
2001-01-22 21:03:48 +00:00
|
|
|
ahc_flush_device_writes(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0)
|
|
|
|
brdctl = 0;
|
|
|
|
else
|
|
|
|
brdctl &= ~BRDCS;
|
|
|
|
ahc_outb(ahc, BRDCTL, brdctl);
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint8_t
|
2003-05-26 21:09:15 +00:00
|
|
|
read_brdctl(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
uint8_t brdctl;
|
|
|
|
uint8_t value;
|
|
|
|
|
|
|
|
if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
|
|
|
|
brdctl = BRDRW;
|
|
|
|
if (ahc->channel == 'B')
|
|
|
|
brdctl |= BRDCS;
|
|
|
|
} else if ((ahc->features & AHC_ULTRA2) != 0) {
|
|
|
|
brdctl = BRDRW_ULTRA2;
|
|
|
|
} else {
|
|
|
|
brdctl = BRDRW|BRDCS;
|
|
|
|
}
|
|
|
|
ahc_outb(ahc, BRDCTL, brdctl);
|
2001-01-22 21:03:48 +00:00
|
|
|
ahc_flush_device_writes(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
value = ahc_inb(ahc, BRDCTL);
|
|
|
|
ahc_outb(ahc, BRDCTL, 0);
|
|
|
|
return (value);
|
|
|
|
}
|
|
|
|
|
2003-05-03 23:55:38 +00:00
|
|
|
static void
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_pci_intr(struct ahc_softc *ahc)
|
|
|
|
{
|
2000-09-22 22:18:05 +00:00
|
|
|
u_int error;
|
|
|
|
u_int status1;
|
|
|
|
|
|
|
|
error = ahc_inb(ahc, ERROR);
|
|
|
|
if ((error & PCIERRSTAT) == 0)
|
|
|
|
return;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
status1 = ahc_pci_read_config(ahc->dev_softc,
|
|
|
|
PCIR_STATUS + 1, /*bytes*/1);
|
|
|
|
|
2000-09-22 22:18:05 +00:00
|
|
|
printf("%s: PCI error Interrupt at seqaddr = 0x%x\n",
|
|
|
|
ahc_name(ahc),
|
|
|
|
ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
if (status1 & DPE) {
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->pci_target_perr_count++;
|
2000-09-16 20:02:28 +00:00
|
|
|
printf("%s: Data Parity Error Detected during address "
|
|
|
|
"or write data phase\n", ahc_name(ahc));
|
|
|
|
}
|
|
|
|
if (status1 & SSE) {
|
2000-10-05 04:24:14 +00:00
|
|
|
printf("%s: Signal System Error Detected\n", ahc_name(ahc));
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
if (status1 & RMA) {
|
2000-10-05 04:24:14 +00:00
|
|
|
printf("%s: Received a Master Abort\n", ahc_name(ahc));
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
if (status1 & RTA) {
|
|
|
|
printf("%s: Received a Target Abort\n", ahc_name(ahc));
|
|
|
|
}
|
|
|
|
if (status1 & STA) {
|
|
|
|
printf("%s: Signaled a Target Abort\n", ahc_name(ahc));
|
|
|
|
}
|
|
|
|
if (status1 & DPR) {
|
|
|
|
printf("%s: Data Parity Error has been reported via PERR#\n",
|
|
|
|
ahc_name(ahc));
|
|
|
|
}
|
2001-07-18 21:39:48 +00:00
|
|
|
|
|
|
|
/* Clear latched errors. */
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
|
|
|
|
status1, /*bytes*/1);
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {
|
|
|
|
printf("%s: Latched PCIERR interrupt with "
|
|
|
|
"no status bits set\n", ahc_name(ahc));
|
|
|
|
} else {
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_outb(ahc, CLRINT, CLRPARERR);
|
|
|
|
}
|
2000-09-22 22:18:05 +00:00
|
|
|
|
2003-05-03 23:55:38 +00:00
|
|
|
if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) {
|
|
|
|
printf(
|
|
|
|
"%s: WARNING WARNING WARNING WARNING\n"
|
|
|
|
"%s: Too many PCI parity errors observed as a target.\n"
|
|
|
|
"%s: Some device on this bus is generating bad parity.\n"
|
|
|
|
"%s: This is an error *observed by*, not *generated by*, this controller.\n"
|
|
|
|
"%s: PCI parity error checking has been disabled.\n"
|
|
|
|
"%s: WARNING WARNING WARNING WARNING\n",
|
|
|
|
ahc_name(ahc), ahc_name(ahc), ahc_name(ahc),
|
|
|
|
ahc_name(ahc), ahc_name(ahc), ahc_name(ahc));
|
2003-05-26 21:20:47 +00:00
|
|
|
ahc->seqctl |= FAILDIS;
|
|
|
|
ahc_outb(ahc, SEQCTL, ahc->seqctl);
|
2003-05-03 23:55:38 +00:00
|
|
|
}
|
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
|
|
|
ahc_unpause(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
2003-05-03 23:55:38 +00:00
|
|
|
static int
|
|
|
|
ahc_pci_chip_init(struct ahc_softc *ahc)
|
|
|
|
{
|
|
|
|
ahc_outb(ahc, DSCOMMAND0, ahc->bus_softc.pci_softc.dscommand0);
|
|
|
|
ahc_outb(ahc, DSPCISTATUS, ahc->bus_softc.pci_softc.dspcistatus);
|
|
|
|
if ((ahc->features & AHC_DT) != 0) {
|
|
|
|
u_int sfunct;
|
|
|
|
|
|
|
|
sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
|
|
|
|
ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
|
|
|
|
ahc_outb(ahc, OPTIONMODE, ahc->bus_softc.pci_softc.optionmode);
|
|
|
|
ahc_outw(ahc, TARGCRCCNT, ahc->bus_softc.pci_softc.targcrccnt);
|
|
|
|
ahc_outb(ahc, SFUNCT, sfunct);
|
|
|
|
ahc_outb(ahc, CRCCONTROL1,
|
|
|
|
ahc->bus_softc.pci_softc.crccontrol1);
|
|
|
|
}
|
|
|
|
if ((ahc->features & AHC_MULTI_FUNC) != 0)
|
|
|
|
ahc_outb(ahc, SCBBADDR, ahc->bus_softc.pci_softc.scbbaddr);
|
|
|
|
|
|
|
|
if ((ahc->features & AHC_ULTRA2) != 0)
|
|
|
|
ahc_outb(ahc, DFF_THRSH, ahc->bus_softc.pci_softc.dff_thrsh);
|
|
|
|
|
|
|
|
return (ahc_chip_init(ahc));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
ahc_pci_suspend(struct ahc_softc *ahc)
|
|
|
|
{
|
|
|
|
return (ahc_suspend(ahc));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
ahc_pci_resume(struct ahc_softc *ahc)
|
|
|
|
{
|
|
|
|
|
|
|
|
ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We assume that the OS has restored our register
|
|
|
|
* mappings, etc. Just update the config space registers
|
|
|
|
* that the OS doesn't know about and rely on our chip
|
|
|
|
* reset handler to handle the rest.
|
|
|
|
*/
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4,
|
|
|
|
ahc->bus_softc.pci_softc.devconfig);
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1,
|
|
|
|
ahc->bus_softc.pci_softc.command);
|
|
|
|
ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1,
|
|
|
|
ahc->bus_softc.pci_softc.csize_lattime);
|
|
|
|
if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) {
|
|
|
|
struct seeprom_descriptor sd;
|
|
|
|
u_int sxfrctl1;
|
|
|
|
|
|
|
|
sd.sd_ahc = ahc;
|
|
|
|
sd.sd_control_offset = SEECTL;
|
|
|
|
sd.sd_status_offset = SEECTL;
|
|
|
|
sd.sd_dataout_offset = SEECTL;
|
|
|
|
|
|
|
|
ahc_acquire_seeprom(ahc, &sd);
|
|
|
|
configure_termination(ahc, &sd,
|
|
|
|
ahc->seep_config->adapter_control,
|
|
|
|
&sxfrctl1);
|
|
|
|
ahc_release_seeprom(&sd);
|
|
|
|
}
|
|
|
|
return (ahc_resume(ahc));
|
|
|
|
}
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aic785X_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
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
|
|
|
uint8_t rev;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
pci = ahc->dev_softc;
|
|
|
|
ahc->channel = 'A';
|
|
|
|
ahc->chip = AHC_AIC7850;
|
|
|
|
ahc->features = AHC_AIC7850_FE;
|
|
|
|
ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
|
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
|
|
|
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
|
|
|
|
if (rev >= 1)
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->instruction_ram_size = 512;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aic7860_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t rev;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
pci = ahc->dev_softc;
|
|
|
|
ahc->channel = 'A';
|
|
|
|
ahc->chip = AHC_AIC7860;
|
|
|
|
ahc->features = AHC_AIC7860_FE;
|
|
|
|
ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
|
2000-09-16 20:02:28 +00:00
|
|
|
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
|
|
|
|
if (rev >= 1)
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->instruction_ram_size = 512;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2001-01-22 21:03:48 +00:00
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_apa1480_setup(struct ahc_softc *ahc)
|
2001-01-22 21:03:48 +00:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aic7860_setup(ahc);
|
2001-01-22 21:03:48 +00:00
|
|
|
if (error != 0)
|
|
|
|
return (error);
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->features |= AHC_REMOVABLE;
|
2001-01-22 21:03:48 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aic7870_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
|
|
|
|
ahc->channel = 'A';
|
|
|
|
ahc->chip = AHC_AIC7870;
|
|
|
|
ahc->features = AHC_AIC7870_FE;
|
|
|
|
ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->instruction_ram_size = 512;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha394X_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aic7870_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
if (error == 0)
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aha394XX_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha398X_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aic7870_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
if (error == 0)
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aha398XX_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha494X_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aic7870_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
if (error == 0)
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aha494XX_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aic7880_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t rev;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
pci = ahc->dev_softc;
|
|
|
|
ahc->channel = 'A';
|
|
|
|
ahc->chip = AHC_AIC7880;
|
|
|
|
ahc->features = AHC_AIC7880_FE;
|
|
|
|
ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
|
2000-09-16 20:02:28 +00:00
|
|
|
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
|
|
|
|
if (rev >= 1) {
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
|
2000-09-16 20:02:28 +00:00
|
|
|
} else {
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->instruction_ram_size = 512;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha2940Pro_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->flags |= AHC_INT50_SPEEDFLEX;
|
2002-08-31 06:44:56 +00:00
|
|
|
return (ahc_aic7880_setup(ahc));
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha394XU_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aic7880_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
if (error == 0)
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aha394XX_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha398XU_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aic7880_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
if (error == 0)
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aha398XX_setup(ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aic7890_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t rev;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
pci = ahc->dev_softc;
|
|
|
|
ahc->channel = 'A';
|
|
|
|
ahc->chip = AHC_AIC7890;
|
|
|
|
ahc->features = AHC_AIC7890_FE;
|
|
|
|
ahc->flags |= AHC_NEWEEPROM_FMT;
|
2000-09-16 20:02:28 +00:00
|
|
|
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
|
|
|
|
if (rev == 0)
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG;
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->instruction_ram_size = 768;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aic7892_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
|
|
|
|
ahc->channel = 'A';
|
|
|
|
ahc->chip = AHC_AIC7892;
|
|
|
|
ahc->features = AHC_AIC7892_FE;
|
|
|
|
ahc->flags |= AHC_NEWEEPROM_FMT;
|
|
|
|
ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->instruction_ram_size = 1024;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aic7895_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t rev;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
pci = ahc->dev_softc;
|
|
|
|
ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* The 'C' revision of the aic7895 has a few additional features.
|
|
|
|
*/
|
|
|
|
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
|
|
|
|
if (rev >= 4) {
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->chip = AHC_AIC7895C;
|
|
|
|
ahc->features = AHC_AIC7895C_FE;
|
2000-09-16 20:02:28 +00:00
|
|
|
} else {
|
|
|
|
u_int command;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->chip = AHC_AIC7895;
|
|
|
|
ahc->features = AHC_AIC7895_FE;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The BIOS disables the use of MWI transactions
|
|
|
|
* since it does not have the MWI bug work around
|
|
|
|
* we have. Disabling MWI reduces performance, so
|
|
|
|
* turn it on again.
|
|
|
|
*/
|
|
|
|
command = ahc_pci_read_config(pci, PCIR_COMMAND, /*bytes*/1);
|
|
|
|
command |= PCIM_CMD_MWRICEN;
|
|
|
|
ahc_pci_write_config(pci, PCIR_COMMAND, command, /*bytes*/1);
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->bugs |= AHC_PCI_MWI_BUG;
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* XXX Does CACHETHEN really not work??? What about PCI retry?
|
|
|
|
* on C level chips. Need to test, but for now, play it safe.
|
|
|
|
*/
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_PCI_2_1_RETRY_BUG
|
|
|
|
| AHC_CACHETHEN_BUG;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
uint32_t devconfig;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cachesize must also be zero due to stray DAC
|
|
|
|
* problem when sitting behind some bridges.
|
|
|
|
*/
|
|
|
|
ahc_pci_write_config(pci, CSIZE_LATTIME, 0, /*bytes*/1);
|
|
|
|
devconfig = ahc_pci_read_config(pci, DEVCONFIG, /*bytes*/1);
|
|
|
|
devconfig |= MRDCEN;
|
|
|
|
ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1);
|
|
|
|
#endif
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->flags |= AHC_NEWEEPROM_FMT;
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->instruction_ram_size = 512;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aic7896_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
|
|
|
|
|
|
|
pci = ahc->dev_softc;
|
|
|
|
ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
|
|
|
|
ahc->chip = AHC_AIC7896;
|
|
|
|
ahc->features = AHC_AIC7896_FE;
|
|
|
|
ahc->flags |= AHC_NEWEEPROM_FMT;
|
|
|
|
ahc->bugs |= AHC_CACHETHEN_DIS_BUG;
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->instruction_ram_size = 768;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aic7899_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
|
|
|
|
|
|
|
pci = ahc->dev_softc;
|
|
|
|
ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
|
|
|
|
ahc->chip = AHC_AIC7899;
|
|
|
|
ahc->features = AHC_AIC7899_FE;
|
|
|
|
ahc->flags |= AHC_NEWEEPROM_FMT;
|
|
|
|
ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
|
2003-05-03 23:55:38 +00:00
|
|
|
ahc->instruction_ram_size = 1024;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2001-01-22 21:03:48 +00:00
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha29160C_setup(struct ahc_softc *ahc)
|
2001-01-22 21:03:48 +00:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
error = ahc_aic7899_setup(ahc);
|
2001-01-22 21:03:48 +00:00
|
|
|
if (error != 0)
|
|
|
|
return (error);
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->features |= AHC_REMOVABLE;
|
2001-01-22 21:03:48 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_raid_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
|
|
|
printf("RAID functionality unsupported\n");
|
|
|
|
return (ENXIO);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha394XX_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
|
|
|
|
|
|
|
pci = ahc->dev_softc;
|
2000-09-16 20:02:28 +00:00
|
|
|
switch (ahc_get_pci_slot(pci)) {
|
|
|
|
case AHC_394X_SLOT_CHANNEL_A:
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'A';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
case AHC_394X_SLOT_CHANNEL_B:
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'B';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("adapter at unexpected slot %d\n"
|
|
|
|
"unable to map to a channel\n",
|
|
|
|
ahc_get_pci_slot(pci));
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'A';
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha398XX_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
|
|
|
|
|
|
|
pci = ahc->dev_softc;
|
2000-09-16 20:02:28 +00:00
|
|
|
switch (ahc_get_pci_slot(pci)) {
|
|
|
|
case AHC_398X_SLOT_CHANNEL_A:
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'A';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
case AHC_398X_SLOT_CHANNEL_B:
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'B';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
case AHC_398X_SLOT_CHANNEL_C:
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'C';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("adapter at unexpected slot %d\n"
|
|
|
|
"unable to map to a channel\n",
|
|
|
|
ahc_get_pci_slot(pci));
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'A';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
}
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->flags |= AHC_LARGE_SEEPROM;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_aha494XX_setup(struct ahc_softc *ahc)
|
2000-09-16 20:02:28 +00:00
|
|
|
{
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc_dev_softc_t pci;
|
|
|
|
|
|
|
|
pci = ahc->dev_softc;
|
2000-09-16 20:02:28 +00:00
|
|
|
switch (ahc_get_pci_slot(pci)) {
|
|
|
|
case AHC_494X_SLOT_CHANNEL_A:
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'A';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
case AHC_494X_SLOT_CHANNEL_B:
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'B';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
case AHC_494X_SLOT_CHANNEL_C:
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'C';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
case AHC_494X_SLOT_CHANNEL_D:
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'D';
|
2000-09-16 20:02:28 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("adapter at unexpected slot %d\n"
|
|
|
|
"unable to map to a channel\n",
|
|
|
|
ahc_get_pci_slot(pci));
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->channel = 'A';
|
2000-09-16 20:02:28 +00:00
|
|
|
}
|
2001-07-18 21:39:48 +00:00
|
|
|
ahc->flags |= AHC_LARGE_SEEPROM;
|
2000-09-16 20:02:28 +00:00
|
|
|
return (0);
|
|
|
|
}
|