--- x/drivers/nfc/virtual_ncidev.c +++ y/drivers/nfc/virtual_ncidev.c @@ -15,6 +15,7 @@ enum virtual_ncidev_mode { virtual_ncidev_enabled, + virtual_ncidev_enabling, virtual_ncidev_disabled, virtual_ncidev_disabling, }; @@ -128,6 +129,7 @@ static ssize_t virtual_ncidev_write(stru static int virtual_ncidev_open(struct inode *inode, struct file *file) { + struct nci_dev *new; int ret = 0; mutex_lock(&nci_mutex); @@ -135,24 +137,27 @@ static int virtual_ncidev_open(struct in mutex_unlock(&nci_mutex); return -EBUSY; } + state = virtual_ncidev_enabling; + mutex_unlock(&nci_mutex); - ndev = nci_allocate_device(&virtual_nci_ops, VIRTUAL_NFC_PROTOCOLS, - 0, 0); - if (!ndev) { - mutex_unlock(&nci_mutex); - return -ENOMEM; + ret = -ENOMEM; + new = nci_allocate_device(&virtual_nci_ops, VIRTUAL_NFC_PROTOCOLS, 0, 0); + if (new) { + ret = nci_register_device(new); + if (ret) + nci_free_device(new); } - ret = nci_register_device(ndev); - if (ret < 0) { - nci_free_device(ndev); - mutex_unlock(&nci_mutex); - return ret; + mutex_lock(&nci_mutex); + if (ret) + state = virtual_ncidev_disabled; + else { + ndev = new; + state = virtual_ncidev_enabled; } - state = virtual_ncidev_enabled; mutex_unlock(&nci_mutex); - return 0; + return ret; } static int virtual_ncidev_close(struct inode *inode, struct file *file) @@ -167,9 +172,9 @@ static int virtual_ncidev_close(struct i nci_free_device(ndev); mutex_lock(&nci_mutex); + state = virtual_ncidev_disabled; } - state = virtual_ncidev_disabled; mutex_unlock(&nci_mutex); return 0;