1 /** 2 * Marvell NFC-over-USB driver: USB interface related functions 3 * 4 * Copyright (C) 2014, Marvell International Ltd. 5 * 6 * This software file (the "File") is distributed by Marvell International 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 8 * (the "License"). You may use, redistribute and/or modify this File in 9 * accordance with the terms and conditions of the License, a copy of which 10 * is available on the worldwide web at 11 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 12 * 13 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 14 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 15 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about 16 * this warranty disclaimer. 17 **/ 18 19 #include <linux/module.h> 20 #include <linux/usb.h> 21 #include <linux/nfc.h> 22 #include <net/nfc/nci.h> 23 #include <net/nfc/nci_core.h> 24 #include "nfcmrvl.h" 25 26 #define VERSION "1.0" 27 28 static struct usb_device_id nfcmrvl_table[] = { 29 { USB_DEVICE_AND_INTERFACE_INFO(0x1286, 0x2046, 30 USB_CLASS_VENDOR_SPEC, 4, 1) }, 31 { } /* Terminating entry */ 32 }; 33 34 MODULE_DEVICE_TABLE(usb, nfcmrvl_table); 35 36 #define NFCMRVL_USB_BULK_RUNNING 1 37 #define NFCMRVL_USB_SUSPENDING 2 38 39 struct nfcmrvl_usb_drv_data { 40 struct usb_device *udev; 41 struct usb_interface *intf; 42 unsigned long flags; 43 struct work_struct waker; 44 struct usb_anchor tx_anchor; 45 struct usb_anchor bulk_anchor; 46 struct usb_anchor deferred; 47 int tx_in_flight; 48 /* protects tx_in_flight */ 49 spinlock_t txlock; 50 struct usb_endpoint_descriptor *bulk_tx_ep; 51 struct usb_endpoint_descriptor *bulk_rx_ep; 52 int suspend_count; 53 struct nfcmrvl_private *priv; 54 }; 55 56 static int nfcmrvl_inc_tx(struct nfcmrvl_usb_drv_data *drv_data) 57 { 58 unsigned long flags; 59 int rv; 60 61 spin_lock_irqsave(&drv_data->txlock, flags); 62 rv = test_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags); 63 if (!rv) 64 drv_data->tx_in_flight++; 65 spin_unlock_irqrestore(&drv_data->txlock, flags); 66 67 return rv; 68 } 69 70 static void nfcmrvl_bulk_complete(struct urb *urb) 71 { 72 struct nfcmrvl_usb_drv_data *drv_data = urb->context; 73 struct sk_buff *skb; 74 int err; 75 76 dev_dbg(&drv_data->udev->dev, "urb %p status %d count %d\n", 77 urb, urb->status, urb->actual_length); 78 79 if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags)) 80 return; 81 82 if (!urb->status) { 83 skb = nci_skb_alloc(drv_data->priv->ndev, urb->actual_length, 84 GFP_ATOMIC); 85 if (!skb) { 86 nfc_err(&drv_data->udev->dev, "failed to alloc mem\n"); 87 } else { 88 memcpy(skb_put(skb, urb->actual_length), 89 urb->transfer_buffer, urb->actual_length); 90 if (nfcmrvl_nci_recv_frame(drv_data->priv, skb) < 0) 91 nfc_err(&drv_data->udev->dev, 92 "corrupted Rx packet\n"); 93 } 94 } 95 96 if (!test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags)) 97 return; 98 99 usb_anchor_urb(urb, &drv_data->bulk_anchor); 100 usb_mark_last_busy(drv_data->udev); 101 102 err = usb_submit_urb(urb, GFP_ATOMIC); 103 if (err) { 104 /* -EPERM: urb is being killed; 105 * -ENODEV: device got disconnected 106 */ 107 if (err != -EPERM && err != -ENODEV) 108 nfc_err(&drv_data->udev->dev, 109 "urb %p failed to resubmit (%d)\n", urb, -err); 110 usb_unanchor_urb(urb); 111 } 112 } 113 114 static int 115 nfcmrvl_submit_bulk_urb(struct nfcmrvl_usb_drv_data *drv_data, gfp_t mem_flags) 116 { 117 struct urb *urb; 118 unsigned char *buf; 119 unsigned int pipe; 120 int err, size = NFCMRVL_NCI_MAX_EVENT_SIZE; 121 122 if (!drv_data->bulk_rx_ep) 123 return -ENODEV; 124 125 urb = usb_alloc_urb(0, mem_flags); 126 if (!urb) 127 return -ENOMEM; 128 129 buf = kmalloc(size, mem_flags); 130 if (!buf) { 131 usb_free_urb(urb); 132 return -ENOMEM; 133 } 134 135 pipe = usb_rcvbulkpipe(drv_data->udev, 136 drv_data->bulk_rx_ep->bEndpointAddress); 137 138 usb_fill_bulk_urb(urb, drv_data->udev, pipe, buf, size, 139 nfcmrvl_bulk_complete, drv_data); 140 141 urb->transfer_flags |= URB_FREE_BUFFER; 142 143 usb_mark_last_busy(drv_data->udev); 144 usb_anchor_urb(urb, &drv_data->bulk_anchor); 145 146 err = usb_submit_urb(urb, mem_flags); 147 if (err) { 148 if (err != -EPERM && err != -ENODEV) 149 nfc_err(&drv_data->udev->dev, 150 "urb %p submission failed (%d)\n", urb, -err); 151 usb_unanchor_urb(urb); 152 } 153 154 usb_free_urb(urb); 155 156 return err; 157 } 158 159 static void nfcmrvl_tx_complete(struct urb *urb) 160 { 161 struct sk_buff *skb = urb->context; 162 struct nci_dev *ndev = (struct nci_dev *)skb->dev; 163 struct nfcmrvl_private *priv = nci_get_drvdata(ndev); 164 struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data; 165 166 nfc_info(priv->dev, "urb %p status %d count %d\n", 167 urb, urb->status, urb->actual_length); 168 169 spin_lock(&drv_data->txlock); 170 drv_data->tx_in_flight--; 171 spin_unlock(&drv_data->txlock); 172 173 kfree(urb->setup_packet); 174 kfree_skb(skb); 175 } 176 177 static int nfcmrvl_usb_nci_open(struct nfcmrvl_private *priv) 178 { 179 struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data; 180 int err; 181 182 err = usb_autopm_get_interface(drv_data->intf); 183 if (err) 184 return err; 185 186 drv_data->intf->needs_remote_wakeup = 1; 187 188 err = nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL); 189 if (err) 190 goto failed; 191 192 set_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags); 193 nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL); 194 195 usb_autopm_put_interface(drv_data->intf); 196 return 0; 197 198 failed: 199 usb_autopm_put_interface(drv_data->intf); 200 return err; 201 } 202 203 static void nfcmrvl_usb_stop_traffic(struct nfcmrvl_usb_drv_data *drv_data) 204 { 205 usb_kill_anchored_urbs(&drv_data->bulk_anchor); 206 } 207 208 static int nfcmrvl_usb_nci_close(struct nfcmrvl_private *priv) 209 { 210 struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data; 211 int err; 212 213 cancel_work_sync(&drv_data->waker); 214 215 clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags); 216 217 nfcmrvl_usb_stop_traffic(drv_data); 218 usb_kill_anchored_urbs(&drv_data->tx_anchor); 219 err = usb_autopm_get_interface(drv_data->intf); 220 if (err) 221 goto failed; 222 223 drv_data->intf->needs_remote_wakeup = 0; 224 usb_autopm_put_interface(drv_data->intf); 225 226 failed: 227 usb_scuttle_anchored_urbs(&drv_data->deferred); 228 return 0; 229 } 230 231 static int nfcmrvl_usb_nci_send(struct nfcmrvl_private *priv, 232 struct sk_buff *skb) 233 { 234 struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data; 235 struct urb *urb; 236 unsigned int pipe; 237 int err; 238 239 if (!drv_data->bulk_tx_ep) 240 return -ENODEV; 241 242 urb = usb_alloc_urb(0, GFP_ATOMIC); 243 if (!urb) 244 return -ENOMEM; 245 246 pipe = usb_sndbulkpipe(drv_data->udev, 247 drv_data->bulk_tx_ep->bEndpointAddress); 248 249 usb_fill_bulk_urb(urb, drv_data->udev, pipe, skb->data, skb->len, 250 nfcmrvl_tx_complete, skb); 251 252 err = nfcmrvl_inc_tx(drv_data); 253 if (err) { 254 usb_anchor_urb(urb, &drv_data->deferred); 255 schedule_work(&drv_data->waker); 256 err = 0; 257 goto done; 258 } 259 260 usb_anchor_urb(urb, &drv_data->tx_anchor); 261 262 err = usb_submit_urb(urb, GFP_ATOMIC); 263 if (err) { 264 if (err != -EPERM && err != -ENODEV) 265 nfc_err(&drv_data->udev->dev, 266 "urb %p submission failed (%d)\n", urb, -err); 267 kfree(urb->setup_packet); 268 usb_unanchor_urb(urb); 269 } else { 270 usb_mark_last_busy(drv_data->udev); 271 } 272 273 done: 274 usb_free_urb(urb); 275 return err; 276 } 277 278 static struct nfcmrvl_if_ops usb_ops = { 279 .nci_open = nfcmrvl_usb_nci_open, 280 .nci_close = nfcmrvl_usb_nci_close, 281 .nci_send = nfcmrvl_usb_nci_send, 282 }; 283 284 static void nfcmrvl_waker(struct work_struct *work) 285 { 286 struct nfcmrvl_usb_drv_data *drv_data = 287 container_of(work, struct nfcmrvl_usb_drv_data, waker); 288 int err; 289 290 err = usb_autopm_get_interface(drv_data->intf); 291 if (err) 292 return; 293 294 usb_autopm_put_interface(drv_data->intf); 295 } 296 297 static int nfcmrvl_probe(struct usb_interface *intf, 298 const struct usb_device_id *id) 299 { 300 struct usb_endpoint_descriptor *ep_desc; 301 struct nfcmrvl_usb_drv_data *drv_data; 302 struct nfcmrvl_private *priv; 303 int i; 304 struct usb_device *udev = interface_to_usbdev(intf); 305 struct nfcmrvl_platform_data config; 306 307 /* No configuration for USB */ 308 memset(&config, 0, sizeof(config)); 309 310 nfc_info(&udev->dev, "intf %p id %p\n", intf, id); 311 312 drv_data = devm_kzalloc(&intf->dev, sizeof(*drv_data), GFP_KERNEL); 313 if (!drv_data) 314 return -ENOMEM; 315 316 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { 317 ep_desc = &intf->cur_altsetting->endpoint[i].desc; 318 319 if (!drv_data->bulk_tx_ep && 320 usb_endpoint_is_bulk_out(ep_desc)) { 321 drv_data->bulk_tx_ep = ep_desc; 322 continue; 323 } 324 325 if (!drv_data->bulk_rx_ep && 326 usb_endpoint_is_bulk_in(ep_desc)) { 327 drv_data->bulk_rx_ep = ep_desc; 328 continue; 329 } 330 } 331 332 if (!drv_data->bulk_tx_ep || !drv_data->bulk_rx_ep) 333 return -ENODEV; 334 335 drv_data->udev = udev; 336 drv_data->intf = intf; 337 338 INIT_WORK(&drv_data->waker, nfcmrvl_waker); 339 spin_lock_init(&drv_data->txlock); 340 341 init_usb_anchor(&drv_data->tx_anchor); 342 init_usb_anchor(&drv_data->bulk_anchor); 343 init_usb_anchor(&drv_data->deferred); 344 345 priv = nfcmrvl_nci_register_dev(drv_data, &usb_ops, 346 &drv_data->udev->dev, &config); 347 if (IS_ERR(priv)) 348 return PTR_ERR(priv); 349 350 drv_data->priv = priv; 351 drv_data->priv->phy = NFCMRVL_PHY_USB; 352 priv->dev = &drv_data->udev->dev; 353 354 usb_set_intfdata(intf, drv_data); 355 356 return 0; 357 } 358 359 static void nfcmrvl_disconnect(struct usb_interface *intf) 360 { 361 struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf); 362 363 if (!drv_data) 364 return; 365 366 nfc_info(&drv_data->udev->dev, "intf %p\n", intf); 367 368 nfcmrvl_nci_unregister_dev(drv_data->priv); 369 370 usb_set_intfdata(drv_data->intf, NULL); 371 } 372 373 #ifdef CONFIG_PM 374 static int nfcmrvl_suspend(struct usb_interface *intf, pm_message_t message) 375 { 376 struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf); 377 378 nfc_info(&drv_data->udev->dev, "intf %p\n", intf); 379 380 if (drv_data->suspend_count++) 381 return 0; 382 383 spin_lock_irq(&drv_data->txlock); 384 if (!(PMSG_IS_AUTO(message) && drv_data->tx_in_flight)) { 385 set_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags); 386 spin_unlock_irq(&drv_data->txlock); 387 } else { 388 spin_unlock_irq(&drv_data->txlock); 389 drv_data->suspend_count--; 390 return -EBUSY; 391 } 392 393 nfcmrvl_usb_stop_traffic(drv_data); 394 usb_kill_anchored_urbs(&drv_data->tx_anchor); 395 396 return 0; 397 } 398 399 static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data *drv_data) 400 { 401 struct urb *urb; 402 int err; 403 404 while ((urb = usb_get_from_anchor(&drv_data->deferred))) { 405 err = usb_submit_urb(urb, GFP_ATOMIC); 406 if (err) 407 break; 408 409 drv_data->tx_in_flight++; 410 } 411 usb_scuttle_anchored_urbs(&drv_data->deferred); 412 } 413 414 static int nfcmrvl_resume(struct usb_interface *intf) 415 { 416 struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf); 417 int err = 0; 418 419 nfc_info(&drv_data->udev->dev, "intf %p\n", intf); 420 421 if (--drv_data->suspend_count) 422 return 0; 423 424 if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags)) 425 goto done; 426 427 if (test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags)) { 428 err = nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO); 429 if (err) { 430 clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags); 431 goto failed; 432 } 433 434 nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO); 435 } 436 437 spin_lock_irq(&drv_data->txlock); 438 nfcmrvl_play_deferred(drv_data); 439 clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags); 440 spin_unlock_irq(&drv_data->txlock); 441 442 return 0; 443 444 failed: 445 usb_scuttle_anchored_urbs(&drv_data->deferred); 446 done: 447 spin_lock_irq(&drv_data->txlock); 448 clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags); 449 spin_unlock_irq(&drv_data->txlock); 450 451 return err; 452 } 453 #endif 454 455 static struct usb_driver nfcmrvl_usb_driver = { 456 .name = "nfcmrvl", 457 .probe = nfcmrvl_probe, 458 .disconnect = nfcmrvl_disconnect, 459 #ifdef CONFIG_PM 460 .suspend = nfcmrvl_suspend, 461 .resume = nfcmrvl_resume, 462 .reset_resume = nfcmrvl_resume, 463 #endif 464 .id_table = nfcmrvl_table, 465 .supports_autosuspend = 1, 466 .disable_hub_initiated_lpm = 1, 467 .soft_unbind = 1, 468 }; 469 module_usb_driver(nfcmrvl_usb_driver); 470 471 MODULE_AUTHOR("Marvell International Ltd."); 472 MODULE_DESCRIPTION("Marvell NFC-over-USB driver ver " VERSION); 473 MODULE_VERSION(VERSION); 474 MODULE_LICENSE("GPL v2"); 475