13 #include <linux/module.h>
14 #include <linux/kernel.h>
17 #include <linux/sched.h>
18 #include <linux/slab.h>
20 #include <linux/errno.h>
23 #include <linux/list.h>
25 #include <linux/device.h>
28 #include <linux/poll.h>
29 #include <linux/types.h>
30 #include <linux/ctype.h>
33 #include <asm/byteorder.h>
37 #include <asm/unaligned.h>
39 #include <linux/usb/ch9.h>
48 #define DRIVER_DESC "Printer Gadget"
49 #define DRIVER_VERSION "2007 OCT 06"
52 static const char shortname [] =
"printer";
55 static dev_t g_printer_devno;
57 static struct class *usb_gadget_class;
102 #define PRINTER_VENDOR_NUM 0x0525
103 #define PRINTER_PRODUCT_NUM 0xa4a8
113 static char *iPNPstring;
118 static unsigned qlen = 10;
131 #define USB_DESC_BUFSIZE 256
132 #define USB_BUFSIZE 8192
135 .bLength =
sizeof device_desc,
139 .bDeviceSubClass = 0,
140 .bDeviceProtocol = 0,
143 .bNumConfigurations = 1
147 .bLength =
sizeof intf_desc,
151 .bInterfaceSubClass = 1,
152 .bInterfaceProtocol = 2,
197 .bLength =
sizeof dev_qualifier,
201 .bNumConfigurations = 1
212 .bLength =
sizeof otg_descriptor,
223 #define ep_desc(g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs))
231 static char pnp_string [1024] =
232 "XXMFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;";
255 printer_req_alloc(
struct usb_ep *ep,
unsigned len,
gfp_t gfp_flags)
259 req = usb_ep_alloc_request(ep, gfp_flags);
265 usb_ep_free_request(ep, req);
278 usb_ep_free_request(ep, req);
292 list_del_init(&req->
list);
300 DBG(dev,
"G_Printer : rx length %d\n", req->
actual);
309 VDBG(dev,
"rx shutdown, code %d\n", status);
315 DBG(dev,
"rx %s reset\n", ep->
name);
324 DBG(dev,
"rx status %d\n", status);
330 spin_unlock_irqrestore(&dev->
lock, flags);
348 spin_lock(&dev->
lock);
352 list_del_init(&req->
list);
358 spin_unlock(&dev->
lock);
383 spin_unlock_irqrestore(&dev->
lock, flags);
385 DBG(dev,
"printer_open returned %x\n", ret);
391 printer_close(
struct inode *inode,
struct file *fd)
401 spin_unlock_irqrestore(&dev->
lock, flags);
403 DBG(dev,
"printer_close\n");
419 list_del_init(&req->
list);
432 DBG(dev,
"rx submit --> %d\n", error);
442 printer_read(
struct file *fd,
char __user *
buf,
size_t len, loff_t *
ptr)
452 size_t current_rx_bytes;
459 DBG(dev,
"printer_read trying to read %d bytes\n", (
int)len);
485 if ((current_rx_bytes == 0) &&
488 spin_unlock_irqrestore(&dev->
lock, flags);
508 if (current_rx_bytes == 0) {
511 list_del_init(&req->
list);
514 current_rx_req =
req;
515 current_rx_bytes = req->
actual;
516 current_rx_buf = req->
buf;
524 spin_unlock_irqrestore(&dev->
lock, flags);
526 if (len > current_rx_bytes)
527 size = current_rx_bytes;
532 bytes_copied +=
size;
541 spin_unlock_irqrestore(&dev->
lock, flags);
551 if (size < current_rx_bytes) {
552 current_rx_bytes -=
size;
553 current_rx_buf +=
size;
556 current_rx_bytes = 0;
557 current_rx_buf =
NULL;
558 current_rx_req =
NULL;
566 spin_unlock_irqrestore(&dev->
lock, flags);
569 DBG(dev,
"printer_read returned %d bytes\n", (
int)bytes_copied);
578 printer_write(
struct file *fd,
const char __user *buf,
size_t len, loff_t *ptr)
583 size_t bytes_copied = 0;
586 DBG(dev,
"printer_write trying to send %d bytes\n", (
int)len);
600 spin_unlock_irqrestore(&dev->
lock, flags);
626 list_del_init(&req->
list);
639 req->
zero = ((len % dev->
in_ep->maxpacket) == 0);
642 spin_unlock_irqrestore(&dev->
lock, flags);
650 bytes_copied +=
size;
659 spin_unlock_irqrestore(&dev->
lock, flags);
666 spin_unlock_irqrestore(&dev->
lock, flags);
675 spin_unlock_irqrestore(&dev->
lock, flags);
678 DBG(dev,
"printer_write sent %d bytes\n", (
int)bytes_copied);
688 printer_fsync(
struct file *fd, loff_t
start, loff_t
end,
int datasync)
691 struct inode *inode = fd->
f_path.dentry->d_inode;
698 spin_unlock_irqrestore(&dev->
lock, flags);
700 if (!tx_list_empty) {
720 spin_unlock_irqrestore(&dev->
lock, flags);
723 poll_wait(fd, &dev->
rx_wait, wait);
724 poll_wait(fd, &dev->
tx_wait, wait);
734 spin_unlock_irqrestore(&dev->
lock, flags);
740 printer_ioctl(
struct file *fd,
unsigned int code,
unsigned long arg)
746 DBG(dev,
"printer_ioctl: cmd=0x%4.4x, arg=%lu\n", code, arg);
761 DBG(dev,
"printer_ioctl: ERROR cmd=0x%4.4xis not supported\n",
766 spin_unlock_irqrestore(&dev->
lock, flags);
774 .open = printer_open,
775 .read = printer_read,
776 .write = printer_write,
777 .fsync = printer_fsync,
778 .poll = printer_poll,
779 .unlocked_ioctl = printer_ioctl,
780 .release = printer_close,
798 result = usb_ep_enable(dev->
in_ep);
800 DBG(dev,
"enable %s --> %d\n", dev->
in_ep->name, result);
804 result = usb_ep_enable(dev->
out_ep);
806 DBG(dev,
"enable %s --> %d\n", dev->
in_ep->name, result);
823 static void printer_reset_interface(
struct printer_dev *dev)
828 DBG(dev,
"%s\n", __func__);
830 if (dev->
in_ep->desc)
831 usb_ep_disable(dev->
in_ep);
834 usb_ep_disable(dev->
out_ep);
842 static int set_interface(
struct printer_dev *dev,
unsigned number)
847 printer_reset_interface(dev);
849 result = set_printer_interface(dev);
851 printer_reset_interface(dev);
856 INFO(dev,
"Using interface %x\n", number);
861 static void printer_soft_reset(
struct printer_dev *dev)
865 INFO(dev,
"Received Printer Reset Request\n");
867 if (usb_ep_disable(dev->
in_ep))
868 DBG(dev,
"Failed to disable USB in_ep\n");
869 if (usb_ep_disable(dev->
out_ep))
870 DBG(dev,
"Failed to disable USB out_ep\n");
883 list_del_init(&req->
list);
890 list_del_init(&req->
list);
897 list_del_init(&req->
list);
901 if (usb_ep_enable(dev->
in_ep))
902 DBG(dev,
"Failed to enable USB in_ep\n");
903 if (usb_ep_enable(dev->
out_ep))
904 DBG(dev,
"Failed to enable USB out_ep\n");
928 DBG(dev,
"ctrl req%02x.%02x v%04x i%04x l%d\n",
939 value = (pnp_string[0]<<8)|pnp_string[1];
941 DBG(dev,
"1284 PNP String: %x %s\n", value,
951 value =
min(wLength, (
u16) 1);
959 printer_soft_reset(dev);
972 "unknown ctrl req%02x.%02x v%04x i%04x l%d\n",
974 wValue, wIndex, wLength);
986 struct usb_ep *in_ep, *out_ep;
1023 static int printer_func_set_alt(
struct usb_function *f,
1024 unsigned intf,
unsigned alt)
1030 ret = set_interface(dev, intf);
1035 static void printer_func_disable(
struct usb_function *f)
1038 unsigned long flags;
1040 DBG(dev,
"%s\n", __func__);
1043 printer_reset_interface(dev);
1044 spin_unlock_irqrestore(&dev->
lock, flags);
1052 dev = &usb_printer_gadget;
1054 DBG(dev,
"%s\n", __func__);
1067 while (!list_empty(&dev->
tx_reqs)) {
1071 printer_req_free(dev->
in_ep, req);
1077 while (!list_empty(&dev->
rx_reqs)) {
1081 printer_req_free(dev->
out_ep, req);
1088 printer_req_free(dev->
out_ep, req);
1094 .unbind = printer_cfg_unbind,
1095 .bConfigurationValue = 1,
1110 dev = &usb_printer_gadget;
1113 dev->
function.descriptors = fs_printer_function;
1114 dev->
function.hs_descriptors = hs_printer_function;
1115 dev->
function.bind = printer_func_bind;
1116 dev->
function.setup = printer_func_setup;
1117 dev->
function.unbind = printer_func_unbind;
1118 dev->
function.set_alt = printer_func_set_alt;
1119 dev->
function.disable = printer_func_disable;
1128 if (IS_ERR(dev->
pdev)) {
1129 ERROR(dev,
"Failed to create device: g_printer\n");
1141 ERROR(dev,
"Failed to open char device\n");
1146 strlcpy(&pnp_string[2], iPNPstring, (
sizeof pnp_string)-2);
1148 len =
strlen(pnp_string);
1149 pnp_string[0] = (len >> 8) & 0xFF;
1150 pnp_string[1] = len & 0xFF;
1152 usb_gadget_set_selfpowered(gadget);
1162 INIT_LIST_HEAD(&dev->
tx_reqs);
1164 INIT_LIST_HEAD(&dev->
rx_reqs);
1178 for (i = 0; i <
QLEN; i++) {
1181 while (!list_empty(&dev->
tx_reqs)) {
1185 printer_req_free(dev->
in_ep, req);
1192 for (i = 0; i <
QLEN; i++) {
1195 while (!list_empty(&dev->
rx_reqs)) {
1199 printer_req_free(dev->
out_ep, req);
1213 printer_cfg_unbind(c);
1233 ret =
usb_add_config(cdev, &printer_cfg_driver, printer_bind_config);
1242 .dev = &device_desc,
1243 .strings = dev_strings,
1245 .bind = printer_bind,
1246 .unbind = printer_unbind,
1255 if (IS_ERR(usb_gadget_class)) {
1256 status = PTR_ERR(usb_gadget_class);
1257 pr_err(
"unable to create usb_gadget class %d\n", status);
1262 "USB printer gadget");
1264 pr_err(
"alloc_chrdev_region %d\n", status);
1273 pr_err(
"usb_gadget_probe_driver %x\n", status);
1283 mutex_lock(&usb_printer_gadget.lock_printer_io);