0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/usb.h>
0010 #include <linux/nfc.h>
0011 #include <net/nfc/nci.h>
0012 #include <net/nfc/nci_core.h>
0013 #include "nfcmrvl.h"
0014
0015 static struct usb_device_id nfcmrvl_table[] = {
0016 { USB_DEVICE_AND_INTERFACE_INFO(0x1286, 0x2046,
0017 USB_CLASS_VENDOR_SPEC, 4, 1) },
0018 { }
0019 };
0020
0021 MODULE_DEVICE_TABLE(usb, nfcmrvl_table);
0022
0023 #define NFCMRVL_USB_BULK_RUNNING 1
0024 #define NFCMRVL_USB_SUSPENDING 2
0025
0026 struct nfcmrvl_usb_drv_data {
0027 struct usb_device *udev;
0028 struct usb_interface *intf;
0029 unsigned long flags;
0030 struct work_struct waker;
0031 struct usb_anchor tx_anchor;
0032 struct usb_anchor bulk_anchor;
0033 struct usb_anchor deferred;
0034 int tx_in_flight;
0035
0036 spinlock_t txlock;
0037 struct usb_endpoint_descriptor *bulk_tx_ep;
0038 struct usb_endpoint_descriptor *bulk_rx_ep;
0039 int suspend_count;
0040 struct nfcmrvl_private *priv;
0041 };
0042
0043 static int nfcmrvl_inc_tx(struct nfcmrvl_usb_drv_data *drv_data)
0044 {
0045 unsigned long flags;
0046 int rv;
0047
0048 spin_lock_irqsave(&drv_data->txlock, flags);
0049 rv = test_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
0050 if (!rv)
0051 drv_data->tx_in_flight++;
0052 spin_unlock_irqrestore(&drv_data->txlock, flags);
0053
0054 return rv;
0055 }
0056
0057 static void nfcmrvl_bulk_complete(struct urb *urb)
0058 {
0059 struct nfcmrvl_usb_drv_data *drv_data = urb->context;
0060 int err;
0061
0062 dev_dbg(&drv_data->udev->dev, "urb %p status %d count %d\n",
0063 urb, urb->status, urb->actual_length);
0064
0065 if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags))
0066 return;
0067
0068 if (!urb->status) {
0069 struct sk_buff *skb;
0070
0071 skb = nci_skb_alloc(drv_data->priv->ndev, urb->actual_length,
0072 GFP_ATOMIC);
0073 if (!skb) {
0074 nfc_err(&drv_data->udev->dev, "failed to alloc mem\n");
0075 } else {
0076 skb_put_data(skb, urb->transfer_buffer,
0077 urb->actual_length);
0078 if (nfcmrvl_nci_recv_frame(drv_data->priv, skb) < 0)
0079 nfc_err(&drv_data->udev->dev,
0080 "corrupted Rx packet\n");
0081 }
0082 }
0083
0084 if (!test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags))
0085 return;
0086
0087 usb_anchor_urb(urb, &drv_data->bulk_anchor);
0088 usb_mark_last_busy(drv_data->udev);
0089
0090 err = usb_submit_urb(urb, GFP_ATOMIC);
0091 if (err) {
0092
0093
0094
0095 if (err != -EPERM && err != -ENODEV)
0096 nfc_err(&drv_data->udev->dev,
0097 "urb %p failed to resubmit (%d)\n", urb, -err);
0098 usb_unanchor_urb(urb);
0099 }
0100 }
0101
0102 static int
0103 nfcmrvl_submit_bulk_urb(struct nfcmrvl_usb_drv_data *drv_data, gfp_t mem_flags)
0104 {
0105 struct urb *urb;
0106 unsigned char *buf;
0107 unsigned int pipe;
0108 int err, size = NFCMRVL_NCI_MAX_EVENT_SIZE;
0109
0110 if (!drv_data->bulk_rx_ep)
0111 return -ENODEV;
0112
0113 urb = usb_alloc_urb(0, mem_flags);
0114 if (!urb)
0115 return -ENOMEM;
0116
0117 buf = kmalloc(size, mem_flags);
0118 if (!buf) {
0119 usb_free_urb(urb);
0120 return -ENOMEM;
0121 }
0122
0123 pipe = usb_rcvbulkpipe(drv_data->udev,
0124 drv_data->bulk_rx_ep->bEndpointAddress);
0125
0126 usb_fill_bulk_urb(urb, drv_data->udev, pipe, buf, size,
0127 nfcmrvl_bulk_complete, drv_data);
0128
0129 urb->transfer_flags |= URB_FREE_BUFFER;
0130
0131 usb_mark_last_busy(drv_data->udev);
0132 usb_anchor_urb(urb, &drv_data->bulk_anchor);
0133
0134 err = usb_submit_urb(urb, mem_flags);
0135 if (err) {
0136 if (err != -EPERM && err != -ENODEV)
0137 nfc_err(&drv_data->udev->dev,
0138 "urb %p submission failed (%d)\n", urb, -err);
0139 usb_unanchor_urb(urb);
0140 }
0141
0142 usb_free_urb(urb);
0143
0144 return err;
0145 }
0146
0147 static void nfcmrvl_tx_complete(struct urb *urb)
0148 {
0149 struct sk_buff *skb = urb->context;
0150 struct nci_dev *ndev = (struct nci_dev *)skb->dev;
0151 struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
0152 struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
0153 unsigned long flags;
0154
0155 nfc_info(priv->dev, "urb %p status %d count %d\n",
0156 urb, urb->status, urb->actual_length);
0157
0158 spin_lock_irqsave(&drv_data->txlock, flags);
0159 drv_data->tx_in_flight--;
0160 spin_unlock_irqrestore(&drv_data->txlock, flags);
0161
0162 kfree(urb->setup_packet);
0163 kfree_skb(skb);
0164 }
0165
0166 static int nfcmrvl_usb_nci_open(struct nfcmrvl_private *priv)
0167 {
0168 struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
0169 int err;
0170
0171 err = usb_autopm_get_interface(drv_data->intf);
0172 if (err)
0173 return err;
0174
0175 drv_data->intf->needs_remote_wakeup = 1;
0176
0177 err = nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL);
0178 if (err)
0179 goto failed;
0180
0181 set_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);
0182 nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL);
0183
0184 usb_autopm_put_interface(drv_data->intf);
0185 return 0;
0186
0187 failed:
0188 usb_autopm_put_interface(drv_data->intf);
0189 return err;
0190 }
0191
0192 static void nfcmrvl_usb_stop_traffic(struct nfcmrvl_usb_drv_data *drv_data)
0193 {
0194 usb_kill_anchored_urbs(&drv_data->bulk_anchor);
0195 }
0196
0197 static int nfcmrvl_usb_nci_close(struct nfcmrvl_private *priv)
0198 {
0199 struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
0200 int err;
0201
0202 cancel_work_sync(&drv_data->waker);
0203
0204 clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);
0205
0206 nfcmrvl_usb_stop_traffic(drv_data);
0207 usb_kill_anchored_urbs(&drv_data->tx_anchor);
0208 err = usb_autopm_get_interface(drv_data->intf);
0209 if (err)
0210 goto failed;
0211
0212 drv_data->intf->needs_remote_wakeup = 0;
0213 usb_autopm_put_interface(drv_data->intf);
0214
0215 failed:
0216 usb_scuttle_anchored_urbs(&drv_data->deferred);
0217 return 0;
0218 }
0219
0220 static int nfcmrvl_usb_nci_send(struct nfcmrvl_private *priv,
0221 struct sk_buff *skb)
0222 {
0223 struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
0224 struct urb *urb;
0225 unsigned int pipe;
0226 int err;
0227
0228 if (!drv_data->bulk_tx_ep)
0229 return -ENODEV;
0230
0231 urb = usb_alloc_urb(0, GFP_ATOMIC);
0232 if (!urb)
0233 return -ENOMEM;
0234
0235 pipe = usb_sndbulkpipe(drv_data->udev,
0236 drv_data->bulk_tx_ep->bEndpointAddress);
0237
0238 usb_fill_bulk_urb(urb, drv_data->udev, pipe, skb->data, skb->len,
0239 nfcmrvl_tx_complete, skb);
0240
0241 err = nfcmrvl_inc_tx(drv_data);
0242 if (err) {
0243 usb_anchor_urb(urb, &drv_data->deferred);
0244 schedule_work(&drv_data->waker);
0245 err = 0;
0246 goto done;
0247 }
0248
0249 usb_anchor_urb(urb, &drv_data->tx_anchor);
0250
0251 err = usb_submit_urb(urb, GFP_ATOMIC);
0252 if (err) {
0253 if (err != -EPERM && err != -ENODEV)
0254 nfc_err(&drv_data->udev->dev,
0255 "urb %p submission failed (%d)\n", urb, -err);
0256 kfree(urb->setup_packet);
0257 usb_unanchor_urb(urb);
0258 } else {
0259 usb_mark_last_busy(drv_data->udev);
0260 }
0261
0262 done:
0263 usb_free_urb(urb);
0264 return err;
0265 }
0266
0267 static const struct nfcmrvl_if_ops usb_ops = {
0268 .nci_open = nfcmrvl_usb_nci_open,
0269 .nci_close = nfcmrvl_usb_nci_close,
0270 .nci_send = nfcmrvl_usb_nci_send,
0271 };
0272
0273 static void nfcmrvl_waker(struct work_struct *work)
0274 {
0275 struct nfcmrvl_usb_drv_data *drv_data =
0276 container_of(work, struct nfcmrvl_usb_drv_data, waker);
0277 int err;
0278
0279 err = usb_autopm_get_interface(drv_data->intf);
0280 if (err)
0281 return;
0282
0283 usb_autopm_put_interface(drv_data->intf);
0284 }
0285
0286 static int nfcmrvl_probe(struct usb_interface *intf,
0287 const struct usb_device_id *id)
0288 {
0289 struct nfcmrvl_usb_drv_data *drv_data;
0290 struct nfcmrvl_private *priv;
0291 int i;
0292 struct usb_device *udev = interface_to_usbdev(intf);
0293 struct nfcmrvl_platform_data config;
0294
0295
0296 memset(&config, 0, sizeof(config));
0297 config.reset_n_io = -EINVAL;
0298
0299 nfc_info(&udev->dev, "intf %p id %p\n", intf, id);
0300
0301 drv_data = devm_kzalloc(&intf->dev, sizeof(*drv_data), GFP_KERNEL);
0302 if (!drv_data)
0303 return -ENOMEM;
0304
0305 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
0306 struct usb_endpoint_descriptor *ep_desc;
0307
0308 ep_desc = &intf->cur_altsetting->endpoint[i].desc;
0309
0310 if (!drv_data->bulk_tx_ep &&
0311 usb_endpoint_is_bulk_out(ep_desc)) {
0312 drv_data->bulk_tx_ep = ep_desc;
0313 } else if (!drv_data->bulk_rx_ep &&
0314 usb_endpoint_is_bulk_in(ep_desc)) {
0315 drv_data->bulk_rx_ep = ep_desc;
0316 }
0317 }
0318
0319 if (!drv_data->bulk_tx_ep || !drv_data->bulk_rx_ep)
0320 return -ENODEV;
0321
0322 drv_data->udev = udev;
0323 drv_data->intf = intf;
0324
0325 INIT_WORK(&drv_data->waker, nfcmrvl_waker);
0326 spin_lock_init(&drv_data->txlock);
0327
0328 init_usb_anchor(&drv_data->tx_anchor);
0329 init_usb_anchor(&drv_data->bulk_anchor);
0330 init_usb_anchor(&drv_data->deferred);
0331
0332 priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_USB, drv_data, &usb_ops,
0333 &intf->dev, &config);
0334 if (IS_ERR(priv))
0335 return PTR_ERR(priv);
0336
0337 drv_data->priv = priv;
0338 drv_data->priv->support_fw_dnld = false;
0339
0340 usb_set_intfdata(intf, drv_data);
0341
0342 return 0;
0343 }
0344
0345 static void nfcmrvl_disconnect(struct usb_interface *intf)
0346 {
0347 struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);
0348
0349 if (!drv_data)
0350 return;
0351
0352 nfc_info(&drv_data->udev->dev, "intf %p\n", intf);
0353
0354 nfcmrvl_nci_unregister_dev(drv_data->priv);
0355
0356 usb_set_intfdata(drv_data->intf, NULL);
0357 }
0358
0359 #ifdef CONFIG_PM
0360 static int nfcmrvl_suspend(struct usb_interface *intf, pm_message_t message)
0361 {
0362 struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);
0363
0364 nfc_info(&drv_data->udev->dev, "intf %p\n", intf);
0365
0366 if (drv_data->suspend_count++)
0367 return 0;
0368
0369 spin_lock_irq(&drv_data->txlock);
0370 if (!(PMSG_IS_AUTO(message) && drv_data->tx_in_flight)) {
0371 set_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
0372 spin_unlock_irq(&drv_data->txlock);
0373 } else {
0374 spin_unlock_irq(&drv_data->txlock);
0375 drv_data->suspend_count--;
0376 return -EBUSY;
0377 }
0378
0379 nfcmrvl_usb_stop_traffic(drv_data);
0380 usb_kill_anchored_urbs(&drv_data->tx_anchor);
0381
0382 return 0;
0383 }
0384
0385 static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data *drv_data)
0386 {
0387 struct urb *urb;
0388 int err;
0389
0390 while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
0391 usb_anchor_urb(urb, &drv_data->tx_anchor);
0392
0393 err = usb_submit_urb(urb, GFP_ATOMIC);
0394 if (err) {
0395 kfree(urb->setup_packet);
0396 usb_unanchor_urb(urb);
0397 usb_free_urb(urb);
0398 break;
0399 }
0400
0401 drv_data->tx_in_flight++;
0402 usb_free_urb(urb);
0403 }
0404
0405
0406 while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
0407 kfree(urb->setup_packet);
0408 usb_free_urb(urb);
0409 }
0410 }
0411
0412 static int nfcmrvl_resume(struct usb_interface *intf)
0413 {
0414 struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);
0415 int err = 0;
0416
0417 nfc_info(&drv_data->udev->dev, "intf %p\n", intf);
0418
0419 if (--drv_data->suspend_count)
0420 return 0;
0421
0422 if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags))
0423 goto done;
0424
0425 if (test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags)) {
0426 err = nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO);
0427 if (err) {
0428 clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);
0429 goto failed;
0430 }
0431
0432 nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO);
0433 }
0434
0435 spin_lock_irq(&drv_data->txlock);
0436 nfcmrvl_play_deferred(drv_data);
0437 clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
0438 spin_unlock_irq(&drv_data->txlock);
0439
0440 return 0;
0441
0442 failed:
0443 usb_scuttle_anchored_urbs(&drv_data->deferred);
0444 done:
0445 spin_lock_irq(&drv_data->txlock);
0446 clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
0447 spin_unlock_irq(&drv_data->txlock);
0448
0449 return err;
0450 }
0451 #endif
0452
0453 static struct usb_driver nfcmrvl_usb_driver = {
0454 .name = "nfcmrvl",
0455 .probe = nfcmrvl_probe,
0456 .disconnect = nfcmrvl_disconnect,
0457 #ifdef CONFIG_PM
0458 .suspend = nfcmrvl_suspend,
0459 .resume = nfcmrvl_resume,
0460 .reset_resume = nfcmrvl_resume,
0461 #endif
0462 .id_table = nfcmrvl_table,
0463 .supports_autosuspend = 1,
0464 .disable_hub_initiated_lpm = 1,
0465 .soft_unbind = 1,
0466 };
0467 module_usb_driver(nfcmrvl_usb_driver);
0468
0469 MODULE_AUTHOR("Marvell International Ltd.");
0470 MODULE_DESCRIPTION("Marvell NFC-over-USB driver");
0471 MODULE_LICENSE("GPL v2");