Commit d98d10eb authored by James Bottomley's avatar James Bottomley

Merge raven.il.steeleye.com:/mnt1/jejb/BK/scsi-aic-2.5

into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.5
parents 5cfbffd1 1d81bb15
......@@ -132,6 +132,11 @@ The following information is available in this file:
2. Version History
6.2.34 - Fix locking regression instroduced in 6.2.29 that
could cuase a lock order reversal between the io_request_lock
and our per-softc lock. This was only possible on RH9,
SuSE, and kernel.org 2.4.X kernels.
6.2.33 - Dynamically disable PCI parity error reporting after
10 errors are reported to the user. These errors are
the result of some other device issuing PCI transactions
......
......@@ -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#89 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#90 $
*
* $FreeBSD$
*/
......@@ -1225,20 +1225,20 @@ struct ahd_softc {
int seltime;
/*
* Interrupt coalessing settings.
* Interrupt coalescing settings.
*/
#define AHD_INT_COALESSING_TIMER_DEFAULT 250 /*us*/
#define AHD_INT_COALESSING_MAXCMDS_DEFAULT 10
#define AHD_INT_COALESSING_MAXCMDS_MAX 127
#define AHD_INT_COALESSING_MINCMDS_DEFAULT 5
#define AHD_INT_COALESSING_MINCMDS_MAX 127
#define AHD_INT_COALESSING_THRESHOLD_DEFAULT 2000
#define AHD_INT_COALESSING_STOP_THRESHOLD_DEFAULT 1000
u_int int_coalessing_timer;
u_int int_coalessing_maxcmds;
u_int int_coalessing_mincmds;
u_int int_coalessing_threshold;
u_int int_coalessing_stop_threshold;
#define AHD_INT_COALESCING_TIMER_DEFAULT 250 /*us*/
#define AHD_INT_COALESCING_MAXCMDS_DEFAULT 10
#define AHD_INT_COALESCING_MAXCMDS_MAX 127
#define AHD_INT_COALESCING_MINCMDS_DEFAULT 5
#define AHD_INT_COALESCING_MINCMDS_MAX 127
#define AHD_INT_COALESCING_THRESHOLD_DEFAULT 2000
#define AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT 1000
u_int int_coalescing_timer;
u_int int_coalescing_maxcmds;
u_int int_coalescing_mincmds;
u_int int_coalescing_threshold;
u_int int_coalescing_stop_threshold;
uint16_t user_discenable;/* Disconnection allowed */
uint16_t user_tagenable;/* Tagged Queuing allowed */
......@@ -1362,11 +1362,11 @@ int ahd_parse_vpddata(struct ahd_softc *ahd,
int ahd_parse_cfgdata(struct ahd_softc *ahd,
struct seeprom_config *sc);
void ahd_intr_enable(struct ahd_softc *ahd, int enable);
void ahd_update_coalessing_values(struct ahd_softc *ahd,
void ahd_update_coalescing_values(struct ahd_softc *ahd,
u_int timer,
u_int maxcmds,
u_int mincmds);
void ahd_enable_coalessing(struct ahd_softc *ahd,
void ahd_enable_coalescing(struct ahd_softc *ahd,
int enable);
void ahd_pause_and_flushwork(struct ahd_softc *ahd);
int ahd_suspend(struct ahd_softc *ahd);
......@@ -1514,7 +1514,7 @@ extern uint32_t ahd_debug;
#define AHD_SHOW_QUEUE 0x02000
#define AHD_SHOW_TQIN 0x04000
#define AHD_SHOW_SG 0x08000
#define AHD_SHOW_INT_COALESSING 0x10000
#define AHD_SHOW_INT_COALESCING 0x10000
#define AHD_DEBUG_SEQUENCER 0x20000
#endif
void ahd_print_scb(struct scb *scb);
......
......@@ -39,7 +39,7 @@
*
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $"
/*
* This file is processed by the aic7xxx_asm utility for use in assembling
......@@ -286,7 +286,7 @@ register HS_MAILBOX {
address 0x00B
access_mode RW
mask HOST_TQINPOS 0x80 /* Boundary at either 0 or 128 */
mask ENINT_COALESS 0x40 /* Perform interrupt coalessing */
mask ENINT_COALESCE 0x40 /* Perform interrupt coalescing */
}
/*
......@@ -3704,28 +3704,28 @@ scratch_ram {
}
/*
* The maximum amount of time to wait, when interrupt coalessing
* The maximum amount of time to wait, when interrupt coalescing
* is enabled, before issueing a CMDCMPLT interrupt for a completed
* command.
*/
INT_COALESSING_TIMER {
INT_COALESCING_TIMER {
size 2
}
/*
* The maximum number of commands to coaless into a single interrupt.
* The maximum number of commands to coalesce into a single interrupt.
* Actually the 2's complement of that value to simplify sequencer
* code.
*/
INT_COALESSING_MAXCMDS {
INT_COALESCING_MAXCMDS {
size 1
}
/*
* The minimum number of commands still outstanding required
* to continue coalessing (2's complement of value).
* to continue coalescing (2's complement of value).
*/
INT_COALESSING_MINCMDS {
INT_COALESCING_MINCMDS {
size 1
}
......@@ -3737,9 +3737,9 @@ scratch_ram {
}
/*
* The count of commands that have been coalessed.
* The count of commands that have been coalesced.
*/
INT_COALESSING_CMDCOUNT {
INT_COALESCING_CMDCOUNT {
size 1
}
......@@ -3842,10 +3842,15 @@ scb {
}
SCB_LUN {
size 1
field LID 0xff
field LID 0xff
}
SCB_TASK_ATTRIBUTE {
size 1
/*
* Overloaded field for non-packetized
* ignore wide residue message handling.
*/
field SCB_XFERLEN_ODD 0x01
}
SCB_CDB_LEN {
size 1
......
......@@ -40,7 +40,7 @@
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#91 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $"
PATCH_ARG_LIST = "struct ahd_softc *ahd"
PREFIX = "ahd_"
......@@ -212,44 +212,44 @@ fill_qoutfifo_dmadone:
qoutfifo_updated:
/*
* If there are more commands waiting to be dma'ed
* to the host, always coaless. Otherwise honor the
* to the host, always coalesce. Otherwise honor the
* host's wishes.
*/
cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coaless_by_count;
cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coaless_by_count;
test LOCAL_HS_MAILBOX, ENINT_COALESS jz issue_cmdcmplt;
cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count;
cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count;
test LOCAL_HS_MAILBOX, ENINT_COALESCE jz issue_cmdcmplt;
/*
* If we have relatively few commands outstanding, don't
* bother waiting for another command to complete.
*/
test CMDS_PENDING[1], 0xFF jnz coaless_by_count;
test CMDS_PENDING[1], 0xFF jnz coalesce_by_count;
/* Add -1 so that jnc means <= not just < */
add A, -1, INT_COALESSING_MINCMDS;
add A, -1, INT_COALESCING_MINCMDS;
add NONE, A, CMDS_PENDING;
jnc issue_cmdcmplt;
/*
* If coalessing, only coaless up to the limit
* If coalescing, only coalesce up to the limit
* provided by the host driver.
*/
coaless_by_count:
mov A, INT_COALESSING_MAXCMDS;
add NONE, A, INT_COALESSING_CMDCOUNT;
coalesce_by_count:
mov A, INT_COALESCING_MAXCMDS;
add NONE, A, INT_COALESCING_CMDCOUNT;
jc issue_cmdcmplt;
/*
* If the timer is not currently active,
* fire it up.
*/
test INTCTL, SWTMINTMASK jz return;
bmov SWTIMER, INT_COALESSING_TIMER, 2;
bmov SWTIMER, INT_COALESCING_TIMER, 2;
mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO;
or INTCTL, SWTMINTEN|SWTIMER_START;
and INTCTL, ~SWTMINTMASK ret;
issue_cmdcmplt:
mvi INTSTAT, CMDCMPLT;
clr INT_COALESSING_CMDCOUNT;
clr INT_COALESCING_CMDCOUNT;
or INTCTL, SWTMINTMASK ret;
BEGIN_CRITICAL;
......@@ -261,6 +261,15 @@ fetch_new_scb_done:
clr A;
add CMDS_PENDING, 1;
adc CMDS_PENDING[1], A;
if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
/*
* "Short Luns" are not placed into outgoing LQ
* packets in the correct byte order. Use a full
* sized lun field instead and fill it with the
* one byte of lun information we support.
*/
mov SCB_PKT_LUN[6], SCB_LUN;
}
/*
* The FIFO use count field is shared with the
* tag set by the host so that our SCB dma engine
......@@ -324,7 +333,7 @@ fill_qoutfifo_loop:
mov CCSCBRAM, SCBPTR;
or CCSCBRAM, A, SCBPTR[1];
mov NONE, SDSCB_QOFF;
inc INT_COALESSING_CMDCOUNT;
inc INT_COALESCING_CMDCOUNT;
add CMDS_PENDING, -1;
adc CMDS_PENDING[1], -1;
cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done;
......@@ -863,7 +872,8 @@ mesgin_ign_wide_residue:
mvi REG0 call inb_next;
cmp REG0, 0x01 jne mesgin_reject;
test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2;
test DATA_COUNT_ODD, 0x1 jz mesgin_done;
test SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jnz mesgin_done;
SET_SEQINTCODE(IGN_WIDE_RES)
jmp mesgin_done;
mesgin_proto_violation:
......@@ -1308,8 +1318,6 @@ idle_sg_avail:
bmov HADDR, CCSGRAM, 4;
}
bmov HCNT, CCSGRAM, 3;
test HCNT[0], 0x1 jz . + 2;
xor DATA_COUNT_ODD, 0x1;
bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
and HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3];
......@@ -1325,8 +1333,6 @@ sg_advance:
adc SCB_RESIDUAL_SGPTR[2],A;
adc SCB_RESIDUAL_SGPTR[3],A;
mov SINDEX, SCB_RESIDUAL_SGPTR[0];
test DATA_COUNT_ODD, 0x1 jz . + 2;
or SINDEX, ODD_SEG;
test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 3;
or SINDEX, LAST_SEG;
clr SG_STATE;
......@@ -1352,12 +1358,9 @@ sg_advance:
*/
load_first_seg:
bmov HADDR, SCB_DATAPTR, 11;
and DATA_COUNT_ODD, 0x1, SCB_DATACNT[0];
and REG_ISR, ~SG_FULL_RESID, SCB_SGPTR[0];
test SCB_DATACNT[3], SG_LAST_SEG jz . + 2;
or REG_ISR, LAST_SEG;
test DATA_COUNT_ODD, 0x1 jz . + 2;
or REG_ISR, ODD_SEG;
mov SG_CACHE_PRE, REG_ISR;
mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);
/*
......@@ -1507,7 +1510,7 @@ data_phase_done:
* send Ignore Wide Residue messages for data-in phases.
test DFCNTRL, DIRECTION jz target_ITloop;
test SSTAT1, REQINIT jnz .;
test DATA_COUNT_ODD, 0x1 jz target_ITloop;
test SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jz target_ITloop;
SET_MODE(M_SCSI, M_SCSI)
test NEGCONOPTS, WIDEXFER jz target_ITloop;
*/
......@@ -1577,9 +1580,6 @@ sgptr_fixup:
adc SCB_RESIDUAL_SGPTR[3], -1;
sgptr_fixup_done:
and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW;
clr DATA_COUNT_ODD;
test SG_CACHE_SHADOW, ODD_SEG jz . + 2;
or DATA_COUNT_ODD, 0x1;
clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */
bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret;
......
......@@ -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#190 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#194 $
*
* $FreeBSD$
*/
......@@ -4401,7 +4401,7 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
if ((sgptr & SG_LIST_NULL) != 0
&& ahd_inb(ahd, DATA_COUNT_ODD) == 1) {
&& (ahd_inb(ahd, SCB_TASK_ATTRIBUTE) & SCB_XFERLEN_ODD) != 0) {
/*
* If the residual occurred on the last
* transfer and the transfer request was
......@@ -4414,29 +4414,20 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
uint32_t sglen;
/* Pull in the rest of the sgptr */
sgptr |=
(ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24)
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16)
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8);
sgptr &= SG_PTR_MASK;
data_cnt =
(ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24)
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+2) << 16)
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+1) << 8)
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT));
data_addr = (((uint64_t)ahd_inb(ahd, SHADDR + 7)) << 56)
| (((uint64_t)ahd_inb(ahd, SHADDR + 6)) << 48)
| (((uint64_t)ahd_inb(ahd, SHADDR + 5)) << 40)
| (((uint64_t)ahd_inb(ahd, SHADDR + 4)) << 32)
| (ahd_inb(ahd, SHADDR + 3) << 24)
| (ahd_inb(ahd, SHADDR + 2) << 16)
| (ahd_inb(ahd, SHADDR + 1) << 8)
| (ahd_inb(ahd, SHADDR));
sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
data_cnt = ahd_inl_scbram(ahd, SCB_RESIDUAL_DATACNT);
if ((sgptr & SG_LIST_NULL) != 0) {
/*
* The residual data count is not updated
* for the command run to completion case.
* Explicitly zero the count.
*/
data_cnt &= ~AHD_SG_LEN_MASK;
}
data_addr = ahd_inq(ahd, SHADDR);
data_cnt += 1;
data_addr -= 1;
sgptr &= SG_PTR_MASK;
if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
struct ahd_dma64_seg *sg;
......@@ -4504,16 +4495,17 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
sg);
}
}
ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 3, sgptr >> 24);
ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 2, sgptr >> 16);
ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 1, sgptr >> 8);
ahd_outb(ahd, SCB_RESIDUAL_SGPTR, sgptr);
ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24);
ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16);
ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8);
ahd_outb(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
/*
* Toggle the "oddness" of the transfer length
* to handle this mid-transfer ignore wide
* residue. This ensures that the oddness is
* correct for subsequent data transfers.
*/
ahd_outb(ahd, SCB_TASK_ATTRIBUTE,
ahd_inb(ahd, SCB_TASK_ATTRIBUTE) ^ SCB_XFERLEN_ODD);
ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
/*
* The FIFO's pointers will be updated if/when the
* sequencer re-enters a data phase.
......@@ -4806,12 +4798,12 @@ ahd_alloc(void *platform_arg, char *name)
| AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A;
ahd_timer_init(&ahd->reset_timer);
ahd_timer_init(&ahd->stat_timer);
ahd->int_coalessing_timer = AHD_INT_COALESSING_TIMER_DEFAULT;
ahd->int_coalessing_maxcmds = AHD_INT_COALESSING_MAXCMDS_DEFAULT;
ahd->int_coalessing_mincmds = AHD_INT_COALESSING_MINCMDS_DEFAULT;
ahd->int_coalessing_threshold = AHD_INT_COALESSING_THRESHOLD_DEFAULT;
ahd->int_coalessing_stop_threshold =
AHD_INT_COALESSING_STOP_THRESHOLD_DEFAULT;
ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT;
ahd->int_coalescing_stop_threshold =
AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT;
if (ahd_platform_alloc(ahd, platform_arg) != 0) {
ahd_free(ahd);
......@@ -5722,6 +5714,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
next_scb->sg_list = segs;
next_scb->sense_data = sense_data;
next_scb->sense_busaddr = sense_busaddr;
memset(hscb, 0, sizeof(*hscb));
next_scb->hscb = hscb;
hscb->hscb_busaddr = ahd_htole32(hscb_busaddr);
......@@ -6341,14 +6334,14 @@ ahd_chip_init(struct ahd_softc *ahd)
ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
/*
* Default to coalessing disabled.
* Default to coalescing disabled.
*/
ahd_outw(ahd, INT_COALESSING_CMDCOUNT, 0);
ahd_outw(ahd, INT_COALESCING_CMDCOUNT, 0);
ahd_outw(ahd, CMDS_PENDING, 0);
ahd_update_coalessing_values(ahd, ahd->int_coalessing_timer,
ahd->int_coalessing_maxcmds,
ahd->int_coalessing_mincmds);
ahd_enable_coalessing(ahd, FALSE);
ahd_update_coalescing_values(ahd, ahd->int_coalescing_timer,
ahd->int_coalescing_maxcmds,
ahd->int_coalescing_mincmds);
ahd_enable_coalescing(ahd, FALSE);
ahd_loadseq(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
......@@ -6601,30 +6594,30 @@ ahd_intr_enable(struct ahd_softc *ahd, int enable)
}
void
ahd_update_coalessing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
u_int mincmds)
{
if (timer > AHD_TIMER_MAX_US)
timer = AHD_TIMER_MAX_US;
ahd->int_coalessing_timer = timer;
ahd->int_coalescing_timer = timer;
if (maxcmds > AHD_INT_COALESSING_MAXCMDS_MAX)
maxcmds = AHD_INT_COALESSING_MAXCMDS_MAX;
if (mincmds > AHD_INT_COALESSING_MINCMDS_MAX)
mincmds = AHD_INT_COALESSING_MINCMDS_MAX;
ahd->int_coalessing_maxcmds = maxcmds;
ahd_outw(ahd, INT_COALESSING_TIMER, timer / AHD_TIMER_US_PER_TICK);
ahd_outb(ahd, INT_COALESSING_MAXCMDS, -maxcmds);
ahd_outb(ahd, INT_COALESSING_MINCMDS, -mincmds);
if (maxcmds > AHD_INT_COALESCING_MAXCMDS_MAX)
maxcmds = AHD_INT_COALESCING_MAXCMDS_MAX;
if (mincmds > AHD_INT_COALESCING_MINCMDS_MAX)
mincmds = AHD_INT_COALESCING_MINCMDS_MAX;
ahd->int_coalescing_maxcmds = maxcmds;
ahd_outw(ahd, INT_COALESCING_TIMER, timer / AHD_TIMER_US_PER_TICK);
ahd_outb(ahd, INT_COALESCING_MAXCMDS, -maxcmds);
ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds);
}
void
ahd_enable_coalessing(struct ahd_softc *ahd, int enable)
ahd_enable_coalescing(struct ahd_softc *ahd, int enable)
{
ahd->hs_mailbox &= ~ENINT_COALESS;
ahd->hs_mailbox &= ~ENINT_COALESCE;
if (enable)
ahd->hs_mailbox |= ENINT_COALESS;
ahd->hs_mailbox |= ENINT_COALESCE;
ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox);
ahd_flush_device_writes(ahd);
ahd_run_qoutfifo(ahd);
......@@ -7718,20 +7711,20 @@ ahd_stat_timer(void *arg)
}
ahd_lock(ahd, &s);
enint_coal = ahd->hs_mailbox & ENINT_COALESS;
if (ahd->cmdcmplt_total > ahd->int_coalessing_threshold)
enint_coal |= ENINT_COALESS;
else if (ahd->cmdcmplt_total < ahd->int_coalessing_stop_threshold)
enint_coal &= ~ENINT_COALESS;
enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold)
enint_coal |= ENINT_COALESCE;
else if (ahd->cmdcmplt_total < ahd->int_coalescing_stop_threshold)
enint_coal &= ~ENINT_COALESCE;
if (enint_coal != (ahd->hs_mailbox & ENINT_COALESS)) {
ahd_enable_coalessing(ahd, enint_coal);
if (enint_coal != (ahd->hs_mailbox & ENINT_COALESCE)) {
ahd_enable_coalescing(ahd, enint_coal);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_INT_COALESSING) != 0)
printf("%s: Interrupt coalessing "
if ((ahd_debug & AHD_SHOW_INT_COALESCING) != 0)
printf("%s: Interrupt coalescing "
"now %sabled. Cmds %d\n",
ahd_name(ahd),
(enint_coal & ENINT_COALESS) ? "en" : "dis",
(enint_coal & ENINT_COALESCE) ? "en" : "dis",
ahd->cmdcmplt_total);
#endif
}
......@@ -8279,8 +8272,6 @@ ahd_loadseq(struct ahd_softc *ahd)
download_consts[PKT_OVERRUN_BUFOFFSET] =
(ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256;
download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN;
if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0)
download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_FULL_LUN;
cur_patch = patches;
downloaded = 0;
skip_addr = 0;
......@@ -8509,7 +8500,7 @@ ahd_probe_stack_size(struct ahd_softc *ahd)
}
void
ahd_dump_all_cards_state()
ahd_dump_all_cards_state(void)
{
struct ahd_softc *list_ahd;
......
......@@ -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#48 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#50 $
*
* $FreeBSD$
*/
......@@ -271,11 +271,12 @@ ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb)
scb->crc_retry_count = 0;
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;
/*
* For Rev A short lun workaround.
*/
scb->hscb->pkt_long_lun[6] = scb->hscb->lun;
scb->hscb->task_attribute = scb->hscb->control & SCB_TAG_TYPE;
} else {
if (ahd_get_transfer_length(scb) & 0x01)
scb->hscb->task_attribute = SCB_XFERLEN_ODD;
else
scb->hscb->task_attribute = 0;
}
if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR
......
/*
* Adaptec AIC79xx device driver for Linux.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#160 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#169 $
*
* --------------------------------------------------------------------------
* Copyright (c) 1994-2000 Justin T. Gibbs.
......@@ -62,11 +62,6 @@
#include <linux/mm.h> /* For fetching system memory size */
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
static int errno;
/*
* Lock protecting manipulation of the ahd softc list.
*/
......@@ -755,31 +750,11 @@ ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb,
consumed = 1;
sg->addr = ahd_htole32(addr & 0xFFFFFFFF);
scb->platform_data->xfer_len += len;
if (sizeof(bus_addr_t) > 4
&& (ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
/*
* Due to DAC restrictions, we can't
* cross a 4GB boundary.
*/
if ((addr ^ (addr + len - 1)) & ~0xFFFFFFFF) {
struct ahd_dma_seg *next_sg;
uint32_t next_len;
printf("Crossed Seg\n");
if ((scb->sg_count + 2) > AHD_NSEG)
panic("Too few segs for dma mapping. "
"Increase AHD_NSEG\n");
consumed++;
next_sg = sg + 1;
next_sg->addr = 0;
next_len = 0x100000000 - (addr & 0xFFFFFFFF);
len -= next_len;
next_len |= ((addr >> 8) + 0x1000000) & 0x7F000000;
next_sg->len = ahd_htole32(next_len);
}
len |= (addr >> 8) & 0x7F000000;
}
&& (ahd->flags & AHD_39BIT_ADDRESSING) != 0)
len |= (addr >> 8) & AHD_SG_HIGH_ADDR_MASK;
sg->len = ahd_htole32(len);
return (consumed);
}
......@@ -796,14 +771,18 @@ static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
static int ahd_linux_slave_alloc(Scsi_Device *);
static int ahd_linux_slave_configure(Scsi_Device *);
static void ahd_linux_slave_destroy(Scsi_Device *);
#if defined(__i386__)
static int ahd_linux_biosparam(struct scsi_device*,
struct block_device*, sector_t, int[]);
#endif
#else
static int ahd_linux_release(struct Scsi_Host *);
static void ahd_linux_select_queue_depth(struct Scsi_Host *host,
Scsi_Device *scsi_devs);
#if defined(__i386__)
static int ahd_linux_biosparam(Disk *, kdev_t, int[]);
#endif
#endif
static int ahd_linux_bus_reset(Scsi_Cmnd *);
static int ahd_linux_dev_reset(Scsi_Cmnd *);
static int ahd_linux_abort(Scsi_Cmnd *);
......@@ -1211,6 +1190,7 @@ ahd_linux_select_queue_depth(struct Scsi_Host * host,
}
#endif
#if defined(__i386__)
/*
* Return the disk geometry for the given SCSI device.
*/
......@@ -1273,6 +1253,7 @@ ahd_linux_biosparam(Disk *disk, kdev_t dev, int geom[])
geom[2] = cylinders;
return (0);
}
#endif
/*
* Abort the current SCSI command(s).
......@@ -2198,7 +2179,7 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template)
}
uint64_t
ahd_linux_get_memsize()
ahd_linux_get_memsize(void)
{
struct sysinfo si;
......@@ -2213,7 +2194,7 @@ ahd_linux_get_memsize()
* scenario.
*/
static int
ahd_linux_next_unit()
ahd_linux_next_unit(void)
{
struct ahd_softc *ahd;
int unit;
......@@ -2955,13 +2936,11 @@ ahd_linux_dv_transition(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
struct ahd_devinfo *devinfo,
struct ahd_linux_target *targ)
{
cam_status cam_status;
u_int32_t status;
u_int scsi_status;
scsi_status = ahd_cmd_get_scsi_status(cmd);
cam_status = ahd_cmd_get_transaction_status(cmd);
status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status);
status = aic_error_action(cmd, targ->inq_data,
ahd_cmd_get_transaction_status(cmd),
ahd_cmd_get_scsi_status(cmd));
#ifdef AHD_DEBUG
......@@ -4211,7 +4190,7 @@ ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev)
/*
* SCSI controller interrupt handler.
*/
AIC_LINUX_IRQRETURN_T
irqreturn_t
ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
{
struct ahd_softc *ahd;
......@@ -4225,7 +4204,7 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
ahd_schedule_runq(ahd);
ahd_linux_run_complete_queue(ahd);
ahd_unlock(ahd, &flags);
AIC_LINUX_IRQRETURN(ours);
return IRQ_RETVAL(ours);
}
void
......
......@@ -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#130 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#133 $
*
*/
#ifndef _AIC79XX_LINUX_H_
......@@ -293,7 +293,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
#define AHD_SCSI_HAS_HOST_LOCK 0
#endif
#define AIC79XX_DRIVER_VERSION "1.3.8"
#define AIC79XX_DRIVER_VERSION "1.3.9"
/**************************** Front End Queues ********************************/
/*
......@@ -1211,7 +1211,7 @@ void ahd_platform_set_tags(struct ahd_softc *ahd,
int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
char channel, int lun, u_int tag,
role_t role, uint32_t status);
AIC_LINUX_IRQRETURN_T
irqreturn_t
ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
void ahd_platform_flushwork(struct ahd_softc *ahd);
int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *);
......
......@@ -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#21 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#23 $
*/
#include "aic79xx_osm.h"
......@@ -156,19 +156,21 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
if (sizeof(bus_addr_t) > 4) {
uint64_t memsize;
uint64_t memsize;
bus_addr_t mask_64bit;
bus_addr_t mask_39bit;
memsize = ahd_linux_get_memsize();
if (memsize >= 0x8000000000
&& ahd_pci_set_dma_mask(pdev, 0xFFFFFFFFFFFFFFFFULL) == 0) {
mask_64bit = (bus_addr_t)(0xFFFFFFFFFFFFFFFFULL&(bus_addr_t)~0);
mask_39bit = (bus_addr_t)(0x7FFFFFFFFFULL&(bus_addr_t)~0);
if (memsize >= 0x8000000000ULL
&& ahd_pci_set_dma_mask(pdev, mask_64bit) == 0) {
ahd->flags |= AHD_64BIT_ADDRESSING;
ahd->platform_data->hw_dma_mask =
(bus_addr_t)(0xFFFFFFFFFFFFFFFFULL&(bus_addr_t)~0);
ahd->platform_data->hw_dma_mask = mask_64bit;
} else if (memsize > 0x80000000
&& ahd_pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) {
&& ahd_pci_set_dma_mask(pdev, mask_39bit) == 0) {
ahd->flags |= AHD_39BIT_ADDRESSING;
ahd->platform_data->hw_dma_mask =
(bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
ahd->platform_data->hw_dma_mask = mask_39bit;
}
} else {
ahd_pci_set_dma_mask(pdev, 0xFFFFFFFF);
......
......@@ -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#71 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#73 $
*
* $FreeBSD$
*/
......@@ -65,28 +65,29 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
}
#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull
#define ID_ALL_IROC_MASK 0xFFFFFF7FFFFFFFFFull
#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
#define ID_9005_GENERIC_IROC_MASK 0xFFF0FF7F00000000ull
#define ID_AIC7901 0x800F9005FFFF9005ull
#define ID_AIC7901A 0x801E9005FFFF9005ull
#define ID_AIC7901A_IROC 0x809E9005FFFF9005ull
#define ID_AHA_29320A 0x8000900500609005ull
#define ID_AHA_29320ALP 0x8017900500449005ull
#define ID_AIC7901A 0x801E9005FFFF9005ull
#define ID_AHA_29320 0x8012900500429005ull
#define ID_AHA_29320B 0x8013900500439005ull
#define ID_AHA_29320LP 0x8014900500449005ull
#define ID_AHA_29320LP_IROC 0x8094900500449005ull
#define ID_AIC7902 0x801F9005FFFF9005ull
#define ID_AIC7902_IROC 0x809F9005FFFF9005ull
#define ID_AIC7902_B 0x801D9005FFFF9005ull
#define ID_AIC7902_B_IROC 0x809D9005FFFF9005ull
#define ID_AHA_39320 0x8010900500409005ull
#define ID_AHA_39320_B 0x8015900500409005ull
#define ID_AHA_39320A 0x8016900500409005ull
#define ID_AHA_39320D 0x8011900500419005ull
#define ID_AHA_39320D_B 0x801C900500419005ull
#define ID_AHA_39320D_HP 0x8011900500AC0E11ull
#define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull
#define ID_AHA_29320 0x8012900500429005ull
#define ID_AHA_29320B 0x8013900500439005ull
#define ID_AIC7902_PCI_REV_A4 0x3
#define ID_AIC7902_PCI_REV_B0 0x10
#define SUBID_HP 0x0E11
......@@ -113,22 +114,42 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
#define SUBID_9005_SEEPTYPE_NONE 0x0
#define SUBID_9005_SEEPTYPE_4K 0x1
static ahd_device_setup_t ahd_aic7901_setup;
static ahd_device_setup_t ahd_aic7901A_setup;
static ahd_device_setup_t ahd_aic7902_setup;
struct ahd_pci_identity ahd_pci_ident_table [] =
{
/* aic7901 based controllers */
{
ID_AHA_29320A,
ID_ALL_MASK,
"Adaptec 29320A Ultra320 SCSI adapter",
ahd_aic7901_setup
},
{
ID_AHA_29320ALP,
ID_ALL_MASK,
"Adaptec 29320ALP Ultra320 SCSI adapter",
ahd_aic7901_setup
},
/* aic7901A based controllers */
{
ID_AHA_29320LP,
ID_AHA_29320,
ID_ALL_MASK,
"Adaptec 29320LP Ultra320 SCSI adapter",
"Adaptec 29320 Ultra320 SCSI adapter",
ahd_aic7901A_setup
},
{
ID_AHA_29320A,
ID_AHA_29320B,
ID_ALL_MASK,
"Adaptec 29320A Ultra320 SCSI adapter",
"Adaptec 29320B Ultra320 SCSI adapter",
ahd_aic7901A_setup
},
{
ID_AHA_29320LP,
ID_ALL_MASK,
"Adaptec 29320LP Ultra320 SCSI adapter",
ahd_aic7901A_setup
},
/* aic7902 based controllers */
......@@ -138,6 +159,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
"Adaptec 39320 Ultra320 SCSI adapter",
ahd_aic7902_setup
},
{
ID_AHA_39320_B,
ID_ALL_MASK,
"Adaptec 39320 Ultra320 SCSI adapter",
ahd_aic7902_setup
},
{
ID_AHA_39320A,
ID_ALL_MASK,
......@@ -181,6 +208,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
ahd_aic7902_setup
},
/* Generic chip probes for devices we don't know 'exactly' */
{
ID_AIC7901 & ID_DEV_VENDOR_MASK,
ID_DEV_VENDOR_MASK,
"Adaptec AIC7901 Ultra320 SCSI adapter",
ahd_aic7901_setup
},
{
ID_AIC7901A & ID_DEV_VENDOR_MASK,
ID_DEV_VENDOR_MASK,
......@@ -332,9 +365,9 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
}
/* Ensure busmastering is enabled */
command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1);
command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
command |= PCIM_CMD_BUSMASTEREN;
ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/1);
ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
error = ahd_softc_init(ahd);
if (error != 0)
......@@ -867,6 +900,18 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
ahd_restore_modes(ahd, saved_modes);
}
static int
ahd_aic7901_setup(struct ahd_softc *ahd)
{
int error;
error = ahd_aic7902_setup(ahd);
if (error != 0)
return (error);
ahd->chip = AHD_AIC7901;
return (0);
}
static int
ahd_aic7901A_setup(struct ahd_softc *ahd)
{
......@@ -890,7 +935,7 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
if (rev < ID_AIC7902_PCI_REV_A4) {
printf("%s: Unable to attach to unsupported chip revision %d\n",
ahd_name(ahd), rev);
ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/1);
ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
return (ENXIO);
}
ahd->channel = ahd_get_pci_function(pci) + 'A';
......
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#91 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $
*/
typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahd_reg_parse_entry {
......@@ -2134,24 +2134,24 @@ ahd_reg_print_t ahd_allocfifo_scbptr_print;
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_int_coalessing_timer_print;
ahd_reg_print_t ahd_int_coalescing_timer_print;
#else
#define ahd_int_coalessing_timer_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "INT_COALESSING_TIMER", 0x14a, regvalue, cur_col, wrap)
#define ahd_int_coalescing_timer_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "INT_COALESCING_TIMER", 0x14a, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_int_coalessing_maxcmds_print;
ahd_reg_print_t ahd_int_coalescing_maxcmds_print;
#else
#define ahd_int_coalessing_maxcmds_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "INT_COALESSING_MAXCMDS", 0x14c, regvalue, cur_col, wrap)
#define ahd_int_coalescing_maxcmds_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS", 0x14c, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_int_coalessing_mincmds_print;
ahd_reg_print_t ahd_int_coalescing_mincmds_print;
#else
#define ahd_int_coalessing_mincmds_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "INT_COALESSING_MINCMDS", 0x14d, regvalue, cur_col, wrap)
#define ahd_int_coalescing_mincmds_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS", 0x14d, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
......@@ -2162,10 +2162,10 @@ ahd_reg_print_t ahd_cmds_pending_print;
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_int_coalessing_cmdcount_print;
ahd_reg_print_t ahd_int_coalescing_cmdcount_print;
#else
#define ahd_int_coalessing_cmdcount_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "INT_COALESSING_CMDCOUNT", 0x150, regvalue, cur_col, wrap)
#define ahd_int_coalescing_cmdcount_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT", 0x150, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
......@@ -2432,7 +2432,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define HS_MAILBOX 0x0b
#define HOST_TQINPOS 0x80
#define ENINT_COALESS 0x40
#define ENINT_COALESCE 0x40
#define CLRSEQINTSTAT 0x0c
#define CLRSEQ_SWTMRTO 0x10
......@@ -3612,15 +3612,15 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define ALLOCFIFO_SCBPTR 0x148
#define INT_COALESSING_TIMER 0x14a
#define INT_COALESCING_TIMER 0x14a
#define INT_COALESSING_MAXCMDS 0x14c
#define INT_COALESCING_MAXCMDS 0x14c
#define INT_COALESSING_MINCMDS 0x14d
#define INT_COALESCING_MINCMDS 0x14d
#define CMDS_PENDING 0x14e
#define INT_COALESSING_CMDCOUNT 0x150
#define INT_COALESCING_CMDCOUNT 0x150
#define LOCAL_HS_MAILBOX 0x151
......@@ -3683,6 +3683,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define LID 0xff
#define SCB_TASK_ATTRIBUTE 0x1ab
#define SCB_XFERLEN_ODD 0x01
#define SCB_CDB_LEN 0x1ac
#define SCB_CDB_LEN_PTR 0x80
......@@ -3768,5 +3769,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
/* Exported Labels */
#define LABEL_seq_isr 0x270
#define LABEL_timer_isr 0x26c
#define LABEL_seq_isr 0x269
#define LABEL_timer_isr 0x265
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#91 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#93 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#68 $
*/
#include "aic79xx_osm.h"
......@@ -161,7 +161,7 @@ ahd_hescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
}
static ahd_reg_parse_entry_t HS_MAILBOX_parse_table[] = {
{ "ENINT_COALESS", 0x40, 0x40 },
{ "ENINT_COALESCE", 0x40, 0x40 },
{ "HOST_TQINPOS", 0x80, 0x80 }
};
......@@ -3375,23 +3375,23 @@ ahd_allocfifo_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
}
int
ahd_int_coalessing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap)
ahd_int_coalescing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "INT_COALESSING_TIMER",
return (ahd_print_register(NULL, 0, "INT_COALESCING_TIMER",
0x14a, regvalue, cur_col, wrap));
}
int
ahd_int_coalessing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
ahd_int_coalescing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "INT_COALESSING_MAXCMDS",
return (ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS",
0x14c, regvalue, cur_col, wrap));
}
int
ahd_int_coalessing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
ahd_int_coalescing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "INT_COALESSING_MINCMDS",
return (ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS",
0x14d, regvalue, cur_col, wrap));
}
......@@ -3403,9 +3403,9 @@ ahd_cmds_pending_print(u_int regvalue, u_int *cur_col, u_int wrap)
}
int
ahd_int_coalessing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
ahd_int_coalescing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "INT_COALESSING_CMDCOUNT",
return (ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT",
0x150, 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#75 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#77 $
*
* $FreeBSD$
*/
......@@ -93,7 +93,7 @@ struct seeprom_descriptor;
#define SCB_GET_CHANNEL(ahc, scb) \
SCSIID_CHANNEL(ahc, (scb)->hscb->scsiid)
#define SCB_GET_LUN(scb) \
((scb)->hscb->lun)
((scb)->hscb->lun & LID)
#define SCB_GET_TARGET_OFFSET(ahc, scb) \
(SCB_GET_TARGET(ahc, scb) + (SCB_IS_SCSIBUS_B(ahc, scb) ? 8 : 0))
#define SCB_GET_TARGET_MASK(ahc, scb) \
......@@ -1046,6 +1046,11 @@ struct ahc_softc {
struct target_cmd *targetcmds;
uint8_t tqinfifonext;
/*
* Cached copy of the sequencer control register.
*/
uint8_t seqctl;
/*
* Incoming and outgoing message handling.
*/
......
......@@ -39,7 +39,7 @@
*
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $"
/*
* This file is processed by the aic7xxx_asm utility for use in assembling
......@@ -1080,7 +1080,8 @@ scb {
mask OID 0x0f
}
SCB_LUN {
mask LID 0xff
field SCB_XFERLEN_ODD 0x80
mask LID 0x3f
size 1
}
SCB_TAG {
......@@ -1239,7 +1240,6 @@ register SG_CACHE_PRE {
access_mode WO
address 0x0fc
mask SG_ADDR_MASK 0xf8
field ODD_SEG 0x04
field LAST_SEG 0x02
field LAST_SEG_DONE 0x01
}
......@@ -1248,7 +1248,6 @@ register SG_CACHE_SHADOW {
access_mode RO
address 0x0fc
mask SG_ADDR_MASK 0xf8
field ODD_SEG 0x04
field LAST_SEG 0x02
field LAST_SEG_DONE 0x01
}
......@@ -1478,14 +1477,6 @@ scratch_ram {
field ENAUTOATNI 0x04
field ENAUTOATNP 0x02
}
/*
* Track whether the transfer byte count for
* the current data phase is odd.
*/
DATA_COUNT_ODD {
size 1
}
}
scratch_ram {
......
......@@ -40,7 +40,7 @@
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $"
PATCH_ARG_LIST = "struct ahc_softc *ahc"
PREFIX = "ahc_"
......@@ -437,7 +437,7 @@ select_out:
mov SCBPTR, WAITING_SCBH;
mov WAITING_SCBH,SCB_NEXT;
mov SAVED_SCSIID, SCB_SCSIID;
mov SAVED_LUN, SCB_LUN;
and SAVED_LUN, LID, SCB_LUN;
call set_transfer_settings;
if ((ahc->flags & AHC_TARGETROLE) != 0) {
test SSTAT0, TARGET jz initiator_select;
......@@ -461,7 +461,7 @@ select_out:
/*
* Start out with a simple identify message.
*/
or SCB_LUN, MSG_IDENTIFYFLAG call target_outb;
or SAVED_LUN, MSG_IDENTIFYFLAG call target_outb;
/*
* If we are the result of a tagged command, send
......@@ -768,16 +768,12 @@ idle_sg_avail:
/* Does the hardware have space for another SG entry? */
test DFSTATUS, PRELOAD_AVAIL jz return;
bmov HADDR, CCSGRAM, 7;
test HCNT[0], 0x1 jz . + 2;
xor DATA_COUNT_ODD, 0x1;
bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
mov SCB_RESIDUAL_DATACNT[3] call set_hhaddr;
}
call sg_advance;
mov SINDEX, SCB_RESIDUAL_SGPTR[0];
test DATA_COUNT_ODD, 0x1 jz . + 2;
or SINDEX, ODD_SEG;
test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2;
or SINDEX, LAST_SEG;
mov SG_CACHE_PRE, SINDEX;
......@@ -875,7 +871,6 @@ data_phase_initialize:
call calc_mwi_residual;
}
and SCB_RESIDUAL_SGPTR[0], ~SG_FULL_RESID;
and DATA_COUNT_ODD, 0x1, HCNT[0];
if ((ahc->features & AHC_ULTRA2) == 0) {
if ((ahc->features & AHC_CMD_CHAN) != 0) {
......@@ -910,8 +905,6 @@ data_phase_inbounds:
mov SINDEX, SCB_RESIDUAL_SGPTR[0];
test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2;
or SINDEX, LAST_SEG;
test DATA_COUNT_ODD, 0x1 jz . + 2;
or SINDEX, ODD_SEG;
mov SG_CACHE_PRE, SINDEX;
mov DFCNTRL, DMAPARAMS;
ultra2_dma_loop:
......@@ -1006,10 +999,8 @@ sgptr_fixup:
adc SCB_RESIDUAL_SGPTR[3], -1;
sgptr_fixup_done:
and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW;
clr DATA_COUNT_ODD;
test SG_CACHE_SHADOW, ODD_SEG jz . + 2;
or DATA_COUNT_ODD, 0x1;
clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */
/* We are not the last seg */
and SCB_RESIDUAL_DATACNT[3], ~SG_LAST_SEG;
residuals_correct:
/*
* Go ahead and shut down the DMA engine now.
......@@ -1053,11 +1044,19 @@ ultra2_fifoflush:
* LAST_SEG_DONE to come true on a completed transfer
* and then test to see if the data FIFO is non-empty.
*/
test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 4;
test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL
jz ultra2_wait_fifoemp;
test SG_CACHE_SHADOW, LAST_SEG_DONE jz .;
/*
* FIFOEMP can lag LAST_SEG_DONE. Wait a few
* clocks before calling this an overrun.
*/
test DFSTATUS, FIFOEMP jnz ultra2_fifoempty;
test DFSTATUS, FIFOEMP jnz ultra2_fifoempty;
test DFSTATUS, FIFOEMP jnz ultra2_fifoempty;
/* Overrun */
jmp data_phase_loop;
ultra2_wait_fifoemp:
test DFSTATUS, FIFOEMP jz .;
}
ultra2_fifoempty:
......@@ -1246,9 +1245,6 @@ sg_load_done:
} else {
call set_stcnt_from_hcnt;
}
/* Track odd'ness */
test HCNT[0], 0x1 jz . + 2;
xor DATA_COUNT_ODD, 0x1;
if ((ahc->flags & AHC_TARGETROLE) != 0) {
test SSTAT0, TARGET jnz data_phase_loop;
......@@ -1350,7 +1346,7 @@ residual_update_done:
*/
test DFCNTRL, DIRECTION jz target_ITloop;
test SSTAT1, REQINIT jnz .;
test DATA_COUNT_ODD, 0x1 jz target_ITloop;
test SCB_LUN, SCB_XFERLEN_ODD jz target_ITloop;
test SCSIRATE, WIDEXFER jz target_ITloop;
/*
* Issue an Ignore Wide Residue Message.
......@@ -1510,7 +1506,7 @@ p_mesgout:
cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host;
test SCB_CONTROL,MK_MESSAGE jnz host_message_loop;
p_mesgout_identify:
or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN;
or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SAVED_LUN;
test SCB_CONTROL, DISCENB jnz . + 2;
and SINDEX, ~DISCENB;
/*
......@@ -1587,7 +1583,7 @@ if ((ahc->features & AHC_WIDE) != 0) {
mvi ARG_1 call inb_next;
cmp ARG_1, 0x01 jne mesgin_reject;
test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2;
test DATA_COUNT_ODD, 0x1 jz mesgin_done;
test SCB_LUN, SCB_XFERLEN_ODD jnz mesgin_done;
mvi IGN_WIDE_RES call set_seqint;
jmp mesgin_done;
}
......@@ -1716,7 +1712,7 @@ mesgin_disconnect:
}
test SCB_CONTROL, TAG_ENB jnz await_busfree;
mov ARG_1, SCB_TAG;
mov SAVED_LUN, SCB_LUN;
and SAVED_LUN, LID, SCB_LUN;
mov SCB_SCSIID call set_busy_target;
jmp await_busfree;
......@@ -1859,7 +1855,7 @@ mesgin_identify:
* at a time. So, if the lun doesn't match, look
* for a tag message.
*/
mov A, SCB_LUN;
and A, LID, SCB_LUN;
cmp SAVED_LUN, A je setup_SCB_id_lun_okay;
if ((ahc->flags & AHC_PAGESCBS) != 0) {
/*
......@@ -1917,7 +1913,7 @@ setup_SCB:
or SEQ_FLAGS, 0x8;
}
setup_SCB_id_okay:
mov A, SCB_LUN;
and A, LID, SCB_LUN;
cmp SAVED_LUN, A jne not_found_cleanup_scb;
setup_SCB_id_lun_okay:
if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
......
......@@ -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#128 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#131 $
*
* $FreeBSD$
*/
......@@ -202,7 +202,7 @@ static void ahc_handle_devreset(struct ahc_softc *ahc,
struct ahc_devinfo *devinfo,
cam_status status, char *message,
int verbose_level);
#if AHC_TARGET_MODE
#ifdef AHC_TARGET_MODE
static void ahc_setup_target_msgin(struct ahc_softc *ahc,
struct ahc_devinfo *devinfo,
struct scb *scb);
......@@ -291,7 +291,7 @@ ahc_restart(struct ahc_softc *ahc)
ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
}
ahc_outb(ahc, MWI_RESIDUAL, 0);
ahc_outb(ahc, SEQCTL, FASTMODE);
ahc_outb(ahc, SEQCTL, ahc->seqctl);
ahc_outb(ahc, SEQADDR0, 0);
ahc_outb(ahc, SEQADDR1, 0);
ahc_unpause(ahc);
......@@ -705,7 +705,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
ahc->msgin_index = 0;
}
}
#if AHC_TARGET_MODE
#ifdef AHC_TARGET_MODE
else {
if (bus_phase == P_MESGOUT) {
ahc->msg_type =
......@@ -1467,7 +1467,7 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
else
ahc_outb(ahc, SIMODE1, 0);
ahc_outb(ahc, CLRINT, CLRSCSIINT);
ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) | STEP);
ahc_outb(ahc, SEQCTL, ahc->seqctl | STEP);
stepping = TRUE;
}
if ((ahc->features & AHC_DT) != 0) {
......@@ -1481,7 +1481,7 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
if (stepping) {
ahc_outb(ahc, SIMODE0, simode0);
ahc_outb(ahc, SIMODE1, simode1);
ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) & ~STEP);
ahc_outb(ahc, SEQCTL, ahc->seqctl);
}
}
......@@ -3573,7 +3573,7 @@ ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
if ((sgptr & SG_LIST_NULL) != 0
&& ahc_inb(ahc, DATA_COUNT_ODD) == 1) {
&& (ahc_inb(ahc, SCB_LUN) & SCB_XFERLEN_ODD) != 0) {
/*
* If the residual occurred on the last
* transfer and the transfer request was
......@@ -3586,25 +3586,27 @@ ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
uint32_t data_addr;
uint32_t sglen;
/* Pull in the rest of the sgptr */
sgptr |= (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
| (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
| (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8);
sgptr &= SG_PTR_MASK;
data_cnt = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+3) << 24)
| (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+2) << 16)
| (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+1) << 8)
| (ahc_inb(ahc, SCB_RESIDUAL_DATACNT));
/* Pull in all of the sgptr */
sgptr = ahc_inl(ahc, SCB_RESIDUAL_SGPTR);
data_cnt = ahc_inl(ahc, SCB_RESIDUAL_DATACNT);
data_addr = (ahc_inb(ahc, SHADDR + 3) << 24)
| (ahc_inb(ahc, SHADDR + 2) << 16)
| (ahc_inb(ahc, SHADDR + 1) << 8)
| (ahc_inb(ahc, SHADDR));
if ((sgptr & SG_LIST_NULL) != 0) {
/*
* The residual data count is not updated
* for the command run to completion case.
* Explicitly zero the count.
*/
data_cnt &= ~AHC_SG_LEN_MASK;
}
data_addr = ahc_inl(ahc, SHADDR);
data_cnt += 1;
data_addr -= 1;
sgptr &= SG_PTR_MASK;
sg = ahc_sg_bus_to_virt(scb, sgptr);
/*
* The residual sg ptr points to the next S/G
* to load so we must go back one.
......@@ -3630,19 +3632,17 @@ ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
*/
sg++;
sgptr = ahc_sg_virt_to_bus(scb, sg);
ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 3,
sgptr >> 24);
ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 2,
sgptr >> 16);
ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 1,
sgptr >> 8);
ahc_outb(ahc, SCB_RESIDUAL_SGPTR, sgptr);
}
ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24);
ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16);
ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8);
ahc_outb(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
ahc_outl(ahc, SCB_RESIDUAL_SGPTR, sgptr);
ahc_outl(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
/*
* Toggle the "oddness" of the transfer length
* to handle this mid-transfer ignore wide
* residue. This ensures that the oddness is
* correct for subsequent data transfers.
*/
ahc_outb(ahc, SCB_LUN,
ahc_inb(ahc, SCB_LUN) ^ SCB_XFERLEN_ODD);
}
}
}
......@@ -3826,6 +3826,12 @@ ahc_alloc(void *platform_arg, char *name)
ahc->features = AHC_FENONE;
ahc->bugs = AHC_BUGNONE;
ahc->flags = AHC_FNONE;
/*
* Default to all error reporting enabled with the
* sequencer operating at its fastest speed.
* The bus attach code may modify this.
*/
ahc->seqctl = FASTMODE;
for (i = 0; i < AHC_NUM_TARGETS; i++)
TAILQ_INIT(&ahc->untagged_queues[i]);
......@@ -3986,7 +3992,7 @@ ahc_free(struct ahc_softc *ahc)
tstate = ahc->enabled_targets[i];
if (tstate != NULL) {
#if AHC_TARGET_MODE
#ifdef AHC_TARGET_MODE
int j;
for (j = 0; j < AHC_NUM_LUNS; j++) {
......@@ -4002,7 +4008,7 @@ ahc_free(struct ahc_softc *ahc)
free(tstate, M_DEVBUF);
}
}
#if AHC_TARGET_MODE
#ifdef AHC_TARGET_MODE
if (ahc->black_hole != NULL) {
xpt_free_path(ahc->black_hole->path);
free(ahc->black_hole, M_DEVBUF);
......@@ -5120,7 +5126,7 @@ ahc_suspend(struct ahc_softc *ahc)
return (EBUSY);
}
#if AHC_TARGET_MODE
#ifdef AHC_TARGET_MODE
/*
* XXX What about ATIOs that have not yet been serviced?
* Perhaps we should just refuse to be suspended if we
......@@ -5221,7 +5227,7 @@ ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target,
if (match != 0)
match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
if (match != 0) {
#if AHC_TARGET_MODE
#ifdef AHC_TARGET_MODE
int group;
group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
......@@ -5964,7 +5970,7 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
* before the reset occurred.
*/
ahc_run_qoutfifo(ahc);
#if AHC_TARGET_MODE
#ifdef AHC_TARGET_MODE
/*
* XXX - In Twin mode, the tqinfifo may have commands
* for an unaffected channel in it. However, if
......@@ -5996,7 +6002,7 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
*/
ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
#if AHC_TARGET_MODE
#ifdef AHC_TARGET_MODE
/*
* Bus resets clear ENSELI, so we cannot
* defer re-enabling bus reset interrupts
......@@ -6015,7 +6021,7 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
} else {
/* Case 2: A command from this bus is active or we're idle */
simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
#if AHC_TARGET_MODE
#ifdef AHC_TARGET_MODE
/*
* Bus resets clear ENSELI, so we cannot
* defer re-enabling bus reset interrupts
......
......@@ -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#42 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#43 $
*
* $FreeBSD$
*/
......@@ -454,6 +454,13 @@ ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb)
panic("Attempt to queue invalid SCB tag %x:%x\n",
scb->hscb->tag, scb->hscb->next);
/*
* Setup data "oddness".
*/
scb->hscb->lun &= LID;
if (ahc_get_transfer_length(scb) & 0x1)
scb->hscb->lun |= SCB_XFERLEN_ODD;
/*
* Keep a history of SCBs we've downloaded in the qinfifo.
*/
......
/*
* Adaptec AIC7xxx device driver for Linux.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#221 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#232 $
*
* Copyright (c) 1994 John Aycock
* The University of Calgary Department of Computer Science.
......@@ -141,11 +141,6 @@
#include <linux/mm.h> /* For fetching system memory size */
#include <linux/blk.h> /* For block_size() */
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
static int errno;
/*
* Lock protecting manipulation of the ahc softc list.
*/
......@@ -746,31 +741,11 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
consumed = 1;
sg->addr = ahc_htole32(addr & 0xFFFFFFFF);
scb->platform_data->xfer_len += len;
if (sizeof(bus_addr_t) > 4
&& (ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
/*
* Due to DAC restrictions, we can't
* cross a 4GB boundary.
*/
if ((addr ^ (addr + len - 1)) & ~0xFFFFFFFF) {
struct ahc_dma_seg *next_sg;
uint32_t next_len;
printf("Crossed Seg\n");
if ((scb->sg_count + 2) > AHC_NSEG)
panic("Too few segs for dma mapping. "
"Increase AHC_NSEG\n");
consumed++;
next_sg = sg + 1;
next_sg->addr = 0;
next_len = 0x100000000 - (addr & 0xFFFFFFFF);
len -= next_len;
next_len |= ((addr >> 8) + 0x1000000) & 0x7F000000;
next_sg->len = ahc_htole32(next_len);
}
len |= (addr >> 8) & 0x7F000000;
}
&& (ahc->flags & AHC_39BIT_ADDRESSING) != 0)
len |= (addr >> 8) & AHC_SG_HIGH_ADDR_MASK;
sg->len = ahc_htole32(len);
return (consumed);
}
......@@ -1195,10 +1170,10 @@ ahc_linux_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs)
}
#endif
#if defined(__i386__)
/*
* Return the disk geometry for the given SCSI device.
*/
#if defined(__i386__)
static int
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
......@@ -1747,7 +1722,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
struct Scsi_Host *host;
char *new_name;
u_long s;
u_int target;
u_int targ_offset;
template->name = ahc->description;
host = scsi_register(template, sizeof(struct ahc_softc *));
......@@ -1802,14 +1777,19 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
* negotiation will occur for the first command, and DV
* will comence should that first command be successful.
*/
for (target = 0;
target < host->max_id * (host->max_channel + 1); target++) {
for (targ_offset = 0;
targ_offset < host->max_id * (host->max_channel + 1);
targ_offset++) {
u_int channel;
u_int target;
channel = 0;
target = targ_offset;
if (target > 7
&& (ahc->features & AHC_TWIN) != 0)
&& (ahc->features & AHC_TWIN) != 0) {
channel = 1;
target &= 0x7;
}
/*
* Skip our own ID. Some Compaq/HP storage devices
* have enclosure management devices that respond to
......@@ -2443,8 +2423,10 @@ ahc_linux_dv_target(struct ahc_softc *ahc, u_int target_offset)
ahc_unlock(ahc, &s);
return;
}
ahc_compile_devinfo(&devinfo, ahc->our_id, targ->target, /*lun*/0,
targ->channel + 'A', ROLE_INITIATOR);
ahc_compile_devinfo(&devinfo,
targ->channel == 0 ? ahc->our_id : ahc->our_id_b,
targ->target, /*lun*/0, targ->channel + 'A',
ROLE_INITIATOR);
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, &devinfo);
......@@ -2616,14 +2598,11 @@ ahc_linux_dv_transition(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
struct ahc_devinfo *devinfo,
struct ahc_linux_target *targ)
{
cam_status cam_status;
u_int32_t status;
u_int scsi_status;
scsi_status = ahc_cmd_get_scsi_status(cmd);
cam_status = ahc_cmd_get_transaction_status(cmd);
status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status);
status = aic_error_action(cmd, targ->inq_data,
ahc_cmd_get_transaction_status(cmd),
ahc_cmd_get_scsi_status(cmd));
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
......@@ -3777,7 +3756,7 @@ ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
cur_seg = (struct scatterlist *)cmd->request_buffer;
nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
scsi_to_pci_dma_dir(cmd ->sc_data_direction));
scsi_to_pci_dma_dir(cmd->sc_data_direction));
end_seg = cur_seg + nseg;
/* Copy the segments into the SG list. */
sg = scb->sg_list;
......@@ -3881,7 +3860,7 @@ ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
/*
* SCSI controller interrupt handler.
*/
AIC_LINUX_IRQRETURN_T
irqreturn_t
ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
{
struct ahc_softc *ahc;
......@@ -3895,7 +3874,7 @@ ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
ahc_schedule_runq(ahc);
ahc_linux_run_complete_queue(ahc);
ahc_unlock(ahc, &flags);
AIC_LINUX_IRQRETURN(ours);
return IRQ_RETVAL(ours);
}
void
......@@ -4910,7 +4889,7 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
disconnected = FALSE;
else if (flag != SCB_ABORT
&& ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid
&& ahc_inb(ahc, SAVED_LUN) == pending_scb->hscb->lun)
&& ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb))
disconnected = FALSE;
}
......
......@@ -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#142 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#147 $
*
*/
#ifndef _AIC7XXX_LINUX_H_
......@@ -305,7 +305,7 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec)
#define AHC_SCSI_HAS_HOST_LOCK 0
#endif
#define AIC7XXX_DRIVER_VERSION "6.2.33"
#define AIC7XXX_DRIVER_VERSION "6.2.35"
/**************************** Front End Queues ********************************/
/*
......@@ -1165,7 +1165,7 @@ void ahc_platform_set_tags(struct ahc_softc *ahc,
int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
char channel, int lun, u_int tag,
role_t role, uint32_t status);
AIC_LINUX_IRQRETURN_T
irqreturn_t
ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
void ahc_platform_flushwork(struct ahc_softc *ahc);
int ahc_softc_comp(struct ahc_softc *, struct ahc_softc *);
......
......@@ -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#44 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#45 $
*/
#include "aic7xxx_osm.h"
......@@ -110,6 +110,7 @@ static int
ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
char buf[80];
bus_addr_t mask_39bit;
struct ahc_softc *ahc;
ahc_dev_softc_t pci;
struct ahc_pci_identity *entry;
......@@ -160,12 +161,12 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
pci_set_master(pdev);
mask_39bit = (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
if (sizeof(bus_addr_t) > 4
&& ahc_linux_get_memsize() > 0x80000000
&& ahc_pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) {
&& ahc_pci_set_dma_mask(pdev, mask_39bit) == 0) {
ahc->flags |= AHC_39BIT_ADDRESSING;
ahc->platform_data->hw_dma_mask =
(bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
ahc->platform_data->hw_dma_mask = mask_39bit;
} else {
ahc_pci_set_dma_mask(pdev, 0xFFFFFFFF);
ahc->platform_data->hw_dma_mask = 0xFFFFFFFF;
......
......@@ -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#63 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#66 $
*
* $FreeBSD$
*/
......@@ -834,10 +834,10 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
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 = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
command |= PCIM_CMD_BUSMASTEREN;
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1);
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
/* On all PCI adapters, we allow SCB paging */
ahc->flags |= AHC_PAGESCBS;
......@@ -854,10 +854,8 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
* error reporting when doing this, so CIO bus, scb ram, and
* scratch ram parity errors will be ignored too.
*/
if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) {
ahc->pause |= FAILDIS;
ahc->unpause |= FAILDIS;
}
if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
ahc->seqctl |= FAILDIS;
ahc->bus_intr = ahc_pci_intr;
ahc->bus_chip_init = ahc_pci_chip_init;
......@@ -2044,8 +2042,8 @@ ahc_pci_intr(struct ahc_softc *ahc)
"%s: WARNING WARNING WARNING WARNING\n",
ahc_name(ahc), ahc_name(ahc), ahc_name(ahc),
ahc_name(ahc), ahc_name(ahc), ahc_name(ahc));
ahc->pause |= FAILDIS;
ahc->unpause |= FAILDIS;
ahc->seqctl |= FAILDIS;
ahc_outb(ahc, SEQCTL, ahc->seqctl);
}
ahc_unpause(ahc);
}
......
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
*/
typedef int (ahc_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahc_reg_parse_entry {
......@@ -432,13 +432,6 @@ ahc_reg_print_t ahc_scsiseq_template_print;
ahc_print_register(NULL, 0, "SCSISEQ_TEMPLATE", 0x54, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahc_reg_print_t ahc_data_count_odd_print;
#else
#define ahc_data_count_odd_print(regvalue, cur_col, wrap) \
ahc_print_register(NULL, 0, "DATA_COUNT_ODD", 0x55, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahc_reg_print_t ahc_ha_274_biosglobal_print;
#else
......@@ -1396,8 +1389,6 @@ ahc_reg_print_t ahc_sg_cache_pre_print;
#define ENAUTOATNI 0x04
#define ENAUTOATNP 0x02
#define DATA_COUNT_ODD 0x55
#define HA_274_BIOSGLOBAL 0x56
#define INITIATOR_TAG 0x56
#define HA_274_EXTENDED_TRANS 0x01
......@@ -1655,7 +1646,8 @@ ahc_reg_print_t ahc_sg_cache_pre_print;
#define TWIN_CHNLB 0x80
#define SCB_LUN 0xba
#define LID 0xff
#define LID 0x3f
#define SCB_XFERLEN_ODD 0x80
#define SCB_TAG 0xbb
......@@ -1749,7 +1741,6 @@ ahc_reg_print_t ahc_sg_cache_pre_print;
#define SG_CACHE_SHADOW 0xfc
#define SG_ADDR_MASK 0xf8
#define ODD_SEG 0x04
#define LAST_SEG 0x02
#define LAST_SEG_DONE 0x01
......
This diff is collapsed.
......@@ -60,12 +60,9 @@
/*
* Linux Interrupt Support.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define AIC_LINUX_IRQRETURN_T irqreturn_t
#define AIC_LINUX_IRQRETURN(ours) return (IRQ_RETVAL(ours))
#else
#define AIC_LINUX_IRQRETURN_T void
#define AIC_LINUX_IRQRETURN(ours) return
#ifndef IRQ_RETVAL
typedef void irqreturn_t;
#define IRQ_RETVAL(x)
#endif
/*
......
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