Commit 0b5b4664 authored by Justin T. Gibbs's avatar Justin T. Gibbs

Aic7xxx Driver Update:

  o Determine more conclusively that a BIOS has initialized the
    adapter before using "left over BIOS settings".
  o Adapt to upcoming removal of cmd->target/channel/lun/host in 2.5.X
  o Fix a memory leak on driver unload.
  o Enable the pci_parity command line option and default to pci parity
    error detection *disabled*.  There are just too many broken VIA
    chipsets out there.
  o Move more functionality into aiclib to share with the aic79xx driver.
  o Correct a few negotiation regressions.
  o Don't bother doing full DV on devices that only support async transfers.
    This should fix a few more of the reported problems with DV.

Aic79xx Driver Update
  o Add abort and bus device reset handlers.
  o Fix a memory leak on driver unload.
  o Adapt to upcoming removal of cmd->target/channel/lun/host in 2.5.X.
  o Correct a few negotiation regressions.
parent 8aecd34f
......@@ -2,7 +2,7 @@
* Core routines and tables shareable across OS platforms.
*
* Copyright (c) 1994-2002 Justin T. Gibbs.
* Copyright (c) 2000-2002 Adaptec Inc.
* Copyright (c) 2000-2003 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -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.c#151 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#153 $
*
* $FreeBSD$
*/
......@@ -171,8 +171,8 @@ static void ahd_handle_ign_wide_residue(struct ahd_softc *ahd,
static void ahd_reinitialize_dataptrs(struct ahd_softc *ahd);
static void ahd_handle_devreset(struct ahd_softc *ahd,
struct ahd_devinfo *devinfo,
cam_status status, char *message,
int verbose_level);
u_int lun, cam_status status,
char *message, int verbose_level);
#if AHD_TARGET_MODE
static void ahd_setup_target_msgin(struct ahd_softc *ahd,
struct ahd_devinfo *devinfo,
......@@ -688,8 +688,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
&tstate);
tinfo = &targ_info->curr;
ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
/*paused*/TRUE);
AHD_TRANS_ACTIVE, /*paused*/TRUE);
ahd_set_syncrate(ahd, &devinfo, /*period*/0,
/*offset*/0, /*ppr_options*/0,
AHD_TRANS_ACTIVE, /*paused*/TRUE);
......@@ -1016,6 +1015,9 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
u_int tag;
cam_status error;
ahd_print_path(ahd, scb);
printf("Task Management Func 0x%x Complete\n",
scb->hscb->task_management);
lun = CAM_LUN_WILDCARD;
tag = SCB_LIST_NULL;
......@@ -1026,18 +1028,30 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
case SIU_TASKMGMT_CLEAR_TASK_SET:
lun = scb->hscb->lun;
error = CAM_REQ_ABORTED;
ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
'A', lun, tag, ROLE_INITIATOR,
error);
break;
case SIU_TASKMGMT_LUN_RESET:
lun = scb->hscb->lun;
case SIU_TASKMGMT_TARGET_RESET:
{
struct ahd_devinfo devinfo;
ahd_scb_devinfo(ahd, &devinfo, scb);
error = CAM_BDR_SENT;
ahd_handle_devreset(ahd, &devinfo, lun,
CAM_BDR_SENT,
lun != CAM_LUN_WILDCARD
? "Lun Reset"
: "Target Reset",
/*verbose_level*/0);
break;
}
default:
panic("Unexpected TaskMgmt Func\n");
break;
}
ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
'A', lun, tag, ROLE_INITIATOR, error);
}
break;
}
......@@ -1046,13 +1060,31 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
u_int scbid;
struct scb *scb;
/*
* An ABORT TASK TMF failed to be delivered before
* the targeted command completed normally.
*/
scbid = ahd_get_scbptr(ahd);
scb = ahd_lookup_scb(ahd, scbid);
if (scb != NULL) {
/*
* Remove the second instance of this SCB from
* Remove the second instance of this SCB from
* the QINFIFO if it is still there.
*/
ahd_print_path(ahd, scb);
printf("SCB completes before TMF\n");
/*
* Handle losing the race. Wait until any
* current selection completes. We will then
* set the TMF back to zero in this SCB so that
* the sequencer doesn't bother to issue another
* sequencer interrupt for its completion.
*/
while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
&& (ahd_inb(ahd, SSTAT0) & SELDO) == 0
&& (ahd_inb(ahd, SSTAT1) & SELTO) == 0)
;
ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0);
ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
SCB_GET_CHANNEL(ahd, scb),
SCB_GET_LUN(scb), scb->hscb->tag,
......@@ -1784,8 +1816,8 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
ROLE_INITIATOR))
ahd_set_transaction_status(scb, CAM_REQ_CMP);
#endif
ahd_handle_devreset(ahd, &devinfo, CAM_BDR_SENT,
"Bus Device Reset",
ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
CAM_BDR_SENT, "Bus Device Reset",
/*verbose_level*/0);
printerror = 0;
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)
......@@ -3692,8 +3724,8 @@ ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full)
if (type == AHDMSG_1B
&& ahd->msgout_index > index
&& (ahd->msgout_buf[index] == msgval
|| ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0))
&& msgval == MSG_IDENTIFYFLAG)
|| ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0
&& msgval == MSG_IDENTIFYFLAG)))
found = TRUE;
index++;
}
......@@ -4039,7 +4071,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
}
#ifdef AHD_TARGET_MODE
case MSG_BUS_DEV_RESET:
ahd_handle_devreset(ahd, devinfo,
ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD,
CAM_BDR_SENT,
"Bus Device Reset Received",
/*verbose_level*/0);
......@@ -4538,16 +4570,16 @@ ahd_reinitialize_dataptrs(struct ahd_softc *ahd)
*/
static void
ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
cam_status status, char *message, int verbose_level)
u_int lun, cam_status status, char *message,
int verbose_level)
{
#ifdef AHD_TARGET_MODE
struct ahd_tmode_tstate* tstate;
u_int lun;
#endif
int found;
found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
lun, SCB_LIST_NULL, devinfo->role,
status);
#ifdef AHD_TARGET_MODE
......@@ -4557,10 +4589,20 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
*/
tstate = ahd->enabled_targets[devinfo->our_scsiid];
if (tstate != NULL) {
for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
u_int cur_lun;
u_int max_lun;
if (lun != CAM_LUN_WILDCARD) {
cur_lun = 0;
max_lun = AHD_NUM_LUNS - 1;
} else {
cur_lun = lun;
max_lun = lun;
}
for (cur_lun <= max_lun; cur_lun++) {
struct ahd_tmode_lstate* lstate;
lstate = tstate->enabled_luns[lun];
lstate = tstate->enabled_luns[cur_lun];
if (lstate == NULL)
continue;
......@@ -4580,7 +4622,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
/*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE);
ahd_send_async(ahd, devinfo->channel, devinfo->target,
CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
lun, AC_SENT_BDR, NULL);
if (message != NULL
&& (verbose_level <= bootverbose))
......
......@@ -2,7 +2,7 @@
* Inline routines shareable across OS platforms.
*
* Copyright (c) 1994-2001 Justin T. Gibbs.
* Copyright (c) 2000-2002 Adaptec Inc.
* Copyright (c) 2000-2003 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -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#40 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#41 $
*
* $FreeBSD$
*/
......@@ -272,7 +272,6 @@ ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb)
if ((scb->flags & SCB_PACKETIZED) != 0) {
/* XXX what about ACA?? It is type 4, but TAG_TYPE == 0x3. */
scb->hscb->task_attribute= scb->hscb->control & SCB_TAG_TYPE;
scb->hscb->task_management = 0;
/*
* For Rev A short lun workaround.
*/
......
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#102 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#106 $
*
*/
#ifndef _AIC79XX_LINUX_H_
......@@ -55,6 +55,7 @@
#endif
#include <linux/module.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
......@@ -72,7 +73,6 @@
#define AIC_LIB_PREFIX ahd
#include "scsi.h"
#include "hosts.h"
#include "aiclib.h"
/* Name space conflict with BSD queue macros */
#ifdef LIST_HEAD
......@@ -83,6 +83,7 @@
#include "queue.h"
#include "scsi_message.h"
#include "scsi_iu.h"
#include "aiclib.h"
/*********************************** Debugging ********************************/
#ifdef CONFIG_AIC79XX_DEBUG_ENABLE
......@@ -288,7 +289,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
#include <linux/smp.h>
#endif
#define AIC79XX_DRIVER_VERSION "1.3.0.BETA2"
#define AIC79XX_DRIVER_VERSION "1.3.0.RC1"
/**************************** Front End Queues ********************************/
/*
......@@ -489,7 +490,7 @@ struct ahd_linux_target {
* Per-SCB OSM storage.
*/
typedef enum {
AHD_UP_EH_SEMAPHORE
AHD_UP_EH_SEMAPHORE = 0x1
} ahd_linux_scb_flags;
struct scb_platform_data {
......@@ -543,6 +544,7 @@ struct ahd_platform_data {
struct semaphore dv_cmd_sem; /* XXX This needs to be in
* the target struct
*/
struct scsi_device *dv_scsi_dev;
struct Scsi_Host *host; /* pointer to scsi host */
#define AHD_LINUX_NOIRQ ((uint32_t)~0)
uint32_t irq; /* IRQ for this adapter */
......
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $
*/
typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahd_reg_parse_entry {
......@@ -2367,11 +2367,13 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SPLTINT 0x01
#define SEQINTCODE 0x02
#define SAW_HWERR 0x17
#define TRACEPOINT3 0x16
#define TRACEPOINT2 0x15
#define TRACEPOINT1 0x14
#define TRACEPOINT0 0x13
#define SAW_HWERR 0x19
#define TRACEPOINT3 0x18
#define TRACEPOINT2 0x17
#define TRACEPOINT1 0x16
#define TRACEPOINT0 0x15
#define TASKMGMT_CMD_CMPLT_OKAY 0x14
#define TASKMGMT_FUNC_COMPLETE 0x13
#define ENTERING_NONPACK 0x12
#define CFG4OVERRUN 0x11
#define STATUS_OVERRUN 0x10
......@@ -3772,5 +3774,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
/* Exported Labels */
#define LABEL_seq_isr 0x25a
#define LABEL_timer_isr 0x256
#define LABEL_seq_isr 0x263
#define LABEL_timer_isr 0x25f
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $
*/
#include "aic79xx_osm.h"
......@@ -59,17 +59,19 @@ static ahd_reg_parse_entry_t SEQINTCODE_parse_table[] = {
{ "STATUS_OVERRUN", 0x10, 0xff },
{ "CFG4OVERRUN", 0x11, 0xff },
{ "ENTERING_NONPACK", 0x12, 0xff },
{ "TRACEPOINT0", 0x13, 0xff },
{ "TRACEPOINT1", 0x14, 0xff },
{ "TRACEPOINT2", 0x15, 0xff },
{ "TRACEPOINT3", 0x16, 0xff },
{ "SAW_HWERR", 0x17, 0xff }
{ "TASKMGMT_FUNC_COMPLETE",0x13, 0xff },
{ "TASKMGMT_CMD_CMPLT_OKAY",0x14, 0xff },
{ "TRACEPOINT0", 0x15, 0xff },
{ "TRACEPOINT1", 0x16, 0xff },
{ "TRACEPOINT2", 0x17, 0xff },
{ "TRACEPOINT3", 0x18, 0xff },
{ "SAW_HWERR", 0x19, 0xff }
};
int
ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(SEQINTCODE_parse_table, 24, "SEQINTCODE",
return (ahd_print_register(SEQINTCODE_parse_table, 26, "SEQINTCODE",
0x02, regvalue, cur_col, wrap));
}
......
This diff is collapsed.
......@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#67 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#70 $
*
* $FreeBSD$
*/
......@@ -318,11 +318,11 @@ typedef enum {
*/
typedef enum {
AHC_FNONE = 0x000,
AHC_PRIMARY_CHANNEL = 0x003,/*
AHC_PRIMARY_CHANNEL = 0x003, /*
* The channel that should
* be probed first.
*/
AHC_USEDEFAULTS = 0x004,/*
AHC_USEDEFAULTS = 0x004, /*
* For cards without an seeprom
* or a BIOS to initialize the chip's
* SRAM, we use the default target
......@@ -330,29 +330,29 @@ typedef enum {
*/
AHC_SEQUENCER_DEBUG = 0x008,
AHC_SHARED_SRAM = 0x010,
AHC_LARGE_SEEPROM = 0x020,/* Uses C56_66 not C46 */
AHC_LARGE_SEEPROM = 0x020, /* Uses C56_66 not C46 */
AHC_RESET_BUS_A = 0x040,
AHC_RESET_BUS_B = 0x080,
AHC_EXTENDED_TRANS_A = 0x100,
AHC_EXTENDED_TRANS_B = 0x200,
AHC_TERM_ENB_A = 0x400,
AHC_TERM_ENB_B = 0x800,
AHC_INITIATORROLE = 0x1000,/*
AHC_INITIATORROLE = 0x1000, /*
* Allow initiator operations on
* this controller.
*/
AHC_TARGETROLE = 0x2000,/*
AHC_TARGETROLE = 0x2000, /*
* Allow target operations on this
* controller.
*/
AHC_NEWEEPROM_FMT = 0x4000,
AHC_RESOURCE_SHORTAGE = 0x8000,
AHC_TQINFIFO_BLOCKED = 0x10000,/* Blocked waiting for ATIOs */
AHC_INT50_SPEEDFLEX = 0x20000,/*
AHC_TQINFIFO_BLOCKED = 0x10000, /* Blocked waiting for ATIOs */
AHC_INT50_SPEEDFLEX = 0x20000, /*
* Internal 50pin connector
* sits behind an aic3860
*/
AHC_SCB_BTT = 0x40000,/*
AHC_SCB_BTT = 0x40000, /*
* The busy targets table is
* stored in SCB space rather
* than SRAM.
......@@ -363,7 +363,9 @@ typedef enum {
AHC_EDGE_INTERRUPT = 0x800000, /* Device uses edge triggered ints */
AHC_39BIT_ADDRESSING = 0x1000000, /* Use 39 bit addressing scheme. */
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_DISABLE_PCI_PERR = 0x10000000
} ahc_flag;
/************************* Hardware SCB Definition ***************************/
......@@ -758,6 +760,7 @@ struct ahc_syncrate {
#define AHC_SYNCRATE_ULTRA 3
#define AHC_SYNCRATE_FAST 6
#define AHC_SYNCRATE_MAX AHC_SYNCRATE_DT
#define AHC_SYNCRATE_MIN 13
/***************************** Lookup Tables **********************************/
/*
......
......@@ -40,7 +40,7 @@
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $"
PATCH_ARG_LIST = "struct ahc_softc *ahc"
PREFIX = "ahc_"
......@@ -193,7 +193,7 @@ select_in:
* Setup the DMA for sending the identify and
* command information.
*/
or SEQ_FLAGS, CMDPHASE_PENDING;
mvi SEQ_FLAGS, CMDPHASE_PENDING;
mov A, TQINPOS;
if ((ahc->features & AHC_CMD_CHAN) != 0) {
......@@ -306,7 +306,7 @@ ident_messages_done:
} else {
mvi DFDAT, SCB_LIST_NULL;
}
mvi SEQ_FLAGS, TARG_CMD_PENDING;
or SEQ_FLAGS, TARG_CMD_PENDING;
test SEQ_FLAGS2, TARGET_MSG_PENDING
jnz target_mesgout_pending;
test SCSISIGI, ATNI jnz target_mesgout_continue;
......@@ -512,6 +512,7 @@ target_mesgout:
target_mesgout_continue:
call target_inb;
target_mesgout_pending:
and SEQ_FLAGS2, ~TARGET_MSG_PENDING;
/* Local Processing goes here... */
jmp host_target_message_loop;
......
......@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#108 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#110 $
*
* $FreeBSD$
*/
......@@ -1844,8 +1844,9 @@ ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
* occurs the need to renegotiate is
* recorded persistently.
*/
if ((ahc->features & AHC_WIDE) != 0)
tinfo->curr.width = AHC_WIDTH_UNKNOWN;
tinfo->curr.period = AHC_PERIOD_UNKNOWN;
tinfo->curr.width = AHC_WIDTH_UNKNOWN;
tinfo->curr.offset = AHC_OFFSET_UNKNOWN;
}
if (tinfo->curr.period != tinfo->goal.period
......@@ -4045,6 +4046,14 @@ ahc_reset(struct ahc_softc *ahc)
* to disturb the integrity of the bus.
*/
ahc_pause(ahc);
if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) {
/*
* The chip has not been initialized since
* PCI/EISA/VLB bus reset. Don't trust
* "left over BIOS data".
*/
ahc->flags |= AHC_NO_BIOS_INIT;
}
sxfrctl1_b = 0;
if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
u_int sblkctl;
......@@ -6725,13 +6734,14 @@ ahc_dump_card_state(struct ahc_softc *ahc)
ahc_inb(ahc, SCBPTR));
cur_col = 0;
if ((ahc->features & AHC_DT) != 0)
ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50);
ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50);
ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50);
ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50);
ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50);
ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50);
ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50);
ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50);
ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50);
ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50);
ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50);
ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50);
ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50);
......
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#118 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#121 $
*
*/
#ifndef _AIC7XXX_LINUX_H_
......@@ -90,7 +90,6 @@
#define AIC_LIB_PREFIX ahc
#include "scsi.h"
#include "hosts.h"
#include "aiclib.h"
/* Name space conflict with BSD queue macros */
#ifdef LIST_HEAD
......@@ -100,6 +99,7 @@
#include "cam.h"
#include "queue.h"
#include "scsi_message.h"
#include "aiclib.h"
/*********************************** Debugging ********************************/
#ifdef CONFIG_AIC7XXX_DEBUG_ENABLE
......@@ -497,7 +497,7 @@ struct ahc_linux_target {
* Per-SCB OSM storage.
*/
typedef enum {
AHC_UP_EH_SEMAPHORE
AHC_UP_EH_SEMAPHORE = 0x1
} ahc_linux_scb_flags;
struct scb_platform_data {
......@@ -550,6 +550,7 @@ struct ahc_platform_data {
struct semaphore dv_cmd_sem; /* XXX This needs to be in
* the target struct
*/
struct scsi_device *dv_scsi_dev;
struct Scsi_Host *host; /* pointer to scsi host */
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
uint32_t irq; /* IRQ for this adapter */
......
......@@ -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#55 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#57 $
*
* $FreeBSD$
*/
......@@ -641,6 +641,7 @@ const u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table);
#define AHC_494X_SLOT_CHANNEL_D 7
#define DEVCONFIG 0x40
#define PCIERRGENDIS 0x80000000ul
#define SCBSIZE32 0x00010000ul /* aic789X only */
#define REXTVALID 0x00001000ul /* ultra cards only */
#define MPORTMODE 0x00000400ul /* aic7870+ only */
......@@ -785,6 +786,7 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
u_int sxfrctl1;
u_int scsiseq;
u_int dscommand0;
uint32_t devconfig;
int error;
uint8_t sblkctl;
......@@ -809,6 +811,8 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
*/
ahc_intr_enable(ahc, FALSE);
devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
/*
* If we need to support high memory, enable dual
* address cycles. This bit must be set to enable
......@@ -816,21 +820,30 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
* 64bit bus (PCI64BIT set in devconfig).
*/
if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
uint32_t devconfig;
if (bootverbose)
printf("%s: Enabling 39Bit Addressing\n",
ahc_name(ahc));
devconfig = ahc_pci_read_config(ahc->dev_softc,
DEVCONFIG, /*bytes*/4);
devconfig |= DACEN;
ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
devconfig, /*bytes*/4);
}
/* Ensure that pci error generation, a test feature, is disabled. */
devconfig |= PCIERRGENDIS;
ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
/* Ensure busmastering is enabled */
command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
command |= PCIM_CMD_BUSMASTEREN;
/*
* Disable PCI parity error reporting. Users typically
* do this to work around broken PCI chipsets that get
* the parity timing wrong and thus generate lots of spurious
* errors.
*/
if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
command &= ~PCIM_CMD_PERRESPEN;
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1);
/* On all PCI adapters, we allow SCB paging */
......@@ -947,7 +960,8 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
* a SEEPROM.
*/
/* See if someone else set us up already */
if (scsiseq != 0) {
if ((ahc->flags & AHC_NO_BIOS_INIT) == 0
&& scsiseq != 0) {
printf("%s: Using left over BIOS settings\n",
ahc_name(ahc));
ahc->flags &= ~AHC_USEDEFAULTS;
......
......@@ -2,7 +2,7 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $
*/
typedef int (ahc_reg_print_t)(u_int, u_int *, u_int);
......
......@@ -2,7 +2,7 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $
*/
......
This diff is collapsed.
......@@ -1230,3 +1230,106 @@ aic_calc_syncsrate(u_int period_factor)
*/
return (10000000 / (period_factor * 4 * 10));
}
/*
* Return speed in KB/s.
*/
u_int
aic_calc_speed(u_int width, u_int period, u_int offset, u_int min_rate)
{
u_int freq;
if (offset != 0 && period < min_rate)
freq = aic_calc_syncsrate(period);
else
/* Roughly 3.3MB/s for async */
freq = 3300;
freq <<= width;
return (freq);
}
uint32_t
aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data,
cam_status status, u_int scsi_status)
{
aic_sense_action err_action;
int sense;
sense = (cmd->result >> 24) == DRIVER_SENSE;
switch (status) {
case CAM_REQ_CMP:
err_action = SS_NOP;
break;
case CAM_AUTOSENSE_FAIL:
case CAM_SCSI_STATUS_ERROR:
switch (scsi_status) {
case SCSI_STATUS_OK:
case SCSI_STATUS_COND_MET:
case SCSI_STATUS_INTERMED:
case SCSI_STATUS_INTERMED_COND_MET:
err_action = SS_NOP;
break;
case SCSI_STATUS_CMD_TERMINATED:
case SCSI_STATUS_CHECK_COND:
if (sense != 0) {
struct scsi_sense_data *sense;
sense = (struct scsi_sense_data *)
&cmd->sense_buffer;
err_action =
aic_sense_error_action(sense, inq_data, 0);
} else {
err_action = SS_RETRY|SSQ_FALLBACK
| SSQ_DECREMENT_COUNT|EIO;
}
break;
case SCSI_STATUS_QUEUE_FULL:
case SCSI_STATUS_BUSY:
err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY
| SSQ_DECREMENT_COUNT|EBUSY;
break;
case SCSI_STATUS_RESERV_CONFLICT:
default:
err_action = SS_FAIL|EBUSY;
break;
}
break;
case CAM_CMD_TIMEOUT:
case CAM_REQ_CMP_ERR:
case CAM_UNEXP_BUSFREE:
case CAM_UNCOR_PARITY:
case CAM_DATA_RUN_ERR:
err_action = SS_RETRY|SSQ_FALLBACK|EIO;
break;
case CAM_UA_ABORT:
case CAM_UA_TERMIO:
case CAM_MSG_REJECT_REC:
case CAM_SEL_TIMEOUT:
err_action = SS_FAIL|EIO;
break;
case CAM_REQ_INVALID:
case CAM_PATH_INVALID:
case CAM_DEV_NOT_THERE:
case CAM_NO_HBA:
case CAM_PROVIDE_FAIL:
case CAM_REQ_TOO_BIG:
case CAM_RESRC_UNAVAIL:
case CAM_BUSY:
default:
/* panic?? These should never occur in our application. */
err_action = SS_FAIL|EIO;
break;
case CAM_SCSI_BUS_RESET:
case CAM_BDR_SENT:
case CAM_REQUEUE_REQ:
/* Unconditional requeue */
err_action = SS_RETRY;
break;
}
return (err_action);
}
......@@ -861,11 +861,13 @@ aic_sector_div(sector_t capacity, int heads, int sectors)
#define aic_sense_desc AIC_LIB_ENTRY(_sense_desc)
#define aic_sense_error_action AIC_LIB_ENTRY(_sense_error_action)
#define aic_error_action AIC_LIB_ENTRY(_error_action)
#define aic_op_desc AIC_LIB_ENTRY(_op_desc)
#define aic_cdb_string AIC_LIB_ENTRY(_cdb_string)
#define aic_print_inquiry AIC_LIB_ENTRY(_print_inquiry)
#define aic_calc_syncsrate AIC_LIB_ENTRY(_calc_syncrate)
#define aic_calc_syncparam AIC_LIB_ENTRY(_calc_syncparam)
#define aic_calc_speed AIC_LIB_ENTRY(_calc_speed)
#define aic_inquiry_match AIC_LIB_ENTRY(_inquiry_match)
#define aic_static_inquiry_match AIC_LIB_ENTRY(_static_inquiry_match)
......@@ -878,6 +880,9 @@ void aic_sense_desc(int /*sense_key*/, int /*asc*/,
aic_sense_action aic_sense_error_action(struct scsi_sense_data*,
struct scsi_inquiry_data*,
uint32_t /*sense_flags*/);
uint32_t aic_error_action(struct scsi_cmnd *,
struct scsi_inquiry_data *,
cam_status, u_int);
#define SF_RETRY_UA 0x01
#define SF_NO_PRINT 0x02
......@@ -892,6 +897,8 @@ void aic_print_inquiry(struct scsi_inquiry_data*);
u_int aic_calc_syncsrate(u_int /*period_factor*/);
u_int aic_calc_syncparam(u_int /*period*/);
u_int aic_calc_speed(u_int width, u_int period, u_int offset,
u_int min_rate);
int aic_inquiry_match(caddr_t /*inqbuffer*/,
caddr_t /*table_entry*/);
......
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