Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Aug 2001 15:40:07 -0600
From:      "Justin T. Gibbs" <gibbs@scsiguy.com>
To:        Kayoko Isshi <isshi@cs.fujitsu.co.jp>
Cc:        "'aic7xxx@FreeBSD.ORG'" <aic7xxx@FreeBSD.ORG>
Subject:   Re: test at Target mode 
Message-ID:  <200108172140.f7HLe8I00977@aslan.scsiguy.com>
In-Reply-To: Your message of "Tue, 07 Aug 2001 09:16:52 %2B0900." <3B6F3374.C98B29AF@cs.fujitsu.co.jp> 

next in thread | previous in thread | raw e-mail | index | archive | help
>> >1)When any abort message is received, sequencer should go to BusFree.
>>
>> This is supposed to be handled by the message handler in the kernel
>> driver.  Abort is a rare occurance, so, other than honoring ATNI in
>> all of the right places, the sequencer shouldn't waste instructions on
>> handling abort on its own.
>
>When sequencer goes to ITloop_target,it automatically goes to command phase.
>How dose it go to BusFree directly?

The kernel driver should handle the abort message and simply reset the
sequencer.  This will cause the bus to go free and program execution
to start from the top.

>> >3)When ABORT message(=1 bytes message) is received,
>> >    driver cannot get it because ATNI is off.
>>
>> You mean the kernel handler for target messages doesn't work for 1
>> byte messages?  That seems odd.  ATNI should drop after our REQ and
>> before the ACK for the last byte.  You don't see this hapening?
>
>I'm sorry that the explanation is not sufficient.
>There are 3 cases when abort/reset message received:
>    1)C006      →Abort message×        goto ident_message_done
>    2)0C        →Device Reset message○ goto host_message_loop
>    3)C020260d  →Abort tag message×    goto ident_message_done
>
>Since next ATNI is off after getting last message,
>ident_message_done dose not go to target_mesgout_pending,
>but goes to ITloop_target.

Yes, this is definitely a bug.  We need to set a flag indicating that
an acked message is pending and then test this flag rather than ATNI.
I've attached some diffs, relative to the latest released sequencer,
that may work.  They include a fix so that we will accept an abort
tag even if our incomming command queue is full.  These are untested.

>If it gose to host_message_loop,
>it invokes an INTSTAT interrupt with HOST_MSG_LOOP.
>Then the driver can change the registers but cannot change the route.

The only alternate route is bus free which can be achieved by resetting
the sequencer (ahc_reset()).

--
Justin

==== //depot/src/aic7xxx/aic7xxx.c#45 - /usr/src/aic7xxx/aic7xxx.c ====
--- /tmp/tmp.17017.0	Fri Aug 17 15:48:59 2001
+++ /usr/src/aic7xxx/aic7xxx.c	Fri Aug 17 15:48:14 2001
@@ -240,6 +240,7 @@
 	ahc_outb(ahc, SCSISIGO, 0);		/* De-assert BSY */
 	ahc_outb(ahc, MSG_OUT, MSG_NOOP);	/* No message to send */
 	ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
+	ahc_outb(ahc, LASTPHASE, P_BUSFREE);
 
 	/*
 	 * Ensure that the sequencer's idea of TQINPOS
@@ -705,19 +706,20 @@
 					    MSG_TYPE_INITIATOR_MSGIN;
 					ahc->msgin_index = 0;
 				}
-			} else {
+			}
+#if AHC_TARGET_MODE
+			else {
 				if (bus_phase == P_MESGOUT) {
 					ahc->msg_type =
 					    MSG_TYPE_TARGET_MSGOUT;
 					ahc->msgin_index = 0;
 				}
-#if AHC_TARGET_MODE
 				else 
 					ahc_setup_target_msgin(ahc,
 							       &devinfo,
 							       scb);
-#endif
 			}
+#endif
 		}
 
 		ahc_handle_message_phase(ahc);
@@ -1382,22 +1384,9 @@
 	       hscb->scsiid,
 	       hscb->lun,
 	       hscb->cdb_len);
-	i = 0;
-	printf("Shared Data: %#02x %#02x %#02x %#02x\n",
-	       hscb->shared_data.cdb[i++],
-	       hscb->shared_data.cdb[i++],
-	       hscb->shared_data.cdb[i++],
-	       hscb->shared_data.cdb[i++]);
-	printf("             %#02x %#02x %#02x %#02x\n",
-	       hscb->shared_data.cdb[i++],
-	       hscb->shared_data.cdb[i++],
-	       hscb->shared_data.cdb[i++],
-	       hscb->shared_data.cdb[i++]);
-	printf("             %#02x %#02x %#02x %#02x\n",
-	       hscb->shared_data.cdb[i++],
-	       hscb->shared_data.cdb[i++],
-	       hscb->shared_data.cdb[i++],
-	       hscb->shared_data.cdb[i++]);
+	printf("Shared Data: ");
+	for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
+		printf("%#02x", hscb->shared_data.cdb[i]);
 	printf("        dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
 		ahc_le32toh(hscb->dataptr),
 		ahc_le32toh(hscb->datacnt),
@@ -2359,6 +2348,8 @@
 		ahc_outb(ahc, CLRSINT1, CLRATNO);
 	}
 	ahc_outb(ahc, MSG_OUT, MSG_NOOP);
+	ahc_outb(ahc, SEQ_FLAGS2,
+		 ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
 }
 
 /*
@@ -2995,6 +2986,7 @@
 		}
 		break;
 	}
+#ifdef AHC_TARGET_MODE
 	case MSG_BUS_DEV_RESET:
 		ahc_handle_devreset(ahc, devinfo,
 				    CAM_BDR_SENT,
@@ -3006,7 +2998,6 @@
 	case MSG_ABORT_TAG:
 	case MSG_ABORT:
 	case MSG_CLEAR_QUEUE:
-#ifdef AHC_TARGET_MODE
 		/* Target mode messages */
 		if (devinfo->role != ROLE_TARGET) {
 			reject = TRUE;
@@ -3032,7 +3023,8 @@
 				ahc_send_lstate_events(ahc, lstate);
 			}
 		}
-		done = MSGLOOP_MSGCOMPLETE;
+		ahc_restart(ahc);
+		done = MSGLOOP_TERMINATED;
 		break;
 #endif
 	case MSG_TERM_IO_PROC:
@@ -3502,8 +3494,10 @@
 {
 
 	/* The IRQMS bit is only valid on VL and EISA chips */
-	if ((ahc->chip & AHC_PCI) != 0)
-		ahc->unpause &= ~IRQMS;
+	if ((ahc->chip & AHC_PCI) == 0)
+		ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
+	else
+		ahc->unpause = 0;
 	ahc->pause = ahc->unpause | PAUSE; 
 	/* XXX The shared scb data stuff should be deprecated */
 	if (ahc->scb_data == NULL) {
==== //depot/src/aic7xxx/aic7xxx.reg#20 - /usr/src/aic7xxx/aic7xxx.reg ====
--- /tmp/tmp.17017.1	Fri Aug 17 15:48:59 2001
+++ /usr/src/aic7xxx/aic7xxx.reg	Fri Aug 17 14:35:43 2001
@@ -1464,7 +1464,8 @@
 
 	SEQ_FLAGS2 {
 		size		1
-		bit	SCB_DMA		0x01
+		bit	SCB_DMA			  0x01
+		bit	TARGET_MSG_PENDING	  0x02
 	}
 	/*
 	 * These are reserved registers in the card's scratch ram.  Some of
==== //depot/src/aic7xxx/aic7xxx.seq#34 - /usr/src/aic7xxx/aic7xxx.seq ====
--- /tmp/tmp.17017.2	Fri Aug 17 15:48:59 2001
+++ /usr/src/aic7xxx/aic7xxx.seq	Fri Aug 17 14:52:49 2001
@@ -242,6 +242,7 @@
 		} else {
 			mov	DFDAT, DINDEX;
 		}
+		and	SAVED_LUN, MSG_IDENTIFY_LUNMASK, DINDEX;
 
 		/* Remember for disconnection decision */
 		test	DINDEX, MSG_IDENTIFY_DISCFLAG jnz . + 2;
@@ -257,9 +258,10 @@
 		 * < MSG_IGN_WIDE_RESIDUE.
 		 */
 		add	A, -MSG_SIMPLE_Q_TAG, DINDEX;
-		jnc	ident_messages_done;
+		jnc	ident_messages_done_msg_pending;
 		add	A, -MSG_IGN_WIDE_RESIDUE, DINDEX;
-		jc	ident_messages_done;
+		jc	ident_messages_done_msg_pending;
+
 		/* Store for host */
 		if ((ahc->features & AHC_CMD_CHAN) != 0) {
 			mov	CCSCBRAM, DINDEX;
@@ -285,9 +287,23 @@
 		}
 		mov	INITIATOR_TAG, DINDEX;
 		or	SEQ_FLAGS, TARGET_CMD_IS_TAGGED;
-		test	SCSISIGI, ATNI	jz . + 2;
-		/* Initiator still wants to give us messages */
-		call	target_inb;
+
+ident_messages_done:
+		/* Terminate the ident list */
+		if ((ahc->features & AHC_CMD_CHAN) != 0) {
+			mvi	CCSCBRAM, SCB_LIST_NULL;
+		} else {
+			mvi	DFDAT, SCB_LIST_NULL;
+		}
+		or	SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN;
+		test	SEQ_FLAGS2, TARGET_MSG_PENDING
+			jnz target_mesgout_pending;
+		test	SCSISIGI, ATNI jnz target_mesgout_continue;
+		jmp	target_ITloop;
+
+
+ident_messages_done_msg_pending:
+		or	SEQ_FLAGS2, TARGET_MSG_PENDING;
 		jmp	ident_messages_done;
 
 		/*
@@ -299,31 +315,6 @@
 		cmp	RETURN_1, EXIT_MSG_LOOP	je target_ITloop;
 		test	SSTAT0, SPIORDY jz .;
 		jmp	host_target_message_loop;
-
-ident_messages_done:
-		/* If ring buffer is full, return busy or queue full */
-		if ((ahc->features & AHC_HS_MAILBOX) != 0) {
-			and	A, HOST_TQINPOS, HS_MAILBOX;
-		} else {
-			mov	A, KERNEL_TQINPOS;
-		}
-		cmp	TQINPOS, A jne tqinfifo_has_space;
-		mvi	P_STATUS|BSYO call change_phase;
-		test	SEQ_FLAGS, TARGET_CMD_IS_TAGGED jz . + 3;
-		mvi	STATUS_QUEUE_FULL call target_outb;
-		jmp	target_busfree_wait;
-		mvi	STATUS_BUSY call target_outb;
-		jmp	target_busfree_wait;
-tqinfifo_has_space:	
-		/* Terminate the ident list */
-		if ((ahc->features & AHC_CMD_CHAN) != 0) {
-			mvi	CCSCBRAM, SCB_LIST_NULL;
-		} else {
-			mvi	DFDAT, SCB_LIST_NULL;
-		}
-		or	SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN;
-		test	SCSISIGI, ATNI	jnz target_mesgout_pending;
-		jmp	target_ITloop;
 	}
 
 if ((ahc->flags & AHC_INITIATORROLE) != 0) {
@@ -528,6 +519,24 @@
 		jmp	poll_for_work;
 
 target_cmdphase:
+		/*
+		 * The target has dropped ATN (doesn't want to abort or BDR)
+		 * and we believe this selection to be valid.  If the ring
+		 * buffer for new commands is full, return busy or queue full.
+		 */
+		if ((ahc->features & AHC_HS_MAILBOX) != 0) {
+			and	A, HOST_TQINPOS, HS_MAILBOX;
+		} else {
+			mov	A, KERNEL_TQINPOS;
+		}
+		cmp	TQINPOS, A jne tqinfifo_has_space;
+		mvi	P_STATUS|BSYO call change_phase;
+		test	SEQ_FLAGS, TARGET_CMD_IS_TAGGED jz . + 3;
+		mvi	STATUS_QUEUE_FULL call target_outb;
+		jmp	target_busfree_wait;
+		mvi	STATUS_BUSY call target_outb;
+		jmp	target_busfree_wait;
+tqinfifo_has_space:	
 		mvi	P_COMMAND|BSYO call change_phase;
 		call	target_inb;
 		mov	A, DINDEX;

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe aic7xxx" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200108172140.f7HLe8I00977>