int diag_bridge_read(char *data, int size) { struct urb *urb = NULL; unsigned int pipe; struct diag_bridge *dev = __dev; int ret; int spin = 50; if (!dev || !dev->udev) return -ENODEV; if (!size) { dev_err(&dev->udev->dev, "invalid size:%d\n", size); return -EINVAL; } if (!dev->ifc) { dev_err(&dev->udev->dev, "device is disconnected\n"); return -ENODEV; } /* if there was a previous unrecoverable error, just quit */ if (dev->err) return -ESHUTDOWN; while (check_request_blocked(rmnet_pm_dev) && spin--) { pr_debug("%s: wake up wait loop\n", __func__); msleep(20); } if (check_request_blocked(rmnet_pm_dev)) { pr_err("%s: in lpa wakeup, return EAGAIN\n", __func__); return -EAGAIN; } urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { dev_err(&dev->udev->dev, "unable to allocate urb\n"); return -ENOMEM; } ret = usb_autopm_get_interface(dev->ifc); if (ret < 0) { dev_err(&dev->udev->dev, "autopm_get failed:%d\n", ret); usb_free_urb(urb); return ret; } pipe = usb_rcvbulkpipe(dev->udev, dev->in_epAddr); usb_fill_bulk_urb(urb, dev->udev, pipe, data, size, diag_bridge_read_cb, dev); usb_anchor_urb(urb, &dev->submitted); dev->pending_reads++; ret = usb_submit_urb(urb, GFP_KERNEL); if (ret) { dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret); dev->pending_reads--; usb_unanchor_urb(urb); usb_free_urb(urb); usb_autopm_put_interface(dev->ifc); return ret; } usb_autopm_put_interface(dev->ifc); usb_free_urb(urb); return 0; }
int diag_bridge_write(char *data, int size) { struct urb *urb = NULL; unsigned int pipe; struct diag_bridge *dev = __dev; int ret; int spin; if (!dev || !dev->udev) return -ENODEV; if (!size) { dev_err(&dev->udev->dev, "invalid size:%d\n", size); return -EINVAL; } if (!dev->ifc) { dev_err(&dev->udev->dev, "device is disconnected\n"); return -ENODEV; } /* if there was a previous unrecoverable error, just quit */ if (dev->err) return -ESHUTDOWN; spin = 50; while (check_request_blocked(rmnet_pm_dev) && spin--) { pr_info("%s: wake up wait loop\n", __func__); msleep(20); } if (check_request_blocked(rmnet_pm_dev)) { pr_err("%s: in lpa wakeup, return EAGAIN\n", __func__); return -EAGAIN; } urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { err("unable to allocate urb"); return -ENOMEM; } ret = usb_autopm_get_interface_async(dev->ifc); if (ret < 0) { dev_err(&dev->udev->dev, "autopm_get failed:%d\n", ret); usb_free_urb(urb); return ret; } for (spin = 0; spin < 10; spin++) { /* check rpm active */ if (dev->udev->dev.power.runtime_status == RPM_ACTIVE) { ret = 0; break; } else { dev_err(&dev->udev->dev, "waiting rpm active\n"); ret = -EAGAIN; } msleep(20); } if (ret < 0) { dev_err(&dev->udev->dev, "rpm active failed:%d\n", ret); usb_free_urb(urb); usb_autopm_put_interface(dev->ifc); return ret; } pipe = usb_sndbulkpipe(dev->udev, dev->out_epAddr); usb_fill_bulk_urb(urb, dev->udev, pipe, data, size, diag_bridge_write_cb, dev); usb_anchor_urb(urb, &dev->submitted); dev->pending_writes++; ret = usb_submit_urb(urb, GFP_KERNEL); if (ret) { dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret); dev->pending_writes--; usb_unanchor_urb(urb); usb_free_urb(urb); usb_autopm_put_interface(dev->ifc); return ret; } #if 0 usb_free_urb(urb); #endif return 0; }
int diag_bridge_write(char *data, int size) { struct urb *urb = NULL; unsigned int pipe; struct diag_bridge *dev = __dev; struct usb_device *udev; int ret; int spin; if (!dev || !dev->udev) return -ENODEV; if (!size) { dev_err(&dev->udev->dev, "invalid size:%d\n", size); return -EINVAL; } if (!dev->ifc) { dev_err(&dev->udev->dev, "device is disconnected\n"); return -ENODEV; } /* if there was a previous unrecoverable error, just quit */ if (dev->err) return -ESHUTDOWN; spin = 50; while (check_request_blocked(rmnet_pm_dev) && spin--) { pr_info("%s: wake up wait loop\n", __func__); msleep(20); } if (check_request_blocked(rmnet_pm_dev)) { pr_err("%s: in lpa wakeup, return EAGAIN\n", __func__); return -EAGAIN; } urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { err("unable to allocate urb"); return -ENOMEM; } udev = interface_to_usbdev(dev->ifc); /* if dev handling suspend wait for suspended or active*/ if (pm_dev_runtime_get_enabled(udev) < 0) { usb_free_urb(urb); return -EAGAIN; } ret = usb_autopm_get_interface(dev->ifc); if (ret < 0) { dev_err(&dev->udev->dev, "autopm_get failed:%d\n", ret); usb_free_urb(urb); return ret; } if (size == 4 || size == 5) { if (data[0] == 0x1d && data[1] == 0x1c && data[2] == 0x3b) pr_info("%s: diag.cfg [send start]\n", __func__); else if (data[0] == 0x60 && data[1] == 0x00 && data[2] == 0x12 && data[3] == 0x6a) pr_info("%s: diag.cfg [send complete]\n", __func__); } pipe = usb_sndbulkpipe(dev->udev, dev->out_epAddr); usb_fill_bulk_urb(urb, dev->udev, pipe, data, size, diag_bridge_write_cb, dev); usb_anchor_urb(urb, &dev->submitted); dev->pending_writes++; ret = usb_submit_urb(urb, GFP_KERNEL); if (ret) { dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret); dev->pending_writes--; usb_unanchor_urb(urb); usb_free_urb(urb); usb_autopm_put_interface(dev->ifc); return ret; } #if 0 usb_free_urb(urb); #endif return 0; }