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 @@ ...@@ -39,7 +39,7 @@
* *
* $FreeBSD$ * $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 * This file is processed by the aic7xxx_asm utility for use in assembling
...@@ -3842,10 +3842,15 @@ scb { ...@@ -3842,10 +3842,15 @@ scb {
} }
SCB_LUN { SCB_LUN {
size 1 size 1
field LID 0xff field LID 0xff
} }
SCB_TASK_ATTRIBUTE { SCB_TASK_ATTRIBUTE {
size 1 size 1
/*
* Overloaded field for non-packetized
* ignore wide residue message handling.
*/
field SCB_XFERLEN_ODD 0x01
} }
SCB_CDB_LEN { SCB_CDB_LEN {
size 1 size 1
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#93 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $"
PATCH_ARG_LIST = "struct ahd_softc *ahd" PATCH_ARG_LIST = "struct ahd_softc *ahd"
PREFIX = "ahd_" PREFIX = "ahd_"
...@@ -872,7 +872,8 @@ mesgin_ign_wide_residue: ...@@ -872,7 +872,8 @@ mesgin_ign_wide_residue:
mvi REG0 call inb_next; mvi REG0 call inb_next;
cmp REG0, 0x01 jne mesgin_reject; cmp REG0, 0x01 jne mesgin_reject;
test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2; 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; jmp mesgin_done;
mesgin_proto_violation: mesgin_proto_violation:
...@@ -1317,8 +1318,6 @@ idle_sg_avail: ...@@ -1317,8 +1318,6 @@ idle_sg_avail:
bmov HADDR, CCSGRAM, 4; bmov HADDR, CCSGRAM, 4;
} }
bmov HCNT, CCSGRAM, 3; bmov HCNT, CCSGRAM, 3;
test HCNT[0], 0x1 jz . + 2;
xor DATA_COUNT_ODD, 0x1;
bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1; bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
and HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3]; and HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3];
...@@ -1334,8 +1333,6 @@ sg_advance: ...@@ -1334,8 +1333,6 @@ sg_advance:
adc SCB_RESIDUAL_SGPTR[2],A; adc SCB_RESIDUAL_SGPTR[2],A;
adc SCB_RESIDUAL_SGPTR[3],A; adc SCB_RESIDUAL_SGPTR[3],A;
mov SINDEX, SCB_RESIDUAL_SGPTR[0]; 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; test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 3;
or SINDEX, LAST_SEG; or SINDEX, LAST_SEG;
clr SG_STATE; clr SG_STATE;
...@@ -1361,12 +1358,9 @@ sg_advance: ...@@ -1361,12 +1358,9 @@ sg_advance:
*/ */
load_first_seg: load_first_seg:
bmov HADDR, SCB_DATAPTR, 11; bmov HADDR, SCB_DATAPTR, 11;
and DATA_COUNT_ODD, 0x1, SCB_DATACNT[0];
and REG_ISR, ~SG_FULL_RESID, SCB_SGPTR[0]; and REG_ISR, ~SG_FULL_RESID, SCB_SGPTR[0];
test SCB_DATACNT[3], SG_LAST_SEG jz . + 2; test SCB_DATACNT[3], SG_LAST_SEG jz . + 2;
or REG_ISR, LAST_SEG; or REG_ISR, LAST_SEG;
test DATA_COUNT_ODD, 0x1 jz . + 2;
or REG_ISR, ODD_SEG;
mov SG_CACHE_PRE, REG_ISR; mov SG_CACHE_PRE, REG_ISR;
mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);
/* /*
...@@ -1516,7 +1510,7 @@ data_phase_done: ...@@ -1516,7 +1510,7 @@ data_phase_done:
* send Ignore Wide Residue messages for data-in phases. * send Ignore Wide Residue messages for data-in phases.
test DFCNTRL, DIRECTION jz target_ITloop; test DFCNTRL, DIRECTION jz target_ITloop;
test SSTAT1, REQINIT jnz .; 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) SET_MODE(M_SCSI, M_SCSI)
test NEGCONOPTS, WIDEXFER jz target_ITloop; test NEGCONOPTS, WIDEXFER jz target_ITloop;
*/ */
...@@ -1586,9 +1580,6 @@ sgptr_fixup: ...@@ -1586,9 +1580,6 @@ sgptr_fixup:
adc SCB_RESIDUAL_SGPTR[3], -1; adc SCB_RESIDUAL_SGPTR[3], -1;
sgptr_fixup_done: sgptr_fixup_done:
and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW; 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 */ clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */
bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret; bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#192 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#193 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -4401,7 +4401,7 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) ...@@ -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); sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
if ((sgptr & SG_LIST_NULL) != 0 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 * If the residual occurred on the last
* transfer and the transfer request was * transfer and the transfer request was
...@@ -4414,29 +4414,20 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) ...@@ -4414,29 +4414,20 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
uint32_t sglen; uint32_t sglen;
/* Pull in the rest of the sgptr */ /* Pull in the rest of the sgptr */
sgptr |= sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
(ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24) data_cnt = ahd_inl_scbram(ahd, SCB_RESIDUAL_DATACNT);
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16) if ((sgptr & SG_LIST_NULL) != 0) {
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8); /*
sgptr &= SG_PTR_MASK; * The residual data count is not updated
data_cnt = * for the command run to completion case.
(ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24) * Explicitly zero the count.
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+2) << 16) */
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+1) << 8) data_cnt &= ~AHD_SG_LEN_MASK;
| (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT)); }
data_addr = ahd_inq(ahd, SHADDR);
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));
data_cnt += 1; data_cnt += 1;
data_addr -= 1; data_addr -= 1;
sgptr &= SG_PTR_MASK;
if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
struct ahd_dma64_seg *sg; struct ahd_dma64_seg *sg;
...@@ -4504,16 +4495,17 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) ...@@ -4504,16 +4495,17 @@ ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
sg); sg);
} }
} }
ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 3, sgptr >> 24); /*
ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 2, sgptr >> 16); * Toggle the "oddness" of the transfer length
ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 1, sgptr >> 8); * to handle this mid-transfer ignore wide
ahd_outb(ahd, SCB_RESIDUAL_SGPTR, sgptr); * residue. This ensures that the oddness is
* correct for subsequent data transfers.
ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24); */
ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16); ahd_outb(ahd, SCB_TASK_ATTRIBUTE,
ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8); ahd_inb(ahd, SCB_TASK_ATTRIBUTE) ^ SCB_XFERLEN_ODD);
ahd_outb(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
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 * The FIFO's pointers will be updated if/when the
* sequencer re-enters a data phase. * sequencer re-enters a data phase.
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#49 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#50 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -271,7 +271,12 @@ ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb) ...@@ -271,7 +271,12 @@ ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb)
scb->crc_retry_count = 0; scb->crc_retry_count = 0;
if ((scb->flags & SCB_PACKETIZED) != 0) { if ((scb->flags & SCB_PACKETIZED) != 0) {
/* XXX what about ACA?? It is type 4, but TAG_TYPE == 0x3. */ /* 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 if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated * DO NOT EDIT - This file is automatically generated
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#93 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#68 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $
*/ */
typedef int (ahd_reg_print_t)(u_int, u_int *, u_int); typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahd_reg_parse_entry { typedef struct ahd_reg_parse_entry {
...@@ -3683,6 +3683,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3683,6 +3683,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define LID 0xff #define LID 0xff
#define SCB_TASK_ATTRIBUTE 0x1ab #define SCB_TASK_ATTRIBUTE 0x1ab
#define SCB_XFERLEN_ODD 0x01
#define SCB_CDB_LEN 0x1ac #define SCB_CDB_LEN 0x1ac
#define SCB_CDB_LEN_PTR 0x80 #define SCB_CDB_LEN_PTR 0x80
...@@ -3768,5 +3769,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3768,5 +3769,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
/* Exported Labels */ /* Exported Labels */
#define LABEL_seq_isr 0x271 #define LABEL_seq_isr 0x269
#define LABEL_timer_isr 0x26d #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