Commit 14686d42 authored by Justin T. Gibbs's avatar Justin T. Gibbs

Merge from Linux bk tree.

parents 8da730e9 403671e8
# #
# 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#5 $ # $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#6 $
# #
config SCSI_AIC7XXX config SCSI_AIC7XXX
tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)" tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
......
...@@ -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#27 $ * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#29 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -59,6 +59,9 @@ ...@@ -59,6 +59,9 @@
#define ID_OLV_274x 0x04907782 /* Olivetti OEM */ #define ID_OLV_274x 0x04907782 /* Olivetti OEM */
#define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */ #define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */
static int aic7770_chip_init(struct ahc_softc *ahc);
static int aic7770_suspend(struct ahc_softc *ahc);
static int aic7770_resume(struct ahc_softc *ahc);
static int aha2840_load_seeprom(struct ahc_softc *ahc); static int aha2840_load_seeprom(struct ahc_softc *ahc);
static ahc_device_setup_t ahc_aic7770_VL_setup; 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;;
...@@ -144,6 +147,12 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) ...@@ -144,6 +147,12 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
ahc->description = entry->name; ahc->description = entry->name;
error = ahc_softc_init(ahc); error = ahc_softc_init(ahc);
if (error != 0)
return (error);
ahc->bus_chip_init = aic7770_chip_init;
ahc->bus_suspend = aic7770_suspend;
ahc->bus_resume = aic7770_resume;
error = ahc_reset(ahc); error = ahc_reset(ahc);
if (error != 0) if (error != 0)
...@@ -226,6 +235,9 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) ...@@ -226,6 +235,9 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH); ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH);
ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF); ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF);
ahc->bus_softc.aic7770_softc.busspd = hostconf & DFTHRSH;
ahc->bus_softc.aic7770_softc.bustime = (hostconf << 2) & BOFF;
/* /*
* Generic aic7xxx initialization. * Generic aic7xxx initialization.
*/ */
...@@ -253,6 +265,28 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) ...@@ -253,6 +265,28 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
return (0); return (0);
} }
static int
aic7770_chip_init(struct ahc_softc *ahc)
{
ahc_outb(ahc, BUSSPD, ahc->bus_softc.aic7770_softc.busspd);
ahc_outb(ahc, BUSTIME, ahc->bus_softc.aic7770_softc.bustime);
ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS);
ahc_outb(ahc, BCTL, ENABLE);
return (ahc_chip_init(ahc));
}
static int
aic7770_suspend(struct ahc_softc *ahc)
{
return (ahc_suspend(ahc));
}
static int
aic7770_resume(struct ahc_softc *ahc)
{
return (ahc_resume(ahc));
}
/* /*
* Read the 284x SEEPROM. * Read the 284x SEEPROM.
*/ */
...@@ -371,5 +405,6 @@ ahc_aic7770_setup(struct ahc_softc *ahc) ...@@ -371,5 +405,6 @@ ahc_aic7770_setup(struct ahc_softc *ahc)
ahc->features = AHC_AIC7770_FE; ahc->features = AHC_AIC7770_FE;
ahc->bugs |= AHC_TMODE_WIDEODD_BUG; ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
ahc->flags |= AHC_PAGESCBS; ahc->flags |= AHC_PAGESCBS;
ahc->instruction_ram_size = 448;
return (0); return (0);
} }
...@@ -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/aic7770_osm.c#12 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#13 $
*/ */
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
...@@ -66,7 +66,7 @@ aic7770_linux_probe(Scsi_Host_Template *template) ...@@ -66,7 +66,7 @@ aic7770_linux_probe(Scsi_Host_Template *template)
continue; continue;
request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx"); request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx");
#else #else
if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") != 0) if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0)
continue; continue;
#endif #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#78 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#85 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -258,27 +258,30 @@ typedef enum { ...@@ -258,27 +258,30 @@ typedef enum {
AHD_PCIX_CHIPRST_BUG = 0x0040, AHD_PCIX_CHIPRST_BUG = 0x0040,
/* MMAPIO is not functional in PCI-X mode. */ /* MMAPIO is not functional in PCI-X mode. */
AHD_PCIX_MMAPIO_BUG = 0x0080, AHD_PCIX_MMAPIO_BUG = 0x0080,
/* Reads to SCBRAM fail to reset the discard timer. */
AHD_PCIX_SCBRAM_RD_BUG = 0x0100,
/* Bug workarounds that can be disabled on non-PCIX busses. */ /* Bug workarounds that can be disabled on non-PCIX busses. */
AHD_PCIX_BUG_MASK = AHD_PCIX_CHIPRST_BUG AHD_PCIX_BUG_MASK = AHD_PCIX_CHIPRST_BUG
| AHD_PCIX_MMAPIO_BUG, | AHD_PCIX_MMAPIO_BUG
| AHD_PCIX_SCBRAM_RD_BUG,
/* /*
* LQOSTOP0 status set even for forced selections with ATN * LQOSTOP0 status set even for forced selections with ATN
* to perform non-packetized message delivery. * to perform non-packetized message delivery.
*/ */
AHD_LQO_ATNO_BUG = 0x0100, AHD_LQO_ATNO_BUG = 0x0200,
/* FIFO auto-flush does not always trigger. */ /* FIFO auto-flush does not always trigger. */
AHD_AUTOFLUSH_BUG = 0x0200, AHD_AUTOFLUSH_BUG = 0x0400,
/* The CLRLQO registers are not self-clearing. */ /* The CLRLQO registers are not self-clearing. */
AHD_CLRLQO_AUTOCLR_BUG = 0x0400, AHD_CLRLQO_AUTOCLR_BUG = 0x0800,
/* The PACKETIZED status bit refers to the previous connection. */ /* The PACKETIZED status bit refers to the previous connection. */
AHD_PKTIZED_STATUS_BUG = 0x0800, AHD_PKTIZED_STATUS_BUG = 0x1000,
/* "Short Luns" are not placed into outgoing LQ packets correctly. */ /* "Short Luns" are not placed into outgoing LQ packets correctly. */
AHD_PKT_LUN_BUG = 0x1000, AHD_PKT_LUN_BUG = 0x2000,
/* /*
* Only the FIFO allocated to the non-packetized connection may * Only the FIFO allocated to the non-packetized connection may
* be in use during a non-packetzied connection. * be in use during a non-packetzied connection.
*/ */
AHD_NONPACKFIFO_BUG = 0x2000, AHD_NONPACKFIFO_BUG = 0x4000,
/* /*
* Writing to a DFF SCBPTR register may fail if concurent with * Writing to a DFF SCBPTR register may fail if concurent with
* a hardware write to the other DFF SCBPTR register. This is * a hardware write to the other DFF SCBPTR register. This is
...@@ -286,30 +289,40 @@ typedef enum { ...@@ -286,30 +289,40 @@ typedef enum {
* this bug have the AHD_NONPACKFIFO_BUG and all writes of concern * this bug have the AHD_NONPACKFIFO_BUG and all writes of concern
* occur in non-packetized connections. * occur in non-packetized connections.
*/ */
AHD_MDFF_WSCBPTR_BUG = 0x4000, AHD_MDFF_WSCBPTR_BUG = 0x8000,
/* SGHADDR updates are slow. */ /* SGHADDR updates are slow. */
AHD_REG_SLOW_SETTLE_BUG = 0x8000, AHD_REG_SLOW_SETTLE_BUG = 0x10000,
/* /*
* Changing the MODE_PTR coincident with an interrupt that * Changing the MODE_PTR coincident with an interrupt that
* switches to a different mode will cause the interrupt to * switches to a different mode will cause the interrupt to
* be in the mode written outside of interrupt context. * be in the mode written outside of interrupt context.
*/ */
AHD_SET_MODE_BUG = 0x10000, AHD_SET_MODE_BUG = 0x20000,
/* Non-packetized busfree revision does not work. */ /* Non-packetized busfree revision does not work. */
AHD_BUSFREEREV_BUG = 0x20000, AHD_BUSFREEREV_BUG = 0x40000,
/* /*
* Paced transfers are indicated with a non-standard PPR * Paced transfers are indicated with a non-standard PPR
* option bit in the neg table, 160MHz is indicated by * option bit in the neg table, 160MHz is indicated by
* sync factor 0x7, and the offset if off by a factor of 2. * sync factor 0x7, and the offset if off by a factor of 2.
*/ */
AHD_PACED_NEGTABLE_BUG = 0x40000, AHD_PACED_NEGTABLE_BUG = 0x80000,
/* LQOOVERRUN false positives. */ /* LQOOVERRUN false positives. */
AHD_LQOOVERRUN_BUG = 0x80000, AHD_LQOOVERRUN_BUG = 0x100000,
/* /*
* Controller write to INTSTAT will lose to a host * Controller write to INTSTAT will lose to a host
* write to CLRINT. * write to CLRINT.
*/ */
AHD_INTCOLLISION_BUG = 0x100000 AHD_INTCOLLISION_BUG = 0x200000,
/*
* The GEM318 violates the SCSI spec by not waiting
* the mandated bus settle delay between phase changes
* in some situations. Some aic79xx chip revs. are more
* strict in this regard and will treat REQ assertions
* that fall within the bus settle delay window as
* glitches. This flag tells the firmware to tolerate
* early REQ assertions.
*/
AHD_EARLY_REQ_BUG = 0x400000
} ahd_bug; } ahd_bug;
/* /*
...@@ -411,7 +424,10 @@ typedef uint32_t sense_addr_t; ...@@ -411,7 +424,10 @@ typedef uint32_t sense_addr_t;
#define MAX_CDB_LEN 16 #define MAX_CDB_LEN 16
#define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t)) #define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t))
union initiator_data { union initiator_data {
uint64_t cdbptr; struct {
uint64_t cdbptr;
uint8_t cdblen;
} cdb_from_host;
uint8_t cdb[MAX_CDB_LEN]; uint8_t cdb[MAX_CDB_LEN];
struct { struct {
uint8_t cdb[MAX_CDB_LEN_WITH_SENSE_ADDR]; uint8_t cdb[MAX_CDB_LEN_WITH_SENSE_ADDR];
...@@ -727,7 +743,7 @@ struct ahd_tmode_lstate; ...@@ -727,7 +743,7 @@ struct ahd_tmode_lstate;
#define AHD_WIDTH_UNKNOWN 0xFF #define AHD_WIDTH_UNKNOWN 0xFF
#define AHD_PERIOD_UNKNOWN 0xFF #define AHD_PERIOD_UNKNOWN 0xFF
#define AHD_OFFSET_UNKNOWN 0x0 #define AHD_OFFSET_UNKNOWN 0xFF
#define AHD_PPR_OPTS_UNKNOWN 0xFF #define AHD_PPR_OPTS_UNKNOWN 0xFF
/* /*
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* *
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#64 $"
/* /*
* 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
...@@ -2071,14 +2071,14 @@ register LQIMODE1 { ...@@ -2071,14 +2071,14 @@ register LQIMODE1 {
address 0x051 address 0x051
access_mode RW access_mode RW
modes M_CFG modes M_CFG
field ENLQIPHASE_LQ 0x80 field ENLQIPHASE_LQ 0x80 /* LQIPHASE1 */
field ENLQIPHASE_NLQ 0x40 field ENLQIPHASE_NLQ 0x40 /* LQIPHASE2 */
field ENLIQABORT 0x20 field ENLIQABORT 0x20
field ENLQICRCI_LQ 0x10 field ENLQICRCI_LQ 0x10 /* LQICRCI1 */
field ENLQICRCI_NLQ 0x08 field ENLQICRCI_NLQ 0x08 /* LQICRCI2 */
field ENLQIBADLQI 0x04 field ENLQIBADLQI 0x04
field ENLQIOVERI_LQ 0x02 field ENLQIOVERI_LQ 0x02 /* LQIOVERI1 */
field ENLQIOVERI_NLQ 0x01 field ENLQIOVERI_NLQ 0x01 /* LQIOVERI2 */
} }
/* /*
...@@ -3769,16 +3769,17 @@ scb { ...@@ -3769,16 +3769,17 @@ scb {
SCB_RESIDUAL_DATACNT { SCB_RESIDUAL_DATACNT {
size 4 size 4
alias SCB_CDB_STORE alias SCB_CDB_STORE
alias SCB_HOST_CDB_PTR
} }
SCB_RESIDUAL_SGPTR { SCB_RESIDUAL_SGPTR {
size 4 size 4
alias SCB_CDB_PTR
field SG_ADDR_MASK 0xf8 /* In the last byte */ field SG_ADDR_MASK 0xf8 /* In the last byte */
field SG_OVERRUN_RESID 0x02 /* In the first byte */ field SG_OVERRUN_RESID 0x02 /* In the first byte */
field SG_LIST_NULL 0x01 /* In the first byte */ field SG_LIST_NULL 0x01 /* In the first byte */
} }
SCB_SCSI_STATUS { SCB_SCSI_STATUS {
size 1 size 1
alias SCB_HOST_CDB_LEN
} }
SCB_TARGET_PHASES { SCB_TARGET_PHASES {
size 1 size 1
......
This diff is collapsed.
This diff is collapsed.
...@@ -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#41 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#44 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -678,7 +678,8 @@ ahd_inb_scbram(struct ahd_softc *ahd, u_int offset) ...@@ -678,7 +678,8 @@ ahd_inb_scbram(struct ahd_softc *ahd, u_int offset)
* Razor #528 * Razor #528
*/ */
value = ahd_inb(ahd, offset); value = ahd_inb(ahd, offset);
ahd_inb(ahd, MODE_PTR); if ((ahd->flags & AHD_PCIX_SCBRAM_RD_BUG) != 0)
ahd_inb(ahd, MODE_PTR);
return (value); return (value);
} }
......
/* /*
* Adaptec AIC79xx device driver for Linux. * Adaptec AIC79xx device driver for Linux.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#115 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#128 $
* *
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Copyright (c) 1994-2000 Justin T. Gibbs. * Copyright (c) 1994-2000 Justin T. Gibbs.
...@@ -994,9 +994,13 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) ...@@ -994,9 +994,13 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
cmd->device->id, cmd->device->lun, cmd->device->id, cmd->device->lun,
/*alloc*/TRUE); /*alloc*/TRUE);
if (dev == NULL) { if (dev == NULL) {
ahd_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
ahd_linux_queue_cmd_complete(ahd, cmd);
ahd_schedule_completeq(ahd, NULL);
ahd_midlayer_entrypoint_unlock(ahd, &flags); ahd_midlayer_entrypoint_unlock(ahd, &flags);
printf("aic79xx_linux_queue: Unable to allocate device!\n"); printf("%s: aic79xx_linux_queue - Unable to allocate device!\n",
return (-ENOMEM); ahd_name(ahd));
return (0);
} }
if (cmd->cmd_len > MAX_CDB_LEN) if (cmd->cmd_len > MAX_CDB_LEN)
return (-EINVAL); return (-EINVAL);
...@@ -1215,6 +1219,7 @@ ahd_linux_abort(Scsi_Cmnd *cmd) ...@@ -1215,6 +1219,7 @@ ahd_linux_abort(Scsi_Cmnd *cmd)
u_int saved_scbptr; u_int saved_scbptr;
u_int active_scbptr; u_int active_scbptr;
u_int last_phase; u_int last_phase;
u_int cdb_byte;
int retval; int retval;
int paused; int paused;
int wait; int wait;
...@@ -1227,9 +1232,12 @@ ahd_linux_abort(Scsi_Cmnd *cmd) ...@@ -1227,9 +1232,12 @@ ahd_linux_abort(Scsi_Cmnd *cmd)
ahd = *(struct ahd_softc **)cmd->device->host->hostdata; ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
acmd = (struct ahd_cmd *)cmd; acmd = (struct ahd_cmd *)cmd;
printf("%s:%d:%d:%d: Attempting to abort cmd %p\n", printf("%s:%d:%d:%d: Attempting to abort cmd %p:",
ahd_name(ahd), cmd->device->channel, cmd->device->id, ahd_name(ahd), cmd->device->channel, cmd->device->id,
cmd->device->lun, cmd); cmd->device->lun, cmd);
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
printf(" 0x%x", cmd->cmnd[cdb_byte]);
printf("\n");
/* /*
* In all versions of Linux, we have to work around * In all versions of Linux, we have to work around
...@@ -1456,14 +1464,14 @@ ahd_linux_abort(Scsi_Cmnd *cmd) ...@@ -1456,14 +1464,14 @@ ahd_linux_abort(Scsi_Cmnd *cmd)
struct timer_list timer; struct timer_list timer;
int ret; int ret;
ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE; pending_scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &s); ahd_unlock(ahd, &s);
#else #else
spin_unlock_irq(ahd->platform_data->host->host_lock); spin_unlock_irq(ahd->platform_data->host->host_lock);
#endif #endif
init_timer(&timer); init_timer(&timer);
timer.data = (u_long)ahd; timer.data = (u_long)pending_scb;
timer.expires = jiffies + (5 * HZ); timer.expires = jiffies + (5 * HZ);
timer.function = ahd_linux_sem_timeout; timer.function = ahd_linux_sem_timeout;
add_timer(&timer); add_timer(&timer);
...@@ -1577,14 +1585,14 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd) ...@@ -1577,14 +1585,14 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
ahd_queue_scb(ahd, scb); ahd_queue_scb(ahd, scb);
ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE; scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &s); ahd_unlock(ahd, &s);
#else #else
spin_unlock_irq(ahd->platform_data->host->host_lock); spin_unlock_irq(ahd->platform_data->host->host_lock);
#endif #endif
init_timer(&timer); init_timer(&timer);
timer.data = (u_long)ahd; timer.data = (u_long)scb;
timer.expires = jiffies + (5 * HZ); timer.expires = jiffies + (5 * HZ);
timer.function = ahd_linux_sem_timeout; timer.function = ahd_linux_sem_timeout;
add_timer(&timer); add_timer(&timer);
...@@ -1691,7 +1699,7 @@ Scsi_Host_Template aic79xx_driver_template = { ...@@ -1691,7 +1699,7 @@ Scsi_Host_Template aic79xx_driver_template = {
.max_sectors = 8192, .max_sectors = 8192,
#endif #endif
#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
/* Assume RedHat Distribution with its different HIGHIO conventions. */ /* Assume RedHat Distribution with its different HIGHIO conventions. */
.can_dma_32 = 1, .can_dma_32 = 1,
.single_sg_okay = 1, .single_sg_okay = 1,
...@@ -2405,8 +2413,23 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template) ...@@ -2405,8 +2413,23 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template)
* negotiation will occur for the first command, and DV * negotiation will occur for the first command, and DV
* will comence should that first command be successful. * will comence should that first command be successful.
*/ */
for (target = 0; target < host->max_id; target++) for (target = 0; target < host->max_id; target++) {
/*
* Skip our own ID. Some Compaq/HP storage devices
* have enclosure management devices that respond to
* single bit selection (i.e. selecting ourselves).
* It is expected that either an external application
* or a modified kernel will be used to probe this
* ID if it is appropriate. To accomodate these installations,
* ahc_linux_alloc_target() will allocate for our ID if
* asked to do so.
*/
if (target == ahd->our_id)
continue;
ahd_linux_alloc_target(ahd, 0, target); ahd_linux_alloc_target(ahd, 0, target);
}
ahd_intr_enable(ahd, TRUE); ahd_intr_enable(ahd, TRUE);
ahd_linux_start_dv(ahd); ahd_linux_start_dv(ahd);
ahd_unlock(ahd, &s); ahd_unlock(ahd, &s);
...@@ -2851,16 +2874,21 @@ ahd_linux_dv_thread(void *data) ...@@ -2851,16 +2874,21 @@ ahd_linux_dv_thread(void *data)
printf("In DV Thread\n"); printf("In DV Thread\n");
#endif #endif
/*
* Complete thread creation.
*/
lock_kernel();
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
/* /*
* Don't care about any signals. * Don't care about any signals.
*/ */
siginitsetinv(&current->blocked, 0); siginitsetinv(&current->blocked, 0);
/* daemonize();
* Complete thread creation. sprintf(current->comm, "ahd_dv_%d", ahd->unit);
*/ #else
lock_kernel();
daemonize("ahd_dv_%d", ahd->unit); daemonize("ahd_dv_%d", ahd->unit);
#endif
unlock_kernel(); unlock_kernel();
while (1) { while (1) {
...@@ -3026,6 +3054,7 @@ ahd_linux_dv_target(struct ahd_softc *ahd, u_int target_offset) ...@@ -3026,6 +3054,7 @@ ahd_linux_dv_target(struct ahd_softc *ahd, u_int target_offset)
} }
case AHD_DV_STATE_TUR: case AHD_DV_STATE_TUR:
case AHD_DV_STATE_BUSY: case AHD_DV_STATE_BUSY:
timeout = 5 * HZ;
ahd_linux_dv_tur(ahd, cmd, &devinfo); ahd_linux_dv_tur(ahd, cmd, &devinfo);
break; break;
case AHD_DV_STATE_REBD: case AHD_DV_STATE_REBD:
...@@ -4437,17 +4466,6 @@ static struct ahd_linux_target* ...@@ -4437,17 +4466,6 @@ static struct ahd_linux_target*
ahd_linux_alloc_target(struct ahd_softc *ahd, u_int channel, u_int target) ahd_linux_alloc_target(struct ahd_softc *ahd, u_int channel, u_int target)
{ {
struct ahd_linux_target *targ; struct ahd_linux_target *targ;
u_int target_offset;
target_offset = target;
/*
* Never allow allocation of a target object for
* our own SCSIID.
*/
if (target == ahd->our_id) {
ahd->platform_data->targets[target_offset] = NULL;
return (NULL);
}
targ = malloc(sizeof(*targ), M_DEVBUF, M_NOWAIT); targ = malloc(sizeof(*targ), M_DEVBUF, M_NOWAIT);
if (targ == NULL) if (targ == NULL)
...@@ -4457,7 +4475,7 @@ ahd_linux_alloc_target(struct ahd_softc *ahd, u_int channel, u_int target) ...@@ -4457,7 +4475,7 @@ ahd_linux_alloc_target(struct ahd_softc *ahd, u_int channel, u_int target)
targ->target = target; targ->target = target;
targ->ahd = ahd; targ->ahd = ahd;
targ->flags = AHD_DV_REQUIRED; targ->flags = AHD_DV_REQUIRED;
ahd->platform_data->targets[target_offset] = targ; ahd->platform_data->targets[target] = targ;
return (targ); return (targ);
} }
...@@ -4699,6 +4717,14 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb) ...@@ -4699,6 +4717,14 @@ 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);
} else if (amount_xferred < scb->io_ctx->underflow) { } else if (amount_xferred < scb->io_ctx->underflow) {
u_int i;
ahd_print_path(ahd, scb);
printf("CDB:");
for (i = 0; i < scb->io_ctx->cmd_len; i++)
printf(" 0x%x", scb->io_ctx->cmnd[i]);
printf("\n");
ahd_print_path(ahd, scb);
printf("Saw underflow (%ld of %ld bytes). " printf("Saw underflow (%ld of %ld bytes). "
"Treated as error\n", "Treated as error\n",
ahd_get_residual(scb), ahd_get_residual(scb),
...@@ -4755,8 +4781,8 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb) ...@@ -4755,8 +4781,8 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
if (ahd_get_transaction_status(scb) == CAM_BDR_SENT if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
|| ahd_get_transaction_status(scb) == CAM_REQ_ABORTED) || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
if ((ahd->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) { if ((scb->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) {
ahd->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE; scb->platform_data->flags &= ~AHD_SCB_UP_EH_SEM;
up(&ahd->platform_data->eh_sem); up(&ahd->platform_data->eh_sem);
} }
} }
...@@ -5258,13 +5284,15 @@ ahd_release_simq(struct ahd_softc *ahd) ...@@ -5258,13 +5284,15 @@ ahd_release_simq(struct ahd_softc *ahd)
static void static void
ahd_linux_sem_timeout(u_long arg) ahd_linux_sem_timeout(u_long arg)
{ {
struct scb *scb;
struct ahd_softc *ahd; struct ahd_softc *ahd;
u_long s; u_long s;
ahd = (struct ahd_softc *)arg; scb = (struct scb *)arg;
ahd = scb->ahd_softc;
ahd_lock(ahd, &s); ahd_lock(ahd, &s);
if ((ahd->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) { if ((scb->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) {
ahd->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE; scb->platform_data->flags &= ~AHD_SCB_UP_EH_SEM;
up(&ahd->platform_data->eh_sem); up(&ahd->platform_data->eh_sem);
} }
ahd_unlock(ahd, &s); ahd_unlock(ahd, &s);
......
...@@ -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#108 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#117 $
* *
*/ */
#ifndef _AIC79XX_LINUX_H_ #ifndef _AIC79XX_LINUX_H_
...@@ -286,7 +286,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec) ...@@ -286,7 +286,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
#include <linux/smp.h> #include <linux/smp.h>
#endif #endif
#define AIC79XX_DRIVER_VERSION "1.3.0" #define AIC79XX_DRIVER_VERSION "1.3.4"
/**************************** Front End Queues ********************************/ /**************************** Front End Queues ********************************/
/* /*
...@@ -487,7 +487,7 @@ struct ahd_linux_target { ...@@ -487,7 +487,7 @@ struct ahd_linux_target {
* Per-SCB OSM storage. * Per-SCB OSM storage.
*/ */
typedef enum { typedef enum {
AHD_UP_EH_SEMAPHORE = 0x1 AHD_SCB_UP_EH_SEM = 0x1
} ahd_linux_scb_flags; } ahd_linux_scb_flags;
struct scb_platform_data { struct scb_platform_data {
...@@ -947,7 +947,7 @@ void ahd_power_state_change(struct ahd_softc *ahd, ...@@ -947,7 +947,7 @@ void ahd_power_state_change(struct ahd_softc *ahd,
*/ */
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92)
#if defined(__sparc_v9__) || defined(__powerpc__) #if defined(__sparc_v9__) || defined(__powerpc__)
#error "PPC and Sparc platforms are only support under 2.1.92 and above" #error "PPC and Sparc platforms are only supported under 2.1.92 and above"
#endif #endif
#include <linux/bios32.h> #include <linux/bios32.h>
#endif #endif
......
...@@ -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#61 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#67 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -80,6 +80,7 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) ...@@ -80,6 +80,7 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
#define ID_AIC7902_B 0x801D9005FFFF9005ull #define ID_AIC7902_B 0x801D9005FFFF9005ull
#define ID_AIC7902_B_IROC 0x809D9005FFFF9005ull #define ID_AIC7902_B_IROC 0x809D9005FFFF9005ull
#define ID_AHA_39320 0x8010900500409005ull #define ID_AHA_39320 0x8010900500409005ull
#define ID_AHA_39320A 0x8016900500409005ull
#define ID_AHA_39320D 0x8011900500419005ull #define ID_AHA_39320D 0x8011900500419005ull
#define ID_AHA_39320D_B 0x801C900500419005ull #define ID_AHA_39320D_B 0x801C900500419005ull
#define ID_AHA_39320D_HP 0x8011900500AC0E11ull #define ID_AHA_39320D_HP 0x8011900500AC0E11ull
...@@ -137,6 +138,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] = ...@@ -137,6 +138,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
"Adaptec 39320 Ultra320 SCSI adapter", "Adaptec 39320 Ultra320 SCSI adapter",
ahd_aic7902_setup ahd_aic7902_setup
}, },
{
ID_AHA_39320A,
ID_ALL_MASK,
"Adaptec 39320A Ultra320 SCSI adapter",
ahd_aic7902_setup
},
{ {
ID_AHA_39320D, ID_AHA_39320D,
ID_ALL_MASK, ID_ALL_MASK,
...@@ -378,12 +385,10 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) ...@@ -378,12 +385,10 @@ 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)
{ {
ahd_mode_state saved_modes;
uint32_t cmd; uint32_t cmd;
int error; int error;
uint8_t hcntrl; uint8_t hcntrl;
saved_modes = ahd_save_modes(ahd);
error = EIO; error = EIO;
/* /*
...@@ -449,7 +454,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd) ...@@ -449,7 +454,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
ahd_outb(ahd, CLRINT, CLRPCIINT); ahd_outb(ahd, CLRINT, CLRPCIINT);
} }
ahd_restore_modes(ahd, saved_modes);
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);
...@@ -698,7 +702,7 @@ static const char *split_status_strings[] = ...@@ -698,7 +702,7 @@ static const char *split_status_strings[] =
"%s: Split completion data bucket in %s\n", "%s: Split completion data bucket in %s\n",
"%s: Split completion address error in %s\n", "%s: Split completion address error in %s\n",
"%s: Split completion byte count error in %s\n", "%s: Split completion byte count error in %s\n",
"%s: Signaled Target-abort to early terminate a split in %s\n", "%s: Signaled Target-abort to early terminate a split in %s\n"
}; };
static const char *pci_status_strings[] = static const char *pci_status_strings[] =
...@@ -879,11 +883,11 @@ ahd_aic7902_setup(struct ahd_softc *ahd) ...@@ -879,11 +883,11 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
| AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
| AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
| AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
| AHD_PCIX_CHIPRST_BUG|AHD_PKTIZED_STATUS_BUG | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
| AHD_PKT_LUN_BUG|AHD_MDFF_WSCBPTR_BUG | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
| AHD_REG_SLOW_SETTLE_BUG|AHD_SET_MODE_BUG | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
| AHD_BUSFREEREV_BUG|AHD_NONPACKFIFO_BUG | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
| AHD_PACED_NEGTABLE_BUG; | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG;
/* /*
* IO Cell paramter setup. * IO Cell paramter setup.
...@@ -898,7 +902,7 @@ ahd_aic7902_setup(struct ahd_softc *ahd) ...@@ -898,7 +902,7 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
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->bugs |= AHD_LQOOVERRUN_BUG|AHD_ABORT_LQI_BUG ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_ABORT_LQI_BUG
| AHD_INTCOLLISION_BUG; | AHD_INTCOLLISION_BUG|AHD_EARLY_REQ_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#11 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#13 $
*/ */
#include "aic79xx_osm.h" #include "aic79xx_osm.h"
#include "aic79xx_inline.h" #include "aic79xx_inline.h"
...@@ -124,8 +124,12 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) ...@@ -124,8 +124,12 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
printed_options = 0; printed_options = 0;
copy_info(info, " (%d.%03dMHz", freq / 1000, freq % 1000); copy_info(info, " (%d.%03dMHz", freq / 1000, freq % 1000);
if ((tinfo->ppr_options & MSG_EXT_PPR_RD_STRM) != 0) {
copy_info(info, " RDSTRM");
printed_options++;
}
if ((tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { if ((tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
copy_info(info, " DT"); copy_info(info, "%s", printed_options ? "|DT" : " DT");
printed_options++; printed_options++;
} }
if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
...@@ -311,6 +315,7 @@ ahd_linux_proc_info(char *buffer, char **start, off_t offset, ...@@ -311,6 +315,7 @@ ahd_linux_proc_info(char *buffer, char **start, off_t offset,
copy_info(&info, "Adaptec AIC79xx driver version: %s\n", copy_info(&info, "Adaptec AIC79xx driver version: %s\n",
AIC79XX_DRIVER_VERSION); AIC79XX_DRIVER_VERSION);
copy_info(&info, "%s\n", ahd->description);
ahd_controller_info(ahd, ahd_info); ahd_controller_info(ahd, ahd_info);
copy_info(&info, "%s\n\n", ahd_info); copy_info(&info, "%s\n\n", ahd_info);
......
...@@ -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#78 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#87 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#62 $
*/ */
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 {
...@@ -3638,13 +3638,14 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3638,13 +3638,14 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SCB_RESIDUAL_DATACNT 0x180 #define SCB_RESIDUAL_DATACNT 0x180
#define SCB_CDB_STORE 0x180 #define SCB_CDB_STORE 0x180
#define SCB_HOST_CDB_PTR 0x180
#define SCB_RESIDUAL_SGPTR 0x184 #define SCB_RESIDUAL_SGPTR 0x184
#define SCB_CDB_PTR 0x184
#define SG_ADDR_MASK 0xf8 #define SG_ADDR_MASK 0xf8
#define SG_OVERRUN_RESID 0x02 #define SG_OVERRUN_RESID 0x02
#define SCB_SCSI_STATUS 0x188 #define SCB_SCSI_STATUS 0x188
#define SCB_HOST_CDB_LEN 0x188
#define SCB_TARGET_PHASES 0x189 #define SCB_TARGET_PHASES 0x189
...@@ -3774,5 +3775,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3774,5 +3775,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
/* Exported Labels */ /* Exported Labels */
#define LABEL_seq_isr 0x263 #define LABEL_seq_isr 0x268
#define LABEL_timer_isr 0x25f #define LABEL_timer_isr 0x264
...@@ -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#78 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#87 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#62 $
*/ */
#include "aic79xx_osm.h" #include "aic79xx_osm.h"
......
This diff is collapsed.
...@@ -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#70 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#73 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -365,7 +365,8 @@ typedef enum { ...@@ -365,7 +365,8 @@ typedef enum {
AHC_LSCBS_ENABLED = 0x2000000, /* 64Byte SCBs enabled */ AHC_LSCBS_ENABLED = 0x2000000, /* 64Byte SCBs enabled */
AHC_SCB_CONFIG_USED = 0x4000000, /* No SEEPROM but SCB2 had info. */ AHC_SCB_CONFIG_USED = 0x4000000, /* No SEEPROM but SCB2 had info. */
AHC_NO_BIOS_INIT = 0x8000000, /* No BIOS left over settings. */ AHC_NO_BIOS_INIT = 0x8000000, /* No BIOS left over settings. */
AHC_DISABLE_PCI_PERR = 0x10000000 AHC_DISABLE_PCI_PERR = 0x10000000,
AHC_HAS_TERM_LOGIC = 0x20000000
} ahc_flag; } ahc_flag;
/************************* Hardware SCB Definition ***************************/ /************************* Hardware SCB Definition ***************************/
...@@ -691,7 +692,7 @@ struct ahc_tmode_lstate; ...@@ -691,7 +692,7 @@ struct ahc_tmode_lstate;
#define AHC_WIDTH_UNKNOWN 0xFF #define AHC_WIDTH_UNKNOWN 0xFF
#define AHC_PERIOD_UNKNOWN 0xFF #define AHC_PERIOD_UNKNOWN 0xFF
#define AHC_OFFSET_UNKNOWN 0x0 #define AHC_OFFSET_UNKNOWN 0xFF
#define AHC_PPR_OPTS_UNKNOWN 0xFF #define AHC_PPR_OPTS_UNKNOWN 0xFF
/* /*
...@@ -877,31 +878,39 @@ typedef enum { ...@@ -877,31 +878,39 @@ typedef enum {
/*********************** Software Configuration Structure *********************/ /*********************** Software Configuration Structure *********************/
TAILQ_HEAD(scb_tailq, scb); TAILQ_HEAD(scb_tailq, scb);
struct ahc_suspend_channel_state { struct ahc_aic7770_softc {
uint8_t scsiseq; /*
uint8_t sxfrctl0; * Saved register state used for chip_init().
uint8_t sxfrctl1; */
uint8_t simode0; uint8_t busspd;
uint8_t simode1; uint8_t bustime;
uint8_t seltimer; };
uint8_t seqctl;
struct ahc_pci_softc {
/*
* Saved register state used for chip_init().
*/
uint32_t devconfig;
uint16_t targcrccnt;
uint8_t command;
uint8_t csize_lattime;
uint8_t optionmode;
uint8_t crccontrol1;
uint8_t dscommand0;
uint8_t dspcistatus;
uint8_t scbbaddr;
uint8_t dff_thrsh;
}; };
struct ahc_suspend_state { union ahc_bus_softc {
struct ahc_suspend_channel_state channel[2]; struct ahc_aic7770_softc aic7770_softc;
uint8_t optionmode; struct ahc_pci_softc pci_softc;
uint8_t dscommand0;
uint8_t dspcistatus;
/* hsmailbox */
uint8_t crccontrol1;
uint8_t scbbaddr;
/* Host and sequencer SCB counts */
uint8_t dff_thrsh;
uint8_t *scratch_ram;
uint8_t *btt;
}; };
typedef void (*ahc_bus_intr_t)(struct ahc_softc *); typedef void (*ahc_bus_intr_t)(struct ahc_softc *);
typedef int (*ahc_bus_chip_init_t)(struct ahc_softc *);
typedef int (*ahc_bus_suspend_t)(struct ahc_softc *);
typedef int (*ahc_bus_resume_t)(struct ahc_softc *);
typedef void ahc_callback_t (void *); typedef void ahc_callback_t (void *);
struct ahc_softc { struct ahc_softc {
...@@ -936,6 +945,11 @@ struct ahc_softc { ...@@ -936,6 +945,11 @@ struct ahc_softc {
*/ */
struct scb_tailq untagged_queues[AHC_NUM_TARGETS]; struct scb_tailq untagged_queues[AHC_NUM_TARGETS];
/*
* Bus attachment specific data.
*/
union ahc_bus_softc bus_softc;
/* /*
* Platform specific data. * Platform specific data.
*/ */
...@@ -951,6 +965,22 @@ struct ahc_softc { ...@@ -951,6 +965,22 @@ struct ahc_softc {
*/ */
ahc_bus_intr_t bus_intr; ahc_bus_intr_t bus_intr;
/*
* Bus specific initialization required
* after a chip reset.
*/
ahc_bus_chip_init_t bus_chip_init;
/*
* Bus specific suspend routine.
*/
ahc_bus_suspend_t bus_suspend;
/*
* Bus specific resume routine.
*/
ahc_bus_resume_t bus_resume;
/* /*
* Target mode related state kept on a per enabled lun basis. * Target mode related state kept on a per enabled lun basis.
* Targets that are not enabled will have null entries. * Targets that are not enabled will have null entries.
...@@ -1043,9 +1073,6 @@ struct ahc_softc { ...@@ -1043,9 +1073,6 @@ struct ahc_softc {
*/ */
bus_addr_t dma_bug_buf; bus_addr_t dma_bug_buf;
/* Information saved through suspend/resume cycles */
struct ahc_suspend_state suspend_state;
/* Number of enabled target mode device on this card */ /* Number of enabled target mode device on this card */
u_int enabled_luns; u_int enabled_luns;
...@@ -1055,7 +1082,8 @@ struct ahc_softc { ...@@ -1055,7 +1082,8 @@ struct ahc_softc {
/* PCI cacheline size. */ /* PCI cacheline size. */
u_int pci_cachesize; u_int pci_cachesize;
u_int stack_size; /* Maximum number of sequencer instructions supported. */
u_int instruction_ram_size;
/* Per-Unit descriptive information */ /* Per-Unit descriptive information */
const char *description; const char *description;
...@@ -1152,6 +1180,7 @@ int ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, ...@@ -1152,6 +1180,7 @@ int ahc_match_scb(struct ahc_softc *ahc, struct scb *scb,
struct ahc_softc *ahc_alloc(void *platform_arg, char *name); struct ahc_softc *ahc_alloc(void *platform_arg, char *name);
int ahc_softc_init(struct ahc_softc *); int ahc_softc_init(struct ahc_softc *);
void ahc_controller_info(struct ahc_softc *ahc, char *buf); void ahc_controller_info(struct ahc_softc *ahc, char *buf);
int ahc_chip_init(struct ahc_softc *ahc);
int ahc_init(struct ahc_softc *ahc); int ahc_init(struct ahc_softc *ahc);
void ahc_intr_enable(struct ahc_softc *ahc, int enable); void ahc_intr_enable(struct ahc_softc *ahc, int enable);
void ahc_pause_and_flushwork(struct ahc_softc *ahc); void ahc_pause_and_flushwork(struct ahc_softc *ahc);
...@@ -1167,7 +1196,6 @@ int ahc_reset(struct ahc_softc *ahc); ...@@ -1167,7 +1196,6 @@ int ahc_reset(struct ahc_softc *ahc);
void ahc_shutdown(void *arg); void ahc_shutdown(void *arg);
/*************************** Interrupt Services *******************************/ /*************************** Interrupt Services *******************************/
void ahc_pci_intr(struct ahc_softc *ahc);
void ahc_clear_intstat(struct ahc_softc *ahc); void ahc_clear_intstat(struct ahc_softc *ahc);
void ahc_run_qoutfifo(struct ahc_softc *ahc); void ahc_run_qoutfifo(struct ahc_softc *ahc);
#ifdef AHC_TARGET_MODE #ifdef AHC_TARGET_MODE
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* *
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $"
/* /*
* 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
...@@ -1580,7 +1580,7 @@ const BUS_32_BIT 0x02 ...@@ -1580,7 +1580,7 @@ const BUS_32_BIT 0x02
const MAX_OFFSET_8BIT 0x0f const MAX_OFFSET_8BIT 0x0f
const MAX_OFFSET_16BIT 0x08 const MAX_OFFSET_16BIT 0x08
const MAX_OFFSET_ULTRA2 0x7f const MAX_OFFSET_ULTRA2 0x7f
const MAX_OFFSET 0xff const MAX_OFFSET 0x7f
const HOST_MSG 0xff const HOST_MSG 0xff
/* Target mode command processing constants */ /* Target mode command processing constants */
......
This diff is collapsed.
...@@ -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_inline.h#39 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#40 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
......
/* /*
* Adaptec AIC7xxx device driver for Linux. * Adaptec AIC7xxx device driver for Linux.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#179 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#192 $
* *
* 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.
...@@ -995,9 +995,13 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) ...@@ -995,9 +995,13 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
cmd->device->lun, /*alloc*/TRUE); cmd->device->lun, /*alloc*/TRUE);
if (dev == NULL) { if (dev == NULL) {
ahc_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
ahc_linux_queue_cmd_complete(ahc, cmd);
ahc_schedule_completeq(ahc, NULL);
ahc_midlayer_entrypoint_unlock(ahc, &flags); ahc_midlayer_entrypoint_unlock(ahc, &flags);
printf("aic7xxx_linux_queue: Unable to allocate device!\n"); printf("%s: aic7xxx_linux_queue - Unable to allocate device!\n",
return (-ENOMEM); ahc_name(ahc));
return (0);
} }
cmd->result = CAM_REQ_INPROG << 16; cmd->result = CAM_REQ_INPROG << 16;
TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe); TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe);
...@@ -1291,7 +1295,7 @@ Scsi_Host_Template aic7xxx_driver_template = { ...@@ -1291,7 +1295,7 @@ Scsi_Host_Template aic7xxx_driver_template = {
.max_sectors = 8192, .max_sectors = 8192,
#endif #endif
#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
/* Assume RedHat Distribution with its different HIGHIO conventions. */ /* Assume RedHat Distribution with its different HIGHIO conventions. */
.can_dma_32 = 1, .can_dma_32 = 1,
.single_sg_okay = 1, .single_sg_okay = 1,
...@@ -1882,13 +1886,28 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) ...@@ -1882,13 +1886,28 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
* negotiation will occur for the first command, and DV * negotiation will occur for the first command, and DV
* will comence should that first command be successful. * will comence should that first command be successful.
*/ */
for (target = 0; target < host->max_id*host->max_channel+1; target++) { for (target = 0;
target < host->max_id * (host->max_channel + 1); target++) {
u_int channel; u_int channel;
channel = 0; channel = 0;
if (target > 7 if (target > 7
&& (ahc->features & AHC_TWIN) != 0) && (ahc->features & AHC_TWIN) != 0)
channel = 1; channel = 1;
/*
* Skip our own ID. Some Compaq/HP storage devices
* have enclosure management devices that respond to
* single bit selection (i.e. selecting ourselves).
* It is expected that either an external application
* or a modified kernel will be used to probe this
* ID if it is appropriate. To accomodate these installations,
* ahc_linux_alloc_target() will allocate for our ID if
* asked to do so.
*/
if ((channel == 0 && target == ahc->our_id)
|| (channel == 1 && target == ahc->our_id_b))
continue;
ahc_linux_alloc_target(ahc, channel, target); ahc_linux_alloc_target(ahc, channel, target);
} }
ahc_intr_enable(ahc, TRUE); ahc_intr_enable(ahc, TRUE);
...@@ -2328,7 +2347,7 @@ ahc_linux_start_dv(struct ahc_softc *ahc) ...@@ -2328,7 +2347,7 @@ ahc_linux_start_dv(struct ahc_softc *ahc)
/* /*
* Freeze the simq and signal ahc_linux_queue to not let any * Freeze the simq and signal ahc_linux_queue to not let any
* more commands through * more commands through.
*/ */
if ((ahc->platform_data->flags & AHC_DV_ACTIVE) == 0) { if ((ahc->platform_data->flags & AHC_DV_ACTIVE) == 0) {
#ifdef AHC_DEBUG #ifdef AHC_DEBUG
...@@ -2362,7 +2381,17 @@ ahc_linux_dv_thread(void *data) ...@@ -2362,7 +2381,17 @@ ahc_linux_dv_thread(void *data)
* Complete thread creation. * Complete thread creation.
*/ */
lock_kernel(); lock_kernel();
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/*
* Don't care about any signals.
*/
siginitsetinv(&current->blocked, 0);
daemonize();
sprintf(current->comm, "ahc_dv_%d", ahc->unit);
#else
daemonize("ahc_dv_%d", ahc->unit); daemonize("ahc_dv_%d", ahc->unit);
#endif
unlock_kernel(); unlock_kernel();
while (1) { while (1) {
...@@ -2528,6 +2557,7 @@ ahc_linux_dv_target(struct ahc_softc *ahc, u_int target_offset) ...@@ -2528,6 +2557,7 @@ ahc_linux_dv_target(struct ahc_softc *ahc, u_int target_offset)
} }
case AHC_DV_STATE_TUR: case AHC_DV_STATE_TUR:
case AHC_DV_STATE_BUSY: case AHC_DV_STATE_BUSY:
timeout = 5 * HZ;
ahc_linux_dv_tur(ahc, cmd, &devinfo); ahc_linux_dv_tur(ahc, cmd, &devinfo);
break; break;
case AHC_DV_STATE_REBD: case AHC_DV_STATE_REBD:
...@@ -3995,15 +4025,6 @@ ahc_linux_alloc_target(struct ahc_softc *ahc, u_int channel, u_int target) ...@@ -3995,15 +4025,6 @@ ahc_linux_alloc_target(struct ahc_softc *ahc, u_int channel, u_int target)
target_offset = target; target_offset = target;
if (channel != 0) if (channel != 0)
target_offset += 8; target_offset += 8;
/*
* Never allow allocation of a target object for
* our own SCSIID.
*/
if ((channel == 0 && target == ahc->our_id)
|| (channel == 1 && target == ahc->our_id_b)) {
ahc->platform_data->targets[target_offset] = NULL;
return (NULL);
}
targ = malloc(sizeof(*targ), M_DEVBUG, M_NOWAIT); targ = malloc(sizeof(*targ), M_DEVBUG, M_NOWAIT);
if (targ == NULL) if (targ == NULL)
...@@ -4274,6 +4295,14 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) ...@@ -4274,6 +4295,14 @@ 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);
} else if (amount_xferred < scb->io_ctx->underflow) { } else if (amount_xferred < scb->io_ctx->underflow) {
u_int i;
ahc_print_path(ahc, scb);
printf("CDB:");
for (i = 0; i < scb->io_ctx->cmd_len; i++)
printf(" 0x%x", scb->io_ctx->cmnd[i]);
printf("\n");
ahc_print_path(ahc, scb);
printf("Saw underflow (%ld of %ld bytes). " printf("Saw underflow (%ld of %ld bytes). "
"Treated as error\n", "Treated as error\n",
ahc_get_residual(scb), ahc_get_residual(scb),
...@@ -4815,6 +4844,7 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) ...@@ -4815,6 +4844,7 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
u_int active_scb_index; u_int active_scb_index;
u_int last_phase; u_int last_phase;
u_int saved_scsiid; u_int saved_scsiid;
u_int cdb_byte;
int retval; int retval;
int paused; int paused;
int wait; int wait;
...@@ -4831,6 +4861,11 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) ...@@ -4831,6 +4861,11 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
cmd->device->id, cmd->device->lun, cmd->device->id, cmd->device->lun,
flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
printf("CDB:");
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
printf(" 0x%x", cmd->cmnd[cdb_byte]);
printf("\n");
/* /*
* In all versions of Linux, we have to work around * In all versions of Linux, we have to work around
* a major flaw in how the mid-layer is locked down * a major flaw in how the mid-layer is locked down
......
...@@ -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#123 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#128 $
* *
*/ */
#ifndef _AIC7XXX_LINUX_H_ #ifndef _AIC7XXX_LINUX_H_
...@@ -299,7 +299,7 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec) ...@@ -299,7 +299,7 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec)
#include <linux/smp.h> #include <linux/smp.h>
#endif #endif
#define AIC7XXX_DRIVER_VERSION "6.2.28" #define AIC7XXX_DRIVER_VERSION "6.2.30"
/**************************** Front End Queues ********************************/ /**************************** Front End Queues ********************************/
/* /*
...@@ -907,7 +907,7 @@ int aic7770_map_int(struct ahc_softc *ahc, u_int irq); ...@@ -907,7 +907,7 @@ int aic7770_map_int(struct ahc_softc *ahc, u_int irq);
*/ */
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92)
#if defined(__sparc_v9__) || defined(__powerpc__) #if defined(__sparc_v9__) || defined(__powerpc__)
#error "PPC and Sparc platforms are only support under 2.1.92 and above" #error "PPC and Sparc platforms are only supported under 2.1.92 and above"
#endif #endif
#include <linux/bios32.h> #include <linux/bios32.h>
#endif #endif
......
...@@ -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#57 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#61 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -696,8 +696,12 @@ static void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, ...@@ -696,8 +696,12 @@ static void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
int *externalcable_present, int *externalcable_present,
int *eeprom_present); int *eeprom_present);
static void write_brdctl(struct ahc_softc *ahc, uint8_t value); static void write_brdctl(struct ahc_softc *ahc, uint8_t value);
static uint8_t read_brdctl(struct ahc_softc *ahc); static uint8_t read_brdctl(struct ahc_softc *ahc);
static void ahc_pci_intr(struct ahc_softc *ahc);
static int ahc_pci_chip_init(struct ahc_softc *ahc);
static int ahc_pci_suspend(struct ahc_softc *ahc);
static int ahc_pci_resume(struct ahc_softc *ahc);
static int static int
ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor, ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor,
...@@ -854,6 +858,9 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) ...@@ -854,6 +858,9 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
return (error); return (error);
ahc->bus_intr = ahc_pci_intr; ahc->bus_intr = ahc_pci_intr;
ahc->bus_chip_init = ahc_pci_chip_init;
ahc->bus_suspend = ahc_pci_suspend;
ahc->bus_resume = ahc_pci_resume;
/* Remeber how the card was setup in case there is no SEEPROM */ /* Remeber how the card was setup in case there is no SEEPROM */
if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) { if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
...@@ -993,6 +1000,35 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) ...@@ -993,6 +1000,35 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
if ((sxfrctl1 & STPWEN) != 0) if ((sxfrctl1 & STPWEN) != 0)
ahc->flags |= AHC_TERM_ENB_A; ahc->flags |= AHC_TERM_ENB_A;
/*
* Save chip register configuration data for chip resets
* that occur during runtime and resume events.
*/
ahc->bus_softc.pci_softc.devconfig =
ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
ahc->bus_softc.pci_softc.command =
ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
ahc->bus_softc.pci_softc.csize_lattime =
ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1);
ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
if ((ahc->features & AHC_DT) != 0) {
u_int sfunct;
sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
ahc->bus_softc.pci_softc.optionmode = ahc_inb(ahc, OPTIONMODE);
ahc->bus_softc.pci_softc.targcrccnt = ahc_inw(ahc, TARGCRCCNT);
ahc_outb(ahc, SFUNCT, sfunct);
ahc->bus_softc.pci_softc.crccontrol1 =
ahc_inb(ahc, CRCCONTROL1);
}
if ((ahc->features & AHC_MULTI_FUNC) != 0)
ahc->bus_softc.pci_softc.scbbaddr = ahc_inb(ahc, SCBBADDR);
if ((ahc->features & AHC_ULTRA2) != 0)
ahc->bus_softc.pci_softc.dff_thrsh = ahc_inb(ahc, DFF_THRSH);
/* Core initialization */ /* Core initialization */
error = ahc_init(ahc); error = ahc_init(ahc);
if (error != 0) if (error != 0)
...@@ -1412,6 +1448,7 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1) ...@@ -1412,6 +1448,7 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
} }
if (have_autoterm) { if (have_autoterm) {
ahc->flags |= AHC_HAS_TERM_LOGIC;
ahc_acquire_seeprom(ahc, &sd); ahc_acquire_seeprom(ahc, &sd);
configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1); configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1);
ahc_release_seeprom(&sd); ahc_release_seeprom(&sd);
...@@ -1845,11 +1882,14 @@ aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, ...@@ -1845,11 +1882,14 @@ aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
spiocap |= EXT_BRDCTL; spiocap |= EXT_BRDCTL;
ahc_outb(ahc, SPIOCAP, spiocap); ahc_outb(ahc, SPIOCAP, spiocap);
ahc_outb(ahc, BRDCTL, BRDRW|BRDCS); ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);
ahc_flush_device_writes(ahc);
ahc_delay(500);
ahc_outb(ahc, BRDCTL, 0); ahc_outb(ahc, BRDCTL, 0);
ahc_flush_device_writes(ahc);
ahc_delay(500);
brdctl = ahc_inb(ahc, BRDCTL); brdctl = ahc_inb(ahc, BRDCTL);
*internal50_present = (brdctl & BRDDAT5) ? 0 : 1; *internal50_present = (brdctl & BRDDAT5) ? 0 : 1;
*externalcable_present = (brdctl & BRDDAT6) ? 0 : 1; *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;
*eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0; *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0;
} }
...@@ -1943,7 +1983,7 @@ read_brdctl(ahc) ...@@ -1943,7 +1983,7 @@ read_brdctl(ahc)
return (value); return (value);
} }
void static void
ahc_pci_intr(struct ahc_softc *ahc) ahc_pci_intr(struct ahc_softc *ahc)
{ {
u_int error; u_int error;
...@@ -1995,6 +2035,73 @@ ahc_pci_intr(struct ahc_softc *ahc) ...@@ -1995,6 +2035,73 @@ ahc_pci_intr(struct ahc_softc *ahc)
ahc_unpause(ahc); ahc_unpause(ahc);
} }
static int
ahc_pci_chip_init(struct ahc_softc *ahc)
{
ahc_outb(ahc, DSCOMMAND0, ahc->bus_softc.pci_softc.dscommand0);
ahc_outb(ahc, DSPCISTATUS, ahc->bus_softc.pci_softc.dspcistatus);
if ((ahc->features & AHC_DT) != 0) {
u_int sfunct;
sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
ahc_outb(ahc, OPTIONMODE, ahc->bus_softc.pci_softc.optionmode);
ahc_outw(ahc, TARGCRCCNT, ahc->bus_softc.pci_softc.targcrccnt);
ahc_outb(ahc, SFUNCT, sfunct);
ahc_outb(ahc, CRCCONTROL1,
ahc->bus_softc.pci_softc.crccontrol1);
}
if ((ahc->features & AHC_MULTI_FUNC) != 0)
ahc_outb(ahc, SCBBADDR, ahc->bus_softc.pci_softc.scbbaddr);
if ((ahc->features & AHC_ULTRA2) != 0)
ahc_outb(ahc, DFF_THRSH, ahc->bus_softc.pci_softc.dff_thrsh);
return (ahc_chip_init(ahc));
}
static int
ahc_pci_suspend(struct ahc_softc *ahc)
{
return (ahc_suspend(ahc));
}
static int
ahc_pci_resume(struct ahc_softc *ahc)
{
ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
/*
* We assume that the OS has restored our register
* mappings, etc. Just update the config space registers
* that the OS doesn't know about and rely on our chip
* reset handler to handle the rest.
*/
ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4,
ahc->bus_softc.pci_softc.devconfig);
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1,
ahc->bus_softc.pci_softc.command);
ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1,
ahc->bus_softc.pci_softc.csize_lattime);
if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) {
struct seeprom_descriptor sd;
u_int sxfrctl1;
sd.sd_ahc = ahc;
sd.sd_control_offset = SEECTL;
sd.sd_status_offset = SEECTL;
sd.sd_dataout_offset = SEECTL;
ahc_acquire_seeprom(ahc, &sd);
configure_termination(ahc, &sd,
ahc->seep_config->adapter_control,
&sxfrctl1);
ahc_release_seeprom(&sd);
}
return (ahc_resume(ahc));
}
static int static int
ahc_aic785X_setup(struct ahc_softc *ahc) ahc_aic785X_setup(struct ahc_softc *ahc)
{ {
...@@ -2009,6 +2116,7 @@ ahc_aic785X_setup(struct ahc_softc *ahc) ...@@ -2009,6 +2116,7 @@ ahc_aic785X_setup(struct ahc_softc *ahc)
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
if (rev >= 1) if (rev >= 1)
ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
ahc->instruction_ram_size = 512;
return (0); return (0);
} }
...@@ -2026,6 +2134,7 @@ ahc_aic7860_setup(struct ahc_softc *ahc) ...@@ -2026,6 +2134,7 @@ ahc_aic7860_setup(struct ahc_softc *ahc)
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
if (rev >= 1) if (rev >= 1)
ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
ahc->instruction_ram_size = 512;
return (0); return (0);
} }
...@@ -2049,6 +2158,7 @@ ahc_aic7870_setup(struct ahc_softc *ahc) ...@@ -2049,6 +2158,7 @@ ahc_aic7870_setup(struct ahc_softc *ahc)
ahc->chip = AHC_AIC7870; ahc->chip = AHC_AIC7870;
ahc->features = AHC_AIC7870_FE; ahc->features = AHC_AIC7870_FE;
ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
ahc->instruction_ram_size = 512;
return (0); return (0);
} }
...@@ -2102,6 +2212,7 @@ ahc_aic7880_setup(struct ahc_softc *ahc) ...@@ -2102,6 +2212,7 @@ ahc_aic7880_setup(struct ahc_softc *ahc)
} else { } else {
ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
} }
ahc->instruction_ram_size = 512;
return (0); return (0);
} }
...@@ -2149,6 +2260,7 @@ ahc_aic7890_setup(struct ahc_softc *ahc) ...@@ -2149,6 +2260,7 @@ ahc_aic7890_setup(struct ahc_softc *ahc)
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
if (rev == 0) if (rev == 0)
ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG; ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG;
ahc->instruction_ram_size = 768;
return (0); return (0);
} }
...@@ -2161,6 +2273,7 @@ ahc_aic7892_setup(struct ahc_softc *ahc) ...@@ -2161,6 +2273,7 @@ ahc_aic7892_setup(struct ahc_softc *ahc)
ahc->features = AHC_AIC7892_FE; ahc->features = AHC_AIC7892_FE;
ahc->flags |= AHC_NEWEEPROM_FMT; ahc->flags |= AHC_NEWEEPROM_FMT;
ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG; ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
ahc->instruction_ram_size = 1024;
return (0); return (0);
} }
...@@ -2216,6 +2329,7 @@ ahc_aic7895_setup(struct ahc_softc *ahc) ...@@ -2216,6 +2329,7 @@ ahc_aic7895_setup(struct ahc_softc *ahc)
ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1); ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1);
#endif #endif
ahc->flags |= AHC_NEWEEPROM_FMT; ahc->flags |= AHC_NEWEEPROM_FMT;
ahc->instruction_ram_size = 512;
return (0); return (0);
} }
...@@ -2230,6 +2344,7 @@ ahc_aic7896_setup(struct ahc_softc *ahc) ...@@ -2230,6 +2344,7 @@ ahc_aic7896_setup(struct ahc_softc *ahc)
ahc->features = AHC_AIC7896_FE; ahc->features = AHC_AIC7896_FE;
ahc->flags |= AHC_NEWEEPROM_FMT; ahc->flags |= AHC_NEWEEPROM_FMT;
ahc->bugs |= AHC_CACHETHEN_DIS_BUG; ahc->bugs |= AHC_CACHETHEN_DIS_BUG;
ahc->instruction_ram_size = 768;
return (0); return (0);
} }
...@@ -2244,6 +2359,7 @@ ahc_aic7899_setup(struct ahc_softc *ahc) ...@@ -2244,6 +2359,7 @@ ahc_aic7899_setup(struct ahc_softc *ahc)
ahc->features = AHC_AIC7899_FE; ahc->features = AHC_AIC7899_FE;
ahc->flags |= AHC_NEWEEPROM_FMT; ahc->flags |= AHC_NEWEEPROM_FMT;
ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG; ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
ahc->instruction_ram_size = 1024;
return (0); return (0);
} }
......
...@@ -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#23 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#24 $
*/ */
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
#include "aic7xxx_inline.h" #include "aic7xxx_inline.h"
...@@ -325,6 +325,7 @@ ahc_linux_proc_info(char *buffer, char **start, off_t offset, ...@@ -325,6 +325,7 @@ ahc_linux_proc_info(char *buffer, char **start, off_t offset,
copy_info(&info, "Adaptec AIC7xxx driver version: %s\n", copy_info(&info, "Adaptec AIC7xxx driver version: %s\n",
AIC7XXX_DRIVER_VERSION); AIC7XXX_DRIVER_VERSION);
copy_info(&info, "%s\n", ahc->description);
ahc_controller_info(ahc, ahc_info); ahc_controller_info(ahc, ahc_info);
copy_info(&info, "%s\n\n", ahc_info); copy_info(&info, "%s\n\n", ahc_info);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $
*/ */
typedef int (ahc_reg_print_t)(u_int, u_int *, u_int); typedef int (ahc_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahc_reg_parse_entry { typedef struct ahc_reg_parse_entry {
...@@ -1776,7 +1776,7 @@ ahc_reg_print_t ahc_sg_cache_pre_print; ...@@ -1776,7 +1776,7 @@ ahc_reg_print_t ahc_sg_cache_pre_print;
#define SEQ_MAILBOX_SHIFT 0x00 #define SEQ_MAILBOX_SHIFT 0x00
#define TARGET_DATA_IN 0x01 #define TARGET_DATA_IN 0x01
#define HOST_MSG 0xff #define HOST_MSG 0xff
#define MAX_OFFSET 0xff #define MAX_OFFSET 0x7f
#define BUS_16_BIT 0x01 #define BUS_16_BIT 0x01
#define SCB_UPLOAD_SIZE 0x20 #define SCB_UPLOAD_SIZE 0x20
#define STACK_SIZE 0x04 #define STACK_SIZE 0x04
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $
*/ */
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $
*/ */
static uint8_t seqprog[] = { static uint8_t seqprog[] = {
0xb2, 0x00, 0x00, 0x08, 0xb2, 0x00, 0x00, 0x08,
......
...@@ -11,7 +11,7 @@ GENSRCS= $(YSRCS:.y=.c) $(LSRCS:.l=.c) ...@@ -11,7 +11,7 @@ GENSRCS= $(YSRCS:.y=.c) $(LSRCS:.l=.c)
SRCS= ${CSRCS} ${GENSRCS} SRCS= ${CSRCS} ${GENSRCS}
LIBS= -ldb LIBS= -ldb
CLEANFILES= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG)
# Override default kernel CFLAGS. This is a userland app. # Override default kernel CFLAGS. This is a userland app.
AICASM_CFLAGS:= -I/usr/include -I. AICASM_CFLAGS:= -I/usr/include -I.
YFLAGS= -d YFLAGS= -d
......
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