1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2015 Karol Kosik <karo9@interia.eu> 4 * Copyright (C) 2015-2016 Samsung Electronics 5 * Igor Kotrasinski <i.kotrasinsk@samsung.com> 6 */ 7 8 #include <net/sock.h> 9 #include <linux/list.h> 10 #include <linux/kthread.h> 11 12 #include "usbip_common.h" 13 #include "vudc.h" 14 15 static int alloc_urb_from_cmd(struct urb **urbp, 16 struct usbip_header *pdu, u8 type) 17 { 18 struct urb *urb; 19 20 if (type == USB_ENDPOINT_XFER_ISOC) 21 urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets, 22 GFP_KERNEL); 23 else 24 urb = usb_alloc_urb(0, GFP_KERNEL); 25 26 if (!urb) 27 goto err; 28 29 usbip_pack_pdu(pdu, urb, USBIP_CMD_SUBMIT, 0); 30 31 if (urb->transfer_buffer_length > 0) { 32 urb->transfer_buffer = kzalloc(urb->transfer_buffer_length, 33 GFP_KERNEL); 34 if (!urb->transfer_buffer) 35 goto free_urb; 36 } 37 38 urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8, 39 GFP_KERNEL); 40 if (!urb->setup_packet) 41 goto free_buffer; 42 43 /* 44 * FIXME - we only setup pipe enough for usbip functions 45 * to behave nicely 46 */ 47 urb->pipe |= pdu->base.direction == USBIP_DIR_IN ? 48 USB_DIR_IN : USB_DIR_OUT; 49 50 *urbp = urb; 51 return 0; 52 53 free_buffer: 54 kfree(urb->transfer_buffer); 55 urb->transfer_buffer = NULL; 56 free_urb: 57 usb_free_urb(urb); 58 err: 59 return -ENOMEM; 60 } 61 62 static int v_recv_cmd_unlink(struct vudc *udc, 63 struct usbip_header *pdu) 64 { 65 unsigned long flags; 66 struct urbp *urb_p; 67 68 spin_lock_irqsave(&udc->lock, flags); 69 list_for_each_entry(urb_p, &udc->urb_queue, urb_entry) { 70 if (urb_p->seqnum != pdu->u.cmd_unlink.seqnum) 71 continue; 72 urb_p->urb->unlinked = -ECONNRESET; 73 urb_p->seqnum = pdu->base.seqnum; 74 v_kick_timer(udc, jiffies); 75 spin_unlock_irqrestore(&udc->lock, flags); 76 return 0; 77 } 78 /* Not found, completed / not queued */ 79 spin_lock(&udc->lock_tx); 80 v_enqueue_ret_unlink(udc, pdu->base.seqnum, 0); 81 wake_up(&udc->tx_waitq); 82 spin_unlock(&udc->lock_tx); 83 spin_unlock_irqrestore(&udc->lock, flags); 84 85 return 0; 86 } 87 88 static int v_recv_cmd_submit(struct vudc *udc, 89 struct usbip_header *pdu) 90 { 91 int ret = 0; 92 struct urbp *urb_p; 93 u8 address; 94 unsigned long flags; 95 96 urb_p = alloc_urbp(); 97 if (!urb_p) { 98 usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_MALLOC); 99 return -ENOMEM; 100 } 101 102 /* base.ep is pipeendpoint(pipe) */ 103 address = pdu->base.ep; 104 if (pdu->base.direction == USBIP_DIR_IN) 105 address |= USB_DIR_IN; 106 107 spin_lock_irqsave(&udc->lock, flags); 108 urb_p->ep = vudc_find_endpoint(udc, address); 109 if (!urb_p->ep) { 110 /* we don't know the type, there may be isoc data! */ 111 dev_err(&udc->pdev->dev, "request to nonexistent endpoint"); 112 spin_unlock_irqrestore(&udc->lock, flags); 113 usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_TCP); 114 ret = -EPIPE; 115 goto free_urbp; 116 } 117 urb_p->type = urb_p->ep->type; 118 spin_unlock_irqrestore(&udc->lock, flags); 119 120 urb_p->new = 1; 121 urb_p->seqnum = pdu->base.seqnum; 122 123 if (urb_p->ep->type == USB_ENDPOINT_XFER_ISOC) { 124 /* validate packet size and number of packets */ 125 unsigned int maxp, packets, bytes; 126 127 maxp = usb_endpoint_maxp(urb_p->ep->desc); 128 maxp *= usb_endpoint_maxp_mult(urb_p->ep->desc); 129 bytes = pdu->u.cmd_submit.transfer_buffer_length; 130 packets = DIV_ROUND_UP(bytes, maxp); 131 132 if (pdu->u.cmd_submit.number_of_packets < 0 || 133 pdu->u.cmd_submit.number_of_packets > packets) { 134 dev_err(&udc->gadget.dev, 135 "CMD_SUBMIT: isoc invalid num packets %d\n", 136 pdu->u.cmd_submit.number_of_packets); 137 ret = -EMSGSIZE; 138 goto free_urbp; 139 } 140 } 141 142 ret = alloc_urb_from_cmd(&urb_p->urb, pdu, urb_p->ep->type); 143 if (ret) { 144 usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_MALLOC); 145 ret = -ENOMEM; 146 goto free_urbp; 147 } 148 149 urb_p->urb->status = -EINPROGRESS; 150 151 /* FIXME: more pipe setup to please usbip_common */ 152 BUILD_BUG_ON_MSG(PIPE_BULK != 3, "PIPE_* doesn't range from 0 to 3"); 153 154 urb_p->urb->pipe &= ~(PIPE_BULK << 30); 155 switch (urb_p->ep->type) { 156 case USB_ENDPOINT_XFER_BULK: 157 urb_p->urb->pipe |= (PIPE_BULK << 30); 158 break; 159 case USB_ENDPOINT_XFER_INT: 160 urb_p->urb->pipe |= (PIPE_INTERRUPT << 30); 161 break; 162 case USB_ENDPOINT_XFER_CONTROL: 163 urb_p->urb->pipe |= (PIPE_CONTROL << 30); 164 break; 165 case USB_ENDPOINT_XFER_ISOC: 166 urb_p->urb->pipe |= (PIPE_ISOCHRONOUS << 30); 167 break; 168 } 169 ret = usbip_recv_xbuff(&udc->ud, urb_p->urb); 170 if (ret < 0) 171 goto free_urbp; 172 173 ret = usbip_recv_iso(&udc->ud, urb_p->urb); 174 if (ret < 0) 175 goto free_urbp; 176 177 spin_lock_irqsave(&udc->lock, flags); 178 v_kick_timer(udc, jiffies); 179 list_add_tail(&urb_p->urb_entry, &udc->urb_queue); 180 spin_unlock_irqrestore(&udc->lock, flags); 181 182 return 0; 183 184 free_urbp: 185 free_urbp_and_urb(urb_p); 186 return ret; 187 } 188 189 static int v_rx_pdu(struct usbip_device *ud) 190 { 191 int ret; 192 struct usbip_header pdu; 193 struct vudc *udc = container_of(ud, struct vudc, ud); 194 195 memset(&pdu, 0, sizeof(pdu)); 196 ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu)); 197 if (ret != sizeof(pdu)) { 198 usbip_event_add(ud, VUDC_EVENT_ERROR_TCP); 199 if (ret >= 0) 200 return -EPIPE; 201 return ret; 202 } 203 usbip_header_correct_endian(&pdu, 0); 204 205 spin_lock_irq(&ud->lock); 206 ret = (ud->status == SDEV_ST_USED); 207 spin_unlock_irq(&ud->lock); 208 if (!ret) { 209 usbip_event_add(ud, VUDC_EVENT_ERROR_TCP); 210 return -EBUSY; 211 } 212 213 switch (pdu.base.command) { 214 case USBIP_CMD_UNLINK: 215 ret = v_recv_cmd_unlink(udc, &pdu); 216 break; 217 case USBIP_CMD_SUBMIT: 218 ret = v_recv_cmd_submit(udc, &pdu); 219 break; 220 default: 221 ret = -EPIPE; 222 pr_err("rx: unknown command"); 223 break; 224 } 225 return ret; 226 } 227 228 int v_rx_loop(void *data) 229 { 230 struct usbip_device *ud = data; 231 int ret = 0; 232 233 while (!kthread_should_stop()) { 234 if (usbip_event_happened(ud)) 235 break; 236 ret = v_rx_pdu(ud); 237 if (ret < 0) { 238 pr_warn("v_rx exit with error %d", ret); 239 break; 240 } 241 } 242 return ret; 243 } 244