xref: /openbmc/linux/drivers/usb/usbip/vhci_rx.c (revision 65417d9f)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2003-2008 Takahiro Hirofuchi
4  */
5 
6 #include <linux/kthread.h>
7 #include <linux/slab.h>
8 
9 #include "usbip_common.h"
10 #include "vhci.h"
11 
12 /* get URB from transmitted urb queue. caller must hold vdev->priv_lock */
13 struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum)
14 {
15 	struct vhci_priv *priv, *tmp;
16 	struct urb *urb = NULL;
17 	int status;
18 
19 	list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
20 		if (priv->seqnum != seqnum)
21 			continue;
22 
23 		urb = priv->urb;
24 		status = urb->status;
25 
26 		usbip_dbg_vhci_rx("find urb %p vurb %p seqnum %u\n",
27 				urb, priv, seqnum);
28 
29 		switch (status) {
30 		case -ENOENT:
31 			/* fall through */
32 		case -ECONNRESET:
33 			dev_info(&urb->dev->dev,
34 				 "urb %p was unlinked %ssynchronuously.\n", urb,
35 				 status == -ENOENT ? "" : "a");
36 			break;
37 		case -EINPROGRESS:
38 			/* no info output */
39 			break;
40 		default:
41 			dev_info(&urb->dev->dev,
42 				 "urb %p may be in a error, status %d\n", urb,
43 				 status);
44 		}
45 
46 		list_del(&priv->list);
47 		kfree(priv);
48 		urb->hcpriv = NULL;
49 
50 		break;
51 	}
52 
53 	return urb;
54 }
55 
56 static void vhci_recv_ret_submit(struct vhci_device *vdev,
57 				 struct usbip_header *pdu)
58 {
59 	struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev);
60 	struct vhci *vhci = vhci_hcd->vhci;
61 	struct usbip_device *ud = &vdev->ud;
62 	struct urb *urb;
63 	unsigned long flags;
64 
65 	spin_lock_irqsave(&vdev->priv_lock, flags);
66 	urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
67 	spin_unlock_irqrestore(&vdev->priv_lock, flags);
68 
69 	if (!urb) {
70 		pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
71 		pr_info("max seqnum %d\n",
72 			atomic_read(&vhci_hcd->seqnum));
73 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
74 		return;
75 	}
76 
77 	/* unpack the pdu to a urb */
78 	usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
79 
80 	/* recv transfer buffer */
81 	if (usbip_recv_xbuff(ud, urb) < 0)
82 		return;
83 
84 	/* recv iso_packet_descriptor */
85 	if (usbip_recv_iso(ud, urb) < 0)
86 		return;
87 
88 	/* restore the padding in iso packets */
89 	usbip_pad_iso(ud, urb);
90 
91 	if (usbip_dbg_flag_vhci_rx)
92 		usbip_dump_urb(urb);
93 
94 	usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
95 
96 	spin_lock_irqsave(&vhci->lock, flags);
97 	usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci_hcd), urb);
98 	spin_unlock_irqrestore(&vhci->lock, flags);
99 
100 	usb_hcd_giveback_urb(vhci_hcd_to_hcd(vhci_hcd), urb, urb->status);
101 
102 	usbip_dbg_vhci_rx("Leave\n");
103 }
104 
105 static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
106 						  struct usbip_header *pdu)
107 {
108 	struct vhci_unlink *unlink, *tmp;
109 	unsigned long flags;
110 
111 	spin_lock_irqsave(&vdev->priv_lock, flags);
112 
113 	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
114 		pr_info("unlink->seqnum %lu\n", unlink->seqnum);
115 		if (unlink->seqnum == pdu->base.seqnum) {
116 			usbip_dbg_vhci_rx("found pending unlink, %lu\n",
117 					  unlink->seqnum);
118 			list_del(&unlink->list);
119 
120 			spin_unlock_irqrestore(&vdev->priv_lock, flags);
121 			return unlink;
122 		}
123 	}
124 
125 	spin_unlock_irqrestore(&vdev->priv_lock, flags);
126 
127 	return NULL;
128 }
129 
130 static void vhci_recv_ret_unlink(struct vhci_device *vdev,
131 				 struct usbip_header *pdu)
132 {
133 	struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev);
134 	struct vhci *vhci = vhci_hcd->vhci;
135 	struct vhci_unlink *unlink;
136 	struct urb *urb;
137 	unsigned long flags;
138 
139 	usbip_dump_header(pdu);
140 
141 	unlink = dequeue_pending_unlink(vdev, pdu);
142 	if (!unlink) {
143 		pr_info("cannot find the pending unlink %u\n",
144 			pdu->base.seqnum);
145 		return;
146 	}
147 
148 	spin_lock_irqsave(&vdev->priv_lock, flags);
149 	urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
150 	spin_unlock_irqrestore(&vdev->priv_lock, flags);
151 
152 	if (!urb) {
153 		/*
154 		 * I get the result of a unlink request. But, it seems that I
155 		 * already received the result of its submit result and gave
156 		 * back the URB.
157 		 */
158 		pr_info("the urb (seqnum %d) was already given back\n",
159 			pdu->base.seqnum);
160 	} else {
161 		usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
162 
163 		/* If unlink is successful, status is -ECONNRESET */
164 		urb->status = pdu->u.ret_unlink.status;
165 		pr_info("urb->status %d\n", urb->status);
166 
167 		spin_lock_irqsave(&vhci->lock, flags);
168 		usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci_hcd), urb);
169 		spin_unlock_irqrestore(&vhci->lock, flags);
170 
171 		usb_hcd_giveback_urb(vhci_hcd_to_hcd(vhci_hcd), urb, urb->status);
172 	}
173 
174 	kfree(unlink);
175 }
176 
177 static int vhci_priv_tx_empty(struct vhci_device *vdev)
178 {
179 	int empty = 0;
180 	unsigned long flags;
181 
182 	spin_lock_irqsave(&vdev->priv_lock, flags);
183 	empty = list_empty(&vdev->priv_rx);
184 	spin_unlock_irqrestore(&vdev->priv_lock, flags);
185 
186 	return empty;
187 }
188 
189 /* recv a pdu */
190 static void vhci_rx_pdu(struct usbip_device *ud)
191 {
192 	int ret;
193 	struct usbip_header pdu;
194 	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
195 
196 	usbip_dbg_vhci_rx("Enter\n");
197 
198 	memset(&pdu, 0, sizeof(pdu));
199 
200 	/* receive a pdu header */
201 	ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu));
202 	if (ret < 0) {
203 		if (ret == -ECONNRESET)
204 			pr_info("connection reset by peer\n");
205 		else if (ret == -EAGAIN) {
206 			/* ignore if connection was idle */
207 			if (vhci_priv_tx_empty(vdev))
208 				return;
209 			pr_info("connection timed out with pending urbs\n");
210 		} else if (ret != -ERESTARTSYS)
211 			pr_info("xmit failed %d\n", ret);
212 
213 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
214 		return;
215 	}
216 	if (ret == 0) {
217 		pr_info("connection closed");
218 		usbip_event_add(ud, VDEV_EVENT_DOWN);
219 		return;
220 	}
221 	if (ret != sizeof(pdu)) {
222 		pr_err("received pdu size is %d, should be %d\n", ret,
223 		       (unsigned int)sizeof(pdu));
224 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
225 		return;
226 	}
227 
228 	usbip_header_correct_endian(&pdu, 0);
229 
230 	if (usbip_dbg_flag_vhci_rx)
231 		usbip_dump_header(&pdu);
232 
233 	switch (pdu.base.command) {
234 	case USBIP_RET_SUBMIT:
235 		vhci_recv_ret_submit(vdev, &pdu);
236 		break;
237 	case USBIP_RET_UNLINK:
238 		vhci_recv_ret_unlink(vdev, &pdu);
239 		break;
240 	default:
241 		/* NOT REACHED */
242 		pr_err("unknown pdu %u\n", pdu.base.command);
243 		usbip_dump_header(&pdu);
244 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
245 		break;
246 	}
247 }
248 
249 int vhci_rx_loop(void *data)
250 {
251 	struct usbip_device *ud = data;
252 
253 	while (!kthread_should_stop()) {
254 		if (usbip_event_happened(ud))
255 			break;
256 
257 		vhci_rx_pdu(ud);
258 	}
259 
260 	return 0;
261 }
262