Commit 6288c338 authored by Linus Torvalds's avatar Linus Torvalds

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.
parents 8b66a454 e675c0d2
...@@ -167,7 +167,7 @@ static int __kprobes swap_instruction(void *aref) ...@@ -167,7 +167,7 @@ static int __kprobes swap_instruction(void *aref)
* shall not cross any page boundaries (vmalloc area!) when writing * shall not cross any page boundaries (vmalloc area!) when writing
* the new instruction. * the new instruction.
*/ */
addr = (u32 *)ALIGN((unsigned long)args->ptr, 4); addr = (u32 *)((unsigned long)args->ptr & -4UL);
if ((unsigned long)args->ptr & 2) if ((unsigned long)args->ptr & 2)
instr = ((*addr) & 0xffff0000) | args->new; instr = ((*addr) & 0xffff0000) | args->new;
else else
......
...@@ -65,7 +65,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */ ...@@ -65,7 +65,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
* resulting condition code and DIAG return code. */ * resulting condition code and DIAG return code. */
static inline int dia250(void *iob, int cmd) static inline int dia250(void *iob, int cmd)
{ {
register unsigned long reg0 asm ("0") = (unsigned long) iob; register unsigned long reg2 asm ("2") = (unsigned long) iob;
typedef union { typedef union {
struct dasd_diag_init_io init_io; struct dasd_diag_init_io init_io;
struct dasd_diag_rw_io rw_io; struct dasd_diag_rw_io rw_io;
...@@ -74,15 +74,15 @@ static inline int dia250(void *iob, int cmd) ...@@ -74,15 +74,15 @@ static inline int dia250(void *iob, int cmd)
rc = 3; rc = 3;
asm volatile( asm volatile(
" diag 0,%2,0x250\n" " diag 2,%2,0x250\n"
"0: ipm %0\n" "0: ipm %0\n"
" srl %0,28\n" " srl %0,28\n"
" or %0,1\n" " or %0,3\n"
"1:\n" "1:\n"
EX_TABLE(0b,1b) EX_TABLE(0b,1b)
: "+d" (rc), "=m" (*(addr_type *) iob) : "+d" (rc), "=m" (*(addr_type *) iob)
: "d" (cmd), "d" (reg0), "m" (*(addr_type *) iob) : "d" (cmd), "d" (reg2), "m" (*(addr_type *) iob)
: "1", "cc"); : "3", "cc");
return rc; return rc;
} }
......
...@@ -263,7 +263,11 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb) ...@@ -263,7 +263,11 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb)
cdev_irb->scsw.cpa = irb->scsw.cpa; cdev_irb->scsw.cpa = irb->scsw.cpa;
/* Accumulate device status, but not the device busy flag. */ /* Accumulate device status, but not the device busy flag. */
cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY; cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY;
cdev_irb->scsw.dstat |= irb->scsw.dstat; /* dstat is not always valid. */
if (irb->scsw.stctl &
(SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS
| SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS))
cdev_irb->scsw.dstat |= irb->scsw.dstat;
/* Accumulate subchannel status. */ /* Accumulate subchannel status. */
cdev_irb->scsw.cstat |= irb->scsw.cstat; cdev_irb->scsw.cstat |= irb->scsw.cstat;
/* Copy residual count if it is valid. */ /* Copy residual count if it is valid. */
......
...@@ -505,6 +505,9 @@ static int ap_device_remove(struct device *dev) ...@@ -505,6 +505,9 @@ static int ap_device_remove(struct device *dev)
spin_lock_bh(&ap_device_lock); spin_lock_bh(&ap_device_lock);
list_del_init(&ap_dev->list); list_del_init(&ap_dev->list);
spin_unlock_bh(&ap_device_lock); spin_unlock_bh(&ap_device_lock);
spin_lock_bh(&ap_dev->lock);
atomic_sub(ap_dev->queue_count, &ap_poll_requests);
spin_unlock_bh(&ap_dev->lock);
return 0; return 0;
} }
...@@ -757,10 +760,16 @@ static void ap_scan_bus(struct work_struct *unused) ...@@ -757,10 +760,16 @@ static void ap_scan_bus(struct work_struct *unused)
(void *)(unsigned long)qid, (void *)(unsigned long)qid,
__ap_scan_bus); __ap_scan_bus);
rc = ap_query_queue(qid, &queue_depth, &device_type); rc = ap_query_queue(qid, &queue_depth, &device_type);
if (dev && rc) { if (dev) {
put_device(dev); ap_dev = to_ap_dev(dev);
device_unregister(dev); spin_lock_bh(&ap_dev->lock);
continue; if (rc || ap_dev->unregistered) {
spin_unlock_bh(&ap_dev->lock);
put_device(dev);
device_unregister(dev);
continue;
} else
spin_unlock_bh(&ap_dev->lock);
} }
if (dev) { if (dev) {
put_device(dev); put_device(dev);
...@@ -861,6 +870,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) ...@@ -861,6 +870,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
case AP_RESPONSE_NO_PENDING_REPLY: case AP_RESPONSE_NO_PENDING_REPLY:
if (status.queue_empty) { if (status.queue_empty) {
/* The card shouldn't forget requests but who knows. */ /* The card shouldn't forget requests but who knows. */
atomic_sub(ap_dev->queue_count, &ap_poll_requests);
ap_dev->queue_count = 0; ap_dev->queue_count = 0;
list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
ap_dev->requestq_count += ap_dev->pendingq_count; 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,7 +1004,7 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
ap_dev->unregistered = 1; ap_dev->unregistered = 1;
} else { } else {
ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
rc = 0; rc = -ENODEV;
} }
spin_unlock_bh(&ap_dev->lock); spin_unlock_bh(&ap_dev->lock);
if (rc == -ENODEV) if (rc == -ENODEV)
...@@ -1044,18 +1054,12 @@ static void ap_poll_timeout(unsigned long unused) ...@@ -1044,18 +1054,12 @@ static void ap_poll_timeout(unsigned long unused)
*/ */
static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags) static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
{ {
int rc;
spin_lock(&ap_dev->lock); spin_lock(&ap_dev->lock);
if (!ap_dev->unregistered) { if (!ap_dev->unregistered) {
rc = ap_poll_queue(ap_dev, flags); if (ap_poll_queue(ap_dev, flags))
if (rc)
ap_dev->unregistered = 1; ap_dev->unregistered = 1;
} else }
rc = 0;
spin_unlock(&ap_dev->lock); spin_unlock(&ap_dev->lock);
if (rc)
device_unregister(&ap_dev->device);
return 0; return 0;
} }
......
...@@ -121,50 +121,21 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, ...@@ -121,50 +121,21 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len, unsigned short proto, unsigned short len, unsigned short proto,
__wsum sum) __wsum sum)
{ {
#ifndef __s390x__ __u32 csum = (__force __u32)sum;
asm volatile(
" alr %0,%1\n" /* sum += saddr */ csum += (__force __u32)saddr;
" brc 12,0f\n" if (csum < (__force __u32)saddr)
" ahi %0,1\n" /* add carry */ csum++;
"0:"
: "+&d" (sum) : "d" (saddr) : "cc"); csum += (__force __u32)daddr;
asm volatile( if (csum < (__force __u32)daddr)
" alr %0,%1\n" /* sum += daddr */ csum++;
" brc 12,1f\n"
" ahi %0,1\n" /* add carry */ csum += len + proto;
"1:" if (csum < len + proto)
: "+&d" (sum) : "d" (daddr) : "cc"); csum++;
asm volatile(
" alr %0,%1\n" /* sum += len + proto */ return (__force __wsum)csum;
" brc 12,2f\n"
" ahi %0,1\n" /* add carry */
"2:"
: "+&d" (sum)
: "d" (len + proto)
: "cc");
#else /* __s390x__ */
asm volatile(
" lgfr %0,%0\n"
" algr %0,%1\n" /* sum += saddr */
" brc 12,0f\n"
" aghi %0,1\n" /* add carry */
"0: algr %0,%2\n" /* sum += daddr */
" brc 12,1f\n"
" aghi %0,1\n" /* add carry */
"1: algfr %0,%3\n" /* sum += len + proto */
" brc 12,2f\n"
" aghi %0,1\n" /* add carry */
"2: srlg 0,%0,32\n"
" alr %0,0\n" /* fold to 32 bits */
" brc 12,3f\n"
" ahi %0,1\n" /* add carry */
"3: llgfr %0,%0"
: "+&d" (sum)
: "d" (saddr), "d" (daddr),
"d" (len + proto)
: "cc", "0");
#endif /* __s390x__ */
return sum;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment