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.
This commit is contained in:
commit
6288c33866
5 changed files with 43 additions and 64 deletions
|
@ -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 */
|
||||||
* 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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
(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)
|
||||||
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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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,
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue