Commit 5e1c38f4 authored by James Bottomley's avatar James Bottomley

Merge raven.il.steeleye.com:/home/jejb/BK/scsi-misc-2.5

into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.5
parents 7b87c44e 7e0ba223
#
# AIC79XX 2.5.X Kernel configuration File.
# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic79xx#3 $
# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic79xx#4 $
#
config SCSI_AIC79XX
tristate "Adaptec AIC79xx U320 support"
......@@ -59,6 +59,7 @@ config AIC79XX_BUILD_FIRMWARE
config AIC79XX_ENABLE_RD_STRM
bool "Enable Read Streaming for All Targets"
depends on SCSI_AIC79XX
default n
help
Read Streaming is a U320 protocol option that should enhance
performance. Early U320 drive firmware actually performs slower
......
#
# 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
tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
......
......@@ -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#27 $
* $Id: //depot/aic7xxx/aic7xxx/aic7770.c#29 $
*
* $FreeBSD$
*/
......@@ -59,6 +59,9 @@
#define ID_OLV_274x 0x04907782 /* Olivetti OEM */
#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 ahc_device_setup_t ahc_aic7770_VL_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)
ahc->description = entry->name;
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);
if (error != 0)
......@@ -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, BUSTIME, (hostconf << 2) & BOFF);
ahc->bus_softc.aic7770_softc.busspd = hostconf & DFTHRSH;
ahc->bus_softc.aic7770_softc.bustime = (hostconf << 2) & BOFF;
/*
* Generic aic7xxx initialization.
*/
......@@ -253,6 +265,28 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
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.
*/
......@@ -371,5 +405,6 @@ ahc_aic7770_setup(struct ahc_softc *ahc)
ahc->features = AHC_AIC7770_FE;
ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
ahc->flags |= AHC_PAGESCBS;
ahc->instruction_ram_size = 448;
return (0);
}
......@@ -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/aic7770_osm.c#12 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#13 $
*/
#include "aic7xxx_osm.h"
......@@ -66,7 +66,7 @@ aic7770_linux_probe(Scsi_Host_Template *template)
continue;
request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx");
#else
if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") != 0)
if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0)
continue;
#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#78 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#88 $
*
* $FreeBSD$
*/
......@@ -258,27 +258,30 @@ typedef enum {
AHD_PCIX_CHIPRST_BUG = 0x0040,
/* MMAPIO is not functional in PCI-X mode. */
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. */
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
* to perform non-packetized message delivery.
*/
AHD_LQO_ATNO_BUG = 0x0100,
AHD_LQO_ATNO_BUG = 0x0200,
/* FIFO auto-flush does not always trigger. */
AHD_AUTOFLUSH_BUG = 0x0200,
AHD_AUTOFLUSH_BUG = 0x0400,
/* 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. */
AHD_PKTIZED_STATUS_BUG = 0x0800,
AHD_PKTIZED_STATUS_BUG = 0x1000,
/* "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
* 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
* a hardware write to the other DFF SCBPTR register. This is
......@@ -286,30 +289,44 @@ typedef enum {
* this bug have the AHD_NONPACKFIFO_BUG and all writes of concern
* occur in non-packetized connections.
*/
AHD_MDFF_WSCBPTR_BUG = 0x4000,
AHD_MDFF_WSCBPTR_BUG = 0x8000,
/* 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
* switches to a different mode will cause the interrupt to
* 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. */
AHD_BUSFREEREV_BUG = 0x20000,
AHD_BUSFREEREV_BUG = 0x40000,
/*
* Paced transfers are indicated with a non-standard PPR
* option bit in the neg table, 160MHz is indicated by
* 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. */
AHD_LQOOVERRUN_BUG = 0x80000,
AHD_LQOOVERRUN_BUG = 0x100000,
/*
* Controller write to INTSTAT will lose to a host
* 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,
/*
* The LED does not stay on long enough in packetized modes.
*/
AHD_FAINT_LED_BUG = 0x800000
} ahd_bug;
/*
......@@ -319,10 +336,7 @@ typedef enum {
*/
typedef enum {
AHD_FNONE = 0x00000,
AHD_PRIMARY_CHANNEL = 0x00003,/*
* The channel that should
* be probed first.
*/
AHD_BOOT_CHANNEL = 0x00001,/* We were set as the boot channel. */
AHD_USEDEFAULTS = 0x00004,/*
* For cards without an seeprom
* or a BIOS to initialize the chip's
......@@ -411,7 +425,10 @@ typedef uint32_t sense_addr_t;
#define MAX_CDB_LEN 16
#define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t))
union initiator_data {
struct {
uint64_t cdbptr;
uint8_t cdblen;
} cdb_from_host;
uint8_t cdb[MAX_CDB_LEN];
struct {
uint8_t cdb[MAX_CDB_LEN_WITH_SENSE_ADDR];
......@@ -727,7 +744,7 @@ struct ahd_tmode_lstate;
#define AHD_WIDTH_UNKNOWN 0xFF
#define AHD_PERIOD_UNKNOWN 0xFF
#define AHD_OFFSET_UNKNOWN 0x0
#define AHD_OFFSET_UNKNOWN 0xFF
#define AHD_PPR_OPTS_UNKNOWN 0xFF
/*
......@@ -884,6 +901,40 @@ struct seeprom_config {
uint16_t checksum; /* word 31 */
};
/*
* Vital Product Data used during POST and by the BIOS.
*/
struct vpd_config {
uint8_t bios_flags;
#define VPDMASTERBIOS 0x0001
#define VPDBOOTHOST 0x0002
uint8_t reserved_1[21];
uint8_t resource_type;
uint8_t resource_len[2];
uint8_t resource_data[8];
uint8_t vpd_tag;
uint16_t vpd_len;
uint8_t vpd_keyword[2];
uint8_t length;
uint8_t revision;
uint8_t device_flags;
uint8_t termnation_menus[2];
uint8_t fifo_threshold;
uint8_t end_tag;
uint8_t vpd_checksum;
uint16_t default_target_flags;
uint16_t default_bios_flags;
uint16_t default_ctrl_flags;
uint8_t default_irq;
uint8_t pci_lattime;
uint8_t max_target;
uint8_t boot_lun;
uint16_t signature;
uint8_t reserved_2;
uint8_t checksum;
uint8_t reserved_3[4];
};
/****************************** Flexport Logic ********************************/
#define FLXADDR_TERMCTL 0x0
#define FLX_TERMCTL_ENSECHIGH 0x8
......@@ -916,11 +967,12 @@ struct seeprom_config {
#define FLX_CSTAT_INVALID 0x3
int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
u_int start_addr, u_int count);
u_int start_addr, u_int count, int bstream);
int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
u_int start_addr, u_int count);
int ahd_wait_seeprom(struct ahd_softc *ahd);
int ahd_verify_vpd_cksum(struct vpd_config *vpd);
int ahd_verify_cksum(struct seeprom_config *sc);
int ahd_acquire_seeprom(struct ahd_softc *ahd);
void ahd_release_seeprom(struct ahd_softc *ahd);
......@@ -1305,6 +1357,8 @@ int ahd_softc_init(struct ahd_softc *);
void ahd_controller_info(struct ahd_softc *ahd, char *buf);
int ahd_init(struct ahd_softc *ahd);
int ahd_default_config(struct ahd_softc *ahd);
int ahd_parse_vpddata(struct ahd_softc *ahd,
struct vpd_config *vpd);
int ahd_parse_cfgdata(struct ahd_softc *ahd,
struct seeprom_config *sc);
void ahd_intr_enable(struct ahd_softc *ahd, int enable);
......
......@@ -39,7 +39,7 @@
*
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $"
/*
* This file is processed by the aic7xxx_asm utility for use in assembling
......@@ -2071,14 +2071,14 @@ register LQIMODE1 {
address 0x051
access_mode RW
modes M_CFG
field ENLQIPHASE_LQ 0x80
field ENLQIPHASE_NLQ 0x40
field ENLQIPHASE_LQ 0x80 /* LQIPHASE1 */
field ENLQIPHASE_NLQ 0x40 /* LQIPHASE2 */
field ENLIQABORT 0x20
field ENLQICRCI_LQ 0x10
field ENLQICRCI_NLQ 0x08
field ENLQICRCI_LQ 0x10 /* LQICRCI1 */
field ENLQICRCI_NLQ 0x08 /* LQICRCI2 */
field ENLQIBADLQI 0x04
field ENLQIOVERI_LQ 0x02
field ENLQIOVERI_NLQ 0x01
field ENLQIOVERI_LQ 0x02 /* LQIOVERI1 */
field ENLQIOVERI_NLQ 0x01 /* LQIOVERI2 */
}
/*
......@@ -2545,10 +2545,10 @@ const AHD_PRECOMP_CUTBACK_37 0x07
const AHD_SLEWRATE_MASK 0x78
const AHD_SLEWRATE_SHIFT 3
/*
* Rev A has only a single bit of slew adjustment.
* Rev B has 4 bits.
* Rev A has only a single bit (high bit of field) of slew adjustment.
* Rev B has 4 bits. The current default happens to be the same for both.
*/
const AHD_SLEWRATE_DEF_REVA 0x01
const AHD_SLEWRATE_DEF_REVA 0x08
const AHD_SLEWRATE_DEF_REVB 0x08
/* Rev A does not have any amplitude setting. */
......@@ -3769,16 +3769,17 @@ scb {
SCB_RESIDUAL_DATACNT {
size 4
alias SCB_CDB_STORE
alias SCB_HOST_CDB_PTR
}
SCB_RESIDUAL_SGPTR {
size 4
alias SCB_CDB_PTR
field SG_ADDR_MASK 0xf8 /* In the last byte */
field SG_OVERRUN_RESID 0x02 /* In the first byte */
field SG_LIST_NULL 0x01 /* In the first byte */
}
SCB_SCSI_STATUS {
size 1
alias SCB_HOST_CDB_LEN
}
SCB_TARGET_PHASES {
size 1
......
This diff is collapsed.
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#41 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#44 $
*
* $FreeBSD$
*/
......@@ -678,6 +678,7 @@ ahd_inb_scbram(struct ahd_softc *ahd, u_int offset)
* Razor #528
*/
value = ahd_inb(ahd, offset);
if ((ahd->flags & AHD_PCIX_SCBRAM_RD_BUG) != 0)
ahd_inb(ahd, MODE_PTR);
return (value);
}
......
This diff is collapsed.
......@@ -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#108 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#121 $
*
*/
#ifndef _AIC79XX_LINUX_H_
......@@ -92,6 +92,7 @@
* Compile in debugging code, but do not enable any printfs.
*/
#define AHD_DEBUG 1
#define AHD_DEBUG_OPTS 0
#endif
/* No debugging code. */
#endif
......@@ -286,7 +287,13 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
#include <linux/smp.h>
#endif
#define AIC79XX_DRIVER_VERSION "1.3.0"
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
#define AHD_SCSI_HAS_HOST_LOCK 1
#else
#define AHD_SCSI_HAS_HOST_LOCK 0
#endif
#define AIC79XX_DRIVER_VERSION "1.3.5"
/**************************** Front End Queues ********************************/
/*
......@@ -487,7 +494,7 @@ struct ahd_linux_target {
* Per-SCB OSM storage.
*/
typedef enum {
AHD_UP_EH_SEMAPHORE = 0x1
AHD_SCB_UP_EH_SEM = 0x1
} ahd_linux_scb_flags;
struct scb_platform_data {
......@@ -733,7 +740,6 @@ ahd_lockinit(struct ahd_softc *ahd)
static __inline void
ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
{
*flags = 0;
spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
}
......@@ -747,23 +753,24 @@ static __inline void
ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags)
{
/*
* In 2.5.X, the midlayer takes our lock just before
* calling us, so avoid locking again.
* In 2.5.X and some 2.4.X versions, the midlayer takes our
* lock just before calling us, so we avoid locking again.
* For other kernel versions, the io_request_lock is taken
* just before our entry point is called. In this case, we
* trade the io_request_lock for our per-softc lock.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_lock(ahd, flags);
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock(&io_request_lock);
spin_lock(&ahd->platform_data->spin_lock);
#endif
}
static __inline void
ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
/*
* In 2.5.X, the midlayer takes our lock just before
* calling us and unlocks when we return, so let it do the unlock.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, flags);
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock(&ahd->platform_data->spin_lock);
spin_lock(&io_request_lock);
#endif
}
......@@ -780,17 +787,16 @@ ahd_done_lockinit(struct ahd_softc *ahd)
static __inline void
ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
*flags = 0;
spin_lock_irqsave(&io_request_lock, *flags);
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_lock(&io_request_lock);
#endif
}
static __inline void
ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_unlock_irqrestore(&io_request_lock, *flags);
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock(&io_request_lock);
#endif
}
......@@ -803,7 +809,6 @@ ahd_list_lockinit()
static __inline void
ahd_list_lock(unsigned long *flags)
{
*flags = 0;
spin_lock_irqsave(&ahd_list_spinlock, *flags);
}
......@@ -822,7 +827,6 @@ ahd_lockinit(struct ahd_softc *ahd)
static __inline void
ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
{
*flags = 0;
save_flags(*flags);
cli();
}
......@@ -860,7 +864,6 @@ ahd_list_lockinit()
static __inline void
ahd_list_lock(unsigned long *flags)
{
*flags = 0;
save_flags(*flags);
cli();
}
......@@ -947,7 +950,7 @@ void ahd_power_state_change(struct ahd_softc *ahd,
*/
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92)
#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
#include <linux/bios32.h>
#endif
......
......@@ -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#20 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#21 $
*/
#include "aic79xx_osm.h"
......
......@@ -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#61 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#70 $
*
* $FreeBSD$
*/
......@@ -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_IROC 0x809D9005FFFF9005ull
#define ID_AHA_39320 0x8010900500409005ull
#define ID_AHA_39320A 0x8016900500409005ull
#define ID_AHA_39320D 0x8011900500419005ull
#define ID_AHA_39320D_B 0x801C900500419005ull
#define ID_AHA_39320D_HP 0x8011900500AC0E11ull
......@@ -137,6 +138,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
"Adaptec 39320 Ultra320 SCSI adapter",
ahd_aic7902_setup
},
{
ID_AHA_39320A,
ID_ALL_MASK,
"Adaptec 39320A Ultra320 SCSI adapter",
ahd_aic7902_setup
},
{
ID_AHA_39320D,
ID_ALL_MASK,
......@@ -378,12 +385,10 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
int
ahd_pci_test_register_access(struct ahd_softc *ahd)
{
ahd_mode_state saved_modes;
uint32_t cmd;
int error;
uint8_t hcntrl;
saved_modes = ahd_save_modes(ahd);
error = EIO;
/*
......@@ -449,7 +454,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
ahd_outb(ahd, CLRINT, CLRPCIINT);
}
ahd_restore_modes(ahd, saved_modes);
ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
return (error);
......@@ -462,6 +466,7 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
static int
ahd_check_extport(struct ahd_softc *ahd)
{
struct vpd_config vpd;
struct seeprom_config *sc;
u_int adapter_control;
int have_seeprom;
......@@ -472,6 +477,27 @@ ahd_check_extport(struct ahd_softc *ahd)
if (have_seeprom) {
u_int start_addr;
/*
* Fetch VPD for this function and parse it.
*/
if (bootverbose)
printf("%s: Reading VPD from SEEPROM...",
ahd_name(ahd));
/* Address is always in units of 16bit words */
start_addr = ((2 * sizeof(*sc))
+ (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
start_addr, sizeof(vpd)/2,
/*bytestream*/TRUE);
if (error == 0)
error = ahd_parse_vpddata(ahd, &vpd);
if (bootverbose)
printf("%s: VPD parsing %s\n",
ahd_name(ahd),
error == 0 ? "successful" : "failed");
if (bootverbose)
printf("%s: Reading SEEPROM...", ahd_name(ahd));
......@@ -479,7 +505,8 @@ ahd_check_extport(struct ahd_softc *ahd)
start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
error = ahd_read_seeprom(ahd, (uint16_t *)sc,
start_addr, sizeof(*sc)/2);
start_addr, sizeof(*sc)/2,
/*bytestream*/FALSE);
if (error != 0) {
printf("Unable to read SEEPROM\n");
......@@ -698,7 +725,7 @@ static const char *split_status_strings[] =
"%s: Split completion data bucket in %s\n",
"%s: Split completion address 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[] =
......@@ -799,7 +826,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
/* Clear latched errors. So our interrupt deasserts. */
ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
if (i != 0)
if (i > 1)
continue;
sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
......@@ -821,7 +848,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
split_status_source[i]);
}
if (i != 0)
if (i > 1)
continue;
if ((sg_split_status[i] & (0x1 << bit)) != 0) {
......@@ -879,11 +906,12 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
| AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
| AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
| AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
| AHD_PCIX_CHIPRST_BUG|AHD_PKTIZED_STATUS_BUG
| AHD_PKT_LUN_BUG|AHD_MDFF_WSCBPTR_BUG
| AHD_REG_SLOW_SETTLE_BUG|AHD_SET_MODE_BUG
| AHD_BUSFREEREV_BUG|AHD_NONPACKFIFO_BUG
| AHD_PACED_NEGTABLE_BUG;
| AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
| AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
| AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
| AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
| AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
| AHD_FAINT_LED_BUG;
/*
* IO Cell paramter setup.
......@@ -898,7 +926,7 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
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_INTCOLLISION_BUG|AHD_EARLY_REQ_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#11 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#14 $
*/
#include "aic79xx_osm.h"
#include "aic79xx_inline.h"
......@@ -124,8 +124,12 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
printed_options = 0;
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) {
copy_info(info, " DT");
copy_info(info, "%s", printed_options ? "|DT" : " DT");
printed_options++;
}
if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
......@@ -258,7 +262,8 @@ ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length)
ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr,
sizeof(struct seeprom_config)/2);
ahd_read_seeprom(ahd, (uint16_t *)ahd->seep_config,
start_addr, sizeof(struct seeprom_config)/2);
start_addr, sizeof(struct seeprom_config)/2,
/*ByteStream*/FALSE);
ahd_release_seeprom(ahd);
written = length;
}
......@@ -311,6 +316,7 @@ ahd_linux_proc_info(char *buffer, char **start, off_t offset,
copy_info(&info, "Adaptec AIC79xx driver version: %s\n",
AIC79XX_DRIVER_VERSION);
copy_info(&info, "%s\n", ahd->description);
ahd_controller_info(ahd, ahd_info);
copy_info(&info, "%s\n\n", ahd_info);
......
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $
*/
typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahd_reg_parse_entry {
......@@ -3638,13 +3638,14 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SCB_RESIDUAL_DATACNT 0x180
#define SCB_CDB_STORE 0x180
#define SCB_HOST_CDB_PTR 0x180
#define SCB_RESIDUAL_SGPTR 0x184
#define SCB_CDB_PTR 0x184
#define SG_ADDR_MASK 0xf8
#define SG_OVERRUN_RESID 0x02
#define SCB_SCSI_STATUS 0x188
#define SCB_HOST_CDB_LEN 0x188
#define SCB_TARGET_PHASES 0x189
......@@ -3719,7 +3720,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define AHD_AMPLITUDE_SHIFT 0x00
#define AHD_AMPLITUDE_MASK 0x07
#define AHD_ANNEXCOL_AMPLITUDE 0x06
#define AHD_SLEWRATE_DEF_REVA 0x01
#define AHD_SLEWRATE_DEF_REVA 0x08
#define AHD_SLEWRATE_SHIFT 0x03
#define AHD_SLEWRATE_MASK 0x78
#define AHD_PRECOMP_CUTBACK_29 0x06
......@@ -3774,5 +3775,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
/* Exported Labels */
#define LABEL_seq_isr 0x263
#define LABEL_timer_isr 0x25f
#define LABEL_seq_isr 0x26d
#define LABEL_timer_isr 0x269
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $
*/
#include "aic79xx_osm.h"
......
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#70 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#74 $
*
* $FreeBSD$
*/
......@@ -365,7 +365,8 @@ typedef enum {
AHC_LSCBS_ENABLED = 0x2000000, /* 64Byte SCBs enabled */
AHC_SCB_CONFIG_USED = 0x4000000, /* No SEEPROM but SCB2 had info. */
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;
/************************* Hardware SCB Definition ***************************/
......@@ -691,7 +692,7 @@ struct ahc_tmode_lstate;
#define AHC_WIDTH_UNKNOWN 0xFF
#define AHC_PERIOD_UNKNOWN 0xFF
#define AHC_OFFSET_UNKNOWN 0x0
#define AHC_OFFSET_UNKNOWN 0xFF
#define AHC_PPR_OPTS_UNKNOWN 0xFF
/*
......@@ -877,31 +878,39 @@ typedef enum {
/*********************** Software Configuration Structure *********************/
TAILQ_HEAD(scb_tailq, scb);
struct ahc_suspend_channel_state {
uint8_t scsiseq;
uint8_t sxfrctl0;
uint8_t sxfrctl1;
uint8_t simode0;
uint8_t simode1;
uint8_t seltimer;
uint8_t seqctl;
struct ahc_aic7770_softc {
/*
* Saved register state used for chip_init().
*/
uint8_t busspd;
uint8_t bustime;
};
struct ahc_suspend_state {
struct ahc_suspend_channel_state channel[2];
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;
/* hsmailbox */
uint8_t crccontrol1;
uint8_t scbbaddr;
/* Host and sequencer SCB counts */
uint8_t dff_thrsh;
uint8_t *scratch_ram;
uint8_t *btt;
};
union ahc_bus_softc {
struct ahc_aic7770_softc aic7770_softc;
struct ahc_pci_softc pci_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 *);
struct ahc_softc {
......@@ -936,6 +945,11 @@ struct ahc_softc {
*/
struct scb_tailq untagged_queues[AHC_NUM_TARGETS];
/*
* Bus attachment specific data.
*/
union ahc_bus_softc bus_softc;
/*
* Platform specific data.
*/
......@@ -951,6 +965,22 @@ struct ahc_softc {
*/
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.
* Targets that are not enabled will have null entries.
......@@ -1043,9 +1073,6 @@ struct ahc_softc {
*/
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 */
u_int enabled_luns;
......@@ -1055,7 +1082,8 @@ struct ahc_softc {
/* PCI cacheline size. */
u_int pci_cachesize;
u_int stack_size;
/* Maximum number of sequencer instructions supported. */
u_int instruction_ram_size;
/* Per-Unit descriptive information */
const char *description;
......@@ -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);
int ahc_softc_init(struct ahc_softc *);
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);
void ahc_intr_enable(struct ahc_softc *ahc, int enable);
void ahc_pause_and_flushwork(struct ahc_softc *ahc);
......@@ -1167,7 +1196,6 @@ int ahc_reset(struct ahc_softc *ahc);
void ahc_shutdown(void *arg);
/*************************** Interrupt Services *******************************/
void ahc_pci_intr(struct ahc_softc *ahc);
void ahc_clear_intstat(struct ahc_softc *ahc);
void ahc_run_qoutfifo(struct ahc_softc *ahc);
#ifdef AHC_TARGET_MODE
......
......@@ -39,7 +39,7 @@
*
* $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
......@@ -1580,7 +1580,7 @@ const BUS_32_BIT 0x02
const MAX_OFFSET_8BIT 0x0f
const MAX_OFFSET_16BIT 0x08
const MAX_OFFSET_ULTRA2 0x7f
const MAX_OFFSET 0xff
const MAX_OFFSET 0x7f
const HOST_MSG 0xff
/* Target mode command processing constants */
......
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_inline.h#39 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#40 $
*
* $FreeBSD$
*/
......
This diff is collapsed.
......@@ -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#123 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#131 $
*
*/
#ifndef _AIC7XXX_LINUX_H_
......@@ -299,7 +299,13 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec)
#include <linux/smp.h>
#endif
#define AIC7XXX_DRIVER_VERSION "6.2.28"
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
#define AHC_SCSI_HAS_HOST_LOCK 1
#else
#define AHC_SCSI_HAS_HOST_LOCK 0
#endif
#define AIC7XXX_DRIVER_VERSION "6.2.31"
/**************************** Front End Queues ********************************/
/*
......@@ -703,7 +709,6 @@ ahc_lockinit(struct ahc_softc *ahc)
static __inline void
ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
{
*flags = 0;
spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);
}
......@@ -717,10 +722,13 @@ static __inline void
ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags)
{
/*
* In 2.5.X, the midlayer takes our lock just before
* calling us, so avoid locking again.
* In 2.5.X and some 2.4.X versions, the midlayer takes our
* lock just before calling us, so we avoid locking again.
* For other kernel versions, the io_request_lock is taken
* just before our entry point is called. In this case, we
* trade the io_request_lock for our per-softc lock.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#if AHC_SCSI_HAS_HOST_LOCK == 0
ahc_lock(ahc, flags);
#endif
}
......@@ -728,11 +736,7 @@ ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags)
static __inline void
ahc_midlayer_entrypoint_unlock(struct ahc_softc *ahc, unsigned long *flags)
{
/*
* In 2.5.X, the midlayer takes our lock just before
* calling us and unlocks when we return, so let it do the unlock.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#if AHC_SCSI_HAS_HOST_LOCK == 0
ahc_unlock(ahc, flags);
#endif
}
......@@ -750,8 +754,7 @@ ahc_done_lockinit(struct ahc_softc *ahc)
static __inline void
ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
*flags = 0;
#if AHC_SCSI_HAS_HOST_LOCK == 0
spin_lock_irqsave(&io_request_lock, *flags);
#endif
}
......@@ -759,7 +762,7 @@ ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags)
static __inline void
ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#if AHC_SCSI_HAS_HOST_LOCK == 0
spin_unlock_irqrestore(&io_request_lock, *flags);
#endif
}
......@@ -773,7 +776,6 @@ ahc_list_lockinit()
static __inline void
ahc_list_lock(unsigned long *flags)
{
*flags = 0;
spin_lock_irqsave(&ahc_list_spinlock, *flags);
}
......@@ -793,7 +795,6 @@ ahc_lockinit(struct ahc_softc *ahc)
static __inline void
ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
{
*flags = 0;
save_flags(*flags);
cli();
}
......@@ -832,7 +833,6 @@ ahc_list_lockinit()
static __inline void
ahc_list_lock(unsigned long *flags)
{
*flags = 0;
save_flags(*flags);
cli();
}
......@@ -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 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
#include <linux/bios32.h>
#endif
......
......@@ -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#43 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#44 $
*/
#include "aic7xxx_osm.h"
......
......@@ -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#57 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#62 $
*
* $FreeBSD$
*/
......@@ -698,6 +698,10 @@ static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
int *eeprom_present);
static void write_brdctl(struct ahc_softc *ahc, uint8_t value);
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
ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor,
......@@ -748,10 +752,7 @@ ahc_find_pci_device(ahc_dev_softc_t pci)
device = ahc_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
subvendor = ahc_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
subdevice = ahc_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
full_id = ahc_compose_id(device,
vendor,
subdevice,
subvendor);
full_id = ahc_compose_id(device, vendor, subdevice, subvendor);
/*
* If the second function is not hooked up, ignore it.
......@@ -854,6 +855,9 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
return (error);
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 */
if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
......@@ -993,6 +997,35 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
if ((sxfrctl1 & STPWEN) != 0)
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 */
error = ahc_init(ahc);
if (error != 0)
......@@ -1412,6 +1445,7 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
}
if (have_autoterm) {
ahc->flags |= AHC_HAS_TERM_LOGIC;
ahc_acquire_seeprom(ahc, &sd);
configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1);
ahc_release_seeprom(&sd);
......@@ -1845,11 +1879,14 @@ aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
spiocap |= EXT_BRDCTL;
ahc_outb(ahc, SPIOCAP, spiocap);
ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);
ahc_flush_device_writes(ahc);
ahc_delay(500);
ahc_outb(ahc, BRDCTL, 0);
ahc_flush_device_writes(ahc);
ahc_delay(500);
brdctl = ahc_inb(ahc, BRDCTL);
*internal50_present = (brdctl & BRDDAT5) ? 0 : 1;
*externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;
*eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0;
}
......@@ -1943,7 +1980,7 @@ read_brdctl(ahc)
return (value);
}
void
static void
ahc_pci_intr(struct ahc_softc *ahc)
{
u_int error;
......@@ -1995,6 +2032,73 @@ ahc_pci_intr(struct ahc_softc *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
ahc_aic785X_setup(struct ahc_softc *ahc)
{
......@@ -2009,6 +2113,7 @@ ahc_aic785X_setup(struct ahc_softc *ahc)
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
if (rev >= 1)
ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
ahc->instruction_ram_size = 512;
return (0);
}
......@@ -2026,6 +2131,7 @@ ahc_aic7860_setup(struct ahc_softc *ahc)
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
if (rev >= 1)
ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
ahc->instruction_ram_size = 512;
return (0);
}
......@@ -2049,6 +2155,7 @@ ahc_aic7870_setup(struct ahc_softc *ahc)
ahc->chip = AHC_AIC7870;
ahc->features = AHC_AIC7870_FE;
ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
ahc->instruction_ram_size = 512;
return (0);
}
......@@ -2102,6 +2209,7 @@ ahc_aic7880_setup(struct ahc_softc *ahc)
} else {
ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
}
ahc->instruction_ram_size = 512;
return (0);
}
......@@ -2149,6 +2257,7 @@ ahc_aic7890_setup(struct ahc_softc *ahc)
rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
if (rev == 0)
ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG;
ahc->instruction_ram_size = 768;
return (0);
}
......@@ -2161,6 +2270,7 @@ ahc_aic7892_setup(struct ahc_softc *ahc)
ahc->features = AHC_AIC7892_FE;
ahc->flags |= AHC_NEWEEPROM_FMT;
ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
ahc->instruction_ram_size = 1024;
return (0);
}
......@@ -2216,6 +2326,7 @@ ahc_aic7895_setup(struct ahc_softc *ahc)
ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1);
#endif
ahc->flags |= AHC_NEWEEPROM_FMT;
ahc->instruction_ram_size = 512;
return (0);
}
......@@ -2230,6 +2341,7 @@ ahc_aic7896_setup(struct ahc_softc *ahc)
ahc->features = AHC_AIC7896_FE;
ahc->flags |= AHC_NEWEEPROM_FMT;
ahc->bugs |= AHC_CACHETHEN_DIS_BUG;
ahc->instruction_ram_size = 768;
return (0);
}
......@@ -2244,6 +2356,7 @@ ahc_aic7899_setup(struct ahc_softc *ahc)
ahc->features = AHC_AIC7899_FE;
ahc->flags |= AHC_NEWEEPROM_FMT;
ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
ahc->instruction_ram_size = 1024;
return (0);
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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