changeset 528:737dce57f60d

cp: add a lock to the virt device struct Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Mon, 25 Apr 2011 22:20:53 -0400
parents 06ba1772ee9c
children 3879c28965b4
files cp/drivers/vdevice.c cp/include/vdevice.h cp/shell/cmd_query.c cp/shell/instruction_priv.c
diffstat 4 files changed, 32 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/cp/drivers/vdevice.c	Mon Apr 25 22:19:59 2011 -0400
+++ b/cp/drivers/vdevice.c	Mon Apr 25 22:20:53 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * (C) Copyright 2007-2011  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * This file is released under the GPLv2.  See the COPYING file for more
  * details.
@@ -28,6 +28,8 @@
 	return 0;
 }
 
+static LOCK_CLASS(vdev_lc);
+
 int alloc_virt_dev(struct virt_sys *sys, struct directory_vdev *dirdev,
 		   u32 sch)
 {
@@ -38,6 +40,8 @@
 	if (!vdev)
 		return -ENOMEM;
 
+	mutex_init(&vdev->lock, &vdev_lc);
+
 	vdev->vtype = dirdev->type;
 	vdev->sch = sch;
 	vdev->pmcw.v = 1;
--- a/cp/include/vdevice.h	Mon Apr 25 22:19:59 2011 -0400
+++ b/cp/include/vdevice.h	Mon Apr 25 22:20:53 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * (C) Copyright 2007-2011  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * This file is released under the GPLv2.  See the COPYING file for more
  * details.
@@ -11,9 +11,18 @@
 #include <list.h>
 #include <directory.h>
 #include <sched.h>
+#include <mutex.h>
 
 struct virt_device {
 	struct list_head devices;
+
+	/*
+	 * protects the R/W fields:
+	 *  - pmcw
+	 *  - scsw
+	 */
+	mutex_t lock;
+
 	enum directory_vdevtype vtype;	/* VDEV_CONS, VDEV_DED, ... */
 	u32 sch;			/* subchannel id */
 	u16 type;			/* 3330, 3215, ... */
--- a/cp/shell/cmd_query.c	Mon Apr 25 22:19:59 2011 -0400
+++ b/cp/shell/cmd_query.c	Mon Apr 25 22:20:53 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * (C) Copyright 2007-2011  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * This file is released under the GPLv2.  See the COPYING file for more
  * details.
@@ -34,6 +34,8 @@
 
 static void display_vdev(struct console *con, struct virt_device *vdev)
 {
+	mutex_lock(&vdev->lock);
+
 	switch (vdev->vtype) {
 		case VDEV_CONS:
 			con_printf(con, "CONS %04X 3215 ON %s %04X %s SCH = %05X\n",
@@ -76,6 +78,8 @@
 				   vdev->pmcw.dev_num, vdev->sch);
 			break;
 	}
+
+	mutex_unlock(&vdev->lock);
 }
 
 static void display_task(struct console *con, struct task *task)
--- a/cp/shell/instruction_priv.c	Mon Apr 25 22:19:59 2011 -0400
+++ b/cp/shell/instruction_priv.c	Mon Apr 25 22:20:53 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * (C) Copyright 2007-2011  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * This file is released under the GPLv2.  See the COPYING file for more
  * details.
@@ -69,6 +69,8 @@
 
 	gschib = (struct schib*) addr;
 
+	mutex_lock(&vdev->lock);
+
 	/*
 	 * Condition code 1 is set, and no other action is taken, when the
 	 *   subchannel is status pending. (See “Status Control (SC)” on
@@ -76,7 +78,7 @@
 	 */
 	if (vdev->scsw.sc & SC_STATUS) {
 		cpu->sie_cb.gpsw.cc = 1;
-		goto out;
+		goto out_unlock;
 	}
 
 	/*
@@ -86,7 +88,7 @@
 	 */
 	if (vdev->scsw.fc & (FC_START | FC_HALT | FC_CLEAR)) {
 		cpu->sie_cb.gpsw.cc = 2;
-		goto out;
+		goto out_unlock;
 	}
 
 	/*
@@ -124,6 +126,9 @@
 out_cc0:
 	cpu->sie_cb.gpsw.cc = 0;
 
+out_unlock:
+	mutex_unlock(&vdev->lock);
+
 out:
 	return ret;
 }
@@ -192,10 +197,14 @@
 
 	gschib = (struct schib*) addr;
 
+	mutex_lock(&vdev->lock);
+
 	/* copy! */
 	memcpy(&gschib->pmcw, &vdev->pmcw, sizeof(struct pmcw));
 	memcpy(&gschib->scsw, &vdev->scsw, sizeof(struct scsw));
 
+	mutex_unlock(&vdev->lock);
+
 	/* CC: 0 */
 	cpu->sie_cb.gpsw.cc = 0;