ap_dev->drv = ap_drv;
rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
- if (rc)
- ap_dev->unregistered = 1;
return rc;
}
struct ap_device *ap_dev = to_ap_dev(dev);
struct ap_driver *ap_drv = ap_dev->drv;
- spin_lock_bh(&ap_dev->lock);
- __ap_flush_queue(ap_dev);
- /**
- * set ->unregistered to 1 while holding the lock. This prevents
- * new messages to be put on the queue from now on.
- */
- ap_dev->unregistered = 1;
- spin_unlock_bh(&ap_dev->lock);
+ ap_flush_queue(ap_dev);
if (ap_drv->remove)
ap_drv->remove(ap_dev);
return 0;
break;
ap_dev->qid = qid;
ap_dev->queue_depth = queue_depth;
+ ap_dev->unregistered = 1;
spin_lock_init(&ap_dev->lock);
INIT_LIST_HEAD(&ap_dev->pendingq);
INIT_LIST_HEAD(&ap_dev->requestq);
/* Add device attributes. */
rc = sysfs_create_group(&ap_dev->device.kobj,
&ap_dev_attr_group);
- if (rc)
+ if (!rc) {
+ spin_lock_bh(&ap_dev->lock);
+ ap_dev->unregistered = 0;
+ spin_unlock_bh(&ap_dev->lock);
+ }
+ else
device_unregister(&ap_dev->device);
}
}
rc = __ap_queue_message(ap_dev, ap_msg);
if (!rc)
wake_up(&ap_poll_wait);
+ if (rc == -ENODEV)
+ ap_dev->unregistered = 1;
} else {
ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
rc = 0;
spin_lock(&ap_dev->lock);
if (!ap_dev->unregistered) {
rc = ap_poll_queue(to_ap_dev(dev), (unsigned long *) data);
+ if (rc)
+ ap_dev->unregistered = 1;
} else
rc = 0;
spin_unlock(&ap_dev->lock);