Skip to contentSkip to conversation

s390 (3/16): common i/o layer update.

PATCH New Martin Schwidefsky 1 participant 1 message Apr 14, 2003

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 s390 (3/16): common i/o layer update.

Common i/o layer fixes:
- Fix for path no operational condition in cio_start.
- Fix handling of user interruption parameter.
- Add code to wait for devices in init_ccw_bus_type.
- Move qdio states out of main cio state machine.
- Reworked chsc data structures.
- Add ccw_device_start_timeout.
- Handle path verification required flag.

diffstat:

 cio/airq.c          |    6 
 cio/airq.h          |    4 
 cio/chsc.c          |  338 ++++++++++++++++-----------
 cio/chsc.h          |   83 ------
 cio/cio.c           |   29 --
 cio/cio.h           |    9 
 cio/css.c           |    8 
 cio/css.h           |    1 
 cio/device.c        |   70 +++++
 cio/device.h        |   10 
 cio/device_fsm.c    |  200 +++++++---------
 cio/device_id.c     |   10 
 cio/device_ops.c    |   98 +++++---
 cio/device_pgid.c   |   27 +-
 cio/device_status.c |    4 
 cio/qdio.c          |  635 ++++++++++++++++++++++++++++------------------------
 cio/qdio.h          |  110 +--------
 cio/requestirq.c    |    6 
 s390mach.c          |   14 -
 19 files changed, 859 insertions(+), 803 deletions(-)
drivers/s390/cio/airq.c +3 -3
diff -urN linux-2.5.67/drivers/s390/cio/airq.c linux-2.5.67-s390/drivers/s390/cio/airq.c
@@ -2,7 +2,7 @@
  *  drivers/s390/cio/airq.c
  *   S/390 common I/O routines -- support for adapter interruptions
  *
- *   $Revision: 1.10 $
+ *   $Revision: 1.11 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -87,14 +87,14 @@
 }
 
 void
-do_adapter_IO (__u32 intparm)
+do_adapter_IO (void)
 {
 	CIO_TRACE_EVENT (4, "doaio");
 
 	spin_lock (&adapter_lock);
 
 	if (adapter_handler)
-		(*adapter_handler) (intparm);
+		(*adapter_handler) ();
 
 	spin_unlock (&adapter_lock);
 
drivers/s390/cio/airq.h +2 -2
diff -urN linux-2.5.67/drivers/s390/cio/airq.h linux-2.5.67-s390/drivers/s390/cio/airq.h
@@ -1,10 +1,10 @@
 #ifndef S390_AINTERRUPT_H
 #define S390_AINTERRUPT_H
 
-typedef	int (*adapter_int_handler_t)(__u32 intparm);
+typedef	int (*adapter_int_handler_t)(void);
 
 extern int s390_register_adapter_interrupt(adapter_int_handler_t handler);
 extern int s390_unregister_adapter_interrupt(adapter_int_handler_t handler);
-extern void do_adapter_IO (__u32 intparm);
+extern void do_adapter_IO (void);
 
 #endif
drivers/s390/cio/chsc.c +199 -139

535 lines not on this page · raw message

drivers/s390/cio/chsc.h +4 -79

89 lines not on this page · raw message

drivers/s390/cio/cio.c +11 -18
diff -urN linux-2.5.67/drivers/s390/cio/cio.c linux-2.5.67-s390/drivers/s390/cio/cio.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/cio.c
  *   S/390 common I/O routines -- low level i/o calls
- *   $Revision: 1.91 $
+ *   $Revision: 1.97 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -176,13 +176,13 @@
 	CIO_TRACE_EVENT(0, dbf_text);
 	CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib));
 
-	return -ENODEV;
+	return (sch->lpm ? -EACCES : -ENODEV);
 }
 
 int
 cio_start (struct subchannel *sch,	/* subchannel structure */
 	   struct ccw1 * cpa,		/* logical channel prog addr */
-	   unsigned long intparm,	/* interruption parameter */
+	   unsigned int intparm,	/* interruption parameter */
 	   __u8 lpm)			/* logical path mask */
 {
 	char dbf_txt[15];
@@ -191,7 +191,7 @@
 	sprintf (dbf_txt, "stIO%x", sch->irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
-	sch->orb.intparm = (__u32) (long) &sch->u_intparm;
+	sch->orb.intparm = intparm;
 	sch->orb.fmt = 1;
 
 	sch->orb.pfch = sch->options.prefetch == 0;
@@ -219,7 +219,6 @@
 		/*
 		 * initialize device status information
 		 */
-		sch->u_intparm = intparm;
 		sch->schib.scsw.actl |= SCSW_ACTL_START_PEND;
 		return 0;
 	case 1:		/* status pending */
@@ -265,13 +264,10 @@
 }
 
 /*
- * Note: The "intparm" parameter is not used by the halt_IO() function
- *	 itself, as no ORB is built for the HSCH instruction. However,
- *	 it allows the device interrupt handler to associate the upcoming
- *	 interrupt with the halt_IO() request.
+ * halt I/O operation
  */
 int
-cio_halt(struct subchannel *sch, unsigned long intparm)
+cio_halt(struct subchannel *sch)
 {
 	char dbf_txt[15];
 	int ccode;
@@ -297,7 +293,6 @@
 
 	switch (ccode) {
 	case 0:
-		sch->u_intparm = intparm;
 		sch->schib.scsw.actl |= SCSW_ACTL_HALT_PEND;
 		return 0;
 	case 1:		/* status pending */
@@ -309,13 +304,10 @@
 }
 
 /*
- * Note: The "intparm" parameter is not used by the clear_IO() function
- *	 itself, as no ORB is built for the CSCH instruction. However,
- *	 it allows the device interrupt handler to associate the upcoming
- *	 interrupt with the clear_IO() request.
+ * Clear I/O operation
  */
 int
-cio_clear(struct subchannel *sch, unsigned long intparm)
+cio_clear(struct subchannel *sch)
 {
 	char dbf_txt[15];
 	int ccode;
@@ -340,7 +332,6 @@
 
 	switch (ccode) {
 	case 0:
-		sch->u_intparm = intparm;
 		sch->schib.scsw.actl |= SCSW_ACTL_CLEAR_PEND;
 		return 0;
 	default:		/* device not operational */
@@ -374,6 +365,8 @@
 
 	switch (ccode) {
 	case 0:		/* success */
+		/* Update information in scsw. */
+		stsch (sch->irq, &sch->schib);
 		return 0;
 	case 1:		/* status pending */
 		return -EBUSY;
@@ -620,7 +613,7 @@
 		 */
 		if (tpi_info->adapter_IO == 1 &&
 		    tpi_info->int_type == IO_INTERRUPT_TYPE) {
-			do_adapter_IO (tpi_info->intparm);
+			do_adapter_IO();
 			continue;
 		}
 		sch = ioinfo[tpi_info->irq];
drivers/s390/cio/cio.h +3 -6
diff -urN linux-2.5.67/drivers/s390/cio/cio.h linux-2.5.67-s390/drivers/s390/cio/cio.h
@@ -98,8 +98,6 @@
 
 	__u8 vpm;		/* verified path mask */
 	__u8 lpm;		/* logical path mask */
-	// TODO: intparm for second start i/o
-	unsigned long u_intparm;	/* user interruption parameter */
 	struct schib schib;	/* subchannel information block */
 	struct orb orb;		/* operation request block */
 	struct ccw1 sense_ccw;	/* static ccw for sense command */
@@ -116,11 +114,10 @@
 extern int cio_enable_subchannel (struct subchannel *, unsigned int);
 extern int cio_disable_subchannel (struct subchannel *);
 extern int cio_cancel (struct subchannel *);
-extern int cio_clear (struct subchannel *, unsigned long);
-extern int cio_do_io (struct subchannel *, struct ccw1 *, unsigned long, __u8);
+extern int cio_clear (struct subchannel *);
 extern int cio_resume (struct subchannel *);
-extern int cio_halt (struct subchannel *, unsigned long);
-extern int cio_start (struct subchannel *, struct ccw1 *, unsigned long, __u8);
+extern int cio_halt (struct subchannel *);
+extern int cio_start (struct subchannel *, struct ccw1 *, unsigned int, __u8);
 extern int cio_cancel (struct subchannel *);
 extern int cio_set_options (struct subchannel *, int);
 extern int cio_get_options (struct subchannel *);
drivers/s390/cio/css.c +4 -4
diff -urN linux-2.5.67/drivers/s390/cio/css.c linux-2.5.67-s390/drivers/s390/cio/css.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/css.c
  *  driver for channel subsystem
- *   $Revision: 1.40 $
+ *   $Revision: 1.43 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -41,7 +41,7 @@
 		/* There already is a struct subchannel for this irq. */
 		return -EBUSY;
 
-	sch = kmalloc (sizeof (*sch), GFP_DMA);
+	sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA);
 	if (sch == NULL)
 		return -ENOMEM;
 	ret = cio_validate_subchannel (sch, irq);
@@ -161,7 +161,7 @@
 
 	sch = ioinfo[irq];
 	if (sch == NULL) {
-		schedule_work(&work);
+		queue_work(ccw_device_work, &work);
 		return;
 	}
 	if (!sch->dev.driver_data)
@@ -172,7 +172,7 @@
 	ccode = stsch(irq, &sch->schib);
 	if (!ccode)
 		if (devno != sch->schib.pmcw.dev)
-			schedule_work(&work);
+			queue_work(ccw_device_work, &work);
 }
 
 /*
drivers/s390/cio/css.h +1 -0
diff -urN linux-2.5.67/drivers/s390/cio/css.h linux-2.5.67-s390/drivers/s390/cio/css.h
@@ -79,6 +79,7 @@
 		unsigned int esid:1;        /* Ext. SenseID supported by HW */
 		unsigned int dosense:1;	    /* delayed SENSE required */
 	} __attribute__((packed)) flags;
+	unsigned long intparm;	/* user interruption parameter */
 	struct qdio_irq *qdio_data;
 	struct irb irb;		/* device status */
 	struct senseid senseid;	/* SenseID info */
drivers/s390/cio/device.c +66 -4

131 lines not on this page · raw message

drivers/s390/cio/device.h +5 -5
diff -urN linux-2.5.67/drivers/s390/cio/device.h linux-2.5.67-s390/drivers/s390/cio/device.h
@@ -14,13 +14,11 @@
 	DEV_STATE_W4SENSE,
 	DEV_STATE_DISBAND_PGID,
 	DEV_STATE_BOXED,
-	/* special states for qdio */
-	DEV_STATE_QDIO_INIT,
-	DEV_STATE_QDIO_ACTIVE,
-	DEV_STATE_QDIO_CLEANUP,
 	/* states to wait for i/o completion before doing something */
 	DEV_STATE_ONLINE_VERIFY,
 	DEV_STATE_W4SENSE_VERIFY,
+	DEV_STATE_CLEAR_VERIFY,
+	DEV_STATE_TIMEOUT_KILL,
 	/* last element! */
 	NR_DEV_STATES
 };
@@ -63,7 +61,9 @@
 		cdev->private->state == DEV_STATE_BOXED);
 }
 
-void io_subchannel_register(void *data);
+extern struct workqueue_struct *ccw_device_work;
+
+void io_subchannel_recog_done(struct ccw_device *cdev);
 
 int ccw_device_recognition(struct ccw_device *);
 int ccw_device_online(struct ccw_device *);
drivers/s390/cio/device_fsm.c +88 -112

324 lines not on this page · raw message

drivers/s390/cio/device_id.c +6 -4
diff -urN linux-2.5.67/drivers/s390/cio/device_id.c linux-2.5.67-s390/drivers/s390/cio/device_id.c
@@ -198,11 +198,13 @@
 			/* 0x00E2C9C4 == ebcdic "SID" */
 			ret = cio_start (sch, cdev->private->iccws,
 					 0x00E2C9C4, cdev->private->imask);
-			/* ret is 0, -EBUSY or -ENODEV */
-			if (ret != -EBUSY)
+			/* ret is 0, -EBUSY, -EACCES or -ENODEV */
+			if (ret == -EBUSY) {
+				udelay(100);
+				continue;
+			}
+			if (ret != -EACCES)
 				return ret;
-			udelay(100);
-			continue;
 		}
 		cdev->private->imask >>= 1;
 		cdev->private->iretry = 5;
drivers/s390/cio/device_ops.c +66 -32

198 lines not on this page · raw message

drivers/s390/cio/device_pgid.c +19 -8
diff -urN linux-2.5.67/drivers/s390/cio/device_pgid.c linux-2.5.67-s390/drivers/s390/cio/device_pgid.c
@@ -51,14 +51,23 @@
 			/* 0xe2d5c9c4 == ebcdic "SNID" */
 			ret = cio_start (sch, cdev->private->iccws, 
 					 0xE2D5C9C4, cdev->private->imask);
-			/* ret is 0, -EBUSY or -ENODEV */
-			if (ret != -EBUSY)
+			/* ret is 0, -EBUSY, -EACCES or -ENODEV */
+			if (ret == -EBUSY) {
+				CIO_MSG_EVENT(2, 
+					      "SNID - device %04X, start_io() "
+					      "reports rc : %d, retrying ...\n",
+					      sch->schib.pmcw.dev, ret);
+				udelay(100);
+				continue;
+			}
+			if (ret != -EACCES)
 				return ret;
-			CIO_MSG_EVENT(2, "SNID - device %04X, start_io() "
-				      "reports rc : %d, retrying ...\n",
-				      sch->schib.pmcw.dev, ret);
-			udelay(100);
-			continue;
+			CIO_MSG_EVENT(2, "SNID - Device %04X on Subchannel "
+				      "%04X, lpm %02X, became 'not "
+				      "operational'\n",
+				      sch->schib.pmcw.dev, sch->irq,
+				      cdev->private->imask);
+
 		}
 		cdev->private->imask >>= 1;
 		cdev->private->iretry = 5;
@@ -231,7 +240,9 @@
 		/* 0xE2D7C9C4 == ebcdic "SPID" */
 		ret = cio_start (sch, cdev->private->iccws,
 				 0xE2D7C9C4, cdev->private->imask);
-		/* ret is 0, -EBUSY or -ENODEV */
+		/* ret is 0, -EBUSY, -EACCES or -ENODEV */
+		if (ret == -EACCES)
+			break;
 		if (ret != -EBUSY)
 			return ret;
 		udelay(100);
drivers/s390/cio/device_status.c +2 -2
diff -urN linux-2.5.67/drivers/s390/cio/device_status.c linux-2.5.67-s390/drivers/s390/cio/device_status.c
@@ -167,7 +167,7 @@
 
 	/* Copy authorization bit. */
 	cdev_irb->esw.esw0.erw.auth = irb->esw.esw0.erw.auth;
-	/* Copy path verification required flag. FIXME: how to verify ?? */
+	/* Copy path verification required flag. */
 	cdev_irb->esw.esw0.erw.pvrf = irb->esw.esw0.erw.pvrf;
 	/* Copy concurrent sense bit. */
 	cdev_irb->esw.esw0.erw.cons = irb->esw.esw0.erw.cons;
@@ -309,7 +309,7 @@
 	sch->sense_ccw.flags = CCW_FLAG_SLI;
 
 	/* 0xe2C5D5E2 == "SENS" in ebcdic */
-	return cio_start (sch, &sch->sense_ccw, 0xE2C5D5E2, 0);
+	return cio_start (sch, &sch->sense_ccw, 0xE2C5D5E2, 0xff);
 }
 
 /*
drivers/s390/cio/qdio.c +348 -287

1,112 lines not on this page · raw message

drivers/s390/cio/qdio.h +15 -95

155 lines not on this page · raw message

drivers/s390/cio/requestirq.c +5 -1
diff -urN linux-2.5.67/drivers/s390/cio/requestirq.c linux-2.5.67-s390/drivers/s390/cio/requestirq.c
@@ -44,7 +44,11 @@
 	/*
 	 * Let's build our path group ID here.
 	 */
-	global_pgid.cpu_addr = *(__u16 *) __LC_CPUADDR;
+#ifdef CONFIG_SMP
+	global_pgid.cpu_addr = hard_smp_processor_id();
+#else
+	global_pgid.cpu_addr = 0;
+#endif
 	global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident;
 	global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine;
 	global_pgid.tod_high = (__u32) (get_clock() >> 32);
drivers/s390/s390mach.c +12 -2
diff -urN linux-2.5.67/drivers/s390/s390mach.c linux-2.5.67-s390/drivers/s390/s390mach.c
@@ -21,7 +21,7 @@
 
 extern void css_process_crw(int);
 extern void chsc_process_crw(void);
-extern void chp_process_crw(int);
+extern void chp_process_crw(int, int);
 
 static void
 s390_handle_damage(char *msg)
@@ -62,7 +62,17 @@
 			break;
 		case CRW_RSC_CPATH:
 			pr_debug("source is channel path %02X\n", crw.rsid);
-			chp_process_crw(crw.rsid);
+			switch (crw.erc) {
+			case CRW_ERC_IPARM: /* Path has come. */
+				chp_process_crw(crw.rsid, 1);
+				break;
+			case CRW_ERC_PERRI: /* Path has gone. */
+				chp_process_crw(crw.rsid, 0);
+				break;
+			default:
+				pr_debug("Don't know how to handle erc=%x\n",
+					 crw.erc);
+			}
 			break;
 		case CRW_RSC_CONFIG:
 			pr_debug("source is configuration-alert facility\n");