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
This diff is collapsed.
......@@ -131,27 +131,54 @@ The following information is available in this file:
SCSI "stub" effects.
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)
- Fix a few GCC 3.3 compiler warnings.
- Correct operation on EISA Twin Channel controller.
- Add support for 2.5.X's scsi_report_device_reset().
6.2.34 (May 5th, 2003)
- Fix locking regression instroduced in 6.2.29 that
could cuase a lock order reversal between the io_request_lock
and our per-softc lock. This was only possible on RH9,
SuSE, and kernel.org 2.4.X kernels.
6.2.33 - Dynamically disable PCI parity error reporting after
6.2.33 (April 30th, 2003)
- 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.32 - Dynamically sized S/G lists to avoid SCSI malloc
6.2.32 (March 28th, 2003)
- Dynamically sized S/G lists to avoid SCSI malloc
pool fragmentation and SCSI mid-layer deadlock.
6.2.28 - Domain Validation Fixes
PCI parity error disable
Enhanced Memory Mapped I/O probe
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 - Added Domain Validation
6.2.20 (November 7th, 2002)
- Added Domain Validation.
3. Command Line Options
......
#
# 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
tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
depends on PCI || EISA
---help---
This driver supports all of Adaptec's Fast through Ultra 160 PCI
based SCSI controllers as well as the aic7770 based EISA and VLB
......@@ -50,7 +51,7 @@ config AIC7XXX_RESET_DELAY_MS
config AIC7XXX_PROBE_EISA_VL
bool "Probe for EISA and VL AIC7XXX Adapters"
depends on SCSI_AIC7XXX
depends on SCSI_AIC7XXX && EISA
help
Probe for EISA and VLB Aic7xxx controllers. In many newer systems,
the invasive probes necessary to detect these controllers can cause
......
#
# 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
......@@ -12,15 +12,15 @@ obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o
# Core Fast -> U160 files
aic7xxx-y += aic7xxx_core.o \
aic7xxx_93cx6.o \
aic7770.o
aic7xxx_93cx6.o
aic7xxx-$(CONFIG_EISA) += aic7770.o
aic7xxx-$(CONFIG_PCI) += aic7xxx_pci.o
aic7xxx-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) += aic7xxx_reg_print.o
# Platform Specific Fast -> U160 Files
aic7xxx-y += aic7xxx_osm.o \
aic7xxx_proc.o \
aic7770_osm.o
aic7xxx_proc.o
aic7xxx-$(CONFIG_EISA) += aic7770_osm.o
aic7xxx-$(CONFIG_PCI) += aic7xxx_osm_pci.o
# Core U320 files
......
......@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic7770.c#30 $
* $Id: //depot/aic7xxx/aic7xxx/aic7770.c#32 $
*
* $FreeBSD$
*/
......@@ -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_setup;
struct aic7770_identity aic7770_ident_table [] =
struct aic7770_identity aic7770_ident_table[] =
{
{
ID_AHA_274x,
......@@ -82,6 +81,12 @@ struct aic7770_identity aic7770_ident_table [] =
"Adaptec 284X SCSI adapter",
ahc_aic7770_VL_setup
},
{
ID_AHA_284x,
0xFFFFFFFE,
"Adaptec 284X SCSI adapter (BIOS Disabled)",
ahc_aic7770_VL_setup
},
{
ID_OLV_274x,
0xFFFFFFFF,
......@@ -154,7 +159,7 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
ahc->bus_suspend = aic7770_suspend;
ahc->bus_resume = aic7770_resume;
error = ahc_reset(ahc);
error = ahc_reset(ahc, /*reinit*/FALSE);
if (error != 0)
return (error);
......
/*
* Linux driver attachment glue for aic7770 based controllers.
*
* Copyright (c) 2000-2001 Adaptec Inc.
* Copyright (c) 2000-2003 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -36,27 +36,90 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* 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"
#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 NUMSLOTS 16
#define IDOFFSET 0x80
int
aic7770_linux_probe(Scsi_Host_Template *template)
typedef void *aic7770_dev_t;
#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 ahc_softc *ahc;
int i, slot;
int eisaBase;
int found;
u_int slot;
u_int eisaBase;
u_int i;
if (aic7xxx_probe_eisa_vl == 0)
return;
eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
found = 0;
for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
uint32_t eisa_id;
size_t id_size;
......@@ -83,7 +146,31 @@ aic7770_linux_probe(Scsi_Host_Template *template)
continue; /* no EISA card in slot */
entry = aic7770_find_device(eisa_id);
if (entry != NULL) {
if (entry != NULL)
aic7770_linux_config(entry, NULL, eisaBase);
}
#endif
}
void
ahc_linux_eisa_exit(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
if (aic7xxx_probe_eisa_vl == 0)
return;
if (aic7770_driver.id_table != NULL) {
eisa_driver_unregister(&aic7770_driver);
free(aic7770_driver.id_table, M_DEVBUF);
}
#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;
......@@ -93,33 +180,28 @@ aic7770_linux_probe(Scsi_Host_Template *template)
* set it up for attachment by our
* common detect routine.
*/
sprintf(buf, "ahc_eisa:%d", slot);
sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
if (name == NULL)
break;
return (ENOMEM);
strcpy(name, buf);
ahc = ahc_alloc(template, name);
ahc = ahc_alloc(&aic7xxx_driver_template, name);
if (ahc == NULL) {
/*
* If we can't allocate this one,
* chances are we won't be able to
* allocate future card structures.
*/
break;
free(name, M_DEVBUF);
return (ENOMEM);
}
error = aic7770_config(ahc, entry, eisaBase);
if (error != 0) {
ahc->bsh.ioport = 0;
ahc_free(ahc);
continue;
}
found++;
return (error);
}
}
return (found);
#else
return (0);
#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
......@@ -129,6 +211,8 @@ aic7770_map_registers(struct ahc_softc *ahc, u_int port)
* Lock out other contenders for our i/o space.
*/
#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");
#else
if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
......@@ -155,3 +239,41 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq)
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 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#90 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#95 $
*
* $FreeBSD$
*/
......@@ -229,8 +229,10 @@ typedef enum {
AHD_RTI = 0x04000,/* Retained Training Support */
AHD_NEW_IOCELL_OPTS = 0x08000,/* More Signal knobs in the IOCELL */
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_AIC7901_FE = AHD_FENONE,
AHD_AIC7901A_FE = AHD_FENONE,
AHD_AIC7902_FE = AHD_MULTI_FUNC
} ahd_feature;
......@@ -372,7 +374,8 @@ typedef enum {
AHD_HP_BOARD = 0x100000,
AHD_RESET_POLL_ACTIVE = 0x200000,
AHD_UPDATE_PEND_CMDS = 0x400000,
AHD_RUNNING_QOUTFIFO = 0x800000
AHD_RUNNING_QOUTFIFO = 0x800000,
AHD_HAD_FIRST_SEL = 0x1000000
} ahd_flag;
/************************* Hardware SCB Definition ***************************/
......@@ -494,21 +497,21 @@ struct hardware_scb {
* transfer.
*/
#define SG_PTR_MASK 0xFFFFFFF8
/*16*/ uint64_t dataptr;
/*24*/ uint32_t datacnt; /* Byte 3 is spare. */
/*28*/ uint32_t sgptr;
/*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; /*
/*16*/ uint16_t tag; /* Reused by Sequencer. */
/*18*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */
/*19*/ uint8_t scsiid; /*
* Selection out Id
* Our Id (bits 0-3) Their ID (bits 4-7)
*/
/*42*/ uint8_t lun;
/*43*/ uint8_t task_attribute;
/*44*/ uint8_t cdb_len;
/*45*/ uint8_t task_management;
/*46*/ uint16_t tag; /* Reused by Sequencer. */
/*20*/ uint8_t lun;
/*21*/ uint8_t task_attribute;
/*22*/ uint8_t cdb_len;
/*23*/ uint8_t task_management;
/*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 ********/
/*48*/ uint8_t pkt_long_lun[8];
/******* Fields below are not Downloaded (Sequencer may use for scratch) ******/
......@@ -1379,7 +1382,7 @@ 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_alloc_scbs(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);
int ahd_write_flexport(struct ahd_softc *ahd,
u_int addr, u_int value);
......
......@@ -39,7 +39,7 @@
*
* $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
......@@ -1377,7 +1377,10 @@ register LUNLEN {
address 0x030
access_mode RW
modes M_CFG
mask ILUNLEN 0x0F
mask TLUNLEN 0xF0
}
const LUNLEN_SINGLE_LEVEL_LUN 0xF
/*
* CDB Limit
......@@ -3797,32 +3800,8 @@ scb {
size 4
alias SCB_NEXT_COMPLETE
}
SCB_DATAPTR {
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 {
SCB_TAG {
alias SCB_FIFO_USE_COUNT
size 2
}
SCB_CONTROL {
......@@ -3859,8 +3838,32 @@ scb {
SCB_TASK_MANAGEMENT {
size 1
}
SCB_TAG {
alias SCB_FIFO_USE_COUNT
SCB_DATAPTR {
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
}
SCB_SPARE {
......
......@@ -40,7 +40,7 @@
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#99 $"
PATCH_ARG_LIST = "struct ahd_softc *ahd"
PREFIX = "ahd_"
......@@ -163,8 +163,8 @@ return:
idle_loop_cchan:
SET_MODE(M_CCHAN, M_CCHAN)
test QOFF_CTLSTA, HS_MAILBOX_ACT jz hs_mailbox_empty;
mov LOCAL_HS_MAILBOX, HS_MAILBOX;
or QOFF_CTLSTA, HS_MAILBOX_ACT;
mov LOCAL_HS_MAILBOX, HS_MAILBOX;
hs_mailbox_empty:
BEGIN_CRITICAL;
test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;
......@@ -276,7 +276,7 @@ fetch_new_scb_done:
* knows the correct location to store 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. */
bmov NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4;
mvi SCB_NEXT[1], SCB_LIST_NULL;
......@@ -492,12 +492,13 @@ SET_DST_MODE M_SCSI;
select_in:
if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
/*
* This exposes a window whereby a
* busfree just after a selection will
* be missed, but there is no other safe
* way to enable busfree detection if
* the busfreerev function is broken.
* Test to ensure that the bus has not
* already gone free prior to clearing
* any stale busfree status. This avoids
* a window whereby a busfree just after
* a selection could be missed.
*/
test SCSISIGI, BSYI jz . + 2;
mvi CLRSINT1,CLRBUSFREE;
or SIMODE1, ENBUSFREE;
}
......@@ -582,9 +583,6 @@ found_last_sent_scb:
bmov CURRSCB, SCBPTR, 2;
curscb_ww_done:
} else {
/*
* Untested - Verify with Rev B.
*/
bmov SCBPTR, CURRSCB, 2;
}
......@@ -651,12 +649,13 @@ select_out_non_packetized:
and SCSISEQ0, ~ENSELO;
if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
/*
* This exposes a window whereby a
* busfree just after a selection will
* be missed, but there is no other safe
* way to enable busfree detection if
* the busfreerev function is broken.
* Test to ensure that the bus has not
* already gone free prior to clearing
* any stale busfree status. This avoids
* a window whereby a busfree just after
* a selection could be missed.
*/
test SCSISIGI, BSYI jz . + 2;
mvi CLRSINT1,CLRBUSFREE;
or SIMODE1, ENBUSFREE;
}
......@@ -729,13 +728,38 @@ p_command_embedded:
mvi DFCNTRL, SCSIEN;
p_command_xfer:
and SEQ_FLAGS, ~NO_CDB_SENT;
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.
* Don't allow a data phase if the command
* was not fully transferred.
*/
test SSTAT2, SDONE jnz ITloop;
p_command_xfer_failed:
or SEQ_FLAGS, NO_CDB_SENT;
jmp ITloop;
......@@ -1959,12 +1983,14 @@ SET_DST_MODE M_SCSI;
test SSTAT0, SELDO jnz return;
mvi SCBPTR[1], SCB_LIST_NULL;
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_DST_MODE M_DFF0;
or LONGJMP_ADDR[1], INVALID_ADDR;
dec SCB_FIFO_USE_COUNT;
mvi DFFSXFRCTL, CLRCHN;
unexpected_nonpkt_mode_cleared:
mvi CLRSINT2, CLRNONPACKREQ;
test SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase;
SET_SEQINTCODE(ENTERING_NONPACK)
......
This diff is collapsed.
......@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#50 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#51 $
*
* $FreeBSD$
*/
......@@ -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 uint32_t
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,
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)
static __inline uint32_t
ahd_inl_scbram(struct ahd_softc *ahd, u_int offset)
{
return (ahd_inb_scbram(ahd, offset)
| (ahd_inb_scbram(ahd, offset+1) << 8)
| (ahd_inb_scbram(ahd, offset+2) << 16)
| (ahd_inb_scbram(ahd, offset+3) << 24));
return (ahd_inw_scbram(ahd, offset)
| (ahd_inw_scbram(ahd, offset+2) << 16));
}
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 *
......
/*
* 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.
......@@ -425,7 +425,7 @@ static char *aic79xx = NULL;
static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n";
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
MODULE_LICENSE("Dual BSD/GPL");
#endif
......@@ -4442,6 +4442,16 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
}
#endif
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) {
u_int i;
......@@ -4456,6 +4466,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
ahd_get_residual(scb),
ahd_get_transfer_length(scb));
ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
#endif
} else {
ahd_set_transaction_status(scb, CAM_REQ_CMP);
}
......
......@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* 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_
......@@ -292,7 +292,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
#define AHD_SCSI_HAS_HOST_LOCK 0
#endif
#define AIC79XX_DRIVER_VERSION "1.3.9"
#define AIC79XX_DRIVER_VERSION "1.3.11"
/**************************** Front End Queues ********************************/
/*
......@@ -590,10 +590,6 @@ ahd_delay(long usec)
/***************************** 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 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);
......@@ -608,16 +604,12 @@ static __inline uint8_t
ahd_inb(struct ahd_softc * ahd, long port)
{
uint8_t x;
#ifdef MMAPIO
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
x = readb(ahd->bshs[0].maddr + port);
} else {
x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
}
#else
x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
#endif
mb();
return (x);
}
......@@ -626,16 +618,12 @@ static __inline uint16_t
ahd_inw_atomic(struct ahd_softc * ahd, long port)
{
uint8_t x;
#ifdef MMAPIO
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
x = readw(ahd->bshs[0].maddr + port);
} else {
x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
}
#else
x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
#endif
mb();
return (x);
}
......@@ -643,30 +631,22 @@ ahd_inw_atomic(struct ahd_softc * ahd, long port)
static __inline void
ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
{
#ifdef MMAPIO
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
writeb(val, ahd->bshs[0].maddr + port);
} else {
outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
}
#else
outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
#endif
mb();
}
static __inline void
ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
{
#ifdef MMAPIO
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
writew(val, ahd->bshs[0].maddr + port);
} else {
outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
}
#else
outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
#endif
mb();
}
......@@ -1005,7 +985,12 @@ ahd_flush_device_writes(struct ahd_softc *ahd)
(((dev_softc)->dma_mask = mask) && 0)
#endif
/**************************** 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 ********************************/
#define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete)
......
......@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* 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"
......@@ -52,11 +52,9 @@ static int ahd_linux_pci_dev_probe(struct pci_dev *pdev,
const struct pci_device_id *ent);
static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd,
u_long *base, u_long *base2);
#ifdef MMAPIO
static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
u_long *bus_addr,
uint8_t **maddr);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
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)
bus_addr_t mask_39bit;
memsize = ahd_linux_get_memsize();
mask_64bit = (bus_addr_t)(0xFFFFFFFFFFFFFFFFULL&(bus_addr_t)~0);
mask_39bit = (bus_addr_t)(0x7FFFFFFFFFULL&(bus_addr_t)~0);
mask_64bit = (bus_addr_t)0xFFFFFFFFFFFFFFFFULL;
mask_39bit = (bus_addr_t)0x7FFFFFFFFFULL;
if (memsize >= 0x8000000000ULL
&& ahd_pci_set_dma_mask(pdev, mask_64bit) == 0) {
ahd->flags |= AHD_64BIT_ADDRESSING;
......@@ -273,7 +271,6 @@ ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
return (0);
}
#ifdef MMAPIO
static int
ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
u_long *bus_addr,
......@@ -321,7 +318,6 @@ ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
error = ENOMEM;
return (error);
}
#endif
int
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);
base = 0;
maddr = NULL;
#ifdef MMAPIO
error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr);
if (error == 0) {
ahd->platform_data->mem_busaddr = base;
......@@ -373,7 +368,6 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
ahd_get_pci_function(ahd->dev_softc),
base);
}
#endif
if (maddr == NULL) {
u_long base2;
......
......@@ -38,7 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#73 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#77 $
*
* $FreeBSD$
*/
......@@ -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_aic7901A_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 [] =
{
......@@ -375,7 +376,7 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
ahd->bus_intr = ahd_pci_intr;
error = ahd_reset(ahd);
error = ahd_reset(ahd, /*reinit*/FALSE);
if (error != 0)
return (ENXIO);
......@@ -419,6 +420,8 @@ int
ahd_pci_test_register_access(struct ahd_softc *ahd)
{
uint32_t cmd;
u_int targpcistat;
u_int pci_status1;
int error;
uint8_t hcntrl;
......@@ -454,6 +457,18 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
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_outl(ahd, SRAM_BASE, 0x5aa555aa);
if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
......@@ -472,8 +487,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
fail:
if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
u_int targpcistat;
u_int pci_status1;
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
targpcistat = ahd_inb(ahd, TARGPCISTAT);
......@@ -486,7 +499,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
pci_status1, /*bytes*/1);
ahd_outb(ahd, CLRINT, CLRPCIINT);
}
ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
return (error);
......@@ -903,29 +915,31 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
static int
ahd_aic7901_setup(struct ahd_softc *ahd)
{
int error;
error = ahd_aic7902_setup(ahd);
if (error != 0)
return (error);
ahd->chip = AHD_AIC7901;
return (0);
ahd->features = AHD_AIC7901_FE;
return (ahd_aic790X_setup(ahd));
}
static int
ahd_aic7901A_setup(struct ahd_softc *ahd)
{
int error;
error = ahd_aic7902_setup(ahd);
if (error != 0)
return (error);
ahd->chip = AHD_AIC7901A;
return (0);
ahd->features = AHD_AIC7901A_FE;
return (ahd_aic790X_setup(ahd));
}
static int
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;
u_int rev;
......@@ -939,8 +953,6 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
return (ENXIO);
}
ahd->channel = ahd_get_pci_function(pci) + 'A';
ahd->chip = AHD_AIC7902;
ahd->features = AHD_AIC7902_FE;
if (rev < ID_AIC7902_PCI_REV_B0) {
/*
* Enable A series workarounds.
......@@ -968,9 +980,14 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
u_int devconfig1;
ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
| AHD_NEW_DFCNTRL_OPTS;
ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_ABORT_LQI_BUG
| AHD_INTCOLLISION_BUG|AHD_EARLY_REQ_BUG;
| AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
ahd->bugs |= AHD_LQOOVERRUN_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.
......
......@@ -37,7 +37,7 @@
* String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
* 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_inline.h"
......@@ -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.
*/
int
ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset,
int length, int inout)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
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 info_str info;
......@@ -291,10 +296,14 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t o
retval = -EINVAL;
ahd_list_lock(&l);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
TAILQ_FOREACH(ahd, &ahd_tailq, links) {
if (ahd->platform_data->host == shost)
if (ahd->platform_data->host->host_no == hostno)
break;
}
#else
ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata);
#endif
if (ahd == NULL)
goto done;
......
......@@ -3,7 +3,7 @@
* from the following source files:
*
* $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 struct ahd_reg_parse_entry {
......@@ -2239,94 +2239,94 @@ ahd_reg_print_t ahd_scb_sense_busaddr_print;
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_dataptr_print;
ahd_reg_print_t ahd_scb_tag_print;
#else
#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x190, regvalue, cur_col, wrap)
#define ahd_scb_tag_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TAG", 0x190, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_datacnt_print;
ahd_reg_print_t ahd_scb_control_print;
#else
#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_DATACNT", 0x198, regvalue, cur_col, wrap)
#define ahd_scb_control_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_CONTROL", 0x192, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_sgptr_print;
ahd_reg_print_t ahd_scb_scsiid_print;
#else
#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_SGPTR", 0x19c, regvalue, cur_col, wrap)
#define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_SCSIID", 0x193, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_busaddr_print;
ahd_reg_print_t ahd_scb_lun_print;
#else
#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a0, regvalue, cur_col, wrap)
#define ahd_scb_lun_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_LUN", 0x194, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_next_print;
ahd_reg_print_t ahd_scb_task_attribute_print;
#else
#define ahd_scb_next_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_NEXT", 0x1a4, regvalue, cur_col, wrap)
#define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x195, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_next2_print;
ahd_reg_print_t ahd_scb_cdb_len_print;
#else
#define ahd_scb_next2_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_NEXT2", 0x1a6, regvalue, cur_col, wrap)
#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x196, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_control_print;
ahd_reg_print_t ahd_scb_task_management_print;
#else
#define ahd_scb_control_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_CONTROL", 0x1a8, regvalue, cur_col, wrap)
#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x197, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_scsiid_print;
ahd_reg_print_t ahd_scb_dataptr_print;
#else
#define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_SCSIID", 0x1a9, regvalue, cur_col, wrap)
#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x198, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_lun_print;
ahd_reg_print_t ahd_scb_datacnt_print;
#else
#define ahd_scb_lun_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_LUN", 0x1aa, regvalue, cur_col, wrap)
#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_DATACNT", 0x1a0, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_task_attribute_print;
ahd_reg_print_t ahd_scb_sgptr_print;
#else
#define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x1ab, regvalue, cur_col, wrap)
#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_SGPTR", 0x1a4, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_cdb_len_print;
ahd_reg_print_t ahd_scb_busaddr_print;
#else
#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x1ac, regvalue, cur_col, wrap)
#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a8, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_task_management_print;
ahd_reg_print_t ahd_scb_next_print;
#else
#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x1ad, regvalue, cur_col, wrap)
#define ahd_scb_next_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_NEXT", 0x1ac, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_tag_print;
ahd_reg_print_t ahd_scb_next2_print;
#else
#define ahd_scb_tag_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TAG", 0x1ae, regvalue, cur_col, wrap)
#define ahd_scb_next2_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_NEXT2", 0x1ae, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
......@@ -2557,6 +2557,8 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SHORTTHRESH 0x2f
#define LUNLEN 0x30
#define TLUNLEN 0xf0
#define ILUNLEN 0x0f
#define CDBLIMIT 0x31
......@@ -3648,25 +3650,10 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SCB_SENSE_BUSADDR 0x18c
#define SCB_NEXT_COMPLETE 0x18c
#define SCB_DATAPTR 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_TAG 0x190
#define SCB_FIFO_USE_COUNT 0x190
#define SCB_BUSADDR 0x1a0
#define SCB_NEXT 0x1a4
#define SCB_NEXT_SCB_BUSADDR 0x1a4
#define SCB_NEXT2 0x1a6
#define SCB_CONTROL 0x1a8
#define SCB_CONTROL 0x192
#define TARGET_SCB 0x80
#define DISCENB 0x40
#define TAG_ENB 0x20
......@@ -3675,23 +3662,38 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define DISCONNECTED 0x04
#define SCB_TAG_TYPE 0x03
#define SCB_SCSIID 0x1a9
#define SCB_SCSIID 0x193
#define TID 0xf0
#define OID 0x0f
#define SCB_LUN 0x1aa
#define SCB_LUN 0x194
#define LID 0xff
#define SCB_TASK_ATTRIBUTE 0x1ab
#define SCB_TASK_ATTRIBUTE 0x195
#define SCB_XFERLEN_ODD 0x01
#define SCB_CDB_LEN 0x1ac
#define SCB_CDB_LEN 0x196
#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_FIFO_USE_COUNT 0x1ae
#define SCB_NEXT2 0x1ae
#define SCB_SPARE 0x1b0
#define SCB_PKT_LUN 0x1b0
......@@ -3720,6 +3722,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define AHD_PRECOMP_CUTBACK_29 0x06
#define AHD_NUM_PER_DEV_ANNEXCOLS 0x04
#define B_CURRFIFO_0 0x02
#define LUNLEN_SINGLE_LEVEL_LUN 0x0f
#define NVRAM_SCB_OFFSET 0x2c
#define AHD_TIMER_MAX_US 0x18ffe7
#define AHD_TIMER_MAX_TICKS 0xffff
......
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#93 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#68 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
*/
#include "aic79xx_osm.h"
......@@ -489,10 +489,15 @@ ahd_shortthresh_print(u_int regvalue, u_int *cur_col, u_int wrap)
0x2f, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t LUNLEN_parse_table[] = {
{ "ILUNLEN", 0x0f, 0x0f },
{ "TLUNLEN", 0xf0, 0xf0 }
};
int
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));
}
......@@ -3486,58 +3491,12 @@ ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
}
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));
}
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[] = {
{ "SCB_TAG_TYPE", 0x03, 0x03 },
{ "DISCONNECTED", 0x04, 0x04 },
......@@ -3552,7 +3511,7 @@ int
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",
0x1a8, regvalue, cur_col, wrap));
0x192, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = {
......@@ -3564,7 +3523,7 @@ int
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",
0x1a9, regvalue, cur_col, wrap));
0x193, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t SCB_LUN_parse_table[] = {
......@@ -3575,14 +3534,18 @@ int
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",
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
ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE",
0x1ab, regvalue, cur_col, wrap));
return (ahd_print_register(SCB_TASK_ATTRIBUTE_parse_table, 1, "SCB_TASK_ATTRIBUTE",
0x195, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = {
......@@ -3593,20 +3556,66 @@ int
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",
0x1ac, regvalue, cur_col, wrap));
0x196, regvalue, cur_col, wrap));
}
int
ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT",
0x1ad, regvalue, cur_col, wrap));
0x197, regvalue, cur_col, wrap));
}
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));
}
......
This diff is collapsed.
......@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#77 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#79 $
*
* $FreeBSD$
*/
......@@ -1143,17 +1143,17 @@ struct ahc_pci_identity {
char *name;
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;
/***************************** VL/EISA Declarations ***************************/
struct aic7770_identity {
uint32_t full_id;
uint32_t id_mask;
char *name;
const char *name;
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;
#define AHC_EISA_SLOT_OFFSET 0xc00
......@@ -1205,7 +1205,7 @@ void ahc_set_unit(struct ahc_softc *, int);
void ahc_set_name(struct ahc_softc *, char *);
void ahc_alloc_scbs(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);
/*************************** Interrupt Services *******************************/
......
......@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#131 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#134 $
*
* $FreeBSD$
*/
......@@ -1304,17 +1304,23 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
ahc_qinfifo_requeue_tail(ahc, scb);
printerror = 0;
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
MSG_EXT_WDTR, FALSE)
|| ahc_sent_msg(ahc, AHCMSG_EXT,
MSG_EXT_SDTR, FALSE)) {
MSG_EXT_WDTR, FALSE)) {
/*
* Negotiation Rejected. Go-async and
* Negotiation Rejected. Go-narrow and
* retry command.
*/
ahc_set_width(ahc, &devinfo,
MSG_EXT_WDTR_BUS_8_BIT,
AHC_TRANS_CUR|AHC_TRANS_GOAL,
/*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,
/*syncrate*/NULL,
/*period*/0, /*offset*/0,
......@@ -1463,7 +1469,7 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
* current connection, so we must
* leave it on while single stepping.
*/
ahc_outb(ahc, SIMODE1, ENBUSFREE);
ahc_outb(ahc, SIMODE1, simode1 & ENBUSFREE);
else
ahc_outb(ahc, SIMODE1, 0);
ahc_outb(ahc, CLRINT, CLRSCSIINT);
......@@ -2373,6 +2379,7 @@ ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
* may change.
*/
period = tinfo->goal.period;
offset = tinfo->goal.offset;
ppr_options = tinfo->goal.ppr_options;
/* Target initiated PPR is not allowed in the SCSI spec */
if (devinfo->role == ROLE_TARGET)
......@@ -2380,7 +2387,7 @@ ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
&ppr_options, devinfo->role);
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
* claims to support it. There might be an expander in the way
......@@ -3176,24 +3183,31 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
response = 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_TRANS_ACTIVE|AHC_TRANS_GOAL,
/*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 (tinfo->goal.offset) {
/*
* We will always have an SDTR to send.
*/
ahc->msgout_index = 0;
ahc->msgout_len = 0;
ahc_build_transfer_msg(ahc, devinfo);
ahc->msgout_index = 0;
response = TRUE;
}
}
done = MSGLOOP_MSGCOMPLETE;
break;
}
......@@ -4033,7 +4047,7 @@ ahc_shutdown(void *arg)
ahc = (struct ahc_softc *)arg;
/* 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, SXFRCTL0, 0);
ahc_outb(ahc, DSPCISTATUS, 0);
......@@ -4044,10 +4058,15 @@ ahc_shutdown(void *arg)
/*
* 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
ahc_reset(struct ahc_softc *ahc)
ahc_reset(struct ahc_softc *ahc, int reinit)
{
u_int sblkctl;
u_int sxfrctl1_a, sxfrctl1_b;
......@@ -4143,7 +4162,7 @@ ahc_reset(struct ahc_softc *ahc)
ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
error = 0;
if (ahc->init_level > 0)
if (reinit != 0)
/*
* If a recovery action has forced a chip reset,
* re-initialize the chip to our liking.
......@@ -4725,14 +4744,12 @@ ahc_chip_init(struct ahc_softc *ahc)
* never settle, so don't complain if we
* fail here.
*/
ahc_pause(ahc);
for (wait = 5000;
(ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
wait--)
ahc_delay(100);
ahc_unpause(ahc);
}
ahc_restart(ahc);
return (0);
}
......@@ -5145,7 +5162,9 @@ int
ahc_resume(struct ahc_softc *ahc)
{
ahc_reset(ahc);
ahc_reset(ahc, /*reinit*/TRUE);
ahc_intr_enable(ahc, TRUE);
ahc_restart(ahc);
return (0);
}
......@@ -6407,7 +6426,6 @@ ahc_loadseq(struct ahc_softc *ahc)
memcpy(ahc->critical_sections, cs_table, cs_count);
}
ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
ahc_restart(ahc);
if (bootverbose) {
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)
*/
ahc->flags = saved_flags;
(void)ahc_loadseq(ahc);
ahc_unpause(ahc);
ahc_restart(ahc);
ahc_unlock(ahc, &s);
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
return;
}
ahc_restart(ahc);
ahc_unlock(ahc, &s);
}
cel = &ccb->cel;
......@@ -7207,12 +7226,16 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
printf("Configuring Initiator Mode\n");
ahc->flags &= ~AHC_TARGETROLE;
ahc->flags |= AHC_INITIATORROLE;
ahc_pause(ahc);
/*
* Returning to a configuration that
* fit previously will always succeed.
*/
(void)ahc_loadseq(ahc);
ahc_restart(ahc);
/*
* Unpaused. The extra unpause
* that follows is harmless.
*/
}
}
ahc_unpause(ahc);
......
/*
* 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
* The University of Calgary Department of Computer Science.
......@@ -293,7 +293,7 @@ static adapter_tag_info_t aic7xxx_tag_info[] =
#define AIC7XXX_CONFIGED_DV -1
#endif
static uint8_t aic7xxx_dv_settings[] =
static int8_t aic7xxx_dv_settings[] =
{
AIC7XXX_CONFIGED_DV,
AIC7XXX_CONFIGED_DV,
......@@ -391,9 +391,9 @@ static uint32_t aic7xxx_pci_parity = ~0;
* would result in never finding any devices :)
*/
#ifndef CONFIG_AIC7XXX_PROBE_EISA_VL
static uint32_t aic7xxx_probe_eisa_vl;
uint32_t aic7xxx_probe_eisa_vl;
#else
static uint32_t aic7xxx_probe_eisa_vl = ~0;
uint32_t aic7xxx_probe_eisa_vl = ~0;
#endif
/*
......@@ -752,7 +752,6 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
/************************ Host template entry points *************************/
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 const char *ahc_linux_info(struct Scsi_Host *);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
......@@ -765,6 +764,7 @@ static int ahc_linux_biosparam(struct scsi_device*,
sector_t, int[]);
#endif
#else
static int ahc_linux_release(struct Scsi_Host *);
static void ahc_linux_select_queue_depth(struct Scsi_Host *host,
Scsi_Device *scsi_devs);
#if defined(__i386__)
......@@ -895,8 +895,9 @@ ahc_linux_detect(Scsi_Host_Template *template)
ahc_linux_pci_init();
#endif
if (aic7xxx_probe_eisa_vl != 0)
aic7770_linux_probe(template);
#ifdef CONFIG_EISA
ahc_linux_eisa_init();
#endif
/*
* Register with the SCSI layer all
......@@ -915,6 +916,7 @@ ahc_linux_detect(Scsi_Host_Template *template)
return (found);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/*
* Free the passed in Scsi_Host memory structures prior to unloading the
* module.
......@@ -946,6 +948,7 @@ ahc_linux_release(struct Scsi_Host * host)
ahc_list_unlock(&l);
return (0);
}
#endif
/*
* Return a string describing the driver.
......@@ -4137,6 +4140,16 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
}
#endif
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) {
u_int i;
......@@ -4151,6 +4164,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
ahc_get_residual(scb),
ahc_get_transfer_length(scb));
ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
#endif
} else {
ahc_set_transaction_status(scb, CAM_REQ_CMP);
}
......@@ -5082,27 +5096,21 @@ ahc_linux_exit(void)
ahc_linux_kill_dv_thread(ahc);
}
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_
* unregistering from the scsi midlayer to avoid dangling
* references.
*/
scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
#endif
#ifdef CONFIG_PCI
ahc_linux_pci_exit();
#endif
#ifdef CONFIG_EISA
ahc_linux_eisa_exit();
#endif
}
module_init(ahc_linux_init);
......
......@@ -53,7 +53,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* 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_
......@@ -304,7 +304,7 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec)
#define AHC_SCSI_HAS_HOST_LOCK 0
#endif
#define AIC7XXX_DRIVER_VERSION "6.2.35"
#define AIC7XXX_DRIVER_VERSION "6.2.36"
/**************************** Front End Queues ********************************/
/*
......@@ -595,10 +595,6 @@ ahc_delay(long usec)
/***************************** 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 void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val);
static __inline void ahc_outsb(struct ahc_softc * ahc, long port,
......@@ -610,16 +606,12 @@ static __inline uint8_t
ahc_inb(struct ahc_softc * ahc, long port)
{
uint8_t x;
#ifdef MMAPIO
if (ahc->tag == BUS_SPACE_MEMIO) {
x = readb(ahc->bsh.maddr + port);
} else {
x = inb(ahc->bsh.ioport + port);
}
#else
x = inb(ahc->bsh.ioport + port);
#endif
mb();
return (x);
}
......@@ -627,15 +619,11 @@ ahc_inb(struct ahc_softc * ahc, long port)
static __inline void
ahc_outb(struct ahc_softc * ahc, long port, uint8_t val)
{
#ifdef MMAPIO
if (ahc->tag == BUS_SPACE_MEMIO) {
writeb(val, ahc->bsh.maddr + port);
} else {
outb(val, ahc->bsh.ioport + port);
}
#else
outb(val, ahc->bsh.ioport + port);
#endif
mb();
}
......@@ -843,15 +831,26 @@ typedef enum
AHC_POWER_STATE_D3
} ahc_power_state;
void ahc_power_state_change(struct ahc_softc *ahc,
ahc_power_state new_state);
/**************************** 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,
u_int port);
int aic7770_map_int(struct ahc_softc *ahc, u_int irq);
#endif
/******************************* 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);
void ahc_linux_pci_exit(void);
int ahc_pci_map_registers(struct ahc_softc *ahc);
......@@ -933,6 +932,7 @@ ahc_get_pci_bus(ahc_dev_softc_t pci)
{
return (pci->bus->number);
}
#endif
static __inline void ahc_flush_device_writes(struct ahc_softc *);
static __inline void
......@@ -962,7 +962,12 @@ ahc_flush_device_writes(struct ahc_softc *ahc)
(((dev_softc)->dma_mask = mask) && 0)
#endif
/**************************** 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 ********************************/
#define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete)
......
......@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* 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"
......@@ -51,11 +51,9 @@ static int ahc_linux_pci_dev_probe(struct pci_dev *pdev,
const struct pci_device_id *ent);
static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc,
u_long *base);
#ifdef MMAPIO
static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
u_long *bus_addr,
uint8_t **maddr);
#endif /* MMAPIO */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
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)
}
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
&& ahc_linux_get_memsize() > 0x80000000
&& 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)
return (0);
}
#ifdef MMAPIO
static int
ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
u_long *bus_addr,
......@@ -296,7 +293,6 @@ ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
error = ENOMEM;
return (error);
}
#endif /* MMAPIO */
int
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);
base = 0;
maddr = NULL;
#ifdef MMAPIO
error = ahc_linux_pci_reserve_mem_region(ahc, &base, &maddr);
if (error == 0) {
ahc->platform_data->mem_busaddr = base;
......@@ -350,7 +345,6 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
ahc_get_pci_function(ahc->dev_softc),
base);
}
#endif /* MMAPIO */
/*
* We always prefer memory mapped access.
......
......@@ -39,7 +39,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#66 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#69 $
*
* $FreeBSD$
*/
......@@ -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_ID 0x0005900500000000ull
#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_AIC7859 0x3860900400000000ull
#define ID_AHA_2930CU 0x3860900438699004ull
......@@ -245,9 +245,9 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
{
/* aic7850 based controllers */
{
ID_AHA_2902_04_10_15_20_30C,
ID_AHA_2902_04_10_15_20C_30C,
ID_ALL_MASK,
"Adaptec 2902/04/10/15/20/30C SCSI adapter",
"Adaptec 2902/04/10/15/20C/30C SCSI adapter",
ahc_aic785X_setup
},
/* aic7860 based controllers */
......@@ -877,7 +877,7 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
scsiseq = 0;
}
error = ahc_reset(ahc);
error = ahc_reset(ahc, /*reinit*/FALSE);
if (error != 0)
return (ENXIO);
......@@ -1289,6 +1289,14 @@ ahc_pci_test_register_access(struct ahc_softc *ahc)
ahc_outb(ahc, HCNTRL, hcntrl|PAUSE);
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, SCBPTR, 0);
ahc_outl(ahc, SCB_BASE, 0x5aa555aa);
......
......@@ -37,7 +37,7 @@
* String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
* 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_inline.h"
......@@ -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.
*/
int
ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset,
int length, int inout)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
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 info_str info;
......@@ -302,10 +307,14 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t o
retval = -EINVAL;
ahc_list_lock(&s);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
TAILQ_FOREACH(ahc, &ahc_tailq, links) {
if (ahc->platform_data->host == shost)
if (ahc->platform_data->host->host_no == hostno)
break;
}
#else
ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata);
#endif
if (ahc == NULL)
goto done;
......
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
*/
#include "aic7xxx_osm.h"
......@@ -747,13 +747,6 @@ ahc_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int 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[] = {
{ "HA_274_EXTENDED_TRANS",0x01, 0x01 }
};
......@@ -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[] = {
{ "LID", 0xff, 0xff }
{ "SCB_XFERLEN_ODD", 0x80, 0x80 },
{ "LID", 0x3f, 0x3f }
};
int
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));
}
......@@ -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[] = {
{ "LAST_SEG_DONE", 0x01, 0x01 },
{ "LAST_SEG", 0x02, 0x02 },
{ "ODD_SEG", 0x04, 0x04 },
{ "SG_ADDR_MASK", 0xf8, 0xf8 }
};
int
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));
}
static ahc_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = {
{ "LAST_SEG_DONE", 0x01, 0x01 },
{ "LAST_SEG", 0x02, 0x02 },
{ "ODD_SEG", 0x04, 0x04 },
{ "SG_ADDR_MASK", 0xf8, 0xf8 }
};
int
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));
}
......@@ -38,7 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* 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$
*/
......@@ -78,6 +78,7 @@ MCARG [^(), \t]+
\n {
++yylineno;
}
\r ;
<ARGLIST>{SPACE} ;
<ARGLIST>\( {
parren_count++;
......
......@@ -38,7 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#18 $
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#19 $
*
* $FreeBSD$
*/
......@@ -87,6 +87,7 @@ MBODY ((\\[^\n])*[^\n\\]*)+
%%
\n { ++yylineno; }
\r ;
"/*" { BEGIN COMMENT; /* Enter comment eating state */ }
<COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); }
<COMMENT>\n { ++yylineno; }
......@@ -114,6 +115,7 @@ if[ \t]*\( {
}
}
<CEXPR>\n { ++yylineno; }
<CEXPR>\r ;
<CEXPR>[^()\n]+ {
char *yptr;
......@@ -359,6 +361,7 @@ else { return T_ELSE; }
/* Eat escaped newlines. */
++yylineno;
}
<MACROBODY>\r ;
<MACROBODY>\n {
/* Macros end on the first unescaped newline. */
BEGIN INITIAL;
......@@ -369,10 +372,17 @@ else { return T_ELSE; }
}
<MACROBODY>{MBODY} {
char *yptr;
char c;
yptr = yytext;
while (*yptr)
*string_buf_ptr++ = *yptr++;
while (c = *yptr++) {
/*
* Strip carriage returns.
*/
if (c == '\r')
continue;
*string_buf_ptr++ = c;
}
}
{WORD}\( {
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