int sipc4_rx(struct sipc4_rx_data *data) { struct net_device *dev = data->dev; struct sk_buff *skb; int ch; /* non HDLC frame */ if (!(data->flags & SIPC4_RX_HDLC)) { ch = SIPC4_NOT_HDLC_CH; /* get socket buffer */ if (!data->skb) { skb = sipc4_alloc_skb(data, 0); if (!skb) return -ENOMEM; data->skb = skb; } else skb = data->skb; /* handle data */ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, data->page, 0, data->size); /* rx data */ if ((data->flags & SIPC4_RX_LAST) || !mc_is_modem_active()) { data->skb = NULL; sipc4_netif_rx(dev, skb, SIPC4_RES(SIPC4_FMT, ch)); } return 0; } return sipc4_hdlc_rx(data); }
static void usbsvn_disconnect(struct usb_interface *intf) { struct usbsvn *svn = usb_get_intfdata(intf); struct usb_device *usbdev = svn->usbdev; int dev_id = intf->altsetting->desc.bInterfaceNumber / 2; struct device *ppdev; if (svn->devdata[dev_id].disconnected) return; svn->usbsvn_connected = 0; svn->flow_suspend = 1; dev_err(&usbdev->dev, "%s\n", __func__); svn->dev_count--; svn->devdata[dev_id].disconnected = 1; usb_driver_release_interface(&usbsvn_driver, svn->devdata[dev_id].data_intf); ppdev = usbdev->dev.parent->parent; pm_runtime_forbid(ppdev); /*ehci*/ usb_put_dev(usbdev); if (svn->dev_count == 0) { svn->usbdev = NULL; cancel_delayed_work_sync(&svn->pm_runtime_work); cancel_work_sync(&svn->post_resume_work); if (!svn->driver_info) { /*TODO:check the Phone ACTIVE pin*/ #ifdef CONFIG_SAMSUNG_PHONE_SVNET if (mc_is_modem_active()) { svn->reconnect_cnt = 2; schedule_delayed_work(&svn->try_reconnect_work, 10); } #endif wake_unlock_pm(svn); } } }