git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Pull asus into release branch
[pandora-kernel.git]
/
drivers
/
s390
/
crypto
/
ap_bus.c
diff --git
a/drivers/s390/crypto/ap_bus.c
b/drivers/s390/crypto/ap_bus.c
index
ad60afe
..
bf37cdf
100644
(file)
--- a/
drivers/s390/crypto/ap_bus.c
+++ b/
drivers/s390/crypto/ap_bus.c
@@
-65,6
+65,8
@@
module_param_named(poll_thread, ap_thread_flag, int, 0000);
MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 1 (on).");
static struct device *ap_root_device = NULL;
MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 1 (on).");
static struct device *ap_root_device = NULL;
+static DEFINE_SPINLOCK(ap_device_lock);
+static LIST_HEAD(ap_device_list);
/**
* Workqueue & timer for bus rescan.
/**
* Workqueue & timer for bus rescan.
@@
-457,6
+459,9
@@
static int ap_device_probe(struct device *dev)
int rc;
ap_dev->drv = ap_drv;
int rc;
ap_dev->drv = ap_drv;
+ spin_lock_bh(&ap_device_lock);
+ list_add(&ap_dev->list, &ap_device_list);
+ spin_unlock_bh(&ap_device_lock);
rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
return rc;
}
rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
return rc;
}
@@
-465,7
+470,7
@@
static int ap_device_probe(struct device *dev)
* Flush all requests from the request/pending queue of an AP device.
* @ap_dev: pointer to the AP device.
*/
* Flush all requests from the request/pending queue of an AP device.
* @ap_dev: pointer to the AP device.
*/
-static
inline
void __ap_flush_queue(struct ap_device *ap_dev)
+static void __ap_flush_queue(struct ap_device *ap_dev)
{
struct ap_message *ap_msg, *next;
{
struct ap_message *ap_msg, *next;
@@
-497,6
+502,12
@@
static int ap_device_remove(struct device *dev)
ap_flush_queue(ap_dev);
if (ap_drv->remove)
ap_drv->remove(ap_dev);
ap_flush_queue(ap_dev);
if (ap_drv->remove)
ap_drv->remove(ap_dev);
+ spin_lock_bh(&ap_device_lock);
+ list_del_init(&ap_dev->list);
+ 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;
}
@@
-587,7
+598,7
@@
static struct bus_attribute *const ap_bus_attrs[] = {
/**
* Pick one of the 16 ap domains.
*/
/**
* Pick one of the 16 ap domains.
*/
-static in
line in
t ap_select_domain(void)
+static int ap_select_domain(void)
{
int queue_depth, device_type, count, max_count, best_domain;
int rc, i, j;
{
int queue_depth, device_type, count, max_count, best_domain;
int rc, i, j;
@@
-749,10
+760,16
@@
static void ap_scan_bus(struct work_struct *unused)
(void *)(unsigned long)qid,
__ap_scan_bus);
rc = ap_query_queue(qid, &queue_depth, &device_type);
(void *)(unsigned long)qid,
__ap_scan_bus);
rc = ap_query_queue(qid, &queue_depth, &device_type);
- if (dev && rc) {
- put_device(dev);
- device_unregister(dev);
- continue;
+ if (dev) {
+ ap_dev = to_ap_dev(dev);
+ spin_lock_bh(&ap_dev->lock);
+ 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) {
put_device(dev);
}
if (dev) {
put_device(dev);
@@
-772,6
+789,7
@@
static void ap_scan_bus(struct work_struct *unused)
spin_lock_init(&ap_dev->lock);
INIT_LIST_HEAD(&ap_dev->pendingq);
INIT_LIST_HEAD(&ap_dev->requestq);
spin_lock_init(&ap_dev->lock);
INIT_LIST_HEAD(&ap_dev->pendingq);
INIT_LIST_HEAD(&ap_dev->requestq);
+ INIT_LIST_HEAD(&ap_dev->list);
if (device_type == 0)
ap_probe_device_type(ap_dev);
else
if (device_type == 0)
ap_probe_device_type(ap_dev);
else
@@
-825,7
+843,7
@@
static inline void ap_schedule_poll_timer(void)
* required, bit 2^1 is set if the poll timer needs to get armed
* Returns 0 if the device is still present, -ENODEV if not.
*/
* required, bit 2^1 is set if the poll timer needs to get armed
* Returns 0 if the device is still present, -ENODEV if not.
*/
-static in
line in
t ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
+static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
{
struct ap_queue_status status;
struct ap_message *ap_msg;
{
struct ap_queue_status status;
struct ap_message *ap_msg;
@@
-852,6
+870,7
@@
static inline int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
case AP_RESPONSE_NO_PENDING_REPLY:
if (status.queue_empty) {
/* The card shouldn't forget requests but who knows. */
case AP_RESPONSE_NO_PENDING_REPLY:
if (status.queue_empty) {
/* The card shouldn't forget requests but who knows. */
+ atomic_sub(ap_dev->queue_count, &ap_poll_requests);
ap_dev->queue_count = 0;
list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
ap_dev->requestq_count += ap_dev->pendingq_count;
ap_dev->queue_count = 0;
list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
ap_dev->requestq_count += ap_dev->pendingq_count;
@@
-872,7
+891,7
@@
static inline int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
* required, bit 2^1 is set if the poll timer needs to get armed
* Returns 0 if the device is still present, -ENODEV if not.
*/
* required, bit 2^1 is set if the poll timer needs to get armed
* Returns 0 if the device is still present, -ENODEV if not.
*/
-static in
line in
t ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
+static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
{
struct ap_queue_status status;
struct ap_message *ap_msg;
{
struct ap_queue_status status;
struct ap_message *ap_msg;
@@
-985,7
+1004,7
@@
void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
ap_dev->unregistered = 1;
} else {
ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
ap_dev->unregistered = 1;
} else {
ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
- rc =
0
;
+ rc =
-ENODEV
;
}
spin_unlock_bh(&ap_dev->lock);
if (rc == -ENODEV)
}
spin_unlock_bh(&ap_dev->lock);
if (rc == -ENODEV)
@@
-1033,31
+1052,29
@@
static void ap_poll_timeout(unsigned long unused)
* polling until bit 2^0 of the control flags is not set. If bit 2^1
* of the control flags has been set arm the poll timer.
*/
* polling until bit 2^0 of the control flags is not set. If bit 2^1
* of the control flags has been set arm the poll timer.
*/
-static int __ap_poll_all(struct
device *dev, void *data
)
+static int __ap_poll_all(struct
ap_device *ap_dev, unsigned long *flags
)
{
{
- struct ap_device *ap_dev = to_ap_dev(dev);
- int rc;
-
spin_lock(&ap_dev->lock);
if (!ap_dev->unregistered) {
spin_lock(&ap_dev->lock);
if (!ap_dev->unregistered) {
- rc = ap_poll_queue(to_ap_dev(dev), (unsigned long *) data);
- if (rc)
+ if (ap_poll_queue(ap_dev, flags))
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;
}
static void ap_poll_all(unsigned long dummy)
{
unsigned long flags;
return 0;
}
static void ap_poll_all(unsigned long dummy)
{
unsigned long flags;
+ struct ap_device *ap_dev;
do {
flags = 0;
do {
flags = 0;
- bus_for_each_dev(&ap_bus_type, NULL, &flags, __ap_poll_all);
+ spin_lock(&ap_device_lock);
+ list_for_each_entry(ap_dev, &ap_device_list, list) {
+ __ap_poll_all(ap_dev, &flags);
+ }
+ spin_unlock(&ap_device_lock);
} while (flags & 1);
if (flags & 2)
ap_schedule_poll_timer();
} while (flags & 1);
if (flags & 2)
ap_schedule_poll_timer();
@@
-1075,6
+1092,7
@@
static int ap_poll_thread(void *data)
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
int requests;
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
int requests;
+ struct ap_device *ap_dev;
set_user_nice(current, 19);
while (1) {
set_user_nice(current, 19);
while (1) {
@@
-1092,10
+1110,12
@@
static int ap_poll_thread(void *data)
set_current_state(TASK_RUNNING);
remove_wait_queue(&ap_poll_wait, &wait);
set_current_state(TASK_RUNNING);
remove_wait_queue(&ap_poll_wait, &wait);
- local_bh_disable();
flags = 0;
flags = 0;
- bus_for_each_dev(&ap_bus_type, NULL, &flags, __ap_poll_all);
- local_bh_enable();
+ spin_lock_bh(&ap_device_lock);
+ list_for_each_entry(ap_dev, &ap_device_list, list) {
+ __ap_poll_all(ap_dev, &flags);
+ }
+ spin_unlock_bh(&ap_device_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&ap_poll_wait, &wait);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&ap_poll_wait, &wait);
@@
-1129,7
+1149,15
@@
static void ap_poll_thread_stop(void)
mutex_unlock(&ap_poll_thread_mutex);
}
mutex_unlock(&ap_poll_thread_mutex);
}
-static void ap_reset(void)
+static void ap_reset_domain(void)
+{
+ int i;
+
+ for (i = 0; i < AP_DEVICES; i++)
+ ap_reset_queue(AP_MKQID(i, ap_domain_index));
+}
+
+static void ap_reset_all(void)
{
int i, j;
{
int i, j;
@@
-1139,7
+1167,7
@@
static void ap_reset(void)
}
static struct reset_call ap_reset_call = {
}
static struct reset_call ap_reset_call = {
- .fn = ap_reset,
+ .fn = ap_reset
_all
,
};
/**
};
/**
@@
-1229,10
+1257,12
@@
void ap_module_exit(void)
int i;
struct device *dev;
int i;
struct device *dev;
+ ap_reset_domain();
ap_poll_thread_stop();
del_timer_sync(&ap_config_timer);
del_timer_sync(&ap_poll_timer);
destroy_workqueue(ap_work_queue);
ap_poll_thread_stop();
del_timer_sync(&ap_config_timer);
del_timer_sync(&ap_poll_timer);
destroy_workqueue(ap_work_queue);
+ tasklet_kill(&ap_tasklet);
s390_root_dev_unregister(ap_root_device);
while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
__ap_match_all)))
s390_root_dev_unregister(ap_root_device);
while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
__ap_match_all)))