public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: "Philip R. Auld" <pauld@egenera.com>
To: linux-scsi@vger.kernel.org
Subject: Re: ide-scsi emulation hangs the kernel?
Date: Thu, 11 Dec 2003 09:13:52 -0500	[thread overview]
Message-ID: <20031211091352.U21958@vienna.EGENERA.COM> (raw)
In-Reply-To: <1071099386.28943.45.camel@patibmrh9>; from p.lavarre@ieee.org on Wed, Dec 10, 2003 at 04:36:26PM -0700

Hi,

Rumor has it that on Wed, Dec 10, 2003 at 04:36:26PM -0700 Pat LaVarre said:
> > Could anybody please tell me what's wrong with
> > the ide-scsi emulation in 2.4.21?
> 

I didn't see the original email, but have had this problem in the past. 
I hit this with a TOSHIBA DVD-ROM SD-C2612 and serverworks CSB5 IDE chip.

There is no timeout handling in ide-scsi. And once it times out the 
command gets re-issued with a timeout that can go off immediately. This 
patch fixes the problem on my system. It's for 2.4.9 but from the sound 
of it should be applicable to later kernels. Your milage may vary.

Cheers,

Phil


diff -ruN -X ../patches/dontdiff linux-clean/drivers/scsi/ide-scsi.c linux-cblade/drivers/scsi/ide-scsi.c
--- linux-clean/drivers/scsi/ide-scsi.c	Fri Aug 29 10:15:16 2003
+++ linux-cblade/drivers/scsi/ide-scsi.c	Fri Aug 29 10:23:25 2003
@@ -77,6 +77,7 @@
 #define PC_DMA_IN_PROGRESS		0	/* 1 while DMA in progress */
 #define PC_WRITING			1	/* Data direction */
 #define PC_TRANSFORM			2	/* transform SCSI commands */
+#define PC_TIMEDOUT                    3       /* command timed out */
 
 /*
  *	SCSI command transformation layer
@@ -113,6 +114,11 @@
 #define IDESCSI_IREASON_COD	0x1		/* Information transferred is command */
 #define IDESCSI_IREASON_IO	0x2		/* The device requests us to read */
 
+/* 
+ *      Timeout less than given scsi cmd timeout to use.
+ */
+#define IDESCSI_TIMEOUT_DELTA     (2 * HZ)
+
 static void idescsi_discard_data (ide_drive_t *drive, unsigned int bcount)
 {
 	while (bcount--)
@@ -279,7 +285,12 @@
 		pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
 		if (log)
 			printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number);
-	} else {
+	} else  if (test_bit(PC_TIMEDOUT, &pc->flags)){
+		pc->scsi_cmd->result = DID_TIME_OUT << 16;
+		if (log)
+			printk ("ide-scsi: %s: timed out  for %lu\n", drive->name, pc->scsi_cmd->serial_number);
+	}
+	else {
 		pc->scsi_cmd->result = DID_OK << 16;
 		idescsi_transform_pc2 (drive, pc);
 		if (log) {
@@ -301,7 +312,21 @@
 
 static inline unsigned long get_timeout(idescsi_pc_t *pc)
 {
-	return IDE_MAX(WAIT_CMD, pc->timeout - jiffies);
+	return IDE_MAX(WAIT_CMD, (signed long) (pc->timeout -jiffies));
+}
+
+/* timeout handler. Mark command as having timed out. 
+ */
+int idescsi_expiry (ide_drive_t *drive){
+	idescsi_scsi_t *scsi = drive->driver_data;
+	idescsi_pc_t *pc=scsi->pc;
+
+#if IDESCSI_DEBUG_LOG
+	printk(KERN_INFO "idescsi_expiry called for %lu at %lu\n", pc->scsi_cmd->serial_number, jiffies);
+#endif
+	set_bit(PC_TIMEDOUT, &pc->flags);
+
+	return 0;
 }
 
 /*
@@ -320,6 +345,15 @@
 	printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n");
 #endif /* IDESCSI_DEBUG_LOG */
 
+	if (test_bit(PC_TIMEDOUT, &pc->flags)){
+#if IDESCSI_DEBUG_LOG
+		printk("idescsi_pc_intr: got timed out packet  %lu at %lu\n", pc->scsi_cmd->serial_number, jiffies);
+#endif
+		/* end this request now - scsi should retry it*/
+		idescsi_end_request (0, HWGROUP(drive));
+		return ide_do_reset (drive);
+	}
+
 	if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
 #if IDESCSI_DEBUG_LOG
 		printk ("ide-scsi: %s: DMA complete\n", drive->name);
@@ -363,7 +397,7 @@
 				pc->actually_transferred += temp;
 				pc->current_position += temp;
 				idescsi_discard_data (drive,bcount - temp);
-				ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL);
+				ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
 				return ide_started;
 			}
 #if IDESCSI_DEBUG_LOG
@@ -387,7 +421,7 @@
 	pc->actually_transferred+=bcount;				/* Update the current position */
 	pc->current_position+=bcount;
 
-	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL);	/* And set the interrupt handler again */
+	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);	/* And set the interrupt handler again */
 	return ide_started;
 }
 
@@ -407,7 +441,7 @@
 		printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
 		return ide_do_reset (drive);
 	}
-	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL);	/* Set the interrupt routine */
+	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);	/* Set the interrupt routine */
 	atapi_output_bytes (drive, scsi->pc->c, 12);			/* Send the actual packet */
 	return ide_started;
 }
@@ -442,7 +476,7 @@
 		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
 	}
 	if (test_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
-		ide_set_handler (drive, &idescsi_transfer_pc, get_timeout(pc), NULL);
+		ide_set_handler (drive, &idescsi_transfer_pc, get_timeout(pc), idescsi_expiry);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);		/* Issue the packet command */
 		return ide_started;
 	} else {
@@ -776,7 +810,7 @@
 	pc->request_transfer = pc->buffer_size = cmd->request_bufflen;
 	pc->scsi_cmd = cmd;
 	pc->done = done;
-	pc->timeout = jiffies + cmd->timeout_per_command;
+	pc->timeout = jiffies + cmd->timeout_per_command - IDESCSI_TIMEOUT_DELTA;
 
 	if (should_transform(drive, cmd))
 		set_bit(PC_TRANSFORM, &pc->flags);


-- 
Philip R. Auld, Ph.D.  	        	       Egenera, Inc.    
Principal Software Engineer                   165 Forest St.
(508) 858-2628                            Marlboro, MA 01752

  reply	other threads:[~2003-12-11 14:14 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-12-10 23:36 ide-scsi emulation hangs the kernel? Pat LaVarre
2003-12-11 14:13 ` Philip R. Auld [this message]
2003-12-11 19:31 ` Pat LaVarre
  -- strict thread matches above, loose matches on Subject: below --
2003-12-09 22:36 Yuri Prushinsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20031211091352.U21958@vienna.EGENERA.COM \
    --to=pauld@egenera.com \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox