2 * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
3 * Copyright (C) 2015-2016 Samsung Electronics
4 * Igor Kotrasinski <i.kotrasinsk@samsung.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <linux/list.h>
22 #include <linux/kthread.h>
24 #include "usbip_common.h"
27 static int alloc_urb_from_cmd(struct urb
**urbp
,
28 struct usbip_header
*pdu
, u8 type
)
32 if (type
== USB_ENDPOINT_XFER_ISOC
)
33 urb
= usb_alloc_urb(pdu
->u
.cmd_submit
.number_of_packets
,
36 urb
= usb_alloc_urb(0, GFP_KERNEL
);
41 usbip_pack_pdu(pdu
, urb
, USBIP_CMD_SUBMIT
, 0);
43 if (urb
->transfer_buffer_length
> 0) {
44 urb
->transfer_buffer
= kzalloc(urb
->transfer_buffer_length
,
46 if (!urb
->transfer_buffer
)
50 urb
->setup_packet
= kmemdup(&pdu
->u
.cmd_submit
.setup
, 8,
52 if (!urb
->setup_packet
)
56 * FIXME - we only setup pipe enough for usbip functions
59 urb
->pipe
|= pdu
->base
.direction
== USBIP_DIR_IN
?
60 USB_DIR_IN
: USB_DIR_OUT
;
66 kfree(urb
->transfer_buffer
);
67 urb
->transfer_buffer
= NULL
;
74 static int v_recv_cmd_unlink(struct vudc
*udc
,
75 struct usbip_header
*pdu
)
80 spin_lock_irqsave(&udc
->lock
, flags
);
81 list_for_each_entry(urb_p
, &udc
->urb_queue
, urb_entry
) {
82 if (urb_p
->seqnum
!= pdu
->u
.cmd_unlink
.seqnum
)
84 urb_p
->urb
->unlinked
= -ECONNRESET
;
85 urb_p
->seqnum
= pdu
->base
.seqnum
;
86 v_kick_timer(udc
, jiffies
);
87 spin_unlock_irqrestore(&udc
->lock
, flags
);
90 /* Not found, completed / not queued */
91 spin_lock(&udc
->lock_tx
);
92 v_enqueue_ret_unlink(udc
, pdu
->base
.seqnum
, 0);
93 wake_up(&udc
->tx_waitq
);
94 spin_unlock(&udc
->lock_tx
);
95 spin_unlock_irqrestore(&udc
->lock
, flags
);
100 static int v_recv_cmd_submit(struct vudc
*udc
,
101 struct usbip_header
*pdu
)
108 urb_p
= alloc_urbp();
110 usbip_event_add(&udc
->ud
, VUDC_EVENT_ERROR_MALLOC
);
114 /* base.ep is pipeendpoint(pipe) */
115 address
= pdu
->base
.ep
;
116 if (pdu
->base
.direction
== USBIP_DIR_IN
)
117 address
|= USB_DIR_IN
;
119 spin_lock_irq(&udc
->lock
);
120 urb_p
->ep
= vudc_find_endpoint(udc
, address
);
122 /* we don't know the type, there may be isoc data! */
123 dev_err(&udc
->pdev
->dev
, "request to nonexistent endpoint");
124 spin_unlock_irq(&udc
->lock
);
125 usbip_event_add(&udc
->ud
, VUDC_EVENT_ERROR_TCP
);
129 urb_p
->type
= urb_p
->ep
->type
;
130 spin_unlock_irq(&udc
->lock
);
133 urb_p
->seqnum
= pdu
->base
.seqnum
;
135 ret
= alloc_urb_from_cmd(&urb_p
->urb
, pdu
, urb_p
->ep
->type
);
137 usbip_event_add(&udc
->ud
, VUDC_EVENT_ERROR_MALLOC
);
142 urb_p
->urb
->status
= -EINPROGRESS
;
144 /* FIXME: more pipe setup to please usbip_common */
145 urb_p
->urb
->pipe
&= ~(11 << 30);
146 switch (urb_p
->ep
->type
) {
147 case USB_ENDPOINT_XFER_BULK
:
148 urb_p
->urb
->pipe
|= (PIPE_BULK
<< 30);
150 case USB_ENDPOINT_XFER_INT
:
151 urb_p
->urb
->pipe
|= (PIPE_INTERRUPT
<< 30);
153 case USB_ENDPOINT_XFER_CONTROL
:
154 urb_p
->urb
->pipe
|= (PIPE_CONTROL
<< 30);
156 case USB_ENDPOINT_XFER_ISOC
:
157 urb_p
->urb
->pipe
|= (PIPE_ISOCHRONOUS
<< 30);
160 ret
= usbip_recv_xbuff(&udc
->ud
, urb_p
->urb
);
164 ret
= usbip_recv_iso(&udc
->ud
, urb_p
->urb
);
168 spin_lock_irqsave(&udc
->lock
, flags
);
169 v_kick_timer(udc
, jiffies
);
170 list_add_tail(&urb_p
->urb_entry
, &udc
->urb_queue
);
171 spin_unlock_irqrestore(&udc
->lock
, flags
);
176 free_urbp_and_urb(urb_p
);
180 static int v_rx_pdu(struct usbip_device
*ud
)
183 struct usbip_header pdu
;
184 struct vudc
*udc
= container_of(ud
, struct vudc
, ud
);
186 memset(&pdu
, 0, sizeof(pdu
));
187 ret
= usbip_recv(ud
->tcp_socket
, &pdu
, sizeof(pdu
));
188 if (ret
!= sizeof(pdu
)) {
189 usbip_event_add(ud
, VUDC_EVENT_ERROR_TCP
);
194 usbip_header_correct_endian(&pdu
, 0);
196 spin_lock_irq(&ud
->lock
);
197 ret
= (ud
->status
== SDEV_ST_USED
);
198 spin_unlock_irq(&ud
->lock
);
200 usbip_event_add(ud
, VUDC_EVENT_ERROR_TCP
);
204 switch (pdu
.base
.command
) {
205 case USBIP_CMD_UNLINK
:
206 ret
= v_recv_cmd_unlink(udc
, &pdu
);
208 case USBIP_CMD_SUBMIT
:
209 ret
= v_recv_cmd_submit(udc
, &pdu
);
213 pr_err("rx: unknown command");
219 int v_rx_loop(void *data
)
221 struct usbip_device
*ud
= data
;
224 while (!kthread_should_stop()) {
225 if (usbip_event_happened(ud
))
229 pr_warn("v_rx exit with error %d", ret
);