X-Sender: ddkilzer@mail.earthlink.net
In-Reply-To: <199809081041.LAA13960@lassi.cygnus.co.uk>
X-Files: Sundays at 8 PM CDT on Fox!
Date: Tue, 8 Sep 1998 07:53:35 -0500
To: Jesper Skov <jskov@cygnus.co.uk>
From: "David D. Kilzer" <ddkilzer@earthlink.net>
Subject: Re: L68K: NCR53C9x patch [forwarded message from Carsten Pluntke]
Cc: linux-m68k@lists.linux-m68k.org
X-MIME-Autoconverted: from quoted-printable to 8bit by www.phil.uni-sb.de id OAA27659
Sender: owner-linux-m68k@phil.uni-sb.de

Here's the instant replay, sans MIME!

This should help with many of the late Mac Quadras which use NCR53C96 chips (or NCR53C94 chips for the AV Macs).

FWIW, Eudora did *NOT* decode this since the MIME content separators were 'destroyed' during the forwarding (%s/^-/- -/) and there were no MIME headers left in the forwarded message.  Had to chop off everything but the encoded message part and run it through Mpack.

Dave


On 09/08/1998, Jesper Skov wrote:

>------- start of forwarded message (RFC 934 encapsulation) -------
>From: Carsten Pluntke <su0289@sx2.hrz.uni-dortmund.de>
>To: Linux Kernel List <linux-kernel@vger.rutgers.edu>
>cc: Jesper Skov <jskov@cygnus.co.uk>
>Subject: [PATCH] NCR53C9x SCSI disconnect bugfix
>Date: Tue, 8 Sep 1998 08:11:15 +0200 (MET DST)
>
>According to recent messages I fixed the bug in the NCR53C9x SCSI driver
>which stops SCSI operation when a target disconnected.
>
>Another little bugfix concerns extremely slow targets (like my Microtek
>ScanMaker 630) which doesn't free the bus quick enough to not to cause
>confusion on fast systems. See comments in file.
>
>                                Carsten
>[Attachment:NCR53C9x-patch]
>------- end -------


diff -urN -X exclude linux-2.1.115/drivers/scsi/NCR53C9x.c linux-2.1.115-current/drivers/scsi/NCR53C9x.c
--- linux-2.1.115/drivers/scsi/NCR53C9x.c	Mon Sep  7 18:35:21 1998
+++ linux-2.1.115-current/drivers/scsi/NCR53C9x.c	Mon Sep  7 19:21:05 1998
@@ -694,6 +694,7 @@
 	/* Initialize the command queues */
 	esp->current_SC = 0;
 	esp->disconnected_SC = 0;
+	esp->disconnected_mask = 0;
 	esp->issue_SC = 0;
 	
 	/* Clear the state machines. */
@@ -987,22 +988,41 @@
 static inline void esp_exec_cmd(struct NCR_ESP *esp)
 {
 	struct ESP_regs *eregs = esp->eregs;
-	Scsi_Cmnd *SCptr;
+	Scsi_Cmnd *SCptr, **SCptr2;
 	Scsi_Device *SDptr;
 	volatile unchar *cmdp = esp->esp_command;
 	unsigned char the_esp_command;
 	int lun, target;
 	int i;
 
-	/* Hold off if we've been reselected or an IRQ is showing... */
-	if(esp->disconnected_SC || esp->dma_irq_p(esp))
-		return;
+	/* Hold off if an IRQ is showing... */
+	if(esp->dma_irq_p(esp)) return;
 
-	/* Grab first member of the issue queue. */
-	SCptr = esp->current_SC = remove_first_SC(&esp->issue_SC);
+	SCptr2 = &(esp->issue_SC);
 
 	/* Safe to panic here because current_SC is null. */
-	if(!SCptr) panic("esp: esp_exec_cmd and issue queue is NULL");
+	if(!(*SCptr2)) panic("esp: esp_exec_cmd and issue queue is NULL");
+
+	/* Search for first command whose target is not disconnected
+	 * (free bus means target is idle in that case)
+	 */
+	while(*SCptr2)
+	 {
+	  if(!(esp->disconnected_mask & (1 << ((*SCptr2)->target)))) break;
+	  SCptr2 = (Scsi_Cmnd **) &((*SCptr2)->host_scribble);
+	 }
+
+	/* Here it means no suitable command found. */
+	if(!(*SCptr2)) return;
+	
+	/* Grab member of the issue queue. */
+	SCptr = esp->current_SC = remove_first_SC(SCptr2);
+
+	/*
+	 * Some devices (like my scanner) are so slow that we really need to
+	 * make sure that the bus is free.
+	 */
+        while(esp->eregs->esp_status & ESP_STAT_PMASK);
 
 	SDptr = SCptr->device;
 	lun = SCptr->lun;
@@ -2130,6 +2150,7 @@
 		esp_cmd(esp, eregs, ESP_CMD_ESEL);
 		ESPDISC(("D<%02x,%02x>", SCptr->target, SCptr->lun));
 		append_SC(&esp->disconnected_SC, SCptr);
+		esp->disconnected_mask |= (1 << (SCptr->target));
 		esp->current_SC = NULL;
 		if(esp->issue_SC)
 			esp_exec_cmd(esp);
@@ -2180,6 +2201,8 @@
 		esp_cmd(esp, eregs, ESP_CMD_NULL);
 	}
 
+	esp->disconnected_mask &= ~(1 << target);
+	
 	SCptr = remove_SC(&esp->disconnected_SC, (unchar) target, (unchar) lun);
 	if(!SCptr) {
 		Scsi_Cmnd *sp;
diff -urN -X exclude linux-2.1.115/drivers/scsi/NCR53C9x.h linux-2.1.115-current/drivers/scsi/NCR53C9x.h
--- linux-2.1.115/drivers/scsi/NCR53C9x.h	Mon Aug 17 20:32:16 1998
+++ linux-2.1.115-current/drivers/scsi/NCR53C9x.h	Mon Sep  7 18:45:26 1998
@@ -282,6 +282,11 @@
   Scsi_Cmnd *current_SC;         /* Who is currently working the bus */
   Scsi_Cmnd *disconnected_SC;    /* Commands disconnected from the bus */
 
+  /* when fetching the next command out of issue_SC, ignore the targets
+   * whose bit is set; they're currently busy.
+   */
+  int disconnected_mask;         /* bit mask of disconnected targets */
+
   /* Message goo */
   unchar cur_msgout[16];
   unchar cur_msgin[16];


