summaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r--drivers/s390/cio/device.c5
-rw-r--r--drivers/s390/cio/qdio.h25
-rw-r--r--drivers/s390/cio/qdio_main.c62
3 files changed, 50 insertions, 42 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index c9bc9a6bd..ee4338158 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1353,6 +1353,7 @@ void ccw_device_set_notoper(struct ccw_device *cdev)
enum io_sch_action {
IO_SCH_UNREG,
IO_SCH_ORPH_UNREG,
+ IO_SCH_UNREG_CDEV,
IO_SCH_ATTACH,
IO_SCH_UNREG_ATTACH,
IO_SCH_ORPH_ATTACH,
@@ -1385,7 +1386,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
}
if ((sch->schib.pmcw.pam & sch->opm) == 0) {
if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK)
- return IO_SCH_UNREG;
+ return IO_SCH_UNREG_CDEV;
return IO_SCH_DISC;
}
if (device_is_disconnected(cdev))
@@ -1447,6 +1448,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
case IO_SCH_ORPH_ATTACH:
ccw_device_set_disconnected(cdev);
break;
+ case IO_SCH_UNREG_CDEV:
case IO_SCH_UNREG_ATTACH:
case IO_SCH_UNREG:
if (!cdev)
@@ -1480,6 +1482,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
if (rc)
goto out;
break;
+ case IO_SCH_UNREG_CDEV:
case IO_SCH_UNREG_ATTACH:
spin_lock_irqsave(sch->lock, flags);
if (cdev->private->flags.resuming) {
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index ed60b8d4e..f98dc3a8e 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -88,15 +88,15 @@ enum qdio_irq_states {
static inline int do_sqbs(u64 token, unsigned char state, int queue,
int *start, int *count)
{
- register unsigned long _ccq asm ("0") = *count;
- register unsigned long _token asm ("1") = token;
unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
+ unsigned long _ccq = *count;
asm volatile(
- " .insn rsy,0xeb000000008A,%1,0,0(%2)"
- : "+d" (_ccq), "+d" (_queuestart)
- : "d" ((unsigned long)state), "d" (_token)
- : "memory", "cc");
+ " lgr 1,%[token]\n"
+ " .insn rsy,0xeb000000008a,%[qs],%[ccq],0(%[state])"
+ : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart)
+ : [state] "a" ((unsigned long)state), [token] "d" (token)
+ : "memory", "cc", "1");
*count = _ccq & 0xff;
*start = _queuestart & 0xff;
@@ -106,16 +106,17 @@ static inline int do_sqbs(u64 token, unsigned char state, int queue,
static inline int do_eqbs(u64 token, unsigned char *state, int queue,
int *start, int *count, int ack)
{
- register unsigned long _ccq asm ("0") = *count;
- register unsigned long _token asm ("1") = token;
unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
unsigned long _state = (unsigned long)ack << 63;
+ unsigned long _ccq = *count;
asm volatile(
- " .insn rrf,0xB99c0000,%1,%2,0,0"
- : "+d" (_ccq), "+d" (_queuestart), "+d" (_state)
- : "d" (_token)
- : "memory", "cc");
+ " lgr 1,%[token]\n"
+ " .insn rrf,0xb99c0000,%[qs],%[state],%[ccq],0"
+ : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart),
+ [state] "+&d" (_state)
+ : [token] "d" (token)
+ : "memory", "cc", "1");
*count = _ccq & 0xff;
*start = _queuestart & 0xff;
*state = _state & 0xff;
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 4b7cc8d42..6100cf4df 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -31,38 +31,41 @@ MODULE_DESCRIPTION("QDIO base support");
MODULE_LICENSE("GPL");
static inline int do_siga_sync(unsigned long schid,
- unsigned int out_mask, unsigned int in_mask,
+ unsigned long out_mask, unsigned long in_mask,
unsigned int fc)
{
- register unsigned long __fc asm ("0") = fc;
- register unsigned long __schid asm ("1") = schid;
- register unsigned long out asm ("2") = out_mask;
- register unsigned long in asm ("3") = in_mask;
int cc;
asm volatile(
+ " lgr 0,%[fc]\n"
+ " lgr 1,%[schid]\n"
+ " lgr 2,%[out]\n"
+ " lgr 3,%[in]\n"
" siga 0\n"
- " ipm %0\n"
- " srl %0,28\n"
- : "=d" (cc)
- : "d" (__fc), "d" (__schid), "d" (out), "d" (in) : "cc");
+ " ipm %[cc]\n"
+ " srl %[cc],28\n"
+ : [cc] "=&d" (cc)
+ : [fc] "d" (fc), [schid] "d" (schid),
+ [out] "d" (out_mask), [in] "d" (in_mask)
+ : "cc", "0", "1", "2", "3");
return cc;
}
-static inline int do_siga_input(unsigned long schid, unsigned int mask,
- unsigned int fc)
+static inline int do_siga_input(unsigned long schid, unsigned long mask,
+ unsigned long fc)
{
- register unsigned long __fc asm ("0") = fc;
- register unsigned long __schid asm ("1") = schid;
- register unsigned long __mask asm ("2") = mask;
int cc;
asm volatile(
+ " lgr 0,%[fc]\n"
+ " lgr 1,%[schid]\n"
+ " lgr 2,%[mask]\n"
" siga 0\n"
- " ipm %0\n"
- " srl %0,28\n"
- : "=d" (cc)
- : "d" (__fc), "d" (__schid), "d" (__mask) : "cc");
+ " ipm %[cc]\n"
+ " srl %[cc],28\n"
+ : [cc] "=&d" (cc)
+ : [fc] "d" (fc), [schid] "d" (schid), [mask] "d" (mask)
+ : "cc", "0", "1", "2");
return cc;
}
@@ -78,23 +81,24 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask,
* Note: For IQDC unicast queues only the highest priority queue is processed.
*/
static inline int do_siga_output(unsigned long schid, unsigned long mask,
- unsigned int *bb, unsigned int fc,
+ unsigned int *bb, unsigned long fc,
unsigned long aob)
{
- register unsigned long __fc asm("0") = fc;
- register unsigned long __schid asm("1") = schid;
- register unsigned long __mask asm("2") = mask;
- register unsigned long __aob asm("3") = aob;
int cc;
asm volatile(
+ " lgr 0,%[fc]\n"
+ " lgr 1,%[schid]\n"
+ " lgr 2,%[mask]\n"
+ " lgr 3,%[aob]\n"
" siga 0\n"
- " ipm %0\n"
- " srl %0,28\n"
- : "=d" (cc), "+d" (__fc), "+d" (__aob)
- : "d" (__schid), "d" (__mask)
- : "cc");
- *bb = __fc >> 31;
+ " lgr %[fc],0\n"
+ " ipm %[cc]\n"
+ " srl %[cc],28\n"
+ : [cc] "=&d" (cc), [fc] "+&d" (fc)
+ : [schid] "d" (schid), [mask] "d" (mask), [aob] "d" (aob)
+ : "cc", "0", "1", "2", "3");
+ *bb = fc >> 31;
return cc;
}