aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 15:41:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 15:41:17 -0400
commite60b9a0346ee08af4715ee5b2d82f705fbe6e309 (patch)
tree886e1be2a283806e1dc940b7379a5a6e4683a97b /drivers/s390/cio
parent9daeaa370526df1c19eba4780247bb7155541e38 (diff)
parenta7475afd530e6bf81c9025b0134dd1c7c6f1a219 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "Just a random collection of bug-fixes and cleanups, nothing new in this merge request." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (46 commits) s390/ap: Fix wrong or missing comments s390/ap: move receive callback to message struct s390/dasd: re-prioritize partition detection message s390/qeth: reshuffle initialization s390/qeth: cleanup drv attr usage s390/claw: cleanup drv attr usage s390/lcs: cleanup drv attr usage s390/ctc: cleanup drv attr usage s390/ccwgroup: remove ccwgroup_create_from_string s390/qeth: stop using struct ccwgroup driver for discipline callbacks s390/qeth: switch to ccwgroup_create_dev s390/claw: switch to ccwgroup_create_dev s390/lcs: switch to ccwgroup_create_dev s390/ctcm: switch to ccwgroup_create_dev s390/ccwgroup: exploit ccwdev_by_dev_id s390/ccwgroup: introduce ccwgroup_create_dev s390: fix race on TIF_MCCK_PENDING s390/barrier: make use of fast-bcr facility s390/barrier: cleanup barrier functions s390/claw: remove "eieio" calls ...
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r--drivers/s390/cio/ccwgroup.c112
-rw-r--r--drivers/s390/cio/cio.c73
-rw-r--r--drivers/s390/cio/device.c13
-rw-r--r--drivers/s390/cio/device.h1
-rw-r--r--drivers/s390/cio/qdio_main.c47
5 files changed, 99 insertions, 147 deletions
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 5f1dc6fb570..731470e6849 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * bus driver for ccwgroup 2 * bus driver for ccwgroup
3 * 3 *
4 * Copyright IBM Corp. 2002, 2009 4 * Copyright IBM Corp. 2002, 2012
5 * 5 *
6 * Author(s): Arnd Bergmann (arndb@de.ibm.com) 6 * Author(s): Arnd Bergmann (arndb@de.ibm.com)
7 * Cornelia Huck (cornelia.huck@de.ibm.com) 7 * Cornelia Huck (cornelia.huck@de.ibm.com)
@@ -15,10 +15,13 @@
15#include <linux/ctype.h> 15#include <linux/ctype.h>
16#include <linux/dcache.h> 16#include <linux/dcache.h>
17 17
18#include <asm/cio.h>
18#include <asm/ccwdev.h> 19#include <asm/ccwdev.h>
19#include <asm/ccwgroup.h> 20#include <asm/ccwgroup.h>
20 21
21#define CCW_BUS_ID_SIZE 20 22#include "device.h"
23
24#define CCW_BUS_ID_SIZE 10
22 25
23/* In Linux 2.4, we had a channel device layer called "chandev" 26/* In Linux 2.4, we had a channel device layer called "chandev"
24 * that did all sorts of obscure stuff for networking devices. 27 * that did all sorts of obscure stuff for networking devices.
@@ -27,19 +30,6 @@
27 * to devices that use multiple subchannels. 30 * to devices that use multiple subchannels.
28 */ 31 */
29 32
30/* a device matches a driver if all its slave devices match the same
31 * entry of the driver */
32static int ccwgroup_bus_match(struct device *dev, struct device_driver * drv)
33{
34 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
35 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(drv);
36
37 if (gdev->creator_id == gdrv->driver_id)
38 return 1;
39
40 return 0;
41}
42
43static struct bus_type ccwgroup_bus_type; 33static struct bus_type ccwgroup_bus_type;
44 34
45static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) 35static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
@@ -254,9 +244,10 @@ static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
254 return 0; 244 return 0;
255} 245}
256 246
257static int __get_next_bus_id(const char **buf, char *bus_id) 247static int __get_next_id(const char **buf, struct ccw_dev_id *id)
258{ 248{
259 int rc, len; 249 unsigned int cssid, ssid, devno;
250 int ret = 0, len;
260 char *start, *end; 251 char *start, *end;
261 252
262 start = (char *)*buf; 253 start = (char *)*buf;
@@ -271,49 +262,40 @@ static int __get_next_bus_id(const char **buf, char *bus_id)
271 len = end - start + 1; 262 len = end - start + 1;
272 end++; 263 end++;
273 } 264 }
274 if (len < CCW_BUS_ID_SIZE) { 265 if (len <= CCW_BUS_ID_SIZE) {
275 strlcpy(bus_id, start, len); 266 if (sscanf(start, "%2x.%1x.%04x", &cssid, &ssid, &devno) != 3)
276 rc = 0; 267 ret = -EINVAL;
277 } else 268 } else
278 rc = -EINVAL; 269 ret = -EINVAL;
279 *buf = end;
280 return rc;
281}
282
283static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE])
284{
285 int cssid, ssid, devno;
286 270
287 /* Must be of form %x.%x.%04x */ 271 if (!ret) {
288 if (sscanf(bus_id, "%x.%1x.%04x", &cssid, &ssid, &devno) != 3) 272 id->ssid = ssid;
289 return 0; 273 id->devno = devno;
290 return 1; 274 }
275 *buf = end;
276 return ret;
291} 277}
292 278
293/** 279/**
294 * ccwgroup_create_from_string() - create and register a ccw group device 280 * ccwgroup_create_dev() - create and register a ccw group device
295 * @root: parent device for the new device 281 * @parent: parent device for the new device
296 * @creator_id: identifier of creating driver 282 * @gdrv: driver for the new group device
297 * @cdrv: ccw driver of slave devices
298 * @num_devices: number of slave devices 283 * @num_devices: number of slave devices
299 * @buf: buffer containing comma separated bus ids of slave devices 284 * @buf: buffer containing comma separated bus ids of slave devices
300 * 285 *
301 * Create and register a new ccw group device as a child of @root. Slave 286 * Create and register a new ccw group device as a child of @parent. Slave
302 * devices are obtained from the list of bus ids given in @buf and must all 287 * devices are obtained from the list of bus ids given in @buf.
303 * belong to @cdrv.
304 * Returns: 288 * Returns:
305 * %0 on success and an error code on failure. 289 * %0 on success and an error code on failure.
306 * Context: 290 * Context:
307 * non-atomic 291 * non-atomic
308 */ 292 */
309int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, 293int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv,
310 struct ccw_driver *cdrv, int num_devices, 294 int num_devices, const char *buf)
311 const char *buf)
312{ 295{
313 struct ccwgroup_device *gdev; 296 struct ccwgroup_device *gdev;
297 struct ccw_dev_id dev_id;
314 int rc, i; 298 int rc, i;
315 char tmp_bus_id[CCW_BUS_ID_SIZE];
316 const char *curr_buf;
317 299
318 gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]), 300 gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]),
319 GFP_KERNEL); 301 GFP_KERNEL);
@@ -323,29 +305,24 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
323 atomic_set(&gdev->onoff, 0); 305 atomic_set(&gdev->onoff, 0);
324 mutex_init(&gdev->reg_mutex); 306 mutex_init(&gdev->reg_mutex);
325 mutex_lock(&gdev->reg_mutex); 307 mutex_lock(&gdev->reg_mutex);
326 gdev->creator_id = creator_id;
327 gdev->count = num_devices; 308 gdev->count = num_devices;
328 gdev->dev.bus = &ccwgroup_bus_type; 309 gdev->dev.bus = &ccwgroup_bus_type;
329 gdev->dev.parent = root; 310 gdev->dev.parent = parent;
330 gdev->dev.release = ccwgroup_release; 311 gdev->dev.release = ccwgroup_release;
331 device_initialize(&gdev->dev); 312 device_initialize(&gdev->dev);
332 313
333 curr_buf = buf; 314 for (i = 0; i < num_devices && buf; i++) {
334 for (i = 0; i < num_devices && curr_buf; i++) { 315 rc = __get_next_id(&buf, &dev_id);
335 rc = __get_next_bus_id(&curr_buf, tmp_bus_id);
336 if (rc != 0) 316 if (rc != 0)
337 goto error; 317 goto error;
338 if (!__is_valid_bus_id(tmp_bus_id)) { 318 gdev->cdev[i] = get_ccwdev_by_dev_id(&dev_id);
339 rc = -EINVAL;
340 goto error;
341 }
342 gdev->cdev[i] = get_ccwdev_by_busid(cdrv, tmp_bus_id);
343 /* 319 /*
344 * All devices have to be of the same type in 320 * All devices have to be of the same type in
345 * order to be grouped. 321 * order to be grouped.
346 */ 322 */
347 if (!gdev->cdev[i] 323 if (!gdev->cdev[i] || !gdev->cdev[i]->drv ||
348 || gdev->cdev[i]->id.driver_info != 324 gdev->cdev[i]->drv != gdev->cdev[0]->drv ||
325 gdev->cdev[i]->id.driver_info !=
349 gdev->cdev[0]->id.driver_info) { 326 gdev->cdev[0]->id.driver_info) {
350 rc = -EINVAL; 327 rc = -EINVAL;
351 goto error; 328 goto error;
@@ -361,18 +338,25 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
361 spin_unlock_irq(gdev->cdev[i]->ccwlock); 338 spin_unlock_irq(gdev->cdev[i]->ccwlock);
362 } 339 }
363 /* Check for sufficient number of bus ids. */ 340 /* Check for sufficient number of bus ids. */
364 if (i < num_devices && !curr_buf) { 341 if (i < num_devices) {
365 rc = -EINVAL; 342 rc = -EINVAL;
366 goto error; 343 goto error;
367 } 344 }
368 /* Check for trailing stuff. */ 345 /* Check for trailing stuff. */
369 if (i == num_devices && strlen(curr_buf) > 0) { 346 if (i == num_devices && strlen(buf) > 0) {
370 rc = -EINVAL; 347 rc = -EINVAL;
371 goto error; 348 goto error;
372 } 349 }
373 350
374 dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); 351 dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
375 gdev->dev.groups = ccwgroup_attr_groups; 352 gdev->dev.groups = ccwgroup_attr_groups;
353
354 if (gdrv) {
355 gdev->dev.driver = &gdrv->driver;
356 rc = gdrv->setup ? gdrv->setup(gdev) : 0;
357 if (rc)
358 goto error;
359 }
376 rc = device_add(&gdev->dev); 360 rc = device_add(&gdev->dev);
377 if (rc) 361 if (rc)
378 goto error; 362 goto error;
@@ -397,7 +381,7 @@ error:
397 put_device(&gdev->dev); 381 put_device(&gdev->dev);
398 return rc; 382 return rc;
399} 383}
400EXPORT_SYMBOL(ccwgroup_create_from_string); 384EXPORT_SYMBOL(ccwgroup_create_dev);
401 385
402static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, 386static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
403 void *data) 387 void *data)
@@ -440,14 +424,6 @@ module_exit(cleanup_ccwgroup);
440 424
441/************************** driver stuff ******************************/ 425/************************** driver stuff ******************************/
442 426
443static int ccwgroup_probe(struct device *dev)
444{
445 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
446 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
447
448 return gdrv->probe ? gdrv->probe(gdev) : -ENODEV;
449}
450
451static int ccwgroup_remove(struct device *dev) 427static int ccwgroup_remove(struct device *dev)
452{ 428{
453 struct ccwgroup_device *gdev = to_ccwgroupdev(dev); 429 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
@@ -542,8 +518,6 @@ static const struct dev_pm_ops ccwgroup_pm_ops = {
542 518
543static struct bus_type ccwgroup_bus_type = { 519static struct bus_type ccwgroup_bus_type = {
544 .name = "ccwgroup", 520 .name = "ccwgroup",
545 .match = ccwgroup_bus_match,
546 .probe = ccwgroup_probe,
547 .remove = ccwgroup_remove, 521 .remove = ccwgroup_remove,
548 .shutdown = ccwgroup_shutdown, 522 .shutdown = ccwgroup_shutdown,
549 .pm = &ccwgroup_pm_ops, 523 .pm = &ccwgroup_pm_ops,
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index a49c46c9198..a6ddaed8793 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -656,51 +656,34 @@ static struct io_subchannel_private console_priv;
656static int console_subchannel_in_use; 656static int console_subchannel_in_use;
657 657
658/* 658/*
659 * Use cio_tpi to get a pending interrupt and call the interrupt handler. 659 * Use cio_tsch to update the subchannel status and call the interrupt handler
660 * Return non-zero if an interrupt was processed, zero otherwise. 660 * if status had been pending. Called with the console_subchannel lock.
661 */ 661 */
662static int cio_tpi(void) 662static void cio_tsch(struct subchannel *sch)
663{ 663{
664 struct tpi_info *tpi_info;
665 struct subchannel *sch;
666 struct irb *irb; 664 struct irb *irb;
667 int irq_context; 665 int irq_context;
668 666
669 tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id;
670 if (tpi(NULL) != 1)
671 return 0;
672 kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++;
673 if (tpi_info->adapter_IO) {
674 do_adapter_IO(tpi_info->isc);
675 return 1;
676 }
677 irb = (struct irb *)&S390_lowcore.irb; 667 irb = (struct irb *)&S390_lowcore.irb;
678 /* Store interrupt response block to lowcore. */ 668 /* Store interrupt response block to lowcore. */
679 if (tsch(tpi_info->schid, irb) != 0) { 669 if (tsch(sch->schid, irb) != 0)
680 /* Not status pending or not operational. */ 670 /* Not status pending or not operational. */
681 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; 671 return;
682 return 1; 672 memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw));
683 } 673 /* Call interrupt handler with updated status. */
684 sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
685 if (!sch) {
686 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
687 return 1;
688 }
689 irq_context = in_interrupt(); 674 irq_context = in_interrupt();
690 if (!irq_context) 675 if (!irq_context) {
691 local_bh_disable(); 676 local_bh_disable();
692 irq_enter(); 677 irq_enter();
693 spin_lock(sch->lock); 678 }
694 memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw));
695 if (sch->driver && sch->driver->irq) 679 if (sch->driver && sch->driver->irq)
696 sch->driver->irq(sch); 680 sch->driver->irq(sch);
697 else 681 else
698 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; 682 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
699 spin_unlock(sch->lock); 683 if (!irq_context) {
700 irq_exit(); 684 irq_exit();
701 if (!irq_context)
702 _local_bh_enable(); 685 _local_bh_enable();
703 return 1; 686 }
704} 687}
705 688
706void *cio_get_console_priv(void) 689void *cio_get_console_priv(void)
@@ -712,34 +695,16 @@ void *cio_get_console_priv(void)
712 * busy wait for the next interrupt on the console 695 * busy wait for the next interrupt on the console
713 */ 696 */
714void wait_cons_dev(void) 697void wait_cons_dev(void)
715 __releases(console_subchannel.lock)
716 __acquires(console_subchannel.lock)
717{ 698{
718 unsigned long cr6 __attribute__ ((aligned (8)));
719 unsigned long save_cr6 __attribute__ ((aligned (8)));
720
721 /*
722 * before entering the spinlock we may already have
723 * processed the interrupt on a different CPU...
724 */
725 if (!console_subchannel_in_use) 699 if (!console_subchannel_in_use)
726 return; 700 return;
727 701
728 /* disable all but the console isc */ 702 while (1) {
729 __ctl_store (save_cr6, 6, 6); 703 cio_tsch(&console_subchannel);
730 cr6 = 1UL << (31 - CONSOLE_ISC); 704 if (console_subchannel.schib.scsw.cmd.actl == 0)
731 __ctl_load (cr6, 6, 6); 705 break;
732 706 udelay_simple(100);
733 do { 707 }
734 spin_unlock(console_subchannel.lock);
735 if (!cio_tpi())
736 cpu_relax();
737 spin_lock(console_subchannel.lock);
738 } while (console_subchannel.schib.scsw.cmd.actl != 0);
739 /*
740 * restore previous isc value
741 */
742 __ctl_load (save_cr6, 6, 6);
743} 708}
744 709
745static int 710static int
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 02d01525946..f8f952d5204 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -695,7 +695,17 @@ static int match_dev_id(struct device *dev, void *data)
695 return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); 695 return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id);
696} 696}
697 697
698static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) 698/**
699 * get_ccwdev_by_dev_id() - obtain device from a ccw device id
700 * @dev_id: id of the device to be searched
701 *
702 * This function searches all devices attached to the ccw bus for a device
703 * matching @dev_id.
704 * Returns:
705 * If a device is found its reference count is increased and returned;
706 * else %NULL is returned.
707 */
708struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id)
699{ 709{
700 struct device *dev; 710 struct device *dev;
701 711
@@ -703,6 +713,7 @@ static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id)
703 713
704 return dev ? to_ccwdev(dev) : NULL; 714 return dev ? to_ccwdev(dev) : NULL;
705} 715}
716EXPORT_SYMBOL_GPL(get_ccwdev_by_dev_id);
706 717
707static void ccw_device_do_unbind_bind(struct ccw_device *cdev) 718static void ccw_device_do_unbind_bind(struct ccw_device *cdev)
708{ 719{
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 179824b3082..6bace694239 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -101,6 +101,7 @@ int ccw_device_test_sense_data(struct ccw_device *);
101void ccw_device_schedule_sch_unregister(struct ccw_device *); 101void ccw_device_schedule_sch_unregister(struct ccw_device *);
102int ccw_purge_blacklisted(void); 102int ccw_purge_blacklisted(void);
103void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo); 103void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo);
104struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id);
104 105
105/* Function prototypes for device status and basic sense stuff. */ 106/* Function prototypes for device status and basic sense stuff. */
106void ccw_device_accumulate_irb(struct ccw_device *, struct irb *); 107void ccw_device_accumulate_irb(struct ccw_device *, struct irb *);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 35c685c374e..7493efafa0d 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -63,7 +63,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask,
63 " ipm %0\n" 63 " ipm %0\n"
64 " srl %0,28\n" 64 " srl %0,28\n"
65 : "=d" (cc) 65 : "=d" (cc)
66 : "d" (__fc), "d" (__schid), "d" (__mask) : "cc", "memory"); 66 : "d" (__fc), "d" (__schid), "d" (__mask) : "cc");
67 return cc; 67 return cc;
68} 68}
69 69
@@ -74,7 +74,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask,
74 * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer 74 * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer
75 * @fc: function code to perform 75 * @fc: function code to perform
76 * 76 *
77 * Returns cc or QDIO_ERROR_SIGA_ACCESS_EXCEPTION. 77 * Returns condition code.
78 * Note: For IQDC unicast queues only the highest priority queue is processed. 78 * Note: For IQDC unicast queues only the highest priority queue is processed.
79 */ 79 */
80static inline int do_siga_output(unsigned long schid, unsigned long mask, 80static inline int do_siga_output(unsigned long schid, unsigned long mask,
@@ -85,18 +85,16 @@ static inline int do_siga_output(unsigned long schid, unsigned long mask,
85 register unsigned long __schid asm("1") = schid; 85 register unsigned long __schid asm("1") = schid;
86 register unsigned long __mask asm("2") = mask; 86 register unsigned long __mask asm("2") = mask;
87 register unsigned long __aob asm("3") = aob; 87 register unsigned long __aob asm("3") = aob;
88 int cc = QDIO_ERROR_SIGA_ACCESS_EXCEPTION; 88 int cc;
89 89
90 asm volatile( 90 asm volatile(
91 " siga 0\n" 91 " siga 0\n"
92 "0: ipm %0\n" 92 " ipm %0\n"
93 " srl %0,28\n" 93 " srl %0,28\n"
94 "1:\n" 94 : "=d" (cc), "+d" (__fc), "+d" (__aob)
95 EX_TABLE(0b, 1b) 95 : "d" (__schid), "d" (__mask)
96 : "+d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask), 96 : "cc");
97 "+d" (__aob) 97 *bb = __fc >> 31;
98 : : "cc", "memory");
99 *bb = ((unsigned int) __fc) >> 31;
100 return cc; 98 return cc;
101} 99}
102 100
@@ -167,7 +165,7 @@ again:
167 165
168 DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); 166 DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
169 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 167 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
170 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 168 q->handler(q->irq_ptr->cdev, QDIO_ERROR_GET_BUF_STATE,
171 q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); 169 q->nr, q->first_to_kick, count, q->irq_ptr->int_parm);
172 return 0; 170 return 0;
173} 171}
@@ -215,7 +213,7 @@ again:
215 213
216 DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); 214 DBF_ERROR("%4x SQBS ERROR", SCH_NO(q));
217 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 215 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
218 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 216 q->handler(q->irq_ptr->cdev, QDIO_ERROR_SET_BUF_STATE,
219 q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); 217 q->nr, q->first_to_kick, count, q->irq_ptr->int_parm);
220 return 0; 218 return 0;
221} 219}
@@ -313,7 +311,7 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
313 cc = do_siga_sync(schid, output, input, fc); 311 cc = do_siga_sync(schid, output, input, fc);
314 if (unlikely(cc)) 312 if (unlikely(cc))
315 DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc); 313 DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc);
316 return cc; 314 return (cc) ? -EIO : 0;
317} 315}
318 316
319static inline int qdio_siga_sync_q(struct qdio_q *q) 317static inline int qdio_siga_sync_q(struct qdio_q *q)
@@ -384,7 +382,7 @@ static inline int qdio_siga_input(struct qdio_q *q)
384 cc = do_siga_input(schid, q->mask, fc); 382 cc = do_siga_input(schid, q->mask, fc);
385 if (unlikely(cc)) 383 if (unlikely(cc))
386 DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc); 384 DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc);
387 return cc; 385 return (cc) ? -EIO : 0;
388} 386}
389 387
390#define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0) 388#define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0)
@@ -443,7 +441,7 @@ static void process_buffer_error(struct qdio_q *q, int count)
443 unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : 441 unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT :
444 SLSB_P_OUTPUT_NOT_INIT; 442 SLSB_P_OUTPUT_NOT_INIT;
445 443
446 q->qdio_error |= QDIO_ERROR_SLSB_STATE; 444 q->qdio_error = QDIO_ERROR_SLSB_STATE;
447 445
448 /* special handling for no target buffer empty */ 446 /* special handling for no target buffer empty */
449 if ((!q->is_input_q && 447 if ((!q->is_input_q &&
@@ -519,7 +517,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
519 int count, stop; 517 int count, stop;
520 unsigned char state = 0; 518 unsigned char state = 0;
521 519
522 q->timestamp = get_clock_fast(); 520 q->timestamp = get_clock();
523 521
524 /* 522 /*
525 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved 523 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved
@@ -575,7 +573,7 @@ static int qdio_inbound_q_moved(struct qdio_q *q)
575 573
576 bufnr = get_inbound_buffer_frontier(q); 574 bufnr = get_inbound_buffer_frontier(q);
577 575
578 if ((bufnr != q->last_move) || q->qdio_error) { 576 if (bufnr != q->last_move) {
579 q->last_move = bufnr; 577 q->last_move = bufnr;
580 if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR) 578 if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR)
581 q->u.in.timestamp = get_clock(); 579 q->u.in.timestamp = get_clock();
@@ -790,7 +788,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
790 int count, stop; 788 int count, stop;
791 unsigned char state = 0; 789 unsigned char state = 0;
792 790
793 q->timestamp = get_clock_fast(); 791 q->timestamp = get_clock();
794 792
795 if (need_siga_sync(q)) 793 if (need_siga_sync(q))
796 if (((queue_type(q) != QDIO_IQDIO_QFMT) && 794 if (((queue_type(q) != QDIO_IQDIO_QFMT) &&
@@ -863,7 +861,7 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q)
863 861
864 bufnr = get_outbound_buffer_frontier(q); 862 bufnr = get_outbound_buffer_frontier(q);
865 863
866 if ((bufnr != q->last_move) || q->qdio_error) { 864 if (bufnr != q->last_move) {
867 q->last_move = bufnr; 865 q->last_move = bufnr;
868 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr); 866 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
869 return 1; 867 return 1;
@@ -894,13 +892,16 @@ retry:
894 goto retry; 892 goto retry;
895 } 893 }
896 DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr); 894 DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr);
897 cc |= QDIO_ERROR_SIGA_BUSY; 895 cc = -EBUSY;
898 } else 896 } else {
899 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr); 897 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr);
898 cc = -ENOBUFS;
899 }
900 break; 900 break;
901 case 1: 901 case 1:
902 case 3: 902 case 3:
903 DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); 903 DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc);
904 cc = -EIO;
904 break; 905 break;
905 } 906 }
906 if (retries) { 907 if (retries) {
@@ -1090,7 +1091,7 @@ static void qdio_handle_activate_check(struct ccw_device *cdev,
1090 } 1091 }
1091 1092
1092 count = sub_buf(q->first_to_check, q->first_to_kick); 1093 count = sub_buf(q->first_to_check, q->first_to_kick);
1093 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 1094 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE,
1094 q->nr, q->first_to_kick, count, irq_ptr->int_parm); 1095 q->nr, q->first_to_kick, count, irq_ptr->int_parm);
1095no_handler: 1096no_handler:
1096 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); 1097 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
@@ -1691,7 +1692,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
1691 "do%02x b:%02x c:%02x", callflags, bufnr, count); 1692 "do%02x b:%02x c:%02x", callflags, bufnr, count);
1692 1693
1693 if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) 1694 if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)
1694 return -EBUSY; 1695 return -EIO;
1695 if (!count) 1696 if (!count)
1696 return 0; 1697 return 0;
1697 if (callflags & QDIO_FLAG_SYNC_INPUT) 1698 if (callflags & QDIO_FLAG_SYNC_INPUT)