1 /* 2 * Copyright (C) 2015 Karol Kosik <karo9@interia.eu> 3 * Copyright (C) 2015-2016 Samsung Electronics 4 * Igor Kotrasinski <i.kotrasinsk@samsung.com> 5 * 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. 10 * 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. 15 * 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/>. 18 */ 19 20 #include <net/sock.h> 21 #include <linux/list.h> 22 #include <linux/kthread.h> 23 24 #include "usbip_common.h" 25 #include "vudc.h" 26 27 static inline void setup_base_pdu(struct usbip_header_basic *base, 28 __u32 command, __u32 seqnum) 29 { 30 base->command = command; 31 base->seqnum = seqnum; 32 base->devid = 0; 33 base->ep = 0; 34 base->direction = 0; 35 } 36 37 static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urbp *urb_p) 38 { 39 setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, urb_p->seqnum); 40 usbip_pack_pdu(rpdu, urb_p->urb, USBIP_RET_SUBMIT, 1); 41 } 42 43 static void setup_ret_unlink_pdu(struct usbip_header *rpdu, 44 struct v_unlink *unlink) 45 { 46 setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum); 47 rpdu->u.ret_unlink.status = unlink->status; 48 } 49 50 static int v_send_ret_unlink(struct vudc *udc, struct v_unlink *unlink) 51 { 52 struct msghdr msg; 53 struct kvec iov[1]; 54 size_t txsize; 55 56 int ret; 57 struct usbip_header pdu_header; 58 59 txsize = 0; 60 memset(&pdu_header, 0, sizeof(pdu_header)); 61 memset(&msg, 0, sizeof(msg)); 62 memset(&iov, 0, sizeof(iov)); 63 64 /* 1. setup usbip_header */ 65 setup_ret_unlink_pdu(&pdu_header, unlink); 66 usbip_header_correct_endian(&pdu_header, 1); 67 68 iov[0].iov_base = &pdu_header; 69 iov[0].iov_len = sizeof(pdu_header); 70 txsize += sizeof(pdu_header); 71 72 ret = kernel_sendmsg(udc->ud.tcp_socket, &msg, iov, 73 1, txsize); 74 if (ret != txsize) { 75 usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_TCP); 76 if (ret >= 0) 77 return -EPIPE; 78 return ret; 79 } 80 kfree(unlink); 81 82 return txsize; 83 } 84 85 static int v_send_ret_submit(struct vudc *udc, struct urbp *urb_p) 86 { 87 struct urb *urb = urb_p->urb; 88 struct usbip_header pdu_header; 89 struct usbip_iso_packet_descriptor *iso_buffer = NULL; 90 struct kvec *iov = NULL; 91 int iovnum = 0; 92 int ret = 0; 93 size_t txsize; 94 struct msghdr msg; 95 96 txsize = 0; 97 memset(&pdu_header, 0, sizeof(pdu_header)); 98 memset(&msg, 0, sizeof(msg)); 99 100 if (urb_p->type == USB_ENDPOINT_XFER_ISOC) 101 iovnum = 2 + urb->number_of_packets; 102 else 103 iovnum = 2; 104 105 iov = kcalloc(iovnum, sizeof(*iov), GFP_KERNEL); 106 if (!iov) { 107 usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_MALLOC); 108 ret = -ENOMEM; 109 goto out; 110 } 111 iovnum = 0; 112 113 /* 1. setup usbip_header */ 114 setup_ret_submit_pdu(&pdu_header, urb_p); 115 usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", 116 pdu_header.base.seqnum, urb); 117 usbip_header_correct_endian(&pdu_header, 1); 118 119 iov[iovnum].iov_base = &pdu_header; 120 iov[iovnum].iov_len = sizeof(pdu_header); 121 iovnum++; 122 txsize += sizeof(pdu_header); 123 124 /* 2. setup transfer buffer */ 125 if (urb_p->type != USB_ENDPOINT_XFER_ISOC && 126 usb_pipein(urb->pipe) && urb->actual_length > 0) { 127 iov[iovnum].iov_base = urb->transfer_buffer; 128 iov[iovnum].iov_len = urb->actual_length; 129 iovnum++; 130 txsize += urb->actual_length; 131 } else if (urb_p->type == USB_ENDPOINT_XFER_ISOC && 132 usb_pipein(urb->pipe)) { 133 /* FIXME - copypasted from stub_tx, refactor */ 134 int i; 135 136 for (i = 0; i < urb->number_of_packets; i++) { 137 iov[iovnum].iov_base = urb->transfer_buffer + 138 urb->iso_frame_desc[i].offset; 139 iov[iovnum].iov_len = 140 urb->iso_frame_desc[i].actual_length; 141 iovnum++; 142 txsize += urb->iso_frame_desc[i].actual_length; 143 } 144 145 if (txsize != sizeof(pdu_header) + urb->actual_length) { 146 usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_TCP); 147 ret = -EPIPE; 148 goto out; 149 } 150 } 151 /* else - no buffer to send */ 152 153 /* 3. setup iso_packet_descriptor */ 154 if (urb_p->type == USB_ENDPOINT_XFER_ISOC) { 155 ssize_t len = 0; 156 157 iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len); 158 if (!iso_buffer) { 159 usbip_event_add(&udc->ud, 160 VUDC_EVENT_ERROR_MALLOC); 161 ret = -ENOMEM; 162 goto out; 163 } 164 165 iov[iovnum].iov_base = iso_buffer; 166 iov[iovnum].iov_len = len; 167 txsize += len; 168 iovnum++; 169 } 170 171 ret = kernel_sendmsg(udc->ud.tcp_socket, &msg, 172 iov, iovnum, txsize); 173 if (ret != txsize) { 174 usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_TCP); 175 if (ret >= 0) 176 ret = -EPIPE; 177 goto out; 178 } 179 180 out: 181 kfree(iov); 182 kfree(iso_buffer); 183 free_urbp_and_urb(urb_p); 184 if (ret < 0) 185 return ret; 186 return txsize; 187 } 188 189 static int v_send_ret(struct vudc *udc) 190 { 191 unsigned long flags; 192 struct tx_item *txi; 193 size_t total_size = 0; 194 int ret = 0; 195 196 spin_lock_irqsave(&udc->lock_tx, flags); 197 while (!list_empty(&udc->tx_queue)) { 198 txi = list_first_entry(&udc->tx_queue, struct tx_item, 199 tx_entry); 200 list_del(&txi->tx_entry); 201 spin_unlock_irqrestore(&udc->lock_tx, flags); 202 203 switch (txi->type) { 204 case TX_SUBMIT: 205 ret = v_send_ret_submit(udc, txi->s); 206 break; 207 case TX_UNLINK: 208 ret = v_send_ret_unlink(udc, txi->u); 209 break; 210 } 211 kfree(txi); 212 213 if (ret < 0) 214 return ret; 215 216 total_size += ret; 217 218 spin_lock_irqsave(&udc->lock_tx, flags); 219 } 220 221 spin_unlock_irqrestore(&udc->lock_tx, flags); 222 return total_size; 223 } 224 225 226 int v_tx_loop(void *data) 227 { 228 struct usbip_device *ud = (struct usbip_device *) data; 229 struct vudc *udc = container_of(ud, struct vudc, ud); 230 int ret; 231 232 while (!kthread_should_stop()) { 233 if (usbip_event_happened(&udc->ud)) 234 break; 235 ret = v_send_ret(udc); 236 if (ret < 0) { 237 pr_warn("v_tx exit with error %d", ret); 238 break; 239 } 240 wait_event_interruptible(udc->tx_waitq, 241 (!list_empty(&udc->tx_queue) || 242 kthread_should_stop())); 243 } 244 245 return 0; 246 } 247 248 /* called with spinlocks held */ 249 void v_enqueue_ret_unlink(struct vudc *udc, __u32 seqnum, __u32 status) 250 { 251 struct tx_item *txi; 252 struct v_unlink *unlink; 253 254 txi = kzalloc(sizeof(*txi), GFP_ATOMIC); 255 if (!txi) { 256 usbip_event_add(&udc->ud, VDEV_EVENT_ERROR_MALLOC); 257 return; 258 } 259 unlink = kzalloc(sizeof(*unlink), GFP_ATOMIC); 260 if (!unlink) { 261 kfree(txi); 262 usbip_event_add(&udc->ud, VDEV_EVENT_ERROR_MALLOC); 263 return; 264 } 265 266 unlink->seqnum = seqnum; 267 unlink->status = status; 268 txi->type = TX_UNLINK; 269 txi->u = unlink; 270 271 list_add_tail(&txi->tx_entry, &udc->tx_queue); 272 } 273 274 /* called with spinlocks held */ 275 void v_enqueue_ret_submit(struct vudc *udc, struct urbp *urb_p) 276 { 277 struct tx_item *txi; 278 279 txi = kzalloc(sizeof(*txi), GFP_ATOMIC); 280 if (!txi) { 281 usbip_event_add(&udc->ud, VDEV_EVENT_ERROR_MALLOC); 282 return; 283 } 284 285 txi->type = TX_SUBMIT; 286 txi->s = urb_p; 287 288 list_add_tail(&txi->tx_entry, &udc->tx_queue); 289 } 290