diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 48ea0004a56d..f07632da815e 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1334,6 +1334,16 @@ static int __match_queue_device_with_qid(struct device *dev, void *data) return is_queue_dev(dev) && to_ap_queue(dev)->qid == (int)(long) data; } +/* + * Helper function to be used with bus_find_dev + * matches any queue device with given queue id + */ +static int __match_queue_device_with_queue_id(struct device *dev, void *data) +{ + return is_queue_dev(dev) + && AP_QID_QUEUE(to_ap_queue(dev)->qid) == (int)(long) data; +} + /* * Helper function for ap_scan_bus(). * Does the scan bus job for the given adapter id. @@ -1434,8 +1444,13 @@ static void _ap_scan_bus_adapter(int id) borked = aq->state == AP_STATE_BORKED; spin_unlock_bh(&aq->lock); } - if (borked) /* Remove broken device */ + if (borked) { + /* Remove broken device */ + AP_DBF(DBF_DEBUG, + "removing broken queue=%02x.%04x\n", + id, dom); device_unregister(dev); + } put_device(dev); continue; } @@ -1505,7 +1520,7 @@ static void ap_scan_bus(struct work_struct *unused) struct device *dev = bus_find_device(&ap_bus_type, NULL, (void *)(long) ap_domain_index, - __match_queue_device_with_qid); + __match_queue_device_with_queue_id); if (dev) put_device(dev); else diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index bfc66e4a9de1..d0059eae5d94 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -91,7 +91,8 @@ enum ap_state { AP_STATE_WORKING, AP_STATE_QUEUE_FULL, AP_STATE_SUSPEND_WAIT, - AP_STATE_BORKED, + AP_STATE_UNBOUND, /* momentary not bound to a driver */ + AP_STATE_BORKED, /* broken */ NR_AP_STATES }; diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 576ac08777c5..ba261210c6da 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -420,6 +420,10 @@ static ap_func_t *ap_jumptable[NR_AP_STATES][NR_AP_EVENTS] = { [AP_EVENT_POLL] = ap_sm_suspend_read, [AP_EVENT_TIMEOUT] = ap_sm_nop, }, + [AP_STATE_UNBOUND] = { + [AP_EVENT_POLL] = ap_sm_nop, + [AP_EVENT_TIMEOUT] = ap_sm_nop, + }, [AP_STATE_BORKED] = { [AP_EVENT_POLL] = ap_sm_nop, [AP_EVENT_TIMEOUT] = ap_sm_nop, @@ -725,6 +729,7 @@ static void __ap_flush_queue(struct ap_queue *aq) ap_msg->rc = -EAGAIN; ap_msg->receive(aq, ap_msg, NULL); } + aq->queue_count = 0; } void ap_flush_queue(struct ap_queue *aq) @@ -743,7 +748,7 @@ void ap_queue_remove(struct ap_queue *aq) /* reset with zero, also clears irq registration */ spin_lock_bh(&aq->lock); ap_zapq(aq->qid); - aq->state = AP_STATE_BORKED; + aq->state = AP_STATE_UNBOUND; spin_unlock_bh(&aq->lock); } EXPORT_SYMBOL(ap_queue_remove);