Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (C) 2003-2008 Takahiro Hirofuchi
0004  */
0005 
0006 #include <linux/kthread.h>
0007 #include <linux/slab.h>
0008 
0009 #include "usbip_common.h"
0010 #include "vhci.h"
0011 
0012 /* get URB from transmitted urb queue. caller must hold vdev->priv_lock */
0013 struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum)
0014 {
0015     struct vhci_priv *priv, *tmp;
0016     struct urb *urb = NULL;
0017     int status;
0018 
0019     list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
0020         if (priv->seqnum != seqnum)
0021             continue;
0022 
0023         urb = priv->urb;
0024         status = urb->status;
0025 
0026         usbip_dbg_vhci_rx("find urb seqnum %u\n", seqnum);
0027 
0028         switch (status) {
0029         case -ENOENT:
0030             fallthrough;
0031         case -ECONNRESET:
0032             dev_dbg(&urb->dev->dev,
0033                  "urb seq# %u was unlinked %ssynchronously\n",
0034                  seqnum, status == -ENOENT ? "" : "a");
0035             break;
0036         case -EINPROGRESS:
0037             /* no info output */
0038             break;
0039         default:
0040             dev_dbg(&urb->dev->dev,
0041                  "urb seq# %u may be in a error, status %d\n",
0042                  seqnum, status);
0043         }
0044 
0045         list_del(&priv->list);
0046         kfree(priv);
0047         urb->hcpriv = NULL;
0048 
0049         break;
0050     }
0051 
0052     return urb;
0053 }
0054 
0055 static void vhci_recv_ret_submit(struct vhci_device *vdev,
0056                  struct usbip_header *pdu)
0057 {
0058     struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev);
0059     struct vhci *vhci = vhci_hcd->vhci;
0060     struct usbip_device *ud = &vdev->ud;
0061     struct urb *urb;
0062     unsigned long flags;
0063 
0064     spin_lock_irqsave(&vdev->priv_lock, flags);
0065     urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
0066     spin_unlock_irqrestore(&vdev->priv_lock, flags);
0067 
0068     if (!urb) {
0069         pr_err("cannot find a urb of seqnum %u max seqnum %d\n",
0070             pdu->base.seqnum,
0071             atomic_read(&vhci_hcd->seqnum));
0072         usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
0073         return;
0074     }
0075 
0076     /* unpack the pdu to a urb */
0077     usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
0078 
0079     /* recv transfer buffer */
0080     if (usbip_recv_xbuff(ud, urb) < 0) {
0081         urb->status = -EPROTO;
0082         goto error;
0083     }
0084 
0085     /* recv iso_packet_descriptor */
0086     if (usbip_recv_iso(ud, urb) < 0) {
0087         urb->status = -EPROTO;
0088         goto error;
0089     }
0090 
0091     /* restore the padding in iso packets */
0092     usbip_pad_iso(ud, urb);
0093 
0094 error:
0095     if (usbip_dbg_flag_vhci_rx)
0096         usbip_dump_urb(urb);
0097 
0098     if (urb->num_sgs)
0099         urb->transfer_flags &= ~URB_DMA_MAP_SG;
0100 
0101     usbip_dbg_vhci_rx("now giveback urb %u\n", pdu->base.seqnum);
0102 
0103     spin_lock_irqsave(&vhci->lock, flags);
0104     usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci_hcd), urb);
0105     spin_unlock_irqrestore(&vhci->lock, flags);
0106 
0107     usb_hcd_giveback_urb(vhci_hcd_to_hcd(vhci_hcd), urb, urb->status);
0108 
0109     usbip_dbg_vhci_rx("Leave\n");
0110 }
0111 
0112 static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
0113                           struct usbip_header *pdu)
0114 {
0115     struct vhci_unlink *unlink, *tmp;
0116     unsigned long flags;
0117 
0118     spin_lock_irqsave(&vdev->priv_lock, flags);
0119 
0120     list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
0121         pr_info("unlink->seqnum %lu\n", unlink->seqnum);
0122         if (unlink->seqnum == pdu->base.seqnum) {
0123             usbip_dbg_vhci_rx("found pending unlink, %lu\n",
0124                       unlink->seqnum);
0125             list_del(&unlink->list);
0126 
0127             spin_unlock_irqrestore(&vdev->priv_lock, flags);
0128             return unlink;
0129         }
0130     }
0131 
0132     spin_unlock_irqrestore(&vdev->priv_lock, flags);
0133 
0134     return NULL;
0135 }
0136 
0137 static void vhci_recv_ret_unlink(struct vhci_device *vdev,
0138                  struct usbip_header *pdu)
0139 {
0140     struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev);
0141     struct vhci *vhci = vhci_hcd->vhci;
0142     struct vhci_unlink *unlink;
0143     struct urb *urb;
0144     unsigned long flags;
0145 
0146     usbip_dump_header(pdu);
0147 
0148     unlink = dequeue_pending_unlink(vdev, pdu);
0149     if (!unlink) {
0150         pr_info("cannot find the pending unlink %u\n",
0151             pdu->base.seqnum);
0152         return;
0153     }
0154 
0155     spin_lock_irqsave(&vdev->priv_lock, flags);
0156     urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
0157     spin_unlock_irqrestore(&vdev->priv_lock, flags);
0158 
0159     if (!urb) {
0160         /*
0161          * I get the result of a unlink request. But, it seems that I
0162          * already received the result of its submit result and gave
0163          * back the URB.
0164          */
0165         pr_info("the urb (seqnum %d) was already given back\n",
0166             pdu->base.seqnum);
0167     } else {
0168         usbip_dbg_vhci_rx("now giveback urb %d\n", pdu->base.seqnum);
0169 
0170         /* If unlink is successful, status is -ECONNRESET */
0171         urb->status = pdu->u.ret_unlink.status;
0172         pr_info("urb->status %d\n", urb->status);
0173 
0174         spin_lock_irqsave(&vhci->lock, flags);
0175         usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci_hcd), urb);
0176         spin_unlock_irqrestore(&vhci->lock, flags);
0177 
0178         usb_hcd_giveback_urb(vhci_hcd_to_hcd(vhci_hcd), urb, urb->status);
0179     }
0180 
0181     kfree(unlink);
0182 }
0183 
0184 static int vhci_priv_tx_empty(struct vhci_device *vdev)
0185 {
0186     int empty = 0;
0187     unsigned long flags;
0188 
0189     spin_lock_irqsave(&vdev->priv_lock, flags);
0190     empty = list_empty(&vdev->priv_rx);
0191     spin_unlock_irqrestore(&vdev->priv_lock, flags);
0192 
0193     return empty;
0194 }
0195 
0196 /* recv a pdu */
0197 static void vhci_rx_pdu(struct usbip_device *ud)
0198 {
0199     int ret;
0200     struct usbip_header pdu;
0201     struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
0202 
0203     usbip_dbg_vhci_rx("Enter\n");
0204 
0205     memset(&pdu, 0, sizeof(pdu));
0206 
0207     /* receive a pdu header */
0208     ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu));
0209     if (ret < 0) {
0210         if (ret == -ECONNRESET)
0211             pr_info("connection reset by peer\n");
0212         else if (ret == -EAGAIN) {
0213             /* ignore if connection was idle */
0214             if (vhci_priv_tx_empty(vdev))
0215                 return;
0216             pr_info("connection timed out with pending urbs\n");
0217         } else if (ret != -ERESTARTSYS)
0218             pr_info("xmit failed %d\n", ret);
0219 
0220         usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
0221         return;
0222     }
0223     if (ret == 0) {
0224         pr_info("connection closed");
0225         usbip_event_add(ud, VDEV_EVENT_DOWN);
0226         return;
0227     }
0228     if (ret != sizeof(pdu)) {
0229         pr_err("received pdu size is %d, should be %d\n", ret,
0230                (unsigned int)sizeof(pdu));
0231         usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
0232         return;
0233     }
0234 
0235     usbip_header_correct_endian(&pdu, 0);
0236 
0237     if (usbip_dbg_flag_vhci_rx)
0238         usbip_dump_header(&pdu);
0239 
0240     switch (pdu.base.command) {
0241     case USBIP_RET_SUBMIT:
0242         vhci_recv_ret_submit(vdev, &pdu);
0243         break;
0244     case USBIP_RET_UNLINK:
0245         vhci_recv_ret_unlink(vdev, &pdu);
0246         break;
0247     default:
0248         /* NOT REACHED */
0249         pr_err("unknown pdu %u\n", pdu.base.command);
0250         usbip_dump_header(&pdu);
0251         usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
0252         break;
0253     }
0254 }
0255 
0256 int vhci_rx_loop(void *data)
0257 {
0258     struct usbip_device *ud = data;
0259 
0260     while (!kthread_should_stop()) {
0261         if (usbip_event_happened(ud))
0262             break;
0263 
0264         usbip_kcov_remote_start(ud);
0265         vhci_rx_pdu(ud);
0266         usbip_kcov_remote_stop();
0267     }
0268 
0269     return 0;
0270 }