aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-08-16 18:50:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-16 18:50:22 -0400
commit45b6ae761e5259d457a797f66f4d4c16b620f268 (patch)
tree6811a3428de0b7a3eb0594cdf9b67adab5b20c34
parentae5d68be42cd0275a91faf56d2b527b448c3caf4 (diff)
parentaf7752106e4f12b4ee47b4eca3e7ba4bcec6e7e5 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky: "A couple of bug fixes, minor cleanup and a change to the default config" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/dasd: fix failing CUIR assignment under LPAR s390/pageattr: handle numpages parameter correctly s390/dasd: fix hanging device after clear subchannel s390/qdio: avoid reschedule of outbound tasklet once killed s390/qdio: remove checks for ccw device internal state s390/qdio: fix double return code evaluation s390/qdio: get rid of spin_lock_irqsave usage s390/cio: remove subchannel_id from ccw_device_private s390/qdio: obtain subchannel_id via ccw_device_get_schid() s390/cio: stop using subchannel_id from ccw_device_private s390/config: make the vector optimized crc function builtin s390/lib: fix memcmp and strstr s390/crc32-vx: Fix checksum calculation for small sizes s390: clarify compressed image code path
-rw-r--r--arch/s390/boot/compressed/head.S11
-rw-r--r--arch/s390/configs/default_defconfig2
-rw-r--r--arch/s390/configs/gcov_defconfig2
-rw-r--r--arch/s390/configs/performance_defconfig2
-rw-r--r--arch/s390/crypto/crc32-vx.c6
-rw-r--r--arch/s390/defconfig2
-rw-r--r--arch/s390/kernel/head.S4
-rw-r--r--arch/s390/lib/string.c16
-rw-r--r--arch/s390/mm/pageattr.c2
-rw-r--r--drivers/s390/block/dasd.c10
-rw-r--r--drivers/s390/block/dasd_eckd.c10
-rw-r--r--drivers/s390/cio/device.c2
-rw-r--r--drivers/s390/cio/device_status.c7
-rw-r--r--drivers/s390/cio/io_sch.h1
-rw-r--r--drivers/s390/cio/qdio_main.c113
15 files changed, 107 insertions, 83 deletions
diff --git a/arch/s390/boot/compressed/head.S b/arch/s390/boot/compressed/head.S
index f86a4eef28a9..28c4f96a2d9c 100644
--- a/arch/s390/boot/compressed/head.S
+++ b/arch/s390/boot/compressed/head.S
@@ -21,16 +21,21 @@ ENTRY(startup_continue)
21 lg %r15,.Lstack-.LPG1(%r13) 21 lg %r15,.Lstack-.LPG1(%r13)
22 aghi %r15,-160 22 aghi %r15,-160
23 brasl %r14,decompress_kernel 23 brasl %r14,decompress_kernel
24 # setup registers for memory mover & branch to target 24 # Set up registers for memory mover. We move the decompressed image to
25 # 0x11000, starting at offset 0x11000 in the decompressed image so
26 # that code living at 0x11000 in the image will end up at 0x11000 in
27 # memory.
25 lgr %r4,%r2 28 lgr %r4,%r2
26 lg %r2,.Loffset-.LPG1(%r13) 29 lg %r2,.Loffset-.LPG1(%r13)
27 la %r4,0(%r2,%r4) 30 la %r4,0(%r2,%r4)
28 lg %r3,.Lmvsize-.LPG1(%r13) 31 lg %r3,.Lmvsize-.LPG1(%r13)
29 lgr %r5,%r3 32 lgr %r5,%r3
30 # move the memory mover someplace safe 33 # Move the memory mover someplace safe so it doesn't overwrite itself.
31 la %r1,0x200 34 la %r1,0x200
32 mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13) 35 mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
33 # decompress image is started at 0x11000 36 # When the memory mover is done we pass control to
37 # arch/s390/kernel/head64.S:startup_continue which lives at 0x11000 in
38 # the decompressed image.
34 lgr %r6,%r2 39 lgr %r6,%r2
35 br %r1 40 br %r1
36mover: 41mover:
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig
index 889ea3450210..26e0c7f08814 100644
--- a/arch/s390/configs/default_defconfig
+++ b/arch/s390/configs/default_defconfig
@@ -678,7 +678,7 @@ CONFIG_CRYPTO_SHA512_S390=m
678CONFIG_CRYPTO_DES_S390=m 678CONFIG_CRYPTO_DES_S390=m
679CONFIG_CRYPTO_AES_S390=m 679CONFIG_CRYPTO_AES_S390=m
680CONFIG_CRYPTO_GHASH_S390=m 680CONFIG_CRYPTO_GHASH_S390=m
681CONFIG_CRYPTO_CRC32_S390=m 681CONFIG_CRYPTO_CRC32_S390=y
682CONFIG_ASYMMETRIC_KEY_TYPE=y 682CONFIG_ASYMMETRIC_KEY_TYPE=y
683CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m 683CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
684CONFIG_X509_CERTIFICATE_PARSER=m 684CONFIG_X509_CERTIFICATE_PARSER=m
diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig
index 1bcfd764910a..24879dab47bc 100644
--- a/arch/s390/configs/gcov_defconfig
+++ b/arch/s390/configs/gcov_defconfig
@@ -616,7 +616,7 @@ CONFIG_CRYPTO_SHA512_S390=m
616CONFIG_CRYPTO_DES_S390=m 616CONFIG_CRYPTO_DES_S390=m
617CONFIG_CRYPTO_AES_S390=m 617CONFIG_CRYPTO_AES_S390=m
618CONFIG_CRYPTO_GHASH_S390=m 618CONFIG_CRYPTO_GHASH_S390=m
619CONFIG_CRYPTO_CRC32_S390=m 619CONFIG_CRYPTO_CRC32_S390=y
620CONFIG_ASYMMETRIC_KEY_TYPE=y 620CONFIG_ASYMMETRIC_KEY_TYPE=y
621CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m 621CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
622CONFIG_X509_CERTIFICATE_PARSER=m 622CONFIG_X509_CERTIFICATE_PARSER=m
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig
index 13ff090139c8..a5c1e5f2a0ca 100644
--- a/arch/s390/configs/performance_defconfig
+++ b/arch/s390/configs/performance_defconfig
@@ -615,7 +615,7 @@ CONFIG_CRYPTO_SHA512_S390=m
615CONFIG_CRYPTO_DES_S390=m 615CONFIG_CRYPTO_DES_S390=m
616CONFIG_CRYPTO_AES_S390=m 616CONFIG_CRYPTO_AES_S390=m
617CONFIG_CRYPTO_GHASH_S390=m 617CONFIG_CRYPTO_GHASH_S390=m
618CONFIG_CRYPTO_CRC32_S390=m 618CONFIG_CRYPTO_CRC32_S390=y
619CONFIG_ASYMMETRIC_KEY_TYPE=y 619CONFIG_ASYMMETRIC_KEY_TYPE=y
620CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m 620CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
621CONFIG_X509_CERTIFICATE_PARSER=m 621CONFIG_X509_CERTIFICATE_PARSER=m
diff --git a/arch/s390/crypto/crc32-vx.c b/arch/s390/crypto/crc32-vx.c
index 577ae1d4ae89..2bad9d837029 100644
--- a/arch/s390/crypto/crc32-vx.c
+++ b/arch/s390/crypto/crc32-vx.c
@@ -51,6 +51,9 @@ u32 crc32c_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
51 struct kernel_fpu vxstate; \ 51 struct kernel_fpu vxstate; \
52 unsigned long prealign, aligned, remaining; \ 52 unsigned long prealign, aligned, remaining; \
53 \ 53 \
54 if (datalen < VX_MIN_LEN + VX_ALIGN_MASK) \
55 return ___crc32_sw(crc, data, datalen); \
56 \
54 if ((unsigned long)data & VX_ALIGN_MASK) { \ 57 if ((unsigned long)data & VX_ALIGN_MASK) { \
55 prealign = VX_ALIGNMENT - \ 58 prealign = VX_ALIGNMENT - \
56 ((unsigned long)data & VX_ALIGN_MASK); \ 59 ((unsigned long)data & VX_ALIGN_MASK); \
@@ -59,9 +62,6 @@ u32 crc32c_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
59 data = (void *)((unsigned long)data + prealign); \ 62 data = (void *)((unsigned long)data + prealign); \
60 } \ 63 } \
61 \ 64 \
62 if (datalen < VX_MIN_LEN) \
63 return ___crc32_sw(crc, data, datalen); \
64 \
65 aligned = datalen & ~VX_ALIGN_MASK; \ 65 aligned = datalen & ~VX_ALIGN_MASK; \
66 remaining = datalen & VX_ALIGN_MASK; \ 66 remaining = datalen & VX_ALIGN_MASK; \
67 \ 67 \
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index ccccebeeaaf6..73610f2e3b4f 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -234,7 +234,7 @@ CONFIG_CRYPTO_SHA256_S390=m
234CONFIG_CRYPTO_SHA512_S390=m 234CONFIG_CRYPTO_SHA512_S390=m
235CONFIG_CRYPTO_DES_S390=m 235CONFIG_CRYPTO_DES_S390=m
236CONFIG_CRYPTO_AES_S390=m 236CONFIG_CRYPTO_AES_S390=m
237CONFIG_CRYPTO_CRC32_S390=m 237CONFIG_CRYPTO_CRC32_S390=y
238CONFIG_CRC7=m 238CONFIG_CRC7=m
239# CONFIG_XZ_DEC_X86 is not set 239# CONFIG_XZ_DEC_X86 is not set
240# CONFIG_XZ_DEC_POWERPC is not set 240# CONFIG_XZ_DEC_POWERPC is not set
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 56e4d8234ef2..4431905f8cfa 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -309,7 +309,9 @@ ENTRY(startup_kdump)
309 l %r15,.Lstack-.LPG0(%r13) 309 l %r15,.Lstack-.LPG0(%r13)
310 ahi %r15,-STACK_FRAME_OVERHEAD 310 ahi %r15,-STACK_FRAME_OVERHEAD
311 brasl %r14,verify_facilities 311 brasl %r14,verify_facilities
312 /* Continue with startup code in head64.S */ 312# For uncompressed images, continue in
313# arch/s390/kernel/head64.S. For compressed images, continue in
314# arch/s390/boot/compressed/head.S.
313 jg startup_continue 315 jg startup_continue
314 316
315.Lstack: 317.Lstack:
diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c
index e390bbb16443..48352bffbc92 100644
--- a/arch/s390/lib/string.c
+++ b/arch/s390/lib/string.c
@@ -237,11 +237,10 @@ char * strrchr(const char * s, int c)
237EXPORT_SYMBOL(strrchr); 237EXPORT_SYMBOL(strrchr);
238 238
239static inline int clcle(const char *s1, unsigned long l1, 239static inline int clcle(const char *s1, unsigned long l1,
240 const char *s2, unsigned long l2, 240 const char *s2, unsigned long l2)
241 int *diff)
242{ 241{
243 register unsigned long r2 asm("2") = (unsigned long) s1; 242 register unsigned long r2 asm("2") = (unsigned long) s1;
244 register unsigned long r3 asm("3") = (unsigned long) l2; 243 register unsigned long r3 asm("3") = (unsigned long) l1;
245 register unsigned long r4 asm("4") = (unsigned long) s2; 244 register unsigned long r4 asm("4") = (unsigned long) s2;
246 register unsigned long r5 asm("5") = (unsigned long) l2; 245 register unsigned long r5 asm("5") = (unsigned long) l2;
247 int cc; 246 int cc;
@@ -252,7 +251,6 @@ static inline int clcle(const char *s1, unsigned long l1,
252 " srl %0,28" 251 " srl %0,28"
253 : "=&d" (cc), "+a" (r2), "+a" (r3), 252 : "=&d" (cc), "+a" (r2), "+a" (r3),
254 "+a" (r4), "+a" (r5) : : "cc"); 253 "+a" (r4), "+a" (r5) : : "cc");
255 *diff = *(char *)r2 - *(char *)r4;
256 return cc; 254 return cc;
257} 255}
258 256
@@ -270,9 +268,9 @@ char * strstr(const char * s1,const char * s2)
270 return (char *) s1; 268 return (char *) s1;
271 l1 = __strend(s1) - s1; 269 l1 = __strend(s1) - s1;
272 while (l1-- >= l2) { 270 while (l1-- >= l2) {
273 int cc, dummy; 271 int cc;
274 272
275 cc = clcle(s1, l1, s2, l2, &dummy); 273 cc = clcle(s1, l2, s2, l2);
276 if (!cc) 274 if (!cc)
277 return (char *) s1; 275 return (char *) s1;
278 s1++; 276 s1++;
@@ -313,11 +311,11 @@ EXPORT_SYMBOL(memchr);
313 */ 311 */
314int memcmp(const void *cs, const void *ct, size_t n) 312int memcmp(const void *cs, const void *ct, size_t n)
315{ 313{
316 int ret, diff; 314 int ret;
317 315
318 ret = clcle(cs, n, ct, n, &diff); 316 ret = clcle(cs, n, ct, n);
319 if (ret) 317 if (ret)
320 ret = diff; 318 ret = ret == 1 ? -1 : 1;
321 return ret; 319 return ret;
322} 320}
323EXPORT_SYMBOL(memcmp); 321EXPORT_SYMBOL(memcmp);
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index 7104ffb5a67f..af7cf28cf97e 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -252,6 +252,8 @@ static int change_page_attr(unsigned long addr, unsigned long end,
252 int rc = -EINVAL; 252 int rc = -EINVAL;
253 pgd_t *pgdp; 253 pgd_t *pgdp;
254 254
255 if (addr == end)
256 return 0;
255 if (end >= MODULES_END) 257 if (end >= MODULES_END)
256 return -EINVAL; 258 return -EINVAL;
257 mutex_lock(&cpa_mutex); 259 mutex_lock(&cpa_mutex);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 8973d34ce5ba..fb1b56a71475 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1643,9 +1643,18 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1643 u8 *sense = NULL; 1643 u8 *sense = NULL;
1644 int expires; 1644 int expires;
1645 1645
1646 cqr = (struct dasd_ccw_req *) intparm;
1646 if (IS_ERR(irb)) { 1647 if (IS_ERR(irb)) {
1647 switch (PTR_ERR(irb)) { 1648 switch (PTR_ERR(irb)) {
1648 case -EIO: 1649 case -EIO:
1650 if (cqr && cqr->status == DASD_CQR_CLEAR_PENDING) {
1651 device = (struct dasd_device *) cqr->startdev;
1652 cqr->status = DASD_CQR_CLEARED;
1653 dasd_device_clear_timer(device);
1654 wake_up(&dasd_flush_wq);
1655 dasd_schedule_device_bh(device);
1656 return;
1657 }
1649 break; 1658 break;
1650 case -ETIMEDOUT: 1659 case -ETIMEDOUT:
1651 DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: " 1660 DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: "
@@ -1661,7 +1670,6 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1661 } 1670 }
1662 1671
1663 now = get_tod_clock(); 1672 now = get_tod_clock();
1664 cqr = (struct dasd_ccw_req *) intparm;
1665 /* check for conditions that should be handled immediately */ 1673 /* check for conditions that should be handled immediately */
1666 if (!cqr || 1674 if (!cqr ||
1667 !(scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && 1675 !(scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index fd2eff440098..98bbec44bcd0 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -5078,6 +5078,8 @@ static int dasd_eckd_read_message_buffer(struct dasd_device *device,
5078 return PTR_ERR(cqr); 5078 return PTR_ERR(cqr);
5079 } 5079 }
5080 5080
5081 cqr->lpm = lpum;
5082retry:
5081 cqr->startdev = device; 5083 cqr->startdev = device;
5082 cqr->memdev = device; 5084 cqr->memdev = device;
5083 cqr->block = NULL; 5085 cqr->block = NULL;
@@ -5122,6 +5124,14 @@ static int dasd_eckd_read_message_buffer(struct dasd_device *device,
5122 (prssdp + 1); 5124 (prssdp + 1);
5123 memcpy(messages, message_buf, 5125 memcpy(messages, message_buf,
5124 sizeof(struct dasd_rssd_messages)); 5126 sizeof(struct dasd_rssd_messages));
5127 } else if (cqr->lpm) {
5128 /*
5129 * on z/VM we might not be able to do I/O on the requested path
5130 * but instead we get the required information on any path
5131 * so retry with open path mask
5132 */
5133 cqr->lpm = 0;
5134 goto retry;
5125 } else 5135 } else
5126 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, 5136 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
5127 "Reading messages failed with rc=%d\n" 5137 "Reading messages failed with rc=%d\n"
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 7ada078ffdd0..6a58bc8f46e2 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -762,7 +762,6 @@ static int io_subchannel_initialize_dev(struct subchannel *sch,
762 priv->state = DEV_STATE_NOT_OPER; 762 priv->state = DEV_STATE_NOT_OPER;
763 priv->dev_id.devno = sch->schib.pmcw.dev; 763 priv->dev_id.devno = sch->schib.pmcw.dev;
764 priv->dev_id.ssid = sch->schid.ssid; 764 priv->dev_id.ssid = sch->schid.ssid;
765 priv->schid = sch->schid;
766 765
767 INIT_WORK(&priv->todo_work, ccw_device_todo); 766 INIT_WORK(&priv->todo_work, ccw_device_todo);
768 INIT_LIST_HEAD(&priv->cmb_list); 767 INIT_LIST_HEAD(&priv->cmb_list);
@@ -1000,7 +999,6 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev,
1000 put_device(&old_sch->dev); 999 put_device(&old_sch->dev);
1001 /* Initialize new subchannel. */ 1000 /* Initialize new subchannel. */
1002 spin_lock_irq(sch->lock); 1001 spin_lock_irq(sch->lock);
1003 cdev->private->schid = sch->schid;
1004 cdev->ccwlock = sch->lock; 1002 cdev->ccwlock = sch->lock;
1005 if (!sch_is_pseudo_sch(sch)) 1003 if (!sch_is_pseudo_sch(sch))
1006 sch_set_cdev(sch, cdev); 1004 sch_set_cdev(sch, cdev);
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 15b56a15db15..9bc3512374c9 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -26,6 +26,7 @@
26static void 26static void
27ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb) 27ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
28{ 28{
29 struct subchannel *sch = to_subchannel(cdev->dev.parent);
29 char dbf_text[15]; 30 char dbf_text[15];
30 31
31 if (!scsw_is_valid_cstat(&irb->scsw) || 32 if (!scsw_is_valid_cstat(&irb->scsw) ||
@@ -36,10 +37,10 @@ ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
36 "received" 37 "received"
37 " ... device %04x on subchannel 0.%x.%04x, dev_stat " 38 " ... device %04x on subchannel 0.%x.%04x, dev_stat "
38 ": %02X sch_stat : %02X\n", 39 ": %02X sch_stat : %02X\n",
39 cdev->private->dev_id.devno, cdev->private->schid.ssid, 40 cdev->private->dev_id.devno, sch->schid.ssid,
40 cdev->private->schid.sch_no, 41 sch->schid.sch_no,
41 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw)); 42 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw));
42 sprintf(dbf_text, "chk%x", cdev->private->schid.sch_no); 43 sprintf(dbf_text, "chk%x", sch->schid.sch_no);
43 CIO_TRACE_EVENT(0, dbf_text); 44 CIO_TRACE_EVENT(0, dbf_text);
44 CIO_HEX_EVENT(0, irb, sizeof(struct irb)); 45 CIO_HEX_EVENT(0, irb, sizeof(struct irb));
45} 46}
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h
index 8975060af96c..220f49145b2f 100644
--- a/drivers/s390/cio/io_sch.h
+++ b/drivers/s390/cio/io_sch.h
@@ -120,7 +120,6 @@ struct ccw_device_private {
120 int state; /* device state */ 120 int state; /* device state */
121 atomic_t onoff; 121 atomic_t onoff;
122 struct ccw_dev_id dev_id; /* device id */ 122 struct ccw_dev_id dev_id; /* device id */
123 struct subchannel_id schid; /* subchannel number */
124 struct ccw_request req; /* internal I/O request */ 123 struct ccw_request req; /* internal I/O request */
125 int iretry; 124 int iretry;
126 u8 pgid_valid_mask; /* mask of valid PGIDs */ 125 u8 pgid_valid_mask; /* mask of valid PGIDs */
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 4bb5262f7aee..71bf9bded485 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -686,6 +686,15 @@ static void qdio_kick_handler(struct qdio_q *q)
686 q->qdio_error = 0; 686 q->qdio_error = 0;
687} 687}
688 688
689static inline int qdio_tasklet_schedule(struct qdio_q *q)
690{
691 if (likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE)) {
692 tasklet_schedule(&q->tasklet);
693 return 0;
694 }
695 return -EPERM;
696}
697
689static void __qdio_inbound_processing(struct qdio_q *q) 698static void __qdio_inbound_processing(struct qdio_q *q)
690{ 699{
691 qperf_inc(q, tasklet_inbound); 700 qperf_inc(q, tasklet_inbound);
@@ -698,10 +707,8 @@ static void __qdio_inbound_processing(struct qdio_q *q)
698 if (!qdio_inbound_q_done(q)) { 707 if (!qdio_inbound_q_done(q)) {
699 /* means poll time is not yet over */ 708 /* means poll time is not yet over */
700 qperf_inc(q, tasklet_inbound_resched); 709 qperf_inc(q, tasklet_inbound_resched);
701 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) { 710 if (!qdio_tasklet_schedule(q))
702 tasklet_schedule(&q->tasklet);
703 return; 711 return;
704 }
705 } 712 }
706 713
707 qdio_stop_polling(q); 714 qdio_stop_polling(q);
@@ -711,8 +718,7 @@ static void __qdio_inbound_processing(struct qdio_q *q)
711 */ 718 */
712 if (!qdio_inbound_q_done(q)) { 719 if (!qdio_inbound_q_done(q)) {
713 qperf_inc(q, tasklet_inbound_resched2); 720 qperf_inc(q, tasklet_inbound_resched2);
714 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) 721 qdio_tasklet_schedule(q);
715 tasklet_schedule(&q->tasklet);
716 } 722 }
717} 723}
718 724
@@ -869,16 +875,15 @@ static void __qdio_outbound_processing(struct qdio_q *q)
869 * is noticed and outbound_handler is called after some time. 875 * is noticed and outbound_handler is called after some time.
870 */ 876 */
871 if (qdio_outbound_q_done(q)) 877 if (qdio_outbound_q_done(q))
872 del_timer(&q->u.out.timer); 878 del_timer_sync(&q->u.out.timer);
873 else 879 else
874 if (!timer_pending(&q->u.out.timer)) 880 if (!timer_pending(&q->u.out.timer) &&
881 likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE))
875 mod_timer(&q->u.out.timer, jiffies + 10 * HZ); 882 mod_timer(&q->u.out.timer, jiffies + 10 * HZ);
876 return; 883 return;
877 884
878sched: 885sched:
879 if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) 886 qdio_tasklet_schedule(q);
880 return;
881 tasklet_schedule(&q->tasklet);
882} 887}
883 888
884/* outbound tasklet */ 889/* outbound tasklet */
@@ -892,9 +897,7 @@ void qdio_outbound_timer(unsigned long data)
892{ 897{
893 struct qdio_q *q = (struct qdio_q *)data; 898 struct qdio_q *q = (struct qdio_q *)data;
894 899
895 if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) 900 qdio_tasklet_schedule(q);
896 return;
897 tasklet_schedule(&q->tasklet);
898} 901}
899 902
900static inline void qdio_check_outbound_after_thinint(struct qdio_q *q) 903static inline void qdio_check_outbound_after_thinint(struct qdio_q *q)
@@ -907,7 +910,7 @@ static inline void qdio_check_outbound_after_thinint(struct qdio_q *q)
907 910
908 for_each_output_queue(q->irq_ptr, out, i) 911 for_each_output_queue(q->irq_ptr, out, i)
909 if (!qdio_outbound_q_done(out)) 912 if (!qdio_outbound_q_done(out))
910 tasklet_schedule(&out->tasklet); 913 qdio_tasklet_schedule(out);
911} 914}
912 915
913static void __tiqdio_inbound_processing(struct qdio_q *q) 916static void __tiqdio_inbound_processing(struct qdio_q *q)
@@ -929,10 +932,8 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
929 932
930 if (!qdio_inbound_q_done(q)) { 933 if (!qdio_inbound_q_done(q)) {
931 qperf_inc(q, tasklet_inbound_resched); 934 qperf_inc(q, tasklet_inbound_resched);
932 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) { 935 if (!qdio_tasklet_schedule(q))
933 tasklet_schedule(&q->tasklet);
934 return; 936 return;
935 }
936 } 937 }
937 938
938 qdio_stop_polling(q); 939 qdio_stop_polling(q);
@@ -942,8 +943,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
942 */ 943 */
943 if (!qdio_inbound_q_done(q)) { 944 if (!qdio_inbound_q_done(q)) {
944 qperf_inc(q, tasklet_inbound_resched2); 945 qperf_inc(q, tasklet_inbound_resched2);
945 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) 946 qdio_tasklet_schedule(q);
946 tasklet_schedule(&q->tasklet);
947 } 947 }
948} 948}
949 949
@@ -977,7 +977,7 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
977 int i; 977 int i;
978 struct qdio_q *q; 978 struct qdio_q *q;
979 979
980 if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) 980 if (unlikely(irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
981 return; 981 return;
982 982
983 for_each_input_queue(irq_ptr, q, i) { 983 for_each_input_queue(irq_ptr, q, i) {
@@ -1003,7 +1003,7 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
1003 continue; 1003 continue;
1004 if (need_siga_sync(q) && need_siga_sync_out_after_pci(q)) 1004 if (need_siga_sync(q) && need_siga_sync_out_after_pci(q))
1005 qdio_siga_sync_q(q); 1005 qdio_siga_sync_q(q);
1006 tasklet_schedule(&q->tasklet); 1006 qdio_tasklet_schedule(q);
1007 } 1007 }
1008} 1008}
1009 1009
@@ -1066,10 +1066,12 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
1066 struct irb *irb) 1066 struct irb *irb)
1067{ 1067{
1068 struct qdio_irq *irq_ptr = cdev->private->qdio_data; 1068 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1069 struct subchannel_id schid;
1069 int cstat, dstat; 1070 int cstat, dstat;
1070 1071
1071 if (!intparm || !irq_ptr) { 1072 if (!intparm || !irq_ptr) {
1072 DBF_ERROR("qint:%4x", cdev->private->schid.sch_no); 1073 ccw_device_get_schid(cdev, &schid);
1074 DBF_ERROR("qint:%4x", schid.sch_no);
1073 return; 1075 return;
1074 } 1076 }
1075 1077
@@ -1122,12 +1124,14 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
1122int qdio_get_ssqd_desc(struct ccw_device *cdev, 1124int qdio_get_ssqd_desc(struct ccw_device *cdev,
1123 struct qdio_ssqd_desc *data) 1125 struct qdio_ssqd_desc *data)
1124{ 1126{
1127 struct subchannel_id schid;
1125 1128
1126 if (!cdev || !cdev->private) 1129 if (!cdev || !cdev->private)
1127 return -EINVAL; 1130 return -EINVAL;
1128 1131
1129 DBF_EVENT("get ssqd:%4x", cdev->private->schid.sch_no); 1132 ccw_device_get_schid(cdev, &schid);
1130 return qdio_setup_get_ssqd(NULL, &cdev->private->schid, data); 1133 DBF_EVENT("get ssqd:%4x", schid.sch_no);
1134 return qdio_setup_get_ssqd(NULL, &schid, data);
1131} 1135}
1132EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc); 1136EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);
1133 1137
@@ -1141,7 +1145,7 @@ static void qdio_shutdown_queues(struct ccw_device *cdev)
1141 tasklet_kill(&q->tasklet); 1145 tasklet_kill(&q->tasklet);
1142 1146
1143 for_each_output_queue(irq_ptr, q, i) { 1147 for_each_output_queue(irq_ptr, q, i) {
1144 del_timer(&q->u.out.timer); 1148 del_timer_sync(&q->u.out.timer);
1145 tasklet_kill(&q->tasklet); 1149 tasklet_kill(&q->tasklet);
1146 } 1150 }
1147} 1151}
@@ -1154,14 +1158,15 @@ static void qdio_shutdown_queues(struct ccw_device *cdev)
1154int qdio_shutdown(struct ccw_device *cdev, int how) 1158int qdio_shutdown(struct ccw_device *cdev, int how)
1155{ 1159{
1156 struct qdio_irq *irq_ptr = cdev->private->qdio_data; 1160 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1161 struct subchannel_id schid;
1157 int rc; 1162 int rc;
1158 unsigned long flags;
1159 1163
1160 if (!irq_ptr) 1164 if (!irq_ptr)
1161 return -ENODEV; 1165 return -ENODEV;
1162 1166
1163 WARN_ON_ONCE(irqs_disabled()); 1167 WARN_ON_ONCE(irqs_disabled());
1164 DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no); 1168 ccw_device_get_schid(cdev, &schid);
1169 DBF_EVENT("qshutdown:%4x", schid.sch_no);
1165 1170
1166 mutex_lock(&irq_ptr->setup_mutex); 1171 mutex_lock(&irq_ptr->setup_mutex);
1167 /* 1172 /*
@@ -1184,7 +1189,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
1184 qdio_shutdown_debug_entries(irq_ptr); 1189 qdio_shutdown_debug_entries(irq_ptr);
1185 1190
1186 /* cleanup subchannel */ 1191 /* cleanup subchannel */
1187 spin_lock_irqsave(get_ccwdev_lock(cdev), flags); 1192 spin_lock_irq(get_ccwdev_lock(cdev));
1188 1193
1189 if (how & QDIO_FLAG_CLEANUP_USING_CLEAR) 1194 if (how & QDIO_FLAG_CLEANUP_USING_CLEAR)
1190 rc = ccw_device_clear(cdev, QDIO_DOING_CLEANUP); 1195 rc = ccw_device_clear(cdev, QDIO_DOING_CLEANUP);
@@ -1198,12 +1203,12 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
1198 } 1203 }
1199 1204
1200 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP); 1205 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP);
1201 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); 1206 spin_unlock_irq(get_ccwdev_lock(cdev));
1202 wait_event_interruptible_timeout(cdev->private->wait_q, 1207 wait_event_interruptible_timeout(cdev->private->wait_q,
1203 irq_ptr->state == QDIO_IRQ_STATE_INACTIVE || 1208 irq_ptr->state == QDIO_IRQ_STATE_INACTIVE ||
1204 irq_ptr->state == QDIO_IRQ_STATE_ERR, 1209 irq_ptr->state == QDIO_IRQ_STATE_ERR,
1205 10 * HZ); 1210 10 * HZ);
1206 spin_lock_irqsave(get_ccwdev_lock(cdev), flags); 1211 spin_lock_irq(get_ccwdev_lock(cdev));
1207 1212
1208no_cleanup: 1213no_cleanup:
1209 qdio_shutdown_thinint(irq_ptr); 1214 qdio_shutdown_thinint(irq_ptr);
@@ -1211,7 +1216,7 @@ no_cleanup:
1211 /* restore interrupt handler */ 1216 /* restore interrupt handler */
1212 if ((void *)cdev->handler == (void *)qdio_int_handler) 1217 if ((void *)cdev->handler == (void *)qdio_int_handler)
1213 cdev->handler = irq_ptr->orig_handler; 1218 cdev->handler = irq_ptr->orig_handler;
1214 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); 1219 spin_unlock_irq(get_ccwdev_lock(cdev));
1215 1220
1216 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); 1221 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
1217 mutex_unlock(&irq_ptr->setup_mutex); 1222 mutex_unlock(&irq_ptr->setup_mutex);
@@ -1228,11 +1233,13 @@ EXPORT_SYMBOL_GPL(qdio_shutdown);
1228int qdio_free(struct ccw_device *cdev) 1233int qdio_free(struct ccw_device *cdev)
1229{ 1234{
1230 struct qdio_irq *irq_ptr = cdev->private->qdio_data; 1235 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1236 struct subchannel_id schid;
1231 1237
1232 if (!irq_ptr) 1238 if (!irq_ptr)
1233 return -ENODEV; 1239 return -ENODEV;
1234 1240
1235 DBF_EVENT("qfree:%4x", cdev->private->schid.sch_no); 1241 ccw_device_get_schid(cdev, &schid);
1242 DBF_EVENT("qfree:%4x", schid.sch_no);
1236 DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf abandoned"); 1243 DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf abandoned");
1237 mutex_lock(&irq_ptr->setup_mutex); 1244 mutex_lock(&irq_ptr->setup_mutex);
1238 1245
@@ -1251,9 +1258,11 @@ EXPORT_SYMBOL_GPL(qdio_free);
1251 */ 1258 */
1252int qdio_allocate(struct qdio_initialize *init_data) 1259int qdio_allocate(struct qdio_initialize *init_data)
1253{ 1260{
1261 struct subchannel_id schid;
1254 struct qdio_irq *irq_ptr; 1262 struct qdio_irq *irq_ptr;
1255 1263
1256 DBF_EVENT("qallocate:%4x", init_data->cdev->private->schid.sch_no); 1264 ccw_device_get_schid(init_data->cdev, &schid);
1265 DBF_EVENT("qallocate:%4x", schid.sch_no);
1257 1266
1258 if ((init_data->no_input_qs && !init_data->input_handler) || 1267 if ((init_data->no_input_qs && !init_data->input_handler) ||
1259 (init_data->no_output_qs && !init_data->output_handler)) 1268 (init_data->no_output_qs && !init_data->output_handler))
@@ -1331,20 +1340,18 @@ static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
1331 */ 1340 */
1332int qdio_establish(struct qdio_initialize *init_data) 1341int qdio_establish(struct qdio_initialize *init_data)
1333{ 1342{
1334 struct qdio_irq *irq_ptr;
1335 struct ccw_device *cdev = init_data->cdev; 1343 struct ccw_device *cdev = init_data->cdev;
1336 unsigned long saveflags; 1344 struct subchannel_id schid;
1345 struct qdio_irq *irq_ptr;
1337 int rc; 1346 int rc;
1338 1347
1339 DBF_EVENT("qestablish:%4x", cdev->private->schid.sch_no); 1348 ccw_device_get_schid(cdev, &schid);
1349 DBF_EVENT("qestablish:%4x", schid.sch_no);
1340 1350
1341 irq_ptr = cdev->private->qdio_data; 1351 irq_ptr = cdev->private->qdio_data;
1342 if (!irq_ptr) 1352 if (!irq_ptr)
1343 return -ENODEV; 1353 return -ENODEV;
1344 1354
1345 if (cdev->private->state != DEV_STATE_ONLINE)
1346 return -EINVAL;
1347
1348 mutex_lock(&irq_ptr->setup_mutex); 1355 mutex_lock(&irq_ptr->setup_mutex);
1349 qdio_setup_irq(init_data); 1356 qdio_setup_irq(init_data);
1350 1357
@@ -1361,17 +1368,14 @@ int qdio_establish(struct qdio_initialize *init_data)
1361 irq_ptr->ccw.count = irq_ptr->equeue.count; 1368 irq_ptr->ccw.count = irq_ptr->equeue.count;
1362 irq_ptr->ccw.cda = (u32)((addr_t)irq_ptr->qdr); 1369 irq_ptr->ccw.cda = (u32)((addr_t)irq_ptr->qdr);
1363 1370
1364 spin_lock_irqsave(get_ccwdev_lock(cdev), saveflags); 1371 spin_lock_irq(get_ccwdev_lock(cdev));
1365 ccw_device_set_options_mask(cdev, 0); 1372 ccw_device_set_options_mask(cdev, 0);
1366 1373
1367 rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ESTABLISH, 0, 0); 1374 rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ESTABLISH, 0, 0);
1375 spin_unlock_irq(get_ccwdev_lock(cdev));
1368 if (rc) { 1376 if (rc) {
1369 DBF_ERROR("%4x est IO ERR", irq_ptr->schid.sch_no); 1377 DBF_ERROR("%4x est IO ERR", irq_ptr->schid.sch_no);
1370 DBF_ERROR("rc:%4x", rc); 1378 DBF_ERROR("rc:%4x", rc);
1371 }
1372 spin_unlock_irqrestore(get_ccwdev_lock(cdev), saveflags);
1373
1374 if (rc) {
1375 mutex_unlock(&irq_ptr->setup_mutex); 1379 mutex_unlock(&irq_ptr->setup_mutex);
1376 qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); 1380 qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
1377 return rc; 1381 return rc;
@@ -1407,19 +1411,17 @@ EXPORT_SYMBOL_GPL(qdio_establish);
1407 */ 1411 */
1408int qdio_activate(struct ccw_device *cdev) 1412int qdio_activate(struct ccw_device *cdev)
1409{ 1413{
1414 struct subchannel_id schid;
1410 struct qdio_irq *irq_ptr; 1415 struct qdio_irq *irq_ptr;
1411 int rc; 1416 int rc;
1412 unsigned long saveflags;
1413 1417
1414 DBF_EVENT("qactivate:%4x", cdev->private->schid.sch_no); 1418 ccw_device_get_schid(cdev, &schid);
1419 DBF_EVENT("qactivate:%4x", schid.sch_no);
1415 1420
1416 irq_ptr = cdev->private->qdio_data; 1421 irq_ptr = cdev->private->qdio_data;
1417 if (!irq_ptr) 1422 if (!irq_ptr)
1418 return -ENODEV; 1423 return -ENODEV;
1419 1424
1420 if (cdev->private->state != DEV_STATE_ONLINE)
1421 return -EINVAL;
1422
1423 mutex_lock(&irq_ptr->setup_mutex); 1425 mutex_lock(&irq_ptr->setup_mutex);
1424 if (irq_ptr->state == QDIO_IRQ_STATE_INACTIVE) { 1426 if (irq_ptr->state == QDIO_IRQ_STATE_INACTIVE) {
1425 rc = -EBUSY; 1427 rc = -EBUSY;
@@ -1431,19 +1433,17 @@ int qdio_activate(struct ccw_device *cdev)
1431 irq_ptr->ccw.count = irq_ptr->aqueue.count; 1433 irq_ptr->ccw.count = irq_ptr->aqueue.count;
1432 irq_ptr->ccw.cda = 0; 1434 irq_ptr->ccw.cda = 0;
1433 1435
1434 spin_lock_irqsave(get_ccwdev_lock(cdev), saveflags); 1436 spin_lock_irq(get_ccwdev_lock(cdev));
1435 ccw_device_set_options(cdev, CCWDEV_REPORT_ALL); 1437 ccw_device_set_options(cdev, CCWDEV_REPORT_ALL);
1436 1438
1437 rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ACTIVATE, 1439 rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ACTIVATE,
1438 0, DOIO_DENY_PREFETCH); 1440 0, DOIO_DENY_PREFETCH);
1441 spin_unlock_irq(get_ccwdev_lock(cdev));
1439 if (rc) { 1442 if (rc) {
1440 DBF_ERROR("%4x act IO ERR", irq_ptr->schid.sch_no); 1443 DBF_ERROR("%4x act IO ERR", irq_ptr->schid.sch_no);
1441 DBF_ERROR("rc:%4x", rc); 1444 DBF_ERROR("rc:%4x", rc);
1442 }
1443 spin_unlock_irqrestore(get_ccwdev_lock(cdev), saveflags);
1444
1445 if (rc)
1446 goto out; 1445 goto out;
1446 }
1447 1447
1448 if (is_thinint_irq(irq_ptr)) 1448 if (is_thinint_irq(irq_ptr))
1449 tiqdio_add_input_queues(irq_ptr); 1449 tiqdio_add_input_queues(irq_ptr);
@@ -1585,10 +1585,11 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1585 1585
1586 /* in case of SIGA errors we must process the error immediately */ 1586 /* in case of SIGA errors we must process the error immediately */
1587 if (used >= q->u.out.scan_threshold || rc) 1587 if (used >= q->u.out.scan_threshold || rc)
1588 tasklet_schedule(&q->tasklet); 1588 qdio_tasklet_schedule(q);
1589 else 1589 else
1590 /* free the SBALs in case of no further traffic */ 1590 /* free the SBALs in case of no further traffic */
1591 if (!timer_pending(&q->u.out.timer)) 1591 if (!timer_pending(&q->u.out.timer) &&
1592 likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE))
1592 mod_timer(&q->u.out.timer, jiffies + HZ); 1593 mod_timer(&q->u.out.timer, jiffies + HZ);
1593 return rc; 1594 return rc;
1594} 1595}