diff options
Diffstat (limited to 'drivers/usb/gadget/printer.c')
-rw-r--r-- | drivers/usb/gadget/printer.c | 173 |
1 files changed, 71 insertions, 102 deletions
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index f1f9290a2f47..e156e3f26727 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/timer.h> | 22 | #include <linux/timer.h> |
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/utsname.h> | ||
26 | #include <linux/device.h> | 25 | #include <linux/device.h> |
27 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
28 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
@@ -38,25 +37,13 @@ | |||
38 | #include <asm/unaligned.h> | 37 | #include <asm/unaligned.h> |
39 | 38 | ||
40 | #include <linux/usb/ch9.h> | 39 | #include <linux/usb/ch9.h> |
40 | #include <linux/usb/composite.h> | ||
41 | #include <linux/usb/gadget.h> | 41 | #include <linux/usb/gadget.h> |
42 | #include <linux/usb/g_printer.h> | 42 | #include <linux/usb/g_printer.h> |
43 | 43 | ||
44 | #include "gadget_chips.h" | 44 | #include "gadget_chips.h" |
45 | 45 | ||
46 | 46 | USB_GADGET_COMPOSITE_OPTIONS(); | |
47 | /* | ||
48 | * Kbuild is not very cooperative with respect to linking separately | ||
49 | * compiled library objects into one module. So for now we won't use | ||
50 | * separate compilation ... ensuring init/exit sections work to shrink | ||
51 | * the runtime footprint, and giving us at least some parts of what | ||
52 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
53 | */ | ||
54 | #include "composite.c" | ||
55 | #include "usbstring.c" | ||
56 | #include "config.c" | ||
57 | #include "epautoconf.c" | ||
58 | |||
59 | /*-------------------------------------------------------------------------*/ | ||
60 | 47 | ||
61 | #define DRIVER_DESC "Printer Gadget" | 48 | #define DRIVER_DESC "Printer Gadget" |
62 | #define DRIVER_VERSION "2007 OCT 06" | 49 | #define DRIVER_VERSION "2007 OCT 06" |
@@ -120,8 +107,7 @@ static struct printer_dev usb_printer_gadget; | |||
120 | * parameters are in UTF-8 (superset of ASCII's 7 bit characters). | 107 | * parameters are in UTF-8 (superset of ASCII's 7 bit characters). |
121 | */ | 108 | */ |
122 | 109 | ||
123 | static char *iSerialNum; | 110 | module_param_named(iSerialNum, coverwrite.serial_number, charp, S_IRUGO); |
124 | module_param(iSerialNum, charp, S_IRUGO); | ||
125 | MODULE_PARM_DESC(iSerialNum, "1"); | 111 | MODULE_PARM_DESC(iSerialNum, "1"); |
126 | 112 | ||
127 | static char *iPNPstring; | 113 | static char *iPNPstring; |
@@ -141,18 +127,10 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); | |||
141 | * descriptors are built on demand. | 127 | * descriptors are built on demand. |
142 | */ | 128 | */ |
143 | 129 | ||
144 | #define STRING_MANUFACTURER 1 | ||
145 | #define STRING_PRODUCT 2 | ||
146 | #define STRING_SERIALNUM 3 | ||
147 | |||
148 | /* holds our biggest descriptor */ | 130 | /* holds our biggest descriptor */ |
149 | #define USB_DESC_BUFSIZE 256 | 131 | #define USB_DESC_BUFSIZE 256 |
150 | #define USB_BUFSIZE 8192 | 132 | #define USB_BUFSIZE 8192 |
151 | 133 | ||
152 | /* This device advertises one configuration. */ | ||
153 | #define DEV_CONFIG_VALUE 1 | ||
154 | #define PRINTER_INTERFACE 0 | ||
155 | |||
156 | static struct usb_device_descriptor device_desc = { | 134 | static struct usb_device_descriptor device_desc = { |
157 | .bLength = sizeof device_desc, | 135 | .bLength = sizeof device_desc, |
158 | .bDescriptorType = USB_DT_DEVICE, | 136 | .bDescriptorType = USB_DT_DEVICE, |
@@ -162,16 +140,12 @@ static struct usb_device_descriptor device_desc = { | |||
162 | .bDeviceProtocol = 0, | 140 | .bDeviceProtocol = 0, |
163 | .idVendor = cpu_to_le16(PRINTER_VENDOR_NUM), | 141 | .idVendor = cpu_to_le16(PRINTER_VENDOR_NUM), |
164 | .idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM), | 142 | .idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM), |
165 | .iManufacturer = STRING_MANUFACTURER, | ||
166 | .iProduct = STRING_PRODUCT, | ||
167 | .iSerialNumber = STRING_SERIALNUM, | ||
168 | .bNumConfigurations = 1 | 143 | .bNumConfigurations = 1 |
169 | }; | 144 | }; |
170 | 145 | ||
171 | static struct usb_interface_descriptor intf_desc = { | 146 | static struct usb_interface_descriptor intf_desc = { |
172 | .bLength = sizeof intf_desc, | 147 | .bLength = sizeof intf_desc, |
173 | .bDescriptorType = USB_DT_INTERFACE, | 148 | .bDescriptorType = USB_DT_INTERFACE, |
174 | .bInterfaceNumber = PRINTER_INTERFACE, | ||
175 | .bNumEndpoints = 2, | 149 | .bNumEndpoints = 2, |
176 | .bInterfaceClass = USB_CLASS_PRINTER, | 150 | .bInterfaceClass = USB_CLASS_PRINTER, |
177 | .bInterfaceSubClass = 1, /* Printer Sub-Class */ | 151 | .bInterfaceSubClass = 1, /* Printer Sub-Class */ |
@@ -252,7 +226,6 @@ static const struct usb_descriptor_header *otg_desc[] = { | |||
252 | 226 | ||
253 | /* descriptors that are built on-demand */ | 227 | /* descriptors that are built on-demand */ |
254 | 228 | ||
255 | static char manufacturer [50]; | ||
256 | static char product_desc [40] = DRIVER_DESC; | 229 | static char product_desc [40] = DRIVER_DESC; |
257 | static char serial_num [40] = "1"; | 230 | static char serial_num [40] = "1"; |
258 | static char pnp_string [1024] = | 231 | static char pnp_string [1024] = |
@@ -260,9 +233,9 @@ static char pnp_string [1024] = | |||
260 | 233 | ||
261 | /* static strings, in UTF-8 */ | 234 | /* static strings, in UTF-8 */ |
262 | static struct usb_string strings [] = { | 235 | static struct usb_string strings [] = { |
263 | { STRING_MANUFACTURER, manufacturer, }, | 236 | [USB_GADGET_MANUFACTURER_IDX].s = "", |
264 | { STRING_PRODUCT, product_desc, }, | 237 | [USB_GADGET_PRODUCT_IDX].s = product_desc, |
265 | { STRING_SERIALNUM, serial_num, }, | 238 | [USB_GADGET_SERIAL_IDX].s = serial_num, |
266 | { } /* end of list */ | 239 | { } /* end of list */ |
267 | }; | 240 | }; |
268 | 241 | ||
@@ -871,25 +844,13 @@ static int set_interface(struct printer_dev *dev, unsigned number) | |||
871 | int result = 0; | 844 | int result = 0; |
872 | 845 | ||
873 | /* Free the current interface */ | 846 | /* Free the current interface */ |
874 | switch (dev->interface) { | 847 | printer_reset_interface(dev); |
875 | case PRINTER_INTERFACE: | ||
876 | printer_reset_interface(dev); | ||
877 | break; | ||
878 | } | ||
879 | 848 | ||
880 | switch (number) { | 849 | result = set_printer_interface(dev); |
881 | case PRINTER_INTERFACE: | 850 | if (result) |
882 | result = set_printer_interface(dev); | 851 | printer_reset_interface(dev); |
883 | if (result) { | 852 | else |
884 | printer_reset_interface(dev); | 853 | dev->interface = number; |
885 | } else { | ||
886 | dev->interface = PRINTER_INTERFACE; | ||
887 | } | ||
888 | break; | ||
889 | default: | ||
890 | result = -EINVAL; | ||
891 | /* FALL THROUGH */ | ||
892 | } | ||
893 | 854 | ||
894 | if (!result) | 855 | if (!result) |
895 | INFO(dev, "Using interface %x\n", number); | 856 | INFO(dev, "Using interface %x\n", number); |
@@ -972,7 +933,7 @@ static int printer_func_setup(struct usb_function *f, | |||
972 | switch (ctrl->bRequest) { | 933 | switch (ctrl->bRequest) { |
973 | case 0: /* Get the IEEE-1284 PNP String */ | 934 | case 0: /* Get the IEEE-1284 PNP String */ |
974 | /* Only one printer interface is supported. */ | 935 | /* Only one printer interface is supported. */ |
975 | if ((wIndex>>8) != PRINTER_INTERFACE) | 936 | if ((wIndex>>8) != dev->interface) |
976 | break; | 937 | break; |
977 | 938 | ||
978 | value = (pnp_string[0]<<8)|pnp_string[1]; | 939 | value = (pnp_string[0]<<8)|pnp_string[1]; |
@@ -983,7 +944,7 @@ static int printer_func_setup(struct usb_function *f, | |||
983 | 944 | ||
984 | case 1: /* Get Port Status */ | 945 | case 1: /* Get Port Status */ |
985 | /* Only one printer interface is supported. */ | 946 | /* Only one printer interface is supported. */ |
986 | if (wIndex != PRINTER_INTERFACE) | 947 | if (wIndex != dev->interface) |
987 | break; | 948 | break; |
988 | 949 | ||
989 | *(u8 *)req->buf = dev->printer_status; | 950 | *(u8 *)req->buf = dev->printer_status; |
@@ -992,7 +953,7 @@ static int printer_func_setup(struct usb_function *f, | |||
992 | 953 | ||
993 | case 2: /* Soft Reset */ | 954 | case 2: /* Soft Reset */ |
994 | /* Only one printer interface is supported. */ | 955 | /* Only one printer interface is supported. */ |
995 | if (wIndex != PRINTER_INTERFACE) | 956 | if (wIndex != dev->interface) |
996 | break; | 957 | break; |
997 | 958 | ||
998 | printer_soft_reset(dev); | 959 | printer_soft_reset(dev); |
@@ -1020,6 +981,37 @@ unknown: | |||
1020 | static int __init printer_func_bind(struct usb_configuration *c, | 981 | static int __init printer_func_bind(struct usb_configuration *c, |
1021 | struct usb_function *f) | 982 | struct usb_function *f) |
1022 | { | 983 | { |
984 | struct printer_dev *dev = container_of(f, struct printer_dev, function); | ||
985 | struct usb_composite_dev *cdev = c->cdev; | ||
986 | struct usb_ep *in_ep, *out_ep; | ||
987 | int id; | ||
988 | |||
989 | id = usb_interface_id(c, f); | ||
990 | if (id < 0) | ||
991 | return id; | ||
992 | intf_desc.bInterfaceNumber = id; | ||
993 | |||
994 | /* all we really need is bulk IN/OUT */ | ||
995 | in_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_in_desc); | ||
996 | if (!in_ep) { | ||
997 | autoconf_fail: | ||
998 | dev_err(&cdev->gadget->dev, "can't autoconfigure on %s\n", | ||
999 | cdev->gadget->name); | ||
1000 | return -ENODEV; | ||
1001 | } | ||
1002 | in_ep->driver_data = in_ep; /* claim */ | ||
1003 | |||
1004 | out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc); | ||
1005 | if (!out_ep) | ||
1006 | goto autoconf_fail; | ||
1007 | out_ep->driver_data = out_ep; /* claim */ | ||
1008 | |||
1009 | /* assumes that all endpoints are dual-speed */ | ||
1010 | hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; | ||
1011 | hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; | ||
1012 | |||
1013 | dev->in_ep = in_ep; | ||
1014 | dev->out_ep = out_ep; | ||
1023 | return 0; | 1015 | return 0; |
1024 | } | 1016 | } |
1025 | 1017 | ||
@@ -1035,7 +1027,8 @@ static int printer_func_set_alt(struct usb_function *f, | |||
1035 | int ret = -ENOTSUPP; | 1027 | int ret = -ENOTSUPP; |
1036 | 1028 | ||
1037 | if (!alt) | 1029 | if (!alt) |
1038 | ret = set_interface(dev, PRINTER_INTERFACE); | 1030 | ret = set_interface(dev, intf); |
1031 | |||
1039 | return ret; | 1032 | return ret; |
1040 | } | 1033 | } |
1041 | 1034 | ||
@@ -1107,13 +1100,13 @@ static int __init printer_bind_config(struct usb_configuration *c) | |||
1107 | { | 1100 | { |
1108 | struct usb_gadget *gadget = c->cdev->gadget; | 1101 | struct usb_gadget *gadget = c->cdev->gadget; |
1109 | struct printer_dev *dev; | 1102 | struct printer_dev *dev; |
1110 | struct usb_ep *in_ep, *out_ep; | ||
1111 | int status = -ENOMEM; | 1103 | int status = -ENOMEM; |
1112 | int gcnum; | ||
1113 | size_t len; | 1104 | size_t len; |
1114 | u32 i; | 1105 | u32 i; |
1115 | struct usb_request *req; | 1106 | struct usb_request *req; |
1116 | 1107 | ||
1108 | usb_ep_autoconfig_reset(gadget); | ||
1109 | |||
1117 | dev = &usb_printer_gadget; | 1110 | dev = &usb_printer_gadget; |
1118 | 1111 | ||
1119 | dev->function.name = shortname; | 1112 | dev->function.name = shortname; |
@@ -1125,6 +1118,10 @@ static int __init printer_bind_config(struct usb_configuration *c) | |||
1125 | dev->function.set_alt = printer_func_set_alt; | 1118 | dev->function.set_alt = printer_func_set_alt; |
1126 | dev->function.disable = printer_func_disable; | 1119 | dev->function.disable = printer_func_disable; |
1127 | 1120 | ||
1121 | status = usb_add_function(c, &dev->function); | ||
1122 | if (status) | ||
1123 | return status; | ||
1124 | |||
1128 | /* Setup the sysfs files for the printer gadget. */ | 1125 | /* Setup the sysfs files for the printer gadget. */ |
1129 | dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno, | 1126 | dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno, |
1130 | NULL, "g_printer"); | 1127 | NULL, "g_printer"); |
@@ -1145,23 +1142,6 @@ static int __init printer_bind_config(struct usb_configuration *c) | |||
1145 | goto fail; | 1142 | goto fail; |
1146 | } | 1143 | } |
1147 | 1144 | ||
1148 | gcnum = usb_gadget_controller_number(gadget); | ||
1149 | if (gcnum >= 0) { | ||
1150 | device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); | ||
1151 | } else { | ||
1152 | dev_warn(&gadget->dev, "controller '%s' not recognized\n", | ||
1153 | gadget->name); | ||
1154 | /* unrecognized, but safe unless bulk is REALLY quirky */ | ||
1155 | device_desc.bcdDevice = | ||
1156 | cpu_to_le16(0xFFFF); | ||
1157 | } | ||
1158 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", | ||
1159 | init_utsname()->sysname, init_utsname()->release, | ||
1160 | gadget->name); | ||
1161 | |||
1162 | if (iSerialNum) | ||
1163 | strlcpy(serial_num, iSerialNum, sizeof serial_num); | ||
1164 | |||
1165 | if (iPNPstring) | 1145 | if (iPNPstring) |
1166 | strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2); | 1146 | strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2); |
1167 | 1147 | ||
@@ -1169,26 +1149,6 @@ static int __init printer_bind_config(struct usb_configuration *c) | |||
1169 | pnp_string[0] = (len >> 8) & 0xFF; | 1149 | pnp_string[0] = (len >> 8) & 0xFF; |
1170 | pnp_string[1] = len & 0xFF; | 1150 | pnp_string[1] = len & 0xFF; |
1171 | 1151 | ||
1172 | /* all we really need is bulk IN/OUT */ | ||
1173 | usb_ep_autoconfig_reset(gadget); | ||
1174 | in_ep = usb_ep_autoconfig(gadget, &fs_ep_in_desc); | ||
1175 | if (!in_ep) { | ||
1176 | autoconf_fail: | ||
1177 | dev_err(&gadget->dev, "can't autoconfigure on %s\n", | ||
1178 | gadget->name); | ||
1179 | return -ENODEV; | ||
1180 | } | ||
1181 | in_ep->driver_data = in_ep; /* claim */ | ||
1182 | |||
1183 | out_ep = usb_ep_autoconfig(gadget, &fs_ep_out_desc); | ||
1184 | if (!out_ep) | ||
1185 | goto autoconf_fail; | ||
1186 | out_ep->driver_data = out_ep; /* claim */ | ||
1187 | |||
1188 | /* assumes that all endpoints are dual-speed */ | ||
1189 | hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; | ||
1190 | hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; | ||
1191 | |||
1192 | usb_gadget_set_selfpowered(gadget); | 1152 | usb_gadget_set_selfpowered(gadget); |
1193 | 1153 | ||
1194 | if (gadget->is_otg) { | 1154 | if (gadget->is_otg) { |
@@ -1215,9 +1175,6 @@ autoconf_fail: | |||
1215 | dev->current_rx_bytes = 0; | 1175 | dev->current_rx_bytes = 0; |
1216 | dev->current_rx_buf = NULL; | 1176 | dev->current_rx_buf = NULL; |
1217 | 1177 | ||
1218 | dev->in_ep = in_ep; | ||
1219 | dev->out_ep = out_ep; | ||
1220 | |||
1221 | for (i = 0; i < QLEN; i++) { | 1178 | for (i = 0; i < QLEN; i++) { |
1222 | req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); | 1179 | req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); |
1223 | if (!req) { | 1180 | if (!req) { |
@@ -1250,8 +1207,6 @@ autoconf_fail: | |||
1250 | dev->gadget = gadget; | 1207 | dev->gadget = gadget; |
1251 | 1208 | ||
1252 | INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); | 1209 | INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); |
1253 | INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, out_ep->name, | ||
1254 | in_ep->name); | ||
1255 | return 0; | 1210 | return 0; |
1256 | 1211 | ||
1257 | fail: | 1212 | fail: |
@@ -1266,14 +1221,28 @@ static int printer_unbind(struct usb_composite_dev *cdev) | |||
1266 | 1221 | ||
1267 | static int __init printer_bind(struct usb_composite_dev *cdev) | 1222 | static int __init printer_bind(struct usb_composite_dev *cdev) |
1268 | { | 1223 | { |
1269 | return usb_add_config(cdev, &printer_cfg_driver, printer_bind_config); | 1224 | int ret; |
1225 | |||
1226 | ret = usb_string_ids_tab(cdev, strings); | ||
1227 | if (ret < 0) | ||
1228 | return ret; | ||
1229 | device_desc.iManufacturer = strings[USB_GADGET_MANUFACTURER_IDX].id; | ||
1230 | device_desc.iProduct = strings[USB_GADGET_PRODUCT_IDX].id; | ||
1231 | device_desc.iSerialNumber = strings[USB_GADGET_SERIAL_IDX].id; | ||
1232 | |||
1233 | ret = usb_add_config(cdev, &printer_cfg_driver, printer_bind_config); | ||
1234 | if (ret) | ||
1235 | return ret; | ||
1236 | usb_composite_overwrite_options(cdev, &coverwrite); | ||
1237 | return ret; | ||
1270 | } | 1238 | } |
1271 | 1239 | ||
1272 | static struct usb_composite_driver printer_driver = { | 1240 | static __refdata struct usb_composite_driver printer_driver = { |
1273 | .name = shortname, | 1241 | .name = shortname, |
1274 | .dev = &device_desc, | 1242 | .dev = &device_desc, |
1275 | .strings = dev_strings, | 1243 | .strings = dev_strings, |
1276 | .max_speed = USB_SPEED_HIGH, | 1244 | .max_speed = USB_SPEED_HIGH, |
1245 | .bind = printer_bind, | ||
1277 | .unbind = printer_unbind, | 1246 | .unbind = printer_unbind, |
1278 | }; | 1247 | }; |
1279 | 1248 | ||
@@ -1297,7 +1266,7 @@ init(void) | |||
1297 | return status; | 1266 | return status; |
1298 | } | 1267 | } |
1299 | 1268 | ||
1300 | status = usb_composite_probe(&printer_driver, printer_bind); | 1269 | status = usb_composite_probe(&printer_driver); |
1301 | if (status) { | 1270 | if (status) { |
1302 | class_destroy(usb_gadget_class); | 1271 | class_destroy(usb_gadget_class); |
1303 | unregister_chrdev_region(g_printer_devno, 1); | 1272 | unregister_chrdev_region(g_printer_devno, 1); |