Date: Tue, 11 Feb 1997 10:40:44 -0700 From: "Justin T. Gibbs" <gibbs@narnia.plutotech.com> To: ip@mcc.ac.uk Cc: freebsd-current@freebsd.org Subject: Re: Adaptec 2940 data overruns continue Message-ID: <199702111740.KAA04890@narnia.plutotech.com> In-Reply-To: Your message of "Tue, 11 Feb 1997 16:34:29 GMT." <199702111634.QAA05874@albatross.mcc.ac.uk>
next in thread | previous in thread | raw e-mail | index | archive | help
>I'm still getting heaps of:
>
> sd1: data overrun of 16777215 bytes detected. Forcing a retry.
>
>messages appearing.
>
>A week or so ago I was advised to get a later aic7xxxx.c; I'm now running
>3.0-CURRENT from just before the lite2 merge. Is this late enough?
I just committed the change to fix this today. The patch at the end
of this mail should bring you up to date without having to deal with
Lite2 stuff.
--
Justin T. Gibbs
===========================================
FreeBSD: Turning PCs into workstations
===========================================
Index: dev/aic7xxx/aic7xxx.seq
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx.seq,v
retrieving revision 1.58
diff -c -r1.58 aic7xxx.seq
*** aic7xxx.seq 1997/02/09 03:23:27 1.58
--- aic7xxx.seq 1997/02/10 18:10:43
***************
*** 80,89 ****
* middle of a DMA, so clear DFCNTRL too.
*/
reset:
- clr DFCNTRL
clr SCSISIGO /* De-assert BSY */
p_busfree:
clr SCSIRATE /*
* We don't know the target we will
* connect to, so default to narrow
--- 80,89 ----
* middle of a DMA, so clear DFCNTRL too.
*/
reset:
clr SCSISIGO /* De-assert BSY */
p_busfree:
+ clr DFCNTRL
clr SCSIRATE /*
* We don't know the target we will
* connect to, so default to narrow
***************
*** 390,398 ****
mvi DINDEX, SG_NEXT
mvi SCB_SGPTR call bcopy_4
- /* We have seen a data phase */
- or FLAGS, DPHASE
-
data_phase_loop:
/* Guard against overruns */
test SG_COUNT, 0xff jnz data_phase_inbounds
--- 390,395 ----
***************
*** 441,453 ****
* This, like all DMA's, assumes little-endian host data storage.
*/
sg_load:
- clr HCNT2
- clr HCNT1
- mvi HCNT0,SG_SIZEOF
-
mvi DINDEX, HADDR0
mvi SG_NEXT0 call bcopy_4
or DFCNTRL,0xd /* HDMAEN|DIRECTION|FIFORESET */
call dma_finish
--- 438,450 ----
* This, like all DMA's, assumes little-endian host data storage.
*/
sg_load:
mvi DINDEX, HADDR0
mvi SG_NEXT0 call bcopy_4
+ mvi HCNT0,SG_SIZEOF
+ clr HCNT1
+ clr HCNT2
+
or DFCNTRL,0xd /* HDMAEN|DIRECTION|FIFORESET */
call dma_finish
***************
*** 465,471 ****
/* Load STCNT as well. It is a mirror of HCNT */
call set_stcnt_from_hcnt
! test SSTAT1,PHASEMIS jz data_phase_loop
data_phase_finish:
/*
--- 462,468 ----
/* Load STCNT as well. It is a mirror of HCNT */
call set_stcnt_from_hcnt
! test SSTAT1,PHASEMIS jz data_phase_loop
data_phase_finish:
/*
***************
*** 477,482 ****
--- 474,483 ----
mov SCB_RESID_DCNT1,STCNT1
mov SCB_RESID_DCNT2,STCNT2
mov SCB_RESID_SGCNT, SG_COUNT
+
+ /* We have seen a data phase */
+ or FLAGS, DPHASE
+
jmp ITloop
data_phase_overrun:
***************
*** 809,814 ****
--- 810,816 ----
mov A, SAVED_TCL
cmp SCB_TCL,A jne send_abort_msg
test SCB_CONTROL,TAG_ENB jz send_abort_msg
+ test SCB_CONTROL,DISCONNECTED jz send_abort_msg
jmp setup_SCB
not_found:
***************
*** 907,916 ****
*/
dma:
mov DFCNTRL,SINDEX
! dma1:
! test SSTAT0,DMADONE jnz dma3
! test SSTAT1,PHASEMIS jz dma1 /* ie. underrun */
! test SSTAT0,SDONE jnz dma3
mov SINDEX,ALLZEROS /* Notify caller of phasemiss */
/*
--- 909,919 ----
*/
dma:
mov DFCNTRL,SINDEX
! dma_loop:
! test SSTAT0,DMADONE jnz dma_dmadone
! test SSTAT1,PHASEMIS jz dma_loop /* ie. underrun */
! dma_phasemis:
! test SSTAT0,SDONE jnz dma_checkfifo
mov SINDEX,ALLZEROS /* Notify caller of phasemiss */
/*
***************
*** 921,942 ****
* magically on STCNT=0 or a phase change, so just wait for FIFO empty
* status.
*/
! dma3:
! test DFCNTRL,DIRECTION jnz dma5
! dma4:
! test DFSTATUS,FIFOEMP jz dma4
/*
* Now shut the DMA enables off and make sure that the DMA enables are
* actually off first lest we get an ILLSADDR.
*/
! dma5:
! /* Don't clobber an inprogress host data transfer */
! test DFSTATUS, MREQPEND jnz dma5
! /* disable DMA */
and DFCNTRL, 0xc7 /* ~(SCSIEN|SDMAEN|HDMAEN) */
! dma6:
! test DFCNTRL, 0x38 jnz dma6 /* (SCSIEN|SDMAEN|HDMAEN) */
return:
ret
--- 924,945 ----
* magically on STCNT=0 or a phase change, so just wait for FIFO empty
* status.
*/
! dma_checkfifo:
! test DFCNTRL,DIRECTION jnz dma_fifoempty
! dma_fifoflush:
! test DFSTATUS,FIFOEMP jz dma_fifoflush
+ dma_fifoempty:
+ /* Don't clobber an inprogress host data transfer */
+ test DFSTATUS, MREQPEND jnz dma_fifoempty
/*
* Now shut the DMA enables off and make sure that the DMA enables are
* actually off first lest we get an ILLSADDR.
*/
! dma_dmadone:
and DFCNTRL, 0xc7 /* ~(SCSIEN|SDMAEN|HDMAEN) */
! dma_halt:
! test DFCNTRL, 0x38 jnz dma_halt /* (SCSIEN|SDMAEN|HDMAEN) */
return:
ret
Index: i386/scsi/aic7xxx.c
===================================================================
RCS file: /usr/cvs/src/sys/i386/scsi/aic7xxx.c,v
retrieving revision 1.96
diff -c -r1.96 aic7xxx.c
*** aic7xxx.c 1997/02/09 03:26:56 1.96
--- aic7xxx.c 1997/02/10 18:27:59
***************
*** 1208,1214 ****
hscb->datalen |= sg->len;
hscb->cmdpointer = vtophys(sc);
hscb->cmdlen = sizeof(*sc);
!
scb->flags |= SCB_SENSE;
ahc_outb(ahc, RETURN_1, SEND_SENSE);
--- 1208,1214 ----
hscb->datalen |= sg->len;
hscb->cmdpointer = vtophys(sc);
hscb->cmdlen = sizeof(*sc);
! scb->sg_count = hscb->SG_segment_count;
scb->flags |= SCB_SENSE;
ahc_outb(ahc, RETURN_1, SEND_SENSE);
***************
*** 1344,1358 ****
* BITBUCKET mode.
*/
u_int8_t scbindex = ahc_inb(ahc, SCB_TAG);
u_int32_t overrun;
scb = ahc->scb_data->scbarray[scbindex];
overrun = ahc_inb(ahc, STCNT0)
| (ahc_inb(ahc, STCNT1) << 8)
| (ahc_inb(ahc, STCNT2) << 16);
overrun = 0x00ffffff - overrun;
sc_print_addr(scb->xs->sc_link);
! printf("data overrun of %d bytes detected."
! " Forcing a retry.\n", overrun);
/*
* Set this and it will take affect when the
* target does a command complete.
--- 1344,1372 ----
* BITBUCKET mode.
*/
u_int8_t scbindex = ahc_inb(ahc, SCB_TAG);
+ u_int8_t lastphase = ahc_inb(ahc, LASTPHASE);
u_int32_t overrun;
+ int i;
scb = ahc->scb_data->scbarray[scbindex];
overrun = ahc_inb(ahc, STCNT0)
| (ahc_inb(ahc, STCNT1) << 8)
| (ahc_inb(ahc, STCNT2) << 16);
overrun = 0x00ffffff - overrun;
sc_print_addr(scb->xs->sc_link);
! printf("data overrun of %d bytes detected in %s phase."
! " Tag == 0x%x. Forcing a retry.\n", overrun,
! lastphase == P_DATAIN ? "Data-In" : "Data-Out",
! scb->hscb->tag);
! sc_print_addr(scb->xs->sc_link);
! printf("%s seen Data Phase. Length = %d. NumSGs = %d.\n",
! ahc_inb(ahc, FLAGS) & DPHASE ? "Have" : "Haven't",
! scb->xs->datalen, scb->sg_count);
! for (i = 0; i < scb->sg_count; i++) {
! printf("sg[%d] - Addr 0x%x : Length %d\n",
! i,
! scb->ahc_dma[i].addr,
! scb->ahc_dma[i].len);
! }
/*
* Set this and it will take affect when the
* target does a command complete.
***************
*** 2374,2379 ****
--- 2388,2394 ----
sg++;
}
hscb->SG_segment_count = seg;
+ scb->sg_count = hscb->SG_segment_count;
/* Copy the first SG into the data pointer area */
hscb->data = scb->ahc_dma->addr;
***************
*** 2395,2400 ****
--- 2410,2416 ----
* No data xfer, use non S/G values
*/
hscb->SG_segment_count = 0;
+ scb->sg_count = hscb->SG_segment_count;
hscb->SG_list_pointer = 0;
hscb->data = 0;
hscb->datalen = (SCB_LIST_NULL << 24);
***************
*** 3443,3453 ****
* SG segments that are after the SG where
* the transfer stopped.
*/
! resid_sgs = hscb->residual_SG_segment_count - 1;
while (resid_sgs > 0) {
int sg;
! sg = hscb->SG_segment_count - resid_sgs;
xs->resid += scb->ahc_dma[sg].len;
resid_sgs--;
}
--- 3459,3469 ----
* SG segments that are after the SG where
* the transfer stopped.
*/
! resid_sgs = scb->hscb->residual_SG_segment_count - 1;
while (resid_sgs > 0) {
int sg;
! sg = scb->sg_count - resid_sgs;
xs->resid += scb->ahc_dma[sg].len;
resid_sgs--;
}
Index: i386/scsi/aic7xxx.h
===================================================================
RCS file: /usr/cvs/src/sys/i386/scsi/aic7xxx.h,v
retrieving revision 1.36
diff -c -r1.36 aic7xxx.h
*** aic7xxx.h 1997/02/03 02:16:16 1.36
--- aic7xxx.h 1997/02/09 22:31:18
***************
*** 209,214 ****
--- 209,215 ----
scb_flag flags;
struct ahc_dma_seg *ahc_dma;/* Pointer to SG segments */
struct scsi_sense sense_cmd;
+ u_int8_t sg_count;/* How full ahc_dma_seg is */
u_int8_t position;/* Position in card's scbarray */
};
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199702111740.KAA04890>
