GNU Linux-libre 4.9.309-gnu1
[releases.git] / drivers / usb / usbip / vudc_sysfs.c
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  *               Krzysztof Opasiak <k.opasiak@samsung.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <linux/device.h>
22 #include <linux/list.h>
23 #include <linux/usb/gadget.h>
24 #include <linux/usb/ch9.h>
25 #include <linux/sysfs.h>
26 #include <linux/kthread.h>
27 #include <linux/file.h>
28 #include <linux/byteorder/generic.h>
29
30 #include "usbip_common.h"
31 #include "vudc.h"
32
33 #include <net/sock.h>
34
35 /* called with udc->lock held */
36 int get_gadget_descs(struct vudc *udc)
37 {
38         struct vrequest *usb_req;
39         struct vep *ep0 = to_vep(udc->gadget.ep0);
40         struct usb_device_descriptor *ddesc = &udc->dev_desc;
41         struct usb_ctrlrequest req;
42         int ret;
43
44         if (!udc->driver || !udc->pullup)
45                 return -EINVAL;
46
47         req.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
48         req.bRequest = USB_REQ_GET_DESCRIPTOR;
49         req.wValue = cpu_to_le16(USB_DT_DEVICE << 8);
50         req.wIndex = cpu_to_le16(0);
51         req.wLength = cpu_to_le16(sizeof(*ddesc));
52
53         spin_unlock(&udc->lock);
54         ret = udc->driver->setup(&(udc->gadget), &req);
55         spin_lock(&udc->lock);
56         if (ret < 0)
57                 goto out;
58
59         /* assuming request queue is empty; request is now on top */
60         usb_req = list_last_entry(&ep0->req_queue, struct vrequest, req_entry);
61         list_del(&usb_req->req_entry);
62
63         if (usb_req->req.length > sizeof(*ddesc)) {
64                 ret = -EOVERFLOW;
65                 goto giveback_req;
66         }
67
68         memcpy(ddesc, usb_req->req.buf, sizeof(*ddesc));
69         udc->desc_cached = 1;
70         ret = 0;
71 giveback_req:
72         usb_req->req.status = 0;
73         usb_req->req.actual = usb_req->req.length;
74         usb_gadget_giveback_request(&(ep0->ep), &(usb_req->req));
75 out:
76         return ret;
77 }
78
79 /*
80  * Exposes device descriptor from the gadget driver.
81  */
82 static ssize_t dev_desc_read(struct file *file, struct kobject *kobj,
83                              struct bin_attribute *attr, char *out,
84                              loff_t off, size_t count)
85 {
86         struct device *dev = kobj_to_dev(kobj);
87         struct vudc *udc = (struct vudc *)dev_get_drvdata(dev);
88         char *desc_ptr = (char *) &udc->dev_desc;
89         unsigned long flags;
90         int ret;
91
92         spin_lock_irqsave(&udc->lock, flags);
93         if (!udc->desc_cached) {
94                 ret = -ENODEV;
95                 goto unlock;
96         }
97
98         memcpy(out, desc_ptr + off, count);
99         ret = count;
100 unlock:
101         spin_unlock_irqrestore(&udc->lock, flags);
102         return ret;
103 }
104 static BIN_ATTR_RO(dev_desc, sizeof(struct usb_device_descriptor));
105
106 static ssize_t store_sockfd(struct device *dev,
107                                  struct device_attribute *attr,
108                                  const char *in, size_t count)
109 {
110         struct vudc *udc = (struct vudc *) dev_get_drvdata(dev);
111         int rv;
112         int sockfd = 0;
113         int err;
114         struct socket *socket;
115         unsigned long flags;
116         int ret;
117         struct task_struct *tcp_rx = NULL;
118         struct task_struct *tcp_tx = NULL;
119
120         rv = kstrtoint(in, 0, &sockfd);
121         if (rv != 0)
122                 return -EINVAL;
123
124         if (!udc) {
125                 dev_err(dev, "no device");
126                 return -ENODEV;
127         }
128         mutex_lock(&udc->ud.sysfs_lock);
129         spin_lock_irqsave(&udc->lock, flags);
130         /* Don't export what we don't have */
131         if (!udc->driver || !udc->pullup) {
132                 dev_err(dev, "gadget not bound");
133                 ret = -ENODEV;
134                 goto unlock;
135         }
136
137         if (sockfd != -1) {
138                 if (udc->connected) {
139                         dev_err(dev, "Device already connected");
140                         ret = -EBUSY;
141                         goto unlock;
142                 }
143
144                 spin_lock_irq(&udc->ud.lock);
145
146                 if (udc->ud.status != SDEV_ST_AVAILABLE) {
147                         ret = -EINVAL;
148                         goto unlock_ud;
149                 }
150
151                 socket = sockfd_lookup(sockfd, &err);
152                 if (!socket) {
153                         dev_err(dev, "failed to lookup sock");
154                         ret = -EINVAL;
155                         goto unlock_ud;
156                 }
157
158                 if (socket->type != SOCK_STREAM) {
159                         dev_err(dev, "Expecting SOCK_STREAM - found %d",
160                                 socket->type);
161                         ret = -EINVAL;
162                         goto sock_err;
163                 }
164
165                 /* unlock and create threads and get tasks */
166                 spin_unlock_irq(&udc->ud.lock);
167                 spin_unlock_irqrestore(&udc->lock, flags);
168
169                 tcp_rx = kthread_create(&v_rx_loop, &udc->ud, "vudc_rx");
170                 if (IS_ERR(tcp_rx)) {
171                         sockfd_put(socket);
172                         return -EINVAL;
173                 }
174                 tcp_tx = kthread_create(&v_tx_loop, &udc->ud, "vudc_tx");
175                 if (IS_ERR(tcp_tx)) {
176                         kthread_stop(tcp_rx);
177                         sockfd_put(socket);
178                         return -EINVAL;
179                 }
180
181                 /* get task structs now */
182                 get_task_struct(tcp_rx);
183                 get_task_struct(tcp_tx);
184
185                 /* lock and update udc->ud state */
186                 spin_lock_irqsave(&udc->lock, flags);
187                 spin_lock_irq(&udc->ud.lock);
188
189                 udc->ud.tcp_socket = socket;
190                 udc->ud.tcp_rx = tcp_rx;
191                 udc->ud.tcp_tx = tcp_tx;
192                 udc->ud.status = SDEV_ST_USED;
193
194                 spin_unlock_irq(&udc->ud.lock);
195
196                 do_gettimeofday(&udc->start_time);
197                 v_start_timer(udc);
198                 udc->connected = 1;
199
200                 spin_unlock_irqrestore(&udc->lock, flags);
201
202                 wake_up_process(udc->ud.tcp_rx);
203                 wake_up_process(udc->ud.tcp_tx);
204
205                 mutex_unlock(&udc->ud.sysfs_lock);
206                 return count;
207
208         } else {
209                 if (!udc->connected) {
210                         dev_err(dev, "Device not connected");
211                         ret = -EINVAL;
212                         goto unlock;
213                 }
214
215                 spin_lock_irq(&udc->ud.lock);
216                 if (udc->ud.status != SDEV_ST_USED) {
217                         ret = -EINVAL;
218                         goto unlock_ud;
219                 }
220                 spin_unlock_irq(&udc->ud.lock);
221
222                 usbip_event_add(&udc->ud, VUDC_EVENT_DOWN);
223         }
224
225         spin_unlock_irqrestore(&udc->lock, flags);
226         mutex_unlock(&udc->ud.sysfs_lock);
227
228         return count;
229
230 sock_err:
231         sockfd_put(socket);
232 unlock_ud:
233         spin_unlock_irq(&udc->ud.lock);
234 unlock:
235         spin_unlock_irqrestore(&udc->lock, flags);
236         mutex_unlock(&udc->ud.sysfs_lock);
237
238         return ret;
239 }
240 static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
241
242 static ssize_t usbip_status_show(struct device *dev,
243                                struct device_attribute *attr, char *out)
244 {
245         struct vudc *udc = (struct vudc *) dev_get_drvdata(dev);
246         int status;
247
248         if (!udc) {
249                 dev_err(dev, "no device");
250                 return -ENODEV;
251         }
252         spin_lock_irq(&udc->ud.lock);
253         status = udc->ud.status;
254         spin_unlock_irq(&udc->ud.lock);
255
256         return snprintf(out, PAGE_SIZE, "%d\n", status);
257 }
258 static DEVICE_ATTR_RO(usbip_status);
259
260 static struct attribute *dev_attrs[] = {
261         &dev_attr_usbip_sockfd.attr,
262         &dev_attr_usbip_status.attr,
263         NULL,
264 };
265
266 static struct bin_attribute *dev_bin_attrs[] = {
267         &bin_attr_dev_desc,
268         NULL,
269 };
270
271 const struct attribute_group vudc_attr_group = {
272         .attrs = dev_attrs,
273         .bin_attrs = dev_bin_attrs,
274 };