Commit | Line | Data |
---|---|---|
5fd54ace | 1 | // SPDX-License-Identifier: GPL-2.0+ |
b185f01a AP |
2 | /* |
3 | * f_printer.c - USB printer function driver | |
4 | * | |
5 | * Copied from drivers/usb/gadget/legacy/printer.c, | |
6 | * which was: | |
7 | * | |
8 | * printer.c -- Printer gadget driver | |
9 | * | |
10 | * Copyright (C) 2003-2005 David Brownell | |
11 | * Copyright (C) 2006 Craig W. Nadler | |
b185f01a AP |
12 | */ |
13 | ||
14 | #include <linux/module.h> | |
15 | #include <linux/kernel.h> | |
16 | #include <linux/delay.h> | |
17 | #include <linux/ioport.h> | |
18 | #include <linux/sched.h> | |
19 | #include <linux/slab.h> | |
20 | #include <linux/mutex.h> | |
21 | #include <linux/errno.h> | |
22 | #include <linux/init.h> | |
b26394bd | 23 | #include <linux/idr.h> |
b185f01a AP |
24 | #include <linux/timer.h> |
25 | #include <linux/list.h> | |
26 | #include <linux/interrupt.h> | |
27 | #include <linux/device.h> | |
28 | #include <linux/moduleparam.h> | |
29 | #include <linux/fs.h> | |
30 | #include <linux/poll.h> | |
31 | #include <linux/types.h> | |
32 | #include <linux/ctype.h> | |
33 | #include <linux/cdev.h> | |
34 | ||
35 | #include <asm/byteorder.h> | |
36 | #include <linux/io.h> | |
37 | #include <linux/irq.h> | |
38 | #include <linux/uaccess.h> | |
39 | #include <asm/unaligned.h> | |
40 | ||
41 | #include <linux/usb/ch9.h> | |
42 | #include <linux/usb/composite.h> | |
43 | #include <linux/usb/gadget.h> | |
44 | #include <linux/usb/g_printer.h> | |
45 | ||
b26394bd AP |
46 | #include "u_printer.h" |
47 | ||
b185f01a AP |
48 | #define PRINTER_MINORS 4 |
49 | #define GET_DEVICE_ID 0 | |
50 | #define GET_PORT_STATUS 1 | |
51 | #define SOFT_RESET 2 | |
52 | ||
53 | static int major, minors; | |
54 | static struct class *usb_gadget_class; | |
b26394bd AP |
55 | static DEFINE_IDA(printer_ida); |
56 | static DEFINE_MUTEX(printer_ida_lock); /* protects access do printer_ida */ | |
b185f01a AP |
57 | |
58 | /*-------------------------------------------------------------------------*/ | |
59 | ||
60 | struct printer_dev { | |
61 | spinlock_t lock; /* lock this structure */ | |
62 | /* lock buffer lists during read/write calls */ | |
63 | struct mutex lock_printer_io; | |
64 | struct usb_gadget *gadget; | |
65 | s8 interface; | |
66 | struct usb_ep *in_ep, *out_ep; | |
67 | ||
68 | struct list_head rx_reqs; /* List of free RX structs */ | |
69 | struct list_head rx_reqs_active; /* List of Active RX xfers */ | |
70 | struct list_head rx_buffers; /* List of completed xfers */ | |
71 | /* wait until there is data to be read. */ | |
72 | wait_queue_head_t rx_wait; | |
73 | struct list_head tx_reqs; /* List of free TX structs */ | |
74 | struct list_head tx_reqs_active; /* List of Active TX xfers */ | |
75 | /* Wait until there are write buffers available to use. */ | |
76 | wait_queue_head_t tx_wait; | |
77 | /* Wait until all write buffers have been sent. */ | |
78 | wait_queue_head_t tx_flush_wait; | |
79 | struct usb_request *current_rx_req; | |
80 | size_t current_rx_bytes; | |
81 | u8 *current_rx_buf; | |
82 | u8 printer_status; | |
83 | u8 reset_printer; | |
84 | int minor; | |
85 | struct cdev printer_cdev; | |
86 | u8 printer_cdev_open; | |
87 | wait_queue_head_t wait; | |
88 | unsigned q_len; | |
89 | char *pnp_string; /* We don't own memory! */ | |
90 | struct usb_function function; | |
91 | }; | |
92 | ||
93 | static inline struct printer_dev *func_to_printer(struct usb_function *f) | |
94 | { | |
95 | return container_of(f, struct printer_dev, function); | |
96 | } | |
97 | ||
98 | /*-------------------------------------------------------------------------*/ | |
99 | ||
100 | /* | |
101 | * DESCRIPTORS ... most are static, but strings and (full) configuration | |
102 | * descriptors are built on demand. | |
103 | */ | |
104 | ||
105 | /* holds our biggest descriptor */ | |
106 | #define USB_DESC_BUFSIZE 256 | |
107 | #define USB_BUFSIZE 8192 | |
108 | ||
109 | static struct usb_interface_descriptor intf_desc = { | |
110 | .bLength = sizeof(intf_desc), | |
111 | .bDescriptorType = USB_DT_INTERFACE, | |
112 | .bNumEndpoints = 2, | |
113 | .bInterfaceClass = USB_CLASS_PRINTER, | |
114 | .bInterfaceSubClass = 1, /* Printer Sub-Class */ | |
115 | .bInterfaceProtocol = 2, /* Bi-Directional */ | |
116 | .iInterface = 0 | |
117 | }; | |
118 | ||
119 | static struct usb_endpoint_descriptor fs_ep_in_desc = { | |
120 | .bLength = USB_DT_ENDPOINT_SIZE, | |
121 | .bDescriptorType = USB_DT_ENDPOINT, | |
122 | .bEndpointAddress = USB_DIR_IN, | |
123 | .bmAttributes = USB_ENDPOINT_XFER_BULK | |
124 | }; | |
125 | ||
126 | static struct usb_endpoint_descriptor fs_ep_out_desc = { | |
127 | .bLength = USB_DT_ENDPOINT_SIZE, | |
128 | .bDescriptorType = USB_DT_ENDPOINT, | |
129 | .bEndpointAddress = USB_DIR_OUT, | |
130 | .bmAttributes = USB_ENDPOINT_XFER_BULK | |
131 | }; | |
132 | ||
133 | static struct usb_descriptor_header *fs_printer_function[] = { | |
134 | (struct usb_descriptor_header *) &intf_desc, | |
135 | (struct usb_descriptor_header *) &fs_ep_in_desc, | |
136 | (struct usb_descriptor_header *) &fs_ep_out_desc, | |
137 | NULL | |
138 | }; | |
139 | ||
140 | /* | |
141 | * usb 2.0 devices need to expose both high speed and full speed | |
142 | * descriptors, unless they only run at full speed. | |
143 | */ | |
144 | ||
145 | static struct usb_endpoint_descriptor hs_ep_in_desc = { | |
146 | .bLength = USB_DT_ENDPOINT_SIZE, | |
147 | .bDescriptorType = USB_DT_ENDPOINT, | |
148 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | |
149 | .wMaxPacketSize = cpu_to_le16(512) | |
150 | }; | |
151 | ||
152 | static struct usb_endpoint_descriptor hs_ep_out_desc = { | |
153 | .bLength = USB_DT_ENDPOINT_SIZE, | |
154 | .bDescriptorType = USB_DT_ENDPOINT, | |
155 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | |
156 | .wMaxPacketSize = cpu_to_le16(512) | |
157 | }; | |
158 | ||
b185f01a AP |
159 | static struct usb_descriptor_header *hs_printer_function[] = { |
160 | (struct usb_descriptor_header *) &intf_desc, | |
161 | (struct usb_descriptor_header *) &hs_ep_in_desc, | |
162 | (struct usb_descriptor_header *) &hs_ep_out_desc, | |
163 | NULL | |
164 | }; | |
165 | ||
166 | /* | |
167 | * Added endpoint descriptors for 3.0 devices | |
168 | */ | |
169 | ||
170 | static struct usb_endpoint_descriptor ss_ep_in_desc = { | |
171 | .bLength = USB_DT_ENDPOINT_SIZE, | |
172 | .bDescriptorType = USB_DT_ENDPOINT, | |
173 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | |
174 | .wMaxPacketSize = cpu_to_le16(1024), | |
175 | }; | |
176 | ||
177 | static struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = { | |
178 | .bLength = sizeof(ss_ep_in_comp_desc), | |
179 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | |
180 | }; | |
181 | ||
182 | static struct usb_endpoint_descriptor ss_ep_out_desc = { | |
183 | .bLength = USB_DT_ENDPOINT_SIZE, | |
184 | .bDescriptorType = USB_DT_ENDPOINT, | |
185 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | |
186 | .wMaxPacketSize = cpu_to_le16(1024), | |
187 | }; | |
188 | ||
189 | static struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = { | |
190 | .bLength = sizeof(ss_ep_out_comp_desc), | |
191 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | |
192 | }; | |
193 | ||
194 | static struct usb_descriptor_header *ss_printer_function[] = { | |
195 | (struct usb_descriptor_header *) &intf_desc, | |
196 | (struct usb_descriptor_header *) &ss_ep_in_desc, | |
197 | (struct usb_descriptor_header *) &ss_ep_in_comp_desc, | |
198 | (struct usb_descriptor_header *) &ss_ep_out_desc, | |
199 | (struct usb_descriptor_header *) &ss_ep_out_comp_desc, | |
200 | NULL | |
201 | }; | |
202 | ||
203 | /* maxpacket and other transfer characteristics vary by speed. */ | |
204 | static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, | |
205 | struct usb_endpoint_descriptor *fs, | |
206 | struct usb_endpoint_descriptor *hs, | |
207 | struct usb_endpoint_descriptor *ss) | |
208 | { | |
209 | switch (gadget->speed) { | |
210 | case USB_SPEED_SUPER: | |
211 | return ss; | |
212 | case USB_SPEED_HIGH: | |
213 | return hs; | |
214 | default: | |
215 | return fs; | |
216 | } | |
217 | } | |
218 | ||
219 | /*-------------------------------------------------------------------------*/ | |
220 | ||
221 | static struct usb_request * | |
222 | printer_req_alloc(struct usb_ep *ep, unsigned len, gfp_t gfp_flags) | |
223 | { | |
224 | struct usb_request *req; | |
225 | ||
226 | req = usb_ep_alloc_request(ep, gfp_flags); | |
227 | ||
228 | if (req != NULL) { | |
229 | req->length = len; | |
230 | req->buf = kmalloc(len, gfp_flags); | |
231 | if (req->buf == NULL) { | |
232 | usb_ep_free_request(ep, req); | |
233 | return NULL; | |
234 | } | |
235 | } | |
236 | ||
237 | return req; | |
238 | } | |
239 | ||
240 | static void | |
241 | printer_req_free(struct usb_ep *ep, struct usb_request *req) | |
242 | { | |
243 | if (ep != NULL && req != NULL) { | |
244 | kfree(req->buf); | |
245 | usb_ep_free_request(ep, req); | |
246 | } | |
247 | } | |
248 | ||
249 | /*-------------------------------------------------------------------------*/ | |
250 | ||
251 | static void rx_complete(struct usb_ep *ep, struct usb_request *req) | |
252 | { | |
253 | struct printer_dev *dev = ep->driver_data; | |
254 | int status = req->status; | |
255 | unsigned long flags; | |
256 | ||
257 | spin_lock_irqsave(&dev->lock, flags); | |
258 | ||
259 | list_del_init(&req->list); /* Remode from Active List */ | |
260 | ||
261 | switch (status) { | |
262 | ||
263 | /* normal completion */ | |
264 | case 0: | |
265 | if (req->actual > 0) { | |
266 | list_add_tail(&req->list, &dev->rx_buffers); | |
267 | DBG(dev, "G_Printer : rx length %d\n", req->actual); | |
268 | } else { | |
269 | list_add(&req->list, &dev->rx_reqs); | |
270 | } | |
271 | break; | |
272 | ||
273 | /* software-driven interface shutdown */ | |
274 | case -ECONNRESET: /* unlink */ | |
275 | case -ESHUTDOWN: /* disconnect etc */ | |
276 | VDBG(dev, "rx shutdown, code %d\n", status); | |
277 | list_add(&req->list, &dev->rx_reqs); | |
278 | break; | |
279 | ||
280 | /* for hardware automagic (such as pxa) */ | |
281 | case -ECONNABORTED: /* endpoint reset */ | |
282 | DBG(dev, "rx %s reset\n", ep->name); | |
283 | list_add(&req->list, &dev->rx_reqs); | |
284 | break; | |
285 | ||
286 | /* data overrun */ | |
287 | case -EOVERFLOW: | |
288 | /* FALLTHROUGH */ | |
289 | ||
290 | default: | |
291 | DBG(dev, "rx status %d\n", status); | |
292 | list_add(&req->list, &dev->rx_reqs); | |
293 | break; | |
294 | } | |
295 | ||
296 | wake_up_interruptible(&dev->rx_wait); | |
297 | spin_unlock_irqrestore(&dev->lock, flags); | |
298 | } | |
299 | ||
300 | static void tx_complete(struct usb_ep *ep, struct usb_request *req) | |
301 | { | |
302 | struct printer_dev *dev = ep->driver_data; | |
303 | ||
304 | switch (req->status) { | |
305 | default: | |
306 | VDBG(dev, "tx err %d\n", req->status); | |
307 | /* FALLTHROUGH */ | |
308 | case -ECONNRESET: /* unlink */ | |
309 | case -ESHUTDOWN: /* disconnect etc */ | |
310 | break; | |
311 | case 0: | |
312 | break; | |
313 | } | |
314 | ||
315 | spin_lock(&dev->lock); | |
316 | /* Take the request struct off the active list and put it on the | |
317 | * free list. | |
318 | */ | |
319 | list_del_init(&req->list); | |
320 | list_add(&req->list, &dev->tx_reqs); | |
321 | wake_up_interruptible(&dev->tx_wait); | |
322 | if (likely(list_empty(&dev->tx_reqs_active))) | |
323 | wake_up_interruptible(&dev->tx_flush_wait); | |
324 | ||
325 | spin_unlock(&dev->lock); | |
326 | } | |
327 | ||
328 | /*-------------------------------------------------------------------------*/ | |
329 | ||
330 | static int | |
331 | printer_open(struct inode *inode, struct file *fd) | |
332 | { | |
333 | struct printer_dev *dev; | |
334 | unsigned long flags; | |
335 | int ret = -EBUSY; | |
336 | ||
337 | dev = container_of(inode->i_cdev, struct printer_dev, printer_cdev); | |
338 | ||
339 | spin_lock_irqsave(&dev->lock, flags); | |
340 | ||
341 | if (!dev->printer_cdev_open) { | |
342 | dev->printer_cdev_open = 1; | |
343 | fd->private_data = dev; | |
344 | ret = 0; | |
345 | /* Change the printer status to show that it's on-line. */ | |
346 | dev->printer_status |= PRINTER_SELECTED; | |
347 | } | |
348 | ||
349 | spin_unlock_irqrestore(&dev->lock, flags); | |
350 | ||
351 | DBG(dev, "printer_open returned %x\n", ret); | |
352 | return ret; | |
353 | } | |
354 | ||
355 | static int | |
356 | printer_close(struct inode *inode, struct file *fd) | |
357 | { | |
358 | struct printer_dev *dev = fd->private_data; | |
359 | unsigned long flags; | |
360 | ||
361 | spin_lock_irqsave(&dev->lock, flags); | |
362 | dev->printer_cdev_open = 0; | |
363 | fd->private_data = NULL; | |
364 | /* Change printer status to show that the printer is off-line. */ | |
365 | dev->printer_status &= ~PRINTER_SELECTED; | |
366 | spin_unlock_irqrestore(&dev->lock, flags); | |
367 | ||
368 | DBG(dev, "printer_close\n"); | |
369 | ||
370 | return 0; | |
371 | } | |
372 | ||
373 | /* This function must be called with interrupts turned off. */ | |
374 | static void | |
375 | setup_rx_reqs(struct printer_dev *dev) | |
376 | { | |
377 | struct usb_request *req; | |
378 | ||
379 | while (likely(!list_empty(&dev->rx_reqs))) { | |
380 | int error; | |
381 | ||
382 | req = container_of(dev->rx_reqs.next, | |
383 | struct usb_request, list); | |
384 | list_del_init(&req->list); | |
385 | ||
386 | /* The USB Host sends us whatever amount of data it wants to | |
387 | * so we always set the length field to the full USB_BUFSIZE. | |
388 | * If the amount of data is more than the read() caller asked | |
389 | * for it will be stored in the request buffer until it is | |
390 | * asked for by read(). | |
391 | */ | |
392 | req->length = USB_BUFSIZE; | |
393 | req->complete = rx_complete; | |
394 | ||
395 | /* here, we unlock, and only unlock, to avoid deadlock. */ | |
396 | spin_unlock(&dev->lock); | |
397 | error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); | |
398 | spin_lock(&dev->lock); | |
399 | if (error) { | |
400 | DBG(dev, "rx submit --> %d\n", error); | |
401 | list_add(&req->list, &dev->rx_reqs); | |
402 | break; | |
403 | } | |
404 | /* if the req is empty, then add it into dev->rx_reqs_active. */ | |
405 | else if (list_empty(&req->list)) | |
406 | list_add(&req->list, &dev->rx_reqs_active); | |
407 | } | |
408 | } | |
409 | ||
410 | static ssize_t | |
411 | printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |
412 | { | |
413 | struct printer_dev *dev = fd->private_data; | |
414 | unsigned long flags; | |
415 | size_t size; | |
416 | size_t bytes_copied; | |
417 | struct usb_request *req; | |
418 | /* This is a pointer to the current USB rx request. */ | |
419 | struct usb_request *current_rx_req; | |
420 | /* This is the number of bytes in the current rx buffer. */ | |
421 | size_t current_rx_bytes; | |
422 | /* This is a pointer to the current rx buffer. */ | |
423 | u8 *current_rx_buf; | |
424 | ||
425 | if (len == 0) | |
426 | return -EINVAL; | |
427 | ||
428 | DBG(dev, "printer_read trying to read %d bytes\n", (int)len); | |
429 | ||
430 | mutex_lock(&dev->lock_printer_io); | |
431 | spin_lock_irqsave(&dev->lock, flags); | |
432 | ||
433 | /* We will use this flag later to check if a printer reset happened | |
434 | * after we turn interrupts back on. | |
435 | */ | |
436 | dev->reset_printer = 0; | |
437 | ||
438 | setup_rx_reqs(dev); | |
439 | ||
440 | bytes_copied = 0; | |
441 | current_rx_req = dev->current_rx_req; | |
442 | current_rx_bytes = dev->current_rx_bytes; | |
443 | current_rx_buf = dev->current_rx_buf; | |
444 | dev->current_rx_req = NULL; | |
445 | dev->current_rx_bytes = 0; | |
446 | dev->current_rx_buf = NULL; | |
447 | ||
448 | /* Check if there is any data in the read buffers. Please note that | |
449 | * current_rx_bytes is the number of bytes in the current rx buffer. | |
450 | * If it is zero then check if there are any other rx_buffers that | |
451 | * are on the completed list. We are only out of data if all rx | |
452 | * buffers are empty. | |
453 | */ | |
454 | if ((current_rx_bytes == 0) && | |
455 | (likely(list_empty(&dev->rx_buffers)))) { | |
456 | /* Turn interrupts back on before sleeping. */ | |
457 | spin_unlock_irqrestore(&dev->lock, flags); | |
458 | ||
459 | /* | |
460 | * If no data is available check if this is a NON-Blocking | |
461 | * call or not. | |
462 | */ | |
463 | if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { | |
464 | mutex_unlock(&dev->lock_printer_io); | |
465 | return -EAGAIN; | |
466 | } | |
467 | ||
468 | /* Sleep until data is available */ | |
469 | wait_event_interruptible(dev->rx_wait, | |
470 | (likely(!list_empty(&dev->rx_buffers)))); | |
471 | spin_lock_irqsave(&dev->lock, flags); | |
472 | } | |
473 | ||
474 | /* We have data to return then copy it to the caller's buffer.*/ | |
475 | while ((current_rx_bytes || likely(!list_empty(&dev->rx_buffers))) | |
476 | && len) { | |
477 | if (current_rx_bytes == 0) { | |
478 | req = container_of(dev->rx_buffers.next, | |
479 | struct usb_request, list); | |
480 | list_del_init(&req->list); | |
481 | ||
482 | if (req->actual && req->buf) { | |
483 | current_rx_req = req; | |
484 | current_rx_bytes = req->actual; | |
485 | current_rx_buf = req->buf; | |
486 | } else { | |
487 | list_add(&req->list, &dev->rx_reqs); | |
488 | continue; | |
489 | } | |
490 | } | |
491 | ||
492 | /* Don't leave irqs off while doing memory copies */ | |
493 | spin_unlock_irqrestore(&dev->lock, flags); | |
494 | ||
495 | if (len > current_rx_bytes) | |
496 | size = current_rx_bytes; | |
497 | else | |
498 | size = len; | |
499 | ||
500 | size -= copy_to_user(buf, current_rx_buf, size); | |
501 | bytes_copied += size; | |
502 | len -= size; | |
503 | buf += size; | |
504 | ||
505 | spin_lock_irqsave(&dev->lock, flags); | |
506 | ||
507 | /* We've disconnected or reset so return. */ | |
508 | if (dev->reset_printer) { | |
509 | list_add(¤t_rx_req->list, &dev->rx_reqs); | |
510 | spin_unlock_irqrestore(&dev->lock, flags); | |
511 | mutex_unlock(&dev->lock_printer_io); | |
512 | return -EAGAIN; | |
513 | } | |
514 | ||
515 | /* If we not returning all the data left in this RX request | |
516 | * buffer then adjust the amount of data left in the buffer. | |
517 | * Othewise if we are done with this RX request buffer then | |
518 | * requeue it to get any incoming data from the USB host. | |
519 | */ | |
520 | if (size < current_rx_bytes) { | |
521 | current_rx_bytes -= size; | |
522 | current_rx_buf += size; | |
523 | } else { | |
524 | list_add(¤t_rx_req->list, &dev->rx_reqs); | |
525 | current_rx_bytes = 0; | |
526 | current_rx_buf = NULL; | |
527 | current_rx_req = NULL; | |
528 | } | |
529 | } | |
530 | ||
531 | dev->current_rx_req = current_rx_req; | |
532 | dev->current_rx_bytes = current_rx_bytes; | |
533 | dev->current_rx_buf = current_rx_buf; | |
534 | ||
535 | spin_unlock_irqrestore(&dev->lock, flags); | |
536 | mutex_unlock(&dev->lock_printer_io); | |
537 | ||
538 | DBG(dev, "printer_read returned %d bytes\n", (int)bytes_copied); | |
539 | ||
540 | if (bytes_copied) | |
541 | return bytes_copied; | |
542 | else | |
543 | return -EAGAIN; | |
544 | } | |
545 | ||
546 | static ssize_t | |
547 | printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |
548 | { | |
549 | struct printer_dev *dev = fd->private_data; | |
550 | unsigned long flags; | |
551 | size_t size; /* Amount of data in a TX request. */ | |
552 | size_t bytes_copied = 0; | |
553 | struct usb_request *req; | |
9ada8c58 | 554 | int value; |
b185f01a AP |
555 | |
556 | DBG(dev, "printer_write trying to send %d bytes\n", (int)len); | |
557 | ||
558 | if (len == 0) | |
559 | return -EINVAL; | |
560 | ||
561 | mutex_lock(&dev->lock_printer_io); | |
562 | spin_lock_irqsave(&dev->lock, flags); | |
563 | ||
564 | /* Check if a printer reset happens while we have interrupts on */ | |
565 | dev->reset_printer = 0; | |
566 | ||
567 | /* Check if there is any available write buffers */ | |
568 | if (likely(list_empty(&dev->tx_reqs))) { | |
569 | /* Turn interrupts back on before sleeping. */ | |
570 | spin_unlock_irqrestore(&dev->lock, flags); | |
571 | ||
572 | /* | |
573 | * If write buffers are available check if this is | |
574 | * a NON-Blocking call or not. | |
575 | */ | |
576 | if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { | |
577 | mutex_unlock(&dev->lock_printer_io); | |
578 | return -EAGAIN; | |
579 | } | |
580 | ||
581 | /* Sleep until a write buffer is available */ | |
582 | wait_event_interruptible(dev->tx_wait, | |
583 | (likely(!list_empty(&dev->tx_reqs)))); | |
584 | spin_lock_irqsave(&dev->lock, flags); | |
585 | } | |
586 | ||
587 | while (likely(!list_empty(&dev->tx_reqs)) && len) { | |
588 | ||
589 | if (len > USB_BUFSIZE) | |
590 | size = USB_BUFSIZE; | |
591 | else | |
592 | size = len; | |
593 | ||
594 | req = container_of(dev->tx_reqs.next, struct usb_request, | |
595 | list); | |
596 | list_del_init(&req->list); | |
597 | ||
598 | req->complete = tx_complete; | |
599 | req->length = size; | |
600 | ||
601 | /* Check if we need to send a zero length packet. */ | |
602 | if (len > size) | |
603 | /* They will be more TX requests so no yet. */ | |
604 | req->zero = 0; | |
605 | else | |
606 | /* If the data amount is not a multiple of the | |
607 | * maxpacket size then send a zero length packet. | |
608 | */ | |
609 | req->zero = ((len % dev->in_ep->maxpacket) == 0); | |
610 | ||
611 | /* Don't leave irqs off while doing memory copies */ | |
612 | spin_unlock_irqrestore(&dev->lock, flags); | |
613 | ||
614 | if (copy_from_user(req->buf, buf, size)) { | |
615 | list_add(&req->list, &dev->tx_reqs); | |
616 | mutex_unlock(&dev->lock_printer_io); | |
617 | return bytes_copied; | |
618 | } | |
619 | ||
620 | bytes_copied += size; | |
621 | len -= size; | |
622 | buf += size; | |
623 | ||
624 | spin_lock_irqsave(&dev->lock, flags); | |
625 | ||
626 | /* We've disconnected or reset so free the req and buffer */ | |
627 | if (dev->reset_printer) { | |
628 | list_add(&req->list, &dev->tx_reqs); | |
629 | spin_unlock_irqrestore(&dev->lock, flags); | |
630 | mutex_unlock(&dev->lock_printer_io); | |
631 | return -EAGAIN; | |
632 | } | |
633 | ||
9ada8c58 YS |
634 | /* here, we unlock, and only unlock, to avoid deadlock. */ |
635 | spin_unlock(&dev->lock); | |
636 | value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); | |
637 | spin_lock(&dev->lock); | |
638 | if (value) { | |
b185f01a AP |
639 | list_add(&req->list, &dev->tx_reqs); |
640 | spin_unlock_irqrestore(&dev->lock, flags); | |
641 | mutex_unlock(&dev->lock_printer_io); | |
642 | return -EAGAIN; | |
643 | } | |
644 | ||
645 | list_add(&req->list, &dev->tx_reqs_active); | |
646 | ||
647 | } | |
648 | ||
649 | spin_unlock_irqrestore(&dev->lock, flags); | |
650 | mutex_unlock(&dev->lock_printer_io); | |
651 | ||
652 | DBG(dev, "printer_write sent %d bytes\n", (int)bytes_copied); | |
653 | ||
654 | if (bytes_copied) | |
655 | return bytes_copied; | |
656 | else | |
657 | return -EAGAIN; | |
658 | } | |
659 | ||
660 | static int | |
661 | printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync) | |
662 | { | |
663 | struct printer_dev *dev = fd->private_data; | |
664 | struct inode *inode = file_inode(fd); | |
665 | unsigned long flags; | |
666 | int tx_list_empty; | |
667 | ||
5955102c | 668 | inode_lock(inode); |
b185f01a AP |
669 | spin_lock_irqsave(&dev->lock, flags); |
670 | tx_list_empty = (likely(list_empty(&dev->tx_reqs))); | |
671 | spin_unlock_irqrestore(&dev->lock, flags); | |
672 | ||
673 | if (!tx_list_empty) { | |
674 | /* Sleep until all data has been sent */ | |
675 | wait_event_interruptible(dev->tx_flush_wait, | |
676 | (likely(list_empty(&dev->tx_reqs_active)))); | |
677 | } | |
5955102c | 678 | inode_unlock(inode); |
b185f01a AP |
679 | |
680 | return 0; | |
681 | } | |
682 | ||
afc9a42b | 683 | static __poll_t |
b185f01a AP |
684 | printer_poll(struct file *fd, poll_table *wait) |
685 | { | |
686 | struct printer_dev *dev = fd->private_data; | |
687 | unsigned long flags; | |
afc9a42b | 688 | __poll_t status = 0; |
b185f01a AP |
689 | |
690 | mutex_lock(&dev->lock_printer_io); | |
691 | spin_lock_irqsave(&dev->lock, flags); | |
692 | setup_rx_reqs(dev); | |
693 | spin_unlock_irqrestore(&dev->lock, flags); | |
694 | mutex_unlock(&dev->lock_printer_io); | |
695 | ||
696 | poll_wait(fd, &dev->rx_wait, wait); | |
697 | poll_wait(fd, &dev->tx_wait, wait); | |
698 | ||
699 | spin_lock_irqsave(&dev->lock, flags); | |
700 | if (likely(!list_empty(&dev->tx_reqs))) | |
a9a08845 | 701 | status |= EPOLLOUT | EPOLLWRNORM; |
b185f01a AP |
702 | |
703 | if (likely(dev->current_rx_bytes) || | |
704 | likely(!list_empty(&dev->rx_buffers))) | |
a9a08845 | 705 | status |= EPOLLIN | EPOLLRDNORM; |
b185f01a AP |
706 | |
707 | spin_unlock_irqrestore(&dev->lock, flags); | |
708 | ||
709 | return status; | |
710 | } | |
711 | ||
712 | static long | |
713 | printer_ioctl(struct file *fd, unsigned int code, unsigned long arg) | |
714 | { | |
715 | struct printer_dev *dev = fd->private_data; | |
716 | unsigned long flags; | |
717 | int status = 0; | |
718 | ||
719 | DBG(dev, "printer_ioctl: cmd=0x%4.4x, arg=%lu\n", code, arg); | |
720 | ||
721 | /* handle ioctls */ | |
722 | ||
723 | spin_lock_irqsave(&dev->lock, flags); | |
724 | ||
725 | switch (code) { | |
726 | case GADGET_GET_PRINTER_STATUS: | |
727 | status = (int)dev->printer_status; | |
728 | break; | |
729 | case GADGET_SET_PRINTER_STATUS: | |
730 | dev->printer_status = (u8)arg; | |
731 | break; | |
732 | default: | |
733 | /* could not handle ioctl */ | |
734 | DBG(dev, "printer_ioctl: ERROR cmd=0x%4.4xis not supported\n", | |
735 | code); | |
736 | status = -ENOTTY; | |
737 | } | |
738 | ||
739 | spin_unlock_irqrestore(&dev->lock, flags); | |
740 | ||
741 | return status; | |
742 | } | |
743 | ||
744 | /* used after endpoint configuration */ | |
745 | static const struct file_operations printer_io_operations = { | |
746 | .owner = THIS_MODULE, | |
747 | .open = printer_open, | |
748 | .read = printer_read, | |
749 | .write = printer_write, | |
750 | .fsync = printer_fsync, | |
751 | .poll = printer_poll, | |
752 | .unlocked_ioctl = printer_ioctl, | |
753 | .release = printer_close, | |
754 | .llseek = noop_llseek, | |
755 | }; | |
756 | ||
757 | /*-------------------------------------------------------------------------*/ | |
758 | ||
759 | static int | |
760 | set_printer_interface(struct printer_dev *dev) | |
761 | { | |
762 | int result = 0; | |
763 | ||
764 | dev->in_ep->desc = ep_desc(dev->gadget, &fs_ep_in_desc, &hs_ep_in_desc, | |
765 | &ss_ep_in_desc); | |
766 | dev->in_ep->driver_data = dev; | |
767 | ||
768 | dev->out_ep->desc = ep_desc(dev->gadget, &fs_ep_out_desc, | |
769 | &hs_ep_out_desc, &ss_ep_out_desc); | |
770 | dev->out_ep->driver_data = dev; | |
771 | ||
772 | result = usb_ep_enable(dev->in_ep); | |
773 | if (result != 0) { | |
774 | DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); | |
775 | goto done; | |
776 | } | |
777 | ||
778 | result = usb_ep_enable(dev->out_ep); | |
779 | if (result != 0) { | |
780 | DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); | |
781 | goto done; | |
782 | } | |
783 | ||
784 | done: | |
785 | /* on error, disable any endpoints */ | |
786 | if (result != 0) { | |
787 | (void) usb_ep_disable(dev->in_ep); | |
788 | (void) usb_ep_disable(dev->out_ep); | |
789 | dev->in_ep->desc = NULL; | |
790 | dev->out_ep->desc = NULL; | |
791 | } | |
792 | ||
793 | /* caller is responsible for cleanup on error */ | |
794 | return result; | |
795 | } | |
796 | ||
797 | static void printer_reset_interface(struct printer_dev *dev) | |
798 | { | |
a24b071b FL |
799 | unsigned long flags; |
800 | ||
b185f01a AP |
801 | if (dev->interface < 0) |
802 | return; | |
803 | ||
804 | DBG(dev, "%s\n", __func__); | |
805 | ||
806 | if (dev->in_ep->desc) | |
807 | usb_ep_disable(dev->in_ep); | |
808 | ||
809 | if (dev->out_ep->desc) | |
810 | usb_ep_disable(dev->out_ep); | |
811 | ||
a24b071b | 812 | spin_lock_irqsave(&dev->lock, flags); |
b185f01a AP |
813 | dev->in_ep->desc = NULL; |
814 | dev->out_ep->desc = NULL; | |
815 | dev->interface = -1; | |
a24b071b | 816 | spin_unlock_irqrestore(&dev->lock, flags); |
b185f01a AP |
817 | } |
818 | ||
819 | /* Change our operational Interface. */ | |
820 | static int set_interface(struct printer_dev *dev, unsigned number) | |
821 | { | |
822 | int result = 0; | |
823 | ||
824 | /* Free the current interface */ | |
825 | printer_reset_interface(dev); | |
826 | ||
827 | result = set_printer_interface(dev); | |
828 | if (result) | |
829 | printer_reset_interface(dev); | |
830 | else | |
831 | dev->interface = number; | |
832 | ||
833 | if (!result) | |
834 | INFO(dev, "Using interface %x\n", number); | |
835 | ||
836 | return result; | |
837 | } | |
838 | ||
839 | static void printer_soft_reset(struct printer_dev *dev) | |
840 | { | |
841 | struct usb_request *req; | |
842 | ||
843 | INFO(dev, "Received Printer Reset Request\n"); | |
844 | ||
845 | if (usb_ep_disable(dev->in_ep)) | |
846 | DBG(dev, "Failed to disable USB in_ep\n"); | |
847 | if (usb_ep_disable(dev->out_ep)) | |
848 | DBG(dev, "Failed to disable USB out_ep\n"); | |
849 | ||
850 | if (dev->current_rx_req != NULL) { | |
851 | list_add(&dev->current_rx_req->list, &dev->rx_reqs); | |
852 | dev->current_rx_req = NULL; | |
853 | } | |
854 | dev->current_rx_bytes = 0; | |
855 | dev->current_rx_buf = NULL; | |
856 | dev->reset_printer = 1; | |
857 | ||
858 | while (likely(!(list_empty(&dev->rx_buffers)))) { | |
859 | req = container_of(dev->rx_buffers.next, struct usb_request, | |
860 | list); | |
861 | list_del_init(&req->list); | |
862 | list_add(&req->list, &dev->rx_reqs); | |
863 | } | |
864 | ||
865 | while (likely(!(list_empty(&dev->rx_reqs_active)))) { | |
866 | req = container_of(dev->rx_buffers.next, struct usb_request, | |
867 | list); | |
868 | list_del_init(&req->list); | |
869 | list_add(&req->list, &dev->rx_reqs); | |
870 | } | |
871 | ||
872 | while (likely(!(list_empty(&dev->tx_reqs_active)))) { | |
873 | req = container_of(dev->tx_reqs_active.next, | |
874 | struct usb_request, list); | |
875 | list_del_init(&req->list); | |
876 | list_add(&req->list, &dev->tx_reqs); | |
877 | } | |
878 | ||
879 | if (usb_ep_enable(dev->in_ep)) | |
880 | DBG(dev, "Failed to enable USB in_ep\n"); | |
881 | if (usb_ep_enable(dev->out_ep)) | |
882 | DBG(dev, "Failed to enable USB out_ep\n"); | |
883 | ||
884 | wake_up_interruptible(&dev->rx_wait); | |
885 | wake_up_interruptible(&dev->tx_wait); | |
886 | wake_up_interruptible(&dev->tx_flush_wait); | |
887 | } | |
888 | ||
889 | /*-------------------------------------------------------------------------*/ | |
890 | ||
891 | static bool gprinter_req_match(struct usb_function *f, | |
1a00b457 FH |
892 | const struct usb_ctrlrequest *ctrl, |
893 | bool config0) | |
b185f01a AP |
894 | { |
895 | struct printer_dev *dev = func_to_printer(f); | |
896 | u16 w_index = le16_to_cpu(ctrl->wIndex); | |
897 | u16 w_value = le16_to_cpu(ctrl->wValue); | |
898 | u16 w_length = le16_to_cpu(ctrl->wLength); | |
899 | ||
1a00b457 FH |
900 | if (config0) |
901 | return false; | |
902 | ||
b185f01a AP |
903 | if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE || |
904 | (ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) | |
905 | return false; | |
906 | ||
907 | switch (ctrl->bRequest) { | |
908 | case GET_DEVICE_ID: | |
909 | w_index >>= 8; | |
fdc01cc2 | 910 | if (USB_DIR_IN & ctrl->bRequestType) |
b185f01a AP |
911 | break; |
912 | return false; | |
913 | case GET_PORT_STATUS: | |
914 | if (!w_value && w_length == 1 && | |
915 | (USB_DIR_IN & ctrl->bRequestType)) | |
916 | break; | |
917 | return false; | |
918 | case SOFT_RESET: | |
919 | if (!w_value && !w_length && | |
fbdecad9 | 920 | !(USB_DIR_IN & ctrl->bRequestType)) |
b185f01a AP |
921 | break; |
922 | /* fall through */ | |
923 | default: | |
924 | return false; | |
925 | } | |
926 | return w_index == dev->interface; | |
927 | } | |
928 | ||
929 | /* | |
930 | * The setup() callback implements all the ep0 functionality that's not | |
931 | * handled lower down. | |
932 | */ | |
933 | static int printer_func_setup(struct usb_function *f, | |
934 | const struct usb_ctrlrequest *ctrl) | |
935 | { | |
936 | struct printer_dev *dev = func_to_printer(f); | |
937 | struct usb_composite_dev *cdev = f->config->cdev; | |
938 | struct usb_request *req = cdev->req; | |
fdc01cc2 | 939 | u8 *buf = req->buf; |
b185f01a AP |
940 | int value = -EOPNOTSUPP; |
941 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | |
942 | u16 wValue = le16_to_cpu(ctrl->wValue); | |
943 | u16 wLength = le16_to_cpu(ctrl->wLength); | |
944 | ||
945 | DBG(dev, "ctrl req%02x.%02x v%04x i%04x l%d\n", | |
946 | ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength); | |
947 | ||
948 | switch (ctrl->bRequestType&USB_TYPE_MASK) { | |
949 | case USB_TYPE_CLASS: | |
950 | switch (ctrl->bRequest) { | |
951 | case GET_DEVICE_ID: /* Get the IEEE-1284 PNP String */ | |
952 | /* Only one printer interface is supported. */ | |
953 | if ((wIndex>>8) != dev->interface) | |
954 | break; | |
955 | ||
fdc01cc2 KO |
956 | if (!dev->pnp_string) { |
957 | value = 0; | |
958 | break; | |
959 | } | |
960 | value = strlen(dev->pnp_string); | |
961 | buf[0] = (value >> 8) & 0xFF; | |
962 | buf[1] = value & 0xFF; | |
963 | memcpy(buf + 2, dev->pnp_string, value); | |
b185f01a | 964 | DBG(dev, "1284 PNP String: %x %s\n", value, |
fdc01cc2 | 965 | dev->pnp_string); |
b185f01a AP |
966 | break; |
967 | ||
968 | case GET_PORT_STATUS: /* Get Port Status */ | |
969 | /* Only one printer interface is supported. */ | |
970 | if (wIndex != dev->interface) | |
971 | break; | |
972 | ||
fdc01cc2 | 973 | buf[0] = dev->printer_status; |
b185f01a AP |
974 | value = min_t(u16, wLength, 1); |
975 | break; | |
976 | ||
977 | case SOFT_RESET: /* Soft Reset */ | |
978 | /* Only one printer interface is supported. */ | |
979 | if (wIndex != dev->interface) | |
980 | break; | |
981 | ||
982 | printer_soft_reset(dev); | |
983 | ||
984 | value = 0; | |
985 | break; | |
986 | ||
987 | default: | |
988 | goto unknown; | |
989 | } | |
990 | break; | |
991 | ||
992 | default: | |
993 | unknown: | |
994 | VDBG(dev, | |
995 | "unknown ctrl req%02x.%02x v%04x i%04x l%d\n", | |
996 | ctrl->bRequestType, ctrl->bRequest, | |
997 | wValue, wIndex, wLength); | |
998 | break; | |
999 | } | |
1000 | /* host either stalls (value < 0) or reports success */ | |
1001 | if (value >= 0) { | |
1002 | req->length = value; | |
1003 | req->zero = value < wLength; | |
1004 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); | |
1005 | if (value < 0) { | |
1006 | ERROR(dev, "%s:%d Error!\n", __func__, __LINE__); | |
1007 | req->status = 0; | |
1008 | } | |
1009 | } | |
1010 | return value; | |
1011 | } | |
1012 | ||
b26394bd | 1013 | static int printer_func_bind(struct usb_configuration *c, |
b185f01a AP |
1014 | struct usb_function *f) |
1015 | { | |
1016 | struct usb_gadget *gadget = c->cdev->gadget; | |
1017 | struct printer_dev *dev = func_to_printer(f); | |
1018 | struct device *pdev; | |
1019 | struct usb_composite_dev *cdev = c->cdev; | |
1020 | struct usb_ep *in_ep; | |
1021 | struct usb_ep *out_ep = NULL; | |
1022 | struct usb_request *req; | |
1023 | dev_t devt; | |
1024 | int id; | |
1025 | int ret; | |
1026 | u32 i; | |
1027 | ||
1028 | id = usb_interface_id(c, f); | |
1029 | if (id < 0) | |
1030 | return id; | |
1031 | intf_desc.bInterfaceNumber = id; | |
1032 | ||
1033 | /* finish hookup to lower layer ... */ | |
1034 | dev->gadget = gadget; | |
1035 | ||
1036 | /* all we really need is bulk IN/OUT */ | |
1037 | in_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_in_desc); | |
1038 | if (!in_ep) { | |
1039 | autoconf_fail: | |
1040 | dev_err(&cdev->gadget->dev, "can't autoconfigure on %s\n", | |
1041 | cdev->gadget->name); | |
1042 | return -ENODEV; | |
1043 | } | |
b185f01a AP |
1044 | |
1045 | out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc); | |
1046 | if (!out_ep) | |
1047 | goto autoconf_fail; | |
b185f01a AP |
1048 | |
1049 | /* assumes that all endpoints are dual-speed */ | |
1050 | hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; | |
1051 | hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; | |
1052 | ss_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; | |
1053 | ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; | |
1054 | ||
1055 | ret = usb_assign_descriptors(f, fs_printer_function, | |
eaef50c7 | 1056 | hs_printer_function, ss_printer_function, NULL); |
b185f01a AP |
1057 | if (ret) |
1058 | return ret; | |
1059 | ||
1060 | dev->in_ep = in_ep; | |
1061 | dev->out_ep = out_ep; | |
1062 | ||
1063 | ret = -ENOMEM; | |
1064 | for (i = 0; i < dev->q_len; i++) { | |
1065 | req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); | |
1066 | if (!req) | |
1067 | goto fail_tx_reqs; | |
1068 | list_add(&req->list, &dev->tx_reqs); | |
1069 | } | |
1070 | ||
1071 | for (i = 0; i < dev->q_len; i++) { | |
1072 | req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL); | |
1073 | if (!req) | |
1074 | goto fail_rx_reqs; | |
1075 | list_add(&req->list, &dev->rx_reqs); | |
1076 | } | |
1077 | ||
1078 | /* Setup the sysfs files for the printer gadget. */ | |
1079 | devt = MKDEV(major, dev->minor); | |
1080 | pdev = device_create(usb_gadget_class, NULL, devt, | |
1081 | NULL, "g_printer%d", dev->minor); | |
1082 | if (IS_ERR(pdev)) { | |
1083 | ERROR(dev, "Failed to create device: g_printer\n"); | |
1084 | ret = PTR_ERR(pdev); | |
1085 | goto fail_rx_reqs; | |
1086 | } | |
1087 | ||
1088 | /* | |
1089 | * Register a character device as an interface to a user mode | |
1090 | * program that handles the printer specific functionality. | |
1091 | */ | |
1092 | cdev_init(&dev->printer_cdev, &printer_io_operations); | |
1093 | dev->printer_cdev.owner = THIS_MODULE; | |
1094 | ret = cdev_add(&dev->printer_cdev, devt, 1); | |
1095 | if (ret) { | |
1096 | ERROR(dev, "Failed to open char device\n"); | |
1097 | goto fail_cdev_add; | |
1098 | } | |
1099 | ||
1100 | return 0; | |
1101 | ||
1102 | fail_cdev_add: | |
1103 | device_destroy(usb_gadget_class, devt); | |
1104 | ||
1105 | fail_rx_reqs: | |
1106 | while (!list_empty(&dev->rx_reqs)) { | |
1107 | req = container_of(dev->rx_reqs.next, struct usb_request, list); | |
1108 | list_del(&req->list); | |
1109 | printer_req_free(dev->out_ep, req); | |
1110 | } | |
1111 | ||
1112 | fail_tx_reqs: | |
1113 | while (!list_empty(&dev->tx_reqs)) { | |
1114 | req = container_of(dev->tx_reqs.next, struct usb_request, list); | |
1115 | list_del(&req->list); | |
1116 | printer_req_free(dev->in_ep, req); | |
1117 | } | |
1118 | ||
1119 | return ret; | |
1120 | ||
1121 | } | |
1122 | ||
b185f01a AP |
1123 | static int printer_func_set_alt(struct usb_function *f, |
1124 | unsigned intf, unsigned alt) | |
1125 | { | |
1126 | struct printer_dev *dev = func_to_printer(f); | |
1127 | int ret = -ENOTSUPP; | |
1128 | ||
1129 | if (!alt) | |
1130 | ret = set_interface(dev, intf); | |
1131 | ||
1132 | return ret; | |
1133 | } | |
1134 | ||
1135 | static void printer_func_disable(struct usb_function *f) | |
1136 | { | |
1137 | struct printer_dev *dev = func_to_printer(f); | |
b185f01a AP |
1138 | |
1139 | DBG(dev, "%s\n", __func__); | |
1140 | ||
b185f01a | 1141 | printer_reset_interface(dev); |
b185f01a AP |
1142 | } |
1143 | ||
ee1cd515 AP |
1144 | static inline struct f_printer_opts |
1145 | *to_f_printer_opts(struct config_item *item) | |
1146 | { | |
1147 | return container_of(to_config_group(item), struct f_printer_opts, | |
1148 | func_inst.group); | |
1149 | } | |
1150 | ||
ee1cd515 AP |
1151 | static void printer_attr_release(struct config_item *item) |
1152 | { | |
1153 | struct f_printer_opts *opts = to_f_printer_opts(item); | |
1154 | ||
1155 | usb_put_function_instance(&opts->func_inst); | |
1156 | } | |
1157 | ||
1158 | static struct configfs_item_operations printer_item_ops = { | |
1159 | .release = printer_attr_release, | |
ee1cd515 AP |
1160 | }; |
1161 | ||
aa48a415 | 1162 | static ssize_t f_printer_opts_pnp_string_show(struct config_item *item, |
ee1cd515 AP |
1163 | char *page) |
1164 | { | |
aa48a415 | 1165 | struct f_printer_opts *opts = to_f_printer_opts(item); |
fdc01cc2 | 1166 | int result = 0; |
ee1cd515 AP |
1167 | |
1168 | mutex_lock(&opts->lock); | |
fdc01cc2 KO |
1169 | if (!opts->pnp_string) |
1170 | goto unlock; | |
1171 | ||
1172 | result = strlcpy(page, opts->pnp_string, PAGE_SIZE); | |
1173 | if (result >= PAGE_SIZE) { | |
1174 | result = PAGE_SIZE; | |
1175 | } else if (page[result - 1] != '\n' && result + 1 < PAGE_SIZE) { | |
1176 | page[result++] = '\n'; | |
1177 | page[result] = '\0'; | |
1178 | } | |
1179 | ||
1180 | unlock: | |
ee1cd515 AP |
1181 | mutex_unlock(&opts->lock); |
1182 | ||
1183 | return result; | |
1184 | } | |
1185 | ||
aa48a415 | 1186 | static ssize_t f_printer_opts_pnp_string_store(struct config_item *item, |
ee1cd515 AP |
1187 | const char *page, size_t len) |
1188 | { | |
aa48a415 | 1189 | struct f_printer_opts *opts = to_f_printer_opts(item); |
fdc01cc2 KO |
1190 | char *new_pnp; |
1191 | int result; | |
ee1cd515 AP |
1192 | |
1193 | mutex_lock(&opts->lock); | |
fdc01cc2 KO |
1194 | |
1195 | new_pnp = kstrndup(page, len, GFP_KERNEL); | |
1196 | if (!new_pnp) { | |
1197 | result = -ENOMEM; | |
1198 | goto unlock; | |
1199 | } | |
1200 | ||
1201 | if (opts->pnp_string_allocated) | |
1202 | kfree(opts->pnp_string); | |
1203 | ||
1204 | opts->pnp_string_allocated = true; | |
1205 | opts->pnp_string = new_pnp; | |
1206 | result = len; | |
1207 | unlock: | |
ee1cd515 AP |
1208 | mutex_unlock(&opts->lock); |
1209 | ||
1210 | return result; | |
1211 | } | |
1212 | ||
aa48a415 | 1213 | CONFIGFS_ATTR(f_printer_opts_, pnp_string); |
ee1cd515 | 1214 | |
aa48a415 | 1215 | static ssize_t f_printer_opts_q_len_show(struct config_item *item, |
ee1cd515 AP |
1216 | char *page) |
1217 | { | |
aa48a415 | 1218 | struct f_printer_opts *opts = to_f_printer_opts(item); |
ee1cd515 AP |
1219 | int result; |
1220 | ||
1221 | mutex_lock(&opts->lock); | |
1222 | result = sprintf(page, "%d\n", opts->q_len); | |
1223 | mutex_unlock(&opts->lock); | |
1224 | ||
1225 | return result; | |
1226 | } | |
1227 | ||
aa48a415 | 1228 | static ssize_t f_printer_opts_q_len_store(struct config_item *item, |
ee1cd515 AP |
1229 | const char *page, size_t len) |
1230 | { | |
aa48a415 | 1231 | struct f_printer_opts *opts = to_f_printer_opts(item); |
ee1cd515 AP |
1232 | int ret; |
1233 | u16 num; | |
1234 | ||
1235 | mutex_lock(&opts->lock); | |
1236 | if (opts->refcnt) { | |
1237 | ret = -EBUSY; | |
1238 | goto end; | |
1239 | } | |
1240 | ||
1241 | ret = kstrtou16(page, 0, &num); | |
1242 | if (ret) | |
1243 | goto end; | |
1244 | ||
ee1cd515 AP |
1245 | opts->q_len = (unsigned)num; |
1246 | ret = len; | |
1247 | end: | |
1248 | mutex_unlock(&opts->lock); | |
1249 | return ret; | |
1250 | } | |
1251 | ||
aa48a415 | 1252 | CONFIGFS_ATTR(f_printer_opts_, q_len); |
ee1cd515 AP |
1253 | |
1254 | static struct configfs_attribute *printer_attrs[] = { | |
aa48a415 CH |
1255 | &f_printer_opts_attr_pnp_string, |
1256 | &f_printer_opts_attr_q_len, | |
ee1cd515 AP |
1257 | NULL, |
1258 | }; | |
1259 | ||
97363902 | 1260 | static const struct config_item_type printer_func_type = { |
ee1cd515 AP |
1261 | .ct_item_ops = &printer_item_ops, |
1262 | .ct_attrs = printer_attrs, | |
1263 | .ct_owner = THIS_MODULE, | |
1264 | }; | |
1265 | ||
b26394bd AP |
1266 | static inline int gprinter_get_minor(void) |
1267 | { | |
4248bd7d AP |
1268 | int ret; |
1269 | ||
1270 | ret = ida_simple_get(&printer_ida, 0, 0, GFP_KERNEL); | |
1271 | if (ret >= PRINTER_MINORS) { | |
1272 | ida_simple_remove(&printer_ida, ret); | |
1273 | ret = -ENODEV; | |
1274 | } | |
1275 | ||
1276 | return ret; | |
b26394bd AP |
1277 | } |
1278 | ||
1279 | static inline void gprinter_put_minor(int minor) | |
1280 | { | |
1281 | ida_simple_remove(&printer_ida, minor); | |
1282 | } | |
1283 | ||
1284 | static int gprinter_setup(int); | |
1285 | static void gprinter_cleanup(void); | |
1286 | ||
1287 | static void gprinter_free_inst(struct usb_function_instance *f) | |
1288 | { | |
1289 | struct f_printer_opts *opts; | |
1290 | ||
1291 | opts = container_of(f, struct f_printer_opts, func_inst); | |
1292 | ||
1293 | mutex_lock(&printer_ida_lock); | |
1294 | ||
1295 | gprinter_put_minor(opts->minor); | |
99c49407 | 1296 | if (ida_is_empty(&printer_ida)) |
b26394bd AP |
1297 | gprinter_cleanup(); |
1298 | ||
1299 | mutex_unlock(&printer_ida_lock); | |
1300 | ||
fdc01cc2 KO |
1301 | if (opts->pnp_string_allocated) |
1302 | kfree(opts->pnp_string); | |
b26394bd AP |
1303 | kfree(opts); |
1304 | } | |
1305 | ||
1306 | static struct usb_function_instance *gprinter_alloc_inst(void) | |
1307 | { | |
1308 | struct f_printer_opts *opts; | |
1309 | struct usb_function_instance *ret; | |
1310 | int status = 0; | |
1311 | ||
1312 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); | |
1313 | if (!opts) | |
1314 | return ERR_PTR(-ENOMEM); | |
1315 | ||
ee1cd515 | 1316 | mutex_init(&opts->lock); |
b26394bd AP |
1317 | opts->func_inst.free_func_inst = gprinter_free_inst; |
1318 | ret = &opts->func_inst; | |
1319 | ||
1320 | mutex_lock(&printer_ida_lock); | |
1321 | ||
99c49407 | 1322 | if (ida_is_empty(&printer_ida)) { |
b26394bd AP |
1323 | status = gprinter_setup(PRINTER_MINORS); |
1324 | if (status) { | |
1325 | ret = ERR_PTR(status); | |
1326 | kfree(opts); | |
1327 | goto unlock; | |
1328 | } | |
1329 | } | |
1330 | ||
1331 | opts->minor = gprinter_get_minor(); | |
1332 | if (opts->minor < 0) { | |
1333 | ret = ERR_PTR(opts->minor); | |
1334 | kfree(opts); | |
99c49407 | 1335 | if (ida_is_empty(&printer_ida)) |
b26394bd | 1336 | gprinter_cleanup(); |
2bb2077e | 1337 | goto unlock; |
b26394bd | 1338 | } |
ee1cd515 AP |
1339 | config_group_init_type_name(&opts->func_inst.group, "", |
1340 | &printer_func_type); | |
b26394bd AP |
1341 | |
1342 | unlock: | |
1343 | mutex_unlock(&printer_ida_lock); | |
1344 | return ret; | |
1345 | } | |
1346 | ||
1347 | static void gprinter_free(struct usb_function *f) | |
1348 | { | |
1349 | struct printer_dev *dev = func_to_printer(f); | |
ee1cd515 | 1350 | struct f_printer_opts *opts; |
b26394bd | 1351 | |
ee1cd515 | 1352 | opts = container_of(f->fi, struct f_printer_opts, func_inst); |
b26394bd | 1353 | kfree(dev); |
ee1cd515 AP |
1354 | mutex_lock(&opts->lock); |
1355 | --opts->refcnt; | |
1356 | mutex_unlock(&opts->lock); | |
b26394bd AP |
1357 | } |
1358 | ||
1359 | static void printer_func_unbind(struct usb_configuration *c, | |
1360 | struct usb_function *f) | |
1361 | { | |
1362 | struct printer_dev *dev; | |
1363 | struct usb_request *req; | |
1364 | ||
1365 | dev = func_to_printer(f); | |
1366 | ||
1367 | device_destroy(usb_gadget_class, MKDEV(major, dev->minor)); | |
1368 | ||
1369 | /* Remove Character Device */ | |
1370 | cdev_del(&dev->printer_cdev); | |
1371 | ||
1372 | /* we must already have been disconnected ... no i/o may be active */ | |
1373 | WARN_ON(!list_empty(&dev->tx_reqs_active)); | |
1374 | WARN_ON(!list_empty(&dev->rx_reqs_active)); | |
1375 | ||
1376 | /* Free all memory for this driver. */ | |
1377 | while (!list_empty(&dev->tx_reqs)) { | |
1378 | req = container_of(dev->tx_reqs.next, struct usb_request, | |
1379 | list); | |
1380 | list_del(&req->list); | |
1381 | printer_req_free(dev->in_ep, req); | |
1382 | } | |
1383 | ||
1384 | if (dev->current_rx_req != NULL) | |
1385 | printer_req_free(dev->out_ep, dev->current_rx_req); | |
1386 | ||
1387 | while (!list_empty(&dev->rx_reqs)) { | |
1388 | req = container_of(dev->rx_reqs.next, | |
1389 | struct usb_request, list); | |
1390 | list_del(&req->list); | |
1391 | printer_req_free(dev->out_ep, req); | |
1392 | } | |
1393 | ||
1394 | while (!list_empty(&dev->rx_buffers)) { | |
1395 | req = container_of(dev->rx_buffers.next, | |
1396 | struct usb_request, list); | |
1397 | list_del(&req->list); | |
1398 | printer_req_free(dev->out_ep, req); | |
1399 | } | |
1400 | usb_free_all_descriptors(f); | |
1401 | } | |
1402 | ||
1403 | static struct usb_function *gprinter_alloc(struct usb_function_instance *fi) | |
1404 | { | |
1405 | struct printer_dev *dev; | |
1406 | struct f_printer_opts *opts; | |
1407 | ||
1408 | opts = container_of(fi, struct f_printer_opts, func_inst); | |
1409 | ||
ee1cd515 AP |
1410 | mutex_lock(&opts->lock); |
1411 | if (opts->minor >= minors) { | |
1412 | mutex_unlock(&opts->lock); | |
b26394bd | 1413 | return ERR_PTR(-ENOENT); |
ee1cd515 | 1414 | } |
b26394bd AP |
1415 | |
1416 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | |
ee1cd515 AP |
1417 | if (!dev) { |
1418 | mutex_unlock(&opts->lock); | |
b26394bd | 1419 | return ERR_PTR(-ENOMEM); |
ee1cd515 | 1420 | } |
b26394bd | 1421 | |
ee1cd515 | 1422 | ++opts->refcnt; |
b26394bd AP |
1423 | dev->minor = opts->minor; |
1424 | dev->pnp_string = opts->pnp_string; | |
1425 | dev->q_len = opts->q_len; | |
ee1cd515 | 1426 | mutex_unlock(&opts->lock); |
b26394bd AP |
1427 | |
1428 | dev->function.name = "printer"; | |
1429 | dev->function.bind = printer_func_bind; | |
1430 | dev->function.setup = printer_func_setup; | |
1431 | dev->function.unbind = printer_func_unbind; | |
1432 | dev->function.set_alt = printer_func_set_alt; | |
1433 | dev->function.disable = printer_func_disable; | |
1434 | dev->function.req_match = gprinter_req_match; | |
1435 | dev->function.free_func = gprinter_free; | |
1436 | ||
1437 | INIT_LIST_HEAD(&dev->tx_reqs); | |
1438 | INIT_LIST_HEAD(&dev->rx_reqs); | |
1439 | INIT_LIST_HEAD(&dev->rx_buffers); | |
1440 | INIT_LIST_HEAD(&dev->tx_reqs_active); | |
1441 | INIT_LIST_HEAD(&dev->rx_reqs_active); | |
1442 | ||
1443 | spin_lock_init(&dev->lock); | |
1444 | mutex_init(&dev->lock_printer_io); | |
1445 | init_waitqueue_head(&dev->rx_wait); | |
1446 | init_waitqueue_head(&dev->tx_wait); | |
1447 | init_waitqueue_head(&dev->tx_flush_wait); | |
1448 | ||
1449 | dev->interface = -1; | |
1450 | dev->printer_cdev_open = 0; | |
1451 | dev->printer_status = PRINTER_NOT_ERROR; | |
1452 | dev->current_rx_req = NULL; | |
1453 | dev->current_rx_bytes = 0; | |
1454 | dev->current_rx_buf = NULL; | |
1455 | ||
1456 | return &dev->function; | |
1457 | } | |
1458 | ||
1459 | DECLARE_USB_FUNCTION_INIT(printer, gprinter_alloc_inst, gprinter_alloc); | |
1460 | MODULE_LICENSE("GPL"); | |
1461 | MODULE_AUTHOR("Craig Nadler"); | |
1462 | ||
b185f01a AP |
1463 | static int gprinter_setup(int count) |
1464 | { | |
1465 | int status; | |
1466 | dev_t devt; | |
1467 | ||
1468 | usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget"); | |
1469 | if (IS_ERR(usb_gadget_class)) { | |
1470 | status = PTR_ERR(usb_gadget_class); | |
1471 | usb_gadget_class = NULL; | |
1472 | pr_err("unable to create usb_gadget class %d\n", status); | |
1473 | return status; | |
1474 | } | |
1475 | ||
1476 | status = alloc_chrdev_region(&devt, 0, count, "USB printer gadget"); | |
1477 | if (status) { | |
1478 | pr_err("alloc_chrdev_region %d\n", status); | |
1479 | class_destroy(usb_gadget_class); | |
1480 | usb_gadget_class = NULL; | |
1481 | return status; | |
1482 | } | |
1483 | ||
1484 | major = MAJOR(devt); | |
1485 | minors = count; | |
1486 | ||
1487 | return status; | |
1488 | } | |
1489 | ||
1490 | static void gprinter_cleanup(void) | |
1491 | { | |
1492 | if (major) { | |
1493 | unregister_chrdev_region(MKDEV(major, 0), minors); | |
1494 | major = minors = 0; | |
1495 | } | |
1496 | class_destroy(usb_gadget_class); | |
1497 | usb_gadget_class = NULL; | |
1498 | } |