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
* bus driver for ccwgroup
* $Revision: 1.15 $
* $Revision: 1.17 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
......@@ -67,10 +67,7 @@ __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
for (i = 0; i < gdev->count; i++) {
sprintf(str, "cdev%d", i);
sysfs_remove_link(&gdev->dev.kobj, str);
/* Hack: Make sure we act on still valid subdirs. */
if (atomic_read(&gdev->cdev[i]->dev.kobj.dentry->d_count))
sysfs_remove_link(&gdev->cdev[i]->dev.kobj,
"group_device");
sysfs_remove_link(&gdev->cdev[i]->dev.kobj, "group_device");
}
}
......@@ -187,7 +184,7 @@ ccwgroup_create(struct device *root,
.dev = {
.bus = &ccwgroup_bus_type,
.parent = root,
.release = &ccwgroup_release,
.release = ccwgroup_release,
},
};
......
/*
* drivers/s390/cio/chsc.c
* S/390 common I/O routines -- channel subsystem call
* $Revision: 1.77 $
* $Revision: 1.78 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
......@@ -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 void
chp_release(struct device *dev)
{
}
/*
* Entries for chpids on the system bus.
* This replaces /proc/chpids.
......@@ -863,8 +869,10 @@ new_channel_path(int chpid, int status)
/* fill in status, etc. */
chp->id = chpid;
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);
/* make it known to the system */
......
......@@ -244,8 +244,7 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
}
static inline int
__ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic,
unsigned long flags)
__ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic)
{
int ret;
struct subchannel *sch;
......@@ -255,7 +254,9 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic,
ret = cio_start (sch, ccw, magic, 0);
if ((ret == -EBUSY) || (ret == -EACCES)) {
/* Try again later. */
spin_unlock_irq(&sch->lock);
schedule_timeout(1);
spin_lock_irq(&sch->lock);
continue;
}
if (ret != 0)
......@@ -263,12 +264,12 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic,
break;
/* Wait for end of request. */
cdev->private->intparm = magic;
spin_unlock_irqrestore(&sch->lock, flags);
spin_unlock_irq(&sch->lock);
wait_event(cdev->private->wait_q,
(cdev->private->intparm == -EIO) ||
(cdev->private->intparm == -EAGAIN) ||
(cdev->private->intparm == 0));
spin_lock_irqsave(&sch->lock, flags);
spin_lock_irq(&sch->lock);
/* Check at least for channel end / device end */
if (cdev->private->intparm == -EIO) {
/* Non-retryable error. */
......@@ -279,7 +280,9 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic,
/* Success. */
break;
/* Try again later. */
spin_unlock_irq(&sch->lock);
schedule_timeout(1);
spin_lock_irq(&sch->lock);
} while (1);
return ret;
......@@ -300,7 +303,6 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length)
{
void (*handler)(struct ccw_device *, unsigned long, struct irb *);
char dbf_txt[15];
unsigned long flags;
struct subchannel *sch;
int ret;
struct ccw1 *rdc_ccw;
......@@ -327,7 +329,7 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length)
return ret;
}
spin_lock_irqsave(&sch->lock, flags);
spin_lock_irq(&sch->lock);
/* Save interrupt handler. */
handler = cdev->handler;
/* Temporarily install own handler. */
......@@ -338,11 +340,11 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length)
ret = -EBUSY;
else
/* 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. */
cdev->handler = handler;
spin_unlock_irqrestore(&sch->lock, flags);
spin_unlock_irq(&sch->lock);
clear_normalized_cda (rdc_ccw);
kfree(rdc_ccw);
......@@ -360,7 +362,6 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length)
char dbf_txt[15];
struct subchannel *sch;
struct ciw *ciw;
unsigned long flags;
char *rcd_buf;
int ret;
struct ccw1 *rcd_ccw;
......@@ -396,7 +397,7 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length)
rcd_ccw->count = ciw->count;
rcd_ccw->flags = CCW_FLAG_SLI;
spin_lock_irqsave(&sch->lock, flags);
spin_lock_irq(&sch->lock);
/* Save interrupt handler. */
handler = cdev->handler;
/* Temporarily install own handler. */
......@@ -407,11 +408,11 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length)
ret = -EBUSY;
else
/* 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. */
cdev->handler = handler;
spin_unlock_irqrestore(&sch->lock, flags);
spin_unlock_irq(&sch->lock);
/*
* on success we update the user input parms
......
......@@ -43,6 +43,7 @@
#include <asm/io.h>
#include <asm/atomic.h>
#include <asm/semaphore.h>
#include <asm/timex.h>
#include <asm/debug.h>
#include <asm/qdio.h>
......@@ -55,7 +56,7 @@
#include "ioasm.h"
#include "chsc.h"
#define VERSION_QDIO_C "$Revision: 1.61 $"
#define VERSION_QDIO_C "$Revision: 1.62 $"
/****************** MODULE PARAMETER VARIABLES ********************/
MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
......@@ -112,10 +113,7 @@ qdio_min(int a,int b)
static inline volatile __u64
qdio_get_micros(void)
{
__u64 time;
asm volatile ("STCK %0" : "=m" (time));
return time>>12; /* time>>12 is microseconds*/
return (get_clock() >> 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
*
......@@ -55,8 +55,14 @@ static struct ccw_device_id cu3088_ids[] = {
static struct ccw_driver cu3088_driver;
static void
cu3088_root_dev_release (struct device *dev)
{
}
struct device cu3088_root_dev = {
.bus_id = "cu3088",
.release = cu3088_root_dev_release,
};
static ssize_t
......
......@@ -44,7 +44,7 @@ s390_collect_crw_info(void)
struct crw crw;
int ccode;
do {
while (1) {
ccode = stcrw(&crw);
if (ccode != 0)
break;
......@@ -85,7 +85,7 @@ s390_collect_crw_info(void)
pr_debug("unknown source\n");
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