[3547] in linux-scsi channel archive

home help back first fref pref prev next nref lref last post

Re: spinlocks in SCSI code

daemon@ATHENA.MIT.EDU (Kurt Garloff)
Tue Mar 17 07:33:20 1998

Date: 	Tue, 17 Mar 1998 13:29:50 +0100
From: Kurt Garloff <garloff@kg1.ping.de>
To: Doug Ledford <dledford@dialnet.net>, linux-scsi@vger.rutgers.edu,
        "Leonard N. Zubkoff" <lnz@dandelion.com>,
        Gerard Roudier <groudier@club-internet.fr>
Mail-Followup-To: Doug Ledford <dledford@dialnet.net>,
	linux-scsi@vger.rutgers.edu,
	"Leonard N. Zubkoff" <lnz@dandelion.com>,
	Gerard Roudier <groudier@club-internet.fr>
In-Reply-To: <19980317121818.A1000@kg1.ping.de>; from Kurt Garloff on Tue, Mar 17, 1998 at 12:18:18PM +0100


--ZGiS0Q5IWpPtfppv
Content-Type: text/plain; charset=us-ascii

On Tue, Mar 17, 1998 at 12:18:18PM +0100, Kurt Garloff wrote:
> If I correctly understand the locking mechanism, it should be possible to
> create a driver specific spinlock: spinlock_t rmscsim_lock =
> SPIN_LOCK_UNLOCKED; and replace every save_flags(flags); cli(); within the
> driver by spin_lock_irqsave (&tmscsim_lock, flags); and every
> restore_flags(flags); by spin_unlock_irqrestore(&tmscsim_lock, flags);
> [I assume, that all necessary locking is done by the driver at the moment
> using the cli() mechanism, here.]
> This would be somehow suboptimal, but very safe and still much better for
> SMP machines than the current approach. 

Well, as a first test, I implemented this for the ncr53c8xx driver, as I'm
able to test it directly. Of course it works very well, as I have a UP
machine and the spin_lock_irqsave (); does exactly the same as save_flags();
cli();

Too bad I don't have a SMP machine to test.

Gerard, I append the diff. (Against 2.1.89, i.e. ncr53c8xx-2.5f)

-- 
Kurt Garloff, Dortmund 
<K.Garloff@ping.de>
PGP key on http://student.physik.uni-dortmund.de/homepages/garloff

--ZGiS0Q5IWpPtfppv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ncr53c8xx.spinlocks.diff"

--- linux/drivers/scsi/ncr53c8xx.c.2189	Sun Jan 18 14:06:04 1998
+++ linux/drivers/scsi/ncr53c8xx.c	Tue Mar 17 12:40:17 1998
@@ -538,6 +538,16 @@
 **	Other Linux definitions
 */
 
+/* Locking */
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,30)
+static spinlock_t ncr53c8xx_lock = SPIN_LOCK_UNLOCKED;
+# define NCRLOCK(f) spin_lock_irqsave(&ncr53c8xx_lock, f)
+# define NCRUNLOCK(f) spin_unlock_irqrestore(&ncr53c8xx_lock, f)
+#else
+# define NCRLOCK(f) save_flags(f); cli()
+# define NCRUNLOCK(f) restore_flags(f)
+#endif
+
 #define ScsiResult(host_code, scsi_code) (((host_code) << 16) + ((scsi_code) & 0x7f))
 
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
@@ -4617,14 +4627,14 @@
 	**	if interrupts are not enabled yet.
 	**	Then enable disconnects.
 	*/
-	save_flags(flags); cli();
+	NCRLOCK(flags);
 	if (ncr_reset_scsi_bus(np, 0, driver_setup.settle_delay) != 0) {
 		printf("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, TERMINATION, DEVICE POWER etc.!\n", ncr_name(np));
 		restore_flags(flags);
 		goto attach_error;
 	}
 	ncr_exception (np);
-	restore_flags(flags);
+	NCRUNLOCK(flags);
 
 	np->disc = 1;
 
@@ -4777,7 +4787,7 @@
 	**
 	**----------------------------------------------------
 	*/
-	save_flags(flags); cli();
+	NCRLOCK(flags);
 
 	if (np->settle_time && cmd->timeout_per_command >= HZ &&
 		np->settle_time > jiffies + cmd->timeout_per_command - HZ) {
@@ -4786,7 +4796,7 @@
 
         if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->target, cmd->lun))) {
 		insert_into_waiting_list(np, cmd);
-		restore_flags(flags);
+		NCRUNLOCK(flags);
 		return(DID_OK);
 	}
 	cp->cmd = cmd;
@@ -5013,7 +5023,7 @@
 
 	if (segments < 0) {
 		ncr_free_ccb(np, cp, cmd->target, cmd->lun);
-		restore_flags(flags);
+		NCRUNLOCK(flags);
 		return(DID_ERROR);
 	}
 
@@ -5193,7 +5203,7 @@
 	/*
 	**	and reenable interrupts
 	*/
-	restore_flags(flags);
+	NCRUNLOCK(flags);
 
 	/*
 	**	Command is successfully queued.
@@ -5218,12 +5228,12 @@
 {
 	u_long flags;
 
-	save_flags(flags); cli();
+	NCRLOCK(flags);
 
 	if (!np->settle_time) {
 		(void) ncr_reset_scsi_bus(np, 1, settle_delay);
 	}
-	restore_flags(flags);
+	NCRUNLOCK(flags);
 }
 
 static int ncr_reset_scsi_bus(ncb_p np, int enab_int, int settle_delay)
@@ -5303,12 +5313,12 @@
 		np->stalling = 0;
 #endif
 
-	save_flags(flags); cli();
+	NCRLOCK(flags);
 /*
  * Return immediately if reset is in progress.
  */
 	if (np->settle_time) {
-		restore_flags(flags);
+		NCRUNLOCK(flags);
 		return SCSI_RESET_PUNT;
 	}
 /*
@@ -5355,7 +5365,7 @@
 		cmd->scsi_done(cmd);
 	}
 
-	restore_flags(flags);
+	NCRUNLOCK(flags);
 
 	return SCSI_RESET_SUCCESS;
 }
@@ -5385,14 +5395,14 @@
 		np->stalling = 0;
 #endif
 
-	save_flags(flags); cli();
+	NCRLOCK(flags);
 /*
  * First, look for the scsi command in the waiting list
  */
 	if (remove_from_waiting_list(np, cmd)) {
 		cmd->result = ScsiResult(DID_ABORT, 0);
 		cmd->scsi_done(cmd);
-		restore_flags(flags);
+		NCRUNLOCK(flags);
 		return SCSI_ABORT_SUCCESS;
 	}
 
@@ -5411,12 +5421,12 @@
 	}
 
 	if (!found) {
-		restore_flags(flags);
+		NCRUNLOCK(flags);
 		return SCSI_ABORT_NOT_RUNNING;
 	}
 
 	if (np->settle_time) {
-		restore_flags(flags);
+		NCRUNLOCK(flags);
 		return SCSI_ABORT_SNOOZE;
 	}
 
@@ -5448,7 +5458,7 @@
 #endif
 	OUTB (nc_istat, SIGP);
 
-	restore_flags(flags);
+	NCRUNLOCK(flags);
 
 	return retv;
 }
@@ -6697,11 +6707,11 @@
 		if (np->settle_time <= thistime) {
 			if (bootverbose > 1)
 				printf("%s: command processing resumed\n", ncr_name(np));
-			save_flags(flags); cli();
+			NCRLOCK(flags);
 			np->settle_time	= 0;
 			np->disc	= 1;
 			requeue_waiting_list(np);
-			restore_flags(flags);
+			NCRUNLOCK(flags);
 		}
 		return;
 	}
@@ -6715,7 +6725,7 @@
 		/*
 		**	block ncr interrupts
 		*/
-		save_flags(flags); cli();
+		NCRLOCK(flags);
 
 		np->lasttime = thistime;
 
@@ -6803,7 +6813,7 @@
 #endif
 			OUTB (nc_istat, SIGP);
 		}
-		restore_flags(flags);
+		NCRUNLOCK(flags);
 	}
 
 #ifdef SCSI_NCR_BROKEN_INTR
@@ -6812,11 +6822,11 @@
 		/*
 		**	Process pending interrupts.
 		*/
-		save_flags(flags); cli();
+		NCRLOCK(flags);
 		if (DEBUG_FLAGS & DEBUG_TINY) printf ("{");
 		ncr_exception (np);
 		if (DEBUG_FLAGS & DEBUG_TINY) printf ("}");
-		restore_flags(flags);
+		NCRUNLOCK(flags);
 	}
 #endif /* SCSI_NCR_BROKEN_INTR */
 }
@@ -9708,7 +9718,7 @@
 	printk("ncr53c8xx_reset: pid=%lu reset_flags=%x serial_number=%ld serial_number_at_timeout=%ld\n",
 		cmd->pid, reset_flags, cmd->serial_number, cmd->serial_number_at_timeout);
 
-	save_flags(flags); cli();
+	NCRLOCK(flags);
 
 	/*
 	 * We have to just ignore reset requests in some situations.
@@ -9738,7 +9748,7 @@
 #endif
 
 out:
-	restore_flags(flags);
+	NCRUNLOCK(flags);
 	return sts;
 }
 #else
@@ -9763,7 +9773,7 @@
 	printk("ncr53c8xx_abort: pid=%lu serial_number=%ld serial_number_at_timeout=%ld\n",
 		cmd->pid, cmd->serial_number, cmd->serial_number_at_timeout);
 
-	save_flags(flags); cli();
+	NCRLOCK(flags);
 
 	/*
 	 * We have to just ignore abort requests in some situations.
@@ -9775,7 +9785,7 @@
 
 	sts = ncr_abort_command(cmd);
 out:
-	restore_flags(flags);
+	NCRUNLOCK(flags);
 	return sts;
 }
 #else
@@ -10148,9 +10158,9 @@
 	else {
 		long flags;
 
-		save_flags(flags); cli();
+		NCRLOCK(flags);
 		ncr_usercmd (np);
-		restore_flags(flags);
+		NCRUNLOCK(flags);
 	}
 	return length;
 }

--ZGiS0Q5IWpPtfppv--

-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.rutgers.edu

home help back first fref pref prev next nref lref last post