Commit 748f7f37 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390 (2/7): common i/o layer.

 - Remove atomic_read hack to test for presence of ccw device directory.
 - Add dummy release function to channel path object and cu3088 group devices.
 - Don't rely on the chaining bit of the channel report word.
 - Don't call schedule while holding a lock in read_dev_chars/read_conf_data.
parent 834bf64a
/* /*
* drivers/s390/cio/ccwgroup.c * drivers/s390/cio/ccwgroup.c
* bus driver for ccwgroup * bus driver for ccwgroup
* $Revision: 1.15 $ * $Revision: 1.17 $
* *
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
...@@ -67,10 +67,7 @@ __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) ...@@ -67,10 +67,7 @@ __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
for (i = 0; i < gdev->count; i++) { for (i = 0; i < gdev->count; i++) {
sprintf(str, "cdev%d", i); sprintf(str, "cdev%d", i);
sysfs_remove_link(&gdev->dev.kobj, str); sysfs_remove_link(&gdev->dev.kobj, str);
/* Hack: Make sure we act on still valid subdirs. */ sysfs_remove_link(&gdev->cdev[i]->dev.kobj, "group_device");
if (atomic_read(&gdev->cdev[i]->dev.kobj.dentry->d_count))
sysfs_remove_link(&gdev->cdev[i]->dev.kobj,
"group_device");
} }
} }
...@@ -187,7 +184,7 @@ ccwgroup_create(struct device *root, ...@@ -187,7 +184,7 @@ ccwgroup_create(struct device *root,
.dev = { .dev = {
.bus = &ccwgroup_bus_type, .bus = &ccwgroup_bus_type,
.parent = root, .parent = root,
.release = &ccwgroup_release, .release = ccwgroup_release,
}, },
}; };
......
/* /*
* drivers/s390/cio/chsc.c * drivers/s390/cio/chsc.c
* S/390 common I/O routines -- channel subsystem call * S/390 common I/O routines -- channel subsystem call
* $Revision: 1.77 $ * $Revision: 1.78 $
* *
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
...@@ -843,6 +843,12 @@ chp_status_write(struct device *dev, const char *buf, size_t count) ...@@ -843,6 +843,12 @@ chp_status_write(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write); static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);
static void
chp_release(struct device *dev)
{
}
/* /*
* Entries for chpids on the system bus. * Entries for chpids on the system bus.
* This replaces /proc/chpids. * This replaces /proc/chpids.
...@@ -863,8 +869,10 @@ new_channel_path(int chpid, int status) ...@@ -863,8 +869,10 @@ new_channel_path(int chpid, int status)
/* fill in status, etc. */ /* fill in status, etc. */
chp->id = chpid; chp->id = chpid;
chp->state = status; chp->state = status;
chp->dev.parent = &css_bus_device; chp->dev = (struct device) {
.parent = &css_bus_device,
.release = chp_release,
};
snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid); snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid);
/* make it known to the system */ /* make it known to the system */
......
...@@ -244,8 +244,7 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb) ...@@ -244,8 +244,7 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
} }
static inline int static inline int
__ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic)
unsigned long flags)
{ {
int ret; int ret;
struct subchannel *sch; struct subchannel *sch;
...@@ -255,7 +254,9 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, ...@@ -255,7 +254,9 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic,
ret = cio_start (sch, ccw, magic, 0); ret = cio_start (sch, ccw, magic, 0);
if ((ret == -EBUSY) || (ret == -EACCES)) { if ((ret == -EBUSY) || (ret == -EACCES)) {
/* Try again later. */ /* Try again later. */
spin_unlock_irq(&sch->lock);
schedule_timeout(1); schedule_timeout(1);
spin_lock_irq(&sch->lock);
continue; continue;
} }
if (ret != 0) if (ret != 0)
...@@ -263,12 +264,12 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, ...@@ -263,12 +264,12 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic,
break; break;
/* Wait for end of request. */ /* Wait for end of request. */
cdev->private->intparm = magic; cdev->private->intparm = magic;
spin_unlock_irqrestore(&sch->lock, flags); spin_unlock_irq(&sch->lock);
wait_event(cdev->private->wait_q, wait_event(cdev->private->wait_q,
(cdev->private->intparm == -EIO) || (cdev->private->intparm == -EIO) ||
(cdev->private->intparm == -EAGAIN) || (cdev->private->intparm == -EAGAIN) ||
(cdev->private->intparm == 0)); (cdev->private->intparm == 0));
spin_lock_irqsave(&sch->lock, flags); spin_lock_irq(&sch->lock);
/* Check at least for channel end / device end */ /* Check at least for channel end / device end */
if (cdev->private->intparm == -EIO) { if (cdev->private->intparm == -EIO) {
/* Non-retryable error. */ /* Non-retryable error. */
...@@ -279,7 +280,9 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, ...@@ -279,7 +280,9 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic,
/* Success. */ /* Success. */
break; break;
/* Try again later. */ /* Try again later. */
spin_unlock_irq(&sch->lock);
schedule_timeout(1); schedule_timeout(1);
spin_lock_irq(&sch->lock);
} while (1); } while (1);
return ret; return ret;
...@@ -300,7 +303,6 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length) ...@@ -300,7 +303,6 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length)
{ {
void (*handler)(struct ccw_device *, unsigned long, struct irb *); void (*handler)(struct ccw_device *, unsigned long, struct irb *);
char dbf_txt[15]; char dbf_txt[15];
unsigned long flags;
struct subchannel *sch; struct subchannel *sch;
int ret; int ret;
struct ccw1 *rdc_ccw; struct ccw1 *rdc_ccw;
...@@ -327,7 +329,7 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length) ...@@ -327,7 +329,7 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length)
return ret; return ret;
} }
spin_lock_irqsave(&sch->lock, flags); spin_lock_irq(&sch->lock);
/* Save interrupt handler. */ /* Save interrupt handler. */
handler = cdev->handler; handler = cdev->handler;
/* Temporarily install own handler. */ /* Temporarily install own handler. */
...@@ -338,11 +340,11 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length) ...@@ -338,11 +340,11 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length)
ret = -EBUSY; ret = -EBUSY;
else else
/* 0x00D9C4C3 == ebcdic "RDC" */ /* 0x00D9C4C3 == ebcdic "RDC" */
ret = __ccw_device_retry_loop(cdev, rdc_ccw, 0x00D9C4C3, flags); ret = __ccw_device_retry_loop(cdev, rdc_ccw, 0x00D9C4C3);
/* Restore interrupt handler. */ /* Restore interrupt handler. */
cdev->handler = handler; cdev->handler = handler;
spin_unlock_irqrestore(&sch->lock, flags); spin_unlock_irq(&sch->lock);
clear_normalized_cda (rdc_ccw); clear_normalized_cda (rdc_ccw);
kfree(rdc_ccw); kfree(rdc_ccw);
...@@ -360,7 +362,6 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length) ...@@ -360,7 +362,6 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length)
char dbf_txt[15]; char dbf_txt[15];
struct subchannel *sch; struct subchannel *sch;
struct ciw *ciw; struct ciw *ciw;
unsigned long flags;
char *rcd_buf; char *rcd_buf;
int ret; int ret;
struct ccw1 *rcd_ccw; struct ccw1 *rcd_ccw;
...@@ -396,7 +397,7 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length) ...@@ -396,7 +397,7 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length)
rcd_ccw->count = ciw->count; rcd_ccw->count = ciw->count;
rcd_ccw->flags = CCW_FLAG_SLI; rcd_ccw->flags = CCW_FLAG_SLI;
spin_lock_irqsave(&sch->lock, flags); spin_lock_irq(&sch->lock);
/* Save interrupt handler. */ /* Save interrupt handler. */
handler = cdev->handler; handler = cdev->handler;
/* Temporarily install own handler. */ /* Temporarily install own handler. */
...@@ -407,11 +408,11 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length) ...@@ -407,11 +408,11 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length)
ret = -EBUSY; ret = -EBUSY;
else else
/* 0x00D9C3C4 == ebcdic "RCD" */ /* 0x00D9C3C4 == ebcdic "RCD" */
ret = __ccw_device_retry_loop(cdev, rcd_ccw, 0x00D9C3C4, flags); ret = __ccw_device_retry_loop(cdev, rcd_ccw, 0x00D9C3C4);
/* Restore interrupt handler. */ /* Restore interrupt handler. */
cdev->handler = handler; cdev->handler = handler;
spin_unlock_irqrestore(&sch->lock, flags); spin_unlock_irq(&sch->lock);
/* /*
* on success we update the user input parms * on success we update the user input parms
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/timex.h>
#include <asm/debug.h> #include <asm/debug.h>
#include <asm/qdio.h> #include <asm/qdio.h>
...@@ -55,7 +56,7 @@ ...@@ -55,7 +56,7 @@
#include "ioasm.h" #include "ioasm.h"
#include "chsc.h" #include "chsc.h"
#define VERSION_QDIO_C "$Revision: 1.61 $" #define VERSION_QDIO_C "$Revision: 1.62 $"
/****************** MODULE PARAMETER VARIABLES ********************/ /****************** MODULE PARAMETER VARIABLES ********************/
MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>"); MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
...@@ -112,10 +113,7 @@ qdio_min(int a,int b) ...@@ -112,10 +113,7 @@ qdio_min(int a,int b)
static inline volatile __u64 static inline volatile __u64
qdio_get_micros(void) qdio_get_micros(void)
{ {
__u64 time; return (get_clock() >> 12); /* time>>12 is microseconds */
asm volatile ("STCK %0" : "=m" (time));
return time>>12; /* time>>12 is microseconds*/
} }
/* /*
......
/* /*
* $Id: cu3088.c,v 1.30 2003/08/28 11:14:11 cohuck Exp $ * $Id: cu3088.c,v 1.31 2003/09/29 15:24:27 cohuck Exp $
* *
* CTC / LCS ccw_device driver * CTC / LCS ccw_device driver
* *
...@@ -55,8 +55,14 @@ static struct ccw_device_id cu3088_ids[] = { ...@@ -55,8 +55,14 @@ static struct ccw_device_id cu3088_ids[] = {
static struct ccw_driver cu3088_driver; static struct ccw_driver cu3088_driver;
static void
cu3088_root_dev_release (struct device *dev)
{
}
struct device cu3088_root_dev = { struct device cu3088_root_dev = {
.bus_id = "cu3088", .bus_id = "cu3088",
.release = cu3088_root_dev_release,
}; };
static ssize_t static ssize_t
......
...@@ -44,7 +44,7 @@ s390_collect_crw_info(void) ...@@ -44,7 +44,7 @@ s390_collect_crw_info(void)
struct crw crw; struct crw crw;
int ccode; int ccode;
do { while (1) {
ccode = stcrw(&crw); ccode = stcrw(&crw);
if (ccode != 0) if (ccode != 0)
break; break;
...@@ -85,7 +85,7 @@ s390_collect_crw_info(void) ...@@ -85,7 +85,7 @@ s390_collect_crw_info(void)
pr_debug("unknown source\n"); pr_debug("unknown source\n");
break; break;
} }
} while (crw.chn); }
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment