stub_tx.c revision 4d7b5c7f8ad49b7f01fb8aed83c560ac43cfbda8
1/*
2 * Copyright (C) 2003-2008 Takahiro Hirofuchi
3 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19
20#include "usbip_common.h"
21#include "stub.h"
22
23
24static void stub_free_priv_and_urb(struct stub_priv *priv)
25{
26	struct urb *urb = priv->urb;
27
28	kfree(urb->setup_packet);
29	kfree(urb->transfer_buffer);
30	list_del(&priv->list);
31	kmem_cache_free(stub_priv_cache, priv);
32	usb_free_urb(urb);
33}
34
35/* be in spin_lock_irqsave(&sdev->priv_lock, flags) */
36void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum,
37			     __u32 status)
38{
39	struct stub_unlink *unlink;
40
41	unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC);
42	if (!unlink) {
43		dev_err(&sdev->interface->dev, "alloc stub_unlink\n");
44		usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC);
45		return;
46	}
47
48	unlink->seqnum = seqnum;
49	unlink->status = status;
50
51	list_add_tail(&unlink->list, &sdev->unlink_tx);
52}
53
54/**
55 * stub_complete - completion handler of a usbip urb
56 * @urb: pointer to the urb completed
57 * @regs:
58 *
59 * When a urb has completed, the USB core driver calls this function mostly in
60 * the interrupt context. To return the result of a urb, the completed urb is
61 * linked to the pending list of returning.
62 *
63 */
64void stub_complete(struct urb *urb)
65{
66	struct stub_priv *priv = (struct stub_priv *) urb->context;
67	struct stub_device *sdev = priv->sdev;
68	unsigned long flags;
69
70	dbg_stub_tx("complete! status %d\n", urb->status);
71
72
73	switch (urb->status) {
74	case 0:
75		/* OK */
76		break;
77	case -ENOENT:
78		uinfo("stopped by a call of usb_kill_urb() because of"
79					"cleaning up a virtual connection\n");
80		return;
81	case -ECONNRESET:
82		uinfo("unlinked by a call of usb_unlink_urb()\n");
83		break;
84	case -EPIPE:
85		uinfo("endpoint %d is stalled\n", usb_pipeendpoint(urb->pipe));
86		break;
87	case -ESHUTDOWN:
88		uinfo("device removed?\n");
89		break;
90	default:
91		uinfo("urb completion with non-zero status %d\n", urb->status);
92	}
93
94	/* link a urb to the queue of tx. */
95	spin_lock_irqsave(&sdev->priv_lock, flags);
96
97	if (priv->unlinking) {
98		stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status);
99		stub_free_priv_and_urb(priv);
100	} else
101		list_move_tail(&priv->list, &sdev->priv_tx);
102
103
104	spin_unlock_irqrestore(&sdev->priv_lock, flags);
105
106	/* wake up tx_thread */
107	wake_up(&sdev->tx_waitq);
108}
109
110
111/*-------------------------------------------------------------------------*/
112/* fill PDU */
113
114static inline void setup_base_pdu(struct usbip_header_basic *base,
115		__u32 command, __u32 seqnum)
116{
117	base->command = command;
118	base->seqnum  = seqnum;
119	base->devid   = 0;
120	base->ep      = 0;
121	base->direction   = 0;
122}
123
124static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb)
125{
126	struct stub_priv *priv = (struct stub_priv *) urb->context;
127
128	setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum);
129
130	usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1);
131}
132
133static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
134		struct stub_unlink *unlink)
135{
136	setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
137
138	rpdu->u.ret_unlink.status = unlink->status;
139}
140
141
142/*-------------------------------------------------------------------------*/
143/* send RET_SUBMIT */
144
145static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev)
146{
147	unsigned long flags;
148	struct stub_priv *priv, *tmp;
149
150	spin_lock_irqsave(&sdev->priv_lock, flags);
151
152	list_for_each_entry_safe(priv, tmp, &sdev->priv_tx, list) {
153		list_move_tail(&priv->list, &sdev->priv_free);
154		spin_unlock_irqrestore(&sdev->priv_lock, flags);
155		return priv;
156	}
157
158	spin_unlock_irqrestore(&sdev->priv_lock, flags);
159
160	return NULL;
161}
162
163static int stub_send_ret_submit(struct stub_device *sdev)
164{
165	unsigned long flags;
166	struct stub_priv *priv, *tmp;
167
168	struct msghdr msg;
169	struct kvec iov[3];
170	size_t txsize;
171
172	size_t total_size = 0;
173
174	while ((priv = dequeue_from_priv_tx(sdev)) != NULL) {
175		int ret;
176		struct urb *urb = priv->urb;
177		struct usbip_header pdu_header;
178		void *iso_buffer = NULL;
179
180		txsize = 0;
181		memset(&pdu_header, 0, sizeof(pdu_header));
182		memset(&msg, 0, sizeof(msg));
183		memset(&iov, 0, sizeof(iov));
184
185		dbg_stub_tx("setup txdata urb %p\n", urb);
186
187
188		/* 1. setup usbip_header */
189		setup_ret_submit_pdu(&pdu_header, urb);
190		usbip_header_correct_endian(&pdu_header, 1);
191
192		iov[0].iov_base = &pdu_header;
193		iov[0].iov_len  = sizeof(pdu_header);
194		txsize += sizeof(pdu_header);
195
196		/* 2. setup transfer buffer */
197		if (usb_pipein(urb->pipe) && urb->actual_length > 0) {
198			iov[1].iov_base = urb->transfer_buffer;
199			iov[1].iov_len  = urb->actual_length;
200			txsize += urb->actual_length;
201		}
202
203		/* 3. setup iso_packet_descriptor */
204		if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
205			ssize_t len = 0;
206
207			iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
208			if (!iso_buffer) {
209				usbip_event_add(&sdev->ud,
210						SDEV_EVENT_ERROR_MALLOC);
211				return -1;
212			}
213
214			iov[2].iov_base = iso_buffer;
215			iov[2].iov_len  = len;
216			txsize += len;
217		}
218
219		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov,
220				     3, txsize);
221		if (ret != txsize) {
222			dev_err(&sdev->interface->dev,
223				"sendmsg failed!, retval %d for %zd\n",
224				ret, txsize);
225			kfree(iso_buffer);
226			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
227			return -1;
228		}
229
230		kfree(iso_buffer);
231		dbg_stub_tx("send txdata\n");
232
233		total_size += txsize;
234	}
235
236
237	spin_lock_irqsave(&sdev->priv_lock, flags);
238
239	list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) {
240		stub_free_priv_and_urb(priv);
241	}
242
243	spin_unlock_irqrestore(&sdev->priv_lock, flags);
244
245	return total_size;
246}
247
248
249/*-------------------------------------------------------------------------*/
250/* send RET_UNLINK */
251
252static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev)
253{
254	unsigned long flags;
255	struct stub_unlink *unlink, *tmp;
256
257	spin_lock_irqsave(&sdev->priv_lock, flags);
258
259	list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) {
260		list_move_tail(&unlink->list, &sdev->unlink_free);
261		spin_unlock_irqrestore(&sdev->priv_lock, flags);
262		return unlink;
263	}
264
265	spin_unlock_irqrestore(&sdev->priv_lock, flags);
266
267	return NULL;
268}
269
270
271static int stub_send_ret_unlink(struct stub_device *sdev)
272{
273	unsigned long flags;
274	struct stub_unlink *unlink, *tmp;
275
276	struct msghdr msg;
277	struct kvec iov[1];
278	size_t txsize;
279
280	size_t total_size = 0;
281
282	while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) {
283		int ret;
284		struct usbip_header pdu_header;
285
286		txsize = 0;
287		memset(&pdu_header, 0, sizeof(pdu_header));
288		memset(&msg, 0, sizeof(msg));
289		memset(&iov, 0, sizeof(iov));
290
291		dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum);
292
293		/* 1. setup usbip_header */
294		setup_ret_unlink_pdu(&pdu_header, unlink);
295		usbip_header_correct_endian(&pdu_header, 1);
296
297		iov[0].iov_base = &pdu_header;
298		iov[0].iov_len  = sizeof(pdu_header);
299		txsize += sizeof(pdu_header);
300
301		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov,
302				     1, txsize);
303		if (ret != txsize) {
304			dev_err(&sdev->interface->dev,
305				"sendmsg failed!, retval %d for %zd\n",
306				ret, txsize);
307			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
308			return -1;
309		}
310
311
312		dbg_stub_tx("send txdata\n");
313
314		total_size += txsize;
315	}
316
317
318	spin_lock_irqsave(&sdev->priv_lock, flags);
319
320	list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) {
321		list_del(&unlink->list);
322		kfree(unlink);
323	}
324
325	spin_unlock_irqrestore(&sdev->priv_lock, flags);
326
327	return total_size;
328}
329
330
331/*-------------------------------------------------------------------------*/
332
333void stub_tx_loop(struct usbip_task *ut)
334{
335	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
336	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
337
338	while (1) {
339		if (signal_pending(current)) {
340			dbg_stub_tx("signal catched\n");
341			break;
342		}
343
344		if (usbip_event_happend(ud))
345			break;
346
347		/*
348		 * send_ret_submit comes earlier than send_ret_unlink.  stub_rx
349		 * looks at only priv_init queue. If the completion of a URB is
350		 * earlier than the receive of CMD_UNLINK, priv is moved to
351		 * priv_tx queue and stub_rx does not find the target priv. In
352		 * this case, vhci_rx receives the result of the submit request
353		 * and then receives the result of the unlink request. The
354		 * result of the submit is given back to the usbcore as the
355		 * completion of the unlink request. The request of the
356		 * unlink is ignored. This is ok because a driver who calls
357		 * usb_unlink_urb() understands the unlink was too late by
358		 * getting the status of the given-backed URB which has the
359		 * status of usb_submit_urb().
360		 */
361		if (stub_send_ret_submit(sdev) < 0)
362			break;
363
364		if (stub_send_ret_unlink(sdev) < 0)
365			break;
366
367		wait_event_interruptible(sdev->tx_waitq,
368				(!list_empty(&sdev->priv_tx) ||
369				 !list_empty(&sdev->unlink_tx)));
370	}
371}
372