aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r--drivers/s390/cio/chsc.c82
-rw-r--r--drivers/s390/cio/cio.c128
-rw-r--r--drivers/s390/cio/css.h3
-rw-r--r--drivers/s390/cio/device.c17
-rw-r--r--drivers/s390/cio/device_fsm.c27
-rw-r--r--drivers/s390/cio/device_id.c10
-rw-r--r--drivers/s390/cio/device_pgid.c30
-rw-r--r--drivers/s390/cio/device_status.c3
-rw-r--r--drivers/s390/cio/qdio.c8
-rw-r--r--drivers/s390/cio/qdio.h4
10 files changed, 226 insertions, 86 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 2d78f0f4a40f..dbfb77b03928 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -251,6 +251,8 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
251 cc = cio_clear(sch); 251 cc = cio_clear(sch);
252 if (cc == -ENODEV) 252 if (cc == -ENODEV)
253 goto out_unreg; 253 goto out_unreg;
254 /* Request retry of internal operation. */
255 device_set_intretry(sch);
254 /* Call handler. */ 256 /* Call handler. */
255 if (sch->driver && sch->driver->termination) 257 if (sch->driver && sch->driver->termination)
256 sch->driver->termination(&sch->dev); 258 sch->driver->termination(&sch->dev);
@@ -711,9 +713,6 @@ static inline int check_for_io_on_path(struct subchannel *sch, int index)
711{ 713{
712 int cc; 714 int cc;
713 715
714 if (!device_is_online(sch))
715 /* cio could be doing I/O. */
716 return 0;
717 cc = stsch(sch->schid, &sch->schib); 716 cc = stsch(sch->schid, &sch->schib);
718 if (cc) 717 if (cc)
719 return 0; 718 return 0;
@@ -722,6 +721,26 @@ static inline int check_for_io_on_path(struct subchannel *sch, int index)
722 return 0; 721 return 0;
723} 722}
724 723
724static void terminate_internal_io(struct subchannel *sch)
725{
726 if (cio_clear(sch)) {
727 /* Recheck device in case clear failed. */
728 sch->lpm = 0;
729 if (device_trigger_verify(sch) != 0) {
730 if(css_enqueue_subchannel_slow(sch->schid)) {
731 css_clear_subchannel_slow_list();
732 need_rescan = 1;
733 }
734 }
735 return;
736 }
737 /* Request retry of internal operation. */
738 device_set_intretry(sch);
739 /* Call handler. */
740 if (sch->driver && sch->driver->termination)
741 sch->driver->termination(&sch->dev);
742}
743
725static inline void 744static inline void
726__s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on) 745__s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
727{ 746{
@@ -744,20 +763,26 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
744 device_trigger_reprobe(sch); 763 device_trigger_reprobe(sch);
745 else if (sch->driver && sch->driver->verify) 764 else if (sch->driver && sch->driver->verify)
746 sch->driver->verify(&sch->dev); 765 sch->driver->verify(&sch->dev);
747 } else { 766 break;
748 sch->opm &= ~(0x80 >> chp); 767 }
749 sch->lpm &= ~(0x80 >> chp); 768 sch->opm &= ~(0x80 >> chp);
750 if (check_for_io_on_path(sch, chp)) 769 sch->lpm &= ~(0x80 >> chp);
770 if (check_for_io_on_path(sch, chp)) {
771 if (device_is_online(sch))
751 /* Path verification is done after killing. */ 772 /* Path verification is done after killing. */
752 device_kill_io(sch); 773 device_kill_io(sch);
753 else if (!sch->lpm) { 774 else
775 /* Kill and retry internal I/O. */
776 terminate_internal_io(sch);
777 } else if (!sch->lpm) {
778 if (device_trigger_verify(sch) != 0) {
754 if (css_enqueue_subchannel_slow(sch->schid)) { 779 if (css_enqueue_subchannel_slow(sch->schid)) {
755 css_clear_subchannel_slow_list(); 780 css_clear_subchannel_slow_list();
756 need_rescan = 1; 781 need_rescan = 1;
757 } 782 }
758 } else if (sch->driver && sch->driver->verify) 783 }
759 sch->driver->verify(&sch->dev); 784 } else if (sch->driver && sch->driver->verify)
760 } 785 sch->driver->verify(&sch->dev);
761 break; 786 break;
762 } 787 }
763 spin_unlock_irqrestore(&sch->lock, flags); 788 spin_unlock_irqrestore(&sch->lock, flags);
@@ -1465,41 +1490,6 @@ chsc_get_chp_desc(struct subchannel *sch, int chp_no)
1465 return desc; 1490 return desc;
1466} 1491}
1467 1492
1468static int reset_channel_path(struct channel_path *chp)
1469{
1470 int cc;
1471
1472 cc = rchp(chp->id);
1473 switch (cc) {
1474 case 0:
1475 return 0;
1476 case 2:
1477 return -EBUSY;
1478 default:
1479 return -ENODEV;
1480 }
1481}
1482
1483static void reset_channel_paths_css(struct channel_subsystem *css)
1484{
1485 int i;
1486
1487 for (i = 0; i <= __MAX_CHPID; i++) {
1488 if (css->chps[i])
1489 reset_channel_path(css->chps[i]);
1490 }
1491}
1492
1493void cio_reset_channel_paths(void)
1494{
1495 int i;
1496
1497 for (i = 0; i <= __MAX_CSSID; i++) {
1498 if (css[i] && css[i]->valid)
1499 reset_channel_paths_css(css[i]);
1500 }
1501}
1502
1503static int __init 1493static int __init
1504chsc_alloc_sei_area(void) 1494chsc_alloc_sei_area(void)
1505{ 1495{
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 8936e460a807..20aee2783847 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -21,6 +21,7 @@
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/irq_regs.h> 22#include <asm/irq_regs.h>
23#include <asm/setup.h> 23#include <asm/setup.h>
24#include <asm/reset.h>
24#include "airq.h" 25#include "airq.h"
25#include "cio.h" 26#include "cio.h"
26#include "css.h" 27#include "css.h"
@@ -28,6 +29,7 @@
28#include "ioasm.h" 29#include "ioasm.h"
29#include "blacklist.h" 30#include "blacklist.h"
30#include "cio_debug.h" 31#include "cio_debug.h"
32#include "../s390mach.h"
31 33
32debug_info_t *cio_debug_msg_id; 34debug_info_t *cio_debug_msg_id;
33debug_info_t *cio_debug_trace_id; 35debug_info_t *cio_debug_trace_id;
@@ -841,26 +843,12 @@ __clear_subchannel_easy(struct subchannel_id schid)
841 return -EBUSY; 843 return -EBUSY;
842} 844}
843 845
844struct sch_match_id { 846static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
845 struct subchannel_id schid;
846 struct ccw_dev_id devid;
847 int rc;
848};
849
850static int __shutdown_subchannel_easy_and_match(struct subchannel_id schid,
851 void *data)
852{ 847{
853 struct schib schib; 848 struct schib schib;
854 struct sch_match_id *match_id = data;
855 849
856 if (stsch_err(schid, &schib)) 850 if (stsch_err(schid, &schib))
857 return -ENXIO; 851 return -ENXIO;
858 if (match_id && schib.pmcw.dnv &&
859 (schib.pmcw.dev == match_id->devid.devno) &&
860 (schid.ssid == match_id->devid.ssid)) {
861 match_id->schid = schid;
862 match_id->rc = 0;
863 }
864 if (!schib.pmcw.ena) 852 if (!schib.pmcw.ena)
865 return 0; 853 return 0;
866 switch(__disable_subchannel_easy(schid, &schib)) { 854 switch(__disable_subchannel_easy(schid, &schib)) {
@@ -876,27 +864,111 @@ static int __shutdown_subchannel_easy_and_match(struct subchannel_id schid,
876 return 0; 864 return 0;
877} 865}
878 866
879static int clear_all_subchannels_and_match(struct ccw_dev_id *devid, 867static atomic_t chpid_reset_count;
880 struct subchannel_id *schid) 868
869static void s390_reset_chpids_mcck_handler(void)
870{
871 struct crw crw;
872 struct mci *mci;
873
874 /* Check for pending channel report word. */
875 mci = (struct mci *)&S390_lowcore.mcck_interruption_code;
876 if (!mci->cp)
877 return;
878 /* Process channel report words. */
879 while (stcrw(&crw) == 0) {
880 /* Check for responses to RCHP. */
881 if (crw.slct && crw.rsc == CRW_RSC_CPATH)
882 atomic_dec(&chpid_reset_count);
883 }
884}
885
886#define RCHP_TIMEOUT (30 * USEC_PER_SEC)
887static void css_reset(void)
888{
889 int i, ret;
890 unsigned long long timeout;
891
892 /* Reset subchannels. */
893 for_each_subchannel(__shutdown_subchannel_easy, NULL);
894 /* Reset channel paths. */
895 s390_reset_mcck_handler = s390_reset_chpids_mcck_handler;
896 /* Enable channel report machine checks. */
897 __ctl_set_bit(14, 28);
898 /* Temporarily reenable machine checks. */
899 local_mcck_enable();
900 for (i = 0; i <= __MAX_CHPID; i++) {
901 ret = rchp(i);
902 if ((ret == 0) || (ret == 2))
903 /*
904 * rchp either succeeded, or another rchp is already
905 * in progress. In either case, we'll get a crw.
906 */
907 atomic_inc(&chpid_reset_count);
908 }
909 /* Wait for machine check for all channel paths. */
910 timeout = get_clock() + (RCHP_TIMEOUT << 12);
911 while (atomic_read(&chpid_reset_count) != 0) {
912 if (get_clock() > timeout)
913 break;
914 cpu_relax();
915 }
916 /* Disable machine checks again. */
917 local_mcck_disable();
918 /* Disable channel report machine checks. */
919 __ctl_clear_bit(14, 28);
920 s390_reset_mcck_handler = NULL;
921}
922
923static struct reset_call css_reset_call = {
924 .fn = css_reset,
925};
926
927static int __init init_css_reset_call(void)
928{
929 atomic_set(&chpid_reset_count, 0);
930 register_reset_call(&css_reset_call);
931 return 0;
932}
933
934arch_initcall(init_css_reset_call);
935
936struct sch_match_id {
937 struct subchannel_id schid;
938 struct ccw_dev_id devid;
939 int rc;
940};
941
942static int __reipl_subchannel_match(struct subchannel_id schid, void *data)
943{
944 struct schib schib;
945 struct sch_match_id *match_id = data;
946
947 if (stsch_err(schid, &schib))
948 return -ENXIO;
949 if (schib.pmcw.dnv &&
950 (schib.pmcw.dev == match_id->devid.devno) &&
951 (schid.ssid == match_id->devid.ssid)) {
952 match_id->schid = schid;
953 match_id->rc = 0;
954 return 1;
955 }
956 return 0;
957}
958
959static int reipl_find_schid(struct ccw_dev_id *devid,
960 struct subchannel_id *schid)
881{ 961{
882 struct sch_match_id match_id; 962 struct sch_match_id match_id;
883 963
884 match_id.devid = *devid; 964 match_id.devid = *devid;
885 match_id.rc = -ENODEV; 965 match_id.rc = -ENODEV;
886 local_irq_disable(); 966 for_each_subchannel(__reipl_subchannel_match, &match_id);
887 for_each_subchannel(__shutdown_subchannel_easy_and_match, &match_id);
888 if (match_id.rc == 0) 967 if (match_id.rc == 0)
889 *schid = match_id.schid; 968 *schid = match_id.schid;
890 return match_id.rc; 969 return match_id.rc;
891} 970}
892 971
893
894void clear_all_subchannels(void)
895{
896 local_irq_disable();
897 for_each_subchannel(__shutdown_subchannel_easy_and_match, NULL);
898}
899
900extern void do_reipl_asm(__u32 schid); 972extern void do_reipl_asm(__u32 schid);
901 973
902/* Make sure all subchannels are quiet before we re-ipl an lpar. */ 974/* Make sure all subchannels are quiet before we re-ipl an lpar. */
@@ -904,9 +976,9 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
904{ 976{
905 struct subchannel_id schid; 977 struct subchannel_id schid;
906 978
907 if (clear_all_subchannels_and_match(devid, &schid)) 979 s390_reset_system();
980 if (reipl_find_schid(devid, &schid) != 0)
908 panic("IPL Device not found\n"); 981 panic("IPL Device not found\n");
909 cio_reset_channel_paths();
910 do_reipl_asm(*((__u32*)&schid)); 982 do_reipl_asm(*((__u32*)&schid));
911} 983}
912 984
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 4c2ff8336288..9ff064e71767 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -94,6 +94,7 @@ struct ccw_device_private {
94 unsigned int donotify:1; /* call notify function */ 94 unsigned int donotify:1; /* call notify function */
95 unsigned int recog_done:1; /* dev. recog. complete */ 95 unsigned int recog_done:1; /* dev. recog. complete */
96 unsigned int fake_irb:1; /* deliver faked irb */ 96 unsigned int fake_irb:1; /* deliver faked irb */
97 unsigned int intretry:1; /* retry internal operation */
97 } __attribute__((packed)) flags; 98 } __attribute__((packed)) flags;
98 unsigned long intparm; /* user interruption parameter */ 99 unsigned long intparm; /* user interruption parameter */
99 struct qdio_irq *qdio_data; 100 struct qdio_irq *qdio_data;
@@ -171,6 +172,8 @@ void device_trigger_reprobe(struct subchannel *);
171/* Helper functions for vary on/off. */ 172/* Helper functions for vary on/off. */
172int device_is_online(struct subchannel *); 173int device_is_online(struct subchannel *);
173void device_kill_io(struct subchannel *); 174void device_kill_io(struct subchannel *);
175void device_set_intretry(struct subchannel *sch);
176int device_trigger_verify(struct subchannel *sch);
174 177
175/* Machine check helper function. */ 178/* Machine check helper function. */
176void device_kill_pending_timer(struct subchannel *); 179void device_kill_pending_timer(struct subchannel *);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 39c98f940507..d3d3716ff84b 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -687,8 +687,20 @@ io_subchannel_register(void *data)
687 cdev = data; 687 cdev = data;
688 sch = to_subchannel(cdev->dev.parent); 688 sch = to_subchannel(cdev->dev.parent);
689 689
690 /*
691 * io_subchannel_register() will also be called after device
692 * recognition has been done for a boxed device (which will already
693 * be registered). We need to reprobe since we may now have sense id
694 * information.
695 */
690 if (klist_node_attached(&cdev->dev.knode_parent)) { 696 if (klist_node_attached(&cdev->dev.knode_parent)) {
691 bus_rescan_devices(&ccw_bus_type); 697 if (!cdev->drv) {
698 ret = device_reprobe(&cdev->dev);
699 if (ret)
700 /* We can't do much here. */
701 dev_info(&cdev->dev, "device_reprobe() returned"
702 " %d\n", ret);
703 }
692 goto out; 704 goto out;
693 } 705 }
694 /* make it known to the system */ 706 /* make it known to the system */
@@ -948,6 +960,9 @@ io_subchannel_ioterm(struct device *dev)
948 cdev = dev->driver_data; 960 cdev = dev->driver_data;
949 if (!cdev) 961 if (!cdev)
950 return; 962 return;
963 /* Internal I/O will be retried by the interrupt handler. */
964 if (cdev->private->flags.intretry)
965 return;
951 cdev->private->state = DEV_STATE_CLEAR_VERIFY; 966 cdev->private->state = DEV_STATE_CLEAR_VERIFY;
952 if (cdev->handler) 967 if (cdev->handler)
953 cdev->handler(cdev, cdev->private->intparm, 968 cdev->handler(cdev, cdev->private->intparm,
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index de3d0857db9f..09c7672eb3f3 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -59,6 +59,27 @@ device_set_disconnected(struct subchannel *sch)
59 cdev->private->state = DEV_STATE_DISCONNECTED; 59 cdev->private->state = DEV_STATE_DISCONNECTED;
60} 60}
61 61
62void device_set_intretry(struct subchannel *sch)
63{
64 struct ccw_device *cdev;
65
66 cdev = sch->dev.driver_data;
67 if (!cdev)
68 return;
69 cdev->private->flags.intretry = 1;
70}
71
72int device_trigger_verify(struct subchannel *sch)
73{
74 struct ccw_device *cdev;
75
76 cdev = sch->dev.driver_data;
77 if (!cdev || !cdev->online)
78 return -EINVAL;
79 dev_fsm_event(cdev, DEV_EVENT_VERIFY);
80 return 0;
81}
82
62/* 83/*
63 * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. 84 * Timeout function. It just triggers a DEV_EVENT_TIMEOUT.
64 */ 85 */
@@ -893,6 +914,12 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
893 * had killed the original request. 914 * had killed the original request.
894 */ 915 */
895 if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) { 916 if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
917 /* Retry Basic Sense if requested. */
918 if (cdev->private->flags.intretry) {
919 cdev->private->flags.intretry = 0;
920 ccw_device_do_sense(cdev, irb);
921 return;
922 }
896 cdev->private->flags.dosense = 0; 923 cdev->private->flags.dosense = 0;
897 memset(&cdev->private->irb, 0, sizeof(struct irb)); 924 memset(&cdev->private->irb, 0, sizeof(struct irb));
898 ccw_device_accumulate_irb(cdev, irb); 925 ccw_device_accumulate_irb(cdev, irb);
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index a74785b9e4eb..f17275917fe5 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -191,6 +191,8 @@ __ccw_device_sense_id_start(struct ccw_device *cdev)
191 if ((sch->opm & cdev->private->imask) != 0 && 191 if ((sch->opm & cdev->private->imask) != 0 &&
192 cdev->private->iretry > 0) { 192 cdev->private->iretry > 0) {
193 cdev->private->iretry--; 193 cdev->private->iretry--;
194 /* Reset internal retry indication. */
195 cdev->private->flags.intretry = 0;
194 ret = cio_start (sch, cdev->private->iccws, 196 ret = cio_start (sch, cdev->private->iccws,
195 cdev->private->imask); 197 cdev->private->imask);
196 /* ret is 0, -EBUSY, -EACCES or -ENODEV */ 198 /* ret is 0, -EBUSY, -EACCES or -ENODEV */
@@ -237,8 +239,14 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
237 return 0; /* Success */ 239 return 0; /* Success */
238 } 240 }
239 /* Check the error cases. */ 241 /* Check the error cases. */
240 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) 242 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
243 /* Retry Sense ID if requested. */
244 if (cdev->private->flags.intretry) {
245 cdev->private->flags.intretry = 0;
246 return -EAGAIN;
247 }
241 return -ETIME; 248 return -ETIME;
249 }
242 if (irb->esw.esw0.erw.cons && (irb->ecw[0] & SNS0_CMD_REJECT)) { 250 if (irb->esw.esw0.erw.cons && (irb->ecw[0] & SNS0_CMD_REJECT)) {
243 /* 251 /*
244 * if the device doesn't support the SenseID 252 * if the device doesn't support the SenseID
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 2975ce888c19..cb1879a96818 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -71,6 +71,8 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev)
71 ccw->cda = (__u32) __pa (&cdev->private->pgid[i]); 71 ccw->cda = (__u32) __pa (&cdev->private->pgid[i]);
72 if (cdev->private->iretry > 0) { 72 if (cdev->private->iretry > 0) {
73 cdev->private->iretry--; 73 cdev->private->iretry--;
74 /* Reset internal retry indication. */
75 cdev->private->flags.intretry = 0;
74 ret = cio_start (sch, cdev->private->iccws, 76 ret = cio_start (sch, cdev->private->iccws,
75 cdev->private->imask); 77 cdev->private->imask);
76 /* ret is 0, -EBUSY, -EACCES or -ENODEV */ 78 /* ret is 0, -EBUSY, -EACCES or -ENODEV */
@@ -122,8 +124,14 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev)
122 124
123 sch = to_subchannel(cdev->dev.parent); 125 sch = to_subchannel(cdev->dev.parent);
124 irb = &cdev->private->irb; 126 irb = &cdev->private->irb;
125 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) 127 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
128 /* Retry Sense PGID if requested. */
129 if (cdev->private->flags.intretry) {
130 cdev->private->flags.intretry = 0;
131 return -EAGAIN;
132 }
126 return -ETIME; 133 return -ETIME;
134 }
127 if (irb->esw.esw0.erw.cons && 135 if (irb->esw.esw0.erw.cons &&
128 (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) { 136 (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) {
129 /* 137 /*
@@ -253,6 +261,8 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
253 ret = -EACCES; 261 ret = -EACCES;
254 if (cdev->private->iretry > 0) { 262 if (cdev->private->iretry > 0) {
255 cdev->private->iretry--; 263 cdev->private->iretry--;
264 /* Reset internal retry indication. */
265 cdev->private->flags.intretry = 0;
256 ret = cio_start (sch, cdev->private->iccws, 266 ret = cio_start (sch, cdev->private->iccws,
257 cdev->private->imask); 267 cdev->private->imask);
258 /* We expect an interrupt in case of success or busy 268 /* We expect an interrupt in case of success or busy
@@ -293,6 +303,8 @@ static int __ccw_device_do_nop(struct ccw_device *cdev)
293 ret = -EACCES; 303 ret = -EACCES;
294 if (cdev->private->iretry > 0) { 304 if (cdev->private->iretry > 0) {
295 cdev->private->iretry--; 305 cdev->private->iretry--;
306 /* Reset internal retry indication. */
307 cdev->private->flags.intretry = 0;
296 ret = cio_start (sch, cdev->private->iccws, 308 ret = cio_start (sch, cdev->private->iccws,
297 cdev->private->imask); 309 cdev->private->imask);
298 /* We expect an interrupt in case of success or busy 310 /* We expect an interrupt in case of success or busy
@@ -321,8 +333,14 @@ __ccw_device_check_pgid(struct ccw_device *cdev)
321 333
322 sch = to_subchannel(cdev->dev.parent); 334 sch = to_subchannel(cdev->dev.parent);
323 irb = &cdev->private->irb; 335 irb = &cdev->private->irb;
324 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) 336 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
337 /* Retry Set PGID if requested. */
338 if (cdev->private->flags.intretry) {
339 cdev->private->flags.intretry = 0;
340 return -EAGAIN;
341 }
325 return -ETIME; 342 return -ETIME;
343 }
326 if (irb->esw.esw0.erw.cons) { 344 if (irb->esw.esw0.erw.cons) {
327 if (irb->ecw[0] & SNS0_CMD_REJECT) 345 if (irb->ecw[0] & SNS0_CMD_REJECT)
328 return -EOPNOTSUPP; 346 return -EOPNOTSUPP;
@@ -360,8 +378,14 @@ static int __ccw_device_check_nop(struct ccw_device *cdev)
360 378
361 sch = to_subchannel(cdev->dev.parent); 379 sch = to_subchannel(cdev->dev.parent);
362 irb = &cdev->private->irb; 380 irb = &cdev->private->irb;
363 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) 381 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
382 /* Retry NOP if requested. */
383 if (cdev->private->flags.intretry) {
384 cdev->private->flags.intretry = 0;
385 return -EAGAIN;
386 }
364 return -ETIME; 387 return -ETIME;
388 }
365 if (irb->scsw.cc == 3) { 389 if (irb->scsw.cc == 3) {
366 CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," 390 CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x,"
367 " lpm %02X, became 'not operational'\n", 391 " lpm %02X, became 'not operational'\n",
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 3f7cbce4cd87..bdcf930f7beb 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -319,6 +319,9 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb)
319 sch->sense_ccw.count = SENSE_MAX_COUNT; 319 sch->sense_ccw.count = SENSE_MAX_COUNT;
320 sch->sense_ccw.flags = CCW_FLAG_SLI; 320 sch->sense_ccw.flags = CCW_FLAG_SLI;
321 321
322 /* Reset internal retry indication. */
323 cdev->private->flags.intretry = 0;
324
322 return cio_start (sch, &sch->sense_ccw, 0xff); 325 return cio_start (sch, &sch->sense_ccw, 0xff);
323} 326}
324 327
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 476aa1da5cbc..8d5fa1b4d11f 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -481,7 +481,7 @@ qdio_stop_polling(struct qdio_q *q)
481 unsigned char state = 0; 481 unsigned char state = 0;
482 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; 482 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
483 483
484 if (!atomic_swap(&q->polling,0)) 484 if (!atomic_xchg(&q->polling,0))
485 return 1; 485 return 1;
486 486
487 QDIO_DBF_TEXT4(0,trace,"stoppoll"); 487 QDIO_DBF_TEXT4(0,trace,"stoppoll");
@@ -1964,8 +1964,8 @@ qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
1964 QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN); 1964 QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN);
1965 1965
1966 QDIO_PRINT_WARN("sense data available on qdio channel.\n"); 1966 QDIO_PRINT_WARN("sense data available on qdio channel.\n");
1967 HEXDUMP16(WARN,"irb: ",irb); 1967 QDIO_HEXDUMP16(WARN,"irb: ",irb);
1968 HEXDUMP16(WARN,"sense data: ",irb->ecw); 1968 QDIO_HEXDUMP16(WARN,"sense data: ",irb->ecw);
1969 } 1969 }
1970 1970
1971} 1971}
@@ -3425,7 +3425,7 @@ do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
3425 3425
3426 if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&& 3426 if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&&
3427 (callflags&QDIO_FLAG_UNDER_INTERRUPT)) 3427 (callflags&QDIO_FLAG_UNDER_INTERRUPT))
3428 atomic_swap(&q->polling,0); 3428 atomic_xchg(&q->polling,0);
3429 3429
3430 if (used_elements) 3430 if (used_elements)
3431 return; 3431 return;
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 49bb9e371c32..42927c1b7451 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -236,7 +236,7 @@ enum qdio_irq_states {
236#define QDIO_PRINT_EMERG(x...) do { } while (0) 236#define QDIO_PRINT_EMERG(x...) do { } while (0)
237#endif 237#endif
238 238
239#define HEXDUMP16(importance,header,ptr) \ 239#define QDIO_HEXDUMP16(importance,header,ptr) \
240QDIO_PRINT_##importance(header "%02x %02x %02x %02x " \ 240QDIO_PRINT_##importance(header "%02x %02x %02x %02x " \
241 "%02x %02x %02x %02x %02x %02x %02x %02x " \ 241 "%02x %02x %02x %02x %02x %02x %02x %02x " \
242 "%02x %02x %02x %02x\n",*(((char*)ptr)), \ 242 "%02x %02x %02x %02x\n",*(((char*)ptr)), \
@@ -429,8 +429,6 @@ struct qdio_perf_stats {
429}; 429};
430#endif /* QDIO_PERFORMANCE_STATS */ 430#endif /* QDIO_PERFORMANCE_STATS */
431 431
432#define atomic_swap(a,b) xchg((int*)a.counter,b)
433
434/* unlikely as the later the better */ 432/* unlikely as the later the better */
435#define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q) 433#define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q)
436#define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \ 434#define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \