Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 351903
b: refs/heads/master
c: f0c9103
h: refs/heads/master
i:
  351901: 7b4628a
  351899: 2347ed3
  351895: 6cf380f
  351887: 68caa3c
  351871: 585e11d
v: v3
  • Loading branch information
Eric Lapuyade authored and Samuel Ortiz committed Jan 9, 2013
1 parent 7e93ca0 commit ab90454
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5f4d6214ef5e9b1ff6a72ddfa387c1d72adfac98
refs/heads/master: f0c9103813b3045bd5b43220b6a78c9908a45d24
2 changes: 2 additions & 0 deletions trunk/include/net/nfc/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ struct nfc_hci_dev {

u32 max_data_link_payload;

bool shutting_down;

struct mutex msg_tx_mutex;

struct list_head msg_tx_queue;
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/net/nfc/nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ struct nfc_dev {
struct timer_list check_pres_timer;
struct work_struct check_pres_work;

bool shutting_down;

struct nfc_ops *ops;
};
#define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev)
Expand Down
47 changes: 22 additions & 25 deletions trunk/net/nfc/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol)
dev->active_target = target;
dev->rf_mode = NFC_RF_INITIATOR;

if (dev->ops->check_presence)
if (dev->ops->check_presence && !dev->shutting_down)
mod_timer(&dev->check_pres_timer, jiffies +
msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS));
}
Expand Down Expand Up @@ -429,7 +429,7 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
rc = dev->ops->im_transceive(dev, dev->active_target, skb, cb,
cb_context);

if (!rc && dev->ops->check_presence)
if (!rc && dev->ops->check_presence && !dev->shutting_down)
mod_timer(&dev->check_pres_timer, jiffies +
msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS));
} else if (dev->rf_mode == NFC_RF_TARGET && dev->ops->tm_send != NULL) {
Expand Down Expand Up @@ -684,11 +684,6 @@ static void nfc_release(struct device *d)

pr_debug("dev_name=%s\n", dev_name(&dev->dev));

if (dev->ops->check_presence) {
del_timer_sync(&dev->check_pres_timer);
cancel_work_sync(&dev->check_pres_work);
}

nfc_genl_data_exit(&dev->genl_data);
kfree(dev->targets);
kfree(dev);
Expand All @@ -706,15 +701,16 @@ static void nfc_check_pres_work(struct work_struct *work)
rc = dev->ops->check_presence(dev, dev->active_target);
if (rc == -EOPNOTSUPP)
goto exit;
if (!rc) {
mod_timer(&dev->check_pres_timer, jiffies +
msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS));
} else {
if (rc) {
u32 active_target_idx = dev->active_target->idx;
device_unlock(&dev->dev);
nfc_target_lost(dev, active_target_idx);
return;
}

if (!dev->shutting_down)
mod_timer(&dev->check_pres_timer, jiffies +
msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS));
}

exit:
Expand Down Expand Up @@ -853,26 +849,27 @@ void nfc_unregister_device(struct nfc_dev *dev)

id = dev->idx;

mutex_lock(&nfc_devlist_mutex);
nfc_devlist_generation++;

/* lock to avoid unregistering a device while an operation
is in progress */
device_lock(&dev->dev);
device_del(&dev->dev);
device_unlock(&dev->dev);
if (dev->ops->check_presence) {
device_lock(&dev->dev);
dev->shutting_down = true;
device_unlock(&dev->dev);
del_timer_sync(&dev->check_pres_timer);
cancel_work_sync(&dev->check_pres_work);
}

mutex_unlock(&nfc_devlist_mutex);
rc = nfc_genl_device_removed(dev);
if (rc)
pr_debug("The userspace won't be notified that the device %s "
"was removed\n", dev_name(&dev->dev));

nfc_llcp_unregister_device(dev);

rc = nfc_genl_device_removed(dev);
if (rc)
pr_debug("The userspace won't be notified that the device %s was removed\n",
dev_name(&dev->dev));
mutex_lock(&nfc_devlist_mutex);
nfc_devlist_generation++;
device_del(&dev->dev);
mutex_unlock(&nfc_devlist_mutex);

ida_simple_remove(&nfc_index_ida, id);

}
EXPORT_SYMBOL(nfc_unregister_device);

Expand Down
31 changes: 24 additions & 7 deletions trunk/net/nfc/hci/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ static void nfc_hci_msg_tx_work(struct work_struct *work)
int r = 0;

mutex_lock(&hdev->msg_tx_mutex);
if (hdev->shutting_down)
goto exit;

if (hdev->cmd_pending_msg) {
if (timer_pending(&hdev->cmd_timer) == 0) {
Expand Down Expand Up @@ -868,6 +870,28 @@ void nfc_hci_unregister_device(struct nfc_hci_dev *hdev)
{
struct hci_msg *msg, *n;

mutex_lock(&hdev->msg_tx_mutex);

if (hdev->cmd_pending_msg) {
if (hdev->cmd_pending_msg->cb)
hdev->cmd_pending_msg->cb(
hdev->cmd_pending_msg->cb_context,
NULL, -ESHUTDOWN);
kfree(hdev->cmd_pending_msg);
hdev->cmd_pending_msg = NULL;
}

hdev->shutting_down = true;

mutex_unlock(&hdev->msg_tx_mutex);

del_timer_sync(&hdev->cmd_timer);
cancel_work_sync(&hdev->msg_tx_work);

cancel_work_sync(&hdev->msg_rx_work);

nfc_unregister_device(hdev->ndev);

skb_queue_purge(&hdev->rx_hcp_frags);
skb_queue_purge(&hdev->msg_rx_queue);

Expand All @@ -876,13 +900,6 @@ void nfc_hci_unregister_device(struct nfc_hci_dev *hdev)
skb_queue_purge(&msg->msg_frags);
kfree(msg);
}

del_timer_sync(&hdev->cmd_timer);

nfc_unregister_device(hdev->ndev);

cancel_work_sync(&hdev->msg_tx_work);
cancel_work_sync(&hdev->msg_rx_work);
}
EXPORT_SYMBOL(nfc_hci_unregister_device);

Expand Down
7 changes: 7 additions & 0 deletions trunk/net/nfc/hci/hcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ int nfc_hci_hcp_message_tx(struct nfc_hci_dev *hdev, u8 pipe,
}

mutex_lock(&hdev->msg_tx_mutex);

if (hdev->shutting_down) {
err = -ESHUTDOWN;
mutex_unlock(&hdev->msg_tx_mutex);
goto out_skb_err;
}

list_add_tail(&cmd->msg_l, &hdev->msg_tx_queue);
mutex_unlock(&hdev->msg_tx_mutex);

Expand Down

0 comments on commit ab90454

Please sign in to comment.