Commit c556b56b authored by Justin T. Gibbs's avatar Justin T. Gibbs

Aic79xx Driver Update

 o Correct/Simplify ignore wide residue message handling
parent 7bf0ba59
......@@ -39,7 +39,7 @@
*
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#68 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $"
/*
* This file is processed by the aic7xxx_asm utility for use in assembling
......@@ -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#93 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $"
PATCH_ARG_LIST = "struct ahd_softc *ahd"
PREFIX = "ahd_"
......@@ -872,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:
......@@ -1317,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];
......@@ -1334,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;
......@@ -1361,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);
/*
......@@ -1516,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;
*/
......@@ -1586,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#192 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#193 $
*
* $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.
......
......@@ -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#49 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#50 $
*
* $FreeBSD$
*/
......@@ -271,7 +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;
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
......
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#93 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#68 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $
*/
typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahd_reg_parse_entry {
......@@ -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 0x271
#define LABEL_timer_isr 0x26d
#define LABEL_seq_isr 0x269
#define LABEL_timer_isr 0x265
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