Skip site navigation (1)Skip section navigation (2)
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>