diff options
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/cio.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 030083f9c6f3..c0cb72547256 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -114,6 +114,7 @@ cio_tpi(void) | |||
114 | struct tpi_info *tpi_info; | 114 | struct tpi_info *tpi_info; |
115 | struct subchannel *sch; | 115 | struct subchannel *sch; |
116 | struct irb *irb; | 116 | struct irb *irb; |
117 | int irq_context; | ||
117 | 118 | ||
118 | tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID; | 119 | tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID; |
119 | if (tpi (NULL) != 1) | 120 | if (tpi (NULL) != 1) |
@@ -126,7 +127,9 @@ cio_tpi(void) | |||
126 | sch = (struct subchannel *)(unsigned long)tpi_info->intparm; | 127 | sch = (struct subchannel *)(unsigned long)tpi_info->intparm; |
127 | if (!sch) | 128 | if (!sch) |
128 | return 1; | 129 | return 1; |
129 | local_bh_disable(); | 130 | irq_context = in_interrupt(); |
131 | if (!irq_context) | ||
132 | local_bh_disable(); | ||
130 | irq_enter (); | 133 | irq_enter (); |
131 | spin_lock(sch->lock); | 134 | spin_lock(sch->lock); |
132 | memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); | 135 | memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); |
@@ -134,7 +137,8 @@ cio_tpi(void) | |||
134 | sch->driver->irq(sch); | 137 | sch->driver->irq(sch); |
135 | spin_unlock(sch->lock); | 138 | spin_unlock(sch->lock); |
136 | irq_exit (); | 139 | irq_exit (); |
137 | _local_bh_enable(); | 140 | if (!irq_context) |
141 | _local_bh_enable(); | ||
138 | return 1; | 142 | return 1; |
139 | } | 143 | } |
140 | 144 | ||