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>