Commit c21e8b92 authored by James Bottomley's avatar James Bottomley

Update aic79xx to 1.3.11, aic7xxx to 6.2.36

From: "Justin T. Gibbs" <gibbs@scsiguy.com>
parent a047e289
==================================================================== ====================================================================
= Adaptec Ultra320 Family Manager Set v1.3.0 = = Adaptec Ultra320 Family Manager Set v1.3.11 =
= = = =
= README for = = README for =
= The Linux Operating System = = The Linux Operating System =
...@@ -19,57 +19,169 @@ The following information is available in this file: ...@@ -19,57 +19,169 @@ The following information is available in this file:
The following Adaptec SCSI Host Adapters are supported by this The following Adaptec SCSI Host Adapters are supported by this
driver set. driver set.
Ultra320 Adapters Description Ultra320 ASIC Description
---------------------------------------------------------------- ----------------------------------------------------------------
Adaptec SCSI Card 39320 Dual Channel 64-bit PCI-X 133MHz to AIC-7901A Single Channel 64-bit PCI-X 133MHz to
Ultra320 SCSI Card (one external Ultra320 SCSI ASIC
68-pin, two internal 68-pin) AIC-7901B Single Channel 64-bit PCI-X 133MHz to
Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to Ultra320 SCSI ASIC with Retained Training
Ultra320 SCSI Card (two external VHDC AIC-7902A4 Dual Channel 64-bit PCI-X 133MHz to
and one internal 68-pin) Ultra320 SCSI ASIC
Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to AIC-7902B Dual Channel 64-bit PCI-X 133MHz to
Ultra320 SCSI Card (two external VHDC Ultra320 SCSI ASIC with Retained Training
and one internal 68-pin) based on the
AIC-7902B ASIC Ultra320 Adapters Description ASIC
Adaptec SCSI Card 29320 Single Channel 64-bit PCI-X 133MHz to --------------------------------------------------------------------------
Ultra320 SCSI Card (one external Adaptec SCSI Card 39320 Dual Channel 64-bit PCI-X 133MHz to 7902A4/7902B
68-pin, two internal 68-pin, one Ultra320 SCSI Card (one external
internal 50-pin) 68-pin, two internal 68-pin)
Adaptec SCSI Card 29320LP Single Channel 64-bit Low Profile Adaptec SCSI Card 39320A Dual Channel 64-bit PCI-X 133MHz to 7902B
PCI-X 133MHz to Ultra320 SCSI Card Ultra320 SCSI Card (one external
(One external VHDC, one internal 68-pin, two internal 68-pin)
68-pin) Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to 7902A4
AIC-7901A Single Channel 64-bit PCI-X 133MHz to Ultra320 SCSI Card (two external VHDC
Ultra320 SCSI ASIC and one internal 68-pin)
AIC-7902A4 Dual Channel 64-bit PCI-X 133MHz to Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to 7902A4
Ultra320 SCSI ASIC Ultra320 SCSI Card (two external VHDC
AIC-7902B Dual Channel 64-bit PCI-X 133MHz to and one internal 68-pin) based on the
Ultra320 SCSI ASIC AIC-7902B ASIC
Adaptec SCSI Card 29320 Single Channel 64-bit PCI-X 133MHz to 7901A
Ultra320 SCSI Card (one external
68-pin, two internal 68-pin, one
internal 50-pin)
Adaptec SCSI Card 29320A Single Channel 64-bit PCI-X 133MHz to 7901B
Ultra320 SCSI Card (one external
68-pin, two internal 68-pin, one
internal 50-pin)
Adaptec SCSI Card 29320LP Single Channel 64-bit Low Profile 7901A
PCI-X 133MHz to Ultra320 SCSI Card
(One external VHDC, one internal
68-pin)
Adaptec SCSI Card 29320ALP Single Channel 64-bit Low Profile 7901B
PCI-X 133MHz to Ultra320 SCSI Card
(One external VHDC, one internal
68-pin)
2. Version History 2. Version History
(V1.3.0, January 2003) Full regression testing for all U320 products 1.3.11 (July 11, 2003)
completed. - Fix several deadlock issues.
- Add 29320ALP and 39320B Id's.
(V1.3.0 ALPHA, November 2002) Initial Alpha release.
Added abort and target/lun reset error recovery handler and 1.3.10 (June 3rd, 2003)
interrupt coalessing. - Align the SCB_TAG field on a 16byte boundary. This avoids
SCB corruption on some PCI-33 busses.
(V1.2.0, November 2002) Added support for Domain Validation and - Correct non-zero luns on Rev B. hardware.
Hewlett-Packard version of the 39320D and AIC-7902 adapters. - Update for change in 2.5.X SCSI proc FS interface.
Support for previous adapters has not been fully tested and should - When negotiation async via an 8bit WDTR message, send
only be used at the customer's own risk. an SDTR with an offset of 0 to be sure the target
knows we are async. This works around a firmware defect
(V1.1.1, September 2002) Added support for the Linux 2.5.X kernel series in the Quantum Atlas 10K.
- Implement controller susupend and resume.
(V1.1.0, August 2002) Added support for four additional SCSI - Clear PCI error state during driver attach so that we
products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901. don't disable memory mapped I/O due to a stray write
by some other driver probe that occurred before we
(V1.1, August 2002) Added support for four additional SCSI claimed the controller.
products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901.
1.3.9 (May 22nd, 2003)
(V1.0, May 2002) This is the initial release of the - Fix compiler errors.
Ultra320 FMS. The following is a list of supported features: - Remove S/G splitting for segments that cross a 4GB boundary.
This is guaranteed not to happen in Linux.
- Add support for scsi_report_device_reset() found in
2.5.X kernels.
- Add 7901B support.
- Simplify handling of the packtized lun Rev A workaround.
- Correct and simplify handling of the ignore wide residue
message. The previous code would fail to report a residual
if the transaction data length was even and we received
an IWR message.
1.3.8 (April 29th, 2003)
- Fix types accessed via the command line interface code.
- Perform a few firmware optimizations.
- Fix "Unexpected PKT busfree" errors.
- Use a sequencer interrupt to notify the host of
commands with bad status. We defer the notification
until there are no outstanding selections to ensure
that the host is interrupted for as short a time as
possible.
- Remove pre-2.2.X support.
- Add support for new 2.5.X interrupt API.
- Correct big-endian architecture support.
1.3.7 (April 16th, 2003)
- Use del_timer_sync() to ensure that no timeouts
are pending during controller shutdown.
- For pre-2.5.X kernels, carefully adjust our segment
list size to avoid SCSI malloc pool fragmentation.
- Cleanup channel display in our /proc output.
- Workaround duplicate device entries in the mid-layer
devlice list during add-single-device.
1.3.6 (March 28th, 2003)
- Correct a double free in the Domain Validation code.
- Correct a reference to free'ed memory during controller
shutdown.
- Reset the bus on an SE->LVD change. This is required
to reset our transcievers.
1.3.5 (March 24th, 2003)
- Fix a few register window mode bugs.
- Include read streaming in the PPR flags we display in
diagnostics as well as /proc.
- Add PCI hot plug support for 2.5.X kernels.
- Correct default precompensation value for RevA hardware.
- Fix Domain Validation thread shutdown.
- Add a firmware workaround to make the LED blink
brighter during packetized operations on the H2A4.
- Correct /proc display of user read streaming settings.
- Simplify driver locking by releasing the io_request_lock
upon driver entry from the mid-layer.
- Cleanup command line parsing and move much of this code
to aiclib.
1.3.4 (February 28th, 2003)
- Correct a race condition in our error recovery handler.
- Allow Test Unit Ready commands to take a full 5 seconds
during Domain Validation.
1.3.2 (February 19th, 2003)
- Correct a Rev B. regression due to the GEM318
compatibility fix included in 1.3.1.
1.3.1 (February 11th, 2003)
- Add support for the 39320A.
- Improve recovery for certain PCI-X errors.
- Fix handling of LQ/DATA/LQ/DATA for the
same write transaction that can occur without
interveining training.
- Correct compatibility issues with the GEM318
enclosure services device.
- Correct data corruption issue that occurred under
high tag depth write loads.
- Adapt to a change in the 2.5.X daemonize() API.
- Correct a "Missing case in ahd_handle_scsiint" panic.
1.3.0 (January 21st, 2003)
- Full regression testing for all U320 products completed.
- Added abort and target/lun reset error recovery handler and
interrupt coalessing.
1.2.0 (November 14th, 2002)
- Added support for Domain Validation
- Add support for the Hewlett-Packard version of the 39320D
and AIC-7902 adapters.
Support for previous adapters has not been fully tested and should
only be used at the customer's own risk.
1.1.1 (September 24th, 2002)
- Added support for the Linux 2.5.X kernel series
1.1.0 (September 17th, 2002)
- Added support for four additional SCSI products:
ASC-39320, ASC-29320, ASC-29320LP, AIC-7901.
1.0.0 (May 30th, 2002)
- Initial driver release.
2.1. Software/Hardware Features 2.1. Software/Hardware Features
- Support for the SPI-4 "Ultra320" standard: - Support for the SPI-4 "Ultra320" standard:
...@@ -82,6 +194,7 @@ The following information is available in this file: ...@@ -82,6 +194,7 @@ The following information is available in this file:
supported) supported)
- Support for the PCI-X standard up to 133MHz - Support for the PCI-X standard up to 133MHz
- Support for the PCI v2.2 standard - Support for the PCI v2.2 standard
- Domain Validation
2.2. Operating System Support: 2.2. Operating System Support:
- Redhat Linux 7.2, 7.3, 8.0, Advanced Server 2.1 - Redhat Linux 7.2, 7.3, 8.0, Advanced Server 2.1
......
...@@ -131,27 +131,54 @@ The following information is available in this file: ...@@ -131,27 +131,54 @@ The following information is available in this file:
SCSI "stub" effects. SCSI "stub" effects.
2. Version History 2. Version History
6.2.36 (June 3rd, 2003)
- Correct code that disables PCI parity error checking.
- Correct and simplify handling of the ignore wide residue
message. The previous code would fail to report a residual
if the transaction data length was even and we received
an IWR message.
- Add support for the 2.5.X EISA framework.
- Update for change in 2.5.X SCSI proc FS interface.
- Correct Domain Validation command-line option parsing.
- When negotiation async via an 8bit WDTR message, send
an SDTR with an offset of 0 to be sure the target
knows we are async. This works around a firmware defect
in the Quantum Atlas 10K.
- Clear PCI error state during driver attach so that we
don't disable memory mapped I/O due to a stray write
by some other driver probe that occurred before we
claimed the controller.
6.2.34 - Fix locking regression instroduced in 6.2.29 that 6.2.35 (May 14th, 2003)
could cuase a lock order reversal between the io_request_lock - Fix a few GCC 3.3 compiler warnings.
and our per-softc lock. This was only possible on RH9, - Correct operation on EISA Twin Channel controller.
SuSE, and kernel.org 2.4.X kernels. - Add support for 2.5.X's scsi_report_device_reset().
6.2.33 - Dynamically disable PCI parity error reporting after 6.2.34 (May 5th, 2003)
10 errors are reported to the user. These errors are - Fix locking regression instroduced in 6.2.29 that
the result of some other device issuing PCI transactions could cuase a lock order reversal between the io_request_lock
with bad parity. Once the user has been informed of the and our per-softc lock. This was only possible on RH9,
problem, continuing to report the errors just degrades SuSE, and kernel.org 2.4.X kernels.
our performance.
6.2.32 - Dynamically sized S/G lists to avoid SCSI malloc 6.2.33 (April 30th, 2003)
pool fragmentation and SCSI mid-layer deadlock. - Dynamically disable PCI parity error reporting after
10 errors are reported to the user. These errors are
the result of some other device issuing PCI transactions
with bad parity. Once the user has been informed of the
problem, continuing to report the errors just degrades
our performance.
6.2.28 - Domain Validation Fixes 6.2.32 (March 28th, 2003)
PCI parity error disable - Dynamically sized S/G lists to avoid SCSI malloc
Enhanced Memory Mapped I/O probe pool fragmentation and SCSI mid-layer deadlock.
6.2.20 - Added Domain Validation 6.2.28 (January 20th, 2003)
- Domain Validation Fixes
- Add ability to disable PCI parity error checking.
- Enhanced Memory Mapped I/O probe
6.2.20 (November 7th, 2002)
- Added Domain Validation.
3. Command Line Options 3. Command Line Options
......
# #
# AIC7XXX and AIC79XX 2.5.X Kernel configuration File. # AIC7XXX and AIC79XX 2.5.X Kernel configuration File.
# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#6 $ # $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#7 $
# #
config SCSI_AIC7XXX config SCSI_AIC7XXX
tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)" tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
depends on PCI || EISA
---help--- ---help---
This driver supports all of Adaptec's Fast through Ultra 160 PCI This driver supports all of Adaptec's Fast through Ultra 160 PCI
based SCSI controllers as well as the aic7770 based EISA and VLB based SCSI controllers as well as the aic7770 based EISA and VLB
...@@ -50,7 +51,7 @@ config AIC7XXX_RESET_DELAY_MS ...@@ -50,7 +51,7 @@ config AIC7XXX_RESET_DELAY_MS
config AIC7XXX_PROBE_EISA_VL config AIC7XXX_PROBE_EISA_VL
bool "Probe for EISA and VL AIC7XXX Adapters" bool "Probe for EISA and VL AIC7XXX Adapters"
depends on SCSI_AIC7XXX depends on SCSI_AIC7XXX && EISA
help help
Probe for EISA and VLB Aic7xxx controllers. In many newer systems, Probe for EISA and VLB Aic7xxx controllers. In many newer systems,
the invasive probes necessary to detect these controllers can cause the invasive probes necessary to detect these controllers can cause
......
# #
# Makefile for the Linux aic7xxx SCSI driver. # Makefile for the Linux aic7xxx SCSI driver.
# #
# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#6 $ # $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#7 $
# #
# Let kbuild descend into aicasm when cleaning # Let kbuild descend into aicasm when cleaning
...@@ -12,15 +12,15 @@ obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o ...@@ -12,15 +12,15 @@ obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o
# Core Fast -> U160 files # Core Fast -> U160 files
aic7xxx-y += aic7xxx_core.o \ aic7xxx-y += aic7xxx_core.o \
aic7xxx_93cx6.o \ aic7xxx_93cx6.o
aic7770.o aic7xxx-$(CONFIG_EISA) += aic7770.o
aic7xxx-$(CONFIG_PCI) += aic7xxx_pci.o aic7xxx-$(CONFIG_PCI) += aic7xxx_pci.o
aic7xxx-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) += aic7xxx_reg_print.o aic7xxx-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) += aic7xxx_reg_print.o
# Platform Specific Fast -> U160 Files # Platform Specific Fast -> U160 Files
aic7xxx-y += aic7xxx_osm.o \ aic7xxx-y += aic7xxx_osm.o \
aic7xxx_proc.o \ aic7xxx_proc.o
aic7770_osm.o aic7xxx-$(CONFIG_EISA) += aic7770_osm.o
aic7xxx-$(CONFIG_PCI) += aic7xxx_osm_pci.o aic7xxx-$(CONFIG_PCI) += aic7xxx_osm_pci.o
# Core U320 files # Core U320 files
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7770.c#30 $ * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#32 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -67,8 +67,7 @@ static ahc_device_setup_t ahc_aic7770_VL_setup; ...@@ -67,8 +67,7 @@ static ahc_device_setup_t ahc_aic7770_VL_setup;
static ahc_device_setup_t ahc_aic7770_EISA_setup;; static ahc_device_setup_t ahc_aic7770_EISA_setup;;
static ahc_device_setup_t ahc_aic7770_setup; static ahc_device_setup_t ahc_aic7770_setup;
struct aic7770_identity aic7770_ident_table[] =
struct aic7770_identity aic7770_ident_table [] =
{ {
{ {
ID_AHA_274x, ID_AHA_274x,
...@@ -82,6 +81,12 @@ struct aic7770_identity aic7770_ident_table [] = ...@@ -82,6 +81,12 @@ struct aic7770_identity aic7770_ident_table [] =
"Adaptec 284X SCSI adapter", "Adaptec 284X SCSI adapter",
ahc_aic7770_VL_setup ahc_aic7770_VL_setup
}, },
{
ID_AHA_284x,
0xFFFFFFFE,
"Adaptec 284X SCSI adapter (BIOS Disabled)",
ahc_aic7770_VL_setup
},
{ {
ID_OLV_274x, ID_OLV_274x,
0xFFFFFFFF, 0xFFFFFFFF,
...@@ -154,7 +159,7 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) ...@@ -154,7 +159,7 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
ahc->bus_suspend = aic7770_suspend; ahc->bus_suspend = aic7770_suspend;
ahc->bus_resume = aic7770_resume; ahc->bus_resume = aic7770_resume;
error = ahc_reset(ahc); error = ahc_reset(ahc, /*reinit*/FALSE);
if (error != 0) if (error != 0)
return (error); return (error);
......
/* /*
* Linux driver attachment glue for aic7770 based controllers. * Linux driver attachment glue for aic7770 based controllers.
* *
* Copyright (c) 2000-2001 Adaptec Inc. * Copyright (c) 2000-2003 Adaptec Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -36,27 +36,90 @@ ...@@ -36,27 +36,90 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#13 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#14 $
*/ */
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <linux/device.h>
#include <linux/eisa.h>
#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */
#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@') /* Bits 21-25 */
#define EISA_MFCTR_CHAR2(ID) (char)(((ID>>16) & 0x1F) | '@') /* Bits 16-20 */
#define EISA_PRODUCT_ID(ID) (short)((ID>>4) & 0xFFF) /* Bits 4-15 */
#define EISA_REVISION_ID(ID) (uint8_t)(ID & 0x0F) /* Bits 0-3 */
static int aic7770_eisa_dev_probe(struct device *dev);
static int aic7770_eisa_dev_remove(struct device *dev);
static struct eisa_driver aic7770_driver = {
.driver = {
.name = "aic7xxx",
.probe = aic7770_eisa_dev_probe,
.remove = aic7770_eisa_dev_remove,
}
};
typedef struct device *aic7770_dev_t;
#else
#define MINSLOT 1 #define MINSLOT 1
#define NUMSLOTS 16 #define NUMSLOTS 16
#define IDOFFSET 0x80 #define IDOFFSET 0x80
int typedef void *aic7770_dev_t;
aic7770_linux_probe(Scsi_Host_Template *template) #endif
static int aic7770_linux_config(struct aic7770_identity *entry,
aic7770_dev_t dev, u_int eisaBase);
void
ahc_linux_eisa_init(void)
{ {
#if defined(__i386__) || defined(__alpha__) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
struct eisa_device_id *eid;
struct aic7770_identity *id;
int i;
if (aic7xxx_probe_eisa_vl == 0)
return;
/*
* Linux requires the EISA IDs to be specified in
* the EISA ID string format. Perform the conversion
* and setup a table with a NUL terminal entry.
*/
aic7770_driver.id_table = malloc(sizeof(struct eisa_device_id) *
(ahc_num_aic7770_devs + 1),
M_DEVBUF, M_NOWAIT);
if (aic7770_driver.id_table == NULL)
return;
for (eid = (struct eisa_device_id *)aic7770_driver.id_table,
id = aic7770_ident_table, i = 0;
i < ahc_num_aic7770_devs; eid++, id++, i++) {
sprintf(eid->sig, "%c%c%c%03X%01X",
EISA_MFCTR_CHAR0(id->full_id),
EISA_MFCTR_CHAR1(id->full_id),
EISA_MFCTR_CHAR2(id->full_id),
EISA_PRODUCT_ID(id->full_id),
EISA_REVISION_ID(id->full_id));
eid->driver_data = i;
}
eid->sig[0] = 0;
eisa_driver_register(&aic7770_driver);
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */
struct aic7770_identity *entry; struct aic7770_identity *entry;
struct ahc_softc *ahc; u_int slot;
int i, slot; u_int eisaBase;
int eisaBase; u_int i;
int found;
if (aic7xxx_probe_eisa_vl == 0)
return;
eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET; eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
found = 0;
for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) { for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
uint32_t eisa_id; uint32_t eisa_id;
size_t id_size; size_t id_size;
...@@ -83,45 +146,64 @@ aic7770_linux_probe(Scsi_Host_Template *template) ...@@ -83,45 +146,64 @@ aic7770_linux_probe(Scsi_Host_Template *template)
continue; /* no EISA card in slot */ continue; /* no EISA card in slot */
entry = aic7770_find_device(eisa_id); entry = aic7770_find_device(eisa_id);
if (entry != NULL) { if (entry != NULL)
char buf[80]; aic7770_linux_config(entry, NULL, eisaBase);
char *name; }
int error; #endif
}
/*
* Allocate a softc for this card and void
* set it up for attachment by our ahc_linux_eisa_exit(void)
* common detect routine. {
*/ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
sprintf(buf, "ahc_eisa:%d", slot); if (aic7xxx_probe_eisa_vl == 0)
name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); return;
if (name == NULL)
break; if (aic7770_driver.id_table != NULL) {
strcpy(name, buf); eisa_driver_unregister(&aic7770_driver);
ahc = ahc_alloc(template, name); free(aic7770_driver.id_table, M_DEVBUF);
if (ahc == NULL) {
/*
* If we can't allocate this one,
* chances are we won't be able to
* allocate future card structures.
*/
break;
}
error = aic7770_config(ahc, entry, eisaBase);
if (error != 0) {
ahc->bsh.ioport = 0;
ahc_free(ahc);
continue;
}
found++;
}
} }
return (found);
#else
return (0);
#endif #endif
} }
static int
aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev,
u_int eisaBase)
{
struct ahc_softc *ahc;
char buf[80];
char *name;
int error;
/*
* Allocate a softc for this card and
* set it up for attachment by our
* common detect routine.
*/
sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
if (name == NULL)
return (ENOMEM);
strcpy(name, buf);
ahc = ahc_alloc(&aic7xxx_driver_template, name);
if (ahc == NULL) {
free(name, M_DEVBUF);
return (ENOMEM);
}
error = aic7770_config(ahc, entry, eisaBase);
if (error != 0) {
ahc->bsh.ioport = 0;
ahc_free(ahc);
return (error);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
dev->driver_data = (void *)ahc;
if (aic7xxx_detect_complete)
error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
#endif
return (error);
}
int int
aic7770_map_registers(struct ahc_softc *ahc, u_int port) aic7770_map_registers(struct ahc_softc *ahc, u_int port)
{ {
...@@ -129,6 +211,8 @@ aic7770_map_registers(struct ahc_softc *ahc, u_int port) ...@@ -129,6 +211,8 @@ aic7770_map_registers(struct ahc_softc *ahc, u_int port)
* Lock out other contenders for our i/o space. * Lock out other contenders for our i/o space.
*/ */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
if (check_region(port, AHC_EISA_IOSIZE) != 0)
return (ENOMEM);
request_region(port, AHC_EISA_IOSIZE, "aic7xxx"); request_region(port, AHC_EISA_IOSIZE, "aic7xxx");
#else #else
if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0) if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
...@@ -155,3 +239,41 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq) ...@@ -155,3 +239,41 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq)
return (-error); return (-error);
} }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
static int
aic7770_eisa_dev_probe(struct device *dev)
{
struct eisa_device *edev;
edev = to_eisa_device(dev);
return (aic7770_linux_config(aic7770_ident_table + edev->id.driver_data,
dev, edev->base_addr+AHC_EISA_SLOT_OFFSET));
}
static int
aic7770_eisa_dev_remove(struct device *dev)
{
struct ahc_softc *ahc;
u_long l;
/*
* We should be able to just perform
* the free directly, but check our
* list for extra sanity.
*/
ahc_list_lock(&l);
ahc = ahc_find_softc((struct ahc_softc *)dev->driver_data);
if (ahc != NULL) {
u_long s;
ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE);
ahc_unlock(ahc, &s);
ahc_free(ahc);
}
ahc_list_unlock(&l);
return (0);
}
#endif
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#90 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#95 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -229,8 +229,10 @@ typedef enum { ...@@ -229,8 +229,10 @@ typedef enum {
AHD_RTI = 0x04000,/* Retained Training Support */ AHD_RTI = 0x04000,/* Retained Training Support */
AHD_NEW_IOCELL_OPTS = 0x08000,/* More Signal knobs in the IOCELL */ AHD_NEW_IOCELL_OPTS = 0x08000,/* More Signal knobs in the IOCELL */
AHD_NEW_DFCNTRL_OPTS = 0x10000,/* SCSIENWRDIS bit */ AHD_NEW_DFCNTRL_OPTS = 0x10000,/* SCSIENWRDIS bit */
AHD_FAST_CDB_DELIVERY = 0x20000,/* CDB acks released to Output Sync */
AHD_REMOVABLE = 0x00000,/* Hot-Swap supported - None so far*/ AHD_REMOVABLE = 0x00000,/* Hot-Swap supported - None so far*/
AHD_AIC7901_FE = AHD_FENONE, AHD_AIC7901_FE = AHD_FENONE,
AHD_AIC7901A_FE = AHD_FENONE,
AHD_AIC7902_FE = AHD_MULTI_FUNC AHD_AIC7902_FE = AHD_MULTI_FUNC
} ahd_feature; } ahd_feature;
...@@ -372,7 +374,8 @@ typedef enum { ...@@ -372,7 +374,8 @@ typedef enum {
AHD_HP_BOARD = 0x100000, AHD_HP_BOARD = 0x100000,
AHD_RESET_POLL_ACTIVE = 0x200000, AHD_RESET_POLL_ACTIVE = 0x200000,
AHD_UPDATE_PEND_CMDS = 0x400000, AHD_UPDATE_PEND_CMDS = 0x400000,
AHD_RUNNING_QOUTFIFO = 0x800000 AHD_RUNNING_QOUTFIFO = 0x800000,
AHD_HAD_FIRST_SEL = 0x1000000
} ahd_flag; } ahd_flag;
/************************* Hardware SCB Definition ***************************/ /************************* Hardware SCB Definition ***************************/
...@@ -494,21 +497,21 @@ struct hardware_scb { ...@@ -494,21 +497,21 @@ struct hardware_scb {
* transfer. * transfer.
*/ */
#define SG_PTR_MASK 0xFFFFFFF8 #define SG_PTR_MASK 0xFFFFFFF8
/*16*/ uint64_t dataptr; /*16*/ uint16_t tag; /* Reused by Sequencer. */
/*24*/ uint32_t datacnt; /* Byte 3 is spare. */ /*18*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */
/*28*/ uint32_t sgptr; /*19*/ uint8_t scsiid; /*
/*32*/ uint32_t hscb_busaddr;
/*36*/ uint32_t next_hscb_busaddr;
/*40*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */
/*41*/ uint8_t scsiid; /*
* Selection out Id * Selection out Id
* Our Id (bits 0-3) Their ID (bits 4-7) * Our Id (bits 0-3) Their ID (bits 4-7)
*/ */
/*42*/ uint8_t lun; /*20*/ uint8_t lun;
/*43*/ uint8_t task_attribute; /*21*/ uint8_t task_attribute;
/*44*/ uint8_t cdb_len; /*22*/ uint8_t cdb_len;
/*45*/ uint8_t task_management; /*23*/ uint8_t task_management;
/*46*/ uint16_t tag; /* Reused by Sequencer. */ /*24*/ uint64_t dataptr;
/*32*/ uint32_t datacnt; /* Byte 3 is spare. */
/*36*/ uint32_t sgptr;
/*40*/ uint32_t hscb_busaddr;
/*44*/ uint32_t next_hscb_busaddr;
/********** Long lun field only downloaded for full 8 byte lun support ********/ /********** Long lun field only downloaded for full 8 byte lun support ********/
/*48*/ uint8_t pkt_long_lun[8]; /*48*/ uint8_t pkt_long_lun[8];
/******* Fields below are not Downloaded (Sequencer may use for scratch) ******/ /******* Fields below are not Downloaded (Sequencer may use for scratch) ******/
...@@ -1379,13 +1382,13 @@ struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); ...@@ -1379,13 +1382,13 @@ struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb);
void ahd_alloc_scbs(struct ahd_softc *ahd); void ahd_alloc_scbs(struct ahd_softc *ahd);
void ahd_free(struct ahd_softc *ahd); void ahd_free(struct ahd_softc *ahd);
int ahd_reset(struct ahd_softc *ahd); int ahd_reset(struct ahd_softc *ahd, int reinit);
void ahd_shutdown(void *arg); void ahd_shutdown(void *arg);
int ahd_write_flexport(struct ahd_softc *ahd, int ahd_write_flexport(struct ahd_softc *ahd,
u_int addr, u_int value); u_int addr, u_int value);
int ahd_read_flexport(struct ahd_softc *ahd, u_int addr, int ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
uint8_t *value); uint8_t *value);
int ahd_wait_flexport(struct ahd_softc *ahd); int ahd_wait_flexport(struct ahd_softc *ahd);
/*************************** Interrupt Services *******************************/ /*************************** Interrupt Services *******************************/
void ahd_pci_intr(struct ahd_softc *ahd); void ahd_pci_intr(struct ahd_softc *ahd);
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* *
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $"
/* /*
* This file is processed by the aic7xxx_asm utility for use in assembling * This file is processed by the aic7xxx_asm utility for use in assembling
...@@ -1377,7 +1377,10 @@ register LUNLEN { ...@@ -1377,7 +1377,10 @@ register LUNLEN {
address 0x030 address 0x030
access_mode RW access_mode RW
modes M_CFG modes M_CFG
mask ILUNLEN 0x0F
mask TLUNLEN 0xF0
} }
const LUNLEN_SINGLE_LEVEL_LUN 0xF
/* /*
* CDB Limit * CDB Limit
...@@ -3797,32 +3800,8 @@ scb { ...@@ -3797,32 +3800,8 @@ scb {
size 4 size 4
alias SCB_NEXT_COMPLETE alias SCB_NEXT_COMPLETE
} }
SCB_DATAPTR { SCB_TAG {
size 8 alias SCB_FIFO_USE_COUNT
}
SCB_DATACNT {
/*
* The last byte is really the high address bits for
* the data address.
*/
size 4
field SG_LAST_SEG 0x80 /* In the fourth byte */
field SG_HIGH_ADDR_BITS 0x7F /* In the fourth byte */
}
SCB_SGPTR {
size 4
field SG_STATUS_VALID 0x04 /* In the first byte */
field SG_FULL_RESID 0x02 /* In the first byte */
field SG_LIST_NULL 0x01 /* In the first byte */
}
SCB_BUSADDR {
size 4
}
SCB_NEXT {
alias SCB_NEXT_SCB_BUSADDR
size 2
}
SCB_NEXT2 {
size 2 size 2
} }
SCB_CONTROL { SCB_CONTROL {
...@@ -3859,8 +3838,32 @@ scb { ...@@ -3859,8 +3838,32 @@ scb {
SCB_TASK_MANAGEMENT { SCB_TASK_MANAGEMENT {
size 1 size 1
} }
SCB_TAG { SCB_DATAPTR {
alias SCB_FIFO_USE_COUNT size 8
}
SCB_DATACNT {
/*
* The last byte is really the high address bits for
* the data address.
*/
size 4
field SG_LAST_SEG 0x80 /* In the fourth byte */
field SG_HIGH_ADDR_BITS 0x7F /* In the fourth byte */
}
SCB_SGPTR {
size 4
field SG_STATUS_VALID 0x04 /* In the first byte */
field SG_FULL_RESID 0x02 /* In the first byte */
field SG_LIST_NULL 0x01 /* In the first byte */
}
SCB_BUSADDR {
size 4
}
SCB_NEXT {
alias SCB_NEXT_SCB_BUSADDR
size 2
}
SCB_NEXT2 {
size 2 size 2
} }
SCB_SPARE { SCB_SPARE {
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#99 $"
PATCH_ARG_LIST = "struct ahd_softc *ahd" PATCH_ARG_LIST = "struct ahd_softc *ahd"
PREFIX = "ahd_" PREFIX = "ahd_"
...@@ -163,8 +163,8 @@ return: ...@@ -163,8 +163,8 @@ return:
idle_loop_cchan: idle_loop_cchan:
SET_MODE(M_CCHAN, M_CCHAN) SET_MODE(M_CCHAN, M_CCHAN)
test QOFF_CTLSTA, HS_MAILBOX_ACT jz hs_mailbox_empty; test QOFF_CTLSTA, HS_MAILBOX_ACT jz hs_mailbox_empty;
mov LOCAL_HS_MAILBOX, HS_MAILBOX;
or QOFF_CTLSTA, HS_MAILBOX_ACT; or QOFF_CTLSTA, HS_MAILBOX_ACT;
mov LOCAL_HS_MAILBOX, HS_MAILBOX;
hs_mailbox_empty: hs_mailbox_empty:
BEGIN_CRITICAL; BEGIN_CRITICAL;
test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle; test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;
...@@ -276,7 +276,7 @@ fetch_new_scb_done: ...@@ -276,7 +276,7 @@ fetch_new_scb_done:
* knows the correct location to store the SCB. * knows the correct location to store the SCB.
* Set it to zero before processing the SCB. * Set it to zero before processing the SCB.
*/ */
mov SCB_FIFO_USE_COUNT, ALLZEROS; clr SCB_FIFO_USE_COUNT;
/* Update the next SCB address to download. */ /* Update the next SCB address to download. */
bmov NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4; bmov NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4;
mvi SCB_NEXT[1], SCB_LIST_NULL; mvi SCB_NEXT[1], SCB_LIST_NULL;
...@@ -492,12 +492,13 @@ SET_DST_MODE M_SCSI; ...@@ -492,12 +492,13 @@ SET_DST_MODE M_SCSI;
select_in: select_in:
if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
/* /*
* This exposes a window whereby a * Test to ensure that the bus has not
* busfree just after a selection will * already gone free prior to clearing
* be missed, but there is no other safe * any stale busfree status. This avoids
* way to enable busfree detection if * a window whereby a busfree just after
* the busfreerev function is broken. * a selection could be missed.
*/ */
test SCSISIGI, BSYI jz . + 2;
mvi CLRSINT1,CLRBUSFREE; mvi CLRSINT1,CLRBUSFREE;
or SIMODE1, ENBUSFREE; or SIMODE1, ENBUSFREE;
} }
...@@ -582,9 +583,6 @@ found_last_sent_scb: ...@@ -582,9 +583,6 @@ found_last_sent_scb:
bmov CURRSCB, SCBPTR, 2; bmov CURRSCB, SCBPTR, 2;
curscb_ww_done: curscb_ww_done:
} else { } else {
/*
* Untested - Verify with Rev B.
*/
bmov SCBPTR, CURRSCB, 2; bmov SCBPTR, CURRSCB, 2;
} }
...@@ -651,12 +649,13 @@ select_out_non_packetized: ...@@ -651,12 +649,13 @@ select_out_non_packetized:
and SCSISEQ0, ~ENSELO; and SCSISEQ0, ~ENSELO;
if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
/* /*
* This exposes a window whereby a * Test to ensure that the bus has not
* busfree just after a selection will * already gone free prior to clearing
* be missed, but there is no other safe * any stale busfree status. This avoids
* way to enable busfree detection if * a window whereby a busfree just after
* the busfreerev function is broken. * a selection could be missed.
*/ */
test SCSISIGI, BSYI jz . + 2;
mvi CLRSINT1,CLRBUSFREE; mvi CLRSINT1,CLRBUSFREE;
or SIMODE1, ENBUSFREE; or SIMODE1, ENBUSFREE;
} }
...@@ -729,13 +728,38 @@ p_command_embedded: ...@@ -729,13 +728,38 @@ p_command_embedded:
mvi DFCNTRL, SCSIEN; mvi DFCNTRL, SCSIEN;
p_command_xfer: p_command_xfer:
and SEQ_FLAGS, ~NO_CDB_SENT; and SEQ_FLAGS, ~NO_CDB_SENT;
test DFCNTRL, SCSIEN jnz .; if ((ahd->features & AHD_FAST_CDB_DELIVERY) != 0) {
/*
* To speed up CDB delivery in Rev B, all CDB acks
* are "released" to the output sync as soon as the
* command phase starts. There is only one problem
* with this approach. If the target changes phase
* before all data are sent, we have left over acks
* that can go out on the bus in a data phase. Due
* to other chip contraints, this only happens if
* the target goes to data-in, but if the acks go
* out before we can test SDONE, we'll think that
* the transfer has completed successfully. Work
* around this by taking advantage of the 400ns or
* 800ns dead time between command phase and the REQ
* of the new phase. If the transfer has completed
* successfully, SCSIEN should fall *long* before we
* see a phase change. We thus treat any phasemiss
* that occurs before SCSIEN falls as an incomplete
* transfer.
*/
test SSTAT1, PHASEMIS jnz p_command_xfer_failed;
test DFCNTRL, SCSIEN jnz . - 1;
} else {
test DFCNTRL, SCSIEN jnz .;
}
/* /*
* DMA Channel automatically disabled. * DMA Channel automatically disabled.
* Don't allow a data phase if the command * Don't allow a data phase if the command
* was not fully transferred. * was not fully transferred.
*/ */
test SSTAT2, SDONE jnz ITloop; test SSTAT2, SDONE jnz ITloop;
p_command_xfer_failed:
or SEQ_FLAGS, NO_CDB_SENT; or SEQ_FLAGS, NO_CDB_SENT;
jmp ITloop; jmp ITloop;
...@@ -1959,12 +1983,14 @@ SET_DST_MODE M_SCSI; ...@@ -1959,12 +1983,14 @@ SET_DST_MODE M_SCSI;
test SSTAT0, SELDO jnz return; test SSTAT0, SELDO jnz return;
mvi SCBPTR[1], SCB_LIST_NULL; mvi SCBPTR[1], SCB_LIST_NULL;
unexpected_nonpkt_phase: unexpected_nonpkt_phase:
test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz . + 3; test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))
jnz unexpected_nonpkt_mode_cleared;
SET_SRC_MODE M_DFF0; SET_SRC_MODE M_DFF0;
SET_DST_MODE M_DFF0; SET_DST_MODE M_DFF0;
or LONGJMP_ADDR[1], INVALID_ADDR; or LONGJMP_ADDR[1], INVALID_ADDR;
dec SCB_FIFO_USE_COUNT; dec SCB_FIFO_USE_COUNT;
mvi DFFSXFRCTL, CLRCHN; mvi DFFSXFRCTL, CLRCHN;
unexpected_nonpkt_mode_cleared:
mvi CLRSINT2, CLRNONPACKREQ; mvi CLRSINT2, CLRNONPACKREQ;
test SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase; test SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase;
SET_SEQINTCODE(ENTERING_NONPACK) SET_SEQINTCODE(ENTERING_NONPACK)
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#194 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#202 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -224,6 +224,11 @@ static u_int ahd_resolve_seqaddr(struct ahd_softc *ahd, ...@@ -224,6 +224,11 @@ static u_int ahd_resolve_seqaddr(struct ahd_softc *ahd,
static void ahd_download_instr(struct ahd_softc *ahd, static void ahd_download_instr(struct ahd_softc *ahd,
u_int instrptr, uint8_t *dconsts); u_int instrptr, uint8_t *dconsts);
static int ahd_probe_stack_size(struct ahd_softc *ahd); static int ahd_probe_stack_size(struct ahd_softc *ahd);
static int ahd_scb_active_in_fifo(struct ahd_softc *ahd,
struct scb *scb);
static void ahd_run_data_fifo(struct ahd_softc *ahd,
struct scb *scb);
#ifdef AHD_TARGET_MODE #ifdef AHD_TARGET_MODE
static void ahd_queue_lstate_event(struct ahd_softc *ahd, static void ahd_queue_lstate_event(struct ahd_softc *ahd,
struct ahd_tmode_lstate *lstate, struct ahd_tmode_lstate *lstate,
...@@ -328,10 +333,7 @@ ahd_restart(struct ahd_softc *ahd) ...@@ -328,10 +333,7 @@ ahd_restart(struct ahd_softc *ahd)
/* Always allow reselection */ /* Always allow reselection */
ahd_outb(ahd, SCSISEQ1, ahd_outb(ahd, SCSISEQ1,
ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP)); ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
/* Ensure that no DMA operations are in progress */
ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
ahd_outb(ahd, SCBHCNT, 0);
ahd_outb(ahd, CCSCBCTL, CCSCBRESET);
ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
ahd_unpause(ahd); ahd_unpause(ahd);
} }
...@@ -371,14 +373,92 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) ...@@ -371,14 +373,92 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
u_int next_scbid; u_int next_scbid;
saved_modes = ahd_save_modes(ahd); saved_modes = ahd_save_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
/*
* Complete any SCBs that just finished being
* DMA'ed into the qoutfifo.
*/
ahd_run_qoutfifo(ahd);
/*
* Flush the good status FIFO for compelted packetized commands.
*/
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
saved_scbptr = ahd_get_scbptr(ahd); saved_scbptr = ahd_get_scbptr(ahd);
while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) {
u_int fifo_mode;
u_int i;
scbid = (ahd_inb(ahd, GSFIFO+1) << 8)
| ahd_inb(ahd, GSFIFO);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
printf("%s: Warning - GSFIFO SCB %d invalid\n",
ahd_name(ahd), scbid);
continue;
}
/*
* Determine if this transaction is still active in
* any FIFO. If it is, we must flush that FIFO to
* the host before completing the command.
*/
fifo_mode = 0;
for (i = 0; i < 2; i++) {
/* Toggle to the other mode. */
fifo_mode ^= 1;
ahd_set_modes(ahd, fifo_mode, fifo_mode);
if (ahd_scb_active_in_fifo(ahd, scb) == 0)
continue;
ahd_run_data_fifo(ahd, scb);
/*
* Clearing this transaction in this FIFO may
* cause a CFG4DATA for this same transaction
* to assert in the other FIFO. Make sure we
* loop one more time and check the other FIFO.
*/
i = 0;
}
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
ahd_set_scbptr(ahd, scbid);
if ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_LIST_NULL) == 0
&& ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_FULL_RESID) != 0
|| (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR)
& SG_LIST_NULL) != 0)) {
u_int comp_head;
/*
* The transfer completed with a residual.
* Place this SCB on the complete DMA list
* so that we Update our in-core copy of the
* SCB before completing the command.
*/
ahd_outb(ahd, SCB_SCSI_STATUS, 0);
ahd_outb(ahd, SCB_SGPTR,
ahd_inb_scbram(ahd, SCB_SGPTR)
| SG_STATUS_VALID);
ahd_outw(ahd, SCB_TAG, SCB_GET_TAG(scb));
comp_head = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
ahd_outw(ahd, SCB_NEXT_COMPLETE, comp_head);
if (SCBID_IS_NULL(comp_head))
ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD,
SCB_GET_TAG(scb));
} else
ahd_complete_scb(ahd, scb);
}
ahd_set_scbptr(ahd, saved_scbptr);
/*
* Setup for command channel portion of flush.
*/
ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
/* /*
* Wait for any inprogress DMA to complete and clear DMA state * Wait for any inprogress DMA to complete and clear DMA state
* if this if for an SCB in the qinfifo. * if this if for an SCB in the qinfifo.
*/ */
while ((ccscbctl = ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0) { while (((ccscbctl = ahd_inb(ahd, CCSCBCTL)) & (CCARREN|CCSCBEN)) != 0) {
if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) { if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) {
if ((ccscbctl & ARRDONE) != 0) if ((ccscbctl & ARRDONE) != 0)
...@@ -390,12 +470,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) ...@@ -390,12 +470,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
if ((ccscbctl & CCSCBDIR) != 0) if ((ccscbctl & CCSCBDIR) != 0)
ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN)); ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN));
/* saved_scbptr = ahd_get_scbptr(ahd);
* Complete any SCBs that just finished being
* DMA'ed into the qoutfifo.
*/
ahd_run_qoutfifo(ahd);
/* /*
* Manually update/complete any completed SCBs that are waiting to be * Manually update/complete any completed SCBs that are waiting to be
* DMA'ed back up to the host. * DMA'ed back up to the host.
...@@ -438,29 +513,276 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) ...@@ -438,29 +513,276 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
scbid = next_scbid; scbid = next_scbid;
} }
ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
/*
* Restore state.
*/
ahd_set_scbptr(ahd, saved_scbptr); ahd_set_scbptr(ahd, saved_scbptr);
ahd_restore_modes(ahd, saved_modes);
ahd->flags |= AHD_UPDATE_PEND_CMDS;
}
/*
* Determine if an SCB for a packetized transaction
* is active in a FIFO.
*/
static int
ahd_scb_active_in_fifo(struct ahd_softc *ahd, struct scb *scb)
{
/* /*
* Flush the good status FIFO for compelted packetized commands. * The FIFO is only active for our transaction if
* the SCBPTR matches the SCB's ID and the firmware
* has installed a handler for the FIFO or we have
* a pending SAVEPTRS or CFG4DATA interrupt.
*/ */
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); if (ahd_get_scbptr(ahd) != SCB_GET_TAG(scb)
while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) { || ((ahd_inb(ahd, LONGJMP_ADDR+1) & INVALID_ADDR) != 0
scbid = (ahd_inb(ahd, GSFIFO+1) << 8) && (ahd_inb(ahd, SEQINTSRC) & (CFG4DATA|SAVEPTRS)) == 0))
| ahd_inb(ahd, GSFIFO); return (0);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) { return (1);
printf("%s: Warning - GSFIFO SCB %d invalid\n", }
ahd_name(ahd), scbid);
continue; /*
* Run a data fifo to completion for a transaction we know
* has completed across the SCSI bus (good status has been
* received). We are already set to the correct FIFO mode
* on entry to this routine.
*
* This function attempts to operate exactly as the firmware
* would when running this FIFO. Care must be taken to update
* this routine any time the firmware's FIFO algorithm is
* changed.
*/
static void
ahd_run_data_fifo(struct ahd_softc *ahd, struct scb *scb)
{
u_int seqintsrc;
while (1) {
seqintsrc = ahd_inb(ahd, SEQINTSRC);
if ((seqintsrc & CFG4DATA) != 0) {
uint32_t datacnt;
uint32_t sgptr;
/*
* Clear full residual flag.
*/
sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID;
ahd_outb(ahd, SCB_SGPTR, sgptr);
/*
* Load datacnt and address.
*/
datacnt = ahd_inl_scbram(ahd, SCB_DATACNT);
if ((datacnt & AHD_DMA_LAST_SEG) != 0) {
sgptr |= LAST_SEG;
ahd_outb(ahd, SG_STATE, 0);
} else
ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR));
ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK);
ahd_outb(ahd, SG_CACHE_PRE, sgptr);
ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
/*
* Initialize Residual Fields.
*/
ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24);
ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK);
/*
* Mark the SCB as having a FIFO in use.
*/
ahd_outb(ahd, SCB_FIFO_USE_COUNT,
ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1);
/*
* Install a "fake" handler for this FIFO.
*/
ahd_outw(ahd, LONGJMP_ADDR, 0);
/*
* Notify the hardware that we have satisfied
* this sequencer interrupt.
*/
ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA);
} else if ((seqintsrc & SAVEPTRS) != 0) {
uint32_t sgptr;
uint32_t resid;
if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) {
/*
* Snapshot Save Pointers. Clear
* the snapshot and continue.
*/
ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
continue;
}
/*
* Disable S/G fetch so the DMA engine
* is available to future users.
*/
if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
ahd_outb(ahd, CCSGCTL, 0);
ahd_outb(ahd, SG_STATE, 0);
/*
* Flush the data FIFO. Strickly only
* necessary for Rev A parts.
*/
ahd_outb(ahd, DFCNTRL,
ahd_inb(ahd, DFCNTRL) | FIFOFLUSH);
/*
* Calculate residual.
*/
sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
resid = ahd_inl(ahd, SHCNT);
resid |=
ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24;
ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid);
if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) {
/*
* Must back up to the correct S/G element.
* Typically this just means resetting our
* low byte to the offset in the SG_CACHE,
* but if we wrapped, we have to correct
* the other bytes of the sgptr too.
*/
if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0
&& (sgptr & 0x80) == 0)
sgptr -= 0x100;
sgptr &= ~0xFF;
sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW)
& SG_ADDR_MASK;
ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0);
} else if ((resid & AHD_SG_LEN_MASK) == 0) {
ahd_outb(ahd, SCB_RESIDUAL_SGPTR,
sgptr | SG_LIST_NULL);
}
/*
* Save Pointers.
*/
ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR));
ahd_outl(ahd, SCB_DATACNT, resid);
ahd_outl(ahd, SCB_SGPTR, sgptr);
ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS);
ahd_outb(ahd, SEQIMODE,
ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS);
/*
* If the data is to the SCSI bus, we are
* done, otherwise wait for FIFOEMP.
*/
if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0)
break;
} else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) {
uint32_t sgptr;
uint64_t data_addr;
uint32_t data_len;
u_int dfcntrl;
/*
* Disable S/G fetch so the DMA engine
* is available to future users.
*/
if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) {
ahd_outb(ahd, CCSGCTL, 0);
ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
}
/*
* Wait for the DMA engine to notice that the
* host transfer is enabled and that there is
* space in the S/G FIFO for new segments before
* loading more segments.
*/
if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) == 0)
continue;
if ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) == 0)
continue;
/*
* Determine the offset of the next S/G
* element to load.
*/
sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
sgptr &= SG_PTR_MASK;
if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
struct ahd_dma64_seg *sg;
sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
data_addr = sg->addr;
data_len = sg->len;
sgptr += sizeof(*sg);
} else {
struct ahd_dma_seg *sg;
sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
data_addr = sg->len & AHD_SG_HIGH_ADDR_MASK;
data_addr <<= 8;
data_addr |= sg->addr;
data_len = sg->len;
sgptr += sizeof(*sg);
}
/*
* Update residual information.
*/
ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, data_len >> 24);
ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
/*
* Load the S/G.
*/
if (data_len & AHD_DMA_LAST_SEG) {
sgptr |= LAST_SEG;
ahd_outb(ahd, SG_STATE, 0);
}
ahd_outq(ahd, HADDR, data_addr);
ahd_outl(ahd, HCNT, data_len & AHD_SG_LEN_MASK);
ahd_outb(ahd, SG_CACHE_PRE, sgptr & 0xFF);
/*
* Advertise the segment to the hardware.
*/
dfcntrl = ahd_inb(ahd, DFCNTRL)|PRELOADEN|HDMAEN;
if ((ahd->features & AHD_NEW_DFCNTRL_OPTS)!=0) {
/*
* Use SCSIENWRDIS so that SCSIEN
* is never modified by this
* operation.
*/
dfcntrl |= SCSIENWRDIS;
}
ahd_outb(ahd, DFCNTRL, dfcntrl);
} else if ((ahd_inb(ahd, SG_CACHE_SHADOW)
& LAST_SEG_DONE) != 0) {
/*
* Transfer completed to the end of SG list
* and has flushed to the host.
*/
ahd_outb(ahd, SCB_SGPTR,
ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL);
break;
} else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) {
break;
} }
ahd_complete_scb(ahd, scb); ahd_delay(200);
} }
/* /*
* Restore state. * Clear any handler for this FIFO, decrement
* the FIFO use count for the SCB, and release
* the FIFO.
*/ */
ahd_restore_modes(ahd, saved_modes); ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
ahd->flags |= AHD_UPDATE_PEND_CMDS; ahd_outb(ahd, SCB_FIFO_USE_COUNT,
ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1);
ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
} }
void void
...@@ -589,7 +911,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ...@@ -589,7 +911,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
/* /*
* Somehow need to know if this * Somehow need to know if this
* is from a selection or reselection. * is from a selection or reselection.
* From that, we can termine target * From that, we can determine target
* ID so we at least have an I_T nexus. * ID so we at least have an I_T nexus.
*/ */
} else { } else {
...@@ -796,7 +1118,8 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ...@@ -796,7 +1118,8 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
* attempt to complete this bogus SCB. * attempt to complete this bogus SCB.
*/ */
ahd_outb(ahd, SCB_CONTROL, ahd_outb(ahd, SCB_CONTROL,
ahd_inb(ahd, SCB_CONTROL) & ~STATUS_RCVD); ahd_inb_scbram(ahd, SCB_CONTROL)
& ~STATUS_RCVD);
} }
break; break;
} }
...@@ -1029,7 +1352,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ...@@ -1029,7 +1352,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
ROLE_INITIATOR, /*status*/0, ROLE_INITIATOR, /*status*/0,
SEARCH_REMOVE); SEARCH_REMOVE);
ahd_outb(ahd, SCB_CONTROL, ahd_outb(ahd, SCB_CONTROL,
ahd_inb(ahd, SCB_CONTROL) & ~MK_MESSAGE); ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
break; break;
} }
case TASKMGMT_FUNC_COMPLETE: case TASKMGMT_FUNC_COMPLETE:
...@@ -1880,21 +2203,32 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) ...@@ -1880,21 +2203,32 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
tinfo->goal.ppr_options = 0; tinfo->goal.ppr_options = 0;
ahd_qinfifo_requeue_tail(ahd, scb); ahd_qinfifo_requeue_tail(ahd, scb);
printerror = 0; printerror = 0;
} else if ((ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
|| ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE))
&& ppr_busfree == 0) { && ppr_busfree == 0) {
/* /*
* Negotiation Rejected. Go-async and * Negotiation Rejected. Go-narrow and
* retry command. * retry command.
*/ */
#ifdef AHD_DEBUG #ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
printf("Negotiation rejected busfree.\n"); printf("WDTR negotiation rejected busfree.\n");
#endif #endif
ahd_set_width(ahd, &devinfo, ahd_set_width(ahd, &devinfo,
MSG_EXT_WDTR_BUS_8_BIT, MSG_EXT_WDTR_BUS_8_BIT,
AHD_TRANS_CUR|AHD_TRANS_GOAL, AHD_TRANS_CUR|AHD_TRANS_GOAL,
/*paused*/TRUE); /*paused*/TRUE);
ahd_qinfifo_requeue_tail(ahd, scb);
printerror = 0;
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
&& ppr_busfree == 0) {
/*
* Negotiation Rejected. Go-async and
* retry command.
*/
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
printf("SDTR negotiation rejected busfree.\n");
#endif
ahd_set_syncrate(ahd, &devinfo, ahd_set_syncrate(ahd, &devinfo,
/*period*/0, /*offset*/0, /*period*/0, /*offset*/0,
/*ppr_options*/0, /*ppr_options*/0,
...@@ -2187,8 +2521,14 @@ ahd_clear_critical_section(struct ahd_softc *ahd) ...@@ -2187,8 +2521,14 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
ahd_outb(ahd, LQOMODE0, 0); ahd_outb(ahd, LQOMODE0, 0);
ahd_outb(ahd, LQOMODE1, 0); ahd_outb(ahd, LQOMODE1, 0);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
simode1 = ahd_inb(ahd, SIMODE1); simode1 = ahd_inb(ahd, SIMODE1);
ahd_outb(ahd, SIMODE1, ENBUSFREE); /*
* We don't clear ENBUSFREE. Unfortunately
* we cannot re-enable busfree detection within
* the current connection, so we must leave it
* on while single stepping.
*/
ahd_outb(ahd, SIMODE1, simode1 & ENBUSFREE);
ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP); ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP);
stepping = TRUE; stepping = TRUE;
} }
...@@ -2196,9 +2536,8 @@ ahd_clear_critical_section(struct ahd_softc *ahd) ...@@ -2196,9 +2536,8 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
ahd_outb(ahd, CLRINT, CLRSCSIINT); ahd_outb(ahd, CLRINT, CLRSCSIINT);
ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
ahd_outb(ahd, HCNTRL, ahd->unpause); ahd_outb(ahd, HCNTRL, ahd->unpause);
do { while (!ahd_is_paused(ahd))
ahd_delay(200); ahd_delay(200);
} while (!ahd_is_paused(ahd));
ahd_update_modes(ahd); ahd_update_modes(ahd);
} }
if (stepping) { if (stepping) {
...@@ -2316,7 +2655,7 @@ ahd_dump_sglist(struct scb *scb) ...@@ -2316,7 +2655,7 @@ ahd_dump_sglist(struct scb *scb)
len = ahd_le32toh(sg_list[i].len); len = ahd_le32toh(sg_list[i].len);
printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
i, i,
(len >> 24) & SG_HIGH_ADDR_BITS, (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
ahd_le32toh(sg_list[i].addr), ahd_le32toh(sg_list[i].addr),
len & AHD_SG_LEN_MASK, len & AHD_SG_LEN_MASK,
len & AHD_DMA_LAST_SEG ? " Last" : ""); len & AHD_DMA_LAST_SEG ? " Last" : "");
...@@ -2904,7 +3243,7 @@ ahd_update_pending_scbs(struct ahd_softc *ahd) ...@@ -2904,7 +3243,7 @@ ahd_update_pending_scbs(struct ahd_softc *ahd)
{ {
struct scb *pending_scb; struct scb *pending_scb;
int pending_scb_count; int pending_scb_count;
int i; u_int scb_tag;
int paused; int paused;
u_int saved_scbptr; u_int saved_scbptr;
ahd_mode_state saved_modes; ahd_mode_state saved_modes;
...@@ -2962,17 +3301,14 @@ ahd_update_pending_scbs(struct ahd_softc *ahd) ...@@ -2962,17 +3301,14 @@ ahd_update_pending_scbs(struct ahd_softc *ahd)
ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
saved_scbptr = ahd_get_scbptr(ahd); saved_scbptr = ahd_get_scbptr(ahd);
/* Ensure that the hscbs down on the card match the new information */ /* Ensure that the hscbs down on the card match the new information */
for (i = 0; i < ahd->scb_data.maxhscbs; i++) { for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) {
struct hardware_scb *pending_hscb; struct hardware_scb *pending_hscb;
u_int control; u_int control;
u_int scb_tag;
ahd_set_scbptr(ahd, i);
scb_tag = i;
pending_scb = ahd_lookup_scb(ahd, scb_tag); pending_scb = ahd_lookup_scb(ahd, scb_tag);
if (pending_scb == NULL) if (pending_scb == NULL)
continue; continue;
ahd_set_scbptr(ahd, scb_tag);
pending_hscb = pending_scb->hscb; pending_hscb = pending_scb->hscb;
control = ahd_inb_scbram(ahd, SCB_CONTROL); control = ahd_inb_scbram(ahd, SCB_CONTROL);
control &= ~MK_MESSAGE; control &= ~MK_MESSAGE;
...@@ -3187,7 +3523,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, ...@@ -3187,7 +3523,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
devinfo->target_mask); devinfo->target_mask);
panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x " panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x "
"SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control, "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control,
ahd_inb(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT), ahd_inb_scbram(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT),
scb->flags); scb->flags);
} }
...@@ -3232,6 +3568,7 @@ ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) ...@@ -3232,6 +3568,7 @@ ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
* may change. * may change.
*/ */
period = tinfo->goal.period; period = tinfo->goal.period;
offset = tinfo->goal.offset;
ppr_options = tinfo->goal.ppr_options; ppr_options = tinfo->goal.ppr_options;
/* Target initiated PPR is not allowed in the SCSI spec */ /* Target initiated PPR is not allowed in the SCSI spec */
if (devinfo->role == ROLE_TARGET) if (devinfo->role == ROLE_TARGET)
...@@ -3239,7 +3576,7 @@ ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) ...@@ -3239,7 +3576,7 @@ ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
ahd_devlimited_syncrate(ahd, tinfo, &period, ahd_devlimited_syncrate(ahd, tinfo, &period,
&ppr_options, devinfo->role); &ppr_options, devinfo->role);
dowide = tinfo->curr.width != tinfo->goal.width; dowide = tinfo->curr.width != tinfo->goal.width;
dosync = tinfo->curr.period != period; dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
/* /*
* Only use PPR if we have options that need it, even if the device * Only use PPR if we have options that need it, even if the device
* claims to support it. There might be an expander in the way * claims to support it. There might be an expander in the way
...@@ -3249,7 +3586,7 @@ ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) ...@@ -3249,7 +3586,7 @@ ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
if (!dowide && !dosync && !doppr) { if (!dowide && !dosync && !doppr) {
dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT; dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
dosync = tinfo->goal.period != 0; dosync = tinfo->goal.offset != 0;
} }
if (!dowide && !dosync && !doppr) { if (!dowide && !dosync && !doppr) {
...@@ -3725,8 +4062,13 @@ ahd_handle_message_phase(struct ahd_softc *ahd) ...@@ -3725,8 +4062,13 @@ ahd_handle_message_phase(struct ahd_softc *ahd)
if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) { if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) {
printf("%s: Returning to Idle Loop\n", printf("%s: Returning to Idle Loop\n",
ahd_name(ahd)); ahd_name(ahd));
ahd_outb(ahd, LASTPHASE, P_BUSFREE);
ahd_clear_msg_state(ahd); ahd_clear_msg_state(ahd);
/*
* Perform the equivalent of a clear_target_state.
*/
ahd_outb(ahd, LASTPHASE, P_BUSFREE);
ahd_outb(ahd, SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT);
ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
} else { } else {
ahd_clear_msg_state(ahd); ahd_clear_msg_state(ahd);
...@@ -3983,22 +4325,30 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) ...@@ -3983,22 +4325,30 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
response = TRUE; response = TRUE;
sending_reply = TRUE; sending_reply = TRUE;
} }
/*
* After a wide message, we are async, but
* some devices don't seem to honor this portion
* of the spec. Force a renegotiation of the
* sync component of our transfer agreement even
* if our goal is async. By updating our width
* after forcing the negotiation, we avoid
* renegotiating for width.
*/
ahd_update_neg_request(ahd, devinfo, tstate,
tinfo, AHD_NEG_ALWAYS);
ahd_set_width(ahd, devinfo, bus_width, ahd_set_width(ahd, devinfo, bus_width,
AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
/*paused*/TRUE); /*paused*/TRUE);
/* After a wide message, we are async */
ahd_set_syncrate(ahd, devinfo, /*period*/0,
/*offset*/0, /*ppr_options*/0,
AHD_TRANS_ACTIVE, /*paused*/TRUE);
if (sending_reply == FALSE && reject == FALSE) { if (sending_reply == FALSE && reject == FALSE) {
if (tinfo->goal.offset) { /*
ahd->msgout_index = 0; * We will always have an SDTR to send.
ahd->msgout_len = 0; */
ahd_build_transfer_msg(ahd, devinfo); ahd->msgout_index = 0;
ahd->msgout_index = 0; ahd->msgout_len = 0;
response = TRUE; ahd_build_transfer_msg(ahd, devinfo);
} ahd->msgout_index = 0;
response = TRUE;
} }
done = MSGLOOP_MSGCOMPLETE; done = MSGLOOP_MSGCOMPLETE;
break; break;
...@@ -4401,7 +4751,8 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) ...@@ -4401,7 +4751,8 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR); sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
if ((sgptr & SG_LIST_NULL) != 0 if ((sgptr & SG_LIST_NULL) != 0
&& (ahd_inb(ahd, SCB_TASK_ATTRIBUTE) & SCB_XFERLEN_ODD) != 0) { && (ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
& SCB_XFERLEN_ODD) != 0) {
/* /*
* If the residual occurred on the last * If the residual occurred on the last
* transfer and the transfer request was * transfer and the transfer request was
...@@ -4502,7 +4853,8 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) ...@@ -4502,7 +4853,8 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
* correct for subsequent data transfers. * correct for subsequent data transfers.
*/ */
ahd_outb(ahd, SCB_TASK_ATTRIBUTE, ahd_outb(ahd, SCB_TASK_ATTRIBUTE,
ahd_inb(ahd, SCB_TASK_ATTRIBUTE) ^ SCB_XFERLEN_ODD); ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
^ SCB_XFERLEN_ODD);
ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr); ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt); ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
...@@ -4542,9 +4894,8 @@ ahd_reinitialize_dataptrs(struct ahd_softc *ahd) ...@@ -4542,9 +4894,8 @@ ahd_reinitialize_dataptrs(struct ahd_softc *ahd)
*/ */
ahd_outb(ahd, DFFSXFRCTL, CLRCHN); ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
wait = 1000; wait = 1000;
do { while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE))
ahd_delay(100); ahd_delay(100);
} while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE));
if (wait == 0) { if (wait == 0) {
ahd_print_path(ahd, scb); ahd_print_path(ahd, scb);
printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n"); printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n");
...@@ -5000,15 +5351,20 @@ ahd_shutdown(void *arg) ...@@ -5000,15 +5351,20 @@ ahd_shutdown(void *arg)
ahd_timer_stop(&ahd->stat_timer); ahd_timer_stop(&ahd->stat_timer);
/* This will reset most registers to 0, but not all */ /* This will reset most registers to 0, but not all */
ahd_reset(ahd); ahd_reset(ahd, /*reinit*/FALSE);
} }
/* /*
* Reset the controller and record some information about it * Reset the controller and record some information about it
* that is only available just after a reset. * that is only available just after a reset. If "reinit" is
* non-zero, this reset occured after initial configuration
* and the caller requests that the chip be fully reinitialized
* to a runable state. Chip interrupts are *not* enabled after
* a reinitialization. The caller must enable interrupts via
* ahd_intr_enable().
*/ */
int int
ahd_reset(struct ahd_softc *ahd) ahd_reset(struct ahd_softc *ahd, int reinit)
{ {
u_int sxfrctl1; u_int sxfrctl1;
int wait; int wait;
...@@ -5101,7 +5457,7 @@ ahd_reset(struct ahd_softc *ahd) ...@@ -5101,7 +5457,7 @@ ahd_reset(struct ahd_softc *ahd)
* If a recovery action has forced a chip reset, * If a recovery action has forced a chip reset,
* re-initialize the chip to our liking. * re-initialize the chip to our liking.
*/ */
if (ahd->init_level > 0) if (reinit != 0)
ahd_chip_init(ahd); ahd_chip_init(ahd);
return (0); return (0);
...@@ -5382,6 +5738,7 @@ ahd_setup_iocell_workaround(struct ahd_softc *ahd) ...@@ -5382,6 +5738,7 @@ ahd_setup_iocell_workaround(struct ahd_softc *ahd)
printf("%s: Setting up iocell workaround\n", ahd_name(ahd)); printf("%s: Setting up iocell workaround\n", ahd_name(ahd));
#endif #endif
ahd_restore_modes(ahd, saved_modes); ahd_restore_modes(ahd, saved_modes);
ahd->flags &= ~AHD_HAD_FIRST_SEL;
} }
static void static void
...@@ -5390,6 +5747,8 @@ ahd_iocell_first_selection(struct ahd_softc *ahd) ...@@ -5390,6 +5747,8 @@ ahd_iocell_first_selection(struct ahd_softc *ahd)
ahd_mode_state saved_modes; ahd_mode_state saved_modes;
u_int sblkctl; u_int sblkctl;
if ((ahd->flags & AHD_HAD_FIRST_SEL) != 0)
return;
saved_modes = ahd_save_modes(ahd); saved_modes = ahd_save_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
sblkctl = ahd_inb(ahd, SBLKCTL); sblkctl = ahd_inb(ahd, SBLKCTL);
...@@ -5409,6 +5768,7 @@ ahd_iocell_first_selection(struct ahd_softc *ahd) ...@@ -5409,6 +5768,7 @@ ahd_iocell_first_selection(struct ahd_softc *ahd)
ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI)); ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI));
ahd_outb(ahd, CLRINT, CLRSCSIINT); ahd_outb(ahd, CLRINT, CLRSCSIINT);
ahd_restore_modes(ahd, saved_modes); ahd_restore_modes(ahd, saved_modes);
ahd->flags |= AHD_HAD_FIRST_SEL;
} }
/*************************** SCB Management ***********************************/ /*************************** SCB Management ***********************************/
...@@ -6174,7 +6534,7 @@ ahd_chip_init(struct ahd_softc *ahd) ...@@ -6174,7 +6534,7 @@ ahd_chip_init(struct ahd_softc *ahd)
ahd_outb(ahd, LUNLEN, ahd_outb(ahd, LUNLEN,
sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1); sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1);
} else { } else {
ahd_outb(ahd, LUNLEN, sizeof(ahd->next_queued_hscb->lun) - 1); ahd_outb(ahd, LUNLEN, LUNLEN_SINGLE_LEVEL_LUN);
} }
ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1); ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1);
ahd_outb(ahd, MAXCMD, 0xFF); ahd_outb(ahd, MAXCMD, 0xFF);
...@@ -6215,6 +6575,7 @@ ahd_chip_init(struct ahd_softc *ahd) ...@@ -6215,6 +6575,7 @@ ahd_chip_init(struct ahd_softc *ahd)
ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR); ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR);
ahd_outb(ahd, CLRINT, CLRSCSIINT); ahd_outb(ahd, CLRINT, CLRSCSIINT);
#if NEEDS_MORE_TESTING
/* /*
* Always enable abort on incoming L_Qs if this feature is * Always enable abort on incoming L_Qs if this feature is
* supported. We use this to catch invalid SCB references. * supported. We use this to catch invalid SCB references.
...@@ -6222,6 +6583,7 @@ ahd_chip_init(struct ahd_softc *ahd) ...@@ -6222,6 +6583,7 @@ ahd_chip_init(struct ahd_softc *ahd)
if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0) if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0)
ahd_outb(ahd, LQCTL1, ABORTPENDING); ahd_outb(ahd, LQCTL1, ABORTPENDING);
else else
#endif
ahd_outb(ahd, LQCTL1, 0); ahd_outb(ahd, LQCTL1, 0);
/* All of our queues are empty */ /* All of our queues are empty */
...@@ -6703,141 +7065,24 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) ...@@ -6703,141 +7065,24 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd)
int int
ahd_suspend(struct ahd_softc *ahd) ahd_suspend(struct ahd_softc *ahd)
{ {
#if 0
uint8_t *ptr;
int i;
ahd_pause_and_flushwork(ahd); ahd_pause_and_flushwork(ahd);
if (LIST_FIRST(&ahd->pending_scbs) != NULL) if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
return (EBUSY); ahd_unpause(ahd);
#if AHD_TARGET_MODE
/*
* XXX What about ATIOs that have not yet been serviced?
* Perhaps we should just refuse to be suspended if we
* are acting in a target role.
*/
if (ahd->pending_device != NULL)
return (EBUSY); return (EBUSY);
#endif
/* Save volatile registers */
ahd->suspend_state.channel[0].scsiseq = ahd_inb(ahd, SCSISEQ0);
ahd->suspend_state.channel[0].sxfrctl0 = ahd_inb(ahd, SXFRCTL0);
ahd->suspend_state.channel[0].sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
ahd->suspend_state.channel[0].simode0 = ahd_inb(ahd, SIMODE0);
ahd->suspend_state.channel[0].simode1 = ahd_inb(ahd, SIMODE1);
ahd->suspend_state.channel[0].seltimer = ahd_inb(ahd, SELTIMER);
ahd->suspend_state.channel[0].seqctl = ahd_inb(ahd, SEQCTL0);
ahd->suspend_state.dscommand0 = ahd_inb(ahd, DSCOMMAND0);
ahd->suspend_state.dspcistatus = ahd_inb(ahd, DSPCISTATUS);
if ((ahd->features & AHD_DT) != 0) {
u_int sfunct;
sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE;
ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE);
ahd->suspend_state.optionmode = ahd_inb(ahd, OPTIONMODE);
ahd_outb(ahd, SFUNCT, sfunct);
ahd->suspend_state.crccontrol1 = ahd_inb(ahd, CRCCONTROL1);
}
if ((ahd->features & AHD_MULTI_FUNC) != 0)
ahd->suspend_state.scbbaddr = ahd_inb(ahd, SCBBADDR);
if ((ahd->features & AHD_ULTRA2) != 0)
ahd->suspend_state.dff_thrsh = ahd_inb(ahd, DFF_THRSH);
ptr = ahd->suspend_state.scratch_ram;
for (i = 0; i < 64; i++)
*ptr++ = ahd_inb(ahd, SRAM_BASE + i);
if ((ahd->features & AHD_MORE_SRAM) != 0) {
for (i = 0; i < 16; i++)
*ptr++ = ahd_inb(ahd, TARG_OFFSET + i);
}
ptr = ahd->suspend_state.btt;
for (i = 0;i < AHD_NUM_TARGETS; i++) {
int j;
for (j = 0;j < AHD_NUM_LUNS_NONPKT; j++) {
u_int tcl;
tcl = BUILD_TCL_RAW(i, 'A', j);
*ptr = ahd_find_busy_tcl(ahd, tcl);
}
} }
ahd_shutdown(ahd); ahd_shutdown(ahd);
#endif
return (0); return (0);
} }
int int
ahd_resume(struct ahd_softc *ahd) ahd_resume(struct ahd_softc *ahd)
{ {
#if 0
uint8_t *ptr;
int i;
ahd_reset(ahd);
ahd_build_free_scb_list(ahd);
/* Restore volatile registers */
ahd_outb(ahd, SCSISEQ0, ahd->suspend_state.channel[0].scsiseq);
ahd_outb(ahd, SXFRCTL0, ahd->suspend_state.channel[0].sxfrctl0);
ahd_outb(ahd, SXFRCTL1, ahd->suspend_state.channel[0].sxfrctl1);
ahd_outb(ahd, SIMODE0, ahd->suspend_state.channel[0].simode0);
ahd_outb(ahd, SIMODE1, ahd->suspend_state.channel[0].simode1);
ahd_outb(ahd, SELTIMER, ahd->suspend_state.channel[0].seltimer);
ahd_outb(ahd, SEQCTL0, ahd->suspend_state.channel[0].seqctl);
if ((ahd->features & AHD_ULTRA2) != 0)
ahd_outb(ahd, SCSIID_ULTRA2, ahd->our_id);
else
ahd_outb(ahd, SCSIID, ahd->our_id);
ahd_outb(ahd, DSCOMMAND0, ahd->suspend_state.dscommand0);
ahd_outb(ahd, DSPCISTATUS, ahd->suspend_state.dspcistatus);
if ((ahd->features & AHD_DT) != 0) {
u_int sfunct;
sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE;
ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE);
ahd_outb(ahd, OPTIONMODE, ahd->suspend_state.optionmode);
ahd_outb(ahd, SFUNCT, sfunct);
ahd_outb(ahd, CRCCONTROL1, ahd->suspend_state.crccontrol1);
}
if ((ahd->features & AHD_MULTI_FUNC) != 0)
ahd_outb(ahd, SCBBADDR, ahd->suspend_state.scbbaddr);
if ((ahd->features & AHD_ULTRA2) != 0)
ahd_outb(ahd, DFF_THRSH, ahd->suspend_state.dff_thrsh);
ptr = ahd->suspend_state.scratch_ram;
for (i = 0; i < 64; i++)
ahd_outb(ahd, SRAM_BASE + i, *ptr++);
if ((ahd->features & AHD_MORE_SRAM) != 0) {
for (i = 0; i < 16; i++)
ahd_outb(ahd, TARG_OFFSET + i, *ptr++);
}
ptr = ahd->suspend_state.btt; ahd_reset(ahd, /*reinit*/TRUE);
for (i = 0;i < AHD_NUM_TARGETS; i++) { ahd_intr_enable(ahd, TRUE);
int j; ahd_restart(ahd);
for (j = 0;j < AHD_NUM_LUNS; j++) {
u_int tcl;
tcl = BUILD_TCL(i << 4, j);
ahd_busy_tcl(ahd, tcl, *ptr);
}
}
#endif
return (0); return (0);
} }
...@@ -7479,9 +7724,12 @@ ahd_reset_current_bus(struct ahd_softc *ahd) ...@@ -7479,9 +7724,12 @@ ahd_reset_current_bus(struct ahd_softc *ahd)
ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST); ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST);
scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO); scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO);
ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO); ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO);
ahd_flush_device_writes(ahd);
ahd_delay(AHD_BUSRESET_DELAY); ahd_delay(AHD_BUSRESET_DELAY);
/* Turn off the bus reset */ /* Turn off the bus reset */
ahd_outb(ahd, SCSISEQ0, scsiseq); ahd_outb(ahd, SCSISEQ0, scsiseq);
ahd_flush_device_writes(ahd);
ahd_delay(AHD_BUSRESET_DELAY);
if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) { if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) {
/* /*
* 2A Razor #474 * 2A Razor #474
...@@ -7489,8 +7737,7 @@ ahd_reset_current_bus(struct ahd_softc *ahd) ...@@ -7489,8 +7737,7 @@ ahd_reset_current_bus(struct ahd_softc *ahd)
* SCSI bus resets that we initiate, so * SCSI bus resets that we initiate, so
* we must reset the chip. * we must reset the chip.
*/ */
ahd_delay(AHD_BUSRESET_DELAY); ahd_reset(ahd, /*reinit*/TRUE);
ahd_reset(ahd);
ahd_intr_enable(ahd, /*enable*/TRUE); ahd_intr_enable(ahd, /*enable*/TRUE);
AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
} }
...@@ -8585,6 +8832,10 @@ ahd_dump_card_state(struct ahd_softc *ahd) ...@@ -8585,6 +8832,10 @@ ahd_dump_card_state(struct ahd_softc *ahd)
ahd->saved_dst_mode)); ahd->saved_dst_mode));
if (paused) if (paused)
printf("Card was paused\n"); printf("Card was paused\n");
if (ahd_check_cmdcmpltqueues(ahd))
printf("Completions are pending\n");
/* /*
* Mode independent registers. * Mode independent registers.
*/ */
...@@ -8634,10 +8885,12 @@ ahd_dump_card_state(struct ahd_softc *ahd) ...@@ -8634,10 +8885,12 @@ ahd_dump_card_state(struct ahd_softc *ahd)
if (i++ > AHD_SCB_MAX) if (i++ > AHD_SCB_MAX)
break; break;
cur_col = printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb), cur_col = printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
ahd_inb(ahd, SCB_FIFO_USE_COUNT)); ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT));
ahd_set_scbptr(ahd, SCB_GET_TAG(scb)); ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
ahd_scb_control_print(ahd_inb(ahd, SCB_CONTROL), &cur_col, 60); ahd_scb_control_print(ahd_inb_scbram(ahd, SCB_CONTROL),
ahd_scb_scsiid_print(ahd_inb(ahd, SCB_SCSIID), &cur_col, 60); &cur_col, 60);
ahd_scb_scsiid_print(ahd_inb_scbram(ahd, SCB_SCSIID),
&cur_col, 60);
} }
printf("\nTotal %d\n", i); printf("\nTotal %d\n", i);
...@@ -8666,7 +8919,7 @@ ahd_dump_card_state(struct ahd_softc *ahd) ...@@ -8666,7 +8919,7 @@ ahd_dump_card_state(struct ahd_softc *ahd)
while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
ahd_set_scbptr(ahd, scb_index); ahd_set_scbptr(ahd, scb_index);
printf("%d ", scb_index); printf("%d ", scb_index);
scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
} }
printf("\n"); printf("\n");
...@@ -8676,7 +8929,7 @@ ahd_dump_card_state(struct ahd_softc *ahd) ...@@ -8676,7 +8929,7 @@ ahd_dump_card_state(struct ahd_softc *ahd)
while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
ahd_set_scbptr(ahd, scb_index); ahd_set_scbptr(ahd, scb_index);
printf("%d ", scb_index); printf("%d ", scb_index);
scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
} }
printf("\n"); printf("\n");
...@@ -8687,7 +8940,7 @@ ahd_dump_card_state(struct ahd_softc *ahd) ...@@ -8687,7 +8940,7 @@ ahd_dump_card_state(struct ahd_softc *ahd)
while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
ahd_set_scbptr(ahd, scb_index); ahd_set_scbptr(ahd, scb_index);
printf("%d ", scb_index); printf("%d ", scb_index);
scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
} }
printf("\n"); printf("\n");
ahd_set_scbptr(ahd, saved_scb_index); ahd_set_scbptr(ahd, saved_scb_index);
...@@ -8766,15 +9019,16 @@ ahd_dump_card_state(struct ahd_softc *ahd) ...@@ -8766,15 +9019,16 @@ ahd_dump_card_state(struct ahd_softc *ahd)
ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX), ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX),
ahd_inw(ahd, DINDEX)); ahd_inw(ahd, DINDEX));
printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n", printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n",
ahd_name(ahd), ahd_get_scbptr(ahd), ahd_inw(ahd, SCB_NEXT), ahd_name(ahd), ahd_get_scbptr(ahd),
ahd_inw(ahd, SCB_NEXT2)); ahd_inw_scbram(ahd, SCB_NEXT),
ahd_inw_scbram(ahd, SCB_NEXT2));
printf("CDB %x %x %x %x %x %x\n", printf("CDB %x %x %x %x %x %x\n",
ahd_inb(ahd, SCB_CDB_STORE), ahd_inb_scbram(ahd, SCB_CDB_STORE),
ahd_inb(ahd, SCB_CDB_STORE+1), ahd_inb_scbram(ahd, SCB_CDB_STORE+1),
ahd_inb(ahd, SCB_CDB_STORE+2), ahd_inb_scbram(ahd, SCB_CDB_STORE+2),
ahd_inb(ahd, SCB_CDB_STORE+3), ahd_inb_scbram(ahd, SCB_CDB_STORE+3),
ahd_inb(ahd, SCB_CDB_STORE+4), ahd_inb_scbram(ahd, SCB_CDB_STORE+4),
ahd_inb(ahd, SCB_CDB_STORE+5)); ahd_inb_scbram(ahd, SCB_CDB_STORE+5));
printf("STACK:"); printf("STACK:");
for (i = 0; i < ahd->stack_size; i++) { for (i = 0; i < ahd->stack_size; i++) {
ahd->saved_stack[i] = ahd->saved_stack[i] =
...@@ -8806,10 +9060,12 @@ ahd_dump_scbs(struct ahd_softc *ahd) ...@@ -8806,10 +9060,12 @@ ahd_dump_scbs(struct ahd_softc *ahd)
ahd_set_scbptr(ahd, i); ahd_set_scbptr(ahd, i);
printf("%3d", i); printf("%3d", i);
printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n", printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n",
ahd_inb(ahd, SCB_CONTROL), ahd_inb_scbram(ahd, SCB_CONTROL),
ahd_inb(ahd, SCB_SCSIID), ahd_inw(ahd, SCB_NEXT), ahd_inb_scbram(ahd, SCB_SCSIID),
ahd_inw(ahd, SCB_NEXT2), ahd_inl(ahd, SCB_SGPTR), ahd_inw_scbram(ahd, SCB_NEXT),
ahd_inl(ahd, SCB_RESIDUAL_SGPTR)); ahd_inw_scbram(ahd, SCB_NEXT2),
ahd_inl_scbram(ahd, SCB_SGPTR),
ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR));
} }
printf("\n"); printf("\n");
ahd_set_scbptr(ahd, saved_scb_index); ahd_set_scbptr(ahd, saved_scb_index);
...@@ -9192,6 +9448,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) ...@@ -9192,6 +9448,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
ahd->flags &= ~AHD_INITIATORROLE; ahd->flags &= ~AHD_INITIATORROLE;
ahd_pause(ahd); ahd_pause(ahd);
ahd_loadseq(ahd); ahd_loadseq(ahd);
ahd_restart(ahd);
ahd_unlock(ahd, &s); ahd_unlock(ahd, &s);
} }
cel = &ccb->cel; cel = &ccb->cel;
...@@ -9425,6 +9682,11 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) ...@@ -9425,6 +9682,11 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
ahd->flags |= AHD_INITIATORROLE; ahd->flags |= AHD_INITIATORROLE;
ahd_pause(ahd); ahd_pause(ahd);
ahd_loadseq(ahd); ahd_loadseq(ahd);
ahd_restart(ahd);
/*
* Unpaused. The extra unpause
* that follows is harmless.
*/
} }
} }
ahd_unpause(ahd); ahd_unpause(ahd);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#50 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#51 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -455,6 +455,8 @@ static __inline u_int ahd_inb_scbram(struct ahd_softc *ahd, u_int offset); ...@@ -455,6 +455,8 @@ static __inline u_int ahd_inb_scbram(struct ahd_softc *ahd, u_int offset);
static __inline u_int ahd_inw_scbram(struct ahd_softc *ahd, u_int offset); static __inline u_int ahd_inw_scbram(struct ahd_softc *ahd, u_int offset);
static __inline uint32_t static __inline uint32_t
ahd_inl_scbram(struct ahd_softc *ahd, u_int offset); ahd_inl_scbram(struct ahd_softc *ahd, u_int offset);
static __inline uint64_t
ahd_inq_scbram(struct ahd_softc *ahd, u_int offset);
static __inline void ahd_swap_with_next_hscb(struct ahd_softc *ahd, static __inline void ahd_swap_with_next_hscb(struct ahd_softc *ahd,
struct scb *scb); struct scb *scb);
static __inline void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb); static __inline void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb);
...@@ -697,10 +699,15 @@ ahd_inw_scbram(struct ahd_softc *ahd, u_int offset) ...@@ -697,10 +699,15 @@ ahd_inw_scbram(struct ahd_softc *ahd, u_int offset)
static __inline uint32_t static __inline uint32_t
ahd_inl_scbram(struct ahd_softc *ahd, u_int offset) ahd_inl_scbram(struct ahd_softc *ahd, u_int offset)
{ {
return (ahd_inb_scbram(ahd, offset) return (ahd_inw_scbram(ahd, offset)
| (ahd_inb_scbram(ahd, offset+1) << 8) | (ahd_inw_scbram(ahd, offset+2) << 16));
| (ahd_inb_scbram(ahd, offset+2) << 16) }
| (ahd_inb_scbram(ahd, offset+3) << 24));
static __inline uint64_t
ahd_inq_scbram(struct ahd_softc *ahd, u_int offset)
{
return (ahd_inl_scbram(ahd, offset)
| ((uint64_t)ahd_inl_scbram(ahd, offset+4)) << 32);
} }
static __inline struct scb * static __inline struct scb *
......
/* /*
* Adaptec AIC79xx device driver for Linux. * Adaptec AIC79xx device driver for Linux.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#169 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#171 $
* *
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Copyright (c) 1994-2000 Justin T. Gibbs. * Copyright (c) 1994-2000 Justin T. Gibbs.
...@@ -425,7 +425,7 @@ static char *aic79xx = NULL; ...@@ -425,7 +425,7 @@ static char *aic79xx = NULL;
static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n"; static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n";
MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>"); MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>");
MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver"); MODULE_DESCRIPTION("Adaptec Aic790X U320 SCSI Host Bus Adapter driver");
#ifdef MODULE_LICENSE #ifdef MODULE_LICENSE
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
#endif #endif
...@@ -4442,6 +4442,16 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb) ...@@ -4442,6 +4442,16 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
} }
#endif #endif
ahd_set_transaction_status(scb, CAM_UNCOR_PARITY); ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
#ifdef AHD_REPORT_UNDERFLOWS
/*
* This code is disabled by default as some
* clients of the SCSI system do not properly
* initialize the underflow parameter. This
* results in spurious termination of commands
* that complete as expected (e.g. underflow is
* allowed as command can return variable amounts
* of data.
*/
} else if (amount_xferred < scb->io_ctx->underflow) { } else if (amount_xferred < scb->io_ctx->underflow) {
u_int i; u_int i;
...@@ -4456,6 +4466,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb) ...@@ -4456,6 +4466,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
ahd_get_residual(scb), ahd_get_residual(scb),
ahd_get_transfer_length(scb)); ahd_get_transfer_length(scb));
ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
#endif
} else { } else {
ahd_set_transaction_status(scb, CAM_REQ_CMP); ahd_set_transaction_status(scb, CAM_REQ_CMP);
} }
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#133 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#137 $
* *
*/ */
#ifndef _AIC79XX_LINUX_H_ #ifndef _AIC79XX_LINUX_H_
...@@ -292,7 +292,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec) ...@@ -292,7 +292,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
#define AHD_SCSI_HAS_HOST_LOCK 0 #define AHD_SCSI_HAS_HOST_LOCK 0
#endif #endif
#define AIC79XX_DRIVER_VERSION "1.3.9" #define AIC79XX_DRIVER_VERSION "1.3.11"
/**************************** Front End Queues ********************************/ /**************************** Front End Queues ********************************/
/* /*
...@@ -590,10 +590,6 @@ ahd_delay(long usec) ...@@ -590,10 +590,6 @@ ahd_delay(long usec)
/***************************** Low Level I/O **********************************/ /***************************** Low Level I/O **********************************/
#if defined(__powerpc__) || defined(__i386__) || defined(__ia64__)
#define MMAPIO
#endif
static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port); static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port);
static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port); static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port);
static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val); static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
...@@ -608,16 +604,12 @@ static __inline uint8_t ...@@ -608,16 +604,12 @@ static __inline uint8_t
ahd_inb(struct ahd_softc * ahd, long port) ahd_inb(struct ahd_softc * ahd, long port)
{ {
uint8_t x; uint8_t x;
#ifdef MMAPIO
if (ahd->tags[0] == BUS_SPACE_MEMIO) { if (ahd->tags[0] == BUS_SPACE_MEMIO) {
x = readb(ahd->bshs[0].maddr + port); x = readb(ahd->bshs[0].maddr + port);
} else { } else {
x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
} }
#else
x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
#endif
mb(); mb();
return (x); return (x);
} }
...@@ -626,16 +618,12 @@ static __inline uint16_t ...@@ -626,16 +618,12 @@ static __inline uint16_t
ahd_inw_atomic(struct ahd_softc * ahd, long port) ahd_inw_atomic(struct ahd_softc * ahd, long port)
{ {
uint8_t x; uint8_t x;
#ifdef MMAPIO
if (ahd->tags[0] == BUS_SPACE_MEMIO) { if (ahd->tags[0] == BUS_SPACE_MEMIO) {
x = readw(ahd->bshs[0].maddr + port); x = readw(ahd->bshs[0].maddr + port);
} else { } else {
x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
} }
#else
x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
#endif
mb(); mb();
return (x); return (x);
} }
...@@ -643,30 +631,22 @@ ahd_inw_atomic(struct ahd_softc * ahd, long port) ...@@ -643,30 +631,22 @@ ahd_inw_atomic(struct ahd_softc * ahd, long port)
static __inline void static __inline void
ahd_outb(struct ahd_softc * ahd, long port, uint8_t val) ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
{ {
#ifdef MMAPIO
if (ahd->tags[0] == BUS_SPACE_MEMIO) { if (ahd->tags[0] == BUS_SPACE_MEMIO) {
writeb(val, ahd->bshs[0].maddr + port); writeb(val, ahd->bshs[0].maddr + port);
} else { } else {
outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
} }
#else
outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
#endif
mb(); mb();
} }
static __inline void static __inline void
ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val) ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
{ {
#ifdef MMAPIO
if (ahd->tags[0] == BUS_SPACE_MEMIO) { if (ahd->tags[0] == BUS_SPACE_MEMIO) {
writew(val, ahd->bshs[0].maddr + port); writew(val, ahd->bshs[0].maddr + port);
} else { } else {
outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
} }
#else
outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
#endif
mb(); mb();
} }
...@@ -1005,7 +985,12 @@ ahd_flush_device_writes(struct ahd_softc *ahd) ...@@ -1005,7 +985,12 @@ ahd_flush_device_writes(struct ahd_softc *ahd)
(((dev_softc)->dma_mask = mask) && 0) (((dev_softc)->dma_mask = mask) && 0)
#endif #endif
/**************************** Proc FS Support *********************************/ /**************************** Proc FS Support *********************************/
int ahd_linux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
int ahd_linux_proc_info(char *, char **, off_t, int, int, int);
#else
int ahd_linux_proc_info(struct Scsi_Host *, char *, char **,
off_t, int, int);
#endif
/*************************** Domain Validation ********************************/ /*************************** Domain Validation ********************************/
#define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete) #define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete)
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#23 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#25 $
*/ */
#include "aic79xx_osm.h" #include "aic79xx_osm.h"
...@@ -52,11 +52,9 @@ static int ahd_linux_pci_dev_probe(struct pci_dev *pdev, ...@@ -52,11 +52,9 @@ static int ahd_linux_pci_dev_probe(struct pci_dev *pdev,
const struct pci_device_id *ent); const struct pci_device_id *ent);
static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd,
u_long *base, u_long *base2); u_long *base, u_long *base2);
#ifdef MMAPIO
static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
u_long *bus_addr, u_long *bus_addr,
uint8_t **maddr); uint8_t **maddr);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); static void ahd_linux_pci_dev_remove(struct pci_dev *pdev);
...@@ -163,8 +161,8 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -163,8 +161,8 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
bus_addr_t mask_39bit; bus_addr_t mask_39bit;
memsize = ahd_linux_get_memsize(); memsize = ahd_linux_get_memsize();
mask_64bit = (bus_addr_t)(0xFFFFFFFFFFFFFFFFULL&(bus_addr_t)~0); mask_64bit = (bus_addr_t)0xFFFFFFFFFFFFFFFFULL;
mask_39bit = (bus_addr_t)(0x7FFFFFFFFFULL&(bus_addr_t)~0); mask_39bit = (bus_addr_t)0x7FFFFFFFFFULL;
if (memsize >= 0x8000000000ULL if (memsize >= 0x8000000000ULL
&& ahd_pci_set_dma_mask(pdev, mask_64bit) == 0) { && ahd_pci_set_dma_mask(pdev, mask_64bit) == 0) {
ahd->flags |= AHD_64BIT_ADDRESSING; ahd->flags |= AHD_64BIT_ADDRESSING;
...@@ -273,7 +271,6 @@ ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base, ...@@ -273,7 +271,6 @@ ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
return (0); return (0);
} }
#ifdef MMAPIO
static int static int
ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
u_long *bus_addr, u_long *bus_addr,
...@@ -321,7 +318,6 @@ ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, ...@@ -321,7 +318,6 @@ ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
error = ENOMEM; error = ENOMEM;
return (error); return (error);
} }
#endif
int int
ahd_pci_map_registers(struct ahd_softc *ahd) ahd_pci_map_registers(struct ahd_softc *ahd)
...@@ -338,7 +334,6 @@ ahd_pci_map_registers(struct ahd_softc *ahd) ...@@ -338,7 +334,6 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN); command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
base = 0; base = 0;
maddr = NULL; maddr = NULL;
#ifdef MMAPIO
error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr); error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr);
if (error == 0) { if (error == 0) {
ahd->platform_data->mem_busaddr = base; ahd->platform_data->mem_busaddr = base;
...@@ -373,7 +368,6 @@ ahd_pci_map_registers(struct ahd_softc *ahd) ...@@ -373,7 +368,6 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
ahd_get_pci_function(ahd->dev_softc), ahd_get_pci_function(ahd->dev_softc),
base); base);
} }
#endif
if (maddr == NULL) { if (maddr == NULL) {
u_long base2; u_long base2;
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#73 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#77 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -117,6 +117,7 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) ...@@ -117,6 +117,7 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
static ahd_device_setup_t ahd_aic7901_setup; static ahd_device_setup_t ahd_aic7901_setup;
static ahd_device_setup_t ahd_aic7901A_setup; static ahd_device_setup_t ahd_aic7901A_setup;
static ahd_device_setup_t ahd_aic7902_setup; static ahd_device_setup_t ahd_aic7902_setup;
static ahd_device_setup_t ahd_aic790X_setup;
struct ahd_pci_identity ahd_pci_ident_table [] = struct ahd_pci_identity ahd_pci_ident_table [] =
{ {
...@@ -375,7 +376,7 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) ...@@ -375,7 +376,7 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
ahd->bus_intr = ahd_pci_intr; ahd->bus_intr = ahd_pci_intr;
error = ahd_reset(ahd); error = ahd_reset(ahd, /*reinit*/FALSE);
if (error != 0) if (error != 0)
return (ENXIO); return (ENXIO);
...@@ -418,9 +419,11 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) ...@@ -418,9 +419,11 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
int int
ahd_pci_test_register_access(struct ahd_softc *ahd) ahd_pci_test_register_access(struct ahd_softc *ahd)
{ {
uint32_t cmd; uint32_t cmd;
int error; u_int targpcistat;
uint8_t hcntrl; u_int pci_status1;
int error;
uint8_t hcntrl;
error = EIO; error = EIO;
...@@ -454,6 +457,18 @@ ahd_pci_test_register_access(struct ahd_softc *ahd) ...@@ -454,6 +457,18 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
ahd_outb(ahd, HCNTRL, hcntrl|PAUSE); ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
while (ahd_is_paused(ahd) == 0) while (ahd_is_paused(ahd) == 0)
; ;
/* Clear any PCI errors that occurred before our driver attached. */
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
targpcistat = ahd_inb(ahd, TARGPCISTAT);
ahd_outb(ahd, TARGPCISTAT, targpcistat);
pci_status1 = ahd_pci_read_config(ahd->dev_softc,
PCIR_STATUS + 1, /*bytes*/1);
ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
pci_status1, /*bytes*/1);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
ahd_outb(ahd, CLRINT, CLRPCIINT);
ahd_outb(ahd, SEQCTL0, PERRORDIS); ahd_outb(ahd, SEQCTL0, PERRORDIS);
ahd_outl(ahd, SRAM_BASE, 0x5aa555aa); ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa) if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
...@@ -472,8 +487,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd) ...@@ -472,8 +487,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
fail: fail:
if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
u_int targpcistat;
u_int pci_status1;
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
targpcistat = ahd_inb(ahd, TARGPCISTAT); targpcistat = ahd_inb(ahd, TARGPCISTAT);
...@@ -486,7 +499,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd) ...@@ -486,7 +499,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
pci_status1, /*bytes*/1); pci_status1, /*bytes*/1);
ahd_outb(ahd, CLRINT, CLRPCIINT); ahd_outb(ahd, CLRINT, CLRPCIINT);
} }
ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS); ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2); ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
return (error); return (error);
...@@ -903,29 +915,31 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat) ...@@ -903,29 +915,31 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
static int static int
ahd_aic7901_setup(struct ahd_softc *ahd) ahd_aic7901_setup(struct ahd_softc *ahd)
{ {
int error;
error = ahd_aic7902_setup(ahd);
if (error != 0)
return (error);
ahd->chip = AHD_AIC7901; ahd->chip = AHD_AIC7901;
return (0); ahd->features = AHD_AIC7901_FE;
return (ahd_aic790X_setup(ahd));
} }
static int static int
ahd_aic7901A_setup(struct ahd_softc *ahd) ahd_aic7901A_setup(struct ahd_softc *ahd)
{ {
int error;
error = ahd_aic7902_setup(ahd);
if (error != 0)
return (error);
ahd->chip = AHD_AIC7901A; ahd->chip = AHD_AIC7901A;
return (0); ahd->features = AHD_AIC7901A_FE;
return (ahd_aic790X_setup(ahd));
} }
static int static int
ahd_aic7902_setup(struct ahd_softc *ahd) ahd_aic7902_setup(struct ahd_softc *ahd)
{
ahd->chip = AHD_AIC7902;
ahd->features = AHD_AIC7902_FE;
return (ahd_aic790X_setup(ahd));
}
static int
ahd_aic790X_setup(struct ahd_softc *ahd)
{ {
ahd_dev_softc_t pci; ahd_dev_softc_t pci;
u_int rev; u_int rev;
...@@ -939,8 +953,6 @@ ahd_aic7902_setup(struct ahd_softc *ahd) ...@@ -939,8 +953,6 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
return (ENXIO); return (ENXIO);
} }
ahd->channel = ahd_get_pci_function(pci) + 'A'; ahd->channel = ahd_get_pci_function(pci) + 'A';
ahd->chip = AHD_AIC7902;
ahd->features = AHD_AIC7902_FE;
if (rev < ID_AIC7902_PCI_REV_B0) { if (rev < ID_AIC7902_PCI_REV_B0) {
/* /*
* Enable A series workarounds. * Enable A series workarounds.
...@@ -968,9 +980,14 @@ ahd_aic7902_setup(struct ahd_softc *ahd) ...@@ -968,9 +980,14 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
u_int devconfig1; u_int devconfig1;
ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
| AHD_NEW_DFCNTRL_OPTS; | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_ABORT_LQI_BUG ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
| AHD_INTCOLLISION_BUG|AHD_EARLY_REQ_BUG;
/*
* Some issues have been resolved in the 7901B.
*/
if ((ahd->features & AHD_MULTI_FUNC) != 0)
ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
/* /*
* IO Cell paramter setup. * IO Cell paramter setup.
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr> * String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
* sym driver. * sym driver.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#17 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#19 $
*/ */
#include "aic79xx_osm.h" #include "aic79xx_osm.h"
#include "aic79xx_inline.h" #include "aic79xx_inline.h"
...@@ -278,8 +278,13 @@ ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length) ...@@ -278,8 +278,13 @@ ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length)
* Return information to handle /proc support for the driver. * Return information to handle /proc support for the driver.
*/ */
int int
ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
int length, int inout) ahd_linux_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout)
#else
ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
off_t offset, int length, int inout)
#endif
{ {
struct ahd_softc *ahd; struct ahd_softc *ahd;
struct info_str info; struct info_str info;
...@@ -291,10 +296,14 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t o ...@@ -291,10 +296,14 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t o
retval = -EINVAL; retval = -EINVAL;
ahd_list_lock(&l); ahd_list_lock(&l);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
TAILQ_FOREACH(ahd, &ahd_tailq, links) { TAILQ_FOREACH(ahd, &ahd_tailq, links) {
if (ahd->platform_data->host == shost) if (ahd->platform_data->host->host_no == hostno)
break; break;
} }
#else
ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata);
#endif
if (ahd == NULL) if (ahd == NULL)
goto done; goto done;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
*/ */
typedef int (ahd_reg_print_t)(u_int, u_int *, u_int); typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahd_reg_parse_entry { typedef struct ahd_reg_parse_entry {
...@@ -2239,94 +2239,94 @@ ahd_reg_print_t ahd_scb_sense_busaddr_print; ...@@ -2239,94 +2239,94 @@ ahd_reg_print_t ahd_scb_sense_busaddr_print;
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_dataptr_print; ahd_reg_print_t ahd_scb_tag_print;
#else #else
#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \ #define ahd_scb_tag_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x190, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_TAG", 0x190, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_datacnt_print; ahd_reg_print_t ahd_scb_control_print;
#else #else
#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \ #define ahd_scb_control_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_DATACNT", 0x198, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_CONTROL", 0x192, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_sgptr_print; ahd_reg_print_t ahd_scb_scsiid_print;
#else #else
#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \ #define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_SGPTR", 0x19c, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_SCSIID", 0x193, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_busaddr_print; ahd_reg_print_t ahd_scb_lun_print;
#else #else
#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \ #define ahd_scb_lun_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a0, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_LUN", 0x194, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_next_print; ahd_reg_print_t ahd_scb_task_attribute_print;
#else #else
#define ahd_scb_next_print(regvalue, cur_col, wrap) \ #define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_NEXT", 0x1a4, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x195, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_next2_print; ahd_reg_print_t ahd_scb_cdb_len_print;
#else #else
#define ahd_scb_next2_print(regvalue, cur_col, wrap) \ #define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_NEXT2", 0x1a6, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x196, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_control_print; ahd_reg_print_t ahd_scb_task_management_print;
#else #else
#define ahd_scb_control_print(regvalue, cur_col, wrap) \ #define ahd_scb_task_management_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_CONTROL", 0x1a8, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x197, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_scsiid_print; ahd_reg_print_t ahd_scb_dataptr_print;
#else #else
#define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \ #define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_SCSIID", 0x1a9, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x198, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_lun_print; ahd_reg_print_t ahd_scb_datacnt_print;
#else #else
#define ahd_scb_lun_print(regvalue, cur_col, wrap) \ #define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_LUN", 0x1aa, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_DATACNT", 0x1a0, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_task_attribute_print; ahd_reg_print_t ahd_scb_sgptr_print;
#else #else
#define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \ #define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x1ab, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_SGPTR", 0x1a4, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_cdb_len_print; ahd_reg_print_t ahd_scb_busaddr_print;
#else #else
#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \ #define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x1ac, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a8, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_task_management_print; ahd_reg_print_t ahd_scb_next_print;
#else #else
#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \ #define ahd_scb_next_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x1ad, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_NEXT", 0x1ac, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_tag_print; ahd_reg_print_t ahd_scb_next2_print;
#else #else
#define ahd_scb_tag_print(regvalue, cur_col, wrap) \ #define ahd_scb_next2_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TAG", 0x1ae, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_NEXT2", 0x1ae, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
...@@ -2557,6 +2557,8 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -2557,6 +2557,8 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SHORTTHRESH 0x2f #define SHORTTHRESH 0x2f
#define LUNLEN 0x30 #define LUNLEN 0x30
#define TLUNLEN 0xf0
#define ILUNLEN 0x0f
#define CDBLIMIT 0x31 #define CDBLIMIT 0x31
...@@ -3648,25 +3650,10 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3648,25 +3650,10 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SCB_SENSE_BUSADDR 0x18c #define SCB_SENSE_BUSADDR 0x18c
#define SCB_NEXT_COMPLETE 0x18c #define SCB_NEXT_COMPLETE 0x18c
#define SCB_DATAPTR 0x190 #define SCB_TAG 0x190
#define SCB_FIFO_USE_COUNT 0x190
#define SCB_DATACNT 0x198
#define SG_LAST_SEG 0x80
#define SG_HIGH_ADDR_BITS 0x7f
#define SCB_SGPTR 0x19c
#define SG_STATUS_VALID 0x04
#define SG_FULL_RESID 0x02
#define SG_LIST_NULL 0x01
#define SCB_BUSADDR 0x1a0 #define SCB_CONTROL 0x192
#define SCB_NEXT 0x1a4
#define SCB_NEXT_SCB_BUSADDR 0x1a4
#define SCB_NEXT2 0x1a6
#define SCB_CONTROL 0x1a8
#define TARGET_SCB 0x80 #define TARGET_SCB 0x80
#define DISCENB 0x40 #define DISCENB 0x40
#define TAG_ENB 0x20 #define TAG_ENB 0x20
...@@ -3675,23 +3662,38 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3675,23 +3662,38 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define DISCONNECTED 0x04 #define DISCONNECTED 0x04
#define SCB_TAG_TYPE 0x03 #define SCB_TAG_TYPE 0x03
#define SCB_SCSIID 0x1a9 #define SCB_SCSIID 0x193
#define TID 0xf0 #define TID 0xf0
#define OID 0x0f #define OID 0x0f
#define SCB_LUN 0x1aa #define SCB_LUN 0x194
#define LID 0xff #define LID 0xff
#define SCB_TASK_ATTRIBUTE 0x1ab #define SCB_TASK_ATTRIBUTE 0x195
#define SCB_XFERLEN_ODD 0x01 #define SCB_XFERLEN_ODD 0x01
#define SCB_CDB_LEN 0x1ac #define SCB_CDB_LEN 0x196
#define SCB_CDB_LEN_PTR 0x80 #define SCB_CDB_LEN_PTR 0x80
#define SCB_TASK_MANAGEMENT 0x1ad #define SCB_TASK_MANAGEMENT 0x197
#define SCB_DATAPTR 0x198
#define SCB_DATACNT 0x1a0
#define SG_LAST_SEG 0x80
#define SG_HIGH_ADDR_BITS 0x7f
#define SCB_SGPTR 0x1a4
#define SG_STATUS_VALID 0x04
#define SG_FULL_RESID 0x02
#define SG_LIST_NULL 0x01
#define SCB_BUSADDR 0x1a8
#define SCB_NEXT 0x1ac
#define SCB_NEXT_SCB_BUSADDR 0x1ac
#define SCB_TAG 0x1ae #define SCB_NEXT2 0x1ae
#define SCB_FIFO_USE_COUNT 0x1ae
#define SCB_SPARE 0x1b0 #define SCB_SPARE 0x1b0
#define SCB_PKT_LUN 0x1b0 #define SCB_PKT_LUN 0x1b0
...@@ -3720,6 +3722,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3720,6 +3722,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define AHD_PRECOMP_CUTBACK_29 0x06 #define AHD_PRECOMP_CUTBACK_29 0x06
#define AHD_NUM_PER_DEV_ANNEXCOLS 0x04 #define AHD_NUM_PER_DEV_ANNEXCOLS 0x04
#define B_CURRFIFO_0 0x02 #define B_CURRFIFO_0 0x02
#define LUNLEN_SINGLE_LEVEL_LUN 0x0f
#define NVRAM_SCB_OFFSET 0x2c #define NVRAM_SCB_OFFSET 0x2c
#define AHD_TIMER_MAX_US 0x18ffe7 #define AHD_TIMER_MAX_US 0x18ffe7
#define AHD_TIMER_MAX_TICKS 0xffff #define AHD_TIMER_MAX_TICKS 0xffff
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated * DO NOT EDIT - This file is automatically generated
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#93 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#68 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
*/ */
#include "aic79xx_osm.h" #include "aic79xx_osm.h"
...@@ -489,10 +489,15 @@ ahd_shortthresh_print(u_int regvalue, u_int *cur_col, u_int wrap) ...@@ -489,10 +489,15 @@ ahd_shortthresh_print(u_int regvalue, u_int *cur_col, u_int wrap)
0x2f, regvalue, cur_col, wrap)); 0x2f, regvalue, cur_col, wrap));
} }
static ahd_reg_parse_entry_t LUNLEN_parse_table[] = {
{ "ILUNLEN", 0x0f, 0x0f },
{ "TLUNLEN", 0xf0, 0xf0 }
};
int int
ahd_lunlen_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_lunlen_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(NULL, 0, "LUNLEN", return (ahd_print_register(LUNLEN_parse_table, 2, "LUNLEN",
0x30, regvalue, cur_col, wrap)); 0x30, regvalue, cur_col, wrap));
} }
...@@ -3486,58 +3491,12 @@ ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) ...@@ -3486,58 +3491,12 @@ ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
} }
int int
ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(NULL, 0, "SCB_DATAPTR", return (ahd_print_register(NULL, 0, "SCB_TAG",
0x190, regvalue, cur_col, wrap)); 0x190, regvalue, cur_col, wrap));
} }
static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = {
{ "SG_HIGH_ADDR_BITS", 0x7f, 0x7f },
{ "SG_LAST_SEG", 0x80, 0x80 }
};
int
ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT",
0x198, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = {
{ "SG_LIST_NULL", 0x01, 0x01 },
{ "SG_FULL_RESID", 0x02, 0x02 },
{ "SG_STATUS_VALID", 0x04, 0x04 }
};
int
ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR",
0x19c, regvalue, cur_col, wrap));
}
int
ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_BUSADDR",
0x1a0, regvalue, cur_col, wrap));
}
int
ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_NEXT",
0x1a4, regvalue, cur_col, wrap));
}
int
ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_NEXT2",
0x1a6, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = { static ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = {
{ "SCB_TAG_TYPE", 0x03, 0x03 }, { "SCB_TAG_TYPE", 0x03, 0x03 },
{ "DISCONNECTED", 0x04, 0x04 }, { "DISCONNECTED", 0x04, 0x04 },
...@@ -3552,7 +3511,7 @@ int ...@@ -3552,7 +3511,7 @@ int
ahd_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(SCB_CONTROL_parse_table, 7, "SCB_CONTROL", return (ahd_print_register(SCB_CONTROL_parse_table, 7, "SCB_CONTROL",
0x1a8, regvalue, cur_col, wrap)); 0x192, regvalue, cur_col, wrap));
} }
static ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = { static ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = {
...@@ -3564,7 +3523,7 @@ int ...@@ -3564,7 +3523,7 @@ int
ahd_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(SCB_SCSIID_parse_table, 2, "SCB_SCSIID", return (ahd_print_register(SCB_SCSIID_parse_table, 2, "SCB_SCSIID",
0x1a9, regvalue, cur_col, wrap)); 0x193, regvalue, cur_col, wrap));
} }
static ahd_reg_parse_entry_t SCB_LUN_parse_table[] = { static ahd_reg_parse_entry_t SCB_LUN_parse_table[] = {
...@@ -3575,14 +3534,18 @@ int ...@@ -3575,14 +3534,18 @@ int
ahd_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(SCB_LUN_parse_table, 1, "SCB_LUN", return (ahd_print_register(SCB_LUN_parse_table, 1, "SCB_LUN",
0x1aa, regvalue, cur_col, wrap)); 0x194, regvalue, cur_col, wrap));
} }
static ahd_reg_parse_entry_t SCB_TASK_ATTRIBUTE_parse_table[] = {
{ "SCB_XFERLEN_ODD", 0x01, 0x01 }
};
int int
ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", return (ahd_print_register(SCB_TASK_ATTRIBUTE_parse_table, 1, "SCB_TASK_ATTRIBUTE",
0x1ab, regvalue, cur_col, wrap)); 0x195, regvalue, cur_col, wrap));
} }
static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = { static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = {
...@@ -3593,20 +3556,66 @@ int ...@@ -3593,20 +3556,66 @@ int
ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN", return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN",
0x1ac, regvalue, cur_col, wrap)); 0x196, regvalue, cur_col, wrap));
} }
int int
ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT",
0x1ad, regvalue, cur_col, wrap)); 0x197, regvalue, cur_col, wrap));
} }
int int
ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(NULL, 0, "SCB_TAG", return (ahd_print_register(NULL, 0, "SCB_DATAPTR",
0x198, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = {
{ "SG_HIGH_ADDR_BITS", 0x7f, 0x7f },
{ "SG_LAST_SEG", 0x80, 0x80 }
};
int
ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT",
0x1a0, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = {
{ "SG_LIST_NULL", 0x01, 0x01 },
{ "SG_FULL_RESID", 0x02, 0x02 },
{ "SG_STATUS_VALID", 0x04, 0x04 }
};
int
ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR",
0x1a4, regvalue, cur_col, wrap));
}
int
ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_BUSADDR",
0x1a8, regvalue, cur_col, wrap));
}
int
ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_NEXT",
0x1ac, regvalue, cur_col, wrap));
}
int
ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_NEXT2",
0x1ae, regvalue, cur_col, wrap)); 0x1ae, regvalue, cur_col, wrap));
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
*/ */
static uint8_t seqprog[] = { static uint8_t seqprog[] = {
0xff, 0x02, 0x06, 0x78, 0xff, 0x02, 0x06, 0x78,
...@@ -40,13 +40,13 @@ static uint8_t seqprog[] = { ...@@ -40,13 +40,13 @@ static uint8_t seqprog[] = {
0x01, 0x52, 0x64, 0x78, 0x01, 0x52, 0x64, 0x78,
0x02, 0x58, 0x50, 0x31, 0x02, 0x58, 0x50, 0x31,
0xff, 0xea, 0x10, 0x0b, 0xff, 0xea, 0x10, 0x0b,
0xff, 0xad, 0x4f, 0x78, 0xff, 0x97, 0x4f, 0x78,
0x50, 0x4b, 0x4a, 0x68, 0x50, 0x4b, 0x4a, 0x68,
0xbf, 0x3a, 0x74, 0x08, 0xbf, 0x3a, 0x74, 0x08,
0x14, 0xea, 0x50, 0x59, 0x14, 0xea, 0x50, 0x59,
0x14, 0xea, 0x04, 0x00, 0x14, 0xea, 0x04, 0x00,
0x08, 0xa8, 0x51, 0x03, 0x08, 0x92, 0x25, 0x03,
0xff, 0xae, 0x3f, 0x68, 0xff, 0x90, 0x3f, 0x68,
0x00, 0xe2, 0x56, 0x5b, 0x00, 0xe2, 0x56, 0x5b,
0x00, 0xe2, 0x3e, 0x40, 0x00, 0xe2, 0x3e, 0x40,
0x00, 0xea, 0x44, 0x59, 0x00, 0xea, 0x44, 0x59,
...@@ -113,24 +113,24 @@ static uint8_t seqprog[] = { ...@@ -113,24 +113,24 @@ static uint8_t seqprog[] = {
0xff, 0xea, 0xc0, 0x09, 0xff, 0xea, 0xc0, 0x09,
0x01, 0x4e, 0x9d, 0x1a, 0x01, 0x4e, 0x9d, 0x1a,
0x00, 0x4f, 0x9f, 0x22, 0x00, 0x4f, 0x9f, 0x22,
0x01, 0xaa, 0x6d, 0x33, 0x01, 0x94, 0x6d, 0x33,
0x01, 0xea, 0x5c, 0x33, 0x01, 0xea, 0x20, 0x33,
0x04, 0xa4, 0x49, 0x32, 0x04, 0xac, 0x49, 0x32,
0xff, 0xea, 0x4a, 0x03, 0xff, 0xea, 0x5a, 0x03,
0xff, 0xea, 0x4e, 0x03, 0xff, 0xea, 0x5e, 0x03,
0x01, 0x10, 0xd4, 0x31, 0x01, 0x10, 0xd4, 0x31,
0x10, 0xa8, 0xf5, 0x68, 0x10, 0x92, 0xf5, 0x68,
0x3d, 0xa9, 0xc5, 0x29, 0x3d, 0x93, 0xc5, 0x29,
0xfe, 0xe2, 0xc4, 0x09, 0xfe, 0xe2, 0xc4, 0x09,
0x01, 0xea, 0xc6, 0x01, 0x01, 0xea, 0xc6, 0x01,
0x02, 0xe2, 0xc8, 0x31, 0x02, 0xe2, 0xc8, 0x31,
0x02, 0xec, 0x50, 0x31, 0x02, 0xec, 0x50, 0x31,
0x02, 0xa0, 0xda, 0x31, 0x02, 0xa0, 0xda, 0x31,
0xff, 0xa9, 0xf4, 0x70, 0xff, 0xa9, 0xf4, 0x70,
0x02, 0xa0, 0x48, 0x37, 0x02, 0xa0, 0x58, 0x37,
0xff, 0x21, 0xfd, 0x70, 0xff, 0x21, 0xfd, 0x70,
0x02, 0x22, 0x51, 0x31, 0x02, 0x22, 0x51, 0x31,
0x02, 0xa0, 0x4c, 0x33, 0x02, 0xa0, 0x5c, 0x33,
0x02, 0xa0, 0x44, 0x36, 0x02, 0xa0, 0x44, 0x36,
0x02, 0xa0, 0x40, 0x32, 0x02, 0xa0, 0x40, 0x32,
0x02, 0xa0, 0x44, 0x36, 0x02, 0xa0, 0x44, 0x36,
...@@ -161,7 +161,7 @@ static uint8_t seqprog[] = { ...@@ -161,7 +161,7 @@ static uint8_t seqprog[] = {
0x04, 0x24, 0xf9, 0x30, 0x04, 0x24, 0xf9, 0x30,
0x1d, 0xea, 0x3a, 0x41, 0x1d, 0xea, 0x3a, 0x41,
0x02, 0x2c, 0x51, 0x31, 0x02, 0x2c, 0x51, 0x31,
0x04, 0xa0, 0xf9, 0x30, 0x04, 0xa8, 0xf9, 0x30,
0x19, 0xea, 0x3a, 0x41, 0x19, 0xea, 0x3a, 0x41,
0x06, 0xea, 0x08, 0x81, 0x06, 0xea, 0x08, 0x81,
0x01, 0xe2, 0x5a, 0x35, 0x01, 0xe2, 0x5a, 0x35,
...@@ -179,8 +179,8 @@ static uint8_t seqprog[] = { ...@@ -179,8 +179,8 @@ static uint8_t seqprog[] = {
0x02, 0x20, 0xbd, 0x30, 0x02, 0x20, 0xbd, 0x30,
0x02, 0x20, 0xb9, 0x30, 0x02, 0x20, 0xb9, 0x30,
0x02, 0x20, 0x51, 0x31, 0x02, 0x20, 0x51, 0x31,
0x4c, 0xa9, 0xd7, 0x28, 0x4c, 0x93, 0xd7, 0x28,
0x10, 0xa8, 0x63, 0x79, 0x10, 0x92, 0x63, 0x79,
0x01, 0x6b, 0xc0, 0x30, 0x01, 0x6b, 0xc0, 0x30,
0x02, 0x64, 0xc8, 0x00, 0x02, 0x64, 0xc8, 0x00,
0x40, 0x3a, 0x74, 0x04, 0x40, 0x3a, 0x74, 0x04,
...@@ -219,42 +219,42 @@ static uint8_t seqprog[] = { ...@@ -219,42 +219,42 @@ static uint8_t seqprog[] = {
0xff, 0xea, 0xb2, 0x09, 0xff, 0xea, 0xb2, 0x09,
0xff, 0xe0, 0xc0, 0x19, 0xff, 0xe0, 0xc0, 0x19,
0xff, 0xe0, 0xb0, 0x79, 0xff, 0xe0, 0xb0, 0x79,
0x02, 0xa4, 0x51, 0x31, 0x02, 0xac, 0x51, 0x31,
0x00, 0xe2, 0xa6, 0x41, 0x00, 0xe2, 0xa6, 0x41,
0x02, 0x5e, 0x50, 0x31, 0x02, 0x5e, 0x50, 0x31,
0x02, 0xa8, 0xb8, 0x30, 0x02, 0xa8, 0xb8, 0x30,
0x02, 0x5c, 0x50, 0x31, 0x02, 0x5c, 0x50, 0x31,
0xff, 0xa5, 0xc1, 0x71, 0xff, 0xad, 0xc1, 0x71,
0x02, 0xa4, 0x41, 0x31, 0x02, 0xac, 0x41, 0x31,
0x02, 0x22, 0x51, 0x31, 0x02, 0x22, 0x51, 0x31,
0x02, 0xa0, 0x4c, 0x33, 0x02, 0xa0, 0x5c, 0x33,
0x02, 0xa0, 0x44, 0x32, 0x02, 0xa0, 0x44, 0x32,
0x00, 0xe2, 0xca, 0x41, 0x00, 0xe2, 0xca, 0x41,
0x10, 0xa8, 0xcb, 0x69, 0x10, 0x92, 0xcb, 0x69,
0x3d, 0xa9, 0xc9, 0x29, 0x3d, 0x93, 0xc9, 0x29,
0x01, 0xe4, 0xc8, 0x01, 0x01, 0xe4, 0xc8, 0x01,
0x01, 0xea, 0xca, 0x01, 0x01, 0xea, 0xca, 0x01,
0xff, 0xea, 0xda, 0x01, 0xff, 0xea, 0xda, 0x01,
0x02, 0x20, 0x51, 0x31, 0x02, 0x20, 0x51, 0x31,
0x02, 0xa6, 0x41, 0x32, 0x02, 0xae, 0x41, 0x32,
0xff, 0x21, 0xd3, 0x61, 0xff, 0x21, 0xd3, 0x61,
0xff, 0xea, 0x46, 0x02, 0xff, 0xea, 0x46, 0x02,
0x02, 0x5c, 0x50, 0x31, 0x02, 0x5c, 0x50, 0x31,
0x40, 0xea, 0x96, 0x00, 0x40, 0xea, 0x96, 0x00,
0x02, 0x56, 0xcc, 0x6d, 0x02, 0x56, 0xcc, 0x6d,
0x01, 0x55, 0xcc, 0x6d, 0x01, 0x55, 0xcc, 0x6d,
0x10, 0xa8, 0xdf, 0x79, 0x10, 0x92, 0xdf, 0x79,
0x10, 0x40, 0xe8, 0x69, 0x10, 0x40, 0xe8, 0x69,
0x01, 0x56, 0xe8, 0x79, 0x01, 0x56, 0xe8, 0x79,
0xff, 0xad, 0x07, 0x78, 0xff, 0x97, 0x07, 0x78,
0x13, 0xea, 0x50, 0x59, 0x13, 0xea, 0x50, 0x59,
0x13, 0xea, 0x04, 0x00, 0x13, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x06, 0x40, 0x00, 0xe2, 0x06, 0x40,
0xbf, 0x3a, 0x74, 0x08, 0xbf, 0x3a, 0x74, 0x08,
0x08, 0xea, 0x98, 0x00, 0x08, 0xea, 0x98, 0x00,
0x08, 0x57, 0xae, 0x00, 0x08, 0x57, 0xae, 0x00,
0x01, 0xa9, 0x69, 0x32, 0x01, 0x93, 0x69, 0x32,
0x01, 0xaa, 0x6b, 0x32, 0x01, 0x94, 0x6b, 0x32,
0x40, 0xea, 0x66, 0x02, 0x40, 0xea, 0x66, 0x02,
0x08, 0x3c, 0x78, 0x00, 0x08, 0x3c, 0x78, 0x00,
0x80, 0xea, 0x62, 0x02, 0x80, 0xea, 0x62, 0x02,
...@@ -277,13 +277,13 @@ static uint8_t seqprog[] = { ...@@ -277,13 +277,13 @@ static uint8_t seqprog[] = {
0x33, 0xea, 0x00, 0x00, 0x33, 0xea, 0x00, 0x00,
0x02, 0xa8, 0x90, 0x32, 0x02, 0xa8, 0x90, 0x32,
0x00, 0xe2, 0x6a, 0x59, 0x00, 0xe2, 0x6a, 0x59,
0xef, 0xac, 0xd5, 0x19, 0xef, 0x96, 0xd5, 0x19,
0x00, 0xe2, 0x2a, 0x52, 0x00, 0xe2, 0x2a, 0x52,
0x09, 0x80, 0xe1, 0x30, 0x09, 0x80, 0xe1, 0x30,
0x02, 0xea, 0x36, 0x00, 0x02, 0xea, 0x36, 0x00,
0xa8, 0xea, 0x32, 0x00, 0xa8, 0xea, 0x32, 0x00,
0x00, 0xe2, 0x30, 0x42, 0x00, 0xe2, 0x30, 0x42,
0x01, 0xac, 0xd1, 0x30, 0x01, 0x96, 0xd1, 0x30,
0x10, 0x80, 0x89, 0x31, 0x10, 0x80, 0x89, 0x31,
0x20, 0xea, 0x32, 0x00, 0x20, 0xea, 0x32, 0x00,
0xbf, 0x33, 0x67, 0x0a, 0xbf, 0x33, 0x67, 0x0a,
...@@ -293,20 +293,20 @@ static uint8_t seqprog[] = { ...@@ -293,20 +293,20 @@ static uint8_t seqprog[] = {
0x00, 0xe2, 0xf8, 0x41, 0x00, 0xe2, 0xf8, 0x41,
0x80, 0x33, 0xb5, 0x6a, 0x80, 0x33, 0xb5, 0x6a,
0x01, 0x44, 0x10, 0x33, 0x01, 0x44, 0x10, 0x33,
0x08, 0xa8, 0x51, 0x03, 0x08, 0x92, 0x25, 0x03,
0x00, 0xe2, 0xf8, 0x41, 0x00, 0xe2, 0xf8, 0x41,
0x10, 0xea, 0x80, 0x00, 0x10, 0xea, 0x80, 0x00,
0x01, 0x31, 0xc5, 0x31, 0x01, 0x31, 0xc5, 0x31,
0x80, 0xe2, 0x60, 0x62, 0x80, 0xe2, 0x60, 0x62,
0x10, 0xa8, 0x85, 0x6a, 0x10, 0x92, 0x85, 0x6a,
0xc0, 0xaa, 0xc5, 0x01, 0xc0, 0x94, 0xc5, 0x01,
0x40, 0xa8, 0x51, 0x6a, 0x40, 0x92, 0x51, 0x6a,
0xbf, 0xe2, 0xc4, 0x09, 0xbf, 0xe2, 0xc4, 0x09,
0x20, 0xa8, 0x65, 0x7a, 0x20, 0x92, 0x65, 0x7a,
0x01, 0xe2, 0x88, 0x30, 0x01, 0xe2, 0x88, 0x30,
0x00, 0xe2, 0xb8, 0x5b, 0x00, 0xe2, 0xb8, 0x5b,
0xa0, 0x36, 0x6d, 0x62, 0xa0, 0x36, 0x6d, 0x62,
0x23, 0xa8, 0x89, 0x08, 0x23, 0x92, 0x89, 0x08,
0x00, 0xe2, 0xb8, 0x5b, 0x00, 0xe2, 0xb8, 0x5b,
0xa0, 0x36, 0x6d, 0x62, 0xa0, 0x36, 0x6d, 0x62,
0x00, 0xa8, 0x64, 0x42, 0x00, 0xa8, 0x64, 0x42,
...@@ -348,7 +348,7 @@ static uint8_t seqprog[] = { ...@@ -348,7 +348,7 @@ static uint8_t seqprog[] = {
0xa0, 0xea, 0xca, 0x5b, 0xa0, 0xea, 0xca, 0x5b,
0x01, 0xa0, 0xba, 0x62, 0x01, 0xa0, 0xba, 0x62,
0x01, 0x84, 0xaf, 0x7a, 0x01, 0x84, 0xaf, 0x7a,
0x01, 0xab, 0xbd, 0x6a, 0x01, 0x95, 0xbd, 0x6a,
0x05, 0xea, 0x50, 0x59, 0x05, 0xea, 0x50, 0x59,
0x05, 0xea, 0x04, 0x00, 0x05, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xbc, 0x42, 0x00, 0xe2, 0xbc, 0x42,
...@@ -381,22 +381,22 @@ static uint8_t seqprog[] = { ...@@ -381,22 +381,22 @@ static uint8_t seqprog[] = {
0x20, 0x46, 0x12, 0x63, 0x20, 0x46, 0x12, 0x63,
0xff, 0xea, 0x52, 0x09, 0xff, 0xea, 0x52, 0x09,
0xa8, 0xea, 0xca, 0x5b, 0xa8, 0xea, 0xca, 0x5b,
0x04, 0xa8, 0xf9, 0x7a, 0x04, 0x92, 0xf9, 0x7a,
0x01, 0x34, 0xc1, 0x31, 0x01, 0x34, 0xc1, 0x31,
0x00, 0xa9, 0xf9, 0x62, 0x00, 0x93, 0xf9, 0x62,
0x01, 0x35, 0xc1, 0x31, 0x01, 0x35, 0xc1, 0x31,
0x00, 0xaa, 0x03, 0x73, 0x00, 0x94, 0x03, 0x73,
0x01, 0xa9, 0x52, 0x11, 0x01, 0xa9, 0x52, 0x11,
0xff, 0xa9, 0xee, 0x6a, 0xff, 0xa9, 0xee, 0x6a,
0x00, 0xe2, 0x12, 0x43, 0x00, 0xe2, 0x12, 0x43,
0x10, 0x33, 0x67, 0x02, 0x10, 0x33, 0x67, 0x02,
0x04, 0xa8, 0x13, 0x7b, 0x04, 0x92, 0x13, 0x7b,
0xfb, 0xa8, 0x51, 0x0b, 0xfb, 0x92, 0x25, 0x0b,
0xff, 0xea, 0x66, 0x0a, 0xff, 0xea, 0x66, 0x0a,
0x01, 0x9c, 0x0d, 0x6b, 0x01, 0xa4, 0x0d, 0x6b,
0x02, 0xa8, 0x90, 0x32, 0x02, 0xa8, 0x90, 0x32,
0x00, 0xe2, 0x6a, 0x59, 0x00, 0xe2, 0x6a, 0x59,
0x10, 0xa8, 0xbd, 0x7a, 0x10, 0x92, 0xbd, 0x7a,
0xff, 0xea, 0xdc, 0x5b, 0xff, 0xea, 0xdc, 0x5b,
0x00, 0xe2, 0xbc, 0x42, 0x00, 0xe2, 0xbc, 0x42,
0x04, 0xea, 0x50, 0x59, 0x04, 0xea, 0x50, 0x59,
...@@ -405,12 +405,12 @@ static uint8_t seqprog[] = { ...@@ -405,12 +405,12 @@ static uint8_t seqprog[] = {
0x04, 0xea, 0x50, 0x59, 0x04, 0xea, 0x50, 0x59,
0x04, 0xea, 0x04, 0x00, 0x04, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xf8, 0x41, 0x00, 0xe2, 0xf8, 0x41,
0x08, 0xa8, 0xb5, 0x7a, 0x08, 0x92, 0xb5, 0x7a,
0xc0, 0x33, 0x29, 0x7b, 0xc0, 0x33, 0x29, 0x7b,
0x80, 0x33, 0xb5, 0x6a, 0x80, 0x33, 0xb5, 0x6a,
0xff, 0x88, 0x29, 0x6b, 0xff, 0x88, 0x29, 0x6b,
0x40, 0x33, 0xb5, 0x6a, 0x40, 0x33, 0xb5, 0x6a,
0x10, 0xa8, 0x2f, 0x7b, 0x10, 0x92, 0x2f, 0x7b,
0x0a, 0xea, 0x50, 0x59, 0x0a, 0xea, 0x50, 0x59,
0x0a, 0xea, 0x04, 0x00, 0x0a, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x4e, 0x5b, 0x00, 0xe2, 0x4e, 0x5b,
...@@ -428,22 +428,22 @@ static uint8_t seqprog[] = { ...@@ -428,22 +428,22 @@ static uint8_t seqprog[] = {
0x33, 0xea, 0x44, 0x59, 0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00, 0x33, 0xea, 0x00, 0x00,
0x02, 0x42, 0x51, 0x31, 0x02, 0x42, 0x51, 0x31,
0xff, 0xae, 0x65, 0x68, 0xff, 0x90, 0x65, 0x68,
0xff, 0x88, 0x5b, 0x6b, 0xff, 0x88, 0x5b, 0x6b,
0x01, 0x9c, 0x57, 0x6b, 0x01, 0xa4, 0x57, 0x6b,
0x02, 0x9c, 0x5f, 0x6b, 0x02, 0xa4, 0x5f, 0x6b,
0x01, 0x84, 0x5f, 0x7b, 0x01, 0x84, 0x5f, 0x7b,
0x02, 0x28, 0x19, 0x33, 0x02, 0x28, 0x19, 0x33,
0x02, 0xa8, 0x50, 0x36, 0x02, 0xa8, 0x50, 0x36,
0xff, 0x88, 0x5f, 0x73, 0xff, 0x88, 0x5f, 0x73,
0x00, 0xe2, 0x32, 0x5b, 0x00, 0xe2, 0x32, 0x5b,
0x02, 0xa8, 0x5c, 0x33, 0x02, 0xa8, 0x20, 0x33,
0x02, 0x2c, 0x19, 0x33, 0x02, 0x2c, 0x19, 0x33,
0x02, 0xa8, 0x58, 0x32, 0x02, 0xa8, 0x58, 0x32,
0x04, 0x9c, 0x39, 0x07, 0x04, 0xa4, 0x49, 0x07,
0xc0, 0x33, 0xb5, 0x6a, 0xc0, 0x33, 0xb5, 0x6a,
0x04, 0xa8, 0x51, 0x03, 0x04, 0x92, 0x25, 0x03,
0x20, 0xa8, 0x83, 0x6b, 0x20, 0x92, 0x83, 0x6b,
0x02, 0xa8, 0x40, 0x31, 0x02, 0xa8, 0x40, 0x31,
0xc0, 0x34, 0xc1, 0x09, 0xc0, 0x34, 0xc1, 0x09,
0x00, 0x35, 0x51, 0x01, 0x00, 0x35, 0x51, 0x01,
...@@ -470,9 +470,9 @@ static uint8_t seqprog[] = { ...@@ -470,9 +470,9 @@ static uint8_t seqprog[] = {
0x00, 0xe2, 0x9e, 0x5b, 0x00, 0xe2, 0x9e, 0x5b,
0x00, 0xe2, 0xf8, 0x41, 0x00, 0xe2, 0xf8, 0x41,
0x01, 0x84, 0xa3, 0x7b, 0x01, 0x84, 0xa3, 0x7b,
0x01, 0x9c, 0x39, 0x07, 0x01, 0xa4, 0x49, 0x07,
0x08, 0x60, 0x20, 0x33, 0x08, 0x60, 0x30, 0x33,
0x08, 0x80, 0x31, 0x37, 0x08, 0x80, 0x41, 0x37,
0xdf, 0x33, 0x67, 0x0a, 0xdf, 0x33, 0x67, 0x0a,
0xee, 0x00, 0xb0, 0x6b, 0xee, 0x00, 0xb0, 0x6b,
0x05, 0xea, 0xb4, 0x00, 0x05, 0xea, 0xb4, 0x00,
...@@ -542,14 +542,14 @@ static uint8_t seqprog[] = { ...@@ -542,14 +542,14 @@ static uint8_t seqprog[] = {
0x01, 0xac, 0xd4, 0x99, 0x01, 0xac, 0xd4, 0x99,
0x00, 0xe2, 0x64, 0x50, 0x00, 0xe2, 0x64, 0x50,
0xfe, 0xa6, 0x4c, 0x0d, 0xfe, 0xa6, 0x4c, 0x0d,
0x0b, 0x90, 0xe1, 0x30, 0x0b, 0x98, 0xe1, 0x30,
0xfd, 0x9c, 0x49, 0x09, 0xfd, 0xa4, 0x49, 0x09,
0x80, 0x9b, 0x39, 0x7c, 0x80, 0xa3, 0x39, 0x7c,
0x02, 0xa4, 0x48, 0x01, 0x02, 0xa4, 0x48, 0x01,
0x01, 0xa4, 0x36, 0x30, 0x01, 0xa4, 0x36, 0x30,
0xa8, 0xea, 0x32, 0x00, 0xa8, 0xea, 0x32, 0x00,
0xfd, 0x9c, 0x39, 0x0b, 0xfd, 0xa4, 0x49, 0x0b,
0x05, 0x9b, 0x07, 0x33, 0x05, 0xa3, 0x07, 0x33,
0x80, 0x83, 0x45, 0x6c, 0x80, 0x83, 0x45, 0x6c,
0x02, 0xea, 0x4c, 0x05, 0x02, 0xea, 0x4c, 0x05,
0xff, 0xea, 0x4c, 0x0d, 0xff, 0xea, 0x4c, 0x0d,
...@@ -577,7 +577,7 @@ static uint8_t seqprog[] = { ...@@ -577,7 +577,7 @@ static uint8_t seqprog[] = {
0x09, 0xea, 0x50, 0x59, 0x09, 0xea, 0x50, 0x59,
0x09, 0xea, 0x04, 0x00, 0x09, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xf8, 0x41, 0x00, 0xe2, 0xf8, 0x41,
0x01, 0x9c, 0x5d, 0x6c, 0x01, 0xa4, 0x5d, 0x6c,
0x00, 0xe2, 0x30, 0x5c, 0x00, 0xe2, 0x30, 0x5c,
0x20, 0x33, 0x67, 0x02, 0x20, 0x33, 0x67, 0x02,
0x01, 0x00, 0x60, 0x32, 0x01, 0x00, 0x60, 0x32,
...@@ -646,15 +646,15 @@ static uint8_t seqprog[] = { ...@@ -646,15 +646,15 @@ static uint8_t seqprog[] = {
0x80, 0xf9, 0xea, 0x6c, 0x80, 0xf9, 0xea, 0x6c,
0xdf, 0x5c, 0xb8, 0x08, 0xdf, 0x5c, 0xb8, 0x08,
0x01, 0xd9, 0xb2, 0x05, 0x01, 0xd9, 0xb2, 0x05,
0x01, 0x9c, 0xe5, 0x6d, 0x01, 0xa4, 0xe5, 0x6d,
0x00, 0xe2, 0x30, 0x5c, 0x00, 0xe2, 0x30, 0x5c,
0x00, 0xe2, 0x34, 0x5d, 0x00, 0xe2, 0x34, 0x5d,
0x01, 0xae, 0x5d, 0x1b, 0x01, 0x90, 0x21, 0x1b,
0x01, 0xd9, 0xb2, 0x05, 0x01, 0xd9, 0xb2, 0x05,
0x00, 0xe2, 0x32, 0x5b, 0x00, 0xe2, 0x32, 0x5b,
0xf3, 0xac, 0xd5, 0x19, 0xf3, 0x96, 0xd5, 0x19,
0x00, 0xe2, 0x18, 0x55, 0x00, 0xe2, 0x18, 0x55,
0x80, 0xac, 0x19, 0x6d, 0x80, 0x96, 0x19, 0x6d,
0x0f, 0xea, 0x50, 0x59, 0x0f, 0xea, 0x50, 0x59,
0x0f, 0xea, 0x04, 0x00, 0x0f, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x20, 0x45, 0x00, 0xe2, 0x20, 0x45,
...@@ -662,7 +662,7 @@ static uint8_t seqprog[] = { ...@@ -662,7 +662,7 @@ static uint8_t seqprog[] = {
0x01, 0xea, 0xf2, 0x00, 0x01, 0xea, 0xf2, 0x00,
0x02, 0xea, 0x36, 0x00, 0x02, 0xea, 0x36, 0x00,
0xa8, 0xea, 0x32, 0x00, 0xa8, 0xea, 0x32, 0x00,
0xff, 0xad, 0x27, 0x7d, 0xff, 0x97, 0x27, 0x7d,
0x14, 0xea, 0x50, 0x59, 0x14, 0xea, 0x50, 0x59,
0x14, 0xea, 0x04, 0x00, 0x14, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x96, 0x5d, 0x00, 0xe2, 0x96, 0x5d,
...@@ -700,10 +700,10 @@ static uint8_t seqprog[] = { ...@@ -700,10 +700,10 @@ static uint8_t seqprog[] = {
0x01, 0x1a, 0x64, 0x78, 0x01, 0x1a, 0x64, 0x78,
0x80, 0xf9, 0xf2, 0x01, 0x80, 0xf9, 0xf2, 0x01,
0x20, 0xa0, 0xcc, 0x7d, 0x20, 0xa0, 0xcc, 0x7d,
0xff, 0xae, 0x5d, 0x1b, 0xff, 0x90, 0x21, 0x1b,
0x08, 0xa8, 0x43, 0x6b, 0x08, 0x92, 0x43, 0x6b,
0x02, 0xea, 0xb4, 0x04, 0x02, 0xea, 0xb4, 0x04,
0x01, 0x9c, 0x39, 0x03, 0x01, 0xa4, 0x49, 0x03,
0x40, 0x5b, 0x82, 0x6d, 0x40, 0x5b, 0x82, 0x6d,
0x00, 0xe2, 0x3e, 0x59, 0x00, 0xe2, 0x3e, 0x59,
0x40, 0x5b, 0x82, 0x6d, 0x40, 0x5b, 0x82, 0x6d,
...@@ -714,8 +714,8 @@ static uint8_t seqprog[] = { ...@@ -714,8 +714,8 @@ static uint8_t seqprog[] = {
0x04, 0x5d, 0xe6, 0x7d, 0x04, 0x5d, 0xe6, 0x7d,
0x01, 0x1a, 0xe6, 0x7d, 0x01, 0x1a, 0xe6, 0x7d,
0x80, 0xf9, 0xf2, 0x01, 0x80, 0xf9, 0xf2, 0x01,
0xff, 0xae, 0x5d, 0x1b, 0xff, 0x90, 0x21, 0x1b,
0x08, 0xa8, 0x43, 0x6b, 0x08, 0x92, 0x43, 0x6b,
0x02, 0xea, 0xb4, 0x04, 0x02, 0xea, 0xb4, 0x04,
0x00, 0xe2, 0x3e, 0x59, 0x00, 0xe2, 0x3e, 0x59,
0x01, 0x1b, 0x64, 0x78, 0x01, 0x1b, 0x64, 0x78,
...@@ -729,7 +729,7 @@ static uint8_t seqprog[] = { ...@@ -729,7 +729,7 @@ static uint8_t seqprog[] = {
0x01, 0x1a, 0x64, 0x78, 0x01, 0x1a, 0x64, 0x78,
0x80, 0xf9, 0xf2, 0x01, 0x80, 0xf9, 0xf2, 0x01,
0xff, 0xea, 0x10, 0x03, 0xff, 0xea, 0x10, 0x03,
0x08, 0xa8, 0x51, 0x03, 0x08, 0x92, 0x25, 0x03,
0x00, 0xe2, 0x42, 0x43, 0x00, 0xe2, 0x42, 0x43,
0x01, 0x1a, 0xb4, 0x7d, 0x01, 0x1a, 0xb4, 0x7d,
0x40, 0x5b, 0xb0, 0x7d, 0x40, 0x5b, 0xb0, 0x7d,
...@@ -743,14 +743,14 @@ static uint8_t seqprog[] = { ...@@ -743,14 +743,14 @@ static uint8_t seqprog[] = {
0x20, 0x4d, 0x64, 0x78, 0x20, 0x4d, 0x64, 0x78,
0x40, 0x5b, 0x9e, 0x6d, 0x40, 0x5b, 0x9e, 0x6d,
0x01, 0x1a, 0x64, 0x78, 0x01, 0x1a, 0x64, 0x78,
0x01, 0xae, 0x5d, 0x1b, 0x01, 0x90, 0x21, 0x1b,
0x30, 0x3f, 0xc0, 0x09, 0x30, 0x3f, 0xc0, 0x09,
0x30, 0xe0, 0x64, 0x60, 0x30, 0xe0, 0x64, 0x60,
0x40, 0x4b, 0x64, 0x68, 0x40, 0x4b, 0x64, 0x68,
0xff, 0xea, 0x52, 0x01, 0xff, 0xea, 0x52, 0x01,
0xee, 0x00, 0xd2, 0x6d, 0xee, 0x00, 0xd2, 0x6d,
0x80, 0xf9, 0xf2, 0x01, 0x80, 0xf9, 0xf2, 0x01,
0xff, 0xae, 0x5d, 0x1b, 0xff, 0x90, 0x21, 0x1b,
0x02, 0xea, 0xb4, 0x00, 0x02, 0xea, 0xb4, 0x00,
0x20, 0xea, 0x9a, 0x00, 0x20, 0xea, 0x9a, 0x00,
0xf3, 0x42, 0xde, 0x6d, 0xf3, 0x42, 0xde, 0x6d,
...@@ -760,7 +760,7 @@ static uint8_t seqprog[] = { ...@@ -760,7 +760,7 @@ static uint8_t seqprog[] = {
0x0d, 0xea, 0x50, 0x59, 0x0d, 0xea, 0x50, 0x59,
0x0d, 0xea, 0x04, 0x00, 0x0d, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xf8, 0x41, 0x00, 0xe2, 0xf8, 0x41,
0x01, 0xae, 0x5d, 0x1b, 0x01, 0x90, 0x21, 0x1b,
0x11, 0xea, 0x50, 0x59, 0x11, 0xea, 0x50, 0x59,
0x11, 0xea, 0x04, 0x00, 0x11, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x32, 0x5b, 0x00, 0xe2, 0x32, 0x5b,
...@@ -776,9 +776,9 @@ static uint8_t seqprog[] = { ...@@ -776,9 +776,9 @@ static uint8_t seqprog[] = {
0x20, 0x4d, 0x64, 0x78, 0x20, 0x4d, 0x64, 0x78,
0x02, 0x84, 0x09, 0x03, 0x02, 0x84, 0x09, 0x03,
0x40, 0x5b, 0xcc, 0x7d, 0x40, 0x5b, 0xcc, 0x7d,
0xff, 0xae, 0x5d, 0x1b, 0xff, 0x90, 0x21, 0x1b,
0x80, 0xf9, 0xf2, 0x01, 0x80, 0xf9, 0xf2, 0x01,
0x08, 0xa8, 0x43, 0x6b, 0x08, 0x92, 0x43, 0x6b,
0x02, 0xea, 0xb4, 0x04, 0x02, 0xea, 0xb4, 0x04,
0x01, 0x38, 0xe1, 0x30, 0x01, 0x38, 0xe1, 0x30,
0x05, 0x39, 0xe3, 0x98, 0x05, 0x39, 0xe3, 0x98,
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#77 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#79 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -1143,17 +1143,17 @@ struct ahc_pci_identity { ...@@ -1143,17 +1143,17 @@ struct ahc_pci_identity {
char *name; char *name;
ahc_device_setup_t *setup; ahc_device_setup_t *setup;
}; };
extern struct ahc_pci_identity ahc_pci_ident_table []; extern struct ahc_pci_identity ahc_pci_ident_table[];
extern const u_int ahc_num_pci_devs; extern const u_int ahc_num_pci_devs;
/***************************** VL/EISA Declarations ***************************/ /***************************** VL/EISA Declarations ***************************/
struct aic7770_identity { struct aic7770_identity {
uint32_t full_id; uint32_t full_id;
uint32_t id_mask; uint32_t id_mask;
char *name; const char *name;
ahc_device_setup_t *setup; ahc_device_setup_t *setup;
}; };
extern struct aic7770_identity aic7770_ident_table []; extern struct aic7770_identity aic7770_ident_table[];
extern const int ahc_num_aic7770_devs; extern const int ahc_num_aic7770_devs;
#define AHC_EISA_SLOT_OFFSET 0xc00 #define AHC_EISA_SLOT_OFFSET 0xc00
...@@ -1205,7 +1205,7 @@ void ahc_set_unit(struct ahc_softc *, int); ...@@ -1205,7 +1205,7 @@ void ahc_set_unit(struct ahc_softc *, int);
void ahc_set_name(struct ahc_softc *, char *); void ahc_set_name(struct ahc_softc *, char *);
void ahc_alloc_scbs(struct ahc_softc *ahc); void ahc_alloc_scbs(struct ahc_softc *ahc);
void ahc_free(struct ahc_softc *ahc); void ahc_free(struct ahc_softc *ahc);
int ahc_reset(struct ahc_softc *ahc); int ahc_reset(struct ahc_softc *ahc, int reinit);
void ahc_shutdown(void *arg); void ahc_shutdown(void *arg);
/*************************** Interrupt Services *******************************/ /*************************** Interrupt Services *******************************/
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#131 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#134 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -1304,17 +1304,23 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat) ...@@ -1304,17 +1304,23 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
ahc_qinfifo_requeue_tail(ahc, scb); ahc_qinfifo_requeue_tail(ahc, scb);
printerror = 0; printerror = 0;
} else if (ahc_sent_msg(ahc, AHCMSG_EXT, } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
MSG_EXT_WDTR, FALSE) MSG_EXT_WDTR, FALSE)) {
|| ahc_sent_msg(ahc, AHCMSG_EXT,
MSG_EXT_SDTR, FALSE)) {
/* /*
* Negotiation Rejected. Go-async and * Negotiation Rejected. Go-narrow and
* retry command. * retry command.
*/ */
ahc_set_width(ahc, &devinfo, ahc_set_width(ahc, &devinfo,
MSG_EXT_WDTR_BUS_8_BIT, MSG_EXT_WDTR_BUS_8_BIT,
AHC_TRANS_CUR|AHC_TRANS_GOAL, AHC_TRANS_CUR|AHC_TRANS_GOAL,
/*paused*/TRUE); /*paused*/TRUE);
ahc_qinfifo_requeue_tail(ahc, scb);
printerror = 0;
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
MSG_EXT_SDTR, FALSE)) {
/*
* Negotiation Rejected. Go-async and
* retry command.
*/
ahc_set_syncrate(ahc, &devinfo, ahc_set_syncrate(ahc, &devinfo,
/*syncrate*/NULL, /*syncrate*/NULL,
/*period*/0, /*offset*/0, /*period*/0, /*offset*/0,
...@@ -1463,7 +1469,7 @@ ahc_clear_critical_section(struct ahc_softc *ahc) ...@@ -1463,7 +1469,7 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
* current connection, so we must * current connection, so we must
* leave it on while single stepping. * leave it on while single stepping.
*/ */
ahc_outb(ahc, SIMODE1, ENBUSFREE); ahc_outb(ahc, SIMODE1, simode1 & ENBUSFREE);
else else
ahc_outb(ahc, SIMODE1, 0); ahc_outb(ahc, SIMODE1, 0);
ahc_outb(ahc, CLRINT, CLRSCSIINT); ahc_outb(ahc, CLRINT, CLRSCSIINT);
...@@ -2373,6 +2379,7 @@ ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) ...@@ -2373,6 +2379,7 @@ ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
* may change. * may change.
*/ */
period = tinfo->goal.period; period = tinfo->goal.period;
offset = tinfo->goal.offset;
ppr_options = tinfo->goal.ppr_options; ppr_options = tinfo->goal.ppr_options;
/* Target initiated PPR is not allowed in the SCSI spec */ /* Target initiated PPR is not allowed in the SCSI spec */
if (devinfo->role == ROLE_TARGET) if (devinfo->role == ROLE_TARGET)
...@@ -2380,7 +2387,7 @@ ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) ...@@ -2380,7 +2387,7 @@ ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
rate = ahc_devlimited_syncrate(ahc, tinfo, &period, rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
&ppr_options, devinfo->role); &ppr_options, devinfo->role);
dowide = tinfo->curr.width != tinfo->goal.width; dowide = tinfo->curr.width != tinfo->goal.width;
dosync = tinfo->curr.period != period; dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
/* /*
* Only use PPR if we have options that need it, even if the device * Only use PPR if we have options that need it, even if the device
* claims to support it. There might be an expander in the way * claims to support it. There might be an expander in the way
...@@ -3176,23 +3183,30 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) ...@@ -3176,23 +3183,30 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
response = TRUE; response = TRUE;
sending_reply = TRUE; sending_reply = TRUE;
} }
/*
* After a wide message, we are async, but
* some devices don't seem to honor this portion
* of the spec. Force a renegotiation of the
* sync component of our transfer agreement even
* if our goal is async. By updating our width
* after forcing the negotiation, we avoid
* renegotiating for width.
*/
ahc_update_neg_request(ahc, devinfo, tstate,
tinfo, AHC_NEG_ALWAYS);
ahc_set_width(ahc, devinfo, bus_width, ahc_set_width(ahc, devinfo, bus_width,
AHC_TRANS_ACTIVE|AHC_TRANS_GOAL, AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
/*paused*/TRUE); /*paused*/TRUE);
/* After a wide message, we are async */
ahc_set_syncrate(ahc, devinfo,
/*syncrate*/NULL, /*period*/0,
/*offset*/0, /*ppr_options*/0,
AHC_TRANS_ACTIVE, /*paused*/TRUE);
if (sending_reply == FALSE && reject == FALSE) { if (sending_reply == FALSE && reject == FALSE) {
if (tinfo->goal.offset) { /*
ahc->msgout_index = 0; * We will always have an SDTR to send.
ahc->msgout_len = 0; */
ahc_build_transfer_msg(ahc, devinfo); ahc->msgout_index = 0;
ahc->msgout_index = 0; ahc->msgout_len = 0;
response = TRUE; ahc_build_transfer_msg(ahc, devinfo);
} ahc->msgout_index = 0;
response = TRUE;
} }
done = MSGLOOP_MSGCOMPLETE; done = MSGLOOP_MSGCOMPLETE;
break; break;
...@@ -4033,7 +4047,7 @@ ahc_shutdown(void *arg) ...@@ -4033,7 +4047,7 @@ ahc_shutdown(void *arg)
ahc = (struct ahc_softc *)arg; ahc = (struct ahc_softc *)arg;
/* This will reset most registers to 0, but not all */ /* This will reset most registers to 0, but not all */
ahc_reset(ahc); ahc_reset(ahc, /*reinit*/FALSE);
ahc_outb(ahc, SCSISEQ, 0); ahc_outb(ahc, SCSISEQ, 0);
ahc_outb(ahc, SXFRCTL0, 0); ahc_outb(ahc, SXFRCTL0, 0);
ahc_outb(ahc, DSPCISTATUS, 0); ahc_outb(ahc, DSPCISTATUS, 0);
...@@ -4044,10 +4058,15 @@ ahc_shutdown(void *arg) ...@@ -4044,10 +4058,15 @@ ahc_shutdown(void *arg)
/* /*
* Reset the controller and record some information about it * Reset the controller and record some information about it
* that is only available just after a reset. * that is only available just after a reset. If "reinit" is
* non-zero, this reset occured after initial configuration
* and the caller requests that the chip be fully reinitialized
* to a runable state. Chip interrupts are *not* enabled after
* a reinitialization. The caller must enable interrupts via
* ahc_intr_enable().
*/ */
int int
ahc_reset(struct ahc_softc *ahc) ahc_reset(struct ahc_softc *ahc, int reinit)
{ {
u_int sblkctl; u_int sblkctl;
u_int sxfrctl1_a, sxfrctl1_b; u_int sxfrctl1_a, sxfrctl1_b;
...@@ -4143,7 +4162,7 @@ ahc_reset(struct ahc_softc *ahc) ...@@ -4143,7 +4162,7 @@ ahc_reset(struct ahc_softc *ahc)
ahc_outb(ahc, SXFRCTL1, sxfrctl1_a); ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
error = 0; error = 0;
if (ahc->init_level > 0) if (reinit != 0)
/* /*
* If a recovery action has forced a chip reset, * If a recovery action has forced a chip reset,
* re-initialize the chip to our liking. * re-initialize the chip to our liking.
...@@ -4725,14 +4744,12 @@ ahc_chip_init(struct ahc_softc *ahc) ...@@ -4725,14 +4744,12 @@ ahc_chip_init(struct ahc_softc *ahc)
* never settle, so don't complain if we * never settle, so don't complain if we
* fail here. * fail here.
*/ */
ahc_pause(ahc);
for (wait = 5000; for (wait = 5000;
(ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait; (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
wait--) wait--)
ahc_delay(100); ahc_delay(100);
ahc_unpause(ahc);
} }
ahc_restart(ahc);
return (0); return (0);
} }
...@@ -5145,7 +5162,9 @@ int ...@@ -5145,7 +5162,9 @@ int
ahc_resume(struct ahc_softc *ahc) ahc_resume(struct ahc_softc *ahc)
{ {
ahc_reset(ahc); ahc_reset(ahc, /*reinit*/TRUE);
ahc_intr_enable(ahc, TRUE);
ahc_restart(ahc);
return (0); return (0);
} }
...@@ -6407,7 +6426,6 @@ ahc_loadseq(struct ahc_softc *ahc) ...@@ -6407,7 +6426,6 @@ ahc_loadseq(struct ahc_softc *ahc)
memcpy(ahc->critical_sections, cs_table, cs_count); memcpy(ahc->critical_sections, cs_table, cs_count);
} }
ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE); ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
ahc_restart(ahc);
if (bootverbose) { if (bootverbose) {
printf(" %d instructions downloaded\n", downloaded); printf(" %d instructions downloaded\n", downloaded);
...@@ -6968,11 +6986,12 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb) ...@@ -6968,11 +6986,12 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
*/ */
ahc->flags = saved_flags; ahc->flags = saved_flags;
(void)ahc_loadseq(ahc); (void)ahc_loadseq(ahc);
ahc_unpause(ahc); ahc_restart(ahc);
ahc_unlock(ahc, &s); ahc_unlock(ahc, &s);
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
return; return;
} }
ahc_restart(ahc);
ahc_unlock(ahc, &s); ahc_unlock(ahc, &s);
} }
cel = &ccb->cel; cel = &ccb->cel;
...@@ -7207,12 +7226,16 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb) ...@@ -7207,12 +7226,16 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
printf("Configuring Initiator Mode\n"); printf("Configuring Initiator Mode\n");
ahc->flags &= ~AHC_TARGETROLE; ahc->flags &= ~AHC_TARGETROLE;
ahc->flags |= AHC_INITIATORROLE; ahc->flags |= AHC_INITIATORROLE;
ahc_pause(ahc);
/* /*
* Returning to a configuration that * Returning to a configuration that
* fit previously will always succeed. * fit previously will always succeed.
*/ */
(void)ahc_loadseq(ahc); (void)ahc_loadseq(ahc);
ahc_restart(ahc);
/*
* Unpaused. The extra unpause
* that follows is harmless.
*/
} }
} }
ahc_unpause(ahc); ahc_unpause(ahc);
......
/* /*
* Adaptec AIC7xxx device driver for Linux. * Adaptec AIC7xxx device driver for Linux.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#232 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#235 $
* *
* Copyright (c) 1994 John Aycock * Copyright (c) 1994 John Aycock
* The University of Calgary Department of Computer Science. * The University of Calgary Department of Computer Science.
...@@ -293,7 +293,7 @@ static adapter_tag_info_t aic7xxx_tag_info[] = ...@@ -293,7 +293,7 @@ static adapter_tag_info_t aic7xxx_tag_info[] =
#define AIC7XXX_CONFIGED_DV -1 #define AIC7XXX_CONFIGED_DV -1
#endif #endif
static uint8_t aic7xxx_dv_settings[] = static int8_t aic7xxx_dv_settings[] =
{ {
AIC7XXX_CONFIGED_DV, AIC7XXX_CONFIGED_DV,
AIC7XXX_CONFIGED_DV, AIC7XXX_CONFIGED_DV,
...@@ -391,9 +391,9 @@ static uint32_t aic7xxx_pci_parity = ~0; ...@@ -391,9 +391,9 @@ static uint32_t aic7xxx_pci_parity = ~0;
* would result in never finding any devices :) * would result in never finding any devices :)
*/ */
#ifndef CONFIG_AIC7XXX_PROBE_EISA_VL #ifndef CONFIG_AIC7XXX_PROBE_EISA_VL
static uint32_t aic7xxx_probe_eisa_vl; uint32_t aic7xxx_probe_eisa_vl;
#else #else
static uint32_t aic7xxx_probe_eisa_vl = ~0; uint32_t aic7xxx_probe_eisa_vl = ~0;
#endif #endif
/* /*
...@@ -752,7 +752,6 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, ...@@ -752,7 +752,6 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
/************************ Host template entry points *************************/ /************************ Host template entry points *************************/
static int ahc_linux_detect(Scsi_Host_Template *); static int ahc_linux_detect(Scsi_Host_Template *);
static int ahc_linux_release(struct Scsi_Host *);
static int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); static int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
static const char *ahc_linux_info(struct Scsi_Host *); static const char *ahc_linux_info(struct Scsi_Host *);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
...@@ -765,6 +764,7 @@ static int ahc_linux_biosparam(struct scsi_device*, ...@@ -765,6 +764,7 @@ static int ahc_linux_biosparam(struct scsi_device*,
sector_t, int[]); sector_t, int[]);
#endif #endif
#else #else
static int ahc_linux_release(struct Scsi_Host *);
static void ahc_linux_select_queue_depth(struct Scsi_Host *host, static void ahc_linux_select_queue_depth(struct Scsi_Host *host,
Scsi_Device *scsi_devs); Scsi_Device *scsi_devs);
#if defined(__i386__) #if defined(__i386__)
...@@ -895,8 +895,9 @@ ahc_linux_detect(Scsi_Host_Template *template) ...@@ -895,8 +895,9 @@ ahc_linux_detect(Scsi_Host_Template *template)
ahc_linux_pci_init(); ahc_linux_pci_init();
#endif #endif
if (aic7xxx_probe_eisa_vl != 0) #ifdef CONFIG_EISA
aic7770_linux_probe(template); ahc_linux_eisa_init();
#endif
/* /*
* Register with the SCSI layer all * Register with the SCSI layer all
...@@ -915,6 +916,7 @@ ahc_linux_detect(Scsi_Host_Template *template) ...@@ -915,6 +916,7 @@ ahc_linux_detect(Scsi_Host_Template *template)
return (found); return (found);
} }
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/* /*
* Free the passed in Scsi_Host memory structures prior to unloading the * Free the passed in Scsi_Host memory structures prior to unloading the
* module. * module.
...@@ -946,6 +948,7 @@ ahc_linux_release(struct Scsi_Host * host) ...@@ -946,6 +948,7 @@ ahc_linux_release(struct Scsi_Host * host)
ahc_list_unlock(&l); ahc_list_unlock(&l);
return (0); return (0);
} }
#endif
/* /*
* Return a string describing the driver. * Return a string describing the driver.
...@@ -4137,6 +4140,16 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) ...@@ -4137,6 +4140,16 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
} }
#endif #endif
ahc_set_transaction_status(scb, CAM_UNCOR_PARITY); ahc_set_transaction_status(scb, CAM_UNCOR_PARITY);
#ifdef AHC_REPORT_UNDERFLOWS
/*
* This code is disabled by default as some
* clients of the SCSI system do not properly
* initialize the underflow parameter. This
* results in spurious termination of commands
* that complete as expected (e.g. underflow is
* allowed as command can return variable amounts
* of data.
*/
} else if (amount_xferred < scb->io_ctx->underflow) { } else if (amount_xferred < scb->io_ctx->underflow) {
u_int i; u_int i;
...@@ -4151,6 +4164,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) ...@@ -4151,6 +4164,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
ahc_get_residual(scb), ahc_get_residual(scb),
ahc_get_transfer_length(scb)); ahc_get_transfer_length(scb));
ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR); ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
#endif
} else { } else {
ahc_set_transaction_status(scb, CAM_REQ_CMP); ahc_set_transaction_status(scb, CAM_REQ_CMP);
} }
...@@ -5082,27 +5096,21 @@ ahc_linux_exit(void) ...@@ -5082,27 +5096,21 @@ ahc_linux_exit(void)
ahc_linux_kill_dv_thread(ahc); ahc_linux_kill_dv_thread(ahc);
} }
ahc_list_unlock(&l); ahc_list_unlock(&l);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahc_linux_pci_exit();
/*
* Get rid of the non-pci devices.
*
* XXX(hch): switch over eisa support to new LDM-based API
*/
TAILQ_FOREACH(ahc, &ahc_tailq, links)
ahc_linux_release(ahc->platform_data->host);
#else
scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/* /*
* In 2.4 we have to unregister from the PCI core _after_ * In 2.4 we have to unregister from the PCI core _after_
* unregistering from the scsi midlayer to avoid dangling * unregistering from the scsi midlayer to avoid dangling
* references. * references.
*/ */
scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
#endif
#ifdef CONFIG_PCI
ahc_linux_pci_exit(); ahc_linux_pci_exit();
#endif #endif
#ifdef CONFIG_EISA
ahc_linux_eisa_exit();
#endif
} }
module_init(ahc_linux_init); module_init(ahc_linux_init);
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#147 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#151 $
* *
*/ */
#ifndef _AIC7XXX_LINUX_H_ #ifndef _AIC7XXX_LINUX_H_
...@@ -304,7 +304,7 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec) ...@@ -304,7 +304,7 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec)
#define AHC_SCSI_HAS_HOST_LOCK 0 #define AHC_SCSI_HAS_HOST_LOCK 0
#endif #endif
#define AIC7XXX_DRIVER_VERSION "6.2.35" #define AIC7XXX_DRIVER_VERSION "6.2.36"
/**************************** Front End Queues ********************************/ /**************************** Front End Queues ********************************/
/* /*
...@@ -595,10 +595,6 @@ ahc_delay(long usec) ...@@ -595,10 +595,6 @@ ahc_delay(long usec)
/***************************** Low Level I/O **********************************/ /***************************** Low Level I/O **********************************/
#if defined(__powerpc__) || defined(__i386__) || defined(__ia64__)
#define MMAPIO
#endif
static __inline uint8_t ahc_inb(struct ahc_softc * ahc, long port); static __inline uint8_t ahc_inb(struct ahc_softc * ahc, long port);
static __inline void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val); static __inline void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val);
static __inline void ahc_outsb(struct ahc_softc * ahc, long port, static __inline void ahc_outsb(struct ahc_softc * ahc, long port,
...@@ -610,16 +606,12 @@ static __inline uint8_t ...@@ -610,16 +606,12 @@ static __inline uint8_t
ahc_inb(struct ahc_softc * ahc, long port) ahc_inb(struct ahc_softc * ahc, long port)
{ {
uint8_t x; uint8_t x;
#ifdef MMAPIO
if (ahc->tag == BUS_SPACE_MEMIO) { if (ahc->tag == BUS_SPACE_MEMIO) {
x = readb(ahc->bsh.maddr + port); x = readb(ahc->bsh.maddr + port);
} else { } else {
x = inb(ahc->bsh.ioport + port); x = inb(ahc->bsh.ioport + port);
} }
#else
x = inb(ahc->bsh.ioport + port);
#endif
mb(); mb();
return (x); return (x);
} }
...@@ -627,15 +619,11 @@ ahc_inb(struct ahc_softc * ahc, long port) ...@@ -627,15 +619,11 @@ ahc_inb(struct ahc_softc * ahc, long port)
static __inline void static __inline void
ahc_outb(struct ahc_softc * ahc, long port, uint8_t val) ahc_outb(struct ahc_softc * ahc, long port, uint8_t val)
{ {
#ifdef MMAPIO
if (ahc->tag == BUS_SPACE_MEMIO) { if (ahc->tag == BUS_SPACE_MEMIO) {
writeb(val, ahc->bsh.maddr + port); writeb(val, ahc->bsh.maddr + port);
} else { } else {
outb(val, ahc->bsh.ioport + port); outb(val, ahc->bsh.ioport + port);
} }
#else
outb(val, ahc->bsh.ioport + port);
#endif
mb(); mb();
} }
...@@ -843,15 +831,26 @@ typedef enum ...@@ -843,15 +831,26 @@ typedef enum
AHC_POWER_STATE_D3 AHC_POWER_STATE_D3
} ahc_power_state; } ahc_power_state;
void ahc_power_state_change(struct ahc_softc *ahc,
ahc_power_state new_state);
/**************************** VL/EISA Routines ********************************/ /**************************** VL/EISA Routines ********************************/
int aic7770_linux_probe(Scsi_Host_Template *); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \
&& (defined(__i386__) || defined(__alpha__)) \
&& (!defined(CONFIG_EISA)))
#define CONFIG_EISA
#endif
#ifdef CONFIG_EISA
extern uint32_t aic7xxx_probe_eisa_vl;
void ahc_linux_eisa_init(void);
void ahc_linux_eisa_exit(void);
int aic7770_map_registers(struct ahc_softc *ahc, int aic7770_map_registers(struct ahc_softc *ahc,
u_int port); u_int port);
int aic7770_map_int(struct ahc_softc *ahc, u_int irq); int aic7770_map_int(struct ahc_softc *ahc, u_int irq);
#endif
/******************************* PCI Routines *********************************/ /******************************* PCI Routines *********************************/
#ifdef CONFIG_PCI
void ahc_power_state_change(struct ahc_softc *ahc,
ahc_power_state new_state);
int ahc_linux_pci_init(void); int ahc_linux_pci_init(void);
void ahc_linux_pci_exit(void); void ahc_linux_pci_exit(void);
int ahc_pci_map_registers(struct ahc_softc *ahc); int ahc_pci_map_registers(struct ahc_softc *ahc);
...@@ -933,6 +932,7 @@ ahc_get_pci_bus(ahc_dev_softc_t pci) ...@@ -933,6 +932,7 @@ ahc_get_pci_bus(ahc_dev_softc_t pci)
{ {
return (pci->bus->number); return (pci->bus->number);
} }
#endif
static __inline void ahc_flush_device_writes(struct ahc_softc *); static __inline void ahc_flush_device_writes(struct ahc_softc *);
static __inline void static __inline void
...@@ -962,7 +962,12 @@ ahc_flush_device_writes(struct ahc_softc *ahc) ...@@ -962,7 +962,12 @@ ahc_flush_device_writes(struct ahc_softc *ahc)
(((dev_softc)->dma_mask = mask) && 0) (((dev_softc)->dma_mask = mask) && 0)
#endif #endif
/**************************** Proc FS Support *********************************/ /**************************** Proc FS Support *********************************/
int ahc_linux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
int ahc_linux_proc_info(char *, char **, off_t, int, int, int);
#else
int ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
off_t, int, int);
#endif
/*************************** Domain Validation ********************************/ /*************************** Domain Validation ********************************/
#define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete) #define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete)
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#45 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#47 $
*/ */
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
...@@ -51,11 +51,9 @@ static int ahc_linux_pci_dev_probe(struct pci_dev *pdev, ...@@ -51,11 +51,9 @@ static int ahc_linux_pci_dev_probe(struct pci_dev *pdev,
const struct pci_device_id *ent); const struct pci_device_id *ent);
static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc,
u_long *base); u_long *base);
#ifdef MMAPIO
static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
u_long *bus_addr, u_long *bus_addr,
uint8_t **maddr); uint8_t **maddr);
#endif /* MMAPIO */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
static void ahc_linux_pci_dev_remove(struct pci_dev *pdev); static void ahc_linux_pci_dev_remove(struct pci_dev *pdev);
...@@ -161,7 +159,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -161,7 +159,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
} }
pci_set_master(pdev); pci_set_master(pdev);
mask_39bit = (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0); mask_39bit = (bus_addr_t)0x7FFFFFFFFFULL;
if (sizeof(bus_addr_t) > 4 if (sizeof(bus_addr_t) > 4
&& ahc_linux_get_memsize() > 0x80000000 && ahc_linux_get_memsize() > 0x80000000
&& ahc_pci_set_dma_mask(pdev, mask_39bit) == 0) { && ahc_pci_set_dma_mask(pdev, mask_39bit) == 0) {
...@@ -254,7 +252,6 @@ ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base) ...@@ -254,7 +252,6 @@ ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base)
return (0); return (0);
} }
#ifdef MMAPIO
static int static int
ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
u_long *bus_addr, u_long *bus_addr,
...@@ -296,7 +293,6 @@ ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, ...@@ -296,7 +293,6 @@ ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
error = ENOMEM; error = ENOMEM;
return (error); return (error);
} }
#endif /* MMAPIO */
int int
ahc_pci_map_registers(struct ahc_softc *ahc) ahc_pci_map_registers(struct ahc_softc *ahc)
...@@ -313,7 +309,6 @@ ahc_pci_map_registers(struct ahc_softc *ahc) ...@@ -313,7 +309,6 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN); command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
base = 0; base = 0;
maddr = NULL; maddr = NULL;
#ifdef MMAPIO
error = ahc_linux_pci_reserve_mem_region(ahc, &base, &maddr); error = ahc_linux_pci_reserve_mem_region(ahc, &base, &maddr);
if (error == 0) { if (error == 0) {
ahc->platform_data->mem_busaddr = base; ahc->platform_data->mem_busaddr = base;
...@@ -350,7 +345,6 @@ ahc_pci_map_registers(struct ahc_softc *ahc) ...@@ -350,7 +345,6 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
ahc_get_pci_function(ahc->dev_softc), ahc_get_pci_function(ahc->dev_softc),
base); base);
} }
#endif /* MMAPIO */
/* /*
* We always prefer memory mapped access. * We always prefer memory mapped access.
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#66 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#69 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -76,7 +76,7 @@ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) ...@@ -76,7 +76,7 @@ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
#define ID_9005_SISL_MASK 0x000FFFFF00000000ull #define ID_9005_SISL_MASK 0x000FFFFF00000000ull
#define ID_9005_SISL_ID 0x0005900500000000ull #define ID_9005_SISL_ID 0x0005900500000000ull
#define ID_AIC7850 0x5078900400000000ull #define ID_AIC7850 0x5078900400000000ull
#define ID_AHA_2902_04_10_15_20_30C 0x5078900478509004ull #define ID_AHA_2902_04_10_15_20C_30C 0x5078900478509004ull
#define ID_AIC7855 0x5578900400000000ull #define ID_AIC7855 0x5578900400000000ull
#define ID_AIC7859 0x3860900400000000ull #define ID_AIC7859 0x3860900400000000ull
#define ID_AHA_2930CU 0x3860900438699004ull #define ID_AHA_2930CU 0x3860900438699004ull
...@@ -245,9 +245,9 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ...@@ -245,9 +245,9 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
{ {
/* aic7850 based controllers */ /* aic7850 based controllers */
{ {
ID_AHA_2902_04_10_15_20_30C, ID_AHA_2902_04_10_15_20C_30C,
ID_ALL_MASK, ID_ALL_MASK,
"Adaptec 2902/04/10/15/20/30C SCSI adapter", "Adaptec 2902/04/10/15/20C/30C SCSI adapter",
ahc_aic785X_setup ahc_aic785X_setup
}, },
/* aic7860 based controllers */ /* aic7860 based controllers */
...@@ -877,7 +877,7 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) ...@@ -877,7 +877,7 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
scsiseq = 0; scsiseq = 0;
} }
error = ahc_reset(ahc); error = ahc_reset(ahc, /*reinit*/FALSE);
if (error != 0) if (error != 0)
return (ENXIO); return (ENXIO);
...@@ -1289,6 +1289,14 @@ ahc_pci_test_register_access(struct ahc_softc *ahc) ...@@ -1289,6 +1289,14 @@ ahc_pci_test_register_access(struct ahc_softc *ahc)
ahc_outb(ahc, HCNTRL, hcntrl|PAUSE); ahc_outb(ahc, HCNTRL, hcntrl|PAUSE);
while (ahc_is_paused(ahc) == 0) while (ahc_is_paused(ahc) == 0)
; ;
/* Clear any PCI errors that occurred before our driver attached. */
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);
ahc_outb(ahc, SEQCTL, PERRORDIS); ahc_outb(ahc, SEQCTL, PERRORDIS);
ahc_outb(ahc, SCBPTR, 0); ahc_outb(ahc, SCBPTR, 0);
ahc_outl(ahc, SCB_BASE, 0x5aa555aa); ahc_outl(ahc, SCB_BASE, 0x5aa555aa);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr> * String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
* sym driver. * sym driver.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#27 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#29 $
*/ */
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
#include "aic7xxx_inline.h" #include "aic7xxx_inline.h"
...@@ -289,8 +289,13 @@ ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length) ...@@ -289,8 +289,13 @@ ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length)
* Return information to handle /proc support for the driver. * Return information to handle /proc support for the driver.
*/ */
int int
ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
int length, int inout) ahc_linux_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout)
#else
ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
off_t offset, int length, int inout)
#endif
{ {
struct ahc_softc *ahc; struct ahc_softc *ahc;
struct info_str info; struct info_str info;
...@@ -302,10 +307,14 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t o ...@@ -302,10 +307,14 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t o
retval = -EINVAL; retval = -EINVAL;
ahc_list_lock(&s); ahc_list_lock(&s);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
TAILQ_FOREACH(ahc, &ahc_tailq, links) { TAILQ_FOREACH(ahc, &ahc_tailq, links) {
if (ahc->platform_data->host == shost) if (ahc->platform_data->host->host_no == hostno)
break; break;
} }
#else
ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata);
#endif
if (ahc == NULL) if (ahc == NULL)
goto done; goto done;
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated * DO NOT EDIT - This file is automatically generated
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
*/ */
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
...@@ -747,13 +747,6 @@ ahc_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap) ...@@ -747,13 +747,6 @@ ahc_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap)
0x54, regvalue, cur_col, wrap)); 0x54, regvalue, cur_col, wrap));
} }
int
ahc_data_count_odd_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahc_print_register(NULL, 0, "DATA_COUNT_ODD",
0x55, regvalue, cur_col, wrap));
}
static ahc_reg_parse_entry_t HA_274_BIOSGLOBAL_parse_table[] = { static ahc_reg_parse_entry_t HA_274_BIOSGLOBAL_parse_table[] = {
{ "HA_274_EXTENDED_TRANS",0x01, 0x01 } { "HA_274_EXTENDED_TRANS",0x01, 0x01 }
}; };
...@@ -1416,13 +1409,14 @@ ahc_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) ...@@ -1416,13 +1409,14 @@ ahc_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
} }
static ahc_reg_parse_entry_t SCB_LUN_parse_table[] = { static ahc_reg_parse_entry_t SCB_LUN_parse_table[] = {
{ "LID", 0xff, 0xff } { "SCB_XFERLEN_ODD", 0x80, 0x80 },
{ "LID", 0x3f, 0x3f }
}; };
int int
ahc_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) ahc_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahc_print_register(SCB_LUN_parse_table, 1, "SCB_LUN", return (ahc_print_register(SCB_LUN_parse_table, 2, "SCB_LUN",
0xba, regvalue, cur_col, wrap)); 0xba, regvalue, cur_col, wrap));
} }
...@@ -1662,28 +1656,26 @@ ahc_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap) ...@@ -1662,28 +1656,26 @@ ahc_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap)
static ahc_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = { static ahc_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = {
{ "LAST_SEG_DONE", 0x01, 0x01 }, { "LAST_SEG_DONE", 0x01, 0x01 },
{ "LAST_SEG", 0x02, 0x02 }, { "LAST_SEG", 0x02, 0x02 },
{ "ODD_SEG", 0x04, 0x04 },
{ "SG_ADDR_MASK", 0xf8, 0xf8 } { "SG_ADDR_MASK", 0xf8, 0xf8 }
}; };
int int
ahc_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap) ahc_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahc_print_register(SG_CACHE_SHADOW_parse_table, 4, "SG_CACHE_SHADOW", return (ahc_print_register(SG_CACHE_SHADOW_parse_table, 3, "SG_CACHE_SHADOW",
0xfc, regvalue, cur_col, wrap)); 0xfc, regvalue, cur_col, wrap));
} }
static ahc_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = { static ahc_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = {
{ "LAST_SEG_DONE", 0x01, 0x01 }, { "LAST_SEG_DONE", 0x01, 0x01 },
{ "LAST_SEG", 0x02, 0x02 }, { "LAST_SEG", 0x02, 0x02 },
{ "ODD_SEG", 0x04, 0x04 },
{ "SG_ADDR_MASK", 0xf8, 0xf8 } { "SG_ADDR_MASK", 0xf8, 0xf8 }
}; };
int int
ahc_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap) ahc_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahc_print_register(SG_CACHE_PRE_parse_table, 4, "SG_CACHE_PRE", return (ahc_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE",
0xfc, regvalue, cur_col, wrap)); 0xfc, regvalue, cur_col, wrap));
} }
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#7 $ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#8 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -78,6 +78,7 @@ MCARG [^(), \t]+ ...@@ -78,6 +78,7 @@ MCARG [^(), \t]+
\n { \n {
++yylineno; ++yylineno;
} }
\r ;
<ARGLIST>{SPACE} ; <ARGLIST>{SPACE} ;
<ARGLIST>\( { <ARGLIST>\( {
parren_count++; parren_count++;
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#18 $ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#19 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -87,6 +87,7 @@ MBODY ((\\[^\n])*[^\n\\]*)+ ...@@ -87,6 +87,7 @@ MBODY ((\\[^\n])*[^\n\\]*)+
%% %%
\n { ++yylineno; } \n { ++yylineno; }
\r ;
"/*" { BEGIN COMMENT; /* Enter comment eating state */ } "/*" { BEGIN COMMENT; /* Enter comment eating state */ }
<COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); } <COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); }
<COMMENT>\n { ++yylineno; } <COMMENT>\n { ++yylineno; }
...@@ -114,6 +115,7 @@ if[ \t]*\( { ...@@ -114,6 +115,7 @@ if[ \t]*\( {
} }
} }
<CEXPR>\n { ++yylineno; } <CEXPR>\n { ++yylineno; }
<CEXPR>\r ;
<CEXPR>[^()\n]+ { <CEXPR>[^()\n]+ {
char *yptr; char *yptr;
...@@ -359,6 +361,7 @@ else { return T_ELSE; } ...@@ -359,6 +361,7 @@ else { return T_ELSE; }
/* Eat escaped newlines. */ /* Eat escaped newlines. */
++yylineno; ++yylineno;
} }
<MACROBODY>\r ;
<MACROBODY>\n { <MACROBODY>\n {
/* Macros end on the first unescaped newline. */ /* Macros end on the first unescaped newline. */
BEGIN INITIAL; BEGIN INITIAL;
...@@ -369,10 +372,17 @@ else { return T_ELSE; } ...@@ -369,10 +372,17 @@ else { return T_ELSE; }
} }
<MACROBODY>{MBODY} { <MACROBODY>{MBODY} {
char *yptr; char *yptr;
char c;
yptr = yytext; yptr = yytext;
while (*yptr) while (c = *yptr++) {
*string_buf_ptr++ = *yptr++; /*
* Strip carriage returns.
*/
if (c == '\r')
continue;
*string_buf_ptr++ = c;
}
} }
{WORD}\( { {WORD}\( {
char *yptr; char *yptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment