示例#1
0
文件: core.c 项目: IDM350/linux
static int nci_close_device(struct nci_dev *ndev)
{
	nci_req_cancel(ndev, ENODEV);
	mutex_lock(&ndev->req_lock);

	if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
		del_timer_sync(&ndev->cmd_timer);
		del_timer_sync(&ndev->data_timer);
		mutex_unlock(&ndev->req_lock);
		return 0;
	}

	/* Drop RX and TX queues */
	skb_queue_purge(&ndev->rx_q);
	skb_queue_purge(&ndev->tx_q);

	/* Flush RX and TX wq */
	flush_workqueue(ndev->rx_wq);
	flush_workqueue(ndev->tx_wq);

	/* Reset device */
	skb_queue_purge(&ndev->cmd_q);
	atomic_set(&ndev->cmd_cnt, 1);

	set_bit(NCI_INIT, &ndev->flags);
	__nci_request(ndev, nci_reset_req, 0,
		      msecs_to_jiffies(NCI_RESET_TIMEOUT));
	clear_bit(NCI_INIT, &ndev->flags);

	del_timer_sync(&ndev->cmd_timer);

	/* Flush cmd wq */
	flush_workqueue(ndev->cmd_wq);

	/* After this point our queues are empty
	 * and no works are scheduled. */
	ndev->ops->close(ndev);

	/* Clear flags */
	ndev->flags = 0;

	mutex_unlock(&ndev->req_lock);

	return 0;
}
static int nci_close_device(struct nci_dev *ndev)
{
	nci_req_cancel(ndev, ENODEV);
	mutex_lock(&ndev->req_lock);

	if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
		del_timer_sync(&ndev->cmd_timer);
		del_timer_sync(&ndev->data_timer);
		mutex_unlock(&ndev->req_lock);
		return 0;
	}

	
	skb_queue_purge(&ndev->rx_q);
	skb_queue_purge(&ndev->tx_q);

	
	flush_workqueue(ndev->rx_wq);
	flush_workqueue(ndev->tx_wq);

	
	skb_queue_purge(&ndev->cmd_q);
	atomic_set(&ndev->cmd_cnt, 1);

	set_bit(NCI_INIT, &ndev->flags);
	__nci_request(ndev, nci_reset_req, 0,
		      msecs_to_jiffies(NCI_RESET_TIMEOUT));
	clear_bit(NCI_INIT, &ndev->flags);

	
	flush_workqueue(ndev->cmd_wq);

	ndev->ops->close(ndev);

	
	ndev->flags = 0;

	mutex_unlock(&ndev->req_lock);

	return 0;
}