diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-26 17:45:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-26 17:45:56 -0400 |
commit | 6288c338661cc26ea66e7818b0d3862ee163fd1d (patch) | |
tree | 49fbca961371119f8c0d476063fa3c7c0ab7124b /drivers | |
parent | 8b66a454bf09958b474d12981996287d19aa462d (diff) | |
parent | e675c0d2bf523a80098c843603ccc091d3720fb4 (diff) |
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6:
[S390] zcrypt: Fix ap_poll_requests counter in lost requests error path.
[S390] zcrypt: Fix possible dead lock in AP bus module.
[S390] cio: Device status validity.
[S390] kprobes: Align probe address.
[S390] Fix TCP/UDP pseudo header checksum computation.
[S390] dasd: Work around gcc bug.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/block/dasd_diag.c | 10 | ||||
-rw-r--r-- | drivers/s390/cio/device_status.c | 6 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 30 |
3 files changed, 27 insertions, 19 deletions
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index ab782bb46a..e810e4a44e 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -65,7 +65,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */ | |||
65 | * resulting condition code and DIAG return code. */ | 65 | * resulting condition code and DIAG return code. */ |
66 | static inline int dia250(void *iob, int cmd) | 66 | static inline int dia250(void *iob, int cmd) |
67 | { | 67 | { |
68 | register unsigned long reg0 asm ("0") = (unsigned long) iob; | 68 | register unsigned long reg2 asm ("2") = (unsigned long) iob; |
69 | typedef union { | 69 | typedef union { |
70 | struct dasd_diag_init_io init_io; | 70 | struct dasd_diag_init_io init_io; |
71 | struct dasd_diag_rw_io rw_io; | 71 | struct dasd_diag_rw_io rw_io; |
@@ -74,15 +74,15 @@ static inline int dia250(void *iob, int cmd) | |||
74 | 74 | ||
75 | rc = 3; | 75 | rc = 3; |
76 | asm volatile( | 76 | asm volatile( |
77 | " diag 0,%2,0x250\n" | 77 | " diag 2,%2,0x250\n" |
78 | "0: ipm %0\n" | 78 | "0: ipm %0\n" |
79 | " srl %0,28\n" | 79 | " srl %0,28\n" |
80 | " or %0,1\n" | 80 | " or %0,3\n" |
81 | "1:\n" | 81 | "1:\n" |
82 | EX_TABLE(0b,1b) | 82 | EX_TABLE(0b,1b) |
83 | : "+d" (rc), "=m" (*(addr_type *) iob) | 83 | : "+d" (rc), "=m" (*(addr_type *) iob) |
84 | : "d" (cmd), "d" (reg0), "m" (*(addr_type *) iob) | 84 | : "d" (cmd), "d" (reg2), "m" (*(addr_type *) iob) |
85 | : "1", "cc"); | 85 | : "3", "cc"); |
86 | return rc; | 86 | return rc; |
87 | } | 87 | } |
88 | 88 | ||
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c index 6b1caea622..25d99bd280 100644 --- a/drivers/s390/cio/device_status.c +++ b/drivers/s390/cio/device_status.c | |||
@@ -263,7 +263,11 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb) | |||
263 | cdev_irb->scsw.cpa = irb->scsw.cpa; | 263 | cdev_irb->scsw.cpa = irb->scsw.cpa; |
264 | /* Accumulate device status, but not the device busy flag. */ | 264 | /* Accumulate device status, but not the device busy flag. */ |
265 | cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY; | 265 | cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY; |
266 | cdev_irb->scsw.dstat |= irb->scsw.dstat; | 266 | /* dstat is not always valid. */ |
267 | if (irb->scsw.stctl & | ||
268 | (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS | ||
269 | | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS)) | ||
270 | cdev_irb->scsw.dstat |= irb->scsw.dstat; | ||
267 | /* Accumulate subchannel status. */ | 271 | /* Accumulate subchannel status. */ |
268 | cdev_irb->scsw.cstat |= irb->scsw.cstat; | 272 | cdev_irb->scsw.cstat |= irb->scsw.cstat; |
269 | /* Copy residual count if it is valid. */ | 273 | /* Copy residual count if it is valid. */ |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 181b51772b..bf37cdf43f 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -505,6 +505,9 @@ static int ap_device_remove(struct device *dev) | |||
505 | spin_lock_bh(&ap_device_lock); | 505 | spin_lock_bh(&ap_device_lock); |
506 | list_del_init(&ap_dev->list); | 506 | list_del_init(&ap_dev->list); |
507 | spin_unlock_bh(&ap_device_lock); | 507 | spin_unlock_bh(&ap_device_lock); |
508 | spin_lock_bh(&ap_dev->lock); | ||
509 | atomic_sub(ap_dev->queue_count, &ap_poll_requests); | ||
510 | spin_unlock_bh(&ap_dev->lock); | ||
508 | return 0; | 511 | return 0; |
509 | } | 512 | } |
510 | 513 | ||
@@ -757,10 +760,16 @@ static void ap_scan_bus(struct work_struct *unused) | |||
757 | (void *)(unsigned long)qid, | 760 | (void *)(unsigned long)qid, |
758 | __ap_scan_bus); | 761 | __ap_scan_bus); |
759 | rc = ap_query_queue(qid, &queue_depth, &device_type); | 762 | rc = ap_query_queue(qid, &queue_depth, &device_type); |
760 | if (dev && rc) { | 763 | if (dev) { |
761 | put_device(dev); | 764 | ap_dev = to_ap_dev(dev); |
762 | device_unregister(dev); | 765 | spin_lock_bh(&ap_dev->lock); |
763 | continue; | 766 | if (rc || ap_dev->unregistered) { |
767 | spin_unlock_bh(&ap_dev->lock); | ||
768 | put_device(dev); | ||
769 | device_unregister(dev); | ||
770 | continue; | ||
771 | } else | ||
772 | spin_unlock_bh(&ap_dev->lock); | ||
764 | } | 773 | } |
765 | if (dev) { | 774 | if (dev) { |
766 | put_device(dev); | 775 | put_device(dev); |
@@ -861,6 +870,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) | |||
861 | case AP_RESPONSE_NO_PENDING_REPLY: | 870 | case AP_RESPONSE_NO_PENDING_REPLY: |
862 | if (status.queue_empty) { | 871 | if (status.queue_empty) { |
863 | /* The card shouldn't forget requests but who knows. */ | 872 | /* The card shouldn't forget requests but who knows. */ |
873 | atomic_sub(ap_dev->queue_count, &ap_poll_requests); | ||
864 | ap_dev->queue_count = 0; | 874 | ap_dev->queue_count = 0; |
865 | list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); | 875 | list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); |
866 | ap_dev->requestq_count += ap_dev->pendingq_count; | 876 | ap_dev->requestq_count += ap_dev->pendingq_count; |
@@ -994,7 +1004,7 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg) | |||
994 | ap_dev->unregistered = 1; | 1004 | ap_dev->unregistered = 1; |
995 | } else { | 1005 | } else { |
996 | ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); | 1006 | ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); |
997 | rc = 0; | 1007 | rc = -ENODEV; |
998 | } | 1008 | } |
999 | spin_unlock_bh(&ap_dev->lock); | 1009 | spin_unlock_bh(&ap_dev->lock); |
1000 | if (rc == -ENODEV) | 1010 | if (rc == -ENODEV) |
@@ -1044,18 +1054,12 @@ static void ap_poll_timeout(unsigned long unused) | |||
1044 | */ | 1054 | */ |
1045 | static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags) | 1055 | static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags) |
1046 | { | 1056 | { |
1047 | int rc; | ||
1048 | |||
1049 | spin_lock(&ap_dev->lock); | 1057 | spin_lock(&ap_dev->lock); |
1050 | if (!ap_dev->unregistered) { | 1058 | if (!ap_dev->unregistered) { |
1051 | rc = ap_poll_queue(ap_dev, flags); | 1059 | if (ap_poll_queue(ap_dev, flags)) |
1052 | if (rc) | ||
1053 | ap_dev->unregistered = 1; | 1060 | ap_dev->unregistered = 1; |
1054 | } else | 1061 | } |
1055 | rc = 0; | ||
1056 | spin_unlock(&ap_dev->lock); | 1062 | spin_unlock(&ap_dev->lock); |
1057 | if (rc) | ||
1058 | device_unregister(&ap_dev->device); | ||
1059 | return 0; | 1063 | return 0; |
1060 | } | 1064 | } |
1061 | 1065 | ||