summaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/ap_bus.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-11 09:16:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-11 09:16:39 -0700
commit89af571ca633ada14d17746519a179553a732d31 (patch)
tree7d5486cc43b4ce4c258cb2fcfc449e6a94cdc33d /drivers/s390/crypto/ap_bus.c
parent1b195b170da6d75abafa290deeb8863dc8a4d79b (diff)
parent59e36927ee08f3bf06d8d14597e57389bf1b41dc (diff)
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (54 commits) [S390] tape: Use pr_xxx instead of dev_xxx in shared driver code [S390] Wire up page fault events for software perf counters. [S390] Remove smp_cpu_not_running. [S390] Get rid of cpuid.h header file. [S390] Limit cpu detection to 256 physical cpus. [S390] tape: Fix device online messages [S390] Enable guest page hinting by default. [S390] use generic scatterlist.h [S390] s390dbf: Add description for usage of "%s" in sprintf events [S390] Initialize __LC_THREAD_INFO early. [S390] fix recursive locking on page_table_lock [S390] kvm: use console_initcall() to initialize s390 virtio console [S390] tape: reversed order of labels [S390] hypfs: Use "%u" instead of "%d" for unsigned ints in snprintf [S390] kernel: Print an error message if kernel NSS cannot be defined [S390] zcrypt: Free ap_device if dev_set_name fails. [S390] zcrypt: Use spin_lock_bh in suspend callback [S390] xpram: Remove checksum validation for suspend/resume [S390] vmur: Invalid allocation sequence for vmur class [S390] hypfs: remove useless variable qname ...
Diffstat (limited to 'drivers/s390/crypto/ap_bus.c')
-rw-r--r--drivers/s390/crypto/ap_bus.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index ed3dcdea7fe..090b32a339c 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -648,7 +648,9 @@ static int ap_bus_suspend(struct device *dev, pm_message_t state)
/* Poll on the device until all requests are finished. */
do {
flags = 0;
+ spin_lock_bh(&ap_dev->lock);
__ap_poll_device(ap_dev, &flags);
+ spin_unlock_bh(&ap_dev->lock);
} while ((flags & 1) || (flags & 2));
ap_device_remove(dev);
@@ -1109,12 +1111,15 @@ static void ap_scan_bus(struct work_struct *unused)
ap_dev->device.bus = &ap_bus_type;
ap_dev->device.parent = ap_root_device;
- dev_set_name(&ap_dev->device, "card%02x",
- AP_QID_DEVICE(ap_dev->qid));
+ if (dev_set_name(&ap_dev->device, "card%02x",
+ AP_QID_DEVICE(ap_dev->qid))) {
+ kfree(ap_dev);
+ continue;
+ }
ap_dev->device.release = ap_device_release;
rc = device_register(&ap_dev->device);
if (rc) {
- kfree(ap_dev);
+ put_device(&ap_dev->device);
continue;
}
/* Add device attributes. */
@@ -1407,14 +1412,12 @@ static void ap_reset(struct ap_device *ap_dev)
static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)
{
- spin_lock(&ap_dev->lock);
if (!ap_dev->unregistered) {
if (ap_poll_queue(ap_dev, flags))
ap_dev->unregistered = 1;
if (ap_dev->reset == AP_RESET_DO)
ap_reset(ap_dev);
}
- spin_unlock(&ap_dev->lock);
return 0;
}
@@ -1441,7 +1444,9 @@ static void ap_poll_all(unsigned long dummy)
flags = 0;
spin_lock(&ap_device_list_lock);
list_for_each_entry(ap_dev, &ap_device_list, list) {
+ spin_lock(&ap_dev->lock);
__ap_poll_device(ap_dev, &flags);
+ spin_unlock(&ap_dev->lock);
}
spin_unlock(&ap_device_list_lock);
} while (flags & 1);
@@ -1487,7 +1492,9 @@ static int ap_poll_thread(void *data)
flags = 0;
spin_lock_bh(&ap_device_list_lock);
list_for_each_entry(ap_dev, &ap_device_list, list) {
+ spin_lock(&ap_dev->lock);
__ap_poll_device(ap_dev, &flags);
+ spin_unlock(&ap_dev->lock);
}
spin_unlock_bh(&ap_device_list_lock);
}