diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
| commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
| tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/usb/gadget | |
| parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) | |
Diffstat (limited to 'drivers/usb/gadget')
| -rw-r--r-- | drivers/usb/gadget/android.c | 1181 | ||||
| -rw-r--r-- | drivers/usb/gadget/ci13xxx_msm.c | 135 | ||||
| -rw-r--r-- | drivers/usb/gadget/ci13xxx_pci.c | 176 | ||||
| -rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 2977 | ||||
| -rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.h | 227 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_accessory.c | 788 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_adb.c | 635 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_audio.c | 798 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_mtp.c | 1264 | ||||
| -rw-r--r-- | drivers/usb/gadget/file_storage.c | 3631 | ||||
| -rw-r--r-- | drivers/usb/gadget/fsl_tegra_udc.c | 155 | ||||
| -rw-r--r-- | drivers/usb/gadget/langwell_udc.c | 3607 | ||||
| -rw-r--r-- | drivers/usb/gadget/langwell_udc.h | 233 | ||||
| -rw-r--r-- | drivers/usb/gadget/mv_udc_phy.c | 214 | ||||
| -rw-r--r-- | drivers/usb/gadget/u_audio.c | 327 | ||||
| -rw-r--r-- | drivers/usb/gadget/u_audio.h | 56 |
16 files changed, 16404 insertions, 0 deletions
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c new file mode 100644 index 00000000000..fbafe8a3bca --- /dev/null +++ b/drivers/usb/gadget/android.c | |||
| @@ -0,0 +1,1181 @@ | |||
| 1 | /* | ||
| 2 | * Gadget Driver for Android | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Google, Inc. | ||
| 5 | * Author: Mike Lockwood <lockwood@android.com> | ||
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* #define DEBUG */ | ||
| 19 | /* #define VERBOSE_DEBUG */ | ||
| 20 | |||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/fs.h> | ||
| 24 | |||
| 25 | #include <linux/delay.h> | ||
| 26 | #include <linux/kernel.h> | ||
| 27 | #include <linux/utsname.h> | ||
| 28 | #include <linux/platform_device.h> | ||
| 29 | |||
| 30 | #include <linux/usb/ch9.h> | ||
| 31 | #include <linux/usb/composite.h> | ||
| 32 | #include <linux/usb/gadget.h> | ||
| 33 | |||
| 34 | #include "gadget_chips.h" | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Kbuild is not very cooperative with respect to linking separately | ||
| 38 | * compiled library objects into one module. So for now we won't use | ||
| 39 | * separate compilation ... ensuring init/exit sections work to shrink | ||
| 40 | * the runtime footprint, and giving us at least some parts of what | ||
| 41 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
| 42 | */ | ||
| 43 | #include "usbstring.c" | ||
| 44 | #include "config.c" | ||
| 45 | #include "epautoconf.c" | ||
| 46 | #include "composite.c" | ||
| 47 | |||
| 48 | #include "f_mass_storage.c" | ||
| 49 | #include "u_serial.c" | ||
| 50 | #include "f_acm.c" | ||
| 51 | #include "f_adb.c" | ||
| 52 | #include "f_mtp.c" | ||
| 53 | #include "f_accessory.c" | ||
| 54 | #define USB_ETH_RNDIS y | ||
| 55 | #include "f_rndis.c" | ||
| 56 | #include "rndis.c" | ||
| 57 | #include "u_ether.c" | ||
| 58 | |||
| 59 | MODULE_AUTHOR("Mike Lockwood"); | ||
| 60 | MODULE_DESCRIPTION("Android Composite USB Driver"); | ||
| 61 | MODULE_LICENSE("GPL"); | ||
| 62 | MODULE_VERSION("1.0"); | ||
| 63 | |||
| 64 | static const char longname[] = "Gadget Android"; | ||
| 65 | |||
| 66 | /* Default vendor and product IDs, overridden by userspace */ | ||
| 67 | #define VENDOR_ID 0x18D1 | ||
| 68 | #define PRODUCT_ID 0x0001 | ||
| 69 | |||
| 70 | struct android_usb_function { | ||
| 71 | char *name; | ||
| 72 | void *config; | ||
| 73 | |||
| 74 | struct device *dev; | ||
| 75 | char *dev_name; | ||
| 76 | struct device_attribute **attributes; | ||
| 77 | |||
| 78 | /* for android_dev.enabled_functions */ | ||
| 79 | struct list_head enabled_list; | ||
| 80 | |||
| 81 | /* Optional: initialization during gadget bind */ | ||
| 82 | int (*init)(struct android_usb_function *, struct usb_composite_dev *); | ||
| 83 | /* Optional: cleanup during gadget unbind */ | ||
| 84 | void (*cleanup)(struct android_usb_function *); | ||
| 85 | |||
| 86 | int (*bind_config)(struct android_usb_function *, struct usb_configuration *); | ||
| 87 | |||
| 88 | /* Optional: called when the configuration is removed */ | ||
| 89 | void (*unbind_config)(struct android_usb_function *, struct usb_configuration *); | ||
| 90 | /* Optional: handle ctrl requests before the device is configured */ | ||
| 91 | int (*ctrlrequest)(struct android_usb_function *, | ||
| 92 | struct usb_composite_dev *, | ||
| 93 | const struct usb_ctrlrequest *); | ||
| 94 | }; | ||
| 95 | |||
| 96 | struct android_dev { | ||
| 97 | struct android_usb_function **functions; | ||
| 98 | struct list_head enabled_functions; | ||
| 99 | struct usb_composite_dev *cdev; | ||
| 100 | struct device *dev; | ||
| 101 | |||
| 102 | bool enabled; | ||
| 103 | struct mutex mutex; | ||
| 104 | bool connected; | ||
| 105 | bool sw_connected; | ||
| 106 | struct work_struct work; | ||
| 107 | }; | ||
| 108 | |||
| 109 | static struct class *android_class; | ||
| 110 | static struct android_dev *_android_dev; | ||
| 111 | static int android_bind_config(struct usb_configuration *c); | ||
| 112 | static void android_unbind_config(struct usb_configuration *c); | ||
| 113 | |||
| 114 | /* string IDs are assigned dynamically */ | ||
| 115 | #define STRING_MANUFACTURER_IDX 0 | ||
| 116 | #define STRING_PRODUCT_IDX 1 | ||
| 117 | #define STRING_SERIAL_IDX 2 | ||
| 118 | |||
| 119 | static char manufacturer_string[256]; | ||
| 120 | static char product_string[256]; | ||
| 121 | static char serial_string[256]; | ||
| 122 | |||
| 123 | /* String Table */ | ||
| 124 | static struct usb_string strings_dev[] = { | ||
| 125 | [STRING_MANUFACTURER_IDX].s = manufacturer_string, | ||
| 126 | [STRING_PRODUCT_IDX].s = product_string, | ||
| 127 | [STRING_SERIAL_IDX].s = serial_string, | ||
| 128 | { } /* end of list */ | ||
| 129 | }; | ||
| 130 | |||
| 131 | static struct usb_gadget_strings stringtab_dev = { | ||
| 132 | .language = 0x0409, /* en-us */ | ||
| 133 | .strings = strings_dev, | ||
| 134 | }; | ||
| 135 | |||
| 136 | static struct usb_gadget_strings *dev_strings[] = { | ||
| 137 | &stringtab_dev, | ||
| 138 | NULL, | ||
| 139 | }; | ||
| 140 | |||
| 141 | static struct usb_device_descriptor device_desc = { | ||
| 142 | .bLength = sizeof(device_desc), | ||
| 143 | .bDescriptorType = USB_DT_DEVICE, | ||
| 144 | .bcdUSB = __constant_cpu_to_le16(0x0200), | ||
| 145 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | ||
| 146 | .idVendor = __constant_cpu_to_le16(VENDOR_ID), | ||
| 147 | .idProduct = __constant_cpu_to_le16(PRODUCT_ID), | ||
| 148 | .bcdDevice = __constant_cpu_to_le16(0xffff), | ||
| 149 | .bNumConfigurations = 1, | ||
| 150 | }; | ||
| 151 | |||
| 152 | static struct usb_configuration android_config_driver = { | ||
| 153 | .label = "android", | ||
| 154 | .unbind = android_unbind_config, | ||
| 155 | .bConfigurationValue = 1, | ||
| 156 | }; | ||
| 157 | |||
| 158 | static void android_work(struct work_struct *data) | ||
| 159 | { | ||
| 160 | struct android_dev *dev = container_of(data, struct android_dev, work); | ||
| 161 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 162 | char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL }; | ||
| 163 | char *connected[2] = { "USB_STATE=CONNECTED", NULL }; | ||
| 164 | char *configured[2] = { "USB_STATE=CONFIGURED", NULL }; | ||
| 165 | char **uevent_envp = NULL; | ||
| 166 | unsigned long flags; | ||
| 167 | |||
| 168 | spin_lock_irqsave(&cdev->lock, flags); | ||
| 169 | if (cdev->config) | ||
| 170 | uevent_envp = configured; | ||
| 171 | else if (dev->connected != dev->sw_connected) | ||
| 172 | uevent_envp = dev->connected ? connected : disconnected; | ||
| 173 | dev->sw_connected = dev->connected; | ||
| 174 | spin_unlock_irqrestore(&cdev->lock, flags); | ||
| 175 | |||
| 176 | if (uevent_envp) { | ||
| 177 | kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp); | ||
| 178 | pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]); | ||
| 179 | } else { | ||
| 180 | pr_info("%s: did not send uevent (%d %d %p)\n", __func__, | ||
| 181 | dev->connected, dev->sw_connected, cdev->config); | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | |||
| 186 | /*-------------------------------------------------------------------------*/ | ||
| 187 | /* Supported functions initialization */ | ||
| 188 | |||
| 189 | static int adb_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) | ||
| 190 | { | ||
| 191 | return adb_setup(); | ||
| 192 | } | ||
| 193 | |||
| 194 | static void adb_function_cleanup(struct android_usb_function *f) | ||
| 195 | { | ||
| 196 | adb_cleanup(); | ||
| 197 | } | ||
| 198 | |||
| 199 | static int adb_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) | ||
| 200 | { | ||
| 201 | return adb_bind_config(c); | ||
| 202 | } | ||
| 203 | |||
| 204 | static struct android_usb_function adb_function = { | ||
| 205 | .name = "adb", | ||
| 206 | .init = adb_function_init, | ||
| 207 | .cleanup = adb_function_cleanup, | ||
| 208 | .bind_config = adb_function_bind_config, | ||
| 209 | }; | ||
| 210 | |||
| 211 | |||
| 212 | #define MAX_ACM_INSTANCES 4 | ||
| 213 | struct acm_function_config { | ||
| 214 | int instances; | ||
| 215 | }; | ||
| 216 | |||
| 217 | static int acm_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) | ||
| 218 | { | ||
| 219 | f->config = kzalloc(sizeof(struct acm_function_config), GFP_KERNEL); | ||
| 220 | if (!f->config) | ||
| 221 | return -ENOMEM; | ||
| 222 | |||
| 223 | return gserial_setup(cdev->gadget, MAX_ACM_INSTANCES); | ||
| 224 | } | ||
| 225 | |||
| 226 | static void acm_function_cleanup(struct android_usb_function *f) | ||
| 227 | { | ||
| 228 | gserial_cleanup(); | ||
| 229 | kfree(f->config); | ||
| 230 | f->config = NULL; | ||
| 231 | } | ||
| 232 | |||
| 233 | static int acm_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) | ||
| 234 | { | ||
| 235 | int i; | ||
| 236 | int ret = 0; | ||
| 237 | struct acm_function_config *config = f->config; | ||
| 238 | |||
| 239 | for (i = 0; i < config->instances; i++) { | ||
| 240 | ret = acm_bind_config(c, i); | ||
| 241 | if (ret) { | ||
| 242 | pr_err("Could not bind acm%u config\n", i); | ||
| 243 | break; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | return ret; | ||
| 248 | } | ||
| 249 | |||
| 250 | static ssize_t acm_instances_show(struct device *dev, | ||
| 251 | struct device_attribute *attr, char *buf) | ||
| 252 | { | ||
| 253 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 254 | struct acm_function_config *config = f->config; | ||
| 255 | return sprintf(buf, "%d\n", config->instances); | ||
| 256 | } | ||
| 257 | |||
| 258 | static ssize_t acm_instances_store(struct device *dev, | ||
| 259 | struct device_attribute *attr, const char *buf, size_t size) | ||
| 260 | { | ||
| 261 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 262 | struct acm_function_config *config = f->config; | ||
| 263 | int value; | ||
| 264 | |||
| 265 | sscanf(buf, "%d", &value); | ||
| 266 | if (value > MAX_ACM_INSTANCES) | ||
| 267 | value = MAX_ACM_INSTANCES; | ||
| 268 | config->instances = value; | ||
| 269 | return size; | ||
| 270 | } | ||
| 271 | |||
| 272 | static DEVICE_ATTR(instances, S_IRUGO | S_IWUSR, acm_instances_show, acm_instances_store); | ||
| 273 | static struct device_attribute *acm_function_attributes[] = { &dev_attr_instances, NULL }; | ||
| 274 | |||
| 275 | static struct android_usb_function acm_function = { | ||
| 276 | .name = "acm", | ||
| 277 | .init = acm_function_init, | ||
| 278 | .cleanup = acm_function_cleanup, | ||
| 279 | .bind_config = acm_function_bind_config, | ||
| 280 | .attributes = acm_function_attributes, | ||
| 281 | }; | ||
| 282 | |||
| 283 | |||
| 284 | static int mtp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) | ||
| 285 | { | ||
| 286 | return mtp_setup(); | ||
| 287 | } | ||
| 288 | |||
| 289 | static void mtp_function_cleanup(struct android_usb_function *f) | ||
| 290 | { | ||
| 291 | mtp_cleanup(); | ||
| 292 | } | ||
| 293 | |||
| 294 | static int mtp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) | ||
| 295 | { | ||
| 296 | return mtp_bind_config(c, false); | ||
| 297 | } | ||
| 298 | |||
| 299 | static int ptp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) | ||
| 300 | { | ||
| 301 | /* nothing to do - initialization is handled by mtp_function_init */ | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | |||
| 305 | static void ptp_function_cleanup(struct android_usb_function *f) | ||
| 306 | { | ||
| 307 | /* nothing to do - cleanup is handled by mtp_function_cleanup */ | ||
| 308 | } | ||
| 309 | |||
| 310 | static int ptp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) | ||
| 311 | { | ||
| 312 | return mtp_bind_config(c, true); | ||
| 313 | } | ||
| 314 | |||
| 315 | static int mtp_function_ctrlrequest(struct android_usb_function *f, | ||
| 316 | struct usb_composite_dev *cdev, | ||
| 317 | const struct usb_ctrlrequest *c) | ||
| 318 | { | ||
| 319 | return mtp_ctrlrequest(cdev, c); | ||
| 320 | } | ||
| 321 | |||
| 322 | static struct android_usb_function mtp_function = { | ||
| 323 | .name = "mtp", | ||
| 324 | .init = mtp_function_init, | ||
| 325 | .cleanup = mtp_function_cleanup, | ||
| 326 | .bind_config = mtp_function_bind_config, | ||
| 327 | .ctrlrequest = mtp_function_ctrlrequest, | ||
| 328 | }; | ||
| 329 | |||
| 330 | /* PTP function is same as MTP with slightly different interface descriptor */ | ||
| 331 | static struct android_usb_function ptp_function = { | ||
| 332 | .name = "ptp", | ||
| 333 | .init = ptp_function_init, | ||
| 334 | .cleanup = ptp_function_cleanup, | ||
| 335 | .bind_config = ptp_function_bind_config, | ||
| 336 | }; | ||
| 337 | |||
| 338 | |||
| 339 | struct rndis_function_config { | ||
| 340 | u8 ethaddr[ETH_ALEN]; | ||
| 341 | u32 vendorID; | ||
| 342 | char manufacturer[256]; | ||
| 343 | bool wceis; | ||
| 344 | }; | ||
| 345 | |||
| 346 | static int rndis_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) | ||
| 347 | { | ||
| 348 | f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL); | ||
| 349 | if (!f->config) | ||
| 350 | return -ENOMEM; | ||
| 351 | return 0; | ||
| 352 | } | ||
| 353 | |||
| 354 | static void rndis_function_cleanup(struct android_usb_function *f) | ||
| 355 | { | ||
| 356 | kfree(f->config); | ||
| 357 | f->config = NULL; | ||
| 358 | } | ||
| 359 | |||
| 360 | static int rndis_function_bind_config(struct android_usb_function *f, | ||
| 361 | struct usb_configuration *c) | ||
| 362 | { | ||
| 363 | int ret; | ||
| 364 | struct rndis_function_config *rndis = f->config; | ||
| 365 | |||
| 366 | if (!rndis) { | ||
| 367 | pr_err("%s: rndis_pdata\n", __func__); | ||
| 368 | return -1; | ||
| 369 | } | ||
| 370 | |||
| 371 | pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__, | ||
| 372 | rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2], | ||
| 373 | rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]); | ||
| 374 | |||
| 375 | ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis"); | ||
| 376 | if (ret) { | ||
| 377 | pr_err("%s: gether_setup failed\n", __func__); | ||
| 378 | return ret; | ||
| 379 | } | ||
| 380 | |||
| 381 | if (rndis->wceis) { | ||
| 382 | /* "Wireless" RNDIS; auto-detected by Windows */ | ||
| 383 | rndis_iad_descriptor.bFunctionClass = | ||
| 384 | USB_CLASS_WIRELESS_CONTROLLER; | ||
| 385 | rndis_iad_descriptor.bFunctionSubClass = 0x01; | ||
| 386 | rndis_iad_descriptor.bFunctionProtocol = 0x03; | ||
| 387 | rndis_control_intf.bInterfaceClass = | ||
| 388 | USB_CLASS_WIRELESS_CONTROLLER; | ||
| 389 | rndis_control_intf.bInterfaceSubClass = 0x01; | ||
| 390 | rndis_control_intf.bInterfaceProtocol = 0x03; | ||
| 391 | } | ||
| 392 | |||
| 393 | return rndis_bind_config(c, rndis->ethaddr, rndis->vendorID, | ||
| 394 | rndis->manufacturer); | ||
| 395 | } | ||
| 396 | |||
| 397 | static void rndis_function_unbind_config(struct android_usb_function *f, | ||
| 398 | struct usb_configuration *c) | ||
| 399 | { | ||
| 400 | gether_cleanup(); | ||
| 401 | } | ||
| 402 | |||
| 403 | static ssize_t rndis_manufacturer_show(struct device *dev, | ||
| 404 | struct device_attribute *attr, char *buf) | ||
| 405 | { | ||
| 406 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 407 | struct rndis_function_config *config = f->config; | ||
| 408 | return sprintf(buf, "%s\n", config->manufacturer); | ||
| 409 | } | ||
| 410 | |||
| 411 | static ssize_t rndis_manufacturer_store(struct device *dev, | ||
| 412 | struct device_attribute *attr, const char *buf, size_t size) | ||
| 413 | { | ||
| 414 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 415 | struct rndis_function_config *config = f->config; | ||
| 416 | |||
| 417 | if (size >= sizeof(config->manufacturer)) | ||
| 418 | return -EINVAL; | ||
| 419 | if (sscanf(buf, "%s", config->manufacturer) == 1) | ||
| 420 | return size; | ||
| 421 | return -1; | ||
| 422 | } | ||
| 423 | |||
| 424 | static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show, | ||
| 425 | rndis_manufacturer_store); | ||
| 426 | |||
| 427 | static ssize_t rndis_wceis_show(struct device *dev, | ||
| 428 | struct device_attribute *attr, char *buf) | ||
| 429 | { | ||
| 430 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 431 | struct rndis_function_config *config = f->config; | ||
| 432 | return sprintf(buf, "%d\n", config->wceis); | ||
| 433 | } | ||
| 434 | |||
| 435 | static ssize_t rndis_wceis_store(struct device *dev, | ||
| 436 | struct device_attribute *attr, const char *buf, size_t size) | ||
| 437 | { | ||
| 438 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 439 | struct rndis_function_config *config = f->config; | ||
| 440 | int value; | ||
| 441 | |||
| 442 | if (sscanf(buf, "%d", &value) == 1) { | ||
| 443 | config->wceis = value; | ||
| 444 | return size; | ||
| 445 | } | ||
| 446 | return -EINVAL; | ||
| 447 | } | ||
| 448 | |||
| 449 | static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show, | ||
| 450 | rndis_wceis_store); | ||
| 451 | |||
| 452 | static ssize_t rndis_ethaddr_show(struct device *dev, | ||
| 453 | struct device_attribute *attr, char *buf) | ||
| 454 | { | ||
| 455 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 456 | struct rndis_function_config *rndis = f->config; | ||
| 457 | return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", | ||
| 458 | rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2], | ||
| 459 | rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]); | ||
| 460 | } | ||
| 461 | |||
| 462 | static ssize_t rndis_ethaddr_store(struct device *dev, | ||
| 463 | struct device_attribute *attr, const char *buf, size_t size) | ||
| 464 | { | ||
| 465 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 466 | struct rndis_function_config *rndis = f->config; | ||
| 467 | |||
| 468 | if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", | ||
| 469 | (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1], | ||
| 470 | (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3], | ||
| 471 | (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6) | ||
| 472 | return size; | ||
| 473 | return -EINVAL; | ||
| 474 | } | ||
| 475 | |||
| 476 | static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show, | ||
| 477 | rndis_ethaddr_store); | ||
| 478 | |||
| 479 | static ssize_t rndis_vendorID_show(struct device *dev, | ||
| 480 | struct device_attribute *attr, char *buf) | ||
| 481 | { | ||
| 482 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 483 | struct rndis_function_config *config = f->config; | ||
| 484 | return sprintf(buf, "%04x\n", config->vendorID); | ||
| 485 | } | ||
| 486 | |||
| 487 | static ssize_t rndis_vendorID_store(struct device *dev, | ||
| 488 | struct device_attribute *attr, const char *buf, size_t size) | ||
| 489 | { | ||
| 490 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 491 | struct rndis_function_config *config = f->config; | ||
| 492 | int value; | ||
| 493 | |||
| 494 | if (sscanf(buf, "%04x", &value) == 1) { | ||
| 495 | config->vendorID = value; | ||
| 496 | return size; | ||
| 497 | } | ||
| 498 | return -EINVAL; | ||
| 499 | } | ||
| 500 | |||
| 501 | static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show, | ||
| 502 | rndis_vendorID_store); | ||
| 503 | |||
| 504 | static struct device_attribute *rndis_function_attributes[] = { | ||
| 505 | &dev_attr_manufacturer, | ||
| 506 | &dev_attr_wceis, | ||
| 507 | &dev_attr_ethaddr, | ||
| 508 | &dev_attr_vendorID, | ||
| 509 | NULL | ||
| 510 | }; | ||
| 511 | |||
| 512 | static struct android_usb_function rndis_function = { | ||
| 513 | .name = "rndis", | ||
| 514 | .init = rndis_function_init, | ||
| 515 | .cleanup = rndis_function_cleanup, | ||
| 516 | .bind_config = rndis_function_bind_config, | ||
| 517 | .unbind_config = rndis_function_unbind_config, | ||
| 518 | .attributes = rndis_function_attributes, | ||
| 519 | }; | ||
| 520 | |||
| 521 | |||
| 522 | struct mass_storage_function_config { | ||
| 523 | struct fsg_config fsg; | ||
| 524 | struct fsg_common *common; | ||
| 525 | }; | ||
| 526 | |||
| 527 | static int mass_storage_function_init(struct android_usb_function *f, | ||
| 528 | struct usb_composite_dev *cdev) | ||
| 529 | { | ||
| 530 | struct mass_storage_function_config *config; | ||
| 531 | struct fsg_common *common; | ||
| 532 | int err; | ||
| 533 | |||
| 534 | config = kzalloc(sizeof(struct mass_storage_function_config), | ||
| 535 | GFP_KERNEL); | ||
| 536 | if (!config) | ||
| 537 | return -ENOMEM; | ||
| 538 | |||
| 539 | config->fsg.nluns = 1; | ||
| 540 | config->fsg.luns[0].removable = 1; | ||
| 541 | |||
| 542 | common = fsg_common_init(NULL, cdev, &config->fsg); | ||
| 543 | if (IS_ERR(common)) { | ||
| 544 | kfree(config); | ||
| 545 | return PTR_ERR(common); | ||
| 546 | } | ||
| 547 | |||
| 548 | err = sysfs_create_link(&f->dev->kobj, | ||
| 549 | &common->luns[0].dev.kobj, | ||
| 550 | "lun"); | ||
| 551 | if (err) { | ||
| 552 | kfree(config); | ||
| 553 | return err; | ||
| 554 | } | ||
| 555 | |||
| 556 | config->common = common; | ||
| 557 | f->config = config; | ||
| 558 | return 0; | ||
| 559 | } | ||
| 560 | |||
| 561 | static void mass_storage_function_cleanup(struct android_usb_function *f) | ||
| 562 | { | ||
| 563 | kfree(f->config); | ||
| 564 | f->config = NULL; | ||
| 565 | } | ||
| 566 | |||
| 567 | static int mass_storage_function_bind_config(struct android_usb_function *f, | ||
| 568 | struct usb_configuration *c) | ||
| 569 | { | ||
| 570 | struct mass_storage_function_config *config = f->config; | ||
| 571 | return fsg_bind_config(c->cdev, c, config->common); | ||
| 572 | } | ||
| 573 | |||
| 574 | static ssize_t mass_storage_inquiry_show(struct device *dev, | ||
| 575 | struct device_attribute *attr, char *buf) | ||
| 576 | { | ||
| 577 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 578 | struct mass_storage_function_config *config = f->config; | ||
| 579 | return sprintf(buf, "%s\n", config->common->inquiry_string); | ||
| 580 | } | ||
| 581 | |||
| 582 | static ssize_t mass_storage_inquiry_store(struct device *dev, | ||
| 583 | struct device_attribute *attr, const char *buf, size_t size) | ||
| 584 | { | ||
| 585 | struct android_usb_function *f = dev_get_drvdata(dev); | ||
| 586 | struct mass_storage_function_config *config = f->config; | ||
| 587 | if (size >= sizeof(config->common->inquiry_string)) | ||
| 588 | return -EINVAL; | ||
| 589 | if (sscanf(buf, "%s", config->common->inquiry_string) != 1) | ||
| 590 | return -EINVAL; | ||
| 591 | return size; | ||
| 592 | } | ||
| 593 | |||
| 594 | static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR, | ||
| 595 | mass_storage_inquiry_show, | ||
| 596 | mass_storage_inquiry_store); | ||
| 597 | |||
| 598 | static struct device_attribute *mass_storage_function_attributes[] = { | ||
| 599 | &dev_attr_inquiry_string, | ||
| 600 | NULL | ||
| 601 | }; | ||
| 602 | |||
| 603 | static struct android_usb_function mass_storage_function = { | ||
| 604 | .name = "mass_storage", | ||
| 605 | .init = mass_storage_function_init, | ||
| 606 | .cleanup = mass_storage_function_cleanup, | ||
| 607 | .bind_config = mass_storage_function_bind_config, | ||
| 608 | .attributes = mass_storage_function_attributes, | ||
| 609 | }; | ||
| 610 | |||
| 611 | |||
| 612 | static int accessory_function_init(struct android_usb_function *f, | ||
| 613 | struct usb_composite_dev *cdev) | ||
| 614 | { | ||
| 615 | return acc_setup(); | ||
| 616 | } | ||
| 617 | |||
| 618 | static void accessory_function_cleanup(struct android_usb_function *f) | ||
| 619 | { | ||
| 620 | acc_cleanup(); | ||
| 621 | } | ||
| 622 | |||
| 623 | static int accessory_function_bind_config(struct android_usb_function *f, | ||
| 624 | struct usb_configuration *c) | ||
| 625 | { | ||
| 626 | return acc_bind_config(c); | ||
| 627 | } | ||
| 628 | |||
| 629 | static int accessory_function_ctrlrequest(struct android_usb_function *f, | ||
| 630 | struct usb_composite_dev *cdev, | ||
| 631 | const struct usb_ctrlrequest *c) | ||
| 632 | { | ||
| 633 | return acc_ctrlrequest(cdev, c); | ||
| 634 | } | ||
| 635 | |||
| 636 | static struct android_usb_function accessory_function = { | ||
| 637 | .name = "accessory", | ||
| 638 | .init = accessory_function_init, | ||
| 639 | .cleanup = accessory_function_cleanup, | ||
| 640 | .bind_config = accessory_function_bind_config, | ||
| 641 | .ctrlrequest = accessory_function_ctrlrequest, | ||
| 642 | }; | ||
| 643 | |||
| 644 | |||
| 645 | static struct android_usb_function *supported_functions[] = { | ||
| 646 | &adb_function, | ||
| 647 | &acm_function, | ||
| 648 | &mtp_function, | ||
| 649 | &ptp_function, | ||
| 650 | &rndis_function, | ||
| 651 | &mass_storage_function, | ||
| 652 | &accessory_function, | ||
| 653 | NULL | ||
| 654 | }; | ||
| 655 | |||
| 656 | |||
| 657 | static int android_init_functions(struct android_usb_function **functions, | ||
| 658 | struct usb_composite_dev *cdev) | ||
| 659 | { | ||
| 660 | struct android_dev *dev = _android_dev; | ||
| 661 | struct android_usb_function *f; | ||
| 662 | struct device_attribute **attrs; | ||
| 663 | struct device_attribute *attr; | ||
| 664 | int err; | ||
| 665 | int index = 0; | ||
| 666 | |||
| 667 | for (; (f = *functions++); index++) { | ||
| 668 | f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name); | ||
| 669 | f->dev = device_create(android_class, dev->dev, | ||
| 670 | MKDEV(0, index), f, f->dev_name); | ||
| 671 | if (IS_ERR(f->dev)) { | ||
| 672 | pr_err("%s: Failed to create dev %s", __func__, | ||
| 673 | f->dev_name); | ||
| 674 | err = PTR_ERR(f->dev); | ||
| 675 | goto err_create; | ||
| 676 | } | ||
| 677 | |||
| 678 | if (f->init) { | ||
| 679 | err = f->init(f, cdev); | ||
| 680 | if (err) { | ||
| 681 | pr_err("%s: Failed to init %s", __func__, | ||
| 682 | f->name); | ||
| 683 | goto err_out; | ||
| 684 | } | ||
| 685 | } | ||
| 686 | |||
| 687 | attrs = f->attributes; | ||
| 688 | if (attrs) { | ||
| 689 | while ((attr = *attrs++) && !err) | ||
| 690 | err = device_create_file(f->dev, attr); | ||
| 691 | } | ||
| 692 | if (err) { | ||
| 693 | pr_err("%s: Failed to create function %s attributes", | ||
| 694 | __func__, f->name); | ||
| 695 | goto err_out; | ||
| 696 | } | ||
| 697 | } | ||
| 698 | return 0; | ||
| 699 | |||
| 700 | err_out: | ||
| 701 | device_destroy(android_class, f->dev->devt); | ||
| 702 | err_create: | ||
| 703 | kfree(f->dev_name); | ||
| 704 | return err; | ||
| 705 | } | ||
| 706 | |||
| 707 | static void android_cleanup_functions(struct android_usb_function **functions) | ||
| 708 | { | ||
| 709 | struct android_usb_function *f; | ||
| 710 | |||
| 711 | while (*functions) { | ||
| 712 | f = *functions++; | ||
| 713 | |||
| 714 | if (f->dev) { | ||
| 715 | device_destroy(android_class, f->dev->devt); | ||
| 716 | kfree(f->dev_name); | ||
| 717 | } | ||
| 718 | |||
| 719 | if (f->cleanup) | ||
| 720 | f->cleanup(f); | ||
| 721 | } | ||
| 722 | } | ||
| 723 | |||
| 724 | static int | ||
| 725 | android_bind_enabled_functions(struct android_dev *dev, | ||
| 726 | struct usb_configuration *c) | ||
| 727 | { | ||
| 728 | struct android_usb_function *f; | ||
| 729 | int ret; | ||
| 730 | |||
| 731 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) { | ||
| 732 | ret = f->bind_config(f, c); | ||
| 733 | if (ret) { | ||
| 734 | pr_err("%s: %s failed", __func__, f->name); | ||
| 735 | return ret; | ||
| 736 | } | ||
| 737 | } | ||
| 738 | return 0; | ||
| 739 | } | ||
| 740 | |||
| 741 | static void | ||
| 742 | android_unbind_enabled_functions(struct android_dev *dev, | ||
| 743 | struct usb_configuration *c) | ||
| 744 | { | ||
| 745 | struct android_usb_function *f; | ||
| 746 | |||
| 747 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) { | ||
| 748 | if (f->unbind_config) | ||
| 749 | f->unbind_config(f, c); | ||
| 750 | } | ||
| 751 | } | ||
| 752 | |||
| 753 | static int android_enable_function(struct android_dev *dev, char *name) | ||
| 754 | { | ||
| 755 | struct android_usb_function **functions = dev->functions; | ||
| 756 | struct android_usb_function *f; | ||
| 757 | while ((f = *functions++)) { | ||
| 758 | if (!strcmp(name, f->name)) { | ||
| 759 | list_add_tail(&f->enabled_list, &dev->enabled_functions); | ||
| 760 | return 0; | ||
| 761 | } | ||
| 762 | } | ||
| 763 | return -EINVAL; | ||
| 764 | } | ||
| 765 | |||
| 766 | /*-------------------------------------------------------------------------*/ | ||
| 767 | /* /sys/class/android_usb/android%d/ interface */ | ||
| 768 | |||
| 769 | static ssize_t | ||
| 770 | functions_show(struct device *pdev, struct device_attribute *attr, char *buf) | ||
| 771 | { | ||
| 772 | struct android_dev *dev = dev_get_drvdata(pdev); | ||
| 773 | struct android_usb_function *f; | ||
| 774 | char *buff = buf; | ||
| 775 | |||
| 776 | mutex_lock(&dev->mutex); | ||
| 777 | |||
| 778 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) | ||
| 779 | buff += sprintf(buff, "%s,", f->name); | ||
| 780 | |||
| 781 | mutex_unlock(&dev->mutex); | ||
| 782 | |||
| 783 | if (buff != buf) | ||
| 784 | *(buff-1) = '\n'; | ||
| 785 | return buff - buf; | ||
| 786 | } | ||
| 787 | |||
| 788 | static ssize_t | ||
| 789 | functions_store(struct device *pdev, struct device_attribute *attr, | ||
| 790 | const char *buff, size_t size) | ||
| 791 | { | ||
| 792 | struct android_dev *dev = dev_get_drvdata(pdev); | ||
| 793 | char *name; | ||
| 794 | char buf[256], *b; | ||
| 795 | int err; | ||
| 796 | |||
| 797 | mutex_lock(&dev->mutex); | ||
| 798 | |||
| 799 | if (dev->enabled) { | ||
| 800 | mutex_unlock(&dev->mutex); | ||
| 801 | return -EBUSY; | ||
| 802 | } | ||
| 803 | |||
| 804 | INIT_LIST_HEAD(&dev->enabled_functions); | ||
| 805 | |||
| 806 | strncpy(buf, buff, sizeof(buf)); | ||
| 807 | b = strim(buf); | ||
| 808 | |||
| 809 | while (b) { | ||
| 810 | name = strsep(&b, ","); | ||
| 811 | if (name) { | ||
| 812 | err = android_enable_function(dev, name); | ||
| 813 | if (err) | ||
| 814 | pr_err("android_usb: Cannot enable '%s'", name); | ||
| 815 | } | ||
| 816 | } | ||
| 817 | |||
| 818 | mutex_unlock(&dev->mutex); | ||
| 819 | |||
| 820 | return size; | ||
| 821 | } | ||
| 822 | |||
| 823 | static ssize_t enable_show(struct device *pdev, struct device_attribute *attr, | ||
| 824 | char *buf) | ||
| 825 | { | ||
| 826 | struct android_dev *dev = dev_get_drvdata(pdev); | ||
| 827 | return sprintf(buf, "%d\n", dev->enabled); | ||
| 828 | } | ||
| 829 | |||
| 830 | static ssize_t enable_store(struct device *pdev, struct device_attribute *attr, | ||
| 831 | const char *buff, size_t size) | ||
| 832 | { | ||
| 833 | struct android_dev *dev = dev_get_drvdata(pdev); | ||
| 834 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 835 | int enabled = 0; | ||
| 836 | |||
| 837 | mutex_lock(&dev->mutex); | ||
| 838 | |||
| 839 | sscanf(buff, "%d", &enabled); | ||
| 840 | if (enabled && !dev->enabled) { | ||
| 841 | /* update values in composite driver's copy of device descriptor */ | ||
| 842 | cdev->desc.idVendor = device_desc.idVendor; | ||
| 843 | cdev->desc.idProduct = device_desc.idProduct; | ||
| 844 | cdev->desc.bcdDevice = device_desc.bcdDevice; | ||
| 845 | cdev->desc.bDeviceClass = device_desc.bDeviceClass; | ||
| 846 | cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass; | ||
| 847 | cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol; | ||
| 848 | usb_add_config(cdev, &android_config_driver, | ||
| 849 | android_bind_config); | ||
| 850 | usb_gadget_connect(cdev->gadget); | ||
| 851 | dev->enabled = true; | ||
| 852 | } else if (!enabled && dev->enabled) { | ||
| 853 | usb_gadget_disconnect(cdev->gadget); | ||
| 854 | /* Cancel pending control requests */ | ||
| 855 | usb_ep_dequeue(cdev->gadget->ep0, cdev->req); | ||
| 856 | usb_remove_config(cdev, &android_config_driver); | ||
| 857 | dev->enabled = false; | ||
| 858 | } else { | ||
| 859 | pr_err("android_usb: already %s\n", | ||
| 860 | dev->enabled ? "enabled" : "disabled"); | ||
| 861 | } | ||
| 862 | |||
| 863 | mutex_unlock(&dev->mutex); | ||
| 864 | return size; | ||
| 865 | } | ||
| 866 | |||
| 867 | static ssize_t state_show(struct device *pdev, struct device_attribute *attr, | ||
| 868 | char *buf) | ||
| 869 | { | ||
| 870 | struct android_dev *dev = dev_get_drvdata(pdev); | ||
| 871 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 872 | char *state = "DISCONNECTED"; | ||
| 873 | unsigned long flags; | ||
| 874 | |||
| 875 | if (!cdev) | ||
| 876 | goto out; | ||
| 877 | |||
| 878 | spin_lock_irqsave(&cdev->lock, flags); | ||
| 879 | if (cdev->config) | ||
| 880 | state = "CONFIGURED"; | ||
| 881 | else if (dev->connected) | ||
| 882 | state = "CONNECTED"; | ||
| 883 | spin_unlock_irqrestore(&cdev->lock, flags); | ||
| 884 | out: | ||
| 885 | return sprintf(buf, "%s\n", state); | ||
| 886 | } | ||
| 887 | |||
| 888 | #define DESCRIPTOR_ATTR(field, format_string) \ | ||
| 889 | static ssize_t \ | ||
| 890 | field ## _show(struct device *dev, struct device_attribute *attr, \ | ||
| 891 | char *buf) \ | ||
| 892 | { \ | ||
| 893 | return sprintf(buf, format_string, device_desc.field); \ | ||
| 894 | } \ | ||
| 895 | static ssize_t \ | ||
| 896 | field ## _store(struct device *dev, struct device_attribute *attr, \ | ||
| 897 | const char *buf, size_t size) \ | ||
| 898 | { \ | ||
| 899 | int value; \ | ||
| 900 | if (sscanf(buf, format_string, &value) == 1) { \ | ||
| 901 | device_desc.field = value; \ | ||
| 902 | return size; \ | ||
| 903 | } \ | ||
| 904 | return -1; \ | ||
| 905 | } \ | ||
| 906 | static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store); | ||
| 907 | |||
| 908 | #define DESCRIPTOR_STRING_ATTR(field, buffer) \ | ||
| 909 | static ssize_t \ | ||
| 910 | field ## _show(struct device *dev, struct device_attribute *attr, \ | ||
| 911 | char *buf) \ | ||
| 912 | { \ | ||
| 913 | return sprintf(buf, "%s", buffer); \ | ||
| 914 | } \ | ||
| 915 | static ssize_t \ | ||
| 916 | field ## _store(struct device *dev, struct device_attribute *attr, \ | ||
| 917 | const char *buf, size_t size) \ | ||
| 918 | { \ | ||
| 919 | if (size >= sizeof(buffer)) return -EINVAL; \ | ||
| 920 | if (sscanf(buf, "%s", buffer) == 1) { \ | ||
| 921 | return size; \ | ||
| 922 | } \ | ||
| 923 | return -1; \ | ||
| 924 | } \ | ||
| 925 | static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store); | ||
| 926 | |||
| 927 | |||
| 928 | DESCRIPTOR_ATTR(idVendor, "%04x\n") | ||
| 929 | DESCRIPTOR_ATTR(idProduct, "%04x\n") | ||
| 930 | DESCRIPTOR_ATTR(bcdDevice, "%04x\n") | ||
| 931 | DESCRIPTOR_ATTR(bDeviceClass, "%d\n") | ||
| 932 | DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n") | ||
| 933 | DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n") | ||
| 934 | DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string) | ||
| 935 | DESCRIPTOR_STRING_ATTR(iProduct, product_string) | ||
| 936 | DESCRIPTOR_STRING_ATTR(iSerial, serial_string) | ||
| 937 | |||
| 938 | static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show, functions_store); | ||
| 939 | static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); | ||
| 940 | static DEVICE_ATTR(state, S_IRUGO, state_show, NULL); | ||
| 941 | |||
| 942 | static struct device_attribute *android_usb_attributes[] = { | ||
| 943 | &dev_attr_idVendor, | ||
| 944 | &dev_attr_idProduct, | ||
| 945 | &dev_attr_bcdDevice, | ||
| 946 | &dev_attr_bDeviceClass, | ||
| 947 | &dev_attr_bDeviceSubClass, | ||
| 948 | &dev_attr_bDeviceProtocol, | ||
| 949 | &dev_attr_iManufacturer, | ||
| 950 | &dev_attr_iProduct, | ||
| 951 | &dev_attr_iSerial, | ||
| 952 | &dev_attr_functions, | ||
| 953 | &dev_attr_enable, | ||
| 954 | &dev_attr_state, | ||
| 955 | NULL | ||
| 956 | }; | ||
| 957 | |||
| 958 | /*-------------------------------------------------------------------------*/ | ||
| 959 | /* Composite driver */ | ||
| 960 | |||
| 961 | static int android_bind_config(struct usb_configuration *c) | ||
| 962 | { | ||
| 963 | struct android_dev *dev = _android_dev; | ||
| 964 | int ret = 0; | ||
| 965 | |||
| 966 | ret = android_bind_enabled_functions(dev, c); | ||
| 967 | if (ret) | ||
| 968 | return ret; | ||
| 969 | |||
| 970 | return 0; | ||
| 971 | } | ||
| 972 | |||
| 973 | static void android_unbind_config(struct usb_configuration *c) | ||
| 974 | { | ||
| 975 | struct android_dev *dev = _android_dev; | ||
| 976 | |||
| 977 | android_unbind_enabled_functions(dev, c); | ||
| 978 | } | ||
| 979 | |||
| 980 | static int android_bind(struct usb_composite_dev *cdev) | ||
| 981 | { | ||
| 982 | struct android_dev *dev = _android_dev; | ||
| 983 | struct usb_gadget *gadget = cdev->gadget; | ||
| 984 | int gcnum, id, ret; | ||
| 985 | |||
| 986 | usb_gadget_disconnect(gadget); | ||
| 987 | |||
| 988 | ret = android_init_functions(dev->functions, cdev); | ||
| 989 | if (ret) | ||
| 990 | return ret; | ||
| 991 | |||
| 992 | /* Allocate string descriptor numbers ... note that string | ||
| 993 | * contents can be overridden by the composite_dev glue. | ||
| 994 | */ | ||
| 995 | id = usb_string_id(cdev); | ||
| 996 | if (id < 0) | ||
| 997 | return id; | ||
| 998 | strings_dev[STRING_MANUFACTURER_IDX].id = id; | ||
| 999 | device_desc.iManufacturer = id; | ||
| 1000 | |||
| 1001 | id = usb_string_id(cdev); | ||
| 1002 | if (id < 0) | ||
| 1003 | return id; | ||
| 1004 | strings_dev[STRING_PRODUCT_IDX].id = id; | ||
| 1005 | device_desc.iProduct = id; | ||
| 1006 | |||
| 1007 | /* Default strings - should be updated by userspace */ | ||
| 1008 | strncpy(manufacturer_string, "Android", sizeof(manufacturer_string) - 1); | ||
| 1009 | strncpy(product_string, "Android", sizeof(product_string) - 1); | ||
| 1010 | strncpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1); | ||
| 1011 | |||
| 1012 | id = usb_string_id(cdev); | ||
| 1013 | if (id < 0) | ||
| 1014 | return id; | ||
| 1015 | strings_dev[STRING_SERIAL_IDX].id = id; | ||
| 1016 | device_desc.iSerialNumber = id; | ||
| 1017 | |||
| 1018 | gcnum = usb_gadget_controller_number(gadget); | ||
| 1019 | if (gcnum >= 0) | ||
| 1020 | device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); | ||
| 1021 | else { | ||
| 1022 | /* gadget zero is so simple (for now, no altsettings) that | ||
| 1023 | * it SHOULD NOT have problems with bulk-capable hardware. | ||
| 1024 | * so just warn about unrcognized controllers -- don't panic. | ||
| 1025 | * | ||
| 1026 | * things like configuration and altsetting numbering | ||
| 1027 | * can need hardware-specific attention though. | ||
| 1028 | */ | ||
| 1029 | pr_warning("%s: controller '%s' not recognized\n", | ||
| 1030 | longname, gadget->name); | ||
| 1031 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | dev->cdev = cdev; | ||
| 1035 | |||
| 1036 | return 0; | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | static int android_usb_unbind(struct usb_composite_dev *cdev) | ||
| 1040 | { | ||
| 1041 | struct android_dev *dev = _android_dev; | ||
| 1042 | |||
| 1043 | cancel_work_sync(&dev->work); | ||
| 1044 | android_cleanup_functions(dev->functions); | ||
| 1045 | return 0; | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | static struct usb_composite_driver android_usb_driver = { | ||
| 1049 | .name = "android_usb", | ||
| 1050 | .dev = &device_desc, | ||
| 1051 | .strings = dev_strings, | ||
| 1052 | .unbind = android_usb_unbind, | ||
| 1053 | .max_speed = USB_SPEED_HIGH, | ||
| 1054 | }; | ||
| 1055 | |||
| 1056 | static int | ||
| 1057 | android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c) | ||
| 1058 | { | ||
| 1059 | struct android_dev *dev = _android_dev; | ||
| 1060 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | ||
| 1061 | struct usb_request *req = cdev->req; | ||
| 1062 | struct android_usb_function *f; | ||
| 1063 | int value = -EOPNOTSUPP; | ||
| 1064 | unsigned long flags; | ||
| 1065 | |||
| 1066 | req->zero = 0; | ||
| 1067 | req->complete = composite_setup_complete; | ||
| 1068 | req->length = 0; | ||
| 1069 | gadget->ep0->driver_data = cdev; | ||
| 1070 | |||
| 1071 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) { | ||
| 1072 | if (f->ctrlrequest) { | ||
| 1073 | value = f->ctrlrequest(f, cdev, c); | ||
| 1074 | if (value >= 0) | ||
| 1075 | break; | ||
| 1076 | } | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | /* Special case the accessory function. | ||
| 1080 | * It needs to handle control requests before it is enabled. | ||
| 1081 | */ | ||
| 1082 | if (value < 0) | ||
| 1083 | value = acc_ctrlrequest(cdev, c); | ||
| 1084 | |||
| 1085 | if (value < 0) | ||
| 1086 | value = composite_setup(gadget, c); | ||
| 1087 | |||
| 1088 | spin_lock_irqsave(&cdev->lock, flags); | ||
| 1089 | if (!dev->connected) { | ||
| 1090 | dev->connected = 1; | ||
| 1091 | schedule_work(&dev->work); | ||
| 1092 | } | ||
| 1093 | else if (c->bRequest == USB_REQ_SET_CONFIGURATION && cdev->config) { | ||
| 1094 | schedule_work(&dev->work); | ||
| 1095 | } | ||
| 1096 | spin_unlock_irqrestore(&cdev->lock, flags); | ||
| 1097 | |||
| 1098 | return value; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | static void android_disconnect(struct usb_gadget *gadget) | ||
| 1102 | { | ||
| 1103 | struct android_dev *dev = _android_dev; | ||
| 1104 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | ||
| 1105 | unsigned long flags; | ||
| 1106 | |||
| 1107 | composite_disconnect(gadget); | ||
| 1108 | |||
| 1109 | spin_lock_irqsave(&cdev->lock, flags); | ||
| 1110 | dev->connected = 0; | ||
| 1111 | schedule_work(&dev->work); | ||
| 1112 | spin_unlock_irqrestore(&cdev->lock, flags); | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | static int android_create_device(struct android_dev *dev) | ||
| 1116 | { | ||
| 1117 | struct device_attribute **attrs = android_usb_attributes; | ||
| 1118 | struct device_attribute *attr; | ||
| 1119 | int err; | ||
| 1120 | |||
| 1121 | dev->dev = device_create(android_class, NULL, | ||
| 1122 | MKDEV(0, 0), NULL, "android0"); | ||
| 1123 | if (IS_ERR(dev->dev)) | ||
| 1124 | return PTR_ERR(dev->dev); | ||
| 1125 | |||
| 1126 | dev_set_drvdata(dev->dev, dev); | ||
| 1127 | |||
| 1128 | while ((attr = *attrs++)) { | ||
| 1129 | err = device_create_file(dev->dev, attr); | ||
| 1130 | if (err) { | ||
| 1131 | device_destroy(android_class, dev->dev->devt); | ||
| 1132 | return err; | ||
| 1133 | } | ||
| 1134 | } | ||
| 1135 | return 0; | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | |||
| 1139 | static int __init init(void) | ||
| 1140 | { | ||
| 1141 | struct android_dev *dev; | ||
| 1142 | int err; | ||
| 1143 | |||
| 1144 | android_class = class_create(THIS_MODULE, "android_usb"); | ||
| 1145 | if (IS_ERR(android_class)) | ||
| 1146 | return PTR_ERR(android_class); | ||
| 1147 | |||
| 1148 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 1149 | if (!dev) | ||
| 1150 | return -ENOMEM; | ||
| 1151 | |||
| 1152 | dev->functions = supported_functions; | ||
| 1153 | INIT_LIST_HEAD(&dev->enabled_functions); | ||
| 1154 | INIT_WORK(&dev->work, android_work); | ||
| 1155 | mutex_init(&dev->mutex); | ||
| 1156 | |||
| 1157 | err = android_create_device(dev); | ||
| 1158 | if (err) { | ||
| 1159 | class_destroy(android_class); | ||
| 1160 | kfree(dev); | ||
| 1161 | return err; | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | _android_dev = dev; | ||
| 1165 | |||
| 1166 | /* Override composite driver functions */ | ||
| 1167 | composite_driver.setup = android_setup; | ||
| 1168 | composite_driver.disconnect = android_disconnect; | ||
| 1169 | |||
| 1170 | return usb_composite_probe(&android_usb_driver, android_bind); | ||
| 1171 | } | ||
| 1172 | module_init(init); | ||
| 1173 | |||
| 1174 | static void __exit cleanup(void) | ||
| 1175 | { | ||
| 1176 | usb_composite_unregister(&android_usb_driver); | ||
| 1177 | class_destroy(android_class); | ||
| 1178 | kfree(_android_dev); | ||
| 1179 | _android_dev = NULL; | ||
| 1180 | } | ||
| 1181 | module_exit(cleanup); | ||
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c new file mode 100644 index 00000000000..470981ad6f7 --- /dev/null +++ b/drivers/usb/gadget/ci13xxx_msm.c | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | /* Copyright (c) 2010, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License version 2 and | ||
| 5 | * only version 2 as published by the Free Software Foundation. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 15 | * 02110-1301, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/pm_runtime.h> | ||
| 22 | #include <linux/usb/msm_hsusb_hw.h> | ||
| 23 | #include <linux/usb/ulpi.h> | ||
| 24 | |||
| 25 | #include "ci13xxx_udc.c" | ||
| 26 | |||
| 27 | #define MSM_USB_BASE (udc->regs) | ||
| 28 | |||
| 29 | static irqreturn_t msm_udc_irq(int irq, void *data) | ||
| 30 | { | ||
| 31 | return udc_irq(); | ||
| 32 | } | ||
| 33 | |||
| 34 | static void ci13xxx_msm_notify_event(struct ci13xxx *udc, unsigned event) | ||
| 35 | { | ||
| 36 | struct device *dev = udc->gadget.dev.parent; | ||
| 37 | int val; | ||
| 38 | |||
| 39 | switch (event) { | ||
| 40 | case CI13XXX_CONTROLLER_RESET_EVENT: | ||
| 41 | dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n"); | ||
| 42 | writel(0, USB_AHBBURST); | ||
| 43 | writel(0, USB_AHBMODE); | ||
| 44 | break; | ||
| 45 | case CI13XXX_CONTROLLER_STOPPED_EVENT: | ||
| 46 | dev_dbg(dev, "CI13XXX_CONTROLLER_STOPPED_EVENT received\n"); | ||
| 47 | /* | ||
| 48 | * Put the transceiver in non-driving mode. Otherwise host | ||
| 49 | * may not detect soft-disconnection. | ||
| 50 | */ | ||
| 51 | val = otg_io_read(udc->transceiver, ULPI_FUNC_CTRL); | ||
| 52 | val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; | ||
| 53 | val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; | ||
| 54 | otg_io_write(udc->transceiver, val, ULPI_FUNC_CTRL); | ||
| 55 | break; | ||
| 56 | default: | ||
| 57 | dev_dbg(dev, "unknown ci13xxx_udc event\n"); | ||
| 58 | break; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | static struct ci13xxx_udc_driver ci13xxx_msm_udc_driver = { | ||
| 63 | .name = "ci13xxx_msm", | ||
| 64 | .flags = CI13XXX_REGS_SHARED | | ||
| 65 | CI13XXX_REQUIRE_TRANSCEIVER | | ||
| 66 | CI13XXX_PULLUP_ON_VBUS | | ||
| 67 | CI13XXX_DISABLE_STREAMING, | ||
| 68 | |||
| 69 | .notify_event = ci13xxx_msm_notify_event, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static int ci13xxx_msm_probe(struct platform_device *pdev) | ||
| 73 | { | ||
| 74 | struct resource *res; | ||
| 75 | void __iomem *regs; | ||
| 76 | int irq; | ||
| 77 | int ret; | ||
| 78 | |||
| 79 | dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n"); | ||
| 80 | |||
| 81 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 82 | if (!res) { | ||
| 83 | dev_err(&pdev->dev, "failed to get platform resource mem\n"); | ||
| 84 | return -ENXIO; | ||
| 85 | } | ||
| 86 | |||
| 87 | regs = ioremap(res->start, resource_size(res)); | ||
| 88 | if (!regs) { | ||
| 89 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
| 90 | return -ENOMEM; | ||
| 91 | } | ||
| 92 | |||
| 93 | ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, regs); | ||
| 94 | if (ret < 0) { | ||
| 95 | dev_err(&pdev->dev, "udc_probe failed\n"); | ||
| 96 | goto iounmap; | ||
| 97 | } | ||
| 98 | |||
| 99 | irq = platform_get_irq(pdev, 0); | ||
| 100 | if (irq < 0) { | ||
| 101 | dev_err(&pdev->dev, "IRQ not found\n"); | ||
| 102 | ret = -ENXIO; | ||
| 103 | goto udc_remove; | ||
| 104 | } | ||
| 105 | |||
| 106 | ret = request_irq(irq, msm_udc_irq, IRQF_SHARED, pdev->name, pdev); | ||
| 107 | if (ret < 0) { | ||
| 108 | dev_err(&pdev->dev, "request_irq failed\n"); | ||
| 109 | goto udc_remove; | ||
| 110 | } | ||
| 111 | |||
| 112 | pm_runtime_no_callbacks(&pdev->dev); | ||
| 113 | pm_runtime_enable(&pdev->dev); | ||
| 114 | |||
| 115 | return 0; | ||
| 116 | |||
| 117 | udc_remove: | ||
| 118 | udc_remove(); | ||
| 119 | iounmap: | ||
| 120 | iounmap(regs); | ||
| 121 | |||
| 122 | return ret; | ||
| 123 | } | ||
| 124 | |||
| 125 | static struct platform_driver ci13xxx_msm_driver = { | ||
| 126 | .probe = ci13xxx_msm_probe, | ||
| 127 | .driver = { .name = "msm_hsusb", }, | ||
| 128 | }; | ||
| 129 | MODULE_ALIAS("platform:msm_hsusb"); | ||
| 130 | |||
| 131 | static int __init ci13xxx_msm_init(void) | ||
| 132 | { | ||
| 133 | return platform_driver_register(&ci13xxx_msm_driver); | ||
| 134 | } | ||
| 135 | module_init(ci13xxx_msm_init); | ||
diff --git a/drivers/usb/gadget/ci13xxx_pci.c b/drivers/usb/gadget/ci13xxx_pci.c new file mode 100644 index 00000000000..883ab5e832d --- /dev/null +++ b/drivers/usb/gadget/ci13xxx_pci.c | |||
| @@ -0,0 +1,176 @@ | |||
| 1 | /* | ||
| 2 | * ci13xxx_pci.c - MIPS USB IP core family device controller | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved. | ||
| 5 | * | ||
| 6 | * Author: David Lopo | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/pci.h> | ||
| 15 | |||
| 16 | #include "ci13xxx_udc.c" | ||
| 17 | |||
| 18 | /* driver name */ | ||
| 19 | #define UDC_DRIVER_NAME "ci13xxx_pci" | ||
| 20 | |||
| 21 | /****************************************************************************** | ||
| 22 | * PCI block | ||
| 23 | *****************************************************************************/ | ||
| 24 | /** | ||
| 25 | * ci13xxx_pci_irq: interrut handler | ||
| 26 | * @irq: irq number | ||
| 27 | * @pdev: USB Device Controller interrupt source | ||
| 28 | * | ||
| 29 | * This function returns IRQ_HANDLED if the IRQ has been handled | ||
| 30 | * This is an ISR don't trace, use attribute interface instead | ||
| 31 | */ | ||
| 32 | static irqreturn_t ci13xxx_pci_irq(int irq, void *pdev) | ||
| 33 | { | ||
| 34 | if (irq == 0) { | ||
| 35 | dev_err(&((struct pci_dev *)pdev)->dev, "Invalid IRQ0 usage!"); | ||
| 36 | return IRQ_HANDLED; | ||
| 37 | } | ||
| 38 | return udc_irq(); | ||
| 39 | } | ||
| 40 | |||
| 41 | static struct ci13xxx_udc_driver ci13xxx_pci_udc_driver = { | ||
| 42 | .name = UDC_DRIVER_NAME, | ||
| 43 | }; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * ci13xxx_pci_probe: PCI probe | ||
| 47 | * @pdev: USB device controller being probed | ||
| 48 | * @id: PCI hotplug ID connecting controller to UDC framework | ||
| 49 | * | ||
| 50 | * This function returns an error code | ||
| 51 | * Allocates basic PCI resources for this USB device controller, and then | ||
| 52 | * invokes the udc_probe() method to start the UDC associated with it | ||
| 53 | */ | ||
| 54 | static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev, | ||
| 55 | const struct pci_device_id *id) | ||
| 56 | { | ||
| 57 | void __iomem *regs = NULL; | ||
| 58 | int retval = 0; | ||
| 59 | |||
| 60 | if (id == NULL) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | retval = pci_enable_device(pdev); | ||
| 64 | if (retval) | ||
| 65 | goto done; | ||
| 66 | |||
| 67 | if (!pdev->irq) { | ||
| 68 | dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!"); | ||
| 69 | retval = -ENODEV; | ||
| 70 | goto disable_device; | ||
| 71 | } | ||
| 72 | |||
| 73 | retval = pci_request_regions(pdev, UDC_DRIVER_NAME); | ||
| 74 | if (retval) | ||
| 75 | goto disable_device; | ||
| 76 | |||
| 77 | /* BAR 0 holds all the registers */ | ||
| 78 | regs = pci_iomap(pdev, 0, 0); | ||
| 79 | if (!regs) { | ||
| 80 | dev_err(&pdev->dev, "Error mapping memory!"); | ||
| 81 | retval = -EFAULT; | ||
| 82 | goto release_regions; | ||
| 83 | } | ||
| 84 | pci_set_drvdata(pdev, (__force void *)regs); | ||
| 85 | |||
| 86 | pci_set_master(pdev); | ||
| 87 | pci_try_set_mwi(pdev); | ||
| 88 | |||
| 89 | retval = udc_probe(&ci13xxx_pci_udc_driver, &pdev->dev, regs); | ||
| 90 | if (retval) | ||
| 91 | goto iounmap; | ||
| 92 | |||
| 93 | /* our device does not have MSI capability */ | ||
| 94 | |||
| 95 | retval = request_irq(pdev->irq, ci13xxx_pci_irq, IRQF_SHARED, | ||
| 96 | UDC_DRIVER_NAME, pdev); | ||
| 97 | if (retval) | ||
| 98 | goto gadget_remove; | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | |||
| 102 | gadget_remove: | ||
| 103 | udc_remove(); | ||
| 104 | iounmap: | ||
| 105 | pci_iounmap(pdev, regs); | ||
| 106 | release_regions: | ||
| 107 | pci_release_regions(pdev); | ||
| 108 | disable_device: | ||
| 109 | pci_disable_device(pdev); | ||
| 110 | done: | ||
| 111 | return retval; | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * ci13xxx_pci_remove: PCI remove | ||
| 116 | * @pdev: USB Device Controller being removed | ||
| 117 | * | ||
| 118 | * Reverses the effect of ci13xxx_pci_probe(), | ||
| 119 | * first invoking the udc_remove() and then releases | ||
| 120 | * all PCI resources allocated for this USB device controller | ||
| 121 | */ | ||
| 122 | static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev) | ||
| 123 | { | ||
| 124 | free_irq(pdev->irq, pdev); | ||
| 125 | udc_remove(); | ||
| 126 | pci_iounmap(pdev, (__force void __iomem *)pci_get_drvdata(pdev)); | ||
| 127 | pci_release_regions(pdev); | ||
| 128 | pci_disable_device(pdev); | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * PCI device table | ||
| 133 | * PCI device structure | ||
| 134 | * | ||
| 135 | * Check "pci.h" for details | ||
| 136 | */ | ||
| 137 | static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = { | ||
| 138 | { PCI_DEVICE(0x153F, 0x1004) }, | ||
| 139 | { PCI_DEVICE(0x153F, 0x1006) }, | ||
| 140 | { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ } | ||
| 141 | }; | ||
| 142 | MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table); | ||
| 143 | |||
| 144 | static struct pci_driver ci13xxx_pci_driver = { | ||
| 145 | .name = UDC_DRIVER_NAME, | ||
| 146 | .id_table = ci13xxx_pci_id_table, | ||
| 147 | .probe = ci13xxx_pci_probe, | ||
| 148 | .remove = __devexit_p(ci13xxx_pci_remove), | ||
| 149 | }; | ||
| 150 | |||
| 151 | /** | ||
| 152 | * ci13xxx_pci_init: module init | ||
| 153 | * | ||
| 154 | * Driver load | ||
| 155 | */ | ||
| 156 | static int __init ci13xxx_pci_init(void) | ||
| 157 | { | ||
| 158 | return pci_register_driver(&ci13xxx_pci_driver); | ||
| 159 | } | ||
| 160 | module_init(ci13xxx_pci_init); | ||
| 161 | |||
| 162 | /** | ||
| 163 | * ci13xxx_pci_exit: module exit | ||
| 164 | * | ||
| 165 | * Driver unload | ||
| 166 | */ | ||
| 167 | static void __exit ci13xxx_pci_exit(void) | ||
| 168 | { | ||
| 169 | pci_unregister_driver(&ci13xxx_pci_driver); | ||
| 170 | } | ||
| 171 | module_exit(ci13xxx_pci_exit); | ||
| 172 | |||
| 173 | MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>"); | ||
| 174 | MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller"); | ||
| 175 | MODULE_LICENSE("GPL"); | ||
| 176 | MODULE_VERSION("June 2008"); | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c new file mode 100644 index 00000000000..1265a8502ea --- /dev/null +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
| @@ -0,0 +1,2977 @@ | |||
| 1 | /* | ||
| 2 | * ci13xxx_udc.c - MIPS USB IP core family device controller | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved. | ||
| 5 | * | ||
| 6 | * Author: David Lopo | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Description: MIPS USB IP core family device controller | ||
| 15 | * Currently it only supports IP part number CI13412 | ||
| 16 | * | ||
| 17 | * This driver is composed of several blocks: | ||
| 18 | * - HW: hardware interface | ||
| 19 | * - DBG: debug facilities (optional) | ||
| 20 | * - UTIL: utilities | ||
| 21 | * - ISR: interrupts handling | ||
| 22 | * - ENDPT: endpoint operations (Gadget API) | ||
| 23 | * - GADGET: gadget operations (Gadget API) | ||
| 24 | * - BUS: bus glue code, bus abstraction layer | ||
| 25 | * | ||
| 26 | * Compile Options | ||
| 27 | * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities | ||
| 28 | * - STALL_IN: non-empty bulk-in pipes cannot be halted | ||
| 29 | * if defined mass storage compliance succeeds but with warnings | ||
| 30 | * => case 4: Hi > Dn | ||
| 31 | * => case 5: Hi > Di | ||
| 32 | * => case 8: Hi <> Do | ||
| 33 | * if undefined usbtest 13 fails | ||
| 34 | * - TRACE: enable function tracing (depends on DEBUG) | ||
| 35 | * | ||
| 36 | * Main Features | ||
| 37 | * - Chapter 9 & Mass Storage Compliance with Gadget File Storage | ||
| 38 | * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined) | ||
| 39 | * - Normal & LPM support | ||
| 40 | * | ||
| 41 | * USBTEST Report | ||
| 42 | * - OK: 0-12, 13 (STALL_IN defined) & 14 | ||
| 43 | * - Not Supported: 15 & 16 (ISO) | ||
| 44 | * | ||
| 45 | * TODO List | ||
| 46 | * - OTG | ||
| 47 | * - Isochronous & Interrupt Traffic | ||
| 48 | * - Handle requests which spawns into several TDs | ||
| 49 | * - GET_STATUS(device) - always reports 0 | ||
| 50 | * - Gadget API (majority of optional features) | ||
| 51 | * - Suspend & Remote Wakeup | ||
| 52 | */ | ||
| 53 | #include <linux/delay.h> | ||
| 54 | #include <linux/device.h> | ||
| 55 | #include <linux/dmapool.h> | ||
| 56 | #include <linux/dma-mapping.h> | ||
| 57 | #include <linux/init.h> | ||
| 58 | #include <linux/interrupt.h> | ||
| 59 | #include <linux/io.h> | ||
| 60 | #include <linux/irq.h> | ||
| 61 | #include <linux/kernel.h> | ||
| 62 | #include <linux/slab.h> | ||
| 63 | #include <linux/pm_runtime.h> | ||
| 64 | #include <linux/usb/ch9.h> | ||
| 65 | #include <linux/usb/gadget.h> | ||
| 66 | #include <linux/usb/otg.h> | ||
| 67 | |||
| 68 | #include "ci13xxx_udc.h" | ||
| 69 | |||
| 70 | |||
| 71 | /****************************************************************************** | ||
| 72 | * DEFINE | ||
| 73 | *****************************************************************************/ | ||
| 74 | /* ctrl register bank access */ | ||
| 75 | static DEFINE_SPINLOCK(udc_lock); | ||
| 76 | |||
| 77 | /* control endpoint description */ | ||
| 78 | static const struct usb_endpoint_descriptor | ||
| 79 | ctrl_endpt_out_desc = { | ||
| 80 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 81 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 82 | |||
| 83 | .bEndpointAddress = USB_DIR_OUT, | ||
| 84 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
| 85 | .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX), | ||
| 86 | }; | ||
| 87 | |||
| 88 | static const struct usb_endpoint_descriptor | ||
| 89 | ctrl_endpt_in_desc = { | ||
| 90 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 91 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 92 | |||
| 93 | .bEndpointAddress = USB_DIR_IN, | ||
| 94 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
| 95 | .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX), | ||
| 96 | }; | ||
| 97 | |||
| 98 | /* UDC descriptor */ | ||
| 99 | static struct ci13xxx *_udc; | ||
| 100 | |||
| 101 | /* Interrupt statistics */ | ||
| 102 | #define ISR_MASK 0x1F | ||
| 103 | static struct { | ||
| 104 | u32 test; | ||
| 105 | u32 ui; | ||
| 106 | u32 uei; | ||
| 107 | u32 pci; | ||
| 108 | u32 uri; | ||
| 109 | u32 sli; | ||
| 110 | u32 none; | ||
| 111 | struct { | ||
| 112 | u32 cnt; | ||
| 113 | u32 buf[ISR_MASK+1]; | ||
| 114 | u32 idx; | ||
| 115 | } hndl; | ||
| 116 | } isr_statistics; | ||
| 117 | |||
| 118 | /** | ||
| 119 | * ffs_nr: find first (least significant) bit set | ||
| 120 | * @x: the word to search | ||
| 121 | * | ||
| 122 | * This function returns bit number (instead of position) | ||
| 123 | */ | ||
| 124 | static int ffs_nr(u32 x) | ||
| 125 | { | ||
| 126 | int n = ffs(x); | ||
| 127 | |||
| 128 | return n ? n-1 : 32; | ||
| 129 | } | ||
| 130 | |||
| 131 | /****************************************************************************** | ||
| 132 | * HW block | ||
| 133 | *****************************************************************************/ | ||
| 134 | /* register bank descriptor */ | ||
| 135 | static struct { | ||
| 136 | unsigned lpm; /* is LPM? */ | ||
| 137 | void __iomem *abs; /* bus map offset */ | ||
| 138 | void __iomem *cap; /* bus map offset + CAP offset + CAP data */ | ||
| 139 | size_t size; /* bank size */ | ||
| 140 | } hw_bank; | ||
| 141 | |||
| 142 | /* MSM specific */ | ||
| 143 | #define ABS_AHBBURST (0x0090UL) | ||
| 144 | #define ABS_AHBMODE (0x0098UL) | ||
| 145 | /* UDC register map */ | ||
| 146 | #define ABS_CAPLENGTH (0x100UL) | ||
| 147 | #define ABS_HCCPARAMS (0x108UL) | ||
| 148 | #define ABS_DCCPARAMS (0x124UL) | ||
| 149 | #define ABS_TESTMODE (hw_bank.lpm ? 0x0FCUL : 0x138UL) | ||
| 150 | /* offset to CAPLENTGH (addr + data) */ | ||
| 151 | #define CAP_USBCMD (0x000UL) | ||
| 152 | #define CAP_USBSTS (0x004UL) | ||
| 153 | #define CAP_USBINTR (0x008UL) | ||
| 154 | #define CAP_DEVICEADDR (0x014UL) | ||
| 155 | #define CAP_ENDPTLISTADDR (0x018UL) | ||
| 156 | #define CAP_PORTSC (0x044UL) | ||
| 157 | #define CAP_DEVLC (0x084UL) | ||
| 158 | #define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL) | ||
| 159 | #define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL) | ||
| 160 | #define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL) | ||
| 161 | #define CAP_ENDPTFLUSH (hw_bank.lpm ? 0x0E0UL : 0x074UL) | ||
| 162 | #define CAP_ENDPTSTAT (hw_bank.lpm ? 0x0E4UL : 0x078UL) | ||
| 163 | #define CAP_ENDPTCOMPLETE (hw_bank.lpm ? 0x0E8UL : 0x07CUL) | ||
| 164 | #define CAP_ENDPTCTRL (hw_bank.lpm ? 0x0ECUL : 0x080UL) | ||
| 165 | #define CAP_LAST (hw_bank.lpm ? 0x12CUL : 0x0C0UL) | ||
| 166 | |||
| 167 | /* maximum number of enpoints: valid only after hw_device_reset() */ | ||
| 168 | static unsigned hw_ep_max; | ||
| 169 | |||
| 170 | /** | ||
| 171 | * hw_ep_bit: calculates the bit number | ||
| 172 | * @num: endpoint number | ||
| 173 | * @dir: endpoint direction | ||
| 174 | * | ||
| 175 | * This function returns bit number | ||
| 176 | */ | ||
| 177 | static inline int hw_ep_bit(int num, int dir) | ||
| 178 | { | ||
| 179 | return num + (dir ? 16 : 0); | ||
| 180 | } | ||
| 181 | |||
| 182 | /** | ||
| 183 | * hw_aread: reads from register bitfield | ||
| 184 | * @addr: address relative to bus map | ||
| 185 | * @mask: bitfield mask | ||
| 186 | * | ||
| 187 | * This function returns register bitfield data | ||
| 188 | */ | ||
| 189 | static u32 hw_aread(u32 addr, u32 mask) | ||
| 190 | { | ||
| 191 | return ioread32(addr + hw_bank.abs) & mask; | ||
| 192 | } | ||
| 193 | |||
| 194 | /** | ||
| 195 | * hw_awrite: writes to register bitfield | ||
| 196 | * @addr: address relative to bus map | ||
| 197 | * @mask: bitfield mask | ||
| 198 | * @data: new data | ||
| 199 | */ | ||
| 200 | static void hw_awrite(u32 addr, u32 mask, u32 data) | ||
| 201 | { | ||
| 202 | iowrite32(hw_aread(addr, ~mask) | (data & mask), | ||
| 203 | addr + hw_bank.abs); | ||
| 204 | } | ||
| 205 | |||
| 206 | /** | ||
| 207 | * hw_cread: reads from register bitfield | ||
| 208 | * @addr: address relative to CAP offset plus content | ||
| 209 | * @mask: bitfield mask | ||
| 210 | * | ||
| 211 | * This function returns register bitfield data | ||
| 212 | */ | ||
| 213 | static u32 hw_cread(u32 addr, u32 mask) | ||
| 214 | { | ||
| 215 | return ioread32(addr + hw_bank.cap) & mask; | ||
| 216 | } | ||
| 217 | |||
| 218 | /** | ||
| 219 | * hw_cwrite: writes to register bitfield | ||
| 220 | * @addr: address relative to CAP offset plus content | ||
| 221 | * @mask: bitfield mask | ||
| 222 | * @data: new data | ||
| 223 | */ | ||
| 224 | static void hw_cwrite(u32 addr, u32 mask, u32 data) | ||
| 225 | { | ||
| 226 | iowrite32(hw_cread(addr, ~mask) | (data & mask), | ||
| 227 | addr + hw_bank.cap); | ||
| 228 | } | ||
| 229 | |||
| 230 | /** | ||
| 231 | * hw_ctest_and_clear: tests & clears register bitfield | ||
| 232 | * @addr: address relative to CAP offset plus content | ||
| 233 | * @mask: bitfield mask | ||
| 234 | * | ||
| 235 | * This function returns register bitfield data | ||
| 236 | */ | ||
| 237 | static u32 hw_ctest_and_clear(u32 addr, u32 mask) | ||
| 238 | { | ||
| 239 | u32 reg = hw_cread(addr, mask); | ||
| 240 | |||
| 241 | iowrite32(reg, addr + hw_bank.cap); | ||
| 242 | return reg; | ||
| 243 | } | ||
| 244 | |||
| 245 | /** | ||
| 246 | * hw_ctest_and_write: tests & writes register bitfield | ||
| 247 | * @addr: address relative to CAP offset plus content | ||
| 248 | * @mask: bitfield mask | ||
| 249 | * @data: new data | ||
| 250 | * | ||
| 251 | * This function returns register bitfield data | ||
| 252 | */ | ||
| 253 | static u32 hw_ctest_and_write(u32 addr, u32 mask, u32 data) | ||
| 254 | { | ||
| 255 | u32 reg = hw_cread(addr, ~0); | ||
| 256 | |||
| 257 | iowrite32((reg & ~mask) | (data & mask), addr + hw_bank.cap); | ||
| 258 | return (reg & mask) >> ffs_nr(mask); | ||
| 259 | } | ||
| 260 | |||
| 261 | static int hw_device_init(void __iomem *base) | ||
| 262 | { | ||
| 263 | u32 reg; | ||
| 264 | |||
| 265 | /* bank is a module variable */ | ||
| 266 | hw_bank.abs = base; | ||
| 267 | |||
| 268 | hw_bank.cap = hw_bank.abs; | ||
| 269 | hw_bank.cap += ABS_CAPLENGTH; | ||
| 270 | hw_bank.cap += ioread8(hw_bank.cap); | ||
| 271 | |||
| 272 | reg = hw_aread(ABS_HCCPARAMS, HCCPARAMS_LEN) >> ffs_nr(HCCPARAMS_LEN); | ||
| 273 | hw_bank.lpm = reg; | ||
| 274 | hw_bank.size = hw_bank.cap - hw_bank.abs; | ||
| 275 | hw_bank.size += CAP_LAST; | ||
| 276 | hw_bank.size /= sizeof(u32); | ||
| 277 | |||
| 278 | reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN); | ||
| 279 | hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */ | ||
| 280 | |||
| 281 | if (hw_ep_max == 0 || hw_ep_max > ENDPT_MAX) | ||
| 282 | return -ENODEV; | ||
| 283 | |||
| 284 | /* setup lock mode ? */ | ||
| 285 | |||
| 286 | /* ENDPTSETUPSTAT is '0' by default */ | ||
| 287 | |||
| 288 | /* HCSPARAMS.bf.ppc SHOULD BE zero for device */ | ||
| 289 | |||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | /** | ||
| 293 | * hw_device_reset: resets chip (execute without interruption) | ||
| 294 | * @base: register base address | ||
| 295 | * | ||
| 296 | * This function returns an error code | ||
| 297 | */ | ||
| 298 | static int hw_device_reset(struct ci13xxx *udc) | ||
| 299 | { | ||
| 300 | /* should flush & stop before reset */ | ||
| 301 | hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); | ||
| 302 | hw_cwrite(CAP_USBCMD, USBCMD_RS, 0); | ||
| 303 | |||
| 304 | hw_cwrite(CAP_USBCMD, USBCMD_RST, USBCMD_RST); | ||
| 305 | while (hw_cread(CAP_USBCMD, USBCMD_RST)) | ||
| 306 | udelay(10); /* not RTOS friendly */ | ||
| 307 | |||
| 308 | |||
| 309 | if (udc->udc_driver->notify_event) | ||
| 310 | udc->udc_driver->notify_event(udc, | ||
| 311 | CI13XXX_CONTROLLER_RESET_EVENT); | ||
| 312 | |||
| 313 | if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING) | ||
| 314 | hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS); | ||
| 315 | |||
| 316 | /* USBMODE should be configured step by step */ | ||
| 317 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); | ||
| 318 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE); | ||
| 319 | hw_cwrite(CAP_USBMODE, USBMODE_SLOM, USBMODE_SLOM); /* HW >= 2.3 */ | ||
| 320 | |||
| 321 | if (hw_cread(CAP_USBMODE, USBMODE_CM) != USBMODE_CM_DEVICE) { | ||
| 322 | pr_err("cannot enter in device mode"); | ||
| 323 | pr_err("lpm = %i", hw_bank.lpm); | ||
| 324 | return -ENODEV; | ||
| 325 | } | ||
| 326 | |||
| 327 | return 0; | ||
| 328 | } | ||
| 329 | |||
| 330 | /** | ||
| 331 | * hw_device_state: enables/disables interrupts & starts/stops device (execute | ||
| 332 | * without interruption) | ||
| 333 | * @dma: 0 => disable, !0 => enable and set dma engine | ||
| 334 | * | ||
| 335 | * This function returns an error code | ||
| 336 | */ | ||
| 337 | static int hw_device_state(u32 dma) | ||
| 338 | { | ||
| 339 | if (dma) { | ||
| 340 | hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma); | ||
| 341 | /* interrupt, error, port change, reset, sleep/suspend */ | ||
| 342 | hw_cwrite(CAP_USBINTR, ~0, | ||
| 343 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); | ||
| 344 | hw_cwrite(CAP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
| 345 | } else { | ||
| 346 | hw_cwrite(CAP_USBCMD, USBCMD_RS, 0); | ||
| 347 | hw_cwrite(CAP_USBINTR, ~0, 0); | ||
| 348 | } | ||
| 349 | return 0; | ||
| 350 | } | ||
| 351 | |||
| 352 | /** | ||
| 353 | * hw_ep_flush: flush endpoint fifo (execute without interruption) | ||
| 354 | * @num: endpoint number | ||
| 355 | * @dir: endpoint direction | ||
| 356 | * | ||
| 357 | * This function returns an error code | ||
| 358 | */ | ||
| 359 | static int hw_ep_flush(int num, int dir) | ||
| 360 | { | ||
| 361 | int n = hw_ep_bit(num, dir); | ||
| 362 | |||
| 363 | do { | ||
| 364 | /* flush any pending transfer */ | ||
| 365 | hw_cwrite(CAP_ENDPTFLUSH, BIT(n), BIT(n)); | ||
| 366 | while (hw_cread(CAP_ENDPTFLUSH, BIT(n))) | ||
| 367 | cpu_relax(); | ||
| 368 | } while (hw_cread(CAP_ENDPTSTAT, BIT(n))); | ||
| 369 | |||
| 370 | return 0; | ||
| 371 | } | ||
| 372 | |||
| 373 | /** | ||
| 374 | * hw_ep_disable: disables endpoint (execute without interruption) | ||
| 375 | * @num: endpoint number | ||
| 376 | * @dir: endpoint direction | ||
| 377 | * | ||
| 378 | * This function returns an error code | ||
| 379 | */ | ||
| 380 | static int hw_ep_disable(int num, int dir) | ||
| 381 | { | ||
| 382 | hw_ep_flush(num, dir); | ||
| 383 | hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32), | ||
| 384 | dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0); | ||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | |||
| 388 | /** | ||
| 389 | * hw_ep_enable: enables endpoint (execute without interruption) | ||
| 390 | * @num: endpoint number | ||
| 391 | * @dir: endpoint direction | ||
| 392 | * @type: endpoint type | ||
| 393 | * | ||
| 394 | * This function returns an error code | ||
| 395 | */ | ||
| 396 | static int hw_ep_enable(int num, int dir, int type) | ||
| 397 | { | ||
| 398 | u32 mask, data; | ||
| 399 | |||
| 400 | if (dir) { | ||
| 401 | mask = ENDPTCTRL_TXT; /* type */ | ||
| 402 | data = type << ffs_nr(mask); | ||
| 403 | |||
| 404 | mask |= ENDPTCTRL_TXS; /* unstall */ | ||
| 405 | mask |= ENDPTCTRL_TXR; /* reset data toggle */ | ||
| 406 | data |= ENDPTCTRL_TXR; | ||
| 407 | mask |= ENDPTCTRL_TXE; /* enable */ | ||
| 408 | data |= ENDPTCTRL_TXE; | ||
| 409 | } else { | ||
| 410 | mask = ENDPTCTRL_RXT; /* type */ | ||
| 411 | data = type << ffs_nr(mask); | ||
| 412 | |||
| 413 | mask |= ENDPTCTRL_RXS; /* unstall */ | ||
| 414 | mask |= ENDPTCTRL_RXR; /* reset data toggle */ | ||
| 415 | data |= ENDPTCTRL_RXR; | ||
| 416 | mask |= ENDPTCTRL_RXE; /* enable */ | ||
| 417 | data |= ENDPTCTRL_RXE; | ||
| 418 | } | ||
| 419 | hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32), mask, data); | ||
| 420 | return 0; | ||
| 421 | } | ||
| 422 | |||
| 423 | /** | ||
| 424 | * hw_ep_get_halt: return endpoint halt status | ||
| 425 | * @num: endpoint number | ||
| 426 | * @dir: endpoint direction | ||
| 427 | * | ||
| 428 | * This function returns 1 if endpoint halted | ||
| 429 | */ | ||
| 430 | static int hw_ep_get_halt(int num, int dir) | ||
| 431 | { | ||
| 432 | u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; | ||
| 433 | |||
| 434 | return hw_cread(CAP_ENDPTCTRL + num * sizeof(u32), mask) ? 1 : 0; | ||
| 435 | } | ||
| 436 | |||
| 437 | /** | ||
| 438 | * hw_test_and_clear_setup_status: test & clear setup status (execute without | ||
| 439 | * interruption) | ||
| 440 | * @n: bit number (endpoint) | ||
| 441 | * | ||
| 442 | * This function returns setup status | ||
| 443 | */ | ||
| 444 | static int hw_test_and_clear_setup_status(int n) | ||
| 445 | { | ||
| 446 | return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n)); | ||
| 447 | } | ||
| 448 | |||
| 449 | /** | ||
| 450 | * hw_ep_prime: primes endpoint (execute without interruption) | ||
| 451 | * @num: endpoint number | ||
| 452 | * @dir: endpoint direction | ||
| 453 | * @is_ctrl: true if control endpoint | ||
| 454 | * | ||
| 455 | * This function returns an error code | ||
| 456 | */ | ||
| 457 | static int hw_ep_prime(int num, int dir, int is_ctrl) | ||
| 458 | { | ||
| 459 | int n = hw_ep_bit(num, dir); | ||
| 460 | |||
| 461 | if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num))) | ||
| 462 | return -EAGAIN; | ||
| 463 | |||
| 464 | hw_cwrite(CAP_ENDPTPRIME, BIT(n), BIT(n)); | ||
| 465 | |||
| 466 | while (hw_cread(CAP_ENDPTPRIME, BIT(n))) | ||
| 467 | cpu_relax(); | ||
| 468 | if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num))) | ||
| 469 | return -EAGAIN; | ||
| 470 | |||
| 471 | /* status shoult be tested according with manual but it doesn't work */ | ||
| 472 | return 0; | ||
| 473 | } | ||
| 474 | |||
| 475 | /** | ||
| 476 | * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute | ||
| 477 | * without interruption) | ||
| 478 | * @num: endpoint number | ||
| 479 | * @dir: endpoint direction | ||
| 480 | * @value: true => stall, false => unstall | ||
| 481 | * | ||
| 482 | * This function returns an error code | ||
| 483 | */ | ||
| 484 | static int hw_ep_set_halt(int num, int dir, int value) | ||
| 485 | { | ||
| 486 | if (value != 0 && value != 1) | ||
| 487 | return -EINVAL; | ||
| 488 | |||
| 489 | do { | ||
| 490 | u32 addr = CAP_ENDPTCTRL + num * sizeof(u32); | ||
| 491 | u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; | ||
| 492 | u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR; | ||
| 493 | |||
| 494 | /* data toggle - reserved for EP0 but it's in ESS */ | ||
| 495 | hw_cwrite(addr, mask_xs|mask_xr, value ? mask_xs : mask_xr); | ||
| 496 | |||
| 497 | } while (value != hw_ep_get_halt(num, dir)); | ||
| 498 | |||
| 499 | return 0; | ||
| 500 | } | ||
| 501 | |||
| 502 | /** | ||
| 503 | * hw_intr_clear: disables interrupt & clears interrupt status (execute without | ||
| 504 | * interruption) | ||
| 505 | * @n: interrupt bit | ||
| 506 | * | ||
| 507 | * This function returns an error code | ||
| 508 | */ | ||
| 509 | static int hw_intr_clear(int n) | ||
| 510 | { | ||
| 511 | if (n >= REG_BITS) | ||
| 512 | return -EINVAL; | ||
| 513 | |||
| 514 | hw_cwrite(CAP_USBINTR, BIT(n), 0); | ||
| 515 | hw_cwrite(CAP_USBSTS, BIT(n), BIT(n)); | ||
| 516 | return 0; | ||
| 517 | } | ||
| 518 | |||
| 519 | /** | ||
| 520 | * hw_intr_force: enables interrupt & forces interrupt status (execute without | ||
| 521 | * interruption) | ||
| 522 | * @n: interrupt bit | ||
| 523 | * | ||
| 524 | * This function returns an error code | ||
| 525 | */ | ||
| 526 | static int hw_intr_force(int n) | ||
| 527 | { | ||
| 528 | if (n >= REG_BITS) | ||
| 529 | return -EINVAL; | ||
| 530 | |||
| 531 | hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE); | ||
| 532 | hw_cwrite(CAP_USBINTR, BIT(n), BIT(n)); | ||
| 533 | hw_cwrite(CAP_USBSTS, BIT(n), BIT(n)); | ||
| 534 | hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, 0); | ||
| 535 | return 0; | ||
| 536 | } | ||
| 537 | |||
| 538 | /** | ||
| 539 | * hw_is_port_high_speed: test if port is high speed | ||
| 540 | * | ||
| 541 | * This function returns true if high speed port | ||
| 542 | */ | ||
| 543 | static int hw_port_is_high_speed(void) | ||
| 544 | { | ||
| 545 | return hw_bank.lpm ? hw_cread(CAP_DEVLC, DEVLC_PSPD) : | ||
| 546 | hw_cread(CAP_PORTSC, PORTSC_HSP); | ||
| 547 | } | ||
| 548 | |||
| 549 | /** | ||
| 550 | * hw_port_test_get: reads port test mode value | ||
| 551 | * | ||
| 552 | * This function returns port test mode value | ||
| 553 | */ | ||
| 554 | static u8 hw_port_test_get(void) | ||
| 555 | { | ||
| 556 | return hw_cread(CAP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC); | ||
| 557 | } | ||
| 558 | |||
| 559 | /** | ||
| 560 | * hw_port_test_set: writes port test mode (execute without interruption) | ||
| 561 | * @mode: new value | ||
| 562 | * | ||
| 563 | * This function returns an error code | ||
| 564 | */ | ||
| 565 | static int hw_port_test_set(u8 mode) | ||
| 566 | { | ||
| 567 | const u8 TEST_MODE_MAX = 7; | ||
| 568 | |||
| 569 | if (mode > TEST_MODE_MAX) | ||
| 570 | return -EINVAL; | ||
| 571 | |||
| 572 | hw_cwrite(CAP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC)); | ||
| 573 | return 0; | ||
| 574 | } | ||
| 575 | |||
| 576 | /** | ||
| 577 | * hw_read_intr_enable: returns interrupt enable register | ||
| 578 | * | ||
| 579 | * This function returns register data | ||
| 580 | */ | ||
| 581 | static u32 hw_read_intr_enable(void) | ||
| 582 | { | ||
| 583 | return hw_cread(CAP_USBINTR, ~0); | ||
| 584 | } | ||
| 585 | |||
| 586 | /** | ||
| 587 | * hw_read_intr_status: returns interrupt status register | ||
| 588 | * | ||
| 589 | * This function returns register data | ||
| 590 | */ | ||
| 591 | static u32 hw_read_intr_status(void) | ||
| 592 | { | ||
| 593 | return hw_cread(CAP_USBSTS, ~0); | ||
| 594 | } | ||
| 595 | |||
| 596 | /** | ||
| 597 | * hw_register_read: reads all device registers (execute without interruption) | ||
| 598 | * @buf: destination buffer | ||
| 599 | * @size: buffer size | ||
| 600 | * | ||
| 601 | * This function returns number of registers read | ||
| 602 | */ | ||
| 603 | static size_t hw_register_read(u32 *buf, size_t size) | ||
| 604 | { | ||
| 605 | unsigned i; | ||
| 606 | |||
| 607 | if (size > hw_bank.size) | ||
| 608 | size = hw_bank.size; | ||
| 609 | |||
| 610 | for (i = 0; i < size; i++) | ||
| 611 | buf[i] = hw_aread(i * sizeof(u32), ~0); | ||
| 612 | |||
| 613 | return size; | ||
| 614 | } | ||
| 615 | |||
| 616 | /** | ||
| 617 | * hw_register_write: writes to register | ||
| 618 | * @addr: register address | ||
| 619 | * @data: register value | ||
| 620 | * | ||
| 621 | * This function returns an error code | ||
| 622 | */ | ||
| 623 | static int hw_register_write(u16 addr, u32 data) | ||
| 624 | { | ||
| 625 | /* align */ | ||
| 626 | addr /= sizeof(u32); | ||
| 627 | |||
| 628 | if (addr >= hw_bank.size) | ||
| 629 | return -EINVAL; | ||
| 630 | |||
| 631 | /* align */ | ||
| 632 | addr *= sizeof(u32); | ||
| 633 | |||
| 634 | hw_awrite(addr, ~0, data); | ||
| 635 | return 0; | ||
| 636 | } | ||
| 637 | |||
| 638 | /** | ||
| 639 | * hw_test_and_clear_complete: test & clear complete status (execute without | ||
| 640 | * interruption) | ||
| 641 | * @n: bit number (endpoint) | ||
| 642 | * | ||
| 643 | * This function returns complete status | ||
| 644 | */ | ||
| 645 | static int hw_test_and_clear_complete(int n) | ||
| 646 | { | ||
| 647 | return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n)); | ||
| 648 | } | ||
| 649 | |||
| 650 | /** | ||
| 651 | * hw_test_and_clear_intr_active: test & clear active interrupts (execute | ||
| 652 | * without interruption) | ||
| 653 | * | ||
| 654 | * This function returns active interrutps | ||
| 655 | */ | ||
| 656 | static u32 hw_test_and_clear_intr_active(void) | ||
| 657 | { | ||
| 658 | u32 reg = hw_read_intr_status() & hw_read_intr_enable(); | ||
| 659 | |||
| 660 | hw_cwrite(CAP_USBSTS, ~0, reg); | ||
| 661 | return reg; | ||
| 662 | } | ||
| 663 | |||
| 664 | /** | ||
| 665 | * hw_test_and_clear_setup_guard: test & clear setup guard (execute without | ||
| 666 | * interruption) | ||
| 667 | * | ||
| 668 | * This function returns guard value | ||
| 669 | */ | ||
| 670 | static int hw_test_and_clear_setup_guard(void) | ||
| 671 | { | ||
| 672 | return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, 0); | ||
| 673 | } | ||
| 674 | |||
| 675 | /** | ||
| 676 | * hw_test_and_set_setup_guard: test & set setup guard (execute without | ||
| 677 | * interruption) | ||
| 678 | * | ||
| 679 | * This function returns guard value | ||
| 680 | */ | ||
| 681 | static int hw_test_and_set_setup_guard(void) | ||
| 682 | { | ||
| 683 | return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, USBCMD_SUTW); | ||
| 684 | } | ||
| 685 | |||
| 686 | /** | ||
| 687 | * hw_usb_set_address: configures USB address (execute without interruption) | ||
| 688 | * @value: new USB address | ||
| 689 | * | ||
| 690 | * This function returns an error code | ||
| 691 | */ | ||
| 692 | static int hw_usb_set_address(u8 value) | ||
| 693 | { | ||
| 694 | /* advance */ | ||
| 695 | hw_cwrite(CAP_DEVICEADDR, DEVICEADDR_USBADR | DEVICEADDR_USBADRA, | ||
| 696 | value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA); | ||
| 697 | return 0; | ||
| 698 | } | ||
| 699 | |||
| 700 | /** | ||
| 701 | * hw_usb_reset: restart device after a bus reset (execute without | ||
| 702 | * interruption) | ||
| 703 | * | ||
| 704 | * This function returns an error code | ||
| 705 | */ | ||
| 706 | static int hw_usb_reset(void) | ||
| 707 | { | ||
| 708 | hw_usb_set_address(0); | ||
| 709 | |||
| 710 | /* ESS flushes only at end?!? */ | ||
| 711 | hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); /* flush all EPs */ | ||
| 712 | |||
| 713 | /* clear setup token semaphores */ | ||
| 714 | hw_cwrite(CAP_ENDPTSETUPSTAT, 0, 0); /* writes its content */ | ||
| 715 | |||
| 716 | /* clear complete status */ | ||
| 717 | hw_cwrite(CAP_ENDPTCOMPLETE, 0, 0); /* writes its content */ | ||
| 718 | |||
| 719 | /* wait until all bits cleared */ | ||
| 720 | while (hw_cread(CAP_ENDPTPRIME, ~0)) | ||
| 721 | udelay(10); /* not RTOS friendly */ | ||
| 722 | |||
| 723 | /* reset all endpoints ? */ | ||
| 724 | |||
| 725 | /* reset internal status and wait for further instructions | ||
| 726 | no need to verify the port reset status (ESS does it) */ | ||
| 727 | |||
| 728 | return 0; | ||
| 729 | } | ||
| 730 | |||
| 731 | /****************************************************************************** | ||
| 732 | * DBG block | ||
| 733 | *****************************************************************************/ | ||
| 734 | /** | ||
| 735 | * show_device: prints information about device capabilities and status | ||
| 736 | * | ||
| 737 | * Check "device.h" for details | ||
| 738 | */ | ||
| 739 | static ssize_t show_device(struct device *dev, struct device_attribute *attr, | ||
| 740 | char *buf) | ||
| 741 | { | ||
| 742 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 743 | struct usb_gadget *gadget = &udc->gadget; | ||
| 744 | int n = 0; | ||
| 745 | |||
| 746 | dbg_trace("[%s] %p\n", __func__, buf); | ||
| 747 | if (attr == NULL || buf == NULL) { | ||
| 748 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 749 | return 0; | ||
| 750 | } | ||
| 751 | |||
| 752 | n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n", | ||
| 753 | gadget->speed); | ||
| 754 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n", | ||
| 755 | gadget->is_dualspeed); | ||
| 756 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n", | ||
| 757 | gadget->is_otg); | ||
| 758 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n", | ||
| 759 | gadget->is_a_peripheral); | ||
| 760 | n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n", | ||
| 761 | gadget->b_hnp_enable); | ||
| 762 | n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n", | ||
| 763 | gadget->a_hnp_support); | ||
| 764 | n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n", | ||
| 765 | gadget->a_alt_hnp_support); | ||
| 766 | n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n", | ||
| 767 | (gadget->name ? gadget->name : "")); | ||
| 768 | |||
| 769 | return n; | ||
| 770 | } | ||
| 771 | static DEVICE_ATTR(device, S_IRUSR, show_device, NULL); | ||
| 772 | |||
| 773 | /** | ||
| 774 | * show_driver: prints information about attached gadget (if any) | ||
| 775 | * | ||
| 776 | * Check "device.h" for details | ||
| 777 | */ | ||
| 778 | static ssize_t show_driver(struct device *dev, struct device_attribute *attr, | ||
| 779 | char *buf) | ||
| 780 | { | ||
| 781 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 782 | struct usb_gadget_driver *driver = udc->driver; | ||
| 783 | int n = 0; | ||
| 784 | |||
| 785 | dbg_trace("[%s] %p\n", __func__, buf); | ||
| 786 | if (attr == NULL || buf == NULL) { | ||
| 787 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 788 | return 0; | ||
| 789 | } | ||
| 790 | |||
| 791 | if (driver == NULL) | ||
| 792 | return scnprintf(buf, PAGE_SIZE, | ||
| 793 | "There is no gadget attached!\n"); | ||
| 794 | |||
| 795 | n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n", | ||
| 796 | (driver->function ? driver->function : "")); | ||
| 797 | n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n", | ||
| 798 | driver->speed); | ||
| 799 | |||
| 800 | return n; | ||
| 801 | } | ||
| 802 | static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL); | ||
| 803 | |||
| 804 | /* Maximum event message length */ | ||
| 805 | #define DBG_DATA_MSG 64UL | ||
| 806 | |||
| 807 | /* Maximum event messages */ | ||
| 808 | #define DBG_DATA_MAX 128UL | ||
| 809 | |||
| 810 | /* Event buffer descriptor */ | ||
| 811 | static struct { | ||
| 812 | char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */ | ||
| 813 | unsigned idx; /* index */ | ||
| 814 | unsigned tty; /* print to console? */ | ||
| 815 | rwlock_t lck; /* lock */ | ||
| 816 | } dbg_data = { | ||
| 817 | .idx = 0, | ||
| 818 | .tty = 0, | ||
| 819 | .lck = __RW_LOCK_UNLOCKED(lck) | ||
| 820 | }; | ||
| 821 | |||
| 822 | /** | ||
| 823 | * dbg_dec: decrements debug event index | ||
| 824 | * @idx: buffer index | ||
| 825 | */ | ||
| 826 | static void dbg_dec(unsigned *idx) | ||
| 827 | { | ||
| 828 | *idx = (*idx - 1) & (DBG_DATA_MAX-1); | ||
| 829 | } | ||
| 830 | |||
| 831 | /** | ||
| 832 | * dbg_inc: increments debug event index | ||
| 833 | * @idx: buffer index | ||
| 834 | */ | ||
| 835 | static void dbg_inc(unsigned *idx) | ||
| 836 | { | ||
| 837 | *idx = (*idx + 1) & (DBG_DATA_MAX-1); | ||
| 838 | } | ||
| 839 | |||
| 840 | /** | ||
| 841 | * dbg_print: prints the common part of the event | ||
| 842 | * @addr: endpoint address | ||
| 843 | * @name: event name | ||
| 844 | * @status: status | ||
| 845 | * @extra: extra information | ||
| 846 | */ | ||
| 847 | static void dbg_print(u8 addr, const char *name, int status, const char *extra) | ||
| 848 | { | ||
| 849 | struct timeval tval; | ||
| 850 | unsigned int stamp; | ||
| 851 | unsigned long flags; | ||
| 852 | |||
| 853 | write_lock_irqsave(&dbg_data.lck, flags); | ||
| 854 | |||
| 855 | do_gettimeofday(&tval); | ||
| 856 | stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */ | ||
| 857 | stamp = stamp * 1000000 + tval.tv_usec; | ||
| 858 | |||
| 859 | scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG, | ||
| 860 | "%04X\t? %02X %-7.7s %4i ?\t%s\n", | ||
| 861 | stamp, addr, name, status, extra); | ||
| 862 | |||
| 863 | dbg_inc(&dbg_data.idx); | ||
| 864 | |||
| 865 | write_unlock_irqrestore(&dbg_data.lck, flags); | ||
| 866 | |||
| 867 | if (dbg_data.tty != 0) | ||
| 868 | pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n", | ||
| 869 | stamp, addr, name, status, extra); | ||
| 870 | } | ||
| 871 | |||
| 872 | /** | ||
| 873 | * dbg_done: prints a DONE event | ||
| 874 | * @addr: endpoint address | ||
| 875 | * @td: transfer descriptor | ||
| 876 | * @status: status | ||
| 877 | */ | ||
| 878 | static void dbg_done(u8 addr, const u32 token, int status) | ||
| 879 | { | ||
| 880 | char msg[DBG_DATA_MSG]; | ||
| 881 | |||
| 882 | scnprintf(msg, sizeof(msg), "%d %02X", | ||
| 883 | (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES), | ||
| 884 | (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS)); | ||
| 885 | dbg_print(addr, "DONE", status, msg); | ||
| 886 | } | ||
| 887 | |||
| 888 | /** | ||
| 889 | * dbg_event: prints a generic event | ||
| 890 | * @addr: endpoint address | ||
| 891 | * @name: event name | ||
| 892 | * @status: status | ||
| 893 | */ | ||
| 894 | static void dbg_event(u8 addr, const char *name, int status) | ||
| 895 | { | ||
| 896 | if (name != NULL) | ||
| 897 | dbg_print(addr, name, status, ""); | ||
| 898 | } | ||
| 899 | |||
| 900 | /* | ||
| 901 | * dbg_queue: prints a QUEUE event | ||
| 902 | * @addr: endpoint address | ||
| 903 | * @req: USB request | ||
| 904 | * @status: status | ||
| 905 | */ | ||
| 906 | static void dbg_queue(u8 addr, const struct usb_request *req, int status) | ||
| 907 | { | ||
| 908 | char msg[DBG_DATA_MSG]; | ||
| 909 | |||
| 910 | if (req != NULL) { | ||
| 911 | scnprintf(msg, sizeof(msg), | ||
| 912 | "%d %d", !req->no_interrupt, req->length); | ||
| 913 | dbg_print(addr, "QUEUE", status, msg); | ||
| 914 | } | ||
| 915 | } | ||
| 916 | |||
| 917 | /** | ||
| 918 | * dbg_setup: prints a SETUP event | ||
| 919 | * @addr: endpoint address | ||
| 920 | * @req: setup request | ||
| 921 | */ | ||
| 922 | static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req) | ||
| 923 | { | ||
| 924 | char msg[DBG_DATA_MSG]; | ||
| 925 | |||
| 926 | if (req != NULL) { | ||
| 927 | scnprintf(msg, sizeof(msg), | ||
| 928 | "%02X %02X %04X %04X %d", req->bRequestType, | ||
| 929 | req->bRequest, le16_to_cpu(req->wValue), | ||
| 930 | le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength)); | ||
| 931 | dbg_print(addr, "SETUP", 0, msg); | ||
| 932 | } | ||
| 933 | } | ||
| 934 | |||
| 935 | /** | ||
| 936 | * show_events: displays the event buffer | ||
| 937 | * | ||
| 938 | * Check "device.h" for details | ||
| 939 | */ | ||
| 940 | static ssize_t show_events(struct device *dev, struct device_attribute *attr, | ||
| 941 | char *buf) | ||
| 942 | { | ||
| 943 | unsigned long flags; | ||
| 944 | unsigned i, j, n = 0; | ||
| 945 | |||
| 946 | dbg_trace("[%s] %p\n", __func__, buf); | ||
| 947 | if (attr == NULL || buf == NULL) { | ||
| 948 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 949 | return 0; | ||
| 950 | } | ||
| 951 | |||
| 952 | read_lock_irqsave(&dbg_data.lck, flags); | ||
| 953 | |||
| 954 | i = dbg_data.idx; | ||
| 955 | for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) { | ||
| 956 | n += strlen(dbg_data.buf[i]); | ||
| 957 | if (n >= PAGE_SIZE) { | ||
| 958 | n -= strlen(dbg_data.buf[i]); | ||
| 959 | break; | ||
| 960 | } | ||
| 961 | } | ||
| 962 | for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i)) | ||
| 963 | j += scnprintf(buf + j, PAGE_SIZE - j, | ||
| 964 | "%s", dbg_data.buf[i]); | ||
| 965 | |||
| 966 | read_unlock_irqrestore(&dbg_data.lck, flags); | ||
| 967 | |||
| 968 | return n; | ||
| 969 | } | ||
| 970 | |||
| 971 | /** | ||
| 972 | * store_events: configure if events are going to be also printed to console | ||
| 973 | * | ||
| 974 | * Check "device.h" for details | ||
| 975 | */ | ||
| 976 | static ssize_t store_events(struct device *dev, struct device_attribute *attr, | ||
| 977 | const char *buf, size_t count) | ||
| 978 | { | ||
| 979 | unsigned tty; | ||
| 980 | |||
| 981 | dbg_trace("[%s] %p, %d\n", __func__, buf, count); | ||
| 982 | if (attr == NULL || buf == NULL) { | ||
| 983 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 984 | goto done; | ||
| 985 | } | ||
| 986 | |||
| 987 | if (sscanf(buf, "%u", &tty) != 1 || tty > 1) { | ||
| 988 | dev_err(dev, "<1|0>: enable|disable console log\n"); | ||
| 989 | goto done; | ||
| 990 | } | ||
| 991 | |||
| 992 | dbg_data.tty = tty; | ||
| 993 | dev_info(dev, "tty = %u", dbg_data.tty); | ||
| 994 | |||
| 995 | done: | ||
| 996 | return count; | ||
| 997 | } | ||
| 998 | static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events); | ||
| 999 | |||
| 1000 | /** | ||
| 1001 | * show_inters: interrupt status, enable status and historic | ||
| 1002 | * | ||
| 1003 | * Check "device.h" for details | ||
| 1004 | */ | ||
| 1005 | static ssize_t show_inters(struct device *dev, struct device_attribute *attr, | ||
| 1006 | char *buf) | ||
| 1007 | { | ||
| 1008 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 1009 | unsigned long flags; | ||
| 1010 | u32 intr; | ||
| 1011 | unsigned i, j, n = 0; | ||
| 1012 | |||
| 1013 | dbg_trace("[%s] %p\n", __func__, buf); | ||
| 1014 | if (attr == NULL || buf == NULL) { | ||
| 1015 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 1016 | return 0; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | spin_lock_irqsave(udc->lock, flags); | ||
| 1020 | |||
| 1021 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
| 1022 | "status = %08x\n", hw_read_intr_status()); | ||
| 1023 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
| 1024 | "enable = %08x\n", hw_read_intr_enable()); | ||
| 1025 | |||
| 1026 | n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n", | ||
| 1027 | isr_statistics.test); | ||
| 1028 | n += scnprintf(buf + n, PAGE_SIZE - n, "? ui = %d\n", | ||
| 1029 | isr_statistics.ui); | ||
| 1030 | n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n", | ||
| 1031 | isr_statistics.uei); | ||
| 1032 | n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n", | ||
| 1033 | isr_statistics.pci); | ||
| 1034 | n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n", | ||
| 1035 | isr_statistics.uri); | ||
| 1036 | n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n", | ||
| 1037 | isr_statistics.sli); | ||
| 1038 | n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n", | ||
| 1039 | isr_statistics.none); | ||
| 1040 | n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n", | ||
| 1041 | isr_statistics.hndl.cnt); | ||
| 1042 | |||
| 1043 | for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) { | ||
| 1044 | i &= ISR_MASK; | ||
| 1045 | intr = isr_statistics.hndl.buf[i]; | ||
| 1046 | |||
| 1047 | if (USBi_UI & intr) | ||
| 1048 | n += scnprintf(buf + n, PAGE_SIZE - n, "ui "); | ||
| 1049 | intr &= ~USBi_UI; | ||
| 1050 | if (USBi_UEI & intr) | ||
| 1051 | n += scnprintf(buf + n, PAGE_SIZE - n, "uei "); | ||
| 1052 | intr &= ~USBi_UEI; | ||
| 1053 | if (USBi_PCI & intr) | ||
| 1054 | n += scnprintf(buf + n, PAGE_SIZE - n, "pci "); | ||
| 1055 | intr &= ~USBi_PCI; | ||
| 1056 | if (USBi_URI & intr) | ||
| 1057 | n += scnprintf(buf + n, PAGE_SIZE - n, "uri "); | ||
| 1058 | intr &= ~USBi_URI; | ||
| 1059 | if (USBi_SLI & intr) | ||
| 1060 | n += scnprintf(buf + n, PAGE_SIZE - n, "sli "); | ||
| 1061 | intr &= ~USBi_SLI; | ||
| 1062 | if (intr) | ||
| 1063 | n += scnprintf(buf + n, PAGE_SIZE - n, "??? "); | ||
| 1064 | if (isr_statistics.hndl.buf[i]) | ||
| 1065 | n += scnprintf(buf + n, PAGE_SIZE - n, "\n"); | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1069 | |||
| 1070 | return n; | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | /** | ||
| 1074 | * store_inters: enable & force or disable an individual interrutps | ||
| 1075 | * (to be used for test purposes only) | ||
| 1076 | * | ||
| 1077 | * Check "device.h" for details | ||
| 1078 | */ | ||
| 1079 | static ssize_t store_inters(struct device *dev, struct device_attribute *attr, | ||
| 1080 | const char *buf, size_t count) | ||
| 1081 | { | ||
| 1082 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 1083 | unsigned long flags; | ||
| 1084 | unsigned en, bit; | ||
| 1085 | |||
| 1086 | dbg_trace("[%s] %p, %d\n", __func__, buf, count); | ||
| 1087 | if (attr == NULL || buf == NULL) { | ||
| 1088 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 1089 | goto done; | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) { | ||
| 1093 | dev_err(dev, "<1|0> <bit>: enable|disable interrupt"); | ||
| 1094 | goto done; | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | spin_lock_irqsave(udc->lock, flags); | ||
| 1098 | if (en) { | ||
| 1099 | if (hw_intr_force(bit)) | ||
| 1100 | dev_err(dev, "invalid bit number\n"); | ||
| 1101 | else | ||
| 1102 | isr_statistics.test++; | ||
| 1103 | } else { | ||
| 1104 | if (hw_intr_clear(bit)) | ||
| 1105 | dev_err(dev, "invalid bit number\n"); | ||
| 1106 | } | ||
| 1107 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1108 | |||
| 1109 | done: | ||
| 1110 | return count; | ||
| 1111 | } | ||
| 1112 | static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters); | ||
| 1113 | |||
| 1114 | /** | ||
| 1115 | * show_port_test: reads port test mode | ||
| 1116 | * | ||
| 1117 | * Check "device.h" for details | ||
| 1118 | */ | ||
| 1119 | static ssize_t show_port_test(struct device *dev, | ||
| 1120 | struct device_attribute *attr, char *buf) | ||
| 1121 | { | ||
| 1122 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 1123 | unsigned long flags; | ||
| 1124 | unsigned mode; | ||
| 1125 | |||
| 1126 | dbg_trace("[%s] %p\n", __func__, buf); | ||
| 1127 | if (attr == NULL || buf == NULL) { | ||
| 1128 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 1129 | return 0; | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | spin_lock_irqsave(udc->lock, flags); | ||
| 1133 | mode = hw_port_test_get(); | ||
| 1134 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1135 | |||
| 1136 | return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode); | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | /** | ||
| 1140 | * store_port_test: writes port test mode | ||
| 1141 | * | ||
| 1142 | * Check "device.h" for details | ||
| 1143 | */ | ||
| 1144 | static ssize_t store_port_test(struct device *dev, | ||
| 1145 | struct device_attribute *attr, | ||
| 1146 | const char *buf, size_t count) | ||
| 1147 | { | ||
| 1148 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 1149 | unsigned long flags; | ||
| 1150 | unsigned mode; | ||
| 1151 | |||
| 1152 | dbg_trace("[%s] %p, %d\n", __func__, buf, count); | ||
| 1153 | if (attr == NULL || buf == NULL) { | ||
| 1154 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 1155 | goto done; | ||
| 1156 | } | ||
| 1157 | |||
| 1158 | if (sscanf(buf, "%u", &mode) != 1) { | ||
| 1159 | dev_err(dev, "<mode>: set port test mode"); | ||
| 1160 | goto done; | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | spin_lock_irqsave(udc->lock, flags); | ||
| 1164 | if (hw_port_test_set(mode)) | ||
| 1165 | dev_err(dev, "invalid mode\n"); | ||
| 1166 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1167 | |||
| 1168 | done: | ||
| 1169 | return count; | ||
| 1170 | } | ||
| 1171 | static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR, | ||
| 1172 | show_port_test, store_port_test); | ||
| 1173 | |||
| 1174 | /** | ||
| 1175 | * show_qheads: DMA contents of all queue heads | ||
| 1176 | * | ||
| 1177 | * Check "device.h" for details | ||
| 1178 | */ | ||
| 1179 | static ssize_t show_qheads(struct device *dev, struct device_attribute *attr, | ||
| 1180 | char *buf) | ||
| 1181 | { | ||
| 1182 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 1183 | unsigned long flags; | ||
| 1184 | unsigned i, j, n = 0; | ||
| 1185 | |||
| 1186 | dbg_trace("[%s] %p\n", __func__, buf); | ||
| 1187 | if (attr == NULL || buf == NULL) { | ||
| 1188 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 1189 | return 0; | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | spin_lock_irqsave(udc->lock, flags); | ||
| 1193 | for (i = 0; i < hw_ep_max/2; i++) { | ||
| 1194 | struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i]; | ||
| 1195 | struct ci13xxx_ep *mEpTx = &udc->ci13xxx_ep[i + hw_ep_max/2]; | ||
| 1196 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
| 1197 | "EP=%02i: RX=%08X TX=%08X\n", | ||
| 1198 | i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma); | ||
| 1199 | for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) { | ||
| 1200 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
| 1201 | " %04X: %08X %08X\n", j, | ||
| 1202 | *((u32 *)mEpRx->qh.ptr + j), | ||
| 1203 | *((u32 *)mEpTx->qh.ptr + j)); | ||
| 1204 | } | ||
| 1205 | } | ||
| 1206 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1207 | |||
| 1208 | return n; | ||
| 1209 | } | ||
| 1210 | static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL); | ||
| 1211 | |||
| 1212 | /** | ||
| 1213 | * show_registers: dumps all registers | ||
| 1214 | * | ||
| 1215 | * Check "device.h" for details | ||
| 1216 | */ | ||
| 1217 | #define DUMP_ENTRIES 512 | ||
| 1218 | static ssize_t show_registers(struct device *dev, | ||
| 1219 | struct device_attribute *attr, char *buf) | ||
| 1220 | { | ||
| 1221 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 1222 | unsigned long flags; | ||
| 1223 | u32 *dump; | ||
| 1224 | unsigned i, k, n = 0; | ||
| 1225 | |||
| 1226 | dbg_trace("[%s] %p\n", __func__, buf); | ||
| 1227 | if (attr == NULL || buf == NULL) { | ||
| 1228 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 1229 | return 0; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL); | ||
| 1233 | if (!dump) { | ||
| 1234 | dev_err(dev, "%s: out of memory\n", __func__); | ||
| 1235 | return 0; | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | spin_lock_irqsave(udc->lock, flags); | ||
| 1239 | k = hw_register_read(dump, DUMP_ENTRIES); | ||
| 1240 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1241 | |||
| 1242 | for (i = 0; i < k; i++) { | ||
| 1243 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
| 1244 | "reg[0x%04X] = 0x%08X\n", | ||
| 1245 | i * (unsigned)sizeof(u32), dump[i]); | ||
| 1246 | } | ||
| 1247 | kfree(dump); | ||
| 1248 | |||
| 1249 | return n; | ||
| 1250 | } | ||
| 1251 | |||
| 1252 | /** | ||
| 1253 | * store_registers: writes value to register address | ||
| 1254 | * | ||
| 1255 | * Check "device.h" for details | ||
| 1256 | */ | ||
| 1257 | static ssize_t store_registers(struct device *dev, | ||
| 1258 | struct device_attribute *attr, | ||
| 1259 | const char *buf, size_t count) | ||
| 1260 | { | ||
| 1261 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 1262 | unsigned long addr, data, flags; | ||
| 1263 | |||
| 1264 | dbg_trace("[%s] %p, %d\n", __func__, buf, count); | ||
| 1265 | if (attr == NULL || buf == NULL) { | ||
| 1266 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 1267 | goto done; | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | if (sscanf(buf, "%li %li", &addr, &data) != 2) { | ||
| 1271 | dev_err(dev, "<addr> <data>: write data to register address"); | ||
| 1272 | goto done; | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | spin_lock_irqsave(udc->lock, flags); | ||
| 1276 | if (hw_register_write(addr, data)) | ||
| 1277 | dev_err(dev, "invalid address range\n"); | ||
| 1278 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1279 | |||
| 1280 | done: | ||
| 1281 | return count; | ||
| 1282 | } | ||
| 1283 | static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR, | ||
| 1284 | show_registers, store_registers); | ||
| 1285 | |||
| 1286 | /** | ||
| 1287 | * show_requests: DMA contents of all requests currently queued (all endpts) | ||
| 1288 | * | ||
| 1289 | * Check "device.h" for details | ||
| 1290 | */ | ||
| 1291 | static ssize_t show_requests(struct device *dev, struct device_attribute *attr, | ||
| 1292 | char *buf) | ||
| 1293 | { | ||
| 1294 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
| 1295 | unsigned long flags; | ||
| 1296 | struct list_head *ptr = NULL; | ||
| 1297 | struct ci13xxx_req *req = NULL; | ||
| 1298 | unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32); | ||
| 1299 | |||
| 1300 | dbg_trace("[%s] %p\n", __func__, buf); | ||
| 1301 | if (attr == NULL || buf == NULL) { | ||
| 1302 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
| 1303 | return 0; | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | spin_lock_irqsave(udc->lock, flags); | ||
| 1307 | for (i = 0; i < hw_ep_max; i++) | ||
| 1308 | list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue) | ||
| 1309 | { | ||
| 1310 | req = list_entry(ptr, struct ci13xxx_req, queue); | ||
| 1311 | |||
| 1312 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
| 1313 | "EP=%02i: TD=%08X %s\n", | ||
| 1314 | i % hw_ep_max/2, (u32)req->dma, | ||
| 1315 | ((i < hw_ep_max/2) ? "RX" : "TX")); | ||
| 1316 | |||
| 1317 | for (j = 0; j < qSize; j++) | ||
| 1318 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
| 1319 | " %04X: %08X\n", j, | ||
| 1320 | *((u32 *)req->ptr + j)); | ||
| 1321 | } | ||
| 1322 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1323 | |||
| 1324 | return n; | ||
| 1325 | } | ||
| 1326 | static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL); | ||
| 1327 | |||
| 1328 | /** | ||
| 1329 | * dbg_create_files: initializes the attribute interface | ||
| 1330 | * @dev: device | ||
| 1331 | * | ||
| 1332 | * This function returns an error code | ||
| 1333 | */ | ||
| 1334 | __maybe_unused static int dbg_create_files(struct device *dev) | ||
| 1335 | { | ||
| 1336 | int retval = 0; | ||
| 1337 | |||
| 1338 | if (dev == NULL) | ||
| 1339 | return -EINVAL; | ||
| 1340 | retval = device_create_file(dev, &dev_attr_device); | ||
| 1341 | if (retval) | ||
| 1342 | goto done; | ||
| 1343 | retval = device_create_file(dev, &dev_attr_driver); | ||
| 1344 | if (retval) | ||
| 1345 | goto rm_device; | ||
| 1346 | retval = device_create_file(dev, &dev_attr_events); | ||
| 1347 | if (retval) | ||
| 1348 | goto rm_driver; | ||
| 1349 | retval = device_create_file(dev, &dev_attr_inters); | ||
| 1350 | if (retval) | ||
| 1351 | goto rm_events; | ||
| 1352 | retval = device_create_file(dev, &dev_attr_port_test); | ||
| 1353 | if (retval) | ||
| 1354 | goto rm_inters; | ||
| 1355 | retval = device_create_file(dev, &dev_attr_qheads); | ||
| 1356 | if (retval) | ||
| 1357 | goto rm_port_test; | ||
| 1358 | retval = device_create_file(dev, &dev_attr_registers); | ||
| 1359 | if (retval) | ||
| 1360 | goto rm_qheads; | ||
| 1361 | retval = device_create_file(dev, &dev_attr_requests); | ||
| 1362 | if (retval) | ||
| 1363 | goto rm_registers; | ||
| 1364 | return 0; | ||
| 1365 | |||
| 1366 | rm_registers: | ||
| 1367 | device_remove_file(dev, &dev_attr_registers); | ||
| 1368 | rm_qheads: | ||
| 1369 | device_remove_file(dev, &dev_attr_qheads); | ||
| 1370 | rm_port_test: | ||
| 1371 | device_remove_file(dev, &dev_attr_port_test); | ||
| 1372 | rm_inters: | ||
| 1373 | device_remove_file(dev, &dev_attr_inters); | ||
| 1374 | rm_events: | ||
| 1375 | device_remove_file(dev, &dev_attr_events); | ||
| 1376 | rm_driver: | ||
| 1377 | device_remove_file(dev, &dev_attr_driver); | ||
| 1378 | rm_device: | ||
| 1379 | device_remove_file(dev, &dev_attr_device); | ||
| 1380 | done: | ||
| 1381 | return retval; | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | /** | ||
| 1385 | * dbg_remove_files: destroys the attribute interface | ||
| 1386 | * @dev: device | ||
| 1387 | * | ||
| 1388 | * This function returns an error code | ||
| 1389 | */ | ||
| 1390 | __maybe_unused static int dbg_remove_files(struct device *dev) | ||
| 1391 | { | ||
| 1392 | if (dev == NULL) | ||
| 1393 | return -EINVAL; | ||
| 1394 | device_remove_file(dev, &dev_attr_requests); | ||
| 1395 | device_remove_file(dev, &dev_attr_registers); | ||
| 1396 | device_remove_file(dev, &dev_attr_qheads); | ||
| 1397 | device_remove_file(dev, &dev_attr_port_test); | ||
| 1398 | device_remove_file(dev, &dev_attr_inters); | ||
| 1399 | device_remove_file(dev, &dev_attr_events); | ||
| 1400 | device_remove_file(dev, &dev_attr_driver); | ||
| 1401 | device_remove_file(dev, &dev_attr_device); | ||
| 1402 | return 0; | ||
| 1403 | } | ||
| 1404 | |||
| 1405 | /****************************************************************************** | ||
| 1406 | * UTIL block | ||
| 1407 | *****************************************************************************/ | ||
| 1408 | /** | ||
| 1409 | * _usb_addr: calculates endpoint address from direction & number | ||
| 1410 | * @ep: endpoint | ||
| 1411 | */ | ||
| 1412 | static inline u8 _usb_addr(struct ci13xxx_ep *ep) | ||
| 1413 | { | ||
| 1414 | return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num; | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | /** | ||
| 1418 | * _hardware_queue: configures a request at hardware level | ||
| 1419 | * @gadget: gadget | ||
| 1420 | * @mEp: endpoint | ||
| 1421 | * | ||
| 1422 | * This function returns an error code | ||
| 1423 | */ | ||
| 1424 | static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | ||
| 1425 | { | ||
| 1426 | unsigned i; | ||
| 1427 | int ret = 0; | ||
| 1428 | unsigned length = mReq->req.length; | ||
| 1429 | |||
| 1430 | trace("%p, %p", mEp, mReq); | ||
| 1431 | |||
| 1432 | /* don't queue twice */ | ||
| 1433 | if (mReq->req.status == -EALREADY) | ||
| 1434 | return -EALREADY; | ||
| 1435 | |||
| 1436 | mReq->req.status = -EALREADY; | ||
| 1437 | if (length && !mReq->req.dma) { | ||
| 1438 | mReq->req.dma = \ | ||
| 1439 | dma_map_single(mEp->device, mReq->req.buf, | ||
| 1440 | length, mEp->dir ? DMA_TO_DEVICE : | ||
| 1441 | DMA_FROM_DEVICE); | ||
| 1442 | if (mReq->req.dma == 0) | ||
| 1443 | return -ENOMEM; | ||
| 1444 | |||
| 1445 | mReq->map = 1; | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) { | ||
| 1449 | mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC, | ||
| 1450 | &mReq->zdma); | ||
| 1451 | if (mReq->zptr == NULL) { | ||
| 1452 | if (mReq->map) { | ||
| 1453 | dma_unmap_single(mEp->device, mReq->req.dma, | ||
| 1454 | length, mEp->dir ? DMA_TO_DEVICE : | ||
| 1455 | DMA_FROM_DEVICE); | ||
| 1456 | mReq->req.dma = 0; | ||
| 1457 | mReq->map = 0; | ||
| 1458 | } | ||
| 1459 | return -ENOMEM; | ||
| 1460 | } | ||
| 1461 | memset(mReq->zptr, 0, sizeof(*mReq->zptr)); | ||
| 1462 | mReq->zptr->next = TD_TERMINATE; | ||
| 1463 | mReq->zptr->token = TD_STATUS_ACTIVE; | ||
| 1464 | if (!mReq->req.no_interrupt) | ||
| 1465 | mReq->zptr->token |= TD_IOC; | ||
| 1466 | } | ||
| 1467 | /* | ||
| 1468 | * TD configuration | ||
| 1469 | * TODO - handle requests which spawns into several TDs | ||
| 1470 | */ | ||
| 1471 | memset(mReq->ptr, 0, sizeof(*mReq->ptr)); | ||
| 1472 | mReq->ptr->token = length << ffs_nr(TD_TOTAL_BYTES); | ||
| 1473 | mReq->ptr->token &= TD_TOTAL_BYTES; | ||
| 1474 | mReq->ptr->token |= TD_STATUS_ACTIVE; | ||
| 1475 | if (mReq->zptr) { | ||
| 1476 | mReq->ptr->next = mReq->zdma; | ||
| 1477 | } else { | ||
| 1478 | mReq->ptr->next = TD_TERMINATE; | ||
| 1479 | if (!mReq->req.no_interrupt) | ||
| 1480 | mReq->ptr->token |= TD_IOC; | ||
| 1481 | } | ||
| 1482 | mReq->ptr->page[0] = mReq->req.dma; | ||
| 1483 | for (i = 1; i < 5; i++) | ||
| 1484 | mReq->ptr->page[i] = | ||
| 1485 | (mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK; | ||
| 1486 | |||
| 1487 | if (!list_empty(&mEp->qh.queue)) { | ||
| 1488 | struct ci13xxx_req *mReqPrev; | ||
| 1489 | int n = hw_ep_bit(mEp->num, mEp->dir); | ||
| 1490 | int tmp_stat; | ||
| 1491 | |||
| 1492 | mReqPrev = list_entry(mEp->qh.queue.prev, | ||
| 1493 | struct ci13xxx_req, queue); | ||
| 1494 | if (mReqPrev->zptr) | ||
| 1495 | mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK; | ||
| 1496 | else | ||
| 1497 | mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK; | ||
| 1498 | wmb(); | ||
| 1499 | if (hw_cread(CAP_ENDPTPRIME, BIT(n))) | ||
| 1500 | goto done; | ||
| 1501 | do { | ||
| 1502 | hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW); | ||
| 1503 | tmp_stat = hw_cread(CAP_ENDPTSTAT, BIT(n)); | ||
| 1504 | } while (!hw_cread(CAP_USBCMD, USBCMD_ATDTW)); | ||
| 1505 | hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, 0); | ||
| 1506 | if (tmp_stat) | ||
| 1507 | goto done; | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | /* QH configuration */ | ||
| 1511 | mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */ | ||
| 1512 | mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */ | ||
| 1513 | mEp->qh.ptr->cap |= QH_ZLT; | ||
| 1514 | |||
| 1515 | wmb(); /* synchronize before ep prime */ | ||
| 1516 | |||
| 1517 | ret = hw_ep_prime(mEp->num, mEp->dir, | ||
| 1518 | mEp->type == USB_ENDPOINT_XFER_CONTROL); | ||
| 1519 | done: | ||
| 1520 | return ret; | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | /** | ||
| 1524 | * _hardware_dequeue: handles a request at hardware level | ||
| 1525 | * @gadget: gadget | ||
| 1526 | * @mEp: endpoint | ||
| 1527 | * | ||
| 1528 | * This function returns an error code | ||
| 1529 | */ | ||
| 1530 | static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | ||
| 1531 | { | ||
| 1532 | trace("%p, %p", mEp, mReq); | ||
| 1533 | |||
| 1534 | if (mReq->req.status != -EALREADY) | ||
| 1535 | return -EINVAL; | ||
| 1536 | |||
| 1537 | if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0) | ||
| 1538 | return -EBUSY; | ||
| 1539 | |||
| 1540 | if (mReq->zptr) { | ||
| 1541 | if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0) | ||
| 1542 | return -EBUSY; | ||
| 1543 | dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma); | ||
| 1544 | mReq->zptr = NULL; | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | mReq->req.status = 0; | ||
| 1548 | |||
| 1549 | if (mReq->map) { | ||
| 1550 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, | ||
| 1551 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 1552 | mReq->req.dma = 0; | ||
| 1553 | mReq->map = 0; | ||
| 1554 | } | ||
| 1555 | |||
| 1556 | mReq->req.status = mReq->ptr->token & TD_STATUS; | ||
| 1557 | if ((TD_STATUS_HALTED & mReq->req.status) != 0) | ||
| 1558 | mReq->req.status = -1; | ||
| 1559 | else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0) | ||
| 1560 | mReq->req.status = -1; | ||
| 1561 | else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0) | ||
| 1562 | mReq->req.status = -1; | ||
| 1563 | |||
| 1564 | mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES; | ||
| 1565 | mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES); | ||
| 1566 | mReq->req.actual = mReq->req.length - mReq->req.actual; | ||
| 1567 | mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual; | ||
| 1568 | |||
| 1569 | return mReq->req.actual; | ||
| 1570 | } | ||
| 1571 | |||
| 1572 | /** | ||
| 1573 | * _ep_nuke: dequeues all endpoint requests | ||
| 1574 | * @mEp: endpoint | ||
| 1575 | * | ||
| 1576 | * This function returns an error code | ||
| 1577 | * Caller must hold lock | ||
| 1578 | */ | ||
| 1579 | static int _ep_nuke(struct ci13xxx_ep *mEp) | ||
| 1580 | __releases(mEp->lock) | ||
| 1581 | __acquires(mEp->lock) | ||
| 1582 | { | ||
| 1583 | trace("%p", mEp); | ||
| 1584 | |||
| 1585 | if (mEp == NULL) | ||
| 1586 | return -EINVAL; | ||
| 1587 | |||
| 1588 | hw_ep_flush(mEp->num, mEp->dir); | ||
| 1589 | |||
| 1590 | while (!list_empty(&mEp->qh.queue)) { | ||
| 1591 | |||
| 1592 | /* pop oldest request */ | ||
| 1593 | struct ci13xxx_req *mReq = \ | ||
| 1594 | list_entry(mEp->qh.queue.next, | ||
| 1595 | struct ci13xxx_req, queue); | ||
| 1596 | list_del_init(&mReq->queue); | ||
| 1597 | mReq->req.status = -ESHUTDOWN; | ||
| 1598 | |||
| 1599 | if (mReq->req.complete != NULL) { | ||
| 1600 | spin_unlock(mEp->lock); | ||
| 1601 | mReq->req.complete(&mEp->ep, &mReq->req); | ||
| 1602 | spin_lock(mEp->lock); | ||
| 1603 | } | ||
| 1604 | } | ||
| 1605 | return 0; | ||
| 1606 | } | ||
| 1607 | |||
| 1608 | /** | ||
| 1609 | * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts | ||
| 1610 | * @gadget: gadget | ||
| 1611 | * | ||
| 1612 | * This function returns an error code | ||
| 1613 | * Caller must hold lock | ||
| 1614 | */ | ||
| 1615 | static int _gadget_stop_activity(struct usb_gadget *gadget) | ||
| 1616 | { | ||
| 1617 | struct usb_ep *ep; | ||
| 1618 | struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); | ||
| 1619 | unsigned long flags; | ||
| 1620 | |||
| 1621 | trace("%p", gadget); | ||
| 1622 | |||
| 1623 | if (gadget == NULL) | ||
| 1624 | return -EINVAL; | ||
| 1625 | |||
| 1626 | spin_lock_irqsave(udc->lock, flags); | ||
| 1627 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1628 | udc->remote_wakeup = 0; | ||
| 1629 | udc->suspended = 0; | ||
| 1630 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1631 | |||
| 1632 | /* flush all endpoints */ | ||
| 1633 | gadget_for_each_ep(ep, gadget) { | ||
| 1634 | usb_ep_fifo_flush(ep); | ||
| 1635 | } | ||
| 1636 | usb_ep_fifo_flush(&udc->ep0out.ep); | ||
| 1637 | usb_ep_fifo_flush(&udc->ep0in.ep); | ||
| 1638 | |||
| 1639 | udc->driver->disconnect(gadget); | ||
| 1640 | |||
| 1641 | /* make sure to disable all endpoints */ | ||
| 1642 | gadget_for_each_ep(ep, gadget) { | ||
| 1643 | usb_ep_disable(ep); | ||
| 1644 | } | ||
| 1645 | |||
| 1646 | if (udc->status != NULL) { | ||
| 1647 | usb_ep_free_request(&udc->ep0in.ep, udc->status); | ||
| 1648 | udc->status = NULL; | ||
| 1649 | } | ||
| 1650 | |||
| 1651 | return 0; | ||
| 1652 | } | ||
| 1653 | |||
| 1654 | /****************************************************************************** | ||
| 1655 | * ISR block | ||
| 1656 | *****************************************************************************/ | ||
| 1657 | /** | ||
| 1658 | * isr_reset_handler: USB reset interrupt handler | ||
| 1659 | * @udc: UDC device | ||
| 1660 | * | ||
| 1661 | * This function resets USB engine after a bus reset occurred | ||
| 1662 | */ | ||
| 1663 | static void isr_reset_handler(struct ci13xxx *udc) | ||
| 1664 | __releases(udc->lock) | ||
| 1665 | __acquires(udc->lock) | ||
| 1666 | { | ||
| 1667 | int retval; | ||
| 1668 | |||
| 1669 | trace("%p", udc); | ||
| 1670 | |||
| 1671 | if (udc == NULL) { | ||
| 1672 | err("EINVAL"); | ||
| 1673 | return; | ||
| 1674 | } | ||
| 1675 | |||
| 1676 | dbg_event(0xFF, "BUS RST", 0); | ||
| 1677 | |||
| 1678 | spin_unlock(udc->lock); | ||
| 1679 | retval = _gadget_stop_activity(&udc->gadget); | ||
| 1680 | if (retval) | ||
| 1681 | goto done; | ||
| 1682 | |||
| 1683 | retval = hw_usb_reset(); | ||
| 1684 | if (retval) | ||
| 1685 | goto done; | ||
| 1686 | |||
| 1687 | udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC); | ||
| 1688 | if (udc->status == NULL) | ||
| 1689 | retval = -ENOMEM; | ||
| 1690 | |||
| 1691 | spin_lock(udc->lock); | ||
| 1692 | |||
| 1693 | done: | ||
| 1694 | if (retval) | ||
| 1695 | err("error: %i", retval); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | /** | ||
| 1699 | * isr_get_status_complete: get_status request complete function | ||
| 1700 | * @ep: endpoint | ||
| 1701 | * @req: request handled | ||
| 1702 | * | ||
| 1703 | * Caller must release lock | ||
| 1704 | */ | ||
| 1705 | static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 1706 | { | ||
| 1707 | trace("%p, %p", ep, req); | ||
| 1708 | |||
| 1709 | if (ep == NULL || req == NULL) { | ||
| 1710 | err("EINVAL"); | ||
| 1711 | return; | ||
| 1712 | } | ||
| 1713 | |||
| 1714 | kfree(req->buf); | ||
| 1715 | usb_ep_free_request(ep, req); | ||
| 1716 | } | ||
| 1717 | |||
| 1718 | /** | ||
| 1719 | * isr_get_status_response: get_status request response | ||
| 1720 | * @udc: udc struct | ||
| 1721 | * @setup: setup request packet | ||
| 1722 | * | ||
| 1723 | * This function returns an error code | ||
| 1724 | */ | ||
| 1725 | static int isr_get_status_response(struct ci13xxx *udc, | ||
| 1726 | struct usb_ctrlrequest *setup) | ||
| 1727 | __releases(mEp->lock) | ||
| 1728 | __acquires(mEp->lock) | ||
| 1729 | { | ||
| 1730 | struct ci13xxx_ep *mEp = &udc->ep0in; | ||
| 1731 | struct usb_request *req = NULL; | ||
| 1732 | gfp_t gfp_flags = GFP_ATOMIC; | ||
| 1733 | int dir, num, retval; | ||
| 1734 | |||
| 1735 | trace("%p, %p", mEp, setup); | ||
| 1736 | |||
| 1737 | if (mEp == NULL || setup == NULL) | ||
| 1738 | return -EINVAL; | ||
| 1739 | |||
| 1740 | spin_unlock(mEp->lock); | ||
| 1741 | req = usb_ep_alloc_request(&mEp->ep, gfp_flags); | ||
| 1742 | spin_lock(mEp->lock); | ||
| 1743 | if (req == NULL) | ||
| 1744 | return -ENOMEM; | ||
| 1745 | |||
| 1746 | req->complete = isr_get_status_complete; | ||
| 1747 | req->length = 2; | ||
| 1748 | req->buf = kzalloc(req->length, gfp_flags); | ||
| 1749 | if (req->buf == NULL) { | ||
| 1750 | retval = -ENOMEM; | ||
| 1751 | goto err_free_req; | ||
| 1752 | } | ||
| 1753 | |||
| 1754 | if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) { | ||
| 1755 | /* Assume that device is bus powered for now. */ | ||
| 1756 | *((u16 *)req->buf) = _udc->remote_wakeup << 1; | ||
| 1757 | retval = 0; | ||
| 1758 | } else if ((setup->bRequestType & USB_RECIP_MASK) \ | ||
| 1759 | == USB_RECIP_ENDPOINT) { | ||
| 1760 | dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ? | ||
| 1761 | TX : RX; | ||
| 1762 | num = le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK; | ||
| 1763 | *((u16 *)req->buf) = hw_ep_get_halt(num, dir); | ||
| 1764 | } | ||
| 1765 | /* else do nothing; reserved for future use */ | ||
| 1766 | |||
| 1767 | spin_unlock(mEp->lock); | ||
| 1768 | retval = usb_ep_queue(&mEp->ep, req, gfp_flags); | ||
| 1769 | spin_lock(mEp->lock); | ||
| 1770 | if (retval) | ||
| 1771 | goto err_free_buf; | ||
| 1772 | |||
| 1773 | return 0; | ||
| 1774 | |||
| 1775 | err_free_buf: | ||
| 1776 | kfree(req->buf); | ||
| 1777 | err_free_req: | ||
| 1778 | spin_unlock(mEp->lock); | ||
| 1779 | usb_ep_free_request(&mEp->ep, req); | ||
| 1780 | spin_lock(mEp->lock); | ||
| 1781 | return retval; | ||
| 1782 | } | ||
| 1783 | |||
| 1784 | /** | ||
| 1785 | * isr_setup_status_complete: setup_status request complete function | ||
| 1786 | * @ep: endpoint | ||
| 1787 | * @req: request handled | ||
| 1788 | * | ||
| 1789 | * Caller must release lock. Put the port in test mode if test mode | ||
| 1790 | * feature is selected. | ||
| 1791 | */ | ||
| 1792 | static void | ||
| 1793 | isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 1794 | { | ||
| 1795 | struct ci13xxx *udc = req->context; | ||
| 1796 | unsigned long flags; | ||
| 1797 | |||
| 1798 | trace("%p, %p", ep, req); | ||
| 1799 | |||
| 1800 | spin_lock_irqsave(udc->lock, flags); | ||
| 1801 | if (udc->test_mode) | ||
| 1802 | hw_port_test_set(udc->test_mode); | ||
| 1803 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 1804 | } | ||
| 1805 | |||
| 1806 | /** | ||
| 1807 | * isr_setup_status_phase: queues the status phase of a setup transation | ||
| 1808 | * @udc: udc struct | ||
| 1809 | * | ||
| 1810 | * This function returns an error code | ||
| 1811 | */ | ||
| 1812 | static int isr_setup_status_phase(struct ci13xxx *udc) | ||
| 1813 | __releases(mEp->lock) | ||
| 1814 | __acquires(mEp->lock) | ||
| 1815 | { | ||
| 1816 | int retval; | ||
| 1817 | struct ci13xxx_ep *mEp; | ||
| 1818 | |||
| 1819 | trace("%p", udc); | ||
| 1820 | |||
| 1821 | mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in; | ||
| 1822 | udc->status->context = udc; | ||
| 1823 | udc->status->complete = isr_setup_status_complete; | ||
| 1824 | |||
| 1825 | spin_unlock(mEp->lock); | ||
| 1826 | retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC); | ||
| 1827 | spin_lock(mEp->lock); | ||
| 1828 | |||
| 1829 | return retval; | ||
| 1830 | } | ||
| 1831 | |||
| 1832 | /** | ||
| 1833 | * isr_tr_complete_low: transaction complete low level handler | ||
| 1834 | * @mEp: endpoint | ||
| 1835 | * | ||
| 1836 | * This function returns an error code | ||
| 1837 | * Caller must hold lock | ||
| 1838 | */ | ||
| 1839 | static int isr_tr_complete_low(struct ci13xxx_ep *mEp) | ||
| 1840 | __releases(mEp->lock) | ||
| 1841 | __acquires(mEp->lock) | ||
| 1842 | { | ||
| 1843 | struct ci13xxx_req *mReq, *mReqTemp; | ||
| 1844 | struct ci13xxx_ep *mEpTemp = mEp; | ||
| 1845 | int uninitialized_var(retval); | ||
| 1846 | |||
| 1847 | trace("%p", mEp); | ||
| 1848 | |||
| 1849 | if (list_empty(&mEp->qh.queue)) | ||
| 1850 | return -EINVAL; | ||
| 1851 | |||
| 1852 | list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, | ||
| 1853 | queue) { | ||
| 1854 | retval = _hardware_dequeue(mEp, mReq); | ||
| 1855 | if (retval < 0) | ||
| 1856 | break; | ||
| 1857 | list_del_init(&mReq->queue); | ||
| 1858 | dbg_done(_usb_addr(mEp), mReq->ptr->token, retval); | ||
| 1859 | if (mReq->req.complete != NULL) { | ||
| 1860 | spin_unlock(mEp->lock); | ||
| 1861 | if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) && | ||
| 1862 | mReq->req.length) | ||
| 1863 | mEpTemp = &_udc->ep0in; | ||
| 1864 | mReq->req.complete(&mEpTemp->ep, &mReq->req); | ||
| 1865 | spin_lock(mEp->lock); | ||
| 1866 | } | ||
| 1867 | } | ||
| 1868 | |||
| 1869 | if (retval == -EBUSY) | ||
| 1870 | retval = 0; | ||
| 1871 | if (retval < 0) | ||
| 1872 | dbg_event(_usb_addr(mEp), "DONE", retval); | ||
| 1873 | |||
| 1874 | return retval; | ||
| 1875 | } | ||
| 1876 | |||
| 1877 | /** | ||
| 1878 | * isr_tr_complete_handler: transaction complete interrupt handler | ||
| 1879 | * @udc: UDC descriptor | ||
| 1880 | * | ||
| 1881 | * This function handles traffic events | ||
| 1882 | */ | ||
| 1883 | static void isr_tr_complete_handler(struct ci13xxx *udc) | ||
| 1884 | __releases(udc->lock) | ||
| 1885 | __acquires(udc->lock) | ||
| 1886 | { | ||
| 1887 | unsigned i; | ||
| 1888 | u8 tmode = 0; | ||
| 1889 | |||
| 1890 | trace("%p", udc); | ||
| 1891 | |||
| 1892 | if (udc == NULL) { | ||
| 1893 | err("EINVAL"); | ||
| 1894 | return; | ||
| 1895 | } | ||
| 1896 | |||
| 1897 | for (i = 0; i < hw_ep_max; i++) { | ||
| 1898 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; | ||
| 1899 | int type, num, dir, err = -EINVAL; | ||
| 1900 | struct usb_ctrlrequest req; | ||
| 1901 | |||
| 1902 | if (mEp->desc == NULL) | ||
| 1903 | continue; /* not configured */ | ||
| 1904 | |||
| 1905 | if (hw_test_and_clear_complete(i)) { | ||
| 1906 | err = isr_tr_complete_low(mEp); | ||
| 1907 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { | ||
| 1908 | if (err > 0) /* needs status phase */ | ||
| 1909 | err = isr_setup_status_phase(udc); | ||
| 1910 | if (err < 0) { | ||
| 1911 | dbg_event(_usb_addr(mEp), | ||
| 1912 | "ERROR", err); | ||
| 1913 | spin_unlock(udc->lock); | ||
| 1914 | if (usb_ep_set_halt(&mEp->ep)) | ||
| 1915 | err("error: ep_set_halt"); | ||
| 1916 | spin_lock(udc->lock); | ||
| 1917 | } | ||
| 1918 | } | ||
| 1919 | } | ||
| 1920 | |||
| 1921 | if (mEp->type != USB_ENDPOINT_XFER_CONTROL || | ||
| 1922 | !hw_test_and_clear_setup_status(i)) | ||
| 1923 | continue; | ||
| 1924 | |||
| 1925 | if (i != 0) { | ||
| 1926 | warn("ctrl traffic received at endpoint"); | ||
| 1927 | continue; | ||
| 1928 | } | ||
| 1929 | |||
| 1930 | /* | ||
| 1931 | * Flush data and handshake transactions of previous | ||
| 1932 | * setup packet. | ||
| 1933 | */ | ||
| 1934 | _ep_nuke(&udc->ep0out); | ||
| 1935 | _ep_nuke(&udc->ep0in); | ||
| 1936 | |||
| 1937 | /* read_setup_packet */ | ||
| 1938 | do { | ||
| 1939 | hw_test_and_set_setup_guard(); | ||
| 1940 | memcpy(&req, &mEp->qh.ptr->setup, sizeof(req)); | ||
| 1941 | } while (!hw_test_and_clear_setup_guard()); | ||
| 1942 | |||
| 1943 | type = req.bRequestType; | ||
| 1944 | |||
| 1945 | udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX; | ||
| 1946 | |||
| 1947 | dbg_setup(_usb_addr(mEp), &req); | ||
| 1948 | |||
| 1949 | switch (req.bRequest) { | ||
| 1950 | case USB_REQ_CLEAR_FEATURE: | ||
| 1951 | if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) && | ||
| 1952 | le16_to_cpu(req.wValue) == | ||
| 1953 | USB_ENDPOINT_HALT) { | ||
| 1954 | if (req.wLength != 0) | ||
| 1955 | break; | ||
| 1956 | num = le16_to_cpu(req.wIndex); | ||
| 1957 | dir = num & USB_ENDPOINT_DIR_MASK; | ||
| 1958 | num &= USB_ENDPOINT_NUMBER_MASK; | ||
| 1959 | if (dir) /* TX */ | ||
| 1960 | num += hw_ep_max/2; | ||
| 1961 | if (!udc->ci13xxx_ep[num].wedge) { | ||
| 1962 | spin_unlock(udc->lock); | ||
| 1963 | err = usb_ep_clear_halt( | ||
| 1964 | &udc->ci13xxx_ep[num].ep); | ||
| 1965 | spin_lock(udc->lock); | ||
| 1966 | if (err) | ||
| 1967 | break; | ||
| 1968 | } | ||
| 1969 | err = isr_setup_status_phase(udc); | ||
| 1970 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) && | ||
| 1971 | le16_to_cpu(req.wValue) == | ||
| 1972 | USB_DEVICE_REMOTE_WAKEUP) { | ||
| 1973 | if (req.wLength != 0) | ||
| 1974 | break; | ||
| 1975 | udc->remote_wakeup = 0; | ||
| 1976 | err = isr_setup_status_phase(udc); | ||
| 1977 | } else { | ||
| 1978 | goto delegate; | ||
| 1979 | } | ||
| 1980 | break; | ||
| 1981 | case USB_REQ_GET_STATUS: | ||
| 1982 | if (type != (USB_DIR_IN|USB_RECIP_DEVICE) && | ||
| 1983 | type != (USB_DIR_IN|USB_RECIP_ENDPOINT) && | ||
| 1984 | type != (USB_DIR_IN|USB_RECIP_INTERFACE)) | ||
| 1985 | goto delegate; | ||
| 1986 | if (le16_to_cpu(req.wLength) != 2 || | ||
| 1987 | le16_to_cpu(req.wValue) != 0) | ||
| 1988 | break; | ||
| 1989 | err = isr_get_status_response(udc, &req); | ||
| 1990 | break; | ||
| 1991 | case USB_REQ_SET_ADDRESS: | ||
| 1992 | if (type != (USB_DIR_OUT|USB_RECIP_DEVICE)) | ||
| 1993 | goto delegate; | ||
| 1994 | if (le16_to_cpu(req.wLength) != 0 || | ||
| 1995 | le16_to_cpu(req.wIndex) != 0) | ||
| 1996 | break; | ||
| 1997 | err = hw_usb_set_address((u8)le16_to_cpu(req.wValue)); | ||
| 1998 | if (err) | ||
| 1999 | break; | ||
| 2000 | err = isr_setup_status_phase(udc); | ||
| 2001 | break; | ||
| 2002 | case USB_REQ_SET_FEATURE: | ||
| 2003 | if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) && | ||
| 2004 | le16_to_cpu(req.wValue) == | ||
| 2005 | USB_ENDPOINT_HALT) { | ||
| 2006 | if (req.wLength != 0) | ||
| 2007 | break; | ||
| 2008 | num = le16_to_cpu(req.wIndex); | ||
| 2009 | dir = num & USB_ENDPOINT_DIR_MASK; | ||
| 2010 | num &= USB_ENDPOINT_NUMBER_MASK; | ||
| 2011 | if (dir) /* TX */ | ||
| 2012 | num += hw_ep_max/2; | ||
| 2013 | |||
| 2014 | spin_unlock(udc->lock); | ||
| 2015 | err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); | ||
| 2016 | spin_lock(udc->lock); | ||
| 2017 | if (!err) | ||
| 2018 | isr_setup_status_phase(udc); | ||
| 2019 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) { | ||
| 2020 | if (req.wLength != 0) | ||
| 2021 | break; | ||
| 2022 | switch (le16_to_cpu(req.wValue)) { | ||
| 2023 | case USB_DEVICE_REMOTE_WAKEUP: | ||
| 2024 | udc->remote_wakeup = 1; | ||
| 2025 | err = isr_setup_status_phase(udc); | ||
| 2026 | break; | ||
| 2027 | case USB_DEVICE_TEST_MODE: | ||
| 2028 | tmode = le16_to_cpu(req.wIndex) >> 8; | ||
| 2029 | switch (tmode) { | ||
| 2030 | case TEST_J: | ||
| 2031 | case TEST_K: | ||
| 2032 | case TEST_SE0_NAK: | ||
| 2033 | case TEST_PACKET: | ||
| 2034 | case TEST_FORCE_EN: | ||
| 2035 | udc->test_mode = tmode; | ||
| 2036 | err = isr_setup_status_phase( | ||
| 2037 | udc); | ||
| 2038 | break; | ||
| 2039 | default: | ||
| 2040 | break; | ||
| 2041 | } | ||
| 2042 | default: | ||
| 2043 | goto delegate; | ||
| 2044 | } | ||
| 2045 | } else { | ||
| 2046 | goto delegate; | ||
| 2047 | } | ||
| 2048 | break; | ||
| 2049 | default: | ||
| 2050 | delegate: | ||
| 2051 | if (req.wLength == 0) /* no data phase */ | ||
| 2052 | udc->ep0_dir = TX; | ||
| 2053 | |||
| 2054 | spin_unlock(udc->lock); | ||
| 2055 | err = udc->driver->setup(&udc->gadget, &req); | ||
| 2056 | spin_lock(udc->lock); | ||
| 2057 | break; | ||
| 2058 | } | ||
| 2059 | |||
| 2060 | if (err < 0) { | ||
| 2061 | dbg_event(_usb_addr(mEp), "ERROR", err); | ||
| 2062 | |||
| 2063 | spin_unlock(udc->lock); | ||
| 2064 | if (usb_ep_set_halt(&mEp->ep)) | ||
| 2065 | err("error: ep_set_halt"); | ||
| 2066 | spin_lock(udc->lock); | ||
| 2067 | } | ||
| 2068 | } | ||
| 2069 | } | ||
| 2070 | |||
| 2071 | /****************************************************************************** | ||
| 2072 | * ENDPT block | ||
| 2073 | *****************************************************************************/ | ||
| 2074 | /** | ||
| 2075 | * ep_enable: configure endpoint, making it usable | ||
| 2076 | * | ||
| 2077 | * Check usb_ep_enable() at "usb_gadget.h" for details | ||
| 2078 | */ | ||
| 2079 | static int ep_enable(struct usb_ep *ep, | ||
| 2080 | const struct usb_endpoint_descriptor *desc) | ||
| 2081 | { | ||
| 2082 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
| 2083 | int retval = 0; | ||
| 2084 | unsigned long flags; | ||
| 2085 | |||
| 2086 | trace("%p, %p", ep, desc); | ||
| 2087 | |||
| 2088 | if (ep == NULL || desc == NULL) | ||
| 2089 | return -EINVAL; | ||
| 2090 | |||
| 2091 | spin_lock_irqsave(mEp->lock, flags); | ||
| 2092 | |||
| 2093 | /* only internal SW should enable ctrl endpts */ | ||
| 2094 | |||
| 2095 | mEp->desc = desc; | ||
| 2096 | |||
| 2097 | if (!list_empty(&mEp->qh.queue)) | ||
| 2098 | warn("enabling a non-empty endpoint!"); | ||
| 2099 | |||
| 2100 | mEp->dir = usb_endpoint_dir_in(desc) ? TX : RX; | ||
| 2101 | mEp->num = usb_endpoint_num(desc); | ||
| 2102 | mEp->type = usb_endpoint_type(desc); | ||
| 2103 | |||
| 2104 | mEp->ep.maxpacket = __constant_le16_to_cpu(desc->wMaxPacketSize); | ||
| 2105 | |||
| 2106 | dbg_event(_usb_addr(mEp), "ENABLE", 0); | ||
| 2107 | |||
| 2108 | mEp->qh.ptr->cap = 0; | ||
| 2109 | |||
| 2110 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | ||
| 2111 | mEp->qh.ptr->cap |= QH_IOS; | ||
| 2112 | else if (mEp->type == USB_ENDPOINT_XFER_ISOC) | ||
| 2113 | mEp->qh.ptr->cap &= ~QH_MULT; | ||
| 2114 | else | ||
| 2115 | mEp->qh.ptr->cap &= ~QH_ZLT; | ||
| 2116 | |||
| 2117 | mEp->qh.ptr->cap |= | ||
| 2118 | (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT; | ||
| 2119 | mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */ | ||
| 2120 | |||
| 2121 | /* | ||
| 2122 | * Enable endpoints in the HW other than ep0 as ep0 | ||
| 2123 | * is always enabled | ||
| 2124 | */ | ||
| 2125 | if (mEp->num) | ||
| 2126 | retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type); | ||
| 2127 | |||
| 2128 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2129 | return retval; | ||
| 2130 | } | ||
| 2131 | |||
| 2132 | /** | ||
| 2133 | * ep_disable: endpoint is no longer usable | ||
| 2134 | * | ||
| 2135 | * Check usb_ep_disable() at "usb_gadget.h" for details | ||
| 2136 | */ | ||
| 2137 | static int ep_disable(struct usb_ep *ep) | ||
| 2138 | { | ||
| 2139 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
| 2140 | int direction, retval = 0; | ||
| 2141 | unsigned long flags; | ||
| 2142 | |||
| 2143 | trace("%p", ep); | ||
| 2144 | |||
| 2145 | if (ep == NULL) | ||
| 2146 | return -EINVAL; | ||
| 2147 | else if (mEp->desc == NULL) | ||
| 2148 | return -EBUSY; | ||
| 2149 | |||
| 2150 | spin_lock_irqsave(mEp->lock, flags); | ||
| 2151 | |||
| 2152 | /* only internal SW should disable ctrl endpts */ | ||
| 2153 | |||
| 2154 | direction = mEp->dir; | ||
| 2155 | do { | ||
| 2156 | dbg_event(_usb_addr(mEp), "DISABLE", 0); | ||
| 2157 | |||
| 2158 | retval |= _ep_nuke(mEp); | ||
| 2159 | retval |= hw_ep_disable(mEp->num, mEp->dir); | ||
| 2160 | |||
| 2161 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | ||
| 2162 | mEp->dir = (mEp->dir == TX) ? RX : TX; | ||
| 2163 | |||
| 2164 | } while (mEp->dir != direction); | ||
| 2165 | |||
| 2166 | mEp->desc = NULL; | ||
| 2167 | |||
| 2168 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2169 | return retval; | ||
| 2170 | } | ||
| 2171 | |||
| 2172 | /** | ||
| 2173 | * ep_alloc_request: allocate a request object to use with this endpoint | ||
| 2174 | * | ||
| 2175 | * Check usb_ep_alloc_request() at "usb_gadget.h" for details | ||
| 2176 | */ | ||
| 2177 | static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) | ||
| 2178 | { | ||
| 2179 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
| 2180 | struct ci13xxx_req *mReq = NULL; | ||
| 2181 | |||
| 2182 | trace("%p, %i", ep, gfp_flags); | ||
| 2183 | |||
| 2184 | if (ep == NULL) { | ||
| 2185 | err("EINVAL"); | ||
| 2186 | return NULL; | ||
| 2187 | } | ||
| 2188 | |||
| 2189 | mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); | ||
| 2190 | if (mReq != NULL) { | ||
| 2191 | INIT_LIST_HEAD(&mReq->queue); | ||
| 2192 | |||
| 2193 | mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags, | ||
| 2194 | &mReq->dma); | ||
| 2195 | if (mReq->ptr == NULL) { | ||
| 2196 | kfree(mReq); | ||
| 2197 | mReq = NULL; | ||
| 2198 | } | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL); | ||
| 2202 | |||
| 2203 | return (mReq == NULL) ? NULL : &mReq->req; | ||
| 2204 | } | ||
| 2205 | |||
| 2206 | /** | ||
| 2207 | * ep_free_request: frees a request object | ||
| 2208 | * | ||
| 2209 | * Check usb_ep_free_request() at "usb_gadget.h" for details | ||
| 2210 | */ | ||
| 2211 | static void ep_free_request(struct usb_ep *ep, struct usb_request *req) | ||
| 2212 | { | ||
| 2213 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
| 2214 | struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); | ||
| 2215 | unsigned long flags; | ||
| 2216 | |||
| 2217 | trace("%p, %p", ep, req); | ||
| 2218 | |||
| 2219 | if (ep == NULL || req == NULL) { | ||
| 2220 | err("EINVAL"); | ||
| 2221 | return; | ||
| 2222 | } else if (!list_empty(&mReq->queue)) { | ||
| 2223 | err("EBUSY"); | ||
| 2224 | return; | ||
| 2225 | } | ||
| 2226 | |||
| 2227 | spin_lock_irqsave(mEp->lock, flags); | ||
| 2228 | |||
| 2229 | if (mReq->ptr) | ||
| 2230 | dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma); | ||
| 2231 | kfree(mReq); | ||
| 2232 | |||
| 2233 | dbg_event(_usb_addr(mEp), "FREE", 0); | ||
| 2234 | |||
| 2235 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2236 | } | ||
| 2237 | |||
| 2238 | /** | ||
| 2239 | * ep_queue: queues (submits) an I/O request to an endpoint | ||
| 2240 | * | ||
| 2241 | * Check usb_ep_queue()* at usb_gadget.h" for details | ||
| 2242 | */ | ||
| 2243 | static int ep_queue(struct usb_ep *ep, struct usb_request *req, | ||
| 2244 | gfp_t __maybe_unused gfp_flags) | ||
| 2245 | { | ||
| 2246 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
| 2247 | struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); | ||
| 2248 | int retval = 0; | ||
| 2249 | unsigned long flags; | ||
| 2250 | |||
| 2251 | trace("%p, %p, %X", ep, req, gfp_flags); | ||
| 2252 | |||
| 2253 | if (ep == NULL || req == NULL || mEp->desc == NULL) | ||
| 2254 | return -EINVAL; | ||
| 2255 | |||
| 2256 | spin_lock_irqsave(mEp->lock, flags); | ||
| 2257 | |||
| 2258 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { | ||
| 2259 | if (req->length) | ||
| 2260 | mEp = (_udc->ep0_dir == RX) ? | ||
| 2261 | &_udc->ep0out : &_udc->ep0in; | ||
| 2262 | if (!list_empty(&mEp->qh.queue)) { | ||
| 2263 | _ep_nuke(mEp); | ||
| 2264 | retval = -EOVERFLOW; | ||
| 2265 | warn("endpoint ctrl %X nuked", _usb_addr(mEp)); | ||
| 2266 | } | ||
| 2267 | } | ||
| 2268 | |||
| 2269 | /* first nuke then test link, e.g. previous status has not sent */ | ||
| 2270 | if (!list_empty(&mReq->queue)) { | ||
| 2271 | retval = -EBUSY; | ||
| 2272 | err("request already in queue"); | ||
| 2273 | goto done; | ||
| 2274 | } | ||
| 2275 | |||
| 2276 | if (req->length > (4 * CI13XXX_PAGE_SIZE)) { | ||
| 2277 | req->length = (4 * CI13XXX_PAGE_SIZE); | ||
| 2278 | retval = -EMSGSIZE; | ||
| 2279 | warn("request length truncated"); | ||
| 2280 | } | ||
| 2281 | |||
| 2282 | dbg_queue(_usb_addr(mEp), req, retval); | ||
| 2283 | |||
| 2284 | /* push request */ | ||
| 2285 | mReq->req.status = -EINPROGRESS; | ||
| 2286 | mReq->req.actual = 0; | ||
| 2287 | |||
| 2288 | retval = _hardware_enqueue(mEp, mReq); | ||
| 2289 | |||
| 2290 | if (retval == -EALREADY) { | ||
| 2291 | dbg_event(_usb_addr(mEp), "QUEUE", retval); | ||
| 2292 | retval = 0; | ||
| 2293 | } | ||
| 2294 | if (!retval) | ||
| 2295 | list_add_tail(&mReq->queue, &mEp->qh.queue); | ||
| 2296 | |||
| 2297 | done: | ||
| 2298 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2299 | return retval; | ||
| 2300 | } | ||
| 2301 | |||
| 2302 | /** | ||
| 2303 | * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint | ||
| 2304 | * | ||
| 2305 | * Check usb_ep_dequeue() at "usb_gadget.h" for details | ||
| 2306 | */ | ||
| 2307 | static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) | ||
| 2308 | { | ||
| 2309 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
| 2310 | struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); | ||
| 2311 | unsigned long flags; | ||
| 2312 | |||
| 2313 | trace("%p, %p", ep, req); | ||
| 2314 | |||
| 2315 | if (ep == NULL || req == NULL || mReq->req.status != -EALREADY || | ||
| 2316 | mEp->desc == NULL || list_empty(&mReq->queue) || | ||
| 2317 | list_empty(&mEp->qh.queue)) | ||
| 2318 | return -EINVAL; | ||
| 2319 | |||
| 2320 | spin_lock_irqsave(mEp->lock, flags); | ||
| 2321 | |||
| 2322 | dbg_event(_usb_addr(mEp), "DEQUEUE", 0); | ||
| 2323 | |||
| 2324 | hw_ep_flush(mEp->num, mEp->dir); | ||
| 2325 | |||
| 2326 | /* pop request */ | ||
| 2327 | list_del_init(&mReq->queue); | ||
| 2328 | if (mReq->map) { | ||
| 2329 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, | ||
| 2330 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 2331 | mReq->req.dma = 0; | ||
| 2332 | mReq->map = 0; | ||
| 2333 | } | ||
| 2334 | req->status = -ECONNRESET; | ||
| 2335 | |||
| 2336 | if (mReq->req.complete != NULL) { | ||
| 2337 | spin_unlock(mEp->lock); | ||
| 2338 | mReq->req.complete(&mEp->ep, &mReq->req); | ||
| 2339 | spin_lock(mEp->lock); | ||
| 2340 | } | ||
| 2341 | |||
| 2342 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2343 | return 0; | ||
| 2344 | } | ||
| 2345 | |||
| 2346 | /** | ||
| 2347 | * ep_set_halt: sets the endpoint halt feature | ||
| 2348 | * | ||
| 2349 | * Check usb_ep_set_halt() at "usb_gadget.h" for details | ||
| 2350 | */ | ||
| 2351 | static int ep_set_halt(struct usb_ep *ep, int value) | ||
| 2352 | { | ||
| 2353 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
| 2354 | int direction, retval = 0; | ||
| 2355 | unsigned long flags; | ||
| 2356 | |||
| 2357 | trace("%p, %i", ep, value); | ||
| 2358 | |||
| 2359 | if (ep == NULL || mEp->desc == NULL) | ||
| 2360 | return -EINVAL; | ||
| 2361 | |||
| 2362 | spin_lock_irqsave(mEp->lock, flags); | ||
| 2363 | |||
| 2364 | #ifndef STALL_IN | ||
| 2365 | /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */ | ||
| 2366 | if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX && | ||
| 2367 | !list_empty(&mEp->qh.queue)) { | ||
| 2368 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2369 | return -EAGAIN; | ||
| 2370 | } | ||
| 2371 | #endif | ||
| 2372 | |||
| 2373 | direction = mEp->dir; | ||
| 2374 | do { | ||
| 2375 | dbg_event(_usb_addr(mEp), "HALT", value); | ||
| 2376 | retval |= hw_ep_set_halt(mEp->num, mEp->dir, value); | ||
| 2377 | |||
| 2378 | if (!value) | ||
| 2379 | mEp->wedge = 0; | ||
| 2380 | |||
| 2381 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | ||
| 2382 | mEp->dir = (mEp->dir == TX) ? RX : TX; | ||
| 2383 | |||
| 2384 | } while (mEp->dir != direction); | ||
| 2385 | |||
| 2386 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2387 | return retval; | ||
| 2388 | } | ||
| 2389 | |||
| 2390 | /** | ||
| 2391 | * ep_set_wedge: sets the halt feature and ignores clear requests | ||
| 2392 | * | ||
| 2393 | * Check usb_ep_set_wedge() at "usb_gadget.h" for details | ||
| 2394 | */ | ||
| 2395 | static int ep_set_wedge(struct usb_ep *ep) | ||
| 2396 | { | ||
| 2397 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
| 2398 | unsigned long flags; | ||
| 2399 | |||
| 2400 | trace("%p", ep); | ||
| 2401 | |||
| 2402 | if (ep == NULL || mEp->desc == NULL) | ||
| 2403 | return -EINVAL; | ||
| 2404 | |||
| 2405 | spin_lock_irqsave(mEp->lock, flags); | ||
| 2406 | |||
| 2407 | dbg_event(_usb_addr(mEp), "WEDGE", 0); | ||
| 2408 | mEp->wedge = 1; | ||
| 2409 | |||
| 2410 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2411 | |||
| 2412 | return usb_ep_set_halt(ep); | ||
| 2413 | } | ||
| 2414 | |||
| 2415 | /** | ||
| 2416 | * ep_fifo_flush: flushes contents of a fifo | ||
| 2417 | * | ||
| 2418 | * Check usb_ep_fifo_flush() at "usb_gadget.h" for details | ||
| 2419 | */ | ||
| 2420 | static void ep_fifo_flush(struct usb_ep *ep) | ||
| 2421 | { | ||
| 2422 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
| 2423 | unsigned long flags; | ||
| 2424 | |||
| 2425 | trace("%p", ep); | ||
| 2426 | |||
| 2427 | if (ep == NULL) { | ||
| 2428 | err("%02X: -EINVAL", _usb_addr(mEp)); | ||
| 2429 | return; | ||
| 2430 | } | ||
| 2431 | |||
| 2432 | spin_lock_irqsave(mEp->lock, flags); | ||
| 2433 | |||
| 2434 | dbg_event(_usb_addr(mEp), "FFLUSH", 0); | ||
| 2435 | hw_ep_flush(mEp->num, mEp->dir); | ||
| 2436 | |||
| 2437 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2438 | } | ||
| 2439 | |||
| 2440 | /** | ||
| 2441 | * Endpoint-specific part of the API to the USB controller hardware | ||
| 2442 | * Check "usb_gadget.h" for details | ||
| 2443 | */ | ||
| 2444 | static const struct usb_ep_ops usb_ep_ops = { | ||
| 2445 | .enable = ep_enable, | ||
| 2446 | .disable = ep_disable, | ||
| 2447 | .alloc_request = ep_alloc_request, | ||
| 2448 | .free_request = ep_free_request, | ||
| 2449 | .queue = ep_queue, | ||
| 2450 | .dequeue = ep_dequeue, | ||
| 2451 | .set_halt = ep_set_halt, | ||
| 2452 | .set_wedge = ep_set_wedge, | ||
| 2453 | .fifo_flush = ep_fifo_flush, | ||
| 2454 | }; | ||
| 2455 | |||
| 2456 | /****************************************************************************** | ||
| 2457 | * GADGET block | ||
| 2458 | *****************************************************************************/ | ||
| 2459 | static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) | ||
| 2460 | { | ||
| 2461 | struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); | ||
| 2462 | unsigned long flags; | ||
| 2463 | int gadget_ready = 0; | ||
| 2464 | |||
| 2465 | if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS)) | ||
| 2466 | return -EOPNOTSUPP; | ||
| 2467 | |||
| 2468 | spin_lock_irqsave(udc->lock, flags); | ||
| 2469 | udc->vbus_active = is_active; | ||
| 2470 | if (udc->driver) | ||
| 2471 | gadget_ready = 1; | ||
| 2472 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2473 | |||
| 2474 | if (gadget_ready) { | ||
| 2475 | if (is_active) { | ||
| 2476 | pm_runtime_get_sync(&_gadget->dev); | ||
| 2477 | hw_device_reset(udc); | ||
| 2478 | hw_device_state(udc->ep0out.qh.dma); | ||
| 2479 | } else { | ||
| 2480 | hw_device_state(0); | ||
| 2481 | if (udc->udc_driver->notify_event) | ||
| 2482 | udc->udc_driver->notify_event(udc, | ||
| 2483 | CI13XXX_CONTROLLER_STOPPED_EVENT); | ||
| 2484 | _gadget_stop_activity(&udc->gadget); | ||
| 2485 | pm_runtime_put_sync(&_gadget->dev); | ||
| 2486 | } | ||
| 2487 | } | ||
| 2488 | |||
| 2489 | return 0; | ||
| 2490 | } | ||
| 2491 | |||
| 2492 | static int ci13xxx_wakeup(struct usb_gadget *_gadget) | ||
| 2493 | { | ||
| 2494 | struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); | ||
| 2495 | unsigned long flags; | ||
| 2496 | int ret = 0; | ||
| 2497 | |||
| 2498 | trace(); | ||
| 2499 | |||
| 2500 | spin_lock_irqsave(udc->lock, flags); | ||
| 2501 | if (!udc->remote_wakeup) { | ||
| 2502 | ret = -EOPNOTSUPP; | ||
| 2503 | dbg_trace("remote wakeup feature is not enabled\n"); | ||
| 2504 | goto out; | ||
| 2505 | } | ||
| 2506 | if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) { | ||
| 2507 | ret = -EINVAL; | ||
| 2508 | dbg_trace("port is not suspended\n"); | ||
| 2509 | goto out; | ||
| 2510 | } | ||
| 2511 | hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR); | ||
| 2512 | out: | ||
| 2513 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2514 | return ret; | ||
| 2515 | } | ||
| 2516 | |||
| 2517 | static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | ||
| 2518 | { | ||
| 2519 | struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); | ||
| 2520 | |||
| 2521 | if (udc->transceiver) | ||
| 2522 | return otg_set_power(udc->transceiver, mA); | ||
| 2523 | return -ENOTSUPP; | ||
| 2524 | } | ||
| 2525 | |||
| 2526 | static int ci13xxx_start(struct usb_gadget_driver *driver, | ||
| 2527 | int (*bind)(struct usb_gadget *)); | ||
| 2528 | static int ci13xxx_stop(struct usb_gadget_driver *driver); | ||
| 2529 | /** | ||
| 2530 | * Device operations part of the API to the USB controller hardware, | ||
| 2531 | * which don't involve endpoints (or i/o) | ||
| 2532 | * Check "usb_gadget.h" for details | ||
| 2533 | */ | ||
| 2534 | static const struct usb_gadget_ops usb_gadget_ops = { | ||
| 2535 | .vbus_session = ci13xxx_vbus_session, | ||
| 2536 | .wakeup = ci13xxx_wakeup, | ||
| 2537 | .vbus_draw = ci13xxx_vbus_draw, | ||
| 2538 | .start = ci13xxx_start, | ||
| 2539 | .stop = ci13xxx_stop, | ||
| 2540 | }; | ||
| 2541 | |||
| 2542 | /** | ||
| 2543 | * ci13xxx_start: register a gadget driver | ||
| 2544 | * @driver: the driver being registered | ||
| 2545 | * @bind: the driver's bind callback | ||
| 2546 | * | ||
| 2547 | * Check ci13xxx_start() at <linux/usb/gadget.h> for details. | ||
| 2548 | * Interrupts are enabled here. | ||
| 2549 | */ | ||
| 2550 | static int ci13xxx_start(struct usb_gadget_driver *driver, | ||
| 2551 | int (*bind)(struct usb_gadget *)) | ||
| 2552 | { | ||
| 2553 | struct ci13xxx *udc = _udc; | ||
| 2554 | unsigned long flags; | ||
| 2555 | int i, j; | ||
| 2556 | int retval = -ENOMEM; | ||
| 2557 | |||
| 2558 | trace("%p", driver); | ||
| 2559 | |||
| 2560 | if (driver == NULL || | ||
| 2561 | bind == NULL || | ||
| 2562 | driver->setup == NULL || | ||
| 2563 | driver->disconnect == NULL || | ||
| 2564 | driver->suspend == NULL || | ||
| 2565 | driver->resume == NULL) | ||
| 2566 | return -EINVAL; | ||
| 2567 | else if (udc == NULL) | ||
| 2568 | return -ENODEV; | ||
| 2569 | else if (udc->driver != NULL) | ||
| 2570 | return -EBUSY; | ||
| 2571 | |||
| 2572 | /* alloc resources */ | ||
| 2573 | udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev, | ||
| 2574 | sizeof(struct ci13xxx_qh), | ||
| 2575 | 64, CI13XXX_PAGE_SIZE); | ||
| 2576 | if (udc->qh_pool == NULL) | ||
| 2577 | return -ENOMEM; | ||
| 2578 | |||
| 2579 | udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev, | ||
| 2580 | sizeof(struct ci13xxx_td), | ||
| 2581 | 64, CI13XXX_PAGE_SIZE); | ||
| 2582 | if (udc->td_pool == NULL) { | ||
| 2583 | dma_pool_destroy(udc->qh_pool); | ||
| 2584 | udc->qh_pool = NULL; | ||
| 2585 | return -ENOMEM; | ||
| 2586 | } | ||
| 2587 | |||
| 2588 | spin_lock_irqsave(udc->lock, flags); | ||
| 2589 | |||
| 2590 | info("hw_ep_max = %d", hw_ep_max); | ||
| 2591 | |||
| 2592 | udc->gadget.dev.driver = NULL; | ||
| 2593 | |||
| 2594 | retval = 0; | ||
| 2595 | for (i = 0; i < hw_ep_max/2; i++) { | ||
| 2596 | for (j = RX; j <= TX; j++) { | ||
| 2597 | int k = i + j * hw_ep_max/2; | ||
| 2598 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k]; | ||
| 2599 | |||
| 2600 | scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i, | ||
| 2601 | (j == TX) ? "in" : "out"); | ||
| 2602 | |||
| 2603 | mEp->lock = udc->lock; | ||
| 2604 | mEp->device = &udc->gadget.dev; | ||
| 2605 | mEp->td_pool = udc->td_pool; | ||
| 2606 | |||
| 2607 | mEp->ep.name = mEp->name; | ||
| 2608 | mEp->ep.ops = &usb_ep_ops; | ||
| 2609 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | ||
| 2610 | |||
| 2611 | INIT_LIST_HEAD(&mEp->qh.queue); | ||
| 2612 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2613 | mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL, | ||
| 2614 | &mEp->qh.dma); | ||
| 2615 | spin_lock_irqsave(udc->lock, flags); | ||
| 2616 | if (mEp->qh.ptr == NULL) | ||
| 2617 | retval = -ENOMEM; | ||
| 2618 | else | ||
| 2619 | memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr)); | ||
| 2620 | |||
| 2621 | /* skip ep0 out and in endpoints */ | ||
| 2622 | if (i == 0) | ||
| 2623 | continue; | ||
| 2624 | |||
| 2625 | list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list); | ||
| 2626 | } | ||
| 2627 | } | ||
| 2628 | if (retval) | ||
| 2629 | goto done; | ||
| 2630 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2631 | udc->ep0out.ep.desc = &ctrl_endpt_out_desc; | ||
| 2632 | retval = usb_ep_enable(&udc->ep0out.ep); | ||
| 2633 | if (retval) | ||
| 2634 | return retval; | ||
| 2635 | |||
| 2636 | udc->ep0in.ep.desc = &ctrl_endpt_in_desc; | ||
| 2637 | retval = usb_ep_enable(&udc->ep0in.ep); | ||
| 2638 | if (retval) | ||
| 2639 | return retval; | ||
| 2640 | spin_lock_irqsave(udc->lock, flags); | ||
| 2641 | |||
| 2642 | udc->gadget.ep0 = &udc->ep0in.ep; | ||
| 2643 | /* bind gadget */ | ||
| 2644 | driver->driver.bus = NULL; | ||
| 2645 | udc->gadget.dev.driver = &driver->driver; | ||
| 2646 | |||
| 2647 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2648 | retval = bind(&udc->gadget); /* MAY SLEEP */ | ||
| 2649 | spin_lock_irqsave(udc->lock, flags); | ||
| 2650 | |||
| 2651 | if (retval) { | ||
| 2652 | udc->gadget.dev.driver = NULL; | ||
| 2653 | goto done; | ||
| 2654 | } | ||
| 2655 | |||
| 2656 | udc->driver = driver; | ||
| 2657 | pm_runtime_get_sync(&udc->gadget.dev); | ||
| 2658 | if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) { | ||
| 2659 | if (udc->vbus_active) { | ||
| 2660 | if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) | ||
| 2661 | hw_device_reset(udc); | ||
| 2662 | } else { | ||
| 2663 | pm_runtime_put_sync(&udc->gadget.dev); | ||
| 2664 | goto done; | ||
| 2665 | } | ||
| 2666 | } | ||
| 2667 | |||
| 2668 | retval = hw_device_state(udc->ep0out.qh.dma); | ||
| 2669 | if (retval) | ||
| 2670 | pm_runtime_put_sync(&udc->gadget.dev); | ||
| 2671 | |||
| 2672 | done: | ||
| 2673 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2674 | return retval; | ||
| 2675 | } | ||
| 2676 | |||
| 2677 | /** | ||
| 2678 | * ci13xxx_stop: unregister a gadget driver | ||
| 2679 | * | ||
| 2680 | * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details | ||
| 2681 | */ | ||
| 2682 | static int ci13xxx_stop(struct usb_gadget_driver *driver) | ||
| 2683 | { | ||
| 2684 | struct ci13xxx *udc = _udc; | ||
| 2685 | unsigned long i, flags; | ||
| 2686 | |||
| 2687 | trace("%p", driver); | ||
| 2688 | |||
| 2689 | if (driver == NULL || | ||
| 2690 | driver->unbind == NULL || | ||
| 2691 | driver->setup == NULL || | ||
| 2692 | driver->disconnect == NULL || | ||
| 2693 | driver->suspend == NULL || | ||
| 2694 | driver->resume == NULL || | ||
| 2695 | driver != udc->driver) | ||
| 2696 | return -EINVAL; | ||
| 2697 | |||
| 2698 | spin_lock_irqsave(udc->lock, flags); | ||
| 2699 | |||
| 2700 | if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) || | ||
| 2701 | udc->vbus_active) { | ||
| 2702 | hw_device_state(0); | ||
| 2703 | if (udc->udc_driver->notify_event) | ||
| 2704 | udc->udc_driver->notify_event(udc, | ||
| 2705 | CI13XXX_CONTROLLER_STOPPED_EVENT); | ||
| 2706 | _gadget_stop_activity(&udc->gadget); | ||
| 2707 | pm_runtime_put(&udc->gadget.dev); | ||
| 2708 | } | ||
| 2709 | |||
| 2710 | /* unbind gadget */ | ||
| 2711 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2712 | driver->unbind(&udc->gadget); /* MAY SLEEP */ | ||
| 2713 | spin_lock_irqsave(udc->lock, flags); | ||
| 2714 | |||
| 2715 | udc->gadget.dev.driver = NULL; | ||
| 2716 | |||
| 2717 | /* free resources */ | ||
| 2718 | for (i = 0; i < hw_ep_max; i++) { | ||
| 2719 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; | ||
| 2720 | |||
| 2721 | if (!list_empty(&mEp->ep.ep_list)) | ||
| 2722 | list_del_init(&mEp->ep.ep_list); | ||
| 2723 | |||
| 2724 | if (mEp->qh.ptr != NULL) | ||
| 2725 | dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma); | ||
| 2726 | } | ||
| 2727 | |||
| 2728 | udc->gadget.ep0 = NULL; | ||
| 2729 | udc->driver = NULL; | ||
| 2730 | |||
| 2731 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2732 | |||
| 2733 | if (udc->td_pool != NULL) { | ||
| 2734 | dma_pool_destroy(udc->td_pool); | ||
| 2735 | udc->td_pool = NULL; | ||
| 2736 | } | ||
| 2737 | if (udc->qh_pool != NULL) { | ||
| 2738 | dma_pool_destroy(udc->qh_pool); | ||
| 2739 | udc->qh_pool = NULL; | ||
| 2740 | } | ||
| 2741 | |||
| 2742 | return 0; | ||
| 2743 | } | ||
| 2744 | |||
| 2745 | /****************************************************************************** | ||
| 2746 | * BUS block | ||
| 2747 | *****************************************************************************/ | ||
| 2748 | /** | ||
| 2749 | * udc_irq: global interrupt handler | ||
| 2750 | * | ||
| 2751 | * This function returns IRQ_HANDLED if the IRQ has been handled | ||
| 2752 | * It locks access to registers | ||
| 2753 | */ | ||
| 2754 | static irqreturn_t udc_irq(void) | ||
| 2755 | { | ||
| 2756 | struct ci13xxx *udc = _udc; | ||
| 2757 | irqreturn_t retval; | ||
| 2758 | u32 intr; | ||
| 2759 | |||
| 2760 | trace(); | ||
| 2761 | |||
| 2762 | if (udc == NULL) { | ||
| 2763 | err("ENODEV"); | ||
| 2764 | return IRQ_HANDLED; | ||
| 2765 | } | ||
| 2766 | |||
| 2767 | spin_lock(udc->lock); | ||
| 2768 | |||
| 2769 | if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) { | ||
| 2770 | if (hw_cread(CAP_USBMODE, USBMODE_CM) != | ||
| 2771 | USBMODE_CM_DEVICE) { | ||
| 2772 | spin_unlock(udc->lock); | ||
| 2773 | return IRQ_NONE; | ||
| 2774 | } | ||
| 2775 | } | ||
| 2776 | intr = hw_test_and_clear_intr_active(); | ||
| 2777 | if (intr) { | ||
| 2778 | isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr; | ||
| 2779 | isr_statistics.hndl.idx &= ISR_MASK; | ||
| 2780 | isr_statistics.hndl.cnt++; | ||
| 2781 | |||
| 2782 | /* order defines priority - do NOT change it */ | ||
| 2783 | if (USBi_URI & intr) { | ||
| 2784 | isr_statistics.uri++; | ||
| 2785 | isr_reset_handler(udc); | ||
| 2786 | } | ||
| 2787 | if (USBi_PCI & intr) { | ||
| 2788 | isr_statistics.pci++; | ||
| 2789 | udc->gadget.speed = hw_port_is_high_speed() ? | ||
| 2790 | USB_SPEED_HIGH : USB_SPEED_FULL; | ||
| 2791 | if (udc->suspended) { | ||
| 2792 | spin_unlock(udc->lock); | ||
| 2793 | udc->driver->resume(&udc->gadget); | ||
| 2794 | spin_lock(udc->lock); | ||
| 2795 | udc->suspended = 0; | ||
| 2796 | } | ||
| 2797 | } | ||
| 2798 | if (USBi_UEI & intr) | ||
| 2799 | isr_statistics.uei++; | ||
| 2800 | if (USBi_UI & intr) { | ||
| 2801 | isr_statistics.ui++; | ||
| 2802 | isr_tr_complete_handler(udc); | ||
| 2803 | } | ||
| 2804 | if (USBi_SLI & intr) { | ||
| 2805 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) { | ||
| 2806 | udc->suspended = 1; | ||
| 2807 | spin_unlock(udc->lock); | ||
| 2808 | udc->driver->suspend(&udc->gadget); | ||
| 2809 | spin_lock(udc->lock); | ||
| 2810 | } | ||
| 2811 | isr_statistics.sli++; | ||
| 2812 | } | ||
| 2813 | retval = IRQ_HANDLED; | ||
| 2814 | } else { | ||
| 2815 | isr_statistics.none++; | ||
| 2816 | retval = IRQ_NONE; | ||
| 2817 | } | ||
| 2818 | spin_unlock(udc->lock); | ||
| 2819 | |||
| 2820 | return retval; | ||
| 2821 | } | ||
| 2822 | |||
| 2823 | /** | ||
| 2824 | * udc_release: driver release function | ||
| 2825 | * @dev: device | ||
| 2826 | * | ||
| 2827 | * Currently does nothing | ||
| 2828 | */ | ||
| 2829 | static void udc_release(struct device *dev) | ||
| 2830 | { | ||
| 2831 | trace("%p", dev); | ||
| 2832 | |||
| 2833 | if (dev == NULL) | ||
| 2834 | err("EINVAL"); | ||
| 2835 | } | ||
| 2836 | |||
| 2837 | /** | ||
| 2838 | * udc_probe: parent probe must call this to initialize UDC | ||
| 2839 | * @dev: parent device | ||
| 2840 | * @regs: registers base address | ||
| 2841 | * @name: driver name | ||
| 2842 | * | ||
| 2843 | * This function returns an error code | ||
| 2844 | * No interrupts active, the IRQ has not been requested yet | ||
| 2845 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask | ||
| 2846 | */ | ||
| 2847 | static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | ||
| 2848 | void __iomem *regs) | ||
| 2849 | { | ||
| 2850 | struct ci13xxx *udc; | ||
| 2851 | int retval = 0; | ||
| 2852 | |||
| 2853 | trace("%p, %p, %p", dev, regs, name); | ||
| 2854 | |||
| 2855 | if (dev == NULL || regs == NULL || driver == NULL || | ||
| 2856 | driver->name == NULL) | ||
| 2857 | return -EINVAL; | ||
| 2858 | |||
| 2859 | udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL); | ||
| 2860 | if (udc == NULL) | ||
| 2861 | return -ENOMEM; | ||
| 2862 | |||
| 2863 | udc->lock = &udc_lock; | ||
| 2864 | udc->regs = regs; | ||
| 2865 | udc->udc_driver = driver; | ||
| 2866 | |||
| 2867 | udc->gadget.ops = &usb_gadget_ops; | ||
| 2868 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 2869 | udc->gadget.is_dualspeed = 1; | ||
| 2870 | udc->gadget.is_otg = 0; | ||
| 2871 | udc->gadget.name = driver->name; | ||
| 2872 | |||
| 2873 | INIT_LIST_HEAD(&udc->gadget.ep_list); | ||
| 2874 | udc->gadget.ep0 = NULL; | ||
| 2875 | |||
| 2876 | dev_set_name(&udc->gadget.dev, "gadget"); | ||
| 2877 | udc->gadget.dev.dma_mask = dev->dma_mask; | ||
| 2878 | udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask; | ||
| 2879 | udc->gadget.dev.parent = dev; | ||
| 2880 | udc->gadget.dev.release = udc_release; | ||
| 2881 | |||
| 2882 | retval = hw_device_init(regs); | ||
| 2883 | if (retval < 0) | ||
| 2884 | goto free_udc; | ||
| 2885 | |||
| 2886 | udc->transceiver = otg_get_transceiver(); | ||
| 2887 | |||
| 2888 | if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) { | ||
| 2889 | if (udc->transceiver == NULL) { | ||
| 2890 | retval = -ENODEV; | ||
| 2891 | goto free_udc; | ||
| 2892 | } | ||
| 2893 | } | ||
| 2894 | |||
| 2895 | if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) { | ||
| 2896 | retval = hw_device_reset(udc); | ||
| 2897 | if (retval) | ||
| 2898 | goto put_transceiver; | ||
| 2899 | } | ||
| 2900 | |||
| 2901 | retval = device_register(&udc->gadget.dev); | ||
| 2902 | if (retval) { | ||
| 2903 | put_device(&udc->gadget.dev); | ||
| 2904 | goto put_transceiver; | ||
| 2905 | } | ||
| 2906 | |||
| 2907 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
| 2908 | retval = dbg_create_files(&udc->gadget.dev); | ||
| 2909 | #endif | ||
| 2910 | if (retval) | ||
| 2911 | goto unreg_device; | ||
| 2912 | |||
| 2913 | if (udc->transceiver) { | ||
| 2914 | retval = otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
| 2915 | if (retval) | ||
| 2916 | goto remove_dbg; | ||
| 2917 | } | ||
| 2918 | |||
| 2919 | retval = usb_add_gadget_udc(dev, &udc->gadget); | ||
| 2920 | if (retval) | ||
| 2921 | goto remove_trans; | ||
| 2922 | |||
| 2923 | pm_runtime_no_callbacks(&udc->gadget.dev); | ||
| 2924 | pm_runtime_enable(&udc->gadget.dev); | ||
| 2925 | |||
| 2926 | _udc = udc; | ||
| 2927 | return retval; | ||
| 2928 | |||
| 2929 | remove_trans: | ||
| 2930 | if (udc->transceiver) { | ||
| 2931 | otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
| 2932 | otg_put_transceiver(udc->transceiver); | ||
| 2933 | } | ||
| 2934 | |||
| 2935 | err("error = %i", retval); | ||
| 2936 | remove_dbg: | ||
| 2937 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
| 2938 | dbg_remove_files(&udc->gadget.dev); | ||
| 2939 | #endif | ||
| 2940 | unreg_device: | ||
| 2941 | device_unregister(&udc->gadget.dev); | ||
| 2942 | put_transceiver: | ||
| 2943 | if (udc->transceiver) | ||
| 2944 | otg_put_transceiver(udc->transceiver); | ||
| 2945 | free_udc: | ||
| 2946 | kfree(udc); | ||
| 2947 | _udc = NULL; | ||
| 2948 | return retval; | ||
| 2949 | } | ||
| 2950 | |||
| 2951 | /** | ||
| 2952 | * udc_remove: parent remove must call this to remove UDC | ||
| 2953 | * | ||
| 2954 | * No interrupts active, the IRQ has been released | ||
| 2955 | */ | ||
| 2956 | static void udc_remove(void) | ||
| 2957 | { | ||
| 2958 | struct ci13xxx *udc = _udc; | ||
| 2959 | |||
| 2960 | if (udc == NULL) { | ||
| 2961 | err("EINVAL"); | ||
| 2962 | return; | ||
| 2963 | } | ||
| 2964 | usb_del_gadget_udc(&udc->gadget); | ||
| 2965 | |||
| 2966 | if (udc->transceiver) { | ||
| 2967 | otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
| 2968 | otg_put_transceiver(udc->transceiver); | ||
| 2969 | } | ||
| 2970 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
| 2971 | dbg_remove_files(&udc->gadget.dev); | ||
| 2972 | #endif | ||
| 2973 | device_unregister(&udc->gadget.dev); | ||
| 2974 | |||
| 2975 | kfree(udc); | ||
| 2976 | _udc = NULL; | ||
| 2977 | } | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h new file mode 100644 index 00000000000..23707775cb4 --- /dev/null +++ b/drivers/usb/gadget/ci13xxx_udc.h | |||
| @@ -0,0 +1,227 @@ | |||
| 1 | /* | ||
| 2 | * ci13xxx_udc.h - structures, registers, and macros MIPS USB IP core | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved. | ||
| 5 | * | ||
| 6 | * Author: David Lopo | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * Description: MIPS USB IP core family device controller | ||
| 13 | * Structures, registers and logging macros | ||
| 14 | */ | ||
| 15 | |||
| 16 | #ifndef _CI13XXX_h_ | ||
| 17 | #define _CI13XXX_h_ | ||
| 18 | |||
| 19 | /****************************************************************************** | ||
| 20 | * DEFINE | ||
| 21 | *****************************************************************************/ | ||
| 22 | #define CI13XXX_PAGE_SIZE 4096ul /* page size for TD's */ | ||
| 23 | #define ENDPT_MAX (32) | ||
| 24 | #define CTRL_PAYLOAD_MAX (64) | ||
| 25 | #define RX (0) /* similar to USB_DIR_OUT but can be used as an index */ | ||
| 26 | #define TX (1) /* similar to USB_DIR_IN but can be used as an index */ | ||
| 27 | |||
| 28 | /****************************************************************************** | ||
| 29 | * STRUCTURES | ||
| 30 | *****************************************************************************/ | ||
| 31 | /* DMA layout of transfer descriptors */ | ||
| 32 | struct ci13xxx_td { | ||
| 33 | /* 0 */ | ||
| 34 | u32 next; | ||
| 35 | #define TD_TERMINATE BIT(0) | ||
| 36 | #define TD_ADDR_MASK (0xFFFFFFEUL << 5) | ||
| 37 | /* 1 */ | ||
| 38 | u32 token; | ||
| 39 | #define TD_STATUS (0x00FFUL << 0) | ||
| 40 | #define TD_STATUS_TR_ERR BIT(3) | ||
| 41 | #define TD_STATUS_DT_ERR BIT(5) | ||
| 42 | #define TD_STATUS_HALTED BIT(6) | ||
| 43 | #define TD_STATUS_ACTIVE BIT(7) | ||
| 44 | #define TD_MULTO (0x0003UL << 10) | ||
| 45 | #define TD_IOC BIT(15) | ||
| 46 | #define TD_TOTAL_BYTES (0x7FFFUL << 16) | ||
| 47 | /* 2 */ | ||
| 48 | u32 page[5]; | ||
| 49 | #define TD_CURR_OFFSET (0x0FFFUL << 0) | ||
| 50 | #define TD_FRAME_NUM (0x07FFUL << 0) | ||
| 51 | #define TD_RESERVED_MASK (0x0FFFUL << 0) | ||
| 52 | } __attribute__ ((packed)); | ||
| 53 | |||
| 54 | /* DMA layout of queue heads */ | ||
| 55 | struct ci13xxx_qh { | ||
| 56 | /* 0 */ | ||
| 57 | u32 cap; | ||
| 58 | #define QH_IOS BIT(15) | ||
| 59 | #define QH_MAX_PKT (0x07FFUL << 16) | ||
| 60 | #define QH_ZLT BIT(29) | ||
| 61 | #define QH_MULT (0x0003UL << 30) | ||
| 62 | /* 1 */ | ||
| 63 | u32 curr; | ||
| 64 | /* 2 - 8 */ | ||
| 65 | struct ci13xxx_td td; | ||
| 66 | /* 9 */ | ||
| 67 | u32 RESERVED; | ||
| 68 | struct usb_ctrlrequest setup; | ||
| 69 | } __attribute__ ((packed)); | ||
| 70 | |||
| 71 | /* Extension of usb_request */ | ||
| 72 | struct ci13xxx_req { | ||
| 73 | struct usb_request req; | ||
| 74 | unsigned map; | ||
| 75 | struct list_head queue; | ||
| 76 | struct ci13xxx_td *ptr; | ||
| 77 | dma_addr_t dma; | ||
| 78 | struct ci13xxx_td *zptr; | ||
| 79 | dma_addr_t zdma; | ||
| 80 | }; | ||
| 81 | |||
| 82 | /* Extension of usb_ep */ | ||
| 83 | struct ci13xxx_ep { | ||
| 84 | struct usb_ep ep; | ||
| 85 | const struct usb_endpoint_descriptor *desc; | ||
| 86 | u8 dir; | ||
| 87 | u8 num; | ||
| 88 | u8 type; | ||
| 89 | char name[16]; | ||
| 90 | struct { | ||
| 91 | struct list_head queue; | ||
| 92 | struct ci13xxx_qh *ptr; | ||
| 93 | dma_addr_t dma; | ||
| 94 | } qh; | ||
| 95 | int wedge; | ||
| 96 | |||
| 97 | /* global resources */ | ||
| 98 | spinlock_t *lock; | ||
| 99 | struct device *device; | ||
| 100 | struct dma_pool *td_pool; | ||
| 101 | }; | ||
| 102 | |||
| 103 | struct ci13xxx; | ||
| 104 | struct ci13xxx_udc_driver { | ||
| 105 | const char *name; | ||
| 106 | unsigned long flags; | ||
| 107 | #define CI13XXX_REGS_SHARED BIT(0) | ||
| 108 | #define CI13XXX_REQUIRE_TRANSCEIVER BIT(1) | ||
| 109 | #define CI13XXX_PULLUP_ON_VBUS BIT(2) | ||
| 110 | #define CI13XXX_DISABLE_STREAMING BIT(3) | ||
| 111 | |||
| 112 | #define CI13XXX_CONTROLLER_RESET_EVENT 0 | ||
| 113 | #define CI13XXX_CONTROLLER_STOPPED_EVENT 1 | ||
| 114 | void (*notify_event) (struct ci13xxx *udc, unsigned event); | ||
| 115 | }; | ||
| 116 | |||
| 117 | /* CI13XXX UDC descriptor & global resources */ | ||
| 118 | struct ci13xxx { | ||
| 119 | spinlock_t *lock; /* ctrl register bank access */ | ||
| 120 | void __iomem *regs; /* registers address space */ | ||
| 121 | |||
| 122 | struct dma_pool *qh_pool; /* DMA pool for queue heads */ | ||
| 123 | struct dma_pool *td_pool; /* DMA pool for transfer descs */ | ||
| 124 | struct usb_request *status; /* ep0 status request */ | ||
| 125 | |||
| 126 | struct usb_gadget gadget; /* USB slave device */ | ||
| 127 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ | ||
| 128 | u32 ep0_dir; /* ep0 direction */ | ||
| 129 | #define ep0out ci13xxx_ep[0] | ||
| 130 | #define ep0in ci13xxx_ep[16] | ||
| 131 | u8 remote_wakeup; /* Is remote wakeup feature | ||
| 132 | enabled by the host? */ | ||
| 133 | u8 suspended; /* suspended by the host */ | ||
| 134 | u8 test_mode; /* the selected test mode */ | ||
| 135 | |||
| 136 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ | ||
| 137 | struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ | ||
| 138 | int vbus_active; /* is VBUS active */ | ||
| 139 | struct otg_transceiver *transceiver; /* Transceiver struct */ | ||
| 140 | }; | ||
| 141 | |||
| 142 | /****************************************************************************** | ||
| 143 | * REGISTERS | ||
| 144 | *****************************************************************************/ | ||
| 145 | /* register size */ | ||
| 146 | #define REG_BITS (32) | ||
| 147 | |||
| 148 | /* HCCPARAMS */ | ||
| 149 | #define HCCPARAMS_LEN BIT(17) | ||
| 150 | |||
| 151 | /* DCCPARAMS */ | ||
| 152 | #define DCCPARAMS_DEN (0x1F << 0) | ||
| 153 | #define DCCPARAMS_DC BIT(7) | ||
| 154 | |||
| 155 | /* TESTMODE */ | ||
| 156 | #define TESTMODE_FORCE BIT(0) | ||
| 157 | |||
| 158 | /* USBCMD */ | ||
| 159 | #define USBCMD_RS BIT(0) | ||
| 160 | #define USBCMD_RST BIT(1) | ||
| 161 | #define USBCMD_SUTW BIT(13) | ||
| 162 | #define USBCMD_ATDTW BIT(14) | ||
| 163 | |||
| 164 | /* USBSTS & USBINTR */ | ||
| 165 | #define USBi_UI BIT(0) | ||
| 166 | #define USBi_UEI BIT(1) | ||
| 167 | #define USBi_PCI BIT(2) | ||
| 168 | #define USBi_URI BIT(6) | ||
| 169 | #define USBi_SLI BIT(8) | ||
| 170 | |||
| 171 | /* DEVICEADDR */ | ||
| 172 | #define DEVICEADDR_USBADRA BIT(24) | ||
| 173 | #define DEVICEADDR_USBADR (0x7FUL << 25) | ||
| 174 | |||
| 175 | /* PORTSC */ | ||
| 176 | #define PORTSC_FPR BIT(6) | ||
| 177 | #define PORTSC_SUSP BIT(7) | ||
| 178 | #define PORTSC_HSP BIT(9) | ||
| 179 | #define PORTSC_PTC (0x0FUL << 16) | ||
| 180 | |||
| 181 | /* DEVLC */ | ||
| 182 | #define DEVLC_PSPD (0x03UL << 25) | ||
| 183 | #define DEVLC_PSPD_HS (0x02UL << 25) | ||
| 184 | |||
| 185 | /* USBMODE */ | ||
| 186 | #define USBMODE_CM (0x03UL << 0) | ||
| 187 | #define USBMODE_CM_IDLE (0x00UL << 0) | ||
| 188 | #define USBMODE_CM_DEVICE (0x02UL << 0) | ||
| 189 | #define USBMODE_CM_HOST (0x03UL << 0) | ||
| 190 | #define USBMODE_SLOM BIT(3) | ||
| 191 | #define USBMODE_SDIS BIT(4) | ||
| 192 | |||
| 193 | /* ENDPTCTRL */ | ||
| 194 | #define ENDPTCTRL_RXS BIT(0) | ||
| 195 | #define ENDPTCTRL_RXT (0x03UL << 2) | ||
| 196 | #define ENDPTCTRL_RXR BIT(6) /* reserved for port 0 */ | ||
| 197 | #define ENDPTCTRL_RXE BIT(7) | ||
| 198 | #define ENDPTCTRL_TXS BIT(16) | ||
| 199 | #define ENDPTCTRL_TXT (0x03UL << 18) | ||
| 200 | #define ENDPTCTRL_TXR BIT(22) /* reserved for port 0 */ | ||
| 201 | #define ENDPTCTRL_TXE BIT(23) | ||
| 202 | |||
| 203 | /****************************************************************************** | ||
| 204 | * LOGGING | ||
| 205 | *****************************************************************************/ | ||
| 206 | #define ci13xxx_printk(level, format, args...) \ | ||
| 207 | do { \ | ||
| 208 | if (_udc == NULL) \ | ||
| 209 | printk(level "[%s] " format "\n", __func__, ## args); \ | ||
| 210 | else \ | ||
| 211 | dev_printk(level, _udc->gadget.dev.parent, \ | ||
| 212 | "[%s] " format "\n", __func__, ## args); \ | ||
| 213 | } while (0) | ||
| 214 | |||
| 215 | #define err(format, args...) ci13xxx_printk(KERN_ERR, format, ## args) | ||
| 216 | #define warn(format, args...) ci13xxx_printk(KERN_WARNING, format, ## args) | ||
| 217 | #define info(format, args...) ci13xxx_printk(KERN_INFO, format, ## args) | ||
| 218 | |||
| 219 | #ifdef TRACE | ||
| 220 | #define trace(format, args...) ci13xxx_printk(KERN_DEBUG, format, ## args) | ||
| 221 | #define dbg_trace(format, args...) dev_dbg(dev, format, ##args) | ||
| 222 | #else | ||
| 223 | #define trace(format, args...) do {} while (0) | ||
| 224 | #define dbg_trace(format, args...) do {} while (0) | ||
| 225 | #endif | ||
| 226 | |||
| 227 | #endif /* _CI13XXX_h_ */ | ||
diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c new file mode 100644 index 00000000000..ae65faaf3d7 --- /dev/null +++ b/drivers/usb/gadget/f_accessory.c | |||
| @@ -0,0 +1,788 @@ | |||
| 1 | /* | ||
| 2 | * Gadget Function Driver for Android USB accessories | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 Google, Inc. | ||
| 5 | * Author: Mike Lockwood <lockwood@android.com> | ||
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* #define DEBUG */ | ||
| 19 | /* #define VERBOSE_DEBUG */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/poll.h> | ||
| 24 | #include <linux/delay.h> | ||
| 25 | #include <linux/wait.h> | ||
| 26 | #include <linux/err.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/kthread.h> | ||
| 29 | #include <linux/freezer.h> | ||
| 30 | |||
| 31 | #include <linux/types.h> | ||
| 32 | #include <linux/file.h> | ||
| 33 | #include <linux/device.h> | ||
| 34 | #include <linux/miscdevice.h> | ||
| 35 | |||
| 36 | #include <linux/usb.h> | ||
| 37 | #include <linux/usb/ch9.h> | ||
| 38 | #include <linux/usb/f_accessory.h> | ||
| 39 | |||
| 40 | #define BULK_BUFFER_SIZE 16384 | ||
| 41 | #define ACC_STRING_SIZE 256 | ||
| 42 | |||
| 43 | #define PROTOCOL_VERSION 1 | ||
| 44 | |||
| 45 | /* String IDs */ | ||
| 46 | #define INTERFACE_STRING_INDEX 0 | ||
| 47 | |||
| 48 | /* number of tx and rx requests to allocate */ | ||
| 49 | #define TX_REQ_MAX 4 | ||
| 50 | #define RX_REQ_MAX 2 | ||
| 51 | |||
| 52 | struct acc_dev { | ||
| 53 | struct usb_function function; | ||
| 54 | struct usb_composite_dev *cdev; | ||
| 55 | spinlock_t lock; | ||
| 56 | |||
| 57 | struct usb_ep *ep_in; | ||
| 58 | struct usb_ep *ep_out; | ||
| 59 | |||
| 60 | /* set to 1 when we connect */ | ||
| 61 | int online:1; | ||
| 62 | /* Set to 1 when we disconnect. | ||
| 63 | * Not cleared until our file is closed. | ||
| 64 | */ | ||
| 65 | int disconnected:1; | ||
| 66 | |||
| 67 | /* strings sent by the host */ | ||
| 68 | char manufacturer[ACC_STRING_SIZE]; | ||
| 69 | char model[ACC_STRING_SIZE]; | ||
| 70 | char description[ACC_STRING_SIZE]; | ||
| 71 | char version[ACC_STRING_SIZE]; | ||
| 72 | char uri[ACC_STRING_SIZE]; | ||
| 73 | char serial[ACC_STRING_SIZE]; | ||
| 74 | |||
| 75 | /* for acc_complete_set_string */ | ||
| 76 | int string_index; | ||
| 77 | |||
| 78 | /* set to 1 if we have a pending start request */ | ||
| 79 | int start_requested; | ||
| 80 | |||
| 81 | /* synchronize access to our device file */ | ||
| 82 | atomic_t open_excl; | ||
| 83 | |||
| 84 | struct list_head tx_idle; | ||
| 85 | |||
| 86 | wait_queue_head_t read_wq; | ||
| 87 | wait_queue_head_t write_wq; | ||
| 88 | struct usb_request *rx_req[RX_REQ_MAX]; | ||
| 89 | int rx_done; | ||
| 90 | struct delayed_work work; | ||
| 91 | }; | ||
| 92 | |||
| 93 | static struct usb_interface_descriptor acc_interface_desc = { | ||
| 94 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 95 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 96 | .bInterfaceNumber = 0, | ||
| 97 | .bNumEndpoints = 2, | ||
| 98 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
| 99 | .bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, | ||
| 100 | .bInterfaceProtocol = 0, | ||
| 101 | }; | ||
| 102 | |||
| 103 | static struct usb_endpoint_descriptor acc_highspeed_in_desc = { | ||
| 104 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 105 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 106 | .bEndpointAddress = USB_DIR_IN, | ||
| 107 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 108 | .wMaxPacketSize = __constant_cpu_to_le16(512), | ||
| 109 | }; | ||
| 110 | |||
| 111 | static struct usb_endpoint_descriptor acc_highspeed_out_desc = { | ||
| 112 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 113 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 114 | .bEndpointAddress = USB_DIR_OUT, | ||
| 115 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 116 | .wMaxPacketSize = __constant_cpu_to_le16(512), | ||
| 117 | }; | ||
| 118 | |||
| 119 | static struct usb_endpoint_descriptor acc_fullspeed_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 acc_fullspeed_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_acc_descs[] = { | ||
| 134 | (struct usb_descriptor_header *) &acc_interface_desc, | ||
| 135 | (struct usb_descriptor_header *) &acc_fullspeed_in_desc, | ||
| 136 | (struct usb_descriptor_header *) &acc_fullspeed_out_desc, | ||
| 137 | NULL, | ||
| 138 | }; | ||
| 139 | |||
| 140 | static struct usb_descriptor_header *hs_acc_descs[] = { | ||
| 141 | (struct usb_descriptor_header *) &acc_interface_desc, | ||
| 142 | (struct usb_descriptor_header *) &acc_highspeed_in_desc, | ||
| 143 | (struct usb_descriptor_header *) &acc_highspeed_out_desc, | ||
| 144 | NULL, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static struct usb_string acc_string_defs[] = { | ||
| 148 | [INTERFACE_STRING_INDEX].s = "Android Accessory Interface", | ||
| 149 | { }, /* end of list */ | ||
| 150 | }; | ||
| 151 | |||
| 152 | static struct usb_gadget_strings acc_string_table = { | ||
| 153 | .language = 0x0409, /* en-US */ | ||
| 154 | .strings = acc_string_defs, | ||
| 155 | }; | ||
| 156 | |||
| 157 | static struct usb_gadget_strings *acc_strings[] = { | ||
| 158 | &acc_string_table, | ||
| 159 | NULL, | ||
| 160 | }; | ||
| 161 | |||
| 162 | /* temporary variable used between acc_open() and acc_gadget_bind() */ | ||
| 163 | static struct acc_dev *_acc_dev; | ||
| 164 | |||
| 165 | static inline struct acc_dev *func_to_dev(struct usb_function *f) | ||
| 166 | { | ||
| 167 | return container_of(f, struct acc_dev, function); | ||
| 168 | } | ||
| 169 | |||
| 170 | static struct usb_request *acc_request_new(struct usb_ep *ep, int buffer_size) | ||
| 171 | { | ||
| 172 | struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); | ||
| 173 | if (!req) | ||
| 174 | return NULL; | ||
| 175 | |||
| 176 | /* now allocate buffers for the requests */ | ||
| 177 | req->buf = kmalloc(buffer_size, GFP_KERNEL); | ||
| 178 | if (!req->buf) { | ||
| 179 | usb_ep_free_request(ep, req); | ||
| 180 | return NULL; | ||
| 181 | } | ||
| 182 | |||
| 183 | return req; | ||
| 184 | } | ||
| 185 | |||
| 186 | static void acc_request_free(struct usb_request *req, struct usb_ep *ep) | ||
| 187 | { | ||
| 188 | if (req) { | ||
| 189 | kfree(req->buf); | ||
| 190 | usb_ep_free_request(ep, req); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | /* add a request to the tail of a list */ | ||
| 195 | static void req_put(struct acc_dev *dev, struct list_head *head, | ||
| 196 | struct usb_request *req) | ||
| 197 | { | ||
| 198 | unsigned long flags; | ||
| 199 | |||
| 200 | spin_lock_irqsave(&dev->lock, flags); | ||
| 201 | list_add_tail(&req->list, head); | ||
| 202 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 203 | } | ||
| 204 | |||
| 205 | /* remove a request from the head of a list */ | ||
| 206 | static struct usb_request *req_get(struct acc_dev *dev, struct list_head *head) | ||
| 207 | { | ||
| 208 | unsigned long flags; | ||
| 209 | struct usb_request *req; | ||
| 210 | |||
| 211 | spin_lock_irqsave(&dev->lock, flags); | ||
| 212 | if (list_empty(head)) { | ||
| 213 | req = 0; | ||
| 214 | } else { | ||
| 215 | req = list_first_entry(head, struct usb_request, list); | ||
| 216 | list_del(&req->list); | ||
| 217 | } | ||
| 218 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 219 | return req; | ||
| 220 | } | ||
| 221 | |||
| 222 | static void acc_set_disconnected(struct acc_dev *dev) | ||
| 223 | { | ||
| 224 | dev->online = 0; | ||
| 225 | dev->disconnected = 1; | ||
| 226 | } | ||
| 227 | |||
| 228 | static void acc_complete_in(struct usb_ep *ep, struct usb_request *req) | ||
| 229 | { | ||
| 230 | struct acc_dev *dev = _acc_dev; | ||
| 231 | |||
| 232 | if (req->status != 0) | ||
| 233 | acc_set_disconnected(dev); | ||
| 234 | |||
| 235 | req_put(dev, &dev->tx_idle, req); | ||
| 236 | |||
| 237 | wake_up(&dev->write_wq); | ||
| 238 | } | ||
| 239 | |||
| 240 | static void acc_complete_out(struct usb_ep *ep, struct usb_request *req) | ||
| 241 | { | ||
| 242 | struct acc_dev *dev = _acc_dev; | ||
| 243 | |||
| 244 | dev->rx_done = 1; | ||
| 245 | if (req->status != 0) | ||
| 246 | acc_set_disconnected(dev); | ||
| 247 | |||
| 248 | wake_up(&dev->read_wq); | ||
| 249 | } | ||
| 250 | |||
| 251 | static void acc_complete_set_string(struct usb_ep *ep, struct usb_request *req) | ||
| 252 | { | ||
| 253 | struct acc_dev *dev = ep->driver_data; | ||
| 254 | char *string_dest = NULL; | ||
| 255 | int length = req->actual; | ||
| 256 | |||
| 257 | if (req->status != 0) { | ||
| 258 | pr_err("acc_complete_set_string, err %d\n", req->status); | ||
| 259 | return; | ||
| 260 | } | ||
| 261 | |||
| 262 | switch (dev->string_index) { | ||
| 263 | case ACCESSORY_STRING_MANUFACTURER: | ||
| 264 | string_dest = dev->manufacturer; | ||
| 265 | break; | ||
| 266 | case ACCESSORY_STRING_MODEL: | ||
| 267 | string_dest = dev->model; | ||
| 268 | break; | ||
| 269 | case ACCESSORY_STRING_DESCRIPTION: | ||
| 270 | string_dest = dev->description; | ||
| 271 | break; | ||
| 272 | case ACCESSORY_STRING_VERSION: | ||
| 273 | string_dest = dev->version; | ||
| 274 | break; | ||
| 275 | case ACCESSORY_STRING_URI: | ||
| 276 | string_dest = dev->uri; | ||
| 277 | break; | ||
| 278 | case ACCESSORY_STRING_SERIAL: | ||
| 279 | string_dest = dev->serial; | ||
| 280 | break; | ||
| 281 | } | ||
| 282 | if (string_dest) { | ||
| 283 | unsigned long flags; | ||
| 284 | |||
| 285 | if (length >= ACC_STRING_SIZE) | ||
| 286 | length = ACC_STRING_SIZE - 1; | ||
| 287 | |||
| 288 | spin_lock_irqsave(&dev->lock, flags); | ||
| 289 | memcpy(string_dest, req->buf, length); | ||
| 290 | /* ensure zero termination */ | ||
| 291 | string_dest[length] = 0; | ||
| 292 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 293 | } else { | ||
| 294 | pr_err("unknown accessory string index %d\n", | ||
| 295 | dev->string_index); | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | static int __init create_bulk_endpoints(struct acc_dev *dev, | ||
| 300 | struct usb_endpoint_descriptor *in_desc, | ||
| 301 | struct usb_endpoint_descriptor *out_desc) | ||
| 302 | { | ||
| 303 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 304 | struct usb_request *req; | ||
| 305 | struct usb_ep *ep; | ||
| 306 | int i; | ||
| 307 | |||
| 308 | DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); | ||
| 309 | |||
| 310 | ep = usb_ep_autoconfig(cdev->gadget, in_desc); | ||
| 311 | if (!ep) { | ||
| 312 | DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); | ||
| 313 | return -ENODEV; | ||
| 314 | } | ||
| 315 | DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); | ||
| 316 | ep->driver_data = dev; /* claim the endpoint */ | ||
| 317 | dev->ep_in = ep; | ||
| 318 | |||
| 319 | ep = usb_ep_autoconfig(cdev->gadget, out_desc); | ||
| 320 | if (!ep) { | ||
| 321 | DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); | ||
| 322 | return -ENODEV; | ||
| 323 | } | ||
| 324 | DBG(cdev, "usb_ep_autoconfig for ep_out got %s\n", ep->name); | ||
| 325 | ep->driver_data = dev; /* claim the endpoint */ | ||
| 326 | dev->ep_out = ep; | ||
| 327 | |||
| 328 | ep = usb_ep_autoconfig(cdev->gadget, out_desc); | ||
| 329 | if (!ep) { | ||
| 330 | DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); | ||
| 331 | return -ENODEV; | ||
| 332 | } | ||
| 333 | DBG(cdev, "usb_ep_autoconfig for ep_out got %s\n", ep->name); | ||
| 334 | ep->driver_data = dev; /* claim the endpoint */ | ||
| 335 | dev->ep_out = ep; | ||
| 336 | |||
| 337 | /* now allocate requests for our endpoints */ | ||
| 338 | for (i = 0; i < TX_REQ_MAX; i++) { | ||
| 339 | req = acc_request_new(dev->ep_in, BULK_BUFFER_SIZE); | ||
| 340 | if (!req) | ||
| 341 | goto fail; | ||
| 342 | req->complete = acc_complete_in; | ||
| 343 | req_put(dev, &dev->tx_idle, req); | ||
| 344 | } | ||
| 345 | for (i = 0; i < RX_REQ_MAX; i++) { | ||
| 346 | req = acc_request_new(dev->ep_out, BULK_BUFFER_SIZE); | ||
| 347 | if (!req) | ||
| 348 | goto fail; | ||
| 349 | req->complete = acc_complete_out; | ||
| 350 | dev->rx_req[i] = req; | ||
| 351 | } | ||
| 352 | |||
| 353 | return 0; | ||
| 354 | |||
| 355 | fail: | ||
| 356 | printk(KERN_ERR "acc_bind() could not allocate requests\n"); | ||
| 357 | while ((req = req_get(dev, &dev->tx_idle))) | ||
| 358 | acc_request_free(req, dev->ep_in); | ||
| 359 | for (i = 0; i < RX_REQ_MAX; i++) | ||
| 360 | acc_request_free(dev->rx_req[i], dev->ep_out); | ||
| 361 | return -1; | ||
| 362 | } | ||
| 363 | |||
| 364 | static ssize_t acc_read(struct file *fp, char __user *buf, | ||
| 365 | size_t count, loff_t *pos) | ||
| 366 | { | ||
| 367 | struct acc_dev *dev = fp->private_data; | ||
| 368 | struct usb_request *req; | ||
| 369 | int r = count, xfer; | ||
| 370 | int ret = 0; | ||
| 371 | |||
| 372 | pr_debug("acc_read(%d)\n", count); | ||
| 373 | |||
| 374 | if (dev->disconnected) | ||
| 375 | return -ENODEV; | ||
| 376 | |||
| 377 | if (count > BULK_BUFFER_SIZE) | ||
| 378 | count = BULK_BUFFER_SIZE; | ||
| 379 | |||
| 380 | /* we will block until we're online */ | ||
| 381 | pr_debug("acc_read: waiting for online\n"); | ||
| 382 | ret = wait_event_interruptible(dev->read_wq, dev->online); | ||
| 383 | if (ret < 0) { | ||
| 384 | r = ret; | ||
| 385 | goto done; | ||
| 386 | } | ||
| 387 | |||
| 388 | requeue_req: | ||
| 389 | /* queue a request */ | ||
| 390 | req = dev->rx_req[0]; | ||
| 391 | req->length = count; | ||
| 392 | dev->rx_done = 0; | ||
| 393 | ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); | ||
| 394 | if (ret < 0) { | ||
| 395 | r = -EIO; | ||
| 396 | goto done; | ||
| 397 | } else { | ||
| 398 | pr_debug("rx %p queue\n", req); | ||
| 399 | } | ||
| 400 | |||
| 401 | /* wait for a request to complete */ | ||
| 402 | ret = wait_event_interruptible(dev->read_wq, dev->rx_done); | ||
| 403 | if (ret < 0) { | ||
| 404 | r = ret; | ||
| 405 | usb_ep_dequeue(dev->ep_out, req); | ||
| 406 | goto done; | ||
| 407 | } | ||
| 408 | if (dev->online) { | ||
| 409 | /* If we got a 0-len packet, throw it back and try again. */ | ||
| 410 | if (req->actual == 0) | ||
| 411 | goto requeue_req; | ||
| 412 | |||
| 413 | pr_debug("rx %p %d\n", req, req->actual); | ||
| 414 | xfer = (req->actual < count) ? req->actual : count; | ||
| 415 | r = xfer; | ||
| 416 | if (copy_to_user(buf, req->buf, xfer)) | ||
| 417 | r = -EFAULT; | ||
| 418 | } else | ||
| 419 | r = -EIO; | ||
| 420 | |||
| 421 | done: | ||
| 422 | pr_debug("acc_read returning %d\n", r); | ||
| 423 | return r; | ||
| 424 | } | ||
| 425 | |||
| 426 | static ssize_t acc_write(struct file *fp, const char __user *buf, | ||
| 427 | size_t count, loff_t *pos) | ||
| 428 | { | ||
| 429 | struct acc_dev *dev = fp->private_data; | ||
| 430 | struct usb_request *req = 0; | ||
| 431 | int r = count, xfer; | ||
| 432 | int ret; | ||
| 433 | |||
| 434 | pr_debug("acc_write(%d)\n", count); | ||
| 435 | |||
| 436 | if (!dev->online || dev->disconnected) | ||
| 437 | return -ENODEV; | ||
| 438 | |||
| 439 | while (count > 0) { | ||
| 440 | if (!dev->online) { | ||
| 441 | pr_debug("acc_write dev->error\n"); | ||
| 442 | r = -EIO; | ||
| 443 | break; | ||
| 444 | } | ||
| 445 | |||
| 446 | /* get an idle tx request to use */ | ||
| 447 | req = 0; | ||
| 448 | ret = wait_event_interruptible(dev->write_wq, | ||
| 449 | ((req = req_get(dev, &dev->tx_idle)) || !dev->online)); | ||
| 450 | if (!req) { | ||
| 451 | r = ret; | ||
| 452 | break; | ||
| 453 | } | ||
| 454 | |||
| 455 | if (count > BULK_BUFFER_SIZE) | ||
| 456 | xfer = BULK_BUFFER_SIZE; | ||
| 457 | else | ||
| 458 | xfer = count; | ||
| 459 | if (copy_from_user(req->buf, buf, xfer)) { | ||
| 460 | r = -EFAULT; | ||
| 461 | break; | ||
| 462 | } | ||
| 463 | |||
| 464 | req->length = xfer; | ||
| 465 | ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); | ||
| 466 | if (ret < 0) { | ||
| 467 | pr_debug("acc_write: xfer error %d\n", ret); | ||
| 468 | r = -EIO; | ||
| 469 | break; | ||
| 470 | } | ||
| 471 | |||
| 472 | buf += xfer; | ||
| 473 | count -= xfer; | ||
| 474 | |||
| 475 | /* zero this so we don't try to free it on error exit */ | ||
| 476 | req = 0; | ||
| 477 | } | ||
| 478 | |||
| 479 | if (req) | ||
| 480 | req_put(dev, &dev->tx_idle, req); | ||
| 481 | |||
| 482 | pr_debug("acc_write returning %d\n", r); | ||
| 483 | return r; | ||
| 484 | } | ||
| 485 | |||
| 486 | static long acc_ioctl(struct file *fp, unsigned code, unsigned long value) | ||
| 487 | { | ||
| 488 | struct acc_dev *dev = fp->private_data; | ||
| 489 | char *src = NULL; | ||
| 490 | int ret; | ||
| 491 | |||
| 492 | switch (code) { | ||
| 493 | case ACCESSORY_GET_STRING_MANUFACTURER: | ||
| 494 | src = dev->manufacturer; | ||
| 495 | break; | ||
| 496 | case ACCESSORY_GET_STRING_MODEL: | ||
| 497 | src = dev->model; | ||
| 498 | break; | ||
| 499 | case ACCESSORY_GET_STRING_DESCRIPTION: | ||
| 500 | src = dev->description; | ||
| 501 | break; | ||
| 502 | case ACCESSORY_GET_STRING_VERSION: | ||
| 503 | src = dev->version; | ||
| 504 | break; | ||
| 505 | case ACCESSORY_GET_STRING_URI: | ||
| 506 | src = dev->uri; | ||
| 507 | break; | ||
| 508 | case ACCESSORY_GET_STRING_SERIAL: | ||
| 509 | src = dev->serial; | ||
| 510 | break; | ||
| 511 | case ACCESSORY_IS_START_REQUESTED: | ||
| 512 | return dev->start_requested; | ||
| 513 | } | ||
| 514 | if (!src) | ||
| 515 | return -EINVAL; | ||
| 516 | |||
| 517 | ret = strlen(src) + 1; | ||
| 518 | if (copy_to_user((void __user *)value, src, ret)) | ||
| 519 | ret = -EFAULT; | ||
| 520 | return ret; | ||
| 521 | } | ||
| 522 | |||
| 523 | static int acc_open(struct inode *ip, struct file *fp) | ||
| 524 | { | ||
| 525 | printk(KERN_INFO "acc_open\n"); | ||
| 526 | if (atomic_xchg(&_acc_dev->open_excl, 1)) | ||
| 527 | return -EBUSY; | ||
| 528 | |||
| 529 | _acc_dev->disconnected = 0; | ||
| 530 | fp->private_data = _acc_dev; | ||
| 531 | return 0; | ||
| 532 | } | ||
| 533 | |||
| 534 | static int acc_release(struct inode *ip, struct file *fp) | ||
| 535 | { | ||
| 536 | printk(KERN_INFO "acc_release\n"); | ||
| 537 | |||
| 538 | WARN_ON(!atomic_xchg(&_acc_dev->open_excl, 0)); | ||
| 539 | _acc_dev->disconnected = 0; | ||
| 540 | return 0; | ||
| 541 | } | ||
| 542 | |||
| 543 | /* file operations for /dev/acc_usb */ | ||
| 544 | static const struct file_operations acc_fops = { | ||
| 545 | .owner = THIS_MODULE, | ||
| 546 | .read = acc_read, | ||
| 547 | .write = acc_write, | ||
| 548 | .unlocked_ioctl = acc_ioctl, | ||
| 549 | .open = acc_open, | ||
| 550 | .release = acc_release, | ||
| 551 | }; | ||
| 552 | |||
| 553 | static struct miscdevice acc_device = { | ||
| 554 | .minor = MISC_DYNAMIC_MINOR, | ||
| 555 | .name = "usb_accessory", | ||
| 556 | .fops = &acc_fops, | ||
| 557 | }; | ||
| 558 | |||
| 559 | |||
| 560 | static int acc_ctrlrequest(struct usb_composite_dev *cdev, | ||
| 561 | const struct usb_ctrlrequest *ctrl) | ||
| 562 | { | ||
| 563 | struct acc_dev *dev = _acc_dev; | ||
| 564 | int value = -EOPNOTSUPP; | ||
| 565 | u8 b_requestType = ctrl->bRequestType; | ||
| 566 | u8 b_request = ctrl->bRequest; | ||
| 567 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
| 568 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 569 | u16 w_length = le16_to_cpu(ctrl->wLength); | ||
| 570 | |||
| 571 | /* | ||
| 572 | printk(KERN_INFO "acc_ctrlrequest " | ||
| 573 | "%02x.%02x v%04x i%04x l%u\n", | ||
| 574 | b_requestType, b_request, | ||
| 575 | w_value, w_index, w_length); | ||
| 576 | */ | ||
| 577 | |||
| 578 | if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) { | ||
| 579 | if (b_request == ACCESSORY_START) { | ||
| 580 | dev->start_requested = 1; | ||
| 581 | schedule_delayed_work( | ||
| 582 | &dev->work, msecs_to_jiffies(10)); | ||
| 583 | value = 0; | ||
| 584 | } else if (b_request == ACCESSORY_SEND_STRING) { | ||
| 585 | dev->string_index = w_index; | ||
| 586 | cdev->gadget->ep0->driver_data = dev; | ||
| 587 | cdev->req->complete = acc_complete_set_string; | ||
| 588 | value = w_length; | ||
| 589 | } | ||
| 590 | } else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) { | ||
| 591 | if (b_request == ACCESSORY_GET_PROTOCOL) { | ||
| 592 | *((u16 *)cdev->req->buf) = PROTOCOL_VERSION; | ||
| 593 | value = sizeof(u16); | ||
| 594 | |||
| 595 | /* clear any strings left over from a previous session */ | ||
| 596 | memset(dev->manufacturer, 0, sizeof(dev->manufacturer)); | ||
| 597 | memset(dev->model, 0, sizeof(dev->model)); | ||
| 598 | memset(dev->description, 0, sizeof(dev->description)); | ||
| 599 | memset(dev->version, 0, sizeof(dev->version)); | ||
| 600 | memset(dev->uri, 0, sizeof(dev->uri)); | ||
| 601 | memset(dev->serial, 0, sizeof(dev->serial)); | ||
| 602 | dev->start_requested = 0; | ||
| 603 | } | ||
| 604 | } | ||
| 605 | |||
| 606 | if (value >= 0) { | ||
| 607 | cdev->req->zero = 0; | ||
| 608 | cdev->req->length = value; | ||
| 609 | value = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); | ||
| 610 | if (value < 0) | ||
| 611 | ERROR(cdev, "%s setup response queue error\n", | ||
| 612 | __func__); | ||
| 613 | } | ||
| 614 | |||
| 615 | if (value == -EOPNOTSUPP) | ||
| 616 | VDBG(cdev, | ||
| 617 | "unknown class-specific control req " | ||
| 618 | "%02x.%02x v%04x i%04x l%u\n", | ||
| 619 | ctrl->bRequestType, ctrl->bRequest, | ||
| 620 | w_value, w_index, w_length); | ||
| 621 | return value; | ||
| 622 | } | ||
| 623 | |||
| 624 | static int | ||
| 625 | acc_function_bind(struct usb_configuration *c, struct usb_function *f) | ||
| 626 | { | ||
| 627 | struct usb_composite_dev *cdev = c->cdev; | ||
| 628 | struct acc_dev *dev = func_to_dev(f); | ||
| 629 | int id; | ||
| 630 | int ret; | ||
| 631 | |||
| 632 | DBG(cdev, "acc_function_bind dev: %p\n", dev); | ||
| 633 | |||
| 634 | dev->start_requested = 0; | ||
| 635 | |||
| 636 | /* allocate interface ID(s) */ | ||
| 637 | id = usb_interface_id(c, f); | ||
| 638 | if (id < 0) | ||
| 639 | return id; | ||
| 640 | acc_interface_desc.bInterfaceNumber = id; | ||
| 641 | |||
| 642 | /* allocate endpoints */ | ||
| 643 | ret = create_bulk_endpoints(dev, &acc_fullspeed_in_desc, | ||
| 644 | &acc_fullspeed_out_desc); | ||
| 645 | if (ret) | ||
| 646 | return ret; | ||
| 647 | |||
| 648 | /* support high speed hardware */ | ||
| 649 | if (gadget_is_dualspeed(c->cdev->gadget)) { | ||
| 650 | acc_highspeed_in_desc.bEndpointAddress = | ||
| 651 | acc_fullspeed_in_desc.bEndpointAddress; | ||
| 652 | acc_highspeed_out_desc.bEndpointAddress = | ||
| 653 | acc_fullspeed_out_desc.bEndpointAddress; | ||
| 654 | } | ||
| 655 | |||
| 656 | DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", | ||
| 657 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||
| 658 | f->name, dev->ep_in->name, dev->ep_out->name); | ||
| 659 | return 0; | ||
| 660 | } | ||
| 661 | |||
| 662 | static void | ||
| 663 | acc_function_unbind(struct usb_configuration *c, struct usb_function *f) | ||
| 664 | { | ||
| 665 | struct acc_dev *dev = func_to_dev(f); | ||
| 666 | struct usb_request *req; | ||
| 667 | int i; | ||
| 668 | |||
| 669 | while ((req = req_get(dev, &dev->tx_idle))) | ||
| 670 | acc_request_free(req, dev->ep_in); | ||
| 671 | for (i = 0; i < RX_REQ_MAX; i++) | ||
| 672 | acc_request_free(dev->rx_req[i], dev->ep_out); | ||
| 673 | } | ||
| 674 | |||
| 675 | static void acc_work(struct work_struct *data) | ||
| 676 | { | ||
| 677 | char *envp[2] = { "ACCESSORY=START", NULL }; | ||
| 678 | kobject_uevent_env(&acc_device.this_device->kobj, KOBJ_CHANGE, envp); | ||
| 679 | } | ||
| 680 | |||
| 681 | static int acc_function_set_alt(struct usb_function *f, | ||
| 682 | unsigned intf, unsigned alt) | ||
| 683 | { | ||
| 684 | struct acc_dev *dev = func_to_dev(f); | ||
| 685 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 686 | int ret; | ||
| 687 | |||
| 688 | DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt); | ||
| 689 | config_ep_by_speed(cdev->gadget, f, dev->ep_in); | ||
| 690 | ret = usb_ep_enable(dev->ep_in); | ||
| 691 | if (ret) | ||
| 692 | return ret; | ||
| 693 | config_ep_by_speed(cdev->gadget, f, dev->ep_out); | ||
| 694 | ret = usb_ep_enable(dev->ep_out); | ||
| 695 | if (ret) { | ||
| 696 | usb_ep_disable(dev->ep_in); | ||
| 697 | return ret; | ||
| 698 | } | ||
| 699 | |||
| 700 | dev->online = 1; | ||
| 701 | |||
| 702 | /* readers may be blocked waiting for us to go online */ | ||
| 703 | wake_up(&dev->read_wq); | ||
| 704 | return 0; | ||
| 705 | } | ||
| 706 | |||
| 707 | static void acc_function_disable(struct usb_function *f) | ||
| 708 | { | ||
| 709 | struct acc_dev *dev = func_to_dev(f); | ||
| 710 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 711 | |||
| 712 | DBG(cdev, "acc_function_disable\n"); | ||
| 713 | acc_set_disconnected(dev); | ||
| 714 | usb_ep_disable(dev->ep_in); | ||
| 715 | usb_ep_disable(dev->ep_out); | ||
| 716 | |||
| 717 | /* readers may be blocked waiting for us to go online */ | ||
| 718 | wake_up(&dev->read_wq); | ||
| 719 | |||
| 720 | VDBG(cdev, "%s disabled\n", dev->function.name); | ||
| 721 | } | ||
| 722 | |||
| 723 | static int acc_bind_config(struct usb_configuration *c) | ||
| 724 | { | ||
| 725 | struct acc_dev *dev = _acc_dev; | ||
| 726 | int ret; | ||
| 727 | |||
| 728 | printk(KERN_INFO "acc_bind_config\n"); | ||
| 729 | |||
| 730 | /* allocate a string ID for our interface */ | ||
| 731 | if (acc_string_defs[INTERFACE_STRING_INDEX].id == 0) { | ||
| 732 | ret = usb_string_id(c->cdev); | ||
| 733 | if (ret < 0) | ||
| 734 | return ret; | ||
| 735 | acc_string_defs[INTERFACE_STRING_INDEX].id = ret; | ||
| 736 | acc_interface_desc.iInterface = ret; | ||
| 737 | } | ||
| 738 | |||
| 739 | dev->cdev = c->cdev; | ||
| 740 | dev->function.name = "accessory"; | ||
| 741 | dev->function.strings = acc_strings, | ||
| 742 | dev->function.descriptors = fs_acc_descs; | ||
| 743 | dev->function.hs_descriptors = hs_acc_descs; | ||
| 744 | dev->function.bind = acc_function_bind; | ||
| 745 | dev->function.unbind = acc_function_unbind; | ||
| 746 | dev->function.set_alt = acc_function_set_alt; | ||
| 747 | dev->function.disable = acc_function_disable; | ||
| 748 | |||
| 749 | return usb_add_function(c, &dev->function); | ||
| 750 | } | ||
| 751 | |||
| 752 | static int acc_setup(void) | ||
| 753 | { | ||
| 754 | struct acc_dev *dev; | ||
| 755 | int ret; | ||
| 756 | |||
| 757 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 758 | if (!dev) | ||
| 759 | return -ENOMEM; | ||
| 760 | |||
| 761 | spin_lock_init(&dev->lock); | ||
| 762 | init_waitqueue_head(&dev->read_wq); | ||
| 763 | init_waitqueue_head(&dev->write_wq); | ||
| 764 | atomic_set(&dev->open_excl, 0); | ||
| 765 | INIT_LIST_HEAD(&dev->tx_idle); | ||
| 766 | INIT_DELAYED_WORK(&dev->work, acc_work); | ||
| 767 | |||
| 768 | /* _acc_dev must be set before calling usb_gadget_register_driver */ | ||
| 769 | _acc_dev = dev; | ||
| 770 | |||
| 771 | ret = misc_register(&acc_device); | ||
| 772 | if (ret) | ||
| 773 | goto err; | ||
| 774 | |||
| 775 | return 0; | ||
| 776 | |||
| 777 | err: | ||
| 778 | kfree(dev); | ||
| 779 | printk(KERN_ERR "USB accessory gadget driver failed to initialize\n"); | ||
| 780 | return ret; | ||
| 781 | } | ||
| 782 | |||
| 783 | static void acc_cleanup(void) | ||
| 784 | { | ||
| 785 | misc_deregister(&acc_device); | ||
| 786 | kfree(_acc_dev); | ||
| 787 | _acc_dev = NULL; | ||
| 788 | } | ||
diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c new file mode 100644 index 00000000000..94a793f4390 --- /dev/null +++ b/drivers/usb/gadget/f_adb.c | |||
| @@ -0,0 +1,635 @@ | |||
| 1 | /* | ||
| 2 | * Gadget Driver for Android ADB | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Google, Inc. | ||
| 5 | * Author: Mike Lockwood <lockwood@android.com> | ||
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/poll.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/wait.h> | ||
| 23 | #include <linux/err.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/sched.h> | ||
| 26 | #include <linux/types.h> | ||
| 27 | #include <linux/device.h> | ||
| 28 | #include <linux/miscdevice.h> | ||
| 29 | |||
| 30 | #define ADB_BULK_BUFFER_SIZE 4096 | ||
| 31 | |||
| 32 | /* number of tx requests to allocate */ | ||
| 33 | #define TX_REQ_MAX 4 | ||
| 34 | |||
| 35 | static const char adb_shortname[] = "android_adb"; | ||
| 36 | |||
| 37 | struct adb_dev { | ||
| 38 | struct usb_function function; | ||
| 39 | struct usb_composite_dev *cdev; | ||
| 40 | spinlock_t lock; | ||
| 41 | |||
| 42 | struct usb_ep *ep_in; | ||
| 43 | struct usb_ep *ep_out; | ||
| 44 | |||
| 45 | int online; | ||
| 46 | int error; | ||
| 47 | |||
| 48 | atomic_t read_excl; | ||
| 49 | atomic_t write_excl; | ||
| 50 | atomic_t open_excl; | ||
| 51 | |||
| 52 | struct list_head tx_idle; | ||
| 53 | |||
| 54 | wait_queue_head_t read_wq; | ||
| 55 | wait_queue_head_t write_wq; | ||
| 56 | struct usb_request *rx_req; | ||
| 57 | int rx_done; | ||
| 58 | }; | ||
| 59 | |||
| 60 | static struct usb_interface_descriptor adb_interface_desc = { | ||
| 61 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 62 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 63 | .bInterfaceNumber = 0, | ||
| 64 | .bNumEndpoints = 2, | ||
| 65 | .bInterfaceClass = 0xFF, | ||
| 66 | .bInterfaceSubClass = 0x42, | ||
| 67 | .bInterfaceProtocol = 1, | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct usb_endpoint_descriptor adb_highspeed_in_desc = { | ||
| 71 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 72 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 73 | .bEndpointAddress = USB_DIR_IN, | ||
| 74 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 75 | .wMaxPacketSize = __constant_cpu_to_le16(512), | ||
| 76 | }; | ||
| 77 | |||
| 78 | static struct usb_endpoint_descriptor adb_highspeed_out_desc = { | ||
| 79 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 80 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 81 | .bEndpointAddress = USB_DIR_OUT, | ||
| 82 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 83 | .wMaxPacketSize = __constant_cpu_to_le16(512), | ||
| 84 | }; | ||
| 85 | |||
| 86 | static struct usb_endpoint_descriptor adb_fullspeed_in_desc = { | ||
| 87 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 88 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 89 | .bEndpointAddress = USB_DIR_IN, | ||
| 90 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 91 | }; | ||
| 92 | |||
| 93 | static struct usb_endpoint_descriptor adb_fullspeed_out_desc = { | ||
| 94 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 95 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 96 | .bEndpointAddress = USB_DIR_OUT, | ||
| 97 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 98 | }; | ||
| 99 | |||
| 100 | static struct usb_descriptor_header *fs_adb_descs[] = { | ||
| 101 | (struct usb_descriptor_header *) &adb_interface_desc, | ||
| 102 | (struct usb_descriptor_header *) &adb_fullspeed_in_desc, | ||
| 103 | (struct usb_descriptor_header *) &adb_fullspeed_out_desc, | ||
| 104 | NULL, | ||
| 105 | }; | ||
| 106 | |||
| 107 | static struct usb_descriptor_header *hs_adb_descs[] = { | ||
| 108 | (struct usb_descriptor_header *) &adb_interface_desc, | ||
| 109 | (struct usb_descriptor_header *) &adb_highspeed_in_desc, | ||
| 110 | (struct usb_descriptor_header *) &adb_highspeed_out_desc, | ||
| 111 | NULL, | ||
| 112 | }; | ||
| 113 | |||
| 114 | |||
| 115 | /* temporary variable used between adb_open() and adb_gadget_bind() */ | ||
| 116 | static struct adb_dev *_adb_dev; | ||
| 117 | |||
| 118 | static inline struct adb_dev *func_to_adb(struct usb_function *f) | ||
| 119 | { | ||
| 120 | return container_of(f, struct adb_dev, function); | ||
| 121 | } | ||
| 122 | |||
| 123 | |||
| 124 | static struct usb_request *adb_request_new(struct usb_ep *ep, int buffer_size) | ||
| 125 | { | ||
| 126 | struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); | ||
| 127 | if (!req) | ||
| 128 | return NULL; | ||
| 129 | |||
| 130 | /* now allocate buffers for the requests */ | ||
| 131 | req->buf = kmalloc(buffer_size, GFP_KERNEL); | ||
| 132 | if (!req->buf) { | ||
| 133 | usb_ep_free_request(ep, req); | ||
| 134 | return NULL; | ||
| 135 | } | ||
| 136 | |||
| 137 | return req; | ||
| 138 | } | ||
| 139 | |||
| 140 | static void adb_request_free(struct usb_request *req, struct usb_ep *ep) | ||
| 141 | { | ||
| 142 | if (req) { | ||
| 143 | kfree(req->buf); | ||
| 144 | usb_ep_free_request(ep, req); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline int adb_lock(atomic_t *excl) | ||
| 149 | { | ||
| 150 | int ret = -1; | ||
| 151 | |||
| 152 | preempt_disable(); | ||
| 153 | if (atomic_inc_return(excl) == 1) { | ||
| 154 | ret = 0; | ||
| 155 | } else | ||
| 156 | atomic_dec(excl); | ||
| 157 | |||
| 158 | preempt_enable(); | ||
| 159 | return ret; | ||
| 160 | } | ||
| 161 | |||
| 162 | static inline void adb_unlock(atomic_t *excl) | ||
| 163 | { | ||
| 164 | atomic_dec(excl); | ||
| 165 | } | ||
| 166 | |||
| 167 | /* add a request to the tail of a list */ | ||
| 168 | void adb_req_put(struct adb_dev *dev, struct list_head *head, | ||
| 169 | struct usb_request *req) | ||
| 170 | { | ||
| 171 | unsigned long flags; | ||
| 172 | |||
| 173 | spin_lock_irqsave(&dev->lock, flags); | ||
| 174 | list_add_tail(&req->list, head); | ||
| 175 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 176 | } | ||
| 177 | |||
| 178 | /* remove a request from the head of a list */ | ||
| 179 | struct usb_request *adb_req_get(struct adb_dev *dev, struct list_head *head) | ||
| 180 | { | ||
| 181 | unsigned long flags; | ||
| 182 | struct usb_request *req; | ||
| 183 | |||
| 184 | spin_lock_irqsave(&dev->lock, flags); | ||
| 185 | if (list_empty(head)) { | ||
| 186 | req = 0; | ||
| 187 | } else { | ||
| 188 | req = list_first_entry(head, struct usb_request, list); | ||
| 189 | list_del(&req->list); | ||
| 190 | } | ||
| 191 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 192 | return req; | ||
| 193 | } | ||
| 194 | |||
| 195 | static void adb_complete_in(struct usb_ep *ep, struct usb_request *req) | ||
| 196 | { | ||
| 197 | struct adb_dev *dev = _adb_dev; | ||
| 198 | |||
| 199 | if (req->status != 0) | ||
| 200 | dev->error = 1; | ||
| 201 | |||
| 202 | adb_req_put(dev, &dev->tx_idle, req); | ||
| 203 | |||
| 204 | wake_up(&dev->write_wq); | ||
| 205 | } | ||
| 206 | |||
| 207 | static void adb_complete_out(struct usb_ep *ep, struct usb_request *req) | ||
| 208 | { | ||
| 209 | struct adb_dev *dev = _adb_dev; | ||
| 210 | |||
| 211 | dev->rx_done = 1; | ||
| 212 | if (req->status != 0) | ||
| 213 | dev->error = 1; | ||
| 214 | |||
| 215 | wake_up(&dev->read_wq); | ||
| 216 | } | ||
| 217 | |||
| 218 | static int adb_create_bulk_endpoints(struct adb_dev *dev, | ||
| 219 | struct usb_endpoint_descriptor *in_desc, | ||
| 220 | struct usb_endpoint_descriptor *out_desc) | ||
| 221 | { | ||
| 222 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 223 | struct usb_request *req; | ||
| 224 | struct usb_ep *ep; | ||
| 225 | int i; | ||
| 226 | |||
| 227 | DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); | ||
| 228 | |||
| 229 | ep = usb_ep_autoconfig(cdev->gadget, in_desc); | ||
| 230 | if (!ep) { | ||
| 231 | DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); | ||
| 232 | return -ENODEV; | ||
| 233 | } | ||
| 234 | DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); | ||
| 235 | ep->driver_data = dev; /* claim the endpoint */ | ||
| 236 | dev->ep_in = ep; | ||
| 237 | |||
| 238 | ep = usb_ep_autoconfig(cdev->gadget, out_desc); | ||
| 239 | if (!ep) { | ||
| 240 | DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); | ||
| 241 | return -ENODEV; | ||
| 242 | } | ||
| 243 | DBG(cdev, "usb_ep_autoconfig for adb ep_out got %s\n", ep->name); | ||
| 244 | ep->driver_data = dev; /* claim the endpoint */ | ||
| 245 | dev->ep_out = ep; | ||
| 246 | |||
| 247 | /* now allocate requests for our endpoints */ | ||
| 248 | req = adb_request_new(dev->ep_out, ADB_BULK_BUFFER_SIZE); | ||
| 249 | if (!req) | ||
| 250 | goto fail; | ||
| 251 | req->complete = adb_complete_out; | ||
| 252 | dev->rx_req = req; | ||
| 253 | |||
| 254 | for (i = 0; i < TX_REQ_MAX; i++) { | ||
| 255 | req = adb_request_new(dev->ep_in, ADB_BULK_BUFFER_SIZE); | ||
| 256 | if (!req) | ||
| 257 | goto fail; | ||
| 258 | req->complete = adb_complete_in; | ||
| 259 | adb_req_put(dev, &dev->tx_idle, req); | ||
| 260 | } | ||
| 261 | |||
| 262 | return 0; | ||
| 263 | |||
| 264 | fail: | ||
| 265 | printk(KERN_ERR "adb_bind() could not allocate requests\n"); | ||
| 266 | return -1; | ||
| 267 | } | ||
| 268 | |||
| 269 | static ssize_t adb_read(struct file *fp, char __user *buf, | ||
| 270 | size_t count, loff_t *pos) | ||
| 271 | { | ||
| 272 | struct adb_dev *dev = fp->private_data; | ||
| 273 | struct usb_request *req; | ||
| 274 | int r = count, xfer; | ||
| 275 | int ret; | ||
| 276 | |||
| 277 | pr_debug("adb_read(%d)\n", count); | ||
| 278 | if (!_adb_dev) | ||
| 279 | return -ENODEV; | ||
| 280 | |||
| 281 | if (count > ADB_BULK_BUFFER_SIZE) | ||
| 282 | return -EINVAL; | ||
| 283 | |||
| 284 | if (adb_lock(&dev->read_excl)) | ||
| 285 | return -EBUSY; | ||
| 286 | |||
| 287 | /* we will block until we're online */ | ||
| 288 | while (!(dev->online || dev->error)) { | ||
| 289 | pr_debug("adb_read: waiting for online state\n"); | ||
| 290 | ret = wait_event_interruptible(dev->read_wq, | ||
| 291 | (dev->online || dev->error)); | ||
| 292 | if (ret < 0) { | ||
| 293 | adb_unlock(&dev->read_excl); | ||
| 294 | return ret; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | if (dev->error) { | ||
| 298 | r = -EIO; | ||
| 299 | goto done; | ||
| 300 | } | ||
| 301 | |||
| 302 | requeue_req: | ||
| 303 | /* queue a request */ | ||
| 304 | req = dev->rx_req; | ||
| 305 | req->length = count; | ||
| 306 | dev->rx_done = 0; | ||
| 307 | ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC); | ||
| 308 | if (ret < 0) { | ||
| 309 | pr_debug("adb_read: failed to queue req %p (%d)\n", req, ret); | ||
| 310 | r = -EIO; | ||
| 311 | dev->error = 1; | ||
| 312 | goto done; | ||
| 313 | } else { | ||
| 314 | pr_debug("rx %p queue\n", req); | ||
| 315 | } | ||
| 316 | |||
| 317 | /* wait for a request to complete */ | ||
| 318 | ret = wait_event_interruptible(dev->read_wq, dev->rx_done); | ||
| 319 | if (ret < 0) { | ||
| 320 | dev->error = 1; | ||
| 321 | r = ret; | ||
| 322 | usb_ep_dequeue(dev->ep_out, req); | ||
| 323 | goto done; | ||
| 324 | } | ||
| 325 | if (!dev->error) { | ||
| 326 | /* If we got a 0-len packet, throw it back and try again. */ | ||
| 327 | if (req->actual == 0) | ||
| 328 | goto requeue_req; | ||
| 329 | |||
| 330 | pr_debug("rx %p %d\n", req, req->actual); | ||
| 331 | xfer = (req->actual < count) ? req->actual : count; | ||
| 332 | if (copy_to_user(buf, req->buf, xfer)) | ||
| 333 | r = -EFAULT; | ||
| 334 | |||
| 335 | } else | ||
| 336 | r = -EIO; | ||
| 337 | |||
| 338 | done: | ||
| 339 | adb_unlock(&dev->read_excl); | ||
| 340 | pr_debug("adb_read returning %d\n", r); | ||
| 341 | return r; | ||
| 342 | } | ||
| 343 | |||
| 344 | static ssize_t adb_write(struct file *fp, const char __user *buf, | ||
| 345 | size_t count, loff_t *pos) | ||
| 346 | { | ||
| 347 | struct adb_dev *dev = fp->private_data; | ||
| 348 | struct usb_request *req = 0; | ||
| 349 | int r = count, xfer; | ||
| 350 | int ret; | ||
| 351 | |||
| 352 | if (!_adb_dev) | ||
| 353 | return -ENODEV; | ||
| 354 | pr_debug("adb_write(%d)\n", count); | ||
| 355 | |||
| 356 | if (adb_lock(&dev->write_excl)) | ||
| 357 | return -EBUSY; | ||
| 358 | |||
| 359 | while (count > 0) { | ||
| 360 | if (dev->error) { | ||
| 361 | pr_debug("adb_write dev->error\n"); | ||
| 362 | r = -EIO; | ||
| 363 | break; | ||
| 364 | } | ||
| 365 | |||
| 366 | /* get an idle tx request to use */ | ||
| 367 | req = 0; | ||
| 368 | ret = wait_event_interruptible(dev->write_wq, | ||
| 369 | (req = adb_req_get(dev, &dev->tx_idle)) || dev->error); | ||
| 370 | |||
| 371 | if (ret < 0) { | ||
| 372 | r = ret; | ||
| 373 | break; | ||
| 374 | } | ||
| 375 | |||
| 376 | if (req != 0) { | ||
| 377 | if (count > ADB_BULK_BUFFER_SIZE) | ||
| 378 | xfer = ADB_BULK_BUFFER_SIZE; | ||
| 379 | else | ||
| 380 | xfer = count; | ||
| 381 | if (copy_from_user(req->buf, buf, xfer)) { | ||
| 382 | r = -EFAULT; | ||
| 383 | break; | ||
| 384 | } | ||
| 385 | |||
| 386 | req->length = xfer; | ||
| 387 | ret = usb_ep_queue(dev->ep_in, req, GFP_ATOMIC); | ||
| 388 | if (ret < 0) { | ||
| 389 | pr_debug("adb_write: xfer error %d\n", ret); | ||
| 390 | dev->error = 1; | ||
| 391 | r = -EIO; | ||
| 392 | break; | ||
| 393 | } | ||
| 394 | |||
| 395 | buf += xfer; | ||
| 396 | count -= xfer; | ||
| 397 | |||
| 398 | /* zero this so we don't try to free it on error exit */ | ||
| 399 | req = 0; | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 403 | if (req) | ||
| 404 | adb_req_put(dev, &dev->tx_idle, req); | ||
| 405 | |||
| 406 | adb_unlock(&dev->write_excl); | ||
| 407 | pr_debug("adb_write returning %d\n", r); | ||
| 408 | return r; | ||
| 409 | } | ||
| 410 | |||
| 411 | static int adb_open(struct inode *ip, struct file *fp) | ||
| 412 | { | ||
| 413 | static unsigned long last_print; | ||
| 414 | static unsigned long count = 0; | ||
| 415 | |||
| 416 | if (!_adb_dev) | ||
| 417 | return -ENODEV; | ||
| 418 | |||
| 419 | if (++count == 1) | ||
| 420 | last_print = jiffies; | ||
| 421 | else { | ||
| 422 | if (!time_before(jiffies, last_print + HZ/2)) | ||
| 423 | count = 0; | ||
| 424 | last_print = jiffies; | ||
| 425 | } | ||
| 426 | |||
| 427 | if (adb_lock(&_adb_dev->open_excl)) { | ||
| 428 | cpu_relax(); | ||
| 429 | return -EBUSY; | ||
| 430 | } | ||
| 431 | |||
| 432 | if (count < 5) | ||
| 433 | printk(KERN_INFO "adb_open(%s)\n", current->comm); | ||
| 434 | |||
| 435 | |||
| 436 | fp->private_data = _adb_dev; | ||
| 437 | |||
| 438 | /* clear the error latch */ | ||
| 439 | _adb_dev->error = 0; | ||
| 440 | |||
| 441 | return 0; | ||
| 442 | } | ||
| 443 | |||
| 444 | static int adb_release(struct inode *ip, struct file *fp) | ||
| 445 | { | ||
| 446 | static unsigned long last_print; | ||
| 447 | static unsigned long count = 0; | ||
| 448 | |||
| 449 | if (++count == 1) | ||
| 450 | last_print = jiffies; | ||
| 451 | else { | ||
| 452 | if (!time_before(jiffies, last_print + HZ/2)) | ||
| 453 | count = 0; | ||
| 454 | last_print = jiffies; | ||
| 455 | } | ||
| 456 | |||
| 457 | if (count < 5) | ||
| 458 | printk(KERN_INFO "adb_release\n"); | ||
| 459 | adb_unlock(&_adb_dev->open_excl); | ||
| 460 | return 0; | ||
| 461 | } | ||
| 462 | |||
| 463 | /* file operations for ADB device /dev/android_adb */ | ||
| 464 | static struct file_operations adb_fops = { | ||
| 465 | .owner = THIS_MODULE, | ||
| 466 | .read = adb_read, | ||
| 467 | .write = adb_write, | ||
| 468 | .open = adb_open, | ||
| 469 | .release = adb_release, | ||
| 470 | }; | ||
| 471 | |||
| 472 | static struct miscdevice adb_device = { | ||
| 473 | .minor = MISC_DYNAMIC_MINOR, | ||
| 474 | .name = adb_shortname, | ||
| 475 | .fops = &adb_fops, | ||
| 476 | }; | ||
| 477 | |||
| 478 | |||
| 479 | |||
| 480 | |||
| 481 | static int | ||
| 482 | adb_function_bind(struct usb_configuration *c, struct usb_function *f) | ||
| 483 | { | ||
| 484 | struct usb_composite_dev *cdev = c->cdev; | ||
| 485 | struct adb_dev *dev = func_to_adb(f); | ||
| 486 | int id; | ||
| 487 | int ret; | ||
| 488 | |||
| 489 | dev->cdev = cdev; | ||
| 490 | DBG(cdev, "adb_function_bind dev: %p\n", dev); | ||
| 491 | |||
| 492 | /* allocate interface ID(s) */ | ||
| 493 | id = usb_interface_id(c, f); | ||
| 494 | if (id < 0) | ||
| 495 | return id; | ||
| 496 | adb_interface_desc.bInterfaceNumber = id; | ||
| 497 | |||
| 498 | /* allocate endpoints */ | ||
| 499 | ret = adb_create_bulk_endpoints(dev, &adb_fullspeed_in_desc, | ||
| 500 | &adb_fullspeed_out_desc); | ||
| 501 | if (ret) | ||
| 502 | return ret; | ||
| 503 | |||
| 504 | /* support high speed hardware */ | ||
| 505 | if (gadget_is_dualspeed(c->cdev->gadget)) { | ||
| 506 | adb_highspeed_in_desc.bEndpointAddress = | ||
| 507 | adb_fullspeed_in_desc.bEndpointAddress; | ||
| 508 | adb_highspeed_out_desc.bEndpointAddress = | ||
| 509 | adb_fullspeed_out_desc.bEndpointAddress; | ||
| 510 | } | ||
| 511 | |||
| 512 | DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", | ||
| 513 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||
| 514 | f->name, dev->ep_in->name, dev->ep_out->name); | ||
| 515 | return 0; | ||
| 516 | } | ||
| 517 | |||
| 518 | static void | ||
| 519 | adb_function_unbind(struct usb_configuration *c, struct usb_function *f) | ||
| 520 | { | ||
| 521 | struct adb_dev *dev = func_to_adb(f); | ||
| 522 | struct usb_request *req; | ||
| 523 | |||
| 524 | |||
| 525 | dev->online = 0; | ||
| 526 | dev->error = 1; | ||
| 527 | |||
| 528 | wake_up(&dev->read_wq); | ||
| 529 | |||
| 530 | adb_request_free(dev->rx_req, dev->ep_out); | ||
| 531 | while ((req = adb_req_get(dev, &dev->tx_idle))) | ||
| 532 | adb_request_free(req, dev->ep_in); | ||
| 533 | } | ||
| 534 | |||
| 535 | static int adb_function_set_alt(struct usb_function *f, | ||
| 536 | unsigned intf, unsigned alt) | ||
| 537 | { | ||
| 538 | struct adb_dev *dev = func_to_adb(f); | ||
| 539 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 540 | int ret; | ||
| 541 | |||
| 542 | DBG(cdev, "adb_function_set_alt intf: %d alt: %d\n", intf, alt); | ||
| 543 | config_ep_by_speed(cdev->gadget, f, dev->ep_in); | ||
| 544 | ret = usb_ep_enable(dev->ep_in); | ||
| 545 | if (ret) | ||
| 546 | return ret; | ||
| 547 | config_ep_by_speed(cdev->gadget, f, dev->ep_out); | ||
| 548 | ret = usb_ep_enable(dev->ep_out); | ||
| 549 | if (ret) { | ||
| 550 | usb_ep_disable(dev->ep_in); | ||
| 551 | return ret; | ||
| 552 | } | ||
| 553 | dev->online = 1; | ||
| 554 | |||
| 555 | /* readers may be blocked waiting for us to go online */ | ||
| 556 | wake_up(&dev->read_wq); | ||
| 557 | return 0; | ||
| 558 | } | ||
| 559 | |||
| 560 | static void adb_function_disable(struct usb_function *f) | ||
| 561 | { | ||
| 562 | struct adb_dev *dev = func_to_adb(f); | ||
| 563 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 564 | |||
| 565 | DBG(cdev, "adb_function_disable cdev %p\n", cdev); | ||
| 566 | dev->online = 0; | ||
| 567 | dev->error = 1; | ||
| 568 | usb_ep_disable(dev->ep_in); | ||
| 569 | usb_ep_disable(dev->ep_out); | ||
| 570 | |||
| 571 | /* readers may be blocked waiting for us to go online */ | ||
| 572 | wake_up(&dev->read_wq); | ||
| 573 | |||
| 574 | VDBG(cdev, "%s disabled\n", dev->function.name); | ||
| 575 | } | ||
| 576 | |||
| 577 | static int adb_bind_config(struct usb_configuration *c) | ||
| 578 | { | ||
| 579 | struct adb_dev *dev = _adb_dev; | ||
| 580 | |||
| 581 | printk(KERN_INFO "adb_bind_config\n"); | ||
| 582 | |||
| 583 | dev->cdev = c->cdev; | ||
| 584 | dev->function.name = "adb"; | ||
| 585 | dev->function.descriptors = fs_adb_descs; | ||
| 586 | dev->function.hs_descriptors = hs_adb_descs; | ||
| 587 | dev->function.bind = adb_function_bind; | ||
| 588 | dev->function.unbind = adb_function_unbind; | ||
| 589 | dev->function.set_alt = adb_function_set_alt; | ||
| 590 | dev->function.disable = adb_function_disable; | ||
| 591 | |||
| 592 | return usb_add_function(c, &dev->function); | ||
| 593 | } | ||
| 594 | |||
| 595 | static int adb_setup(void) | ||
| 596 | { | ||
| 597 | struct adb_dev *dev; | ||
| 598 | int ret; | ||
| 599 | |||
| 600 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 601 | if (!dev) | ||
| 602 | return -ENOMEM; | ||
| 603 | |||
| 604 | spin_lock_init(&dev->lock); | ||
| 605 | |||
| 606 | init_waitqueue_head(&dev->read_wq); | ||
| 607 | init_waitqueue_head(&dev->write_wq); | ||
| 608 | |||
| 609 | atomic_set(&dev->open_excl, 0); | ||
| 610 | atomic_set(&dev->read_excl, 0); | ||
| 611 | atomic_set(&dev->write_excl, 0); | ||
| 612 | |||
| 613 | INIT_LIST_HEAD(&dev->tx_idle); | ||
| 614 | |||
| 615 | _adb_dev = dev; | ||
| 616 | |||
| 617 | ret = misc_register(&adb_device); | ||
| 618 | if (ret) | ||
| 619 | goto err; | ||
| 620 | |||
| 621 | return 0; | ||
| 622 | |||
| 623 | err: | ||
| 624 | kfree(dev); | ||
| 625 | printk(KERN_ERR "adb gadget driver failed to initialize\n"); | ||
| 626 | return ret; | ||
| 627 | } | ||
| 628 | |||
| 629 | static void adb_cleanup(void) | ||
| 630 | { | ||
| 631 | misc_deregister(&adb_device); | ||
| 632 | |||
| 633 | kfree(_adb_dev); | ||
| 634 | _adb_dev = NULL; | ||
| 635 | } | ||
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c new file mode 100644 index 00000000000..a9a4eade7e8 --- /dev/null +++ b/drivers/usb/gadget/f_audio.c | |||
| @@ -0,0 +1,798 @@ | |||
| 1 | /* | ||
| 2 | * f_audio.c -- USB Audio class function driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org> | ||
| 5 | * Copyright (C) 2008 Analog Devices, Inc | ||
| 6 | * | ||
| 7 | * Enter bugs at http://blackfin.uclinux.org/ | ||
| 8 | * | ||
| 9 | * Licensed under the GPL-2 or later. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/slab.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/atomic.h> | ||
| 16 | |||
| 17 | #include "u_audio.h" | ||
| 18 | |||
| 19 | #define OUT_EP_MAX_PACKET_SIZE 200 | ||
| 20 | static int req_buf_size = OUT_EP_MAX_PACKET_SIZE; | ||
| 21 | module_param(req_buf_size, int, S_IRUGO); | ||
| 22 | MODULE_PARM_DESC(req_buf_size, "ISO OUT endpoint request buffer size"); | ||
| 23 | |||
| 24 | static int req_count = 256; | ||
| 25 | module_param(req_count, int, S_IRUGO); | ||
| 26 | MODULE_PARM_DESC(req_count, "ISO OUT endpoint request count"); | ||
| 27 | |||
| 28 | static int audio_buf_size = 48000; | ||
| 29 | module_param(audio_buf_size, int, S_IRUGO); | ||
| 30 | MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); | ||
| 31 | |||
| 32 | static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); | ||
| 33 | static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); | ||
| 34 | |||
| 35 | /* | ||
| 36 | * DESCRIPTORS ... most are static, but strings and full | ||
| 37 | * configuration descriptors are built on demand. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /* | ||
| 41 | * We have two interfaces- AudioControl and AudioStreaming | ||
| 42 | * TODO: only supcard playback currently | ||
| 43 | */ | ||
| 44 | #define F_AUDIO_AC_INTERFACE 0 | ||
| 45 | #define F_AUDIO_AS_INTERFACE 1 | ||
| 46 | #define F_AUDIO_NUM_INTERFACES 2 | ||
| 47 | |||
| 48 | /* B.3.1 Standard AC Interface Descriptor */ | ||
| 49 | static struct usb_interface_descriptor ac_interface_desc __initdata = { | ||
| 50 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 51 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 52 | .bNumEndpoints = 0, | ||
| 53 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
| 54 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, | ||
| 55 | }; | ||
| 56 | |||
| 57 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); | ||
| 58 | |||
| 59 | #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) | ||
| 60 | /* 1 input terminal, 1 output terminal and 1 feature unit */ | ||
| 61 | #define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ | ||
| 62 | + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) | ||
| 63 | /* B.3.2 Class-Specific AC Interface Descriptor */ | ||
| 64 | static struct uac1_ac_header_descriptor_2 ac_header_desc = { | ||
| 65 | .bLength = UAC_DT_AC_HEADER_LENGTH, | ||
| 66 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 67 | .bDescriptorSubtype = UAC_HEADER, | ||
| 68 | .bcdADC = __constant_cpu_to_le16(0x0100), | ||
| 69 | .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), | ||
| 70 | .bInCollection = F_AUDIO_NUM_INTERFACES, | ||
| 71 | .baInterfaceNr = { | ||
| 72 | [0] = F_AUDIO_AC_INTERFACE, | ||
| 73 | [1] = F_AUDIO_AS_INTERFACE, | ||
| 74 | } | ||
| 75 | }; | ||
| 76 | |||
| 77 | #define INPUT_TERMINAL_ID 1 | ||
| 78 | static struct uac_input_terminal_descriptor input_terminal_desc = { | ||
| 79 | .bLength = UAC_DT_INPUT_TERMINAL_SIZE, | ||
| 80 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 81 | .bDescriptorSubtype = UAC_INPUT_TERMINAL, | ||
| 82 | .bTerminalID = INPUT_TERMINAL_ID, | ||
| 83 | .wTerminalType = UAC_TERMINAL_STREAMING, | ||
| 84 | .bAssocTerminal = 0, | ||
| 85 | .wChannelConfig = 0x3, | ||
| 86 | }; | ||
| 87 | |||
| 88 | DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); | ||
| 89 | |||
| 90 | #define FEATURE_UNIT_ID 2 | ||
| 91 | static struct uac_feature_unit_descriptor_0 feature_unit_desc = { | ||
| 92 | .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), | ||
| 93 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 94 | .bDescriptorSubtype = UAC_FEATURE_UNIT, | ||
| 95 | .bUnitID = FEATURE_UNIT_ID, | ||
| 96 | .bSourceID = INPUT_TERMINAL_ID, | ||
| 97 | .bControlSize = 2, | ||
| 98 | .bmaControls[0] = (UAC_FU_MUTE | UAC_FU_VOLUME), | ||
| 99 | }; | ||
| 100 | |||
| 101 | static struct usb_audio_control mute_control = { | ||
| 102 | .list = LIST_HEAD_INIT(mute_control.list), | ||
| 103 | .name = "Mute Control", | ||
| 104 | .type = UAC_FU_MUTE, | ||
| 105 | /* Todo: add real Mute control code */ | ||
| 106 | .set = generic_set_cmd, | ||
| 107 | .get = generic_get_cmd, | ||
| 108 | }; | ||
| 109 | |||
| 110 | static struct usb_audio_control volume_control = { | ||
| 111 | .list = LIST_HEAD_INIT(volume_control.list), | ||
| 112 | .name = "Volume Control", | ||
| 113 | .type = UAC_FU_VOLUME, | ||
| 114 | /* Todo: add real Volume control code */ | ||
| 115 | .set = generic_set_cmd, | ||
| 116 | .get = generic_get_cmd, | ||
| 117 | }; | ||
| 118 | |||
| 119 | static struct usb_audio_control_selector feature_unit = { | ||
| 120 | .list = LIST_HEAD_INIT(feature_unit.list), | ||
| 121 | .id = FEATURE_UNIT_ID, | ||
| 122 | .name = "Mute & Volume Control", | ||
| 123 | .type = UAC_FEATURE_UNIT, | ||
| 124 | .desc = (struct usb_descriptor_header *)&feature_unit_desc, | ||
| 125 | }; | ||
| 126 | |||
| 127 | #define OUTPUT_TERMINAL_ID 3 | ||
| 128 | static struct uac1_output_terminal_descriptor output_terminal_desc = { | ||
| 129 | .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, | ||
| 130 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 131 | .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, | ||
| 132 | .bTerminalID = OUTPUT_TERMINAL_ID, | ||
| 133 | .wTerminalType = UAC_OUTPUT_TERMINAL_SPEAKER, | ||
| 134 | .bAssocTerminal = FEATURE_UNIT_ID, | ||
| 135 | .bSourceID = FEATURE_UNIT_ID, | ||
| 136 | }; | ||
| 137 | |||
| 138 | /* B.4.1 Standard AS Interface Descriptor */ | ||
| 139 | static struct usb_interface_descriptor as_interface_alt_0_desc = { | ||
| 140 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 141 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 142 | .bAlternateSetting = 0, | ||
| 143 | .bNumEndpoints = 0, | ||
| 144 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
| 145 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, | ||
| 146 | }; | ||
| 147 | |||
| 148 | static struct usb_interface_descriptor as_interface_alt_1_desc = { | ||
| 149 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 150 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 151 | .bAlternateSetting = 1, | ||
| 152 | .bNumEndpoints = 1, | ||
| 153 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
| 154 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, | ||
| 155 | }; | ||
| 156 | |||
| 157 | /* B.4.2 Class-Specific AS Interface Descriptor */ | ||
| 158 | static struct uac1_as_header_descriptor as_header_desc = { | ||
| 159 | .bLength = UAC_DT_AS_HEADER_SIZE, | ||
| 160 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 161 | .bDescriptorSubtype = UAC_AS_GENERAL, | ||
| 162 | .bTerminalLink = INPUT_TERMINAL_ID, | ||
| 163 | .bDelay = 1, | ||
| 164 | .wFormatTag = UAC_FORMAT_TYPE_I_PCM, | ||
| 165 | }; | ||
| 166 | |||
| 167 | DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); | ||
| 168 | |||
| 169 | static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { | ||
| 170 | .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), | ||
| 171 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 172 | .bDescriptorSubtype = UAC_FORMAT_TYPE, | ||
| 173 | .bFormatType = UAC_FORMAT_TYPE_I, | ||
| 174 | .bSubframeSize = 2, | ||
| 175 | .bBitResolution = 16, | ||
| 176 | .bSamFreqType = 1, | ||
| 177 | }; | ||
| 178 | |||
| 179 | /* Standard ISO OUT Endpoint Descriptor */ | ||
| 180 | static struct usb_endpoint_descriptor as_out_ep_desc = { | ||
| 181 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, | ||
| 182 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 183 | .bEndpointAddress = USB_DIR_OUT, | ||
| 184 | .bmAttributes = USB_ENDPOINT_SYNC_ADAPTIVE | ||
| 185 | | USB_ENDPOINT_XFER_ISOC, | ||
| 186 | .wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE), | ||
| 187 | .bInterval = 4, | ||
| 188 | }; | ||
| 189 | |||
| 190 | /* Class-specific AS ISO OUT Endpoint Descriptor */ | ||
| 191 | static struct uac_iso_endpoint_descriptor as_iso_out_desc __initdata = { | ||
| 192 | .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, | ||
| 193 | .bDescriptorType = USB_DT_CS_ENDPOINT, | ||
| 194 | .bDescriptorSubtype = UAC_EP_GENERAL, | ||
| 195 | .bmAttributes = 1, | ||
| 196 | .bLockDelayUnits = 1, | ||
| 197 | .wLockDelay = __constant_cpu_to_le16(1), | ||
| 198 | }; | ||
| 199 | |||
| 200 | static struct usb_descriptor_header *f_audio_desc[] __initdata = { | ||
| 201 | (struct usb_descriptor_header *)&ac_interface_desc, | ||
| 202 | (struct usb_descriptor_header *)&ac_header_desc, | ||
| 203 | |||
| 204 | (struct usb_descriptor_header *)&input_terminal_desc, | ||
| 205 | (struct usb_descriptor_header *)&output_terminal_desc, | ||
| 206 | (struct usb_descriptor_header *)&feature_unit_desc, | ||
| 207 | |||
| 208 | (struct usb_descriptor_header *)&as_interface_alt_0_desc, | ||
| 209 | (struct usb_descriptor_header *)&as_interface_alt_1_desc, | ||
| 210 | (struct usb_descriptor_header *)&as_header_desc, | ||
| 211 | |||
| 212 | (struct usb_descriptor_header *)&as_type_i_desc, | ||
| 213 | |||
| 214 | (struct usb_descriptor_header *)&as_out_ep_desc, | ||
| 215 | (struct usb_descriptor_header *)&as_iso_out_desc, | ||
| 216 | NULL, | ||
| 217 | }; | ||
| 218 | |||
| 219 | /* string IDs are assigned dynamically */ | ||
| 220 | |||
| 221 | #define STRING_MANUFACTURER_IDX 0 | ||
| 222 | #define STRING_PRODUCT_IDX 1 | ||
| 223 | |||
| 224 | static char manufacturer[50]; | ||
| 225 | |||
| 226 | static struct usb_string strings_dev[] = { | ||
| 227 | [STRING_MANUFACTURER_IDX].s = manufacturer, | ||
| 228 | [STRING_PRODUCT_IDX].s = DRIVER_DESC, | ||
| 229 | { } /* end of list */ | ||
| 230 | }; | ||
| 231 | |||
| 232 | static struct usb_gadget_strings stringtab_dev = { | ||
| 233 | .language = 0x0409, /* en-us */ | ||
| 234 | .strings = strings_dev, | ||
| 235 | }; | ||
| 236 | |||
| 237 | static struct usb_gadget_strings *audio_strings[] = { | ||
| 238 | &stringtab_dev, | ||
| 239 | NULL, | ||
| 240 | }; | ||
| 241 | |||
| 242 | /* | ||
| 243 | * This function is an ALSA sound card following USB Audio Class Spec 1.0. | ||
| 244 | */ | ||
| 245 | |||
| 246 | /*-------------------------------------------------------------------------*/ | ||
| 247 | struct f_audio_buf { | ||
| 248 | u8 *buf; | ||
| 249 | int actual; | ||
| 250 | struct list_head list; | ||
| 251 | }; | ||
| 252 | |||
| 253 | static struct f_audio_buf *f_audio_buffer_alloc(int buf_size) | ||
| 254 | { | ||
| 255 | struct f_audio_buf *copy_buf; | ||
| 256 | |||
| 257 | copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC); | ||
| 258 | if (!copy_buf) | ||
| 259 | return ERR_PTR(-ENOMEM); | ||
| 260 | |||
| 261 | copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC); | ||
| 262 | if (!copy_buf->buf) { | ||
| 263 | kfree(copy_buf); | ||
| 264 | return ERR_PTR(-ENOMEM); | ||
| 265 | } | ||
| 266 | |||
| 267 | return copy_buf; | ||
| 268 | } | ||
| 269 | |||
| 270 | static void f_audio_buffer_free(struct f_audio_buf *audio_buf) | ||
| 271 | { | ||
| 272 | kfree(audio_buf->buf); | ||
| 273 | kfree(audio_buf); | ||
| 274 | } | ||
| 275 | /*-------------------------------------------------------------------------*/ | ||
| 276 | |||
| 277 | struct f_audio { | ||
| 278 | struct gaudio card; | ||
| 279 | |||
| 280 | /* endpoints handle full and/or high speeds */ | ||
| 281 | struct usb_ep *out_ep; | ||
| 282 | |||
| 283 | spinlock_t lock; | ||
| 284 | struct f_audio_buf *copy_buf; | ||
| 285 | struct work_struct playback_work; | ||
| 286 | struct list_head play_queue; | ||
| 287 | |||
| 288 | /* Control Set command */ | ||
| 289 | struct list_head cs; | ||
| 290 | u8 set_cmd; | ||
| 291 | struct usb_audio_control *set_con; | ||
| 292 | }; | ||
| 293 | |||
| 294 | static inline struct f_audio *func_to_audio(struct usb_function *f) | ||
| 295 | { | ||
| 296 | return container_of(f, struct f_audio, card.func); | ||
| 297 | } | ||
| 298 | |||
| 299 | /*-------------------------------------------------------------------------*/ | ||
| 300 | |||
| 301 | static void f_audio_playback_work(struct work_struct *data) | ||
| 302 | { | ||
| 303 | struct f_audio *audio = container_of(data, struct f_audio, | ||
| 304 | playback_work); | ||
| 305 | struct f_audio_buf *play_buf; | ||
| 306 | |||
| 307 | spin_lock_irq(&audio->lock); | ||
| 308 | if (list_empty(&audio->play_queue)) { | ||
| 309 | spin_unlock_irq(&audio->lock); | ||
| 310 | return; | ||
| 311 | } | ||
| 312 | play_buf = list_first_entry(&audio->play_queue, | ||
| 313 | struct f_audio_buf, list); | ||
| 314 | list_del(&play_buf->list); | ||
| 315 | spin_unlock_irq(&audio->lock); | ||
| 316 | |||
| 317 | u_audio_playback(&audio->card, play_buf->buf, play_buf->actual); | ||
| 318 | f_audio_buffer_free(play_buf); | ||
| 319 | } | ||
| 320 | |||
| 321 | static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 322 | { | ||
| 323 | struct f_audio *audio = req->context; | ||
| 324 | struct usb_composite_dev *cdev = audio->card.func.config->cdev; | ||
| 325 | struct f_audio_buf *copy_buf = audio->copy_buf; | ||
| 326 | int err; | ||
| 327 | |||
| 328 | if (!copy_buf) | ||
| 329 | return -EINVAL; | ||
| 330 | |||
| 331 | /* Copy buffer is full, add it to the play_queue */ | ||
| 332 | if (audio_buf_size - copy_buf->actual < req->actual) { | ||
| 333 | list_add_tail(©_buf->list, &audio->play_queue); | ||
| 334 | schedule_work(&audio->playback_work); | ||
| 335 | copy_buf = f_audio_buffer_alloc(audio_buf_size); | ||
| 336 | if (IS_ERR(copy_buf)) | ||
| 337 | return -ENOMEM; | ||
| 338 | } | ||
| 339 | |||
| 340 | memcpy(copy_buf->buf + copy_buf->actual, req->buf, req->actual); | ||
| 341 | copy_buf->actual += req->actual; | ||
| 342 | audio->copy_buf = copy_buf; | ||
| 343 | |||
| 344 | err = usb_ep_queue(ep, req, GFP_ATOMIC); | ||
| 345 | if (err) | ||
| 346 | ERROR(cdev, "%s queue req: %d\n", ep->name, err); | ||
| 347 | |||
| 348 | return 0; | ||
| 349 | |||
| 350 | } | ||
| 351 | |||
| 352 | static void f_audio_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 353 | { | ||
| 354 | struct f_audio *audio = req->context; | ||
| 355 | int status = req->status; | ||
| 356 | u32 data = 0; | ||
| 357 | struct usb_ep *out_ep = audio->out_ep; | ||
| 358 | |||
| 359 | switch (status) { | ||
| 360 | |||
| 361 | case 0: /* normal completion? */ | ||
| 362 | if (ep == out_ep) | ||
| 363 | f_audio_out_ep_complete(ep, req); | ||
| 364 | else if (audio->set_con) { | ||
| 365 | memcpy(&data, req->buf, req->length); | ||
| 366 | audio->set_con->set(audio->set_con, audio->set_cmd, | ||
| 367 | le16_to_cpu(data)); | ||
| 368 | audio->set_con = NULL; | ||
| 369 | } | ||
| 370 | break; | ||
| 371 | default: | ||
| 372 | break; | ||
| 373 | } | ||
| 374 | } | ||
| 375 | |||
| 376 | static int audio_set_intf_req(struct usb_function *f, | ||
| 377 | const struct usb_ctrlrequest *ctrl) | ||
| 378 | { | ||
| 379 | struct f_audio *audio = func_to_audio(f); | ||
| 380 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 381 | struct usb_request *req = cdev->req; | ||
| 382 | u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); | ||
| 383 | u16 len = le16_to_cpu(ctrl->wLength); | ||
| 384 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 385 | u8 con_sel = (w_value >> 8) & 0xFF; | ||
| 386 | u8 cmd = (ctrl->bRequest & 0x0F); | ||
| 387 | struct usb_audio_control_selector *cs; | ||
| 388 | struct usb_audio_control *con; | ||
| 389 | |||
| 390 | DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", | ||
| 391 | ctrl->bRequest, w_value, len, id); | ||
| 392 | |||
| 393 | list_for_each_entry(cs, &audio->cs, list) { | ||
| 394 | if (cs->id == id) { | ||
| 395 | list_for_each_entry(con, &cs->control, list) { | ||
| 396 | if (con->type == con_sel) { | ||
| 397 | audio->set_con = con; | ||
| 398 | break; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | break; | ||
| 402 | } | ||
| 403 | } | ||
| 404 | |||
| 405 | audio->set_cmd = cmd; | ||
| 406 | req->context = audio; | ||
| 407 | req->complete = f_audio_complete; | ||
| 408 | |||
| 409 | return len; | ||
| 410 | } | ||
| 411 | |||
| 412 | static int audio_get_intf_req(struct usb_function *f, | ||
| 413 | const struct usb_ctrlrequest *ctrl) | ||
| 414 | { | ||
| 415 | struct f_audio *audio = func_to_audio(f); | ||
| 416 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 417 | struct usb_request *req = cdev->req; | ||
| 418 | int value = -EOPNOTSUPP; | ||
| 419 | u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); | ||
| 420 | u16 len = le16_to_cpu(ctrl->wLength); | ||
| 421 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 422 | u8 con_sel = (w_value >> 8) & 0xFF; | ||
| 423 | u8 cmd = (ctrl->bRequest & 0x0F); | ||
| 424 | struct usb_audio_control_selector *cs; | ||
| 425 | struct usb_audio_control *con; | ||
| 426 | |||
| 427 | DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", | ||
| 428 | ctrl->bRequest, w_value, len, id); | ||
| 429 | |||
| 430 | list_for_each_entry(cs, &audio->cs, list) { | ||
| 431 | if (cs->id == id) { | ||
| 432 | list_for_each_entry(con, &cs->control, list) { | ||
| 433 | if (con->type == con_sel && con->get) { | ||
| 434 | value = con->get(con, cmd); | ||
| 435 | break; | ||
| 436 | } | ||
| 437 | } | ||
| 438 | break; | ||
| 439 | } | ||
| 440 | } | ||
| 441 | |||
| 442 | req->context = audio; | ||
| 443 | req->complete = f_audio_complete; | ||
| 444 | memcpy(req->buf, &value, len); | ||
| 445 | |||
| 446 | return len; | ||
| 447 | } | ||
| 448 | |||
| 449 | static int audio_set_endpoint_req(struct usb_function *f, | ||
| 450 | const struct usb_ctrlrequest *ctrl) | ||
| 451 | { | ||
| 452 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 453 | int value = -EOPNOTSUPP; | ||
| 454 | u16 ep = le16_to_cpu(ctrl->wIndex); | ||
| 455 | u16 len = le16_to_cpu(ctrl->wLength); | ||
| 456 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 457 | |||
| 458 | DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", | ||
| 459 | ctrl->bRequest, w_value, len, ep); | ||
| 460 | |||
| 461 | switch (ctrl->bRequest) { | ||
| 462 | case UAC_SET_CUR: | ||
| 463 | value = 0; | ||
| 464 | break; | ||
| 465 | |||
| 466 | case UAC_SET_MIN: | ||
| 467 | break; | ||
| 468 | |||
| 469 | case UAC_SET_MAX: | ||
| 470 | break; | ||
| 471 | |||
| 472 | case UAC_SET_RES: | ||
| 473 | break; | ||
| 474 | |||
| 475 | case UAC_SET_MEM: | ||
| 476 | break; | ||
| 477 | |||
| 478 | default: | ||
| 479 | break; | ||
| 480 | } | ||
| 481 | |||
| 482 | return value; | ||
| 483 | } | ||
| 484 | |||
| 485 | static int audio_get_endpoint_req(struct usb_function *f, | ||
| 486 | const struct usb_ctrlrequest *ctrl) | ||
| 487 | { | ||
| 488 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 489 | int value = -EOPNOTSUPP; | ||
| 490 | u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); | ||
| 491 | u16 len = le16_to_cpu(ctrl->wLength); | ||
| 492 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 493 | |||
| 494 | DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", | ||
| 495 | ctrl->bRequest, w_value, len, ep); | ||
| 496 | |||
| 497 | switch (ctrl->bRequest) { | ||
| 498 | case UAC_GET_CUR: | ||
| 499 | case UAC_GET_MIN: | ||
| 500 | case UAC_GET_MAX: | ||
| 501 | case UAC_GET_RES: | ||
| 502 | value = 3; | ||
| 503 | break; | ||
| 504 | case UAC_GET_MEM: | ||
| 505 | break; | ||
| 506 | default: | ||
| 507 | break; | ||
| 508 | } | ||
| 509 | |||
| 510 | return value; | ||
| 511 | } | ||
| 512 | |||
| 513 | static int | ||
| 514 | f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | ||
| 515 | { | ||
| 516 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 517 | struct usb_request *req = cdev->req; | ||
| 518 | int value = -EOPNOTSUPP; | ||
| 519 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
| 520 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 521 | u16 w_length = le16_to_cpu(ctrl->wLength); | ||
| 522 | |||
| 523 | /* composite driver infrastructure handles everything; interface | ||
| 524 | * activation uses set_alt(). | ||
| 525 | */ | ||
| 526 | switch (ctrl->bRequestType) { | ||
| 527 | case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: | ||
| 528 | value = audio_set_intf_req(f, ctrl); | ||
| 529 | break; | ||
| 530 | |||
| 531 | case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE: | ||
| 532 | value = audio_get_intf_req(f, ctrl); | ||
| 533 | break; | ||
| 534 | |||
| 535 | case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: | ||
| 536 | value = audio_set_endpoint_req(f, ctrl); | ||
| 537 | break; | ||
| 538 | |||
| 539 | case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: | ||
| 540 | value = audio_get_endpoint_req(f, ctrl); | ||
| 541 | break; | ||
| 542 | |||
| 543 | default: | ||
| 544 | ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", | ||
| 545 | ctrl->bRequestType, ctrl->bRequest, | ||
| 546 | w_value, w_index, w_length); | ||
| 547 | } | ||
| 548 | |||
| 549 | /* respond with data transfer or status phase? */ | ||
| 550 | if (value >= 0) { | ||
| 551 | DBG(cdev, "audio req%02x.%02x v%04x i%04x l%d\n", | ||
| 552 | ctrl->bRequestType, ctrl->bRequest, | ||
| 553 | w_value, w_index, w_length); | ||
| 554 | req->zero = 0; | ||
| 555 | req->length = value; | ||
| 556 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); | ||
| 557 | if (value < 0) | ||
| 558 | ERROR(cdev, "audio response on err %d\n", value); | ||
| 559 | } | ||
| 560 | |||
| 561 | /* device either stalls (value < 0) or reports success */ | ||
| 562 | return value; | ||
| 563 | } | ||
| 564 | |||
| 565 | static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | ||
| 566 | { | ||
| 567 | struct f_audio *audio = func_to_audio(f); | ||
| 568 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 569 | struct usb_ep *out_ep = audio->out_ep; | ||
| 570 | struct usb_request *req; | ||
| 571 | int i = 0, err = 0; | ||
| 572 | |||
| 573 | DBG(cdev, "intf %d, alt %d\n", intf, alt); | ||
| 574 | |||
| 575 | if (intf == 1) { | ||
| 576 | if (alt == 1) { | ||
| 577 | usb_ep_enable(out_ep); | ||
| 578 | out_ep->driver_data = audio; | ||
| 579 | audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); | ||
| 580 | if (IS_ERR(audio->copy_buf)) | ||
| 581 | return -ENOMEM; | ||
| 582 | |||
| 583 | /* | ||
| 584 | * allocate a bunch of read buffers | ||
| 585 | * and queue them all at once. | ||
| 586 | */ | ||
| 587 | for (i = 0; i < req_count && err == 0; i++) { | ||
| 588 | req = usb_ep_alloc_request(out_ep, GFP_ATOMIC); | ||
| 589 | if (req) { | ||
| 590 | req->buf = kzalloc(req_buf_size, | ||
| 591 | GFP_ATOMIC); | ||
| 592 | if (req->buf) { | ||
| 593 | req->length = req_buf_size; | ||
| 594 | req->context = audio; | ||
| 595 | req->complete = | ||
| 596 | f_audio_complete; | ||
| 597 | err = usb_ep_queue(out_ep, | ||
| 598 | req, GFP_ATOMIC); | ||
| 599 | if (err) | ||
| 600 | ERROR(cdev, | ||
| 601 | "%s queue req: %d\n", | ||
| 602 | out_ep->name, err); | ||
| 603 | } else | ||
| 604 | err = -ENOMEM; | ||
| 605 | } else | ||
| 606 | err = -ENOMEM; | ||
| 607 | } | ||
| 608 | |||
| 609 | } else { | ||
| 610 | struct f_audio_buf *copy_buf = audio->copy_buf; | ||
| 611 | if (copy_buf) { | ||
| 612 | list_add_tail(©_buf->list, | ||
| 613 | &audio->play_queue); | ||
| 614 | schedule_work(&audio->playback_work); | ||
| 615 | } | ||
| 616 | } | ||
| 617 | } | ||
| 618 | |||
| 619 | return err; | ||
| 620 | } | ||
| 621 | |||
| 622 | static void f_audio_disable(struct usb_function *f) | ||
| 623 | { | ||
| 624 | return; | ||
| 625 | } | ||
| 626 | |||
| 627 | /*-------------------------------------------------------------------------*/ | ||
| 628 | |||
| 629 | static void f_audio_build_desc(struct f_audio *audio) | ||
| 630 | { | ||
| 631 | struct gaudio *card = &audio->card; | ||
| 632 | u8 *sam_freq; | ||
| 633 | int rate; | ||
| 634 | |||
| 635 | /* Set channel numbers */ | ||
| 636 | input_terminal_desc.bNrChannels = u_audio_get_playback_channels(card); | ||
| 637 | as_type_i_desc.bNrChannels = u_audio_get_playback_channels(card); | ||
| 638 | |||
| 639 | /* Set sample rates */ | ||
| 640 | rate = u_audio_get_playback_rate(card); | ||
| 641 | sam_freq = as_type_i_desc.tSamFreq[0]; | ||
| 642 | memcpy(sam_freq, &rate, 3); | ||
| 643 | |||
| 644 | /* Todo: Set Sample bits and other parameters */ | ||
| 645 | |||
| 646 | return; | ||
| 647 | } | ||
| 648 | |||
| 649 | /* audio function driver setup/binding */ | ||
| 650 | static int __init | ||
| 651 | f_audio_bind(struct usb_configuration *c, struct usb_function *f) | ||
| 652 | { | ||
| 653 | struct usb_composite_dev *cdev = c->cdev; | ||
| 654 | struct f_audio *audio = func_to_audio(f); | ||
| 655 | int status; | ||
| 656 | struct usb_ep *ep; | ||
| 657 | |||
| 658 | f_audio_build_desc(audio); | ||
| 659 | |||
| 660 | /* allocate instance-specific interface IDs, and patch descriptors */ | ||
| 661 | status = usb_interface_id(c, f); | ||
| 662 | if (status < 0) | ||
| 663 | goto fail; | ||
| 664 | ac_interface_desc.bInterfaceNumber = status; | ||
| 665 | |||
| 666 | status = usb_interface_id(c, f); | ||
| 667 | if (status < 0) | ||
| 668 | goto fail; | ||
| 669 | as_interface_alt_0_desc.bInterfaceNumber = status; | ||
| 670 | as_interface_alt_1_desc.bInterfaceNumber = status; | ||
| 671 | |||
| 672 | status = -ENODEV; | ||
| 673 | |||
| 674 | /* allocate instance-specific endpoints */ | ||
| 675 | ep = usb_ep_autoconfig(cdev->gadget, &as_out_ep_desc); | ||
| 676 | if (!ep) | ||
| 677 | goto fail; | ||
| 678 | audio->out_ep = ep; | ||
| 679 | audio->out_ep->desc = &as_out_ep_desc; | ||
| 680 | ep->driver_data = cdev; /* claim */ | ||
| 681 | |||
| 682 | status = -ENOMEM; | ||
| 683 | |||
| 684 | /* supcard all relevant hardware speeds... we expect that when | ||
| 685 | * hardware is dual speed, all bulk-capable endpoints work at | ||
| 686 | * both speeds | ||
| 687 | */ | ||
| 688 | |||
| 689 | /* copy descriptors, and track endpoint copies */ | ||
| 690 | if (gadget_is_dualspeed(c->cdev->gadget)) { | ||
| 691 | c->highspeed = true; | ||
| 692 | f->hs_descriptors = usb_copy_descriptors(f_audio_desc); | ||
| 693 | } else | ||
| 694 | f->descriptors = usb_copy_descriptors(f_audio_desc); | ||
| 695 | |||
| 696 | return 0; | ||
| 697 | |||
| 698 | fail: | ||
| 699 | |||
| 700 | return status; | ||
| 701 | } | ||
| 702 | |||
| 703 | static void | ||
| 704 | f_audio_unbind(struct usb_configuration *c, struct usb_function *f) | ||
| 705 | { | ||
| 706 | struct f_audio *audio = func_to_audio(f); | ||
| 707 | |||
| 708 | usb_free_descriptors(f->descriptors); | ||
| 709 | usb_free_descriptors(f->hs_descriptors); | ||
| 710 | kfree(audio); | ||
| 711 | } | ||
| 712 | |||
| 713 | /*-------------------------------------------------------------------------*/ | ||
| 714 | |||
| 715 | static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value) | ||
| 716 | { | ||
| 717 | con->data[cmd] = value; | ||
| 718 | |||
| 719 | return 0; | ||
| 720 | } | ||
| 721 | |||
| 722 | static int generic_get_cmd(struct usb_audio_control *con, u8 cmd) | ||
| 723 | { | ||
| 724 | return con->data[cmd]; | ||
| 725 | } | ||
| 726 | |||
| 727 | /* Todo: add more control selecotor dynamically */ | ||
| 728 | int __init control_selector_init(struct f_audio *audio) | ||
| 729 | { | ||
| 730 | INIT_LIST_HEAD(&audio->cs); | ||
| 731 | list_add(&feature_unit.list, &audio->cs); | ||
| 732 | |||
| 733 | INIT_LIST_HEAD(&feature_unit.control); | ||
| 734 | list_add(&mute_control.list, &feature_unit.control); | ||
| 735 | list_add(&volume_control.list, &feature_unit.control); | ||
| 736 | |||
| 737 | volume_control.data[UAC__CUR] = 0xffc0; | ||
| 738 | volume_control.data[UAC__MIN] = 0xe3a0; | ||
| 739 | volume_control.data[UAC__MAX] = 0xfff0; | ||
| 740 | volume_control.data[UAC__RES] = 0x0030; | ||
| 741 | |||
| 742 | return 0; | ||
| 743 | } | ||
| 744 | |||
| 745 | /** | ||
| 746 | * audio_bind_config - add USB audio function to a configuration | ||
| 747 | * @c: the configuration to supcard the USB audio function | ||
| 748 | * Context: single threaded during gadget setup | ||
| 749 | * | ||
| 750 | * Returns zero on success, else negative errno. | ||
| 751 | */ | ||
| 752 | int __init audio_bind_config(struct usb_configuration *c) | ||
| 753 | { | ||
| 754 | struct f_audio *audio; | ||
| 755 | int status; | ||
| 756 | |||
| 757 | /* allocate and initialize one new instance */ | ||
| 758 | audio = kzalloc(sizeof *audio, GFP_KERNEL); | ||
| 759 | if (!audio) | ||
| 760 | return -ENOMEM; | ||
| 761 | |||
| 762 | audio->card.func.name = "g_audio"; | ||
| 763 | audio->card.gadget = c->cdev->gadget; | ||
| 764 | |||
| 765 | INIT_LIST_HEAD(&audio->play_queue); | ||
| 766 | spin_lock_init(&audio->lock); | ||
| 767 | |||
| 768 | /* set up ASLA audio devices */ | ||
| 769 | status = gaudio_setup(&audio->card); | ||
| 770 | if (status < 0) | ||
| 771 | goto setup_fail; | ||
| 772 | |||
| 773 | audio->card.func.strings = audio_strings; | ||
| 774 | audio->card.func.bind = f_audio_bind; | ||
| 775 | audio->card.func.unbind = f_audio_unbind; | ||
| 776 | audio->card.func.set_alt = f_audio_set_alt; | ||
| 777 | audio->card.func.setup = f_audio_setup; | ||
| 778 | audio->card.func.disable = f_audio_disable; | ||
| 779 | |||
| 780 | control_selector_init(audio); | ||
| 781 | |||
| 782 | INIT_WORK(&audio->playback_work, f_audio_playback_work); | ||
| 783 | |||
| 784 | status = usb_add_function(c, &audio->card.func); | ||
| 785 | if (status) | ||
| 786 | goto add_fail; | ||
| 787 | |||
| 788 | INFO(c->cdev, "audio_buf_size %d, req_buf_size %d, req_count %d\n", | ||
| 789 | audio_buf_size, req_buf_size, req_count); | ||
| 790 | |||
| 791 | return status; | ||
| 792 | |||
| 793 | add_fail: | ||
| 794 | gaudio_cleanup(); | ||
| 795 | setup_fail: | ||
| 796 | kfree(audio); | ||
| 797 | return status; | ||
| 798 | } | ||
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c new file mode 100644 index 00000000000..5aa5214297d --- /dev/null +++ b/drivers/usb/gadget/f_mtp.c | |||
| @@ -0,0 +1,1264 @@ | |||
| 1 | /* | ||
| 2 | * Gadget Function Driver for MTP | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Google, Inc. | ||
| 5 | * Author: Mike Lockwood <lockwood@android.com> | ||
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* #define DEBUG */ | ||
| 19 | /* #define VERBOSE_DEBUG */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/poll.h> | ||
| 24 | #include <linux/delay.h> | ||
| 25 | #include <linux/wait.h> | ||
| 26 | #include <linux/err.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | |||
| 29 | #include <linux/types.h> | ||
| 30 | #include <linux/file.h> | ||
| 31 | #include <linux/device.h> | ||
| 32 | #include <linux/miscdevice.h> | ||
| 33 | |||
| 34 | #include <linux/usb.h> | ||
| 35 | #include <linux/usb_usual.h> | ||
| 36 | #include <linux/usb/ch9.h> | ||
| 37 | #include <linux/usb/f_mtp.h> | ||
| 38 | |||
| 39 | #define MTP_BULK_BUFFER_SIZE 16384 | ||
| 40 | #define INTR_BUFFER_SIZE 28 | ||
| 41 | |||
| 42 | /* String IDs */ | ||
| 43 | #define INTERFACE_STRING_INDEX 0 | ||
| 44 | |||
| 45 | /* values for mtp_dev.state */ | ||
| 46 | #define STATE_OFFLINE 0 /* initial state, disconnected */ | ||
| 47 | #define STATE_READY 1 /* ready for userspace calls */ | ||
| 48 | #define STATE_BUSY 2 /* processing userspace calls */ | ||
| 49 | #define STATE_CANCELED 3 /* transaction canceled by host */ | ||
| 50 | #define STATE_ERROR 4 /* error from completion routine */ | ||
| 51 | |||
| 52 | /* number of tx and rx requests to allocate */ | ||
| 53 | #define TX_REQ_MAX 4 | ||
| 54 | #define RX_REQ_MAX 2 | ||
| 55 | #define INTR_REQ_MAX 5 | ||
| 56 | |||
| 57 | /* ID for Microsoft MTP OS String */ | ||
| 58 | #define MTP_OS_STRING_ID 0xEE | ||
| 59 | |||
| 60 | /* MTP class reqeusts */ | ||
| 61 | #define MTP_REQ_CANCEL 0x64 | ||
| 62 | #define MTP_REQ_GET_EXT_EVENT_DATA 0x65 | ||
| 63 | #define MTP_REQ_RESET 0x66 | ||
| 64 | #define MTP_REQ_GET_DEVICE_STATUS 0x67 | ||
| 65 | |||
| 66 | /* constants for device status */ | ||
| 67 | #define MTP_RESPONSE_OK 0x2001 | ||
| 68 | #define MTP_RESPONSE_DEVICE_BUSY 0x2019 | ||
| 69 | |||
| 70 | static const char mtp_shortname[] = "mtp_usb"; | ||
| 71 | |||
| 72 | struct mtp_dev { | ||
| 73 | struct usb_function function; | ||
| 74 | struct usb_composite_dev *cdev; | ||
| 75 | spinlock_t lock; | ||
| 76 | |||
| 77 | struct usb_ep *ep_in; | ||
| 78 | struct usb_ep *ep_out; | ||
| 79 | struct usb_ep *ep_intr; | ||
| 80 | |||
| 81 | int state; | ||
| 82 | |||
| 83 | /* synchronize access to our device file */ | ||
| 84 | atomic_t open_excl; | ||
| 85 | /* to enforce only one ioctl at a time */ | ||
| 86 | atomic_t ioctl_excl; | ||
| 87 | |||
| 88 | struct list_head tx_idle; | ||
| 89 | struct list_head intr_idle; | ||
| 90 | |||
| 91 | wait_queue_head_t read_wq; | ||
| 92 | wait_queue_head_t write_wq; | ||
| 93 | wait_queue_head_t intr_wq; | ||
| 94 | struct usb_request *rx_req[RX_REQ_MAX]; | ||
| 95 | int rx_done; | ||
| 96 | |||
| 97 | /* for processing MTP_SEND_FILE, MTP_RECEIVE_FILE and | ||
| 98 | * MTP_SEND_FILE_WITH_HEADER ioctls on a work queue | ||
| 99 | */ | ||
| 100 | struct workqueue_struct *wq; | ||
| 101 | struct work_struct send_file_work; | ||
| 102 | struct work_struct receive_file_work; | ||
| 103 | struct file *xfer_file; | ||
| 104 | loff_t xfer_file_offset; | ||
| 105 | int64_t xfer_file_length; | ||
| 106 | unsigned xfer_send_header; | ||
| 107 | uint16_t xfer_command; | ||
| 108 | uint32_t xfer_transaction_id; | ||
| 109 | int xfer_result; | ||
| 110 | }; | ||
| 111 | |||
| 112 | static struct usb_interface_descriptor mtp_interface_desc = { | ||
| 113 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 114 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 115 | .bInterfaceNumber = 0, | ||
| 116 | .bNumEndpoints = 3, | ||
| 117 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
| 118 | .bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, | ||
| 119 | .bInterfaceProtocol = 0, | ||
| 120 | }; | ||
| 121 | |||
| 122 | static struct usb_interface_descriptor ptp_interface_desc = { | ||
| 123 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 124 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 125 | .bInterfaceNumber = 0, | ||
| 126 | .bNumEndpoints = 3, | ||
| 127 | .bInterfaceClass = USB_CLASS_STILL_IMAGE, | ||
| 128 | .bInterfaceSubClass = 1, | ||
| 129 | .bInterfaceProtocol = 1, | ||
| 130 | }; | ||
| 131 | |||
| 132 | static struct usb_endpoint_descriptor mtp_highspeed_in_desc = { | ||
| 133 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 134 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 135 | .bEndpointAddress = USB_DIR_IN, | ||
| 136 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 137 | .wMaxPacketSize = __constant_cpu_to_le16(512), | ||
| 138 | }; | ||
| 139 | |||
| 140 | static struct usb_endpoint_descriptor mtp_highspeed_out_desc = { | ||
| 141 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 142 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 143 | .bEndpointAddress = USB_DIR_OUT, | ||
| 144 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 145 | .wMaxPacketSize = __constant_cpu_to_le16(512), | ||
| 146 | }; | ||
| 147 | |||
| 148 | static struct usb_endpoint_descriptor mtp_fullspeed_in_desc = { | ||
| 149 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 150 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 151 | .bEndpointAddress = USB_DIR_IN, | ||
| 152 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 153 | }; | ||
| 154 | |||
| 155 | static struct usb_endpoint_descriptor mtp_fullspeed_out_desc = { | ||
| 156 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 157 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 158 | .bEndpointAddress = USB_DIR_OUT, | ||
| 159 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 160 | }; | ||
| 161 | |||
| 162 | static struct usb_endpoint_descriptor mtp_intr_desc = { | ||
| 163 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 164 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 165 | .bEndpointAddress = USB_DIR_IN, | ||
| 166 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
| 167 | .wMaxPacketSize = __constant_cpu_to_le16(INTR_BUFFER_SIZE), | ||
| 168 | .bInterval = 6, | ||
| 169 | }; | ||
| 170 | |||
| 171 | static struct usb_descriptor_header *fs_mtp_descs[] = { | ||
| 172 | (struct usb_descriptor_header *) &mtp_interface_desc, | ||
| 173 | (struct usb_descriptor_header *) &mtp_fullspeed_in_desc, | ||
| 174 | (struct usb_descriptor_header *) &mtp_fullspeed_out_desc, | ||
| 175 | (struct usb_descriptor_header *) &mtp_intr_desc, | ||
| 176 | NULL, | ||
| 177 | }; | ||
| 178 | |||
| 179 | static struct usb_descriptor_header *hs_mtp_descs[] = { | ||
| 180 | (struct usb_descriptor_header *) &mtp_interface_desc, | ||
| 181 | (struct usb_descriptor_header *) &mtp_highspeed_in_desc, | ||
| 182 | (struct usb_descriptor_header *) &mtp_highspeed_out_desc, | ||
| 183 | (struct usb_descriptor_header *) &mtp_intr_desc, | ||
| 184 | NULL, | ||
| 185 | }; | ||
| 186 | |||
| 187 | static struct usb_descriptor_header *fs_ptp_descs[] = { | ||
| 188 | (struct usb_descriptor_header *) &ptp_interface_desc, | ||
| 189 | (struct usb_descriptor_header *) &mtp_fullspeed_in_desc, | ||
| 190 | (struct usb_descriptor_header *) &mtp_fullspeed_out_desc, | ||
| 191 | (struct usb_descriptor_header *) &mtp_intr_desc, | ||
| 192 | NULL, | ||
| 193 | }; | ||
| 194 | |||
| 195 | static struct usb_descriptor_header *hs_ptp_descs[] = { | ||
| 196 | (struct usb_descriptor_header *) &ptp_interface_desc, | ||
| 197 | (struct usb_descriptor_header *) &mtp_highspeed_in_desc, | ||
| 198 | (struct usb_descriptor_header *) &mtp_highspeed_out_desc, | ||
| 199 | (struct usb_descriptor_header *) &mtp_intr_desc, | ||
| 200 | NULL, | ||
| 201 | }; | ||
| 202 | |||
| 203 | static struct usb_string mtp_string_defs[] = { | ||
| 204 | /* Naming interface "MTP" so libmtp will recognize us */ | ||
| 205 | [INTERFACE_STRING_INDEX].s = "MTP", | ||
| 206 | { }, /* end of list */ | ||
| 207 | }; | ||
| 208 | |||
| 209 | static struct usb_gadget_strings mtp_string_table = { | ||
| 210 | .language = 0x0409, /* en-US */ | ||
| 211 | .strings = mtp_string_defs, | ||
| 212 | }; | ||
| 213 | |||
| 214 | static struct usb_gadget_strings *mtp_strings[] = { | ||
| 215 | &mtp_string_table, | ||
| 216 | NULL, | ||
| 217 | }; | ||
| 218 | |||
| 219 | /* Microsoft MTP OS String */ | ||
| 220 | static u8 mtp_os_string[] = { | ||
| 221 | 18, /* sizeof(mtp_os_string) */ | ||
| 222 | USB_DT_STRING, | ||
| 223 | /* Signature field: "MSFT100" */ | ||
| 224 | 'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0, | ||
| 225 | /* vendor code */ | ||
| 226 | 1, | ||
| 227 | /* padding */ | ||
| 228 | 0 | ||
| 229 | }; | ||
| 230 | |||
| 231 | /* Microsoft Extended Configuration Descriptor Header Section */ | ||
| 232 | struct mtp_ext_config_desc_header { | ||
| 233 | __le32 dwLength; | ||
| 234 | __u16 bcdVersion; | ||
| 235 | __le16 wIndex; | ||
| 236 | __u8 bCount; | ||
| 237 | __u8 reserved[7]; | ||
| 238 | }; | ||
| 239 | |||
| 240 | /* Microsoft Extended Configuration Descriptor Function Section */ | ||
| 241 | struct mtp_ext_config_desc_function { | ||
| 242 | __u8 bFirstInterfaceNumber; | ||
| 243 | __u8 bInterfaceCount; | ||
| 244 | __u8 compatibleID[8]; | ||
| 245 | __u8 subCompatibleID[8]; | ||
| 246 | __u8 reserved[6]; | ||
| 247 | }; | ||
| 248 | |||
| 249 | /* MTP Extended Configuration Descriptor */ | ||
| 250 | struct { | ||
| 251 | struct mtp_ext_config_desc_header header; | ||
| 252 | struct mtp_ext_config_desc_function function; | ||
| 253 | } mtp_ext_config_desc = { | ||
| 254 | .header = { | ||
| 255 | .dwLength = __constant_cpu_to_le32(sizeof(mtp_ext_config_desc)), | ||
| 256 | .bcdVersion = __constant_cpu_to_le16(0x0100), | ||
| 257 | .wIndex = __constant_cpu_to_le16(4), | ||
| 258 | .bCount = __constant_cpu_to_le16(1), | ||
| 259 | }, | ||
| 260 | .function = { | ||
| 261 | .bFirstInterfaceNumber = 0, | ||
| 262 | .bInterfaceCount = 1, | ||
| 263 | .compatibleID = { 'M', 'T', 'P' }, | ||
| 264 | }, | ||
| 265 | }; | ||
| 266 | |||
| 267 | struct mtp_device_status { | ||
| 268 | __le16 wLength; | ||
| 269 | __le16 wCode; | ||
| 270 | }; | ||
| 271 | |||
| 272 | /* temporary variable used between mtp_open() and mtp_gadget_bind() */ | ||
| 273 | static struct mtp_dev *_mtp_dev; | ||
| 274 | |||
| 275 | static inline struct mtp_dev *func_to_mtp(struct usb_function *f) | ||
| 276 | { | ||
| 277 | return container_of(f, struct mtp_dev, function); | ||
| 278 | } | ||
| 279 | |||
| 280 | static struct usb_request *mtp_request_new(struct usb_ep *ep, int buffer_size) | ||
| 281 | { | ||
| 282 | struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); | ||
| 283 | if (!req) | ||
| 284 | return NULL; | ||
| 285 | |||
| 286 | /* now allocate buffers for the requests */ | ||
| 287 | req->buf = kmalloc(buffer_size, GFP_KERNEL); | ||
| 288 | if (!req->buf) { | ||
| 289 | usb_ep_free_request(ep, req); | ||
| 290 | return NULL; | ||
| 291 | } | ||
| 292 | |||
| 293 | return req; | ||
| 294 | } | ||
| 295 | |||
| 296 | static void mtp_request_free(struct usb_request *req, struct usb_ep *ep) | ||
| 297 | { | ||
| 298 | if (req) { | ||
| 299 | kfree(req->buf); | ||
| 300 | usb_ep_free_request(ep, req); | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | static inline int mtp_lock(atomic_t *excl) | ||
| 305 | { | ||
| 306 | if (atomic_inc_return(excl) == 1) { | ||
| 307 | return 0; | ||
| 308 | } else { | ||
| 309 | atomic_dec(excl); | ||
| 310 | return -1; | ||
| 311 | } | ||
| 312 | } | ||
| 313 | |||
| 314 | static inline void mtp_unlock(atomic_t *excl) | ||
| 315 | { | ||
| 316 | atomic_dec(excl); | ||
| 317 | } | ||
| 318 | |||
| 319 | /* add a request to the tail of a list */ | ||
| 320 | static void mtp_req_put(struct mtp_dev *dev, struct list_head *head, | ||
| 321 | struct usb_request *req) | ||
| 322 | { | ||
| 323 | unsigned long flags; | ||
| 324 | |||
| 325 | spin_lock_irqsave(&dev->lock, flags); | ||
| 326 | list_add_tail(&req->list, head); | ||
| 327 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 328 | } | ||
| 329 | |||
| 330 | /* remove a request from the head of a list */ | ||
| 331 | static struct usb_request | ||
| 332 | *mtp_req_get(struct mtp_dev *dev, struct list_head *head) | ||
| 333 | { | ||
| 334 | unsigned long flags; | ||
| 335 | struct usb_request *req; | ||
| 336 | |||
| 337 | spin_lock_irqsave(&dev->lock, flags); | ||
| 338 | if (list_empty(head)) { | ||
| 339 | req = 0; | ||
| 340 | } else { | ||
| 341 | req = list_first_entry(head, struct usb_request, list); | ||
| 342 | list_del(&req->list); | ||
| 343 | } | ||
| 344 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 345 | return req; | ||
| 346 | } | ||
| 347 | |||
| 348 | static void mtp_complete_in(struct usb_ep *ep, struct usb_request *req) | ||
| 349 | { | ||
| 350 | struct mtp_dev *dev = _mtp_dev; | ||
| 351 | |||
| 352 | if (req->status != 0) | ||
| 353 | dev->state = STATE_ERROR; | ||
| 354 | |||
| 355 | mtp_req_put(dev, &dev->tx_idle, req); | ||
| 356 | |||
| 357 | wake_up(&dev->write_wq); | ||
| 358 | } | ||
| 359 | |||
| 360 | static void mtp_complete_out(struct usb_ep *ep, struct usb_request *req) | ||
| 361 | { | ||
| 362 | struct mtp_dev *dev = _mtp_dev; | ||
| 363 | |||
| 364 | dev->rx_done = 1; | ||
| 365 | if (req->status != 0) | ||
| 366 | dev->state = STATE_ERROR; | ||
| 367 | |||
| 368 | wake_up(&dev->read_wq); | ||
| 369 | } | ||
| 370 | |||
| 371 | static void mtp_complete_intr(struct usb_ep *ep, struct usb_request *req) | ||
| 372 | { | ||
| 373 | struct mtp_dev *dev = _mtp_dev; | ||
| 374 | |||
| 375 | if (req->status != 0) | ||
| 376 | dev->state = STATE_ERROR; | ||
| 377 | |||
| 378 | mtp_req_put(dev, &dev->intr_idle, req); | ||
| 379 | |||
| 380 | wake_up(&dev->intr_wq); | ||
| 381 | } | ||
| 382 | |||
| 383 | static int mtp_create_bulk_endpoints(struct mtp_dev *dev, | ||
| 384 | struct usb_endpoint_descriptor *in_desc, | ||
| 385 | struct usb_endpoint_descriptor *out_desc, | ||
| 386 | struct usb_endpoint_descriptor *intr_desc) | ||
| 387 | { | ||
| 388 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 389 | struct usb_request *req; | ||
| 390 | struct usb_ep *ep; | ||
| 391 | int i; | ||
| 392 | |||
| 393 | DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); | ||
| 394 | |||
| 395 | ep = usb_ep_autoconfig(cdev->gadget, in_desc); | ||
| 396 | if (!ep) { | ||
| 397 | DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); | ||
| 398 | return -ENODEV; | ||
| 399 | } | ||
| 400 | DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); | ||
| 401 | ep->driver_data = dev; /* claim the endpoint */ | ||
| 402 | dev->ep_in = ep; | ||
| 403 | |||
| 404 | ep = usb_ep_autoconfig(cdev->gadget, out_desc); | ||
| 405 | if (!ep) { | ||
| 406 | DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); | ||
| 407 | return -ENODEV; | ||
| 408 | } | ||
| 409 | DBG(cdev, "usb_ep_autoconfig for mtp ep_out got %s\n", ep->name); | ||
| 410 | ep->driver_data = dev; /* claim the endpoint */ | ||
| 411 | dev->ep_out = ep; | ||
| 412 | |||
| 413 | ep = usb_ep_autoconfig(cdev->gadget, out_desc); | ||
| 414 | if (!ep) { | ||
| 415 | DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); | ||
| 416 | return -ENODEV; | ||
| 417 | } | ||
| 418 | DBG(cdev, "usb_ep_autoconfig for mtp ep_out got %s\n", ep->name); | ||
| 419 | ep->driver_data = dev; /* claim the endpoint */ | ||
| 420 | dev->ep_out = ep; | ||
| 421 | |||
| 422 | ep = usb_ep_autoconfig(cdev->gadget, intr_desc); | ||
| 423 | if (!ep) { | ||
| 424 | DBG(cdev, "usb_ep_autoconfig for ep_intr failed\n"); | ||
| 425 | return -ENODEV; | ||
| 426 | } | ||
| 427 | DBG(cdev, "usb_ep_autoconfig for mtp ep_intr got %s\n", ep->name); | ||
| 428 | ep->driver_data = dev; /* claim the endpoint */ | ||
| 429 | dev->ep_intr = ep; | ||
| 430 | |||
| 431 | /* now allocate requests for our endpoints */ | ||
| 432 | for (i = 0; i < TX_REQ_MAX; i++) { | ||
| 433 | req = mtp_request_new(dev->ep_in, MTP_BULK_BUFFER_SIZE); | ||
| 434 | if (!req) | ||
| 435 | goto fail; | ||
| 436 | req->complete = mtp_complete_in; | ||
| 437 | mtp_req_put(dev, &dev->tx_idle, req); | ||
| 438 | } | ||
| 439 | for (i = 0; i < RX_REQ_MAX; i++) { | ||
| 440 | req = mtp_request_new(dev->ep_out, MTP_BULK_BUFFER_SIZE); | ||
| 441 | if (!req) | ||
| 442 | goto fail; | ||
| 443 | req->complete = mtp_complete_out; | ||
| 444 | dev->rx_req[i] = req; | ||
| 445 | } | ||
| 446 | for (i = 0; i < INTR_REQ_MAX; i++) { | ||
| 447 | req = mtp_request_new(dev->ep_intr, INTR_BUFFER_SIZE); | ||
| 448 | if (!req) | ||
| 449 | goto fail; | ||
| 450 | req->complete = mtp_complete_intr; | ||
| 451 | mtp_req_put(dev, &dev->intr_idle, req); | ||
| 452 | } | ||
| 453 | |||
| 454 | return 0; | ||
| 455 | |||
| 456 | fail: | ||
| 457 | printk(KERN_ERR "mtp_bind() could not allocate requests\n"); | ||
| 458 | return -1; | ||
| 459 | } | ||
| 460 | |||
| 461 | static ssize_t mtp_read(struct file *fp, char __user *buf, | ||
| 462 | size_t count, loff_t *pos) | ||
| 463 | { | ||
| 464 | struct mtp_dev *dev = fp->private_data; | ||
| 465 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 466 | struct usb_request *req; | ||
| 467 | int r = count, xfer; | ||
| 468 | int ret = 0; | ||
| 469 | |||
| 470 | DBG(cdev, "mtp_read(%d)\n", count); | ||
| 471 | |||
| 472 | if (count > MTP_BULK_BUFFER_SIZE) | ||
| 473 | return -EINVAL; | ||
| 474 | |||
| 475 | /* we will block until we're online */ | ||
| 476 | DBG(cdev, "mtp_read: waiting for online state\n"); | ||
| 477 | ret = wait_event_interruptible(dev->read_wq, | ||
| 478 | dev->state != STATE_OFFLINE); | ||
| 479 | if (ret < 0) { | ||
| 480 | r = ret; | ||
| 481 | goto done; | ||
| 482 | } | ||
| 483 | spin_lock_irq(&dev->lock); | ||
| 484 | if (dev->state == STATE_CANCELED) { | ||
| 485 | /* report cancelation to userspace */ | ||
| 486 | dev->state = STATE_READY; | ||
| 487 | spin_unlock_irq(&dev->lock); | ||
| 488 | return -ECANCELED; | ||
| 489 | } | ||
| 490 | dev->state = STATE_BUSY; | ||
| 491 | spin_unlock_irq(&dev->lock); | ||
| 492 | |||
| 493 | requeue_req: | ||
| 494 | /* queue a request */ | ||
| 495 | req = dev->rx_req[0]; | ||
| 496 | req->length = count; | ||
| 497 | dev->rx_done = 0; | ||
| 498 | ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); | ||
| 499 | if (ret < 0) { | ||
| 500 | r = -EIO; | ||
| 501 | goto done; | ||
| 502 | } else { | ||
| 503 | DBG(cdev, "rx %p queue\n", req); | ||
| 504 | } | ||
| 505 | |||
| 506 | /* wait for a request to complete */ | ||
| 507 | ret = wait_event_interruptible(dev->read_wq, dev->rx_done); | ||
| 508 | if (ret < 0) { | ||
| 509 | r = ret; | ||
| 510 | usb_ep_dequeue(dev->ep_out, req); | ||
| 511 | goto done; | ||
| 512 | } | ||
| 513 | if (dev->state == STATE_BUSY) { | ||
| 514 | /* If we got a 0-len packet, throw it back and try again. */ | ||
| 515 | if (req->actual == 0) | ||
| 516 | goto requeue_req; | ||
| 517 | |||
| 518 | DBG(cdev, "rx %p %d\n", req, req->actual); | ||
| 519 | xfer = (req->actual < count) ? req->actual : count; | ||
| 520 | r = xfer; | ||
| 521 | if (copy_to_user(buf, req->buf, xfer)) | ||
| 522 | r = -EFAULT; | ||
| 523 | } else | ||
| 524 | r = -EIO; | ||
| 525 | |||
| 526 | done: | ||
| 527 | spin_lock_irq(&dev->lock); | ||
| 528 | if (dev->state == STATE_CANCELED) | ||
| 529 | r = -ECANCELED; | ||
| 530 | else if (dev->state != STATE_OFFLINE) | ||
| 531 | dev->state = STATE_READY; | ||
| 532 | spin_unlock_irq(&dev->lock); | ||
| 533 | |||
| 534 | DBG(cdev, "mtp_read returning %d\n", r); | ||
| 535 | return r; | ||
| 536 | } | ||
| 537 | |||
| 538 | static ssize_t mtp_write(struct file *fp, const char __user *buf, | ||
| 539 | size_t count, loff_t *pos) | ||
| 540 | { | ||
| 541 | struct mtp_dev *dev = fp->private_data; | ||
| 542 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 543 | struct usb_request *req = 0; | ||
| 544 | int r = count, xfer; | ||
| 545 | int sendZLP = 0; | ||
| 546 | int ret; | ||
| 547 | |||
| 548 | DBG(cdev, "mtp_write(%d)\n", count); | ||
| 549 | |||
| 550 | spin_lock_irq(&dev->lock); | ||
| 551 | if (dev->state == STATE_CANCELED) { | ||
| 552 | /* report cancelation to userspace */ | ||
| 553 | dev->state = STATE_READY; | ||
| 554 | spin_unlock_irq(&dev->lock); | ||
| 555 | return -ECANCELED; | ||
| 556 | } | ||
| 557 | if (dev->state == STATE_OFFLINE) { | ||
| 558 | spin_unlock_irq(&dev->lock); | ||
| 559 | return -ENODEV; | ||
| 560 | } | ||
| 561 | dev->state = STATE_BUSY; | ||
| 562 | spin_unlock_irq(&dev->lock); | ||
| 563 | |||
| 564 | /* we need to send a zero length packet to signal the end of transfer | ||
| 565 | * if the transfer size is aligned to a packet boundary. | ||
| 566 | */ | ||
| 567 | if ((count & (dev->ep_in->maxpacket - 1)) == 0) { | ||
| 568 | sendZLP = 1; | ||
| 569 | } | ||
| 570 | |||
| 571 | while (count > 0 || sendZLP) { | ||
| 572 | /* so we exit after sending ZLP */ | ||
| 573 | if (count == 0) | ||
| 574 | sendZLP = 0; | ||
| 575 | |||
| 576 | if (dev->state != STATE_BUSY) { | ||
| 577 | DBG(cdev, "mtp_write dev->error\n"); | ||
| 578 | r = -EIO; | ||
| 579 | break; | ||
| 580 | } | ||
| 581 | |||
| 582 | /* get an idle tx request to use */ | ||
| 583 | req = 0; | ||
| 584 | ret = wait_event_interruptible(dev->write_wq, | ||
| 585 | ((req = mtp_req_get(dev, &dev->tx_idle)) | ||
| 586 | || dev->state != STATE_BUSY)); | ||
| 587 | if (!req) { | ||
| 588 | r = ret; | ||
| 589 | break; | ||
| 590 | } | ||
| 591 | |||
| 592 | if (count > MTP_BULK_BUFFER_SIZE) | ||
| 593 | xfer = MTP_BULK_BUFFER_SIZE; | ||
| 594 | else | ||
| 595 | xfer = count; | ||
| 596 | if (xfer && copy_from_user(req->buf, buf, xfer)) { | ||
| 597 | r = -EFAULT; | ||
| 598 | break; | ||
| 599 | } | ||
| 600 | |||
| 601 | req->length = xfer; | ||
| 602 | ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); | ||
| 603 | if (ret < 0) { | ||
| 604 | DBG(cdev, "mtp_write: xfer error %d\n", ret); | ||
| 605 | r = -EIO; | ||
| 606 | break; | ||
| 607 | } | ||
| 608 | |||
| 609 | buf += xfer; | ||
| 610 | count -= xfer; | ||
| 611 | |||
| 612 | /* zero this so we don't try to free it on error exit */ | ||
| 613 | req = 0; | ||
| 614 | } | ||
| 615 | |||
| 616 | if (req) | ||
| 617 | mtp_req_put(dev, &dev->tx_idle, req); | ||
| 618 | |||
| 619 | spin_lock_irq(&dev->lock); | ||
| 620 | if (dev->state == STATE_CANCELED) | ||
| 621 | r = -ECANCELED; | ||
| 622 | else if (dev->state != STATE_OFFLINE) | ||
| 623 | dev->state = STATE_READY; | ||
| 624 | spin_unlock_irq(&dev->lock); | ||
| 625 | |||
| 626 | DBG(cdev, "mtp_write returning %d\n", r); | ||
| 627 | return r; | ||
| 628 | } | ||
| 629 | |||
| 630 | /* read from a local file and write to USB */ | ||
| 631 | static void send_file_work(struct work_struct *data) { | ||
| 632 | struct mtp_dev *dev = container_of(data, struct mtp_dev, send_file_work); | ||
| 633 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 634 | struct usb_request *req = 0; | ||
| 635 | struct mtp_data_header *header; | ||
| 636 | struct file *filp; | ||
| 637 | loff_t offset; | ||
| 638 | int64_t count; | ||
| 639 | int xfer, ret, hdr_size; | ||
| 640 | int r = 0; | ||
| 641 | int sendZLP = 0; | ||
| 642 | |||
| 643 | /* read our parameters */ | ||
| 644 | smp_rmb(); | ||
| 645 | filp = dev->xfer_file; | ||
| 646 | offset = dev->xfer_file_offset; | ||
| 647 | count = dev->xfer_file_length; | ||
| 648 | |||
| 649 | DBG(cdev, "send_file_work(%lld %lld)\n", offset, count); | ||
| 650 | |||
| 651 | if (dev->xfer_send_header) { | ||
| 652 | hdr_size = sizeof(struct mtp_data_header); | ||
| 653 | count += hdr_size; | ||
| 654 | } else { | ||
| 655 | hdr_size = 0; | ||
| 656 | } | ||
| 657 | |||
| 658 | /* we need to send a zero length packet to signal the end of transfer | ||
| 659 | * if the transfer size is aligned to a packet boundary. | ||
| 660 | */ | ||
| 661 | if ((count & (dev->ep_in->maxpacket - 1)) == 0) { | ||
| 662 | sendZLP = 1; | ||
| 663 | } | ||
| 664 | |||
| 665 | while (count > 0 || sendZLP) { | ||
| 666 | /* so we exit after sending ZLP */ | ||
| 667 | if (count == 0) | ||
| 668 | sendZLP = 0; | ||
| 669 | |||
| 670 | /* get an idle tx request to use */ | ||
| 671 | req = 0; | ||
| 672 | ret = wait_event_interruptible(dev->write_wq, | ||
| 673 | (req = mtp_req_get(dev, &dev->tx_idle)) | ||
| 674 | || dev->state != STATE_BUSY); | ||
| 675 | if (dev->state == STATE_CANCELED) { | ||
| 676 | r = -ECANCELED; | ||
| 677 | break; | ||
| 678 | } | ||
| 679 | if (!req) { | ||
| 680 | r = ret; | ||
| 681 | break; | ||
| 682 | } | ||
| 683 | |||
| 684 | if (count > MTP_BULK_BUFFER_SIZE) | ||
| 685 | xfer = MTP_BULK_BUFFER_SIZE; | ||
| 686 | else | ||
| 687 | xfer = count; | ||
| 688 | |||
| 689 | if (hdr_size) { | ||
| 690 | /* prepend MTP data header */ | ||
| 691 | header = (struct mtp_data_header *)req->buf; | ||
| 692 | header->length = __cpu_to_le32(count); | ||
| 693 | header->type = __cpu_to_le16(2); /* data packet */ | ||
| 694 | header->command = __cpu_to_le16(dev->xfer_command); | ||
| 695 | header->transaction_id = __cpu_to_le32(dev->xfer_transaction_id); | ||
| 696 | } | ||
| 697 | |||
| 698 | ret = vfs_read(filp, req->buf + hdr_size, xfer - hdr_size, &offset); | ||
| 699 | if (ret < 0) { | ||
| 700 | r = ret; | ||
| 701 | break; | ||
| 702 | } | ||
| 703 | xfer = ret + hdr_size; | ||
| 704 | hdr_size = 0; | ||
| 705 | |||
| 706 | req->length = xfer; | ||
| 707 | ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); | ||
| 708 | if (ret < 0) { | ||
| 709 | DBG(cdev, "send_file_work: xfer error %d\n", ret); | ||
| 710 | dev->state = STATE_ERROR; | ||
| 711 | r = -EIO; | ||
| 712 | break; | ||
| 713 | } | ||
| 714 | |||
| 715 | count -= xfer; | ||
| 716 | |||
| 717 | /* zero this so we don't try to free it on error exit */ | ||
| 718 | req = 0; | ||
| 719 | } | ||
| 720 | |||
| 721 | if (req) | ||
| 722 | mtp_req_put(dev, &dev->tx_idle, req); | ||
| 723 | |||
| 724 | DBG(cdev, "send_file_work returning %d\n", r); | ||
| 725 | /* write the result */ | ||
| 726 | dev->xfer_result = r; | ||
| 727 | smp_wmb(); | ||
| 728 | } | ||
| 729 | |||
| 730 | /* read from USB and write to a local file */ | ||
| 731 | static void receive_file_work(struct work_struct *data) | ||
| 732 | { | ||
| 733 | struct mtp_dev *dev = container_of(data, struct mtp_dev, receive_file_work); | ||
| 734 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 735 | struct usb_request *read_req = NULL, *write_req = NULL; | ||
| 736 | struct file *filp; | ||
| 737 | loff_t offset; | ||
| 738 | int64_t count; | ||
| 739 | int ret, cur_buf = 0; | ||
| 740 | int r = 0; | ||
| 741 | |||
| 742 | /* read our parameters */ | ||
| 743 | smp_rmb(); | ||
| 744 | filp = dev->xfer_file; | ||
| 745 | offset = dev->xfer_file_offset; | ||
| 746 | count = dev->xfer_file_length; | ||
| 747 | |||
| 748 | DBG(cdev, "receive_file_work(%lld)\n", count); | ||
| 749 | |||
| 750 | while (count > 0 || write_req) { | ||
| 751 | if (count > 0) { | ||
| 752 | /* queue a request */ | ||
| 753 | read_req = dev->rx_req[cur_buf]; | ||
| 754 | cur_buf = (cur_buf + 1) % RX_REQ_MAX; | ||
| 755 | |||
| 756 | read_req->length = (count > MTP_BULK_BUFFER_SIZE | ||
| 757 | ? MTP_BULK_BUFFER_SIZE : count); | ||
| 758 | dev->rx_done = 0; | ||
| 759 | ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL); | ||
| 760 | if (ret < 0) { | ||
| 761 | r = -EIO; | ||
| 762 | dev->state = STATE_ERROR; | ||
| 763 | break; | ||
| 764 | } | ||
| 765 | } | ||
| 766 | |||
| 767 | if (write_req) { | ||
| 768 | DBG(cdev, "rx %p %d\n", write_req, write_req->actual); | ||
| 769 | ret = vfs_write(filp, write_req->buf, write_req->actual, | ||
| 770 | &offset); | ||
| 771 | DBG(cdev, "vfs_write %d\n", ret); | ||
| 772 | if (ret != write_req->actual) { | ||
| 773 | r = -EIO; | ||
| 774 | dev->state = STATE_ERROR; | ||
| 775 | break; | ||
| 776 | } | ||
| 777 | write_req = NULL; | ||
| 778 | } | ||
| 779 | |||
| 780 | if (read_req) { | ||
| 781 | /* wait for our last read to complete */ | ||
| 782 | ret = wait_event_interruptible(dev->read_wq, | ||
| 783 | dev->rx_done || dev->state != STATE_BUSY); | ||
| 784 | if (dev->state == STATE_CANCELED) { | ||
| 785 | r = -ECANCELED; | ||
| 786 | if (!dev->rx_done) | ||
| 787 | usb_ep_dequeue(dev->ep_out, read_req); | ||
| 788 | break; | ||
| 789 | } | ||
| 790 | /* if xfer_file_length is 0xFFFFFFFF, then we read until | ||
| 791 | * we get a zero length packet | ||
| 792 | */ | ||
| 793 | if (count != 0xFFFFFFFF) | ||
| 794 | count -= read_req->actual; | ||
| 795 | if (read_req->actual < read_req->length) { | ||
| 796 | /* short packet is used to signal EOF for sizes > 4 gig */ | ||
| 797 | DBG(cdev, "got short packet\n"); | ||
| 798 | count = 0; | ||
| 799 | } | ||
| 800 | |||
| 801 | write_req = read_req; | ||
| 802 | read_req = NULL; | ||
| 803 | } | ||
| 804 | } | ||
| 805 | |||
| 806 | DBG(cdev, "receive_file_work returning %d\n", r); | ||
| 807 | /* write the result */ | ||
| 808 | dev->xfer_result = r; | ||
| 809 | smp_wmb(); | ||
| 810 | } | ||
| 811 | |||
| 812 | static int mtp_send_event(struct mtp_dev *dev, struct mtp_event *event) | ||
| 813 | { | ||
| 814 | struct usb_request *req= NULL; | ||
| 815 | int ret; | ||
| 816 | int length = event->length; | ||
| 817 | |||
| 818 | DBG(dev->cdev, "mtp_send_event(%d)\n", event->length); | ||
| 819 | |||
| 820 | if (length < 0 || length > INTR_BUFFER_SIZE) | ||
| 821 | return -EINVAL; | ||
| 822 | if (dev->state == STATE_OFFLINE) | ||
| 823 | return -ENODEV; | ||
| 824 | |||
| 825 | ret = wait_event_interruptible_timeout(dev->intr_wq, | ||
| 826 | (req = mtp_req_get(dev, &dev->intr_idle)), msecs_to_jiffies(1000)); | ||
| 827 | if (!req) | ||
| 828 | return -ETIME; | ||
| 829 | |||
| 830 | if (copy_from_user(req->buf, (void __user *)event->data, length)) { | ||
| 831 | mtp_req_put(dev, &dev->intr_idle, req); | ||
| 832 | return -EFAULT; | ||
| 833 | } | ||
| 834 | req->length = length; | ||
| 835 | ret = usb_ep_queue(dev->ep_intr, req, GFP_KERNEL); | ||
| 836 | if (ret) | ||
| 837 | mtp_req_put(dev, &dev->intr_idle, req); | ||
| 838 | |||
| 839 | return ret; | ||
| 840 | } | ||
| 841 | |||
| 842 | static long mtp_ioctl(struct file *fp, unsigned code, unsigned long value) | ||
| 843 | { | ||
| 844 | struct mtp_dev *dev = fp->private_data; | ||
| 845 | struct file *filp = NULL; | ||
| 846 | int ret = -EINVAL; | ||
| 847 | |||
| 848 | if (mtp_lock(&dev->ioctl_excl)) | ||
| 849 | return -EBUSY; | ||
| 850 | |||
| 851 | switch (code) { | ||
| 852 | case MTP_SEND_FILE: | ||
| 853 | case MTP_RECEIVE_FILE: | ||
| 854 | case MTP_SEND_FILE_WITH_HEADER: | ||
| 855 | { | ||
| 856 | struct mtp_file_range mfr; | ||
| 857 | struct work_struct *work; | ||
| 858 | |||
| 859 | spin_lock_irq(&dev->lock); | ||
| 860 | if (dev->state == STATE_CANCELED) { | ||
| 861 | /* report cancelation to userspace */ | ||
| 862 | dev->state = STATE_READY; | ||
| 863 | spin_unlock_irq(&dev->lock); | ||
| 864 | ret = -ECANCELED; | ||
| 865 | goto out; | ||
| 866 | } | ||
| 867 | if (dev->state == STATE_OFFLINE) { | ||
| 868 | spin_unlock_irq(&dev->lock); | ||
| 869 | ret = -ENODEV; | ||
| 870 | goto out; | ||
| 871 | } | ||
| 872 | dev->state = STATE_BUSY; | ||
| 873 | spin_unlock_irq(&dev->lock); | ||
| 874 | |||
| 875 | if (copy_from_user(&mfr, (void __user *)value, sizeof(mfr))) { | ||
| 876 | ret = -EFAULT; | ||
| 877 | goto fail; | ||
| 878 | } | ||
| 879 | /* hold a reference to the file while we are working with it */ | ||
| 880 | filp = fget(mfr.fd); | ||
| 881 | if (!filp) { | ||
| 882 | ret = -EBADF; | ||
| 883 | goto fail; | ||
| 884 | } | ||
| 885 | |||
| 886 | /* write the parameters */ | ||
| 887 | dev->xfer_file = filp; | ||
| 888 | dev->xfer_file_offset = mfr.offset; | ||
| 889 | dev->xfer_file_length = mfr.length; | ||
| 890 | smp_wmb(); | ||
| 891 | |||
| 892 | if (code == MTP_SEND_FILE_WITH_HEADER) { | ||
| 893 | work = &dev->send_file_work; | ||
| 894 | dev->xfer_send_header = 1; | ||
| 895 | dev->xfer_command = mfr.command; | ||
| 896 | dev->xfer_transaction_id = mfr.transaction_id; | ||
| 897 | } else if (code == MTP_SEND_FILE) { | ||
| 898 | work = &dev->send_file_work; | ||
| 899 | dev->xfer_send_header = 0; | ||
| 900 | } else { | ||
| 901 | work = &dev->receive_file_work; | ||
| 902 | } | ||
| 903 | |||
| 904 | /* We do the file transfer on a work queue so it will run | ||
| 905 | * in kernel context, which is necessary for vfs_read and | ||
| 906 | * vfs_write to use our buffers in the kernel address space. | ||
| 907 | */ | ||
| 908 | queue_work(dev->wq, work); | ||
| 909 | /* wait for operation to complete */ | ||
| 910 | flush_workqueue(dev->wq); | ||
| 911 | fput(filp); | ||
| 912 | |||
| 913 | /* read the result */ | ||
| 914 | smp_rmb(); | ||
| 915 | ret = dev->xfer_result; | ||
| 916 | break; | ||
| 917 | } | ||
| 918 | case MTP_SEND_EVENT: | ||
| 919 | { | ||
| 920 | struct mtp_event event; | ||
| 921 | /* return here so we don't change dev->state below, | ||
| 922 | * which would interfere with bulk transfer state. | ||
| 923 | */ | ||
| 924 | if (copy_from_user(&event, (void __user *)value, sizeof(event))) | ||
| 925 | ret = -EFAULT; | ||
| 926 | else | ||
| 927 | ret = mtp_send_event(dev, &event); | ||
| 928 | goto out; | ||
| 929 | } | ||
| 930 | } | ||
| 931 | |||
| 932 | fail: | ||
| 933 | spin_lock_irq(&dev->lock); | ||
| 934 | if (dev->state == STATE_CANCELED) | ||
| 935 | ret = -ECANCELED; | ||
| 936 | else if (dev->state != STATE_OFFLINE) | ||
| 937 | dev->state = STATE_READY; | ||
| 938 | spin_unlock_irq(&dev->lock); | ||
| 939 | out: | ||
| 940 | mtp_unlock(&dev->ioctl_excl); | ||
| 941 | DBG(dev->cdev, "ioctl returning %d\n", ret); | ||
| 942 | return ret; | ||
| 943 | } | ||
| 944 | |||
| 945 | static int mtp_open(struct inode *ip, struct file *fp) | ||
| 946 | { | ||
| 947 | printk(KERN_INFO "mtp_open\n"); | ||
| 948 | if (mtp_lock(&_mtp_dev->open_excl)) | ||
| 949 | return -EBUSY; | ||
| 950 | |||
| 951 | /* clear any error condition */ | ||
| 952 | if (_mtp_dev->state != STATE_OFFLINE) | ||
| 953 | _mtp_dev->state = STATE_READY; | ||
| 954 | |||
| 955 | fp->private_data = _mtp_dev; | ||
| 956 | return 0; | ||
| 957 | } | ||
| 958 | |||
| 959 | static int mtp_release(struct inode *ip, struct file *fp) | ||
| 960 | { | ||
| 961 | printk(KERN_INFO "mtp_release\n"); | ||
| 962 | |||
| 963 | mtp_unlock(&_mtp_dev->open_excl); | ||
| 964 | return 0; | ||
| 965 | } | ||
| 966 | |||
| 967 | /* file operations for /dev/mtp_usb */ | ||
| 968 | static const struct file_operations mtp_fops = { | ||
| 969 | .owner = THIS_MODULE, | ||
| 970 | .read = mtp_read, | ||
| 971 | .write = mtp_write, | ||
| 972 | .unlocked_ioctl = mtp_ioctl, | ||
| 973 | .open = mtp_open, | ||
| 974 | .release = mtp_release, | ||
| 975 | }; | ||
| 976 | |||
| 977 | static struct miscdevice mtp_device = { | ||
| 978 | .minor = MISC_DYNAMIC_MINOR, | ||
| 979 | .name = mtp_shortname, | ||
| 980 | .fops = &mtp_fops, | ||
| 981 | }; | ||
| 982 | |||
| 983 | static int mtp_ctrlrequest(struct usb_composite_dev *cdev, | ||
| 984 | const struct usb_ctrlrequest *ctrl) | ||
| 985 | { | ||
| 986 | struct mtp_dev *dev = _mtp_dev; | ||
| 987 | int value = -EOPNOTSUPP; | ||
| 988 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
| 989 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 990 | u16 w_length = le16_to_cpu(ctrl->wLength); | ||
| 991 | unsigned long flags; | ||
| 992 | |||
| 993 | VDBG(cdev, "mtp_ctrlrequest " | ||
| 994 | "%02x.%02x v%04x i%04x l%u\n", | ||
| 995 | ctrl->bRequestType, ctrl->bRequest, | ||
| 996 | w_value, w_index, w_length); | ||
| 997 | |||
| 998 | /* Handle MTP OS string */ | ||
| 999 | if (ctrl->bRequestType == | ||
| 1000 | (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) | ||
| 1001 | && ctrl->bRequest == USB_REQ_GET_DESCRIPTOR | ||
| 1002 | && (w_value >> 8) == USB_DT_STRING | ||
| 1003 | && (w_value & 0xFF) == MTP_OS_STRING_ID) { | ||
| 1004 | value = (w_length < sizeof(mtp_os_string) | ||
| 1005 | ? w_length : sizeof(mtp_os_string)); | ||
| 1006 | memcpy(cdev->req->buf, mtp_os_string, value); | ||
| 1007 | } else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) { | ||
| 1008 | /* Handle MTP OS descriptor */ | ||
| 1009 | DBG(cdev, "vendor request: %d index: %d value: %d length: %d\n", | ||
| 1010 | ctrl->bRequest, w_index, w_value, w_length); | ||
| 1011 | |||
| 1012 | if (ctrl->bRequest == 1 | ||
| 1013 | && (ctrl->bRequestType & USB_DIR_IN) | ||
| 1014 | && (w_index == 4 || w_index == 5)) { | ||
| 1015 | value = (w_length < sizeof(mtp_ext_config_desc) ? | ||
| 1016 | w_length : sizeof(mtp_ext_config_desc)); | ||
| 1017 | memcpy(cdev->req->buf, &mtp_ext_config_desc, value); | ||
| 1018 | } | ||
| 1019 | } else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) { | ||
| 1020 | DBG(cdev, "class request: %d index: %d value: %d length: %d\n", | ||
| 1021 | ctrl->bRequest, w_index, w_value, w_length); | ||
| 1022 | |||
| 1023 | if (ctrl->bRequest == MTP_REQ_CANCEL && w_index == 0 | ||
| 1024 | && w_value == 0) { | ||
| 1025 | DBG(cdev, "MTP_REQ_CANCEL\n"); | ||
| 1026 | |||
| 1027 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1028 | if (dev->state == STATE_BUSY) { | ||
| 1029 | dev->state = STATE_CANCELED; | ||
| 1030 | wake_up(&dev->read_wq); | ||
| 1031 | wake_up(&dev->write_wq); | ||
| 1032 | } | ||
| 1033 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1034 | |||
| 1035 | /* We need to queue a request to read the remaining | ||
| 1036 | * bytes, but we don't actually need to look at | ||
| 1037 | * the contents. | ||
| 1038 | */ | ||
| 1039 | value = w_length; | ||
| 1040 | } else if (ctrl->bRequest == MTP_REQ_GET_DEVICE_STATUS | ||
| 1041 | && w_index == 0 && w_value == 0) { | ||
| 1042 | struct mtp_device_status *status = cdev->req->buf; | ||
| 1043 | status->wLength = | ||
| 1044 | __constant_cpu_to_le16(sizeof(*status)); | ||
| 1045 | |||
| 1046 | DBG(cdev, "MTP_REQ_GET_DEVICE_STATUS\n"); | ||
| 1047 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1048 | /* device status is "busy" until we report | ||
| 1049 | * the cancelation to userspace | ||
| 1050 | */ | ||
| 1051 | if (dev->state == STATE_CANCELED) | ||
| 1052 | status->wCode = | ||
| 1053 | __cpu_to_le16(MTP_RESPONSE_DEVICE_BUSY); | ||
| 1054 | else | ||
| 1055 | status->wCode = | ||
| 1056 | __cpu_to_le16(MTP_RESPONSE_OK); | ||
| 1057 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1058 | value = sizeof(*status); | ||
| 1059 | } | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | /* respond with data transfer or status phase? */ | ||
| 1063 | if (value >= 0) { | ||
| 1064 | int rc; | ||
| 1065 | cdev->req->zero = value < w_length; | ||
| 1066 | cdev->req->length = value; | ||
| 1067 | rc = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); | ||
| 1068 | if (rc < 0) | ||
| 1069 | ERROR(cdev, "%s setup response queue error\n", __func__); | ||
| 1070 | } | ||
| 1071 | return value; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | static int | ||
| 1075 | mtp_function_bind(struct usb_configuration *c, struct usb_function *f) | ||
| 1076 | { | ||
| 1077 | struct usb_composite_dev *cdev = c->cdev; | ||
| 1078 | struct mtp_dev *dev = func_to_mtp(f); | ||
| 1079 | int id; | ||
| 1080 | int ret; | ||
| 1081 | |||
| 1082 | dev->cdev = cdev; | ||
| 1083 | DBG(cdev, "mtp_function_bind dev: %p\n", dev); | ||
| 1084 | |||
| 1085 | /* allocate interface ID(s) */ | ||
| 1086 | id = usb_interface_id(c, f); | ||
| 1087 | if (id < 0) | ||
| 1088 | return id; | ||
| 1089 | mtp_interface_desc.bInterfaceNumber = id; | ||
| 1090 | |||
| 1091 | /* allocate endpoints */ | ||
| 1092 | ret = mtp_create_bulk_endpoints(dev, &mtp_fullspeed_in_desc, | ||
| 1093 | &mtp_fullspeed_out_desc, &mtp_intr_desc); | ||
| 1094 | if (ret) | ||
| 1095 | return ret; | ||
| 1096 | |||
| 1097 | /* support high speed hardware */ | ||
| 1098 | if (gadget_is_dualspeed(c->cdev->gadget)) { | ||
| 1099 | mtp_highspeed_in_desc.bEndpointAddress = | ||
| 1100 | mtp_fullspeed_in_desc.bEndpointAddress; | ||
| 1101 | mtp_highspeed_out_desc.bEndpointAddress = | ||
| 1102 | mtp_fullspeed_out_desc.bEndpointAddress; | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", | ||
| 1106 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||
| 1107 | f->name, dev->ep_in->name, dev->ep_out->name); | ||
| 1108 | return 0; | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | static void | ||
| 1112 | mtp_function_unbind(struct usb_configuration *c, struct usb_function *f) | ||
| 1113 | { | ||
| 1114 | struct mtp_dev *dev = func_to_mtp(f); | ||
| 1115 | struct usb_request *req; | ||
| 1116 | int i; | ||
| 1117 | |||
| 1118 | while ((req = mtp_req_get(dev, &dev->tx_idle))) | ||
| 1119 | mtp_request_free(req, dev->ep_in); | ||
| 1120 | for (i = 0; i < RX_REQ_MAX; i++) | ||
| 1121 | mtp_request_free(dev->rx_req[i], dev->ep_out); | ||
| 1122 | while ((req = mtp_req_get(dev, &dev->intr_idle))) | ||
| 1123 | mtp_request_free(req, dev->ep_intr); | ||
| 1124 | dev->state = STATE_OFFLINE; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | static int mtp_function_set_alt(struct usb_function *f, | ||
| 1128 | unsigned intf, unsigned alt) | ||
| 1129 | { | ||
| 1130 | struct mtp_dev *dev = func_to_mtp(f); | ||
| 1131 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 1132 | int ret; | ||
| 1133 | |||
| 1134 | DBG(cdev, "mtp_function_set_alt intf: %d alt: %d\n", intf, alt); | ||
| 1135 | config_ep_by_speed(cdev->gadget, f, dev->ep_in); | ||
| 1136 | ret = usb_ep_enable(dev->ep_in); | ||
| 1137 | if (ret) | ||
| 1138 | return ret; | ||
| 1139 | config_ep_by_speed(cdev->gadget, f, dev->ep_out); | ||
| 1140 | ret = usb_ep_enable(dev->ep_out); | ||
| 1141 | if (ret) { | ||
| 1142 | usb_ep_disable(dev->ep_in); | ||
| 1143 | return ret; | ||
| 1144 | } | ||
| 1145 | dev->ep_intr->desc = &mtp_intr_desc; | ||
| 1146 | ret = usb_ep_enable(dev->ep_intr); | ||
| 1147 | if (ret) { | ||
| 1148 | usb_ep_disable(dev->ep_out); | ||
| 1149 | usb_ep_disable(dev->ep_in); | ||
| 1150 | return ret; | ||
| 1151 | } | ||
| 1152 | dev->state = STATE_READY; | ||
| 1153 | |||
| 1154 | /* readers may be blocked waiting for us to go online */ | ||
| 1155 | wake_up(&dev->read_wq); | ||
| 1156 | return 0; | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | static void mtp_function_disable(struct usb_function *f) | ||
| 1160 | { | ||
| 1161 | struct mtp_dev *dev = func_to_mtp(f); | ||
| 1162 | struct usb_composite_dev *cdev = dev->cdev; | ||
| 1163 | |||
| 1164 | DBG(cdev, "mtp_function_disable\n"); | ||
| 1165 | dev->state = STATE_OFFLINE; | ||
| 1166 | usb_ep_disable(dev->ep_in); | ||
| 1167 | usb_ep_disable(dev->ep_out); | ||
| 1168 | usb_ep_disable(dev->ep_intr); | ||
| 1169 | |||
| 1170 | /* readers may be blocked waiting for us to go online */ | ||
| 1171 | wake_up(&dev->read_wq); | ||
| 1172 | |||
| 1173 | VDBG(cdev, "%s disabled\n", dev->function.name); | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | static int mtp_bind_config(struct usb_configuration *c, bool ptp_config) | ||
| 1177 | { | ||
| 1178 | struct mtp_dev *dev = _mtp_dev; | ||
| 1179 | int ret = 0; | ||
| 1180 | |||
| 1181 | printk(KERN_INFO "mtp_bind_config\n"); | ||
| 1182 | |||
| 1183 | /* allocate a string ID for our interface */ | ||
| 1184 | if (mtp_string_defs[INTERFACE_STRING_INDEX].id == 0) { | ||
| 1185 | ret = usb_string_id(c->cdev); | ||
| 1186 | if (ret < 0) | ||
| 1187 | return ret; | ||
| 1188 | mtp_string_defs[INTERFACE_STRING_INDEX].id = ret; | ||
| 1189 | mtp_interface_desc.iInterface = ret; | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | dev->cdev = c->cdev; | ||
| 1193 | dev->function.name = "mtp"; | ||
| 1194 | dev->function.strings = mtp_strings; | ||
| 1195 | if (ptp_config) { | ||
| 1196 | dev->function.descriptors = fs_ptp_descs; | ||
| 1197 | dev->function.hs_descriptors = hs_ptp_descs; | ||
| 1198 | } else { | ||
| 1199 | dev->function.descriptors = fs_mtp_descs; | ||
| 1200 | dev->function.hs_descriptors = hs_mtp_descs; | ||
| 1201 | } | ||
| 1202 | dev->function.bind = mtp_function_bind; | ||
| 1203 | dev->function.unbind = mtp_function_unbind; | ||
| 1204 | dev->function.set_alt = mtp_function_set_alt; | ||
| 1205 | dev->function.disable = mtp_function_disable; | ||
| 1206 | |||
| 1207 | return usb_add_function(c, &dev->function); | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | static int mtp_setup(void) | ||
| 1211 | { | ||
| 1212 | struct mtp_dev *dev; | ||
| 1213 | int ret; | ||
| 1214 | |||
| 1215 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 1216 | if (!dev) | ||
| 1217 | return -ENOMEM; | ||
| 1218 | |||
| 1219 | spin_lock_init(&dev->lock); | ||
| 1220 | init_waitqueue_head(&dev->read_wq); | ||
| 1221 | init_waitqueue_head(&dev->write_wq); | ||
| 1222 | init_waitqueue_head(&dev->intr_wq); | ||
| 1223 | atomic_set(&dev->open_excl, 0); | ||
| 1224 | atomic_set(&dev->ioctl_excl, 0); | ||
| 1225 | INIT_LIST_HEAD(&dev->tx_idle); | ||
| 1226 | INIT_LIST_HEAD(&dev->intr_idle); | ||
| 1227 | |||
| 1228 | dev->wq = create_singlethread_workqueue("f_mtp"); | ||
| 1229 | if (!dev->wq) { | ||
| 1230 | ret = -ENOMEM; | ||
| 1231 | goto err1; | ||
| 1232 | } | ||
| 1233 | INIT_WORK(&dev->send_file_work, send_file_work); | ||
| 1234 | INIT_WORK(&dev->receive_file_work, receive_file_work); | ||
| 1235 | |||
| 1236 | _mtp_dev = dev; | ||
| 1237 | |||
| 1238 | ret = misc_register(&mtp_device); | ||
| 1239 | if (ret) | ||
| 1240 | goto err2; | ||
| 1241 | |||
| 1242 | return 0; | ||
| 1243 | |||
| 1244 | err2: | ||
| 1245 | destroy_workqueue(dev->wq); | ||
| 1246 | err1: | ||
| 1247 | _mtp_dev = NULL; | ||
| 1248 | kfree(dev); | ||
| 1249 | printk(KERN_ERR "mtp gadget driver failed to initialize\n"); | ||
| 1250 | return ret; | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | static void mtp_cleanup(void) | ||
| 1254 | { | ||
| 1255 | struct mtp_dev *dev = _mtp_dev; | ||
| 1256 | |||
| 1257 | if (!dev) | ||
| 1258 | return; | ||
| 1259 | |||
| 1260 | misc_deregister(&mtp_device); | ||
| 1261 | destroy_workqueue(dev->wq); | ||
| 1262 | _mtp_dev = NULL; | ||
| 1263 | kfree(dev); | ||
| 1264 | } | ||
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c new file mode 100644 index 00000000000..639e14a2fd1 --- /dev/null +++ b/drivers/usb/gadget/file_storage.c | |||
| @@ -0,0 +1,3631 @@ | |||
| 1 | /* | ||
| 2 | * file_storage.c -- File-backed USB Storage Gadget, for USB development | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003-2008 Alan Stern | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions, and the following disclaimer, | ||
| 12 | * without modification. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * 3. The names of the above-listed copyright holders may not be used | ||
| 17 | * to endorse or promote products derived from this software without | ||
| 18 | * specific prior written permission. | ||
| 19 | * | ||
| 20 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 21 | * GNU General Public License ("GPL") as published by the Free Software | ||
| 22 | * Foundation, either version 2 of that License or (at your option) any | ||
| 23 | * later version. | ||
| 24 | * | ||
| 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 26 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 27 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 28 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 29 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 30 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 31 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 36 | */ | ||
| 37 | |||
| 38 | |||
| 39 | /* | ||
| 40 | * The File-backed Storage Gadget acts as a USB Mass Storage device, | ||
| 41 | * appearing to the host as a disk drive or as a CD-ROM drive. In addition | ||
| 42 | * to providing an example of a genuinely useful gadget driver for a USB | ||
| 43 | * device, it also illustrates a technique of double-buffering for increased | ||
| 44 | * throughput. Last but not least, it gives an easy way to probe the | ||
| 45 | * behavior of the Mass Storage drivers in a USB host. | ||
| 46 | * | ||
| 47 | * Backing storage is provided by a regular file or a block device, specified | ||
| 48 | * by the "file" module parameter. Access can be limited to read-only by | ||
| 49 | * setting the optional "ro" module parameter. (For CD-ROM emulation, | ||
| 50 | * access is always read-only.) The gadget will indicate that it has | ||
| 51 | * removable media if the optional "removable" module parameter is set. | ||
| 52 | * | ||
| 53 | * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI), | ||
| 54 | * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected | ||
| 55 | * by the optional "transport" module parameter. It also supports the | ||
| 56 | * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03), | ||
| 57 | * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by | ||
| 58 | * the optional "protocol" module parameter. In addition, the default | ||
| 59 | * Vendor ID, Product ID, release number and serial number can be overridden. | ||
| 60 | * | ||
| 61 | * There is support for multiple logical units (LUNs), each of which has | ||
| 62 | * its own backing file. The number of LUNs can be set using the optional | ||
| 63 | * "luns" module parameter (anywhere from 1 to 8), and the corresponding | ||
| 64 | * files are specified using comma-separated lists for "file" and "ro". | ||
| 65 | * The default number of LUNs is taken from the number of "file" elements; | ||
| 66 | * it is 1 if "file" is not given. If "removable" is not set then a backing | ||
| 67 | * file must be specified for each LUN. If it is set, then an unspecified | ||
| 68 | * or empty backing filename means the LUN's medium is not loaded. Ideally | ||
| 69 | * each LUN would be settable independently as a disk drive or a CD-ROM | ||
| 70 | * drive, but currently all LUNs have to be the same type. The CD-ROM | ||
| 71 | * emulation includes a single data track and no audio tracks; hence there | ||
| 72 | * need be only one backing file per LUN. Note also that the CD-ROM block | ||
| 73 | * length is set to 512 rather than the more common value 2048. | ||
| 74 | * | ||
| 75 | * Requirements are modest; only a bulk-in and a bulk-out endpoint are | ||
| 76 | * needed (an interrupt-out endpoint is also needed for CBI). The memory | ||
| 77 | * requirement amounts to two 16K buffers, size configurable by a parameter. | ||
| 78 | * Support is included for both full-speed and high-speed operation. | ||
| 79 | * | ||
| 80 | * Note that the driver is slightly non-portable in that it assumes a | ||
| 81 | * single memory/DMA buffer will be useable for bulk-in, bulk-out, and | ||
| 82 | * interrupt-in endpoints. With most device controllers this isn't an | ||
| 83 | * issue, but there may be some with hardware restrictions that prevent | ||
| 84 | * a buffer from being used by more than one endpoint. | ||
| 85 | * | ||
| 86 | * Module options: | ||
| 87 | * | ||
| 88 | * file=filename[,filename...] | ||
| 89 | * Required if "removable" is not set, names of | ||
| 90 | * the files or block devices used for | ||
| 91 | * backing storage | ||
| 92 | * serial=HHHH... Required serial number (string of hex chars) | ||
| 93 | * ro=b[,b...] Default false, booleans for read-only access | ||
| 94 | * removable Default false, boolean for removable media | ||
| 95 | * luns=N Default N = number of filenames, number of | ||
| 96 | * LUNs to support | ||
| 97 | * nofua=b[,b...] Default false, booleans for ignore FUA flag | ||
| 98 | * in SCSI WRITE(10,12) commands | ||
| 99 | * stall Default determined according to the type of | ||
| 100 | * USB device controller (usually true), | ||
| 101 | * boolean to permit the driver to halt | ||
| 102 | * bulk endpoints | ||
| 103 | * cdrom Default false, boolean for whether to emulate | ||
| 104 | * a CD-ROM drive | ||
| 105 | * transport=XXX Default BBB, transport name (CB, CBI, or BBB) | ||
| 106 | * protocol=YYY Default SCSI, protocol name (RBC, 8020 or | ||
| 107 | * ATAPI, QIC, UFI, 8070, or SCSI; | ||
| 108 | * also 1 - 6) | ||
| 109 | * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID | ||
| 110 | * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID | ||
| 111 | * release=0xRRRR Override the USB release number (bcdDevice) | ||
| 112 | * buflen=N Default N=16384, buffer size used (will be | ||
| 113 | * rounded down to a multiple of | ||
| 114 | * PAGE_CACHE_SIZE) | ||
| 115 | * | ||
| 116 | * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "serial", "ro", | ||
| 117 | * "removable", "luns", "nofua", "stall", and "cdrom" options are available; | ||
| 118 | * default values are used for everything else. | ||
| 119 | * | ||
| 120 | * The pathnames of the backing files and the ro settings are available in | ||
| 121 | * the attribute files "file", "nofua", and "ro" in the lun<n> subdirectory of | ||
| 122 | * the gadget's sysfs directory. If the "removable" option is set, writing to | ||
| 123 | * these files will simulate ejecting/loading the medium (writing an empty | ||
| 124 | * line means eject) and adjusting a write-enable tab. Changes to the ro | ||
| 125 | * setting are not allowed when the medium is loaded or if CD-ROM emulation | ||
| 126 | * is being used. | ||
| 127 | * | ||
| 128 | * This gadget driver is heavily based on "Gadget Zero" by David Brownell. | ||
| 129 | * The driver's SCSI command interface was based on the "Information | ||
| 130 | * technology - Small Computer System Interface - 2" document from | ||
| 131 | * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at | ||
| 132 | * <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>. The single exception | ||
| 133 | * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the | ||
| 134 | * "Universal Serial Bus Mass Storage Class UFI Command Specification" | ||
| 135 | * document, Revision 1.0, December 14, 1998, available at | ||
| 136 | * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>. | ||
| 137 | */ | ||
| 138 | |||
| 139 | |||
| 140 | /* | ||
| 141 | * Driver Design | ||
| 142 | * | ||
| 143 | * The FSG driver is fairly straightforward. There is a main kernel | ||
| 144 | * thread that handles most of the work. Interrupt routines field | ||
| 145 | * callbacks from the controller driver: bulk- and interrupt-request | ||
| 146 | * completion notifications, endpoint-0 events, and disconnect events. | ||
| 147 | * Completion events are passed to the main thread by wakeup calls. Many | ||
| 148 | * ep0 requests are handled at interrupt time, but SetInterface, | ||
| 149 | * SetConfiguration, and device reset requests are forwarded to the | ||
| 150 | * thread in the form of "exceptions" using SIGUSR1 signals (since they | ||
| 151 | * should interrupt any ongoing file I/O operations). | ||
| 152 | * | ||
| 153 | * The thread's main routine implements the standard command/data/status | ||
| 154 | * parts of a SCSI interaction. It and its subroutines are full of tests | ||
| 155 | * for pending signals/exceptions -- all this polling is necessary since | ||
| 156 | * the kernel has no setjmp/longjmp equivalents. (Maybe this is an | ||
| 157 | * indication that the driver really wants to be running in userspace.) | ||
| 158 | * An important point is that so long as the thread is alive it keeps an | ||
| 159 | * open reference to the backing file. This will prevent unmounting | ||
| 160 | * the backing file's underlying filesystem and could cause problems | ||
| 161 | * during system shutdown, for example. To prevent such problems, the | ||
| 162 | * thread catches INT, TERM, and KILL signals and converts them into | ||
| 163 | * an EXIT exception. | ||
| 164 | * | ||
| 165 | * In normal operation the main thread is started during the gadget's | ||
| 166 | * fsg_bind() callback and stopped during fsg_unbind(). But it can also | ||
| 167 | * exit when it receives a signal, and there's no point leaving the | ||
| 168 | * gadget running when the thread is dead. So just before the thread | ||
| 169 | * exits, it deregisters the gadget driver. This makes things a little | ||
| 170 | * tricky: The driver is deregistered at two places, and the exiting | ||
| 171 | * thread can indirectly call fsg_unbind() which in turn can tell the | ||
| 172 | * thread to exit. The first problem is resolved through the use of the | ||
| 173 | * REGISTERED atomic bitflag; the driver will only be deregistered once. | ||
| 174 | * The second problem is resolved by having fsg_unbind() check | ||
| 175 | * fsg->state; it won't try to stop the thread if the state is already | ||
| 176 | * FSG_STATE_TERMINATED. | ||
| 177 | * | ||
| 178 | * To provide maximum throughput, the driver uses a circular pipeline of | ||
| 179 | * buffer heads (struct fsg_buffhd). In principle the pipeline can be | ||
| 180 | * arbitrarily long; in practice the benefits don't justify having more | ||
| 181 | * than 2 stages (i.e., double buffering). But it helps to think of the | ||
| 182 | * pipeline as being a long one. Each buffer head contains a bulk-in and | ||
| 183 | * a bulk-out request pointer (since the buffer can be used for both | ||
| 184 | * output and input -- directions always are given from the host's | ||
| 185 | * point of view) as well as a pointer to the buffer and various state | ||
| 186 | * variables. | ||
| 187 | * | ||
| 188 | * Use of the pipeline follows a simple protocol. There is a variable | ||
| 189 | * (fsg->next_buffhd_to_fill) that points to the next buffer head to use. | ||
| 190 | * At any time that buffer head may still be in use from an earlier | ||
| 191 | * request, so each buffer head has a state variable indicating whether | ||
| 192 | * it is EMPTY, FULL, or BUSY. Typical use involves waiting for the | ||
| 193 | * buffer head to be EMPTY, filling the buffer either by file I/O or by | ||
| 194 | * USB I/O (during which the buffer head is BUSY), and marking the buffer | ||
| 195 | * head FULL when the I/O is complete. Then the buffer will be emptied | ||
| 196 | * (again possibly by USB I/O, during which it is marked BUSY) and | ||
| 197 | * finally marked EMPTY again (possibly by a completion routine). | ||
| 198 | * | ||
| 199 | * A module parameter tells the driver to avoid stalling the bulk | ||
| 200 | * endpoints wherever the transport specification allows. This is | ||
| 201 | * necessary for some UDCs like the SuperH, which cannot reliably clear a | ||
| 202 | * halt on a bulk endpoint. However, under certain circumstances the | ||
| 203 | * Bulk-only specification requires a stall. In such cases the driver | ||
| 204 | * will halt the endpoint and set a flag indicating that it should clear | ||
| 205 | * the halt in software during the next device reset. Hopefully this | ||
| 206 | * will permit everything to work correctly. Furthermore, although the | ||
| 207 | * specification allows the bulk-out endpoint to halt when the host sends | ||
| 208 | * too much data, implementing this would cause an unavoidable race. | ||
| 209 | * The driver will always use the "no-stall" approach for OUT transfers. | ||
| 210 | * | ||
| 211 | * One subtle point concerns sending status-stage responses for ep0 | ||
| 212 | * requests. Some of these requests, such as device reset, can involve | ||
| 213 | * interrupting an ongoing file I/O operation, which might take an | ||
| 214 | * arbitrarily long time. During that delay the host might give up on | ||
| 215 | * the original ep0 request and issue a new one. When that happens the | ||
| 216 | * driver should not notify the host about completion of the original | ||
| 217 | * request, as the host will no longer be waiting for it. So the driver | ||
| 218 | * assigns to each ep0 request a unique tag, and it keeps track of the | ||
| 219 | * tag value of the request associated with a long-running exception | ||
| 220 | * (device-reset, interface-change, or configuration-change). When the | ||
| 221 | * exception handler is finished, the status-stage response is submitted | ||
| 222 | * only if the current ep0 request tag is equal to the exception request | ||
| 223 | * tag. Thus only the most recently received ep0 request will get a | ||
| 224 | * status-stage response. | ||
| 225 | * | ||
| 226 | * Warning: This driver source file is too long. It ought to be split up | ||
| 227 | * into a header file plus about 3 separate .c files, to handle the details | ||
| 228 | * of the Gadget, USB Mass Storage, and SCSI protocols. | ||
| 229 | */ | ||
| 230 | |||
| 231 | |||
| 232 | /* #define VERBOSE_DEBUG */ | ||
| 233 | /* #define DUMP_MSGS */ | ||
| 234 | |||
| 235 | |||
| 236 | #include <linux/blkdev.h> | ||
| 237 | #include <linux/completion.h> | ||
| 238 | #include <linux/dcache.h> | ||
| 239 | #include <linux/delay.h> | ||
| 240 | #include <linux/device.h> | ||
| 241 | #include <linux/fcntl.h> | ||
| 242 | #include <linux/file.h> | ||
| 243 | #include <linux/fs.h> | ||
| 244 | #include <linux/kref.h> | ||
| 245 | #include <linux/kthread.h> | ||
| 246 | #include <linux/limits.h> | ||
| 247 | #include <linux/rwsem.h> | ||
| 248 | #include <linux/slab.h> | ||
| 249 | #include <linux/spinlock.h> | ||
| 250 | #include <linux/string.h> | ||
| 251 | #include <linux/freezer.h> | ||
| 252 | #include <linux/utsname.h> | ||
| 253 | |||
| 254 | #include <linux/usb/ch9.h> | ||
| 255 | #include <linux/usb/gadget.h> | ||
| 256 | |||
| 257 | #include "gadget_chips.h" | ||
| 258 | |||
| 259 | |||
| 260 | |||
| 261 | /* | ||
| 262 | * Kbuild is not very cooperative with respect to linking separately | ||
| 263 | * compiled library objects into one module. So for now we won't use | ||
| 264 | * separate compilation ... ensuring init/exit sections work to shrink | ||
| 265 | * the runtime footprint, and giving us at least some parts of what | ||
| 266 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
| 267 | */ | ||
| 268 | #include "usbstring.c" | ||
| 269 | #include "config.c" | ||
| 270 | #include "epautoconf.c" | ||
| 271 | |||
| 272 | /*-------------------------------------------------------------------------*/ | ||
| 273 | |||
| 274 | #define DRIVER_DESC "File-backed Storage Gadget" | ||
| 275 | #define DRIVER_NAME "g_file_storage" | ||
| 276 | #define DRIVER_VERSION "1 September 2010" | ||
| 277 | |||
| 278 | static char fsg_string_manufacturer[64]; | ||
| 279 | static const char fsg_string_product[] = DRIVER_DESC; | ||
| 280 | static const char fsg_string_config[] = "Self-powered"; | ||
| 281 | static const char fsg_string_interface[] = "Mass Storage"; | ||
| 282 | |||
| 283 | |||
| 284 | #include "storage_common.c" | ||
| 285 | |||
| 286 | |||
| 287 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 288 | MODULE_AUTHOR("Alan Stern"); | ||
| 289 | MODULE_LICENSE("Dual BSD/GPL"); | ||
| 290 | |||
| 291 | /* | ||
| 292 | * This driver assumes self-powered hardware and has no way for users to | ||
| 293 | * trigger remote wakeup. It uses autoconfiguration to select endpoints | ||
| 294 | * and endpoint addresses. | ||
| 295 | */ | ||
| 296 | |||
| 297 | |||
| 298 | /*-------------------------------------------------------------------------*/ | ||
| 299 | |||
| 300 | |||
| 301 | /* Encapsulate the module parameter settings */ | ||
| 302 | |||
| 303 | static struct { | ||
| 304 | char *file[FSG_MAX_LUNS]; | ||
| 305 | char *serial; | ||
| 306 | int ro[FSG_MAX_LUNS]; | ||
| 307 | int nofua[FSG_MAX_LUNS]; | ||
| 308 | unsigned int num_filenames; | ||
| 309 | unsigned int num_ros; | ||
| 310 | unsigned int num_nofuas; | ||
| 311 | unsigned int nluns; | ||
| 312 | |||
| 313 | int removable; | ||
| 314 | int can_stall; | ||
| 315 | int cdrom; | ||
| 316 | |||
| 317 | char *transport_parm; | ||
| 318 | char *protocol_parm; | ||
| 319 | unsigned short vendor; | ||
| 320 | unsigned short product; | ||
| 321 | unsigned short release; | ||
| 322 | unsigned int buflen; | ||
| 323 | |||
| 324 | int transport_type; | ||
| 325 | char *transport_name; | ||
| 326 | int protocol_type; | ||
| 327 | char *protocol_name; | ||
| 328 | |||
| 329 | } mod_data = { // Default values | ||
| 330 | .transport_parm = "BBB", | ||
| 331 | .protocol_parm = "SCSI", | ||
| 332 | .removable = 0, | ||
| 333 | .can_stall = 1, | ||
| 334 | .cdrom = 0, | ||
| 335 | .vendor = FSG_VENDOR_ID, | ||
| 336 | .product = FSG_PRODUCT_ID, | ||
| 337 | .release = 0xffff, // Use controller chip type | ||
| 338 | .buflen = 16384, | ||
| 339 | }; | ||
| 340 | |||
| 341 | |||
| 342 | module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames, | ||
| 343 | S_IRUGO); | ||
| 344 | MODULE_PARM_DESC(file, "names of backing files or devices"); | ||
| 345 | |||
| 346 | module_param_named(serial, mod_data.serial, charp, S_IRUGO); | ||
| 347 | MODULE_PARM_DESC(serial, "USB serial number"); | ||
| 348 | |||
| 349 | module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); | ||
| 350 | MODULE_PARM_DESC(ro, "true to force read-only"); | ||
| 351 | |||
| 352 | module_param_array_named(nofua, mod_data.nofua, bool, &mod_data.num_nofuas, | ||
| 353 | S_IRUGO); | ||
| 354 | MODULE_PARM_DESC(nofua, "true to ignore SCSI WRITE(10,12) FUA bit"); | ||
| 355 | |||
| 356 | module_param_named(luns, mod_data.nluns, uint, S_IRUGO); | ||
| 357 | MODULE_PARM_DESC(luns, "number of LUNs"); | ||
| 358 | |||
| 359 | module_param_named(removable, mod_data.removable, bool, S_IRUGO); | ||
| 360 | MODULE_PARM_DESC(removable, "true to simulate removable media"); | ||
| 361 | |||
| 362 | module_param_named(stall, mod_data.can_stall, bool, S_IRUGO); | ||
| 363 | MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); | ||
| 364 | |||
| 365 | module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO); | ||
| 366 | MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk"); | ||
| 367 | |||
| 368 | /* In the non-TEST version, only the module parameters listed above | ||
| 369 | * are available. */ | ||
| 370 | #ifdef CONFIG_USB_FILE_STORAGE_TEST | ||
| 371 | |||
| 372 | module_param_named(transport, mod_data.transport_parm, charp, S_IRUGO); | ||
| 373 | MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)"); | ||
| 374 | |||
| 375 | module_param_named(protocol, mod_data.protocol_parm, charp, S_IRUGO); | ||
| 376 | MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, " | ||
| 377 | "8070, or SCSI)"); | ||
| 378 | |||
| 379 | module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO); | ||
| 380 | MODULE_PARM_DESC(vendor, "USB Vendor ID"); | ||
| 381 | |||
| 382 | module_param_named(product, mod_data.product, ushort, S_IRUGO); | ||
| 383 | MODULE_PARM_DESC(product, "USB Product ID"); | ||
| 384 | |||
| 385 | module_param_named(release, mod_data.release, ushort, S_IRUGO); | ||
| 386 | MODULE_PARM_DESC(release, "USB release number"); | ||
| 387 | |||
| 388 | module_param_named(buflen, mod_data.buflen, uint, S_IRUGO); | ||
| 389 | MODULE_PARM_DESC(buflen, "I/O buffer size"); | ||
| 390 | |||
| 391 | #endif /* CONFIG_USB_FILE_STORAGE_TEST */ | ||
| 392 | |||
| 393 | |||
| 394 | /* | ||
| 395 | * These definitions will permit the compiler to avoid generating code for | ||
| 396 | * parts of the driver that aren't used in the non-TEST version. Even gcc | ||
| 397 | * can recognize when a test of a constant expression yields a dead code | ||
| 398 | * path. | ||
| 399 | */ | ||
| 400 | |||
| 401 | #ifdef CONFIG_USB_FILE_STORAGE_TEST | ||
| 402 | |||
| 403 | #define transport_is_bbb() (mod_data.transport_type == USB_PR_BULK) | ||
| 404 | #define transport_is_cbi() (mod_data.transport_type == USB_PR_CBI) | ||
| 405 | #define protocol_is_scsi() (mod_data.protocol_type == USB_SC_SCSI) | ||
| 406 | |||
| 407 | #else | ||
| 408 | |||
| 409 | #define transport_is_bbb() 1 | ||
| 410 | #define transport_is_cbi() 0 | ||
| 411 | #define protocol_is_scsi() 1 | ||
| 412 | |||
| 413 | #endif /* CONFIG_USB_FILE_STORAGE_TEST */ | ||
| 414 | |||
| 415 | |||
| 416 | /*-------------------------------------------------------------------------*/ | ||
| 417 | |||
| 418 | |||
| 419 | struct fsg_dev { | ||
| 420 | /* lock protects: state, all the req_busy's, and cbbuf_cmnd */ | ||
| 421 | spinlock_t lock; | ||
| 422 | struct usb_gadget *gadget; | ||
| 423 | |||
| 424 | /* filesem protects: backing files in use */ | ||
| 425 | struct rw_semaphore filesem; | ||
| 426 | |||
| 427 | /* reference counting: wait until all LUNs are released */ | ||
| 428 | struct kref ref; | ||
| 429 | |||
| 430 | struct usb_ep *ep0; // Handy copy of gadget->ep0 | ||
| 431 | struct usb_request *ep0req; // For control responses | ||
| 432 | unsigned int ep0_req_tag; | ||
| 433 | const char *ep0req_name; | ||
| 434 | |||
| 435 | struct usb_request *intreq; // For interrupt responses | ||
| 436 | int intreq_busy; | ||
| 437 | struct fsg_buffhd *intr_buffhd; | ||
| 438 | |||
| 439 | unsigned int bulk_out_maxpacket; | ||
| 440 | enum fsg_state state; // For exception handling | ||
| 441 | unsigned int exception_req_tag; | ||
| 442 | |||
| 443 | u8 config, new_config; | ||
| 444 | |||
| 445 | unsigned int running : 1; | ||
| 446 | unsigned int bulk_in_enabled : 1; | ||
| 447 | unsigned int bulk_out_enabled : 1; | ||
| 448 | unsigned int intr_in_enabled : 1; | ||
| 449 | unsigned int phase_error : 1; | ||
| 450 | unsigned int short_packet_received : 1; | ||
| 451 | unsigned int bad_lun_okay : 1; | ||
| 452 | |||
| 453 | unsigned long atomic_bitflags; | ||
| 454 | #define REGISTERED 0 | ||
| 455 | #define IGNORE_BULK_OUT 1 | ||
| 456 | #define SUSPENDED 2 | ||
| 457 | |||
| 458 | struct usb_ep *bulk_in; | ||
| 459 | struct usb_ep *bulk_out; | ||
| 460 | struct usb_ep *intr_in; | ||
| 461 | |||
| 462 | struct fsg_buffhd *next_buffhd_to_fill; | ||
| 463 | struct fsg_buffhd *next_buffhd_to_drain; | ||
| 464 | struct fsg_buffhd buffhds[FSG_NUM_BUFFERS]; | ||
| 465 | |||
| 466 | int thread_wakeup_needed; | ||
| 467 | struct completion thread_notifier; | ||
| 468 | struct task_struct *thread_task; | ||
| 469 | |||
| 470 | int cmnd_size; | ||
| 471 | u8 cmnd[MAX_COMMAND_SIZE]; | ||
| 472 | enum data_direction data_dir; | ||
| 473 | u32 data_size; | ||
| 474 | u32 data_size_from_cmnd; | ||
| 475 | u32 tag; | ||
| 476 | unsigned int lun; | ||
| 477 | u32 residue; | ||
| 478 | u32 usb_amount_left; | ||
| 479 | |||
| 480 | /* The CB protocol offers no way for a host to know when a command | ||
| 481 | * has completed. As a result the next command may arrive early, | ||
| 482 | * and we will still have to handle it. For that reason we need | ||
| 483 | * a buffer to store new commands when using CB (or CBI, which | ||
| 484 | * does not oblige a host to wait for command completion either). */ | ||
| 485 | int cbbuf_cmnd_size; | ||
| 486 | u8 cbbuf_cmnd[MAX_COMMAND_SIZE]; | ||
| 487 | |||
| 488 | unsigned int nluns; | ||
| 489 | struct fsg_lun *luns; | ||
| 490 | struct fsg_lun *curlun; | ||
| 491 | }; | ||
| 492 | |||
| 493 | typedef void (*fsg_routine_t)(struct fsg_dev *); | ||
| 494 | |||
| 495 | static int exception_in_progress(struct fsg_dev *fsg) | ||
| 496 | { | ||
| 497 | return (fsg->state > FSG_STATE_IDLE); | ||
| 498 | } | ||
| 499 | |||
| 500 | /* Make bulk-out requests be divisible by the maxpacket size */ | ||
| 501 | static void set_bulk_out_req_length(struct fsg_dev *fsg, | ||
| 502 | struct fsg_buffhd *bh, unsigned int length) | ||
| 503 | { | ||
| 504 | unsigned int rem; | ||
| 505 | |||
| 506 | bh->bulk_out_intended_length = length; | ||
| 507 | rem = length % fsg->bulk_out_maxpacket; | ||
| 508 | if (rem > 0) | ||
| 509 | length += fsg->bulk_out_maxpacket - rem; | ||
| 510 | bh->outreq->length = length; | ||
| 511 | } | ||
| 512 | |||
| 513 | static struct fsg_dev *the_fsg; | ||
| 514 | static struct usb_gadget_driver fsg_driver; | ||
| 515 | |||
| 516 | |||
| 517 | /*-------------------------------------------------------------------------*/ | ||
| 518 | |||
| 519 | static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | ||
| 520 | { | ||
| 521 | const char *name; | ||
| 522 | |||
| 523 | if (ep == fsg->bulk_in) | ||
| 524 | name = "bulk-in"; | ||
| 525 | else if (ep == fsg->bulk_out) | ||
| 526 | name = "bulk-out"; | ||
| 527 | else | ||
| 528 | name = ep->name; | ||
| 529 | DBG(fsg, "%s set halt\n", name); | ||
| 530 | return usb_ep_set_halt(ep); | ||
| 531 | } | ||
| 532 | |||
| 533 | |||
| 534 | /*-------------------------------------------------------------------------*/ | ||
| 535 | |||
| 536 | /* | ||
| 537 | * DESCRIPTORS ... most are static, but strings and (full) configuration | ||
| 538 | * descriptors are built on demand. Also the (static) config and interface | ||
| 539 | * descriptors are adjusted during fsg_bind(). | ||
| 540 | */ | ||
| 541 | |||
| 542 | /* There is only one configuration. */ | ||
| 543 | #define CONFIG_VALUE 1 | ||
| 544 | |||
| 545 | static struct usb_device_descriptor | ||
| 546 | device_desc = { | ||
| 547 | .bLength = sizeof device_desc, | ||
| 548 | .bDescriptorType = USB_DT_DEVICE, | ||
| 549 | |||
| 550 | .bcdUSB = cpu_to_le16(0x0200), | ||
| 551 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | ||
| 552 | |||
| 553 | /* The next three values can be overridden by module parameters */ | ||
| 554 | .idVendor = cpu_to_le16(FSG_VENDOR_ID), | ||
| 555 | .idProduct = cpu_to_le16(FSG_PRODUCT_ID), | ||
| 556 | .bcdDevice = cpu_to_le16(0xffff), | ||
| 557 | |||
| 558 | .iManufacturer = FSG_STRING_MANUFACTURER, | ||
| 559 | .iProduct = FSG_STRING_PRODUCT, | ||
| 560 | .iSerialNumber = FSG_STRING_SERIAL, | ||
| 561 | .bNumConfigurations = 1, | ||
| 562 | }; | ||
| 563 | |||
| 564 | static struct usb_config_descriptor | ||
| 565 | config_desc = { | ||
| 566 | .bLength = sizeof config_desc, | ||
| 567 | .bDescriptorType = USB_DT_CONFIG, | ||
| 568 | |||
| 569 | /* wTotalLength computed by usb_gadget_config_buf() */ | ||
| 570 | .bNumInterfaces = 1, | ||
| 571 | .bConfigurationValue = CONFIG_VALUE, | ||
| 572 | .iConfiguration = FSG_STRING_CONFIG, | ||
| 573 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | ||
| 574 | .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, | ||
| 575 | }; | ||
| 576 | |||
| 577 | |||
| 578 | static struct usb_qualifier_descriptor | ||
| 579 | dev_qualifier = { | ||
| 580 | .bLength = sizeof dev_qualifier, | ||
| 581 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | ||
| 582 | |||
| 583 | .bcdUSB = cpu_to_le16(0x0200), | ||
| 584 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | ||
| 585 | |||
| 586 | .bNumConfigurations = 1, | ||
| 587 | }; | ||
| 588 | |||
| 589 | |||
| 590 | |||
| 591 | /* | ||
| 592 | * Config descriptors must agree with the code that sets configurations | ||
| 593 | * and with code managing interfaces and their altsettings. They must | ||
| 594 | * also handle different speeds and other-speed requests. | ||
| 595 | */ | ||
| 596 | static int populate_config_buf(struct usb_gadget *gadget, | ||
| 597 | u8 *buf, u8 type, unsigned index) | ||
| 598 | { | ||
| 599 | enum usb_device_speed speed = gadget->speed; | ||
| 600 | int len; | ||
| 601 | const struct usb_descriptor_header **function; | ||
| 602 | |||
| 603 | if (index > 0) | ||
| 604 | return -EINVAL; | ||
| 605 | |||
| 606 | if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG) | ||
| 607 | speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; | ||
| 608 | function = gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH | ||
| 609 | ? (const struct usb_descriptor_header **)fsg_hs_function | ||
| 610 | : (const struct usb_descriptor_header **)fsg_fs_function; | ||
| 611 | |||
| 612 | /* for now, don't advertise srp-only devices */ | ||
| 613 | if (!gadget_is_otg(gadget)) | ||
| 614 | function++; | ||
| 615 | |||
| 616 | len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); | ||
| 617 | ((struct usb_config_descriptor *) buf)->bDescriptorType = type; | ||
| 618 | return len; | ||
| 619 | } | ||
| 620 | |||
| 621 | |||
| 622 | /*-------------------------------------------------------------------------*/ | ||
| 623 | |||
| 624 | /* These routines may be called in process context or in_irq */ | ||
| 625 | |||
| 626 | /* Caller must hold fsg->lock */ | ||
| 627 | static void wakeup_thread(struct fsg_dev *fsg) | ||
| 628 | { | ||
| 629 | /* Tell the main thread that something has happened */ | ||
| 630 | fsg->thread_wakeup_needed = 1; | ||
| 631 | if (fsg->thread_task) | ||
| 632 | wake_up_process(fsg->thread_task); | ||
| 633 | } | ||
| 634 | |||
| 635 | |||
| 636 | static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) | ||
| 637 | { | ||
| 638 | unsigned long flags; | ||
| 639 | |||
| 640 | /* Do nothing if a higher-priority exception is already in progress. | ||
| 641 | * If a lower-or-equal priority exception is in progress, preempt it | ||
| 642 | * and notify the main thread by sending it a signal. */ | ||
| 643 | spin_lock_irqsave(&fsg->lock, flags); | ||
| 644 | if (fsg->state <= new_state) { | ||
| 645 | fsg->exception_req_tag = fsg->ep0_req_tag; | ||
| 646 | fsg->state = new_state; | ||
| 647 | if (fsg->thread_task) | ||
| 648 | send_sig_info(SIGUSR1, SEND_SIG_FORCED, | ||
| 649 | fsg->thread_task); | ||
| 650 | } | ||
| 651 | spin_unlock_irqrestore(&fsg->lock, flags); | ||
| 652 | } | ||
| 653 | |||
| 654 | |||
| 655 | /*-------------------------------------------------------------------------*/ | ||
| 656 | |||
| 657 | /* The disconnect callback and ep0 routines. These always run in_irq, | ||
| 658 | * except that ep0_queue() is called in the main thread to acknowledge | ||
| 659 | * completion of various requests: set config, set interface, and | ||
| 660 | * Bulk-only device reset. */ | ||
| 661 | |||
| 662 | static void fsg_disconnect(struct usb_gadget *gadget) | ||
| 663 | { | ||
| 664 | struct fsg_dev *fsg = get_gadget_data(gadget); | ||
| 665 | |||
| 666 | DBG(fsg, "disconnect or port reset\n"); | ||
| 667 | raise_exception(fsg, FSG_STATE_DISCONNECT); | ||
| 668 | } | ||
| 669 | |||
| 670 | |||
| 671 | static int ep0_queue(struct fsg_dev *fsg) | ||
| 672 | { | ||
| 673 | int rc; | ||
| 674 | |||
| 675 | rc = usb_ep_queue(fsg->ep0, fsg->ep0req, GFP_ATOMIC); | ||
| 676 | if (rc != 0 && rc != -ESHUTDOWN) { | ||
| 677 | |||
| 678 | /* We can't do much more than wait for a reset */ | ||
| 679 | WARNING(fsg, "error in submission: %s --> %d\n", | ||
| 680 | fsg->ep0->name, rc); | ||
| 681 | } | ||
| 682 | return rc; | ||
| 683 | } | ||
| 684 | |||
| 685 | static void ep0_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 686 | { | ||
| 687 | struct fsg_dev *fsg = ep->driver_data; | ||
| 688 | |||
| 689 | if (req->actual > 0) | ||
| 690 | dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); | ||
| 691 | if (req->status || req->actual != req->length) | ||
| 692 | DBG(fsg, "%s --> %d, %u/%u\n", __func__, | ||
| 693 | req->status, req->actual, req->length); | ||
| 694 | if (req->status == -ECONNRESET) // Request was cancelled | ||
| 695 | usb_ep_fifo_flush(ep); | ||
| 696 | |||
| 697 | if (req->status == 0 && req->context) | ||
| 698 | ((fsg_routine_t) (req->context))(fsg); | ||
| 699 | } | ||
| 700 | |||
| 701 | |||
| 702 | /*-------------------------------------------------------------------------*/ | ||
| 703 | |||
| 704 | /* Bulk and interrupt endpoint completion handlers. | ||
| 705 | * These always run in_irq. */ | ||
| 706 | |||
| 707 | static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 708 | { | ||
| 709 | struct fsg_dev *fsg = ep->driver_data; | ||
| 710 | struct fsg_buffhd *bh = req->context; | ||
| 711 | |||
| 712 | if (req->status || req->actual != req->length) | ||
| 713 | DBG(fsg, "%s --> %d, %u/%u\n", __func__, | ||
| 714 | req->status, req->actual, req->length); | ||
| 715 | if (req->status == -ECONNRESET) // Request was cancelled | ||
| 716 | usb_ep_fifo_flush(ep); | ||
| 717 | |||
| 718 | /* Hold the lock while we update the request and buffer states */ | ||
| 719 | smp_wmb(); | ||
| 720 | spin_lock(&fsg->lock); | ||
| 721 | bh->inreq_busy = 0; | ||
| 722 | bh->state = BUF_STATE_EMPTY; | ||
| 723 | wakeup_thread(fsg); | ||
| 724 | spin_unlock(&fsg->lock); | ||
| 725 | } | ||
| 726 | |||
| 727 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 728 | { | ||
| 729 | struct fsg_dev *fsg = ep->driver_data; | ||
| 730 | struct fsg_buffhd *bh = req->context; | ||
| 731 | |||
| 732 | dump_msg(fsg, "bulk-out", req->buf, req->actual); | ||
| 733 | if (req->status || req->actual != bh->bulk_out_intended_length) | ||
| 734 | DBG(fsg, "%s --> %d, %u/%u\n", __func__, | ||
| 735 | req->status, req->actual, | ||
| 736 | bh->bulk_out_intended_length); | ||
| 737 | if (req->status == -ECONNRESET) // Request was cancelled | ||
| 738 | usb_ep_fifo_flush(ep); | ||
| 739 | |||
| 740 | /* Hold the lock while we update the request and buffer states */ | ||
| 741 | smp_wmb(); | ||
| 742 | spin_lock(&fsg->lock); | ||
| 743 | bh->outreq_busy = 0; | ||
| 744 | bh->state = BUF_STATE_FULL; | ||
| 745 | wakeup_thread(fsg); | ||
| 746 | spin_unlock(&fsg->lock); | ||
| 747 | } | ||
| 748 | |||
| 749 | |||
| 750 | #ifdef CONFIG_USB_FILE_STORAGE_TEST | ||
| 751 | static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 752 | { | ||
| 753 | struct fsg_dev *fsg = ep->driver_data; | ||
| 754 | struct fsg_buffhd *bh = req->context; | ||
| 755 | |||
| 756 | if (req->status || req->actual != req->length) | ||
| 757 | DBG(fsg, "%s --> %d, %u/%u\n", __func__, | ||
| 758 | req->status, req->actual, req->length); | ||
| 759 | if (req->status == -ECONNRESET) // Request was cancelled | ||
| 760 | usb_ep_fifo_flush(ep); | ||
| 761 | |||
| 762 | /* Hold the lock while we update the request and buffer states */ | ||
| 763 | smp_wmb(); | ||
| 764 | spin_lock(&fsg->lock); | ||
| 765 | fsg->intreq_busy = 0; | ||
| 766 | bh->state = BUF_STATE_EMPTY; | ||
| 767 | wakeup_thread(fsg); | ||
| 768 | spin_unlock(&fsg->lock); | ||
| 769 | } | ||
| 770 | |||
| 771 | #else | ||
| 772 | static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 773 | {} | ||
| 774 | #endif /* CONFIG_USB_FILE_STORAGE_TEST */ | ||
| 775 | |||
| 776 | |||
| 777 | /*-------------------------------------------------------------------------*/ | ||
| 778 | |||
| 779 | /* Ep0 class-specific handlers. These always run in_irq. */ | ||
| 780 | |||
| 781 | #ifdef CONFIG_USB_FILE_STORAGE_TEST | ||
| 782 | static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 783 | { | ||
| 784 | struct usb_request *req = fsg->ep0req; | ||
| 785 | static u8 cbi_reset_cmnd[6] = { | ||
| 786 | SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff}; | ||
| 787 | |||
| 788 | /* Error in command transfer? */ | ||
| 789 | if (req->status || req->length != req->actual || | ||
| 790 | req->actual < 6 || req->actual > MAX_COMMAND_SIZE) { | ||
| 791 | |||
| 792 | /* Not all controllers allow a protocol stall after | ||
| 793 | * receiving control-out data, but we'll try anyway. */ | ||
| 794 | fsg_set_halt(fsg, fsg->ep0); | ||
| 795 | return; // Wait for reset | ||
| 796 | } | ||
| 797 | |||
| 798 | /* Is it the special reset command? */ | ||
| 799 | if (req->actual >= sizeof cbi_reset_cmnd && | ||
| 800 | memcmp(req->buf, cbi_reset_cmnd, | ||
| 801 | sizeof cbi_reset_cmnd) == 0) { | ||
| 802 | |||
| 803 | /* Raise an exception to stop the current operation | ||
| 804 | * and reinitialize our state. */ | ||
| 805 | DBG(fsg, "cbi reset request\n"); | ||
| 806 | raise_exception(fsg, FSG_STATE_RESET); | ||
| 807 | return; | ||
| 808 | } | ||
| 809 | |||
| 810 | VDBG(fsg, "CB[I] accept device-specific command\n"); | ||
| 811 | spin_lock(&fsg->lock); | ||
| 812 | |||
| 813 | /* Save the command for later */ | ||
| 814 | if (fsg->cbbuf_cmnd_size) | ||
| 815 | WARNING(fsg, "CB[I] overwriting previous command\n"); | ||
| 816 | fsg->cbbuf_cmnd_size = req->actual; | ||
| 817 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); | ||
| 818 | |||
| 819 | wakeup_thread(fsg); | ||
| 820 | spin_unlock(&fsg->lock); | ||
| 821 | } | ||
| 822 | |||
| 823 | #else | ||
| 824 | static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 825 | {} | ||
| 826 | #endif /* CONFIG_USB_FILE_STORAGE_TEST */ | ||
| 827 | |||
| 828 | |||
| 829 | static int class_setup_req(struct fsg_dev *fsg, | ||
| 830 | const struct usb_ctrlrequest *ctrl) | ||
| 831 | { | ||
| 832 | struct usb_request *req = fsg->ep0req; | ||
| 833 | int value = -EOPNOTSUPP; | ||
| 834 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
| 835 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 836 | u16 w_length = le16_to_cpu(ctrl->wLength); | ||
| 837 | |||
| 838 | if (!fsg->config) | ||
| 839 | return value; | ||
| 840 | |||
| 841 | /* Handle Bulk-only class-specific requests */ | ||
| 842 | if (transport_is_bbb()) { | ||
| 843 | switch (ctrl->bRequest) { | ||
| 844 | |||
| 845 | case USB_BULK_RESET_REQUEST: | ||
| 846 | if (ctrl->bRequestType != (USB_DIR_OUT | | ||
| 847 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | ||
| 848 | break; | ||
| 849 | if (w_index != 0 || w_value != 0) { | ||
| 850 | value = -EDOM; | ||
| 851 | break; | ||
| 852 | } | ||
| 853 | |||
| 854 | /* Raise an exception to stop the current operation | ||
| 855 | * and reinitialize our state. */ | ||
| 856 | DBG(fsg, "bulk reset request\n"); | ||
| 857 | raise_exception(fsg, FSG_STATE_RESET); | ||
| 858 | value = DELAYED_STATUS; | ||
| 859 | break; | ||
| 860 | |||
| 861 | case USB_BULK_GET_MAX_LUN_REQUEST: | ||
| 862 | if (ctrl->bRequestType != (USB_DIR_IN | | ||
| 863 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | ||
| 864 | break; | ||
| 865 | if (w_index != 0 || w_value != 0) { | ||
| 866 | value = -EDOM; | ||
| 867 | break; | ||
| 868 | } | ||
| 869 | VDBG(fsg, "get max LUN\n"); | ||
| 870 | *(u8 *) req->buf = fsg->nluns - 1; | ||
| 871 | value = 1; | ||
| 872 | break; | ||
| 873 | } | ||
| 874 | } | ||
| 875 | |||
| 876 | /* Handle CBI class-specific requests */ | ||
| 877 | else { | ||
| 878 | switch (ctrl->bRequest) { | ||
| 879 | |||
| 880 | case USB_CBI_ADSC_REQUEST: | ||
| 881 | if (ctrl->bRequestType != (USB_DIR_OUT | | ||
| 882 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | ||
| 883 | break; | ||
| 884 | if (w_index != 0 || w_value != 0) { | ||
| 885 | value = -EDOM; | ||
| 886 | break; | ||
| 887 | } | ||
| 888 | if (w_length > MAX_COMMAND_SIZE) { | ||
| 889 | value = -EOVERFLOW; | ||
| 890 | break; | ||
| 891 | } | ||
| 892 | value = w_length; | ||
| 893 | fsg->ep0req->context = received_cbi_adsc; | ||
| 894 | break; | ||
| 895 | } | ||
| 896 | } | ||
| 897 | |||
| 898 | if (value == -EOPNOTSUPP) | ||
| 899 | VDBG(fsg, | ||
| 900 | "unknown class-specific control req " | ||
| 901 | "%02x.%02x v%04x i%04x l%u\n", | ||
| 902 | ctrl->bRequestType, ctrl->bRequest, | ||
| 903 | le16_to_cpu(ctrl->wValue), w_index, w_length); | ||
| 904 | return value; | ||
| 905 | } | ||
| 906 | |||
| 907 | |||
| 908 | /*-------------------------------------------------------------------------*/ | ||
| 909 | |||
| 910 | /* Ep0 standard request handlers. These always run in_irq. */ | ||
| 911 | |||
| 912 | static int standard_setup_req(struct fsg_dev *fsg, | ||
| 913 | const struct usb_ctrlrequest *ctrl) | ||
| 914 | { | ||
| 915 | struct usb_request *req = fsg->ep0req; | ||
| 916 | int value = -EOPNOTSUPP; | ||
| 917 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
| 918 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 919 | |||
| 920 | /* Usually this just stores reply data in the pre-allocated ep0 buffer, | ||
| 921 | * but config change events will also reconfigure hardware. */ | ||
| 922 | switch (ctrl->bRequest) { | ||
| 923 | |||
| 924 | case USB_REQ_GET_DESCRIPTOR: | ||
| 925 | if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | | ||
| 926 | USB_RECIP_DEVICE)) | ||
| 927 | break; | ||
| 928 | switch (w_value >> 8) { | ||
| 929 | |||
| 930 | case USB_DT_DEVICE: | ||
| 931 | VDBG(fsg, "get device descriptor\n"); | ||
| 932 | device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket; | ||
| 933 | value = sizeof device_desc; | ||
| 934 | memcpy(req->buf, &device_desc, value); | ||
| 935 | break; | ||
| 936 | case USB_DT_DEVICE_QUALIFIER: | ||
| 937 | VDBG(fsg, "get device qualifier\n"); | ||
| 938 | if (!gadget_is_dualspeed(fsg->gadget)) | ||
| 939 | break; | ||
| 940 | /* | ||
| 941 | * Assume ep0 uses the same maxpacket value for both | ||
| 942 | * speeds | ||
| 943 | */ | ||
| 944 | dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; | ||
| 945 | value = sizeof dev_qualifier; | ||
| 946 | memcpy(req->buf, &dev_qualifier, value); | ||
| 947 | break; | ||
| 948 | |||
| 949 | case USB_DT_OTHER_SPEED_CONFIG: | ||
| 950 | VDBG(fsg, "get other-speed config descriptor\n"); | ||
| 951 | if (!gadget_is_dualspeed(fsg->gadget)) | ||
| 952 | break; | ||
| 953 | goto get_config; | ||
| 954 | case USB_DT_CONFIG: | ||
| 955 | VDBG(fsg, "get configuration descriptor\n"); | ||
| 956 | get_config: | ||
| 957 | value = populate_config_buf(fsg->gadget, | ||
| 958 | req->buf, | ||
| 959 | w_value >> 8, | ||
| 960 | w_value & 0xff); | ||
| 961 | break; | ||
| 962 | |||
| 963 | case USB_DT_STRING: | ||
| 964 | VDBG(fsg, "get string descriptor\n"); | ||
| 965 | |||
| 966 | /* wIndex == language code */ | ||
| 967 | value = usb_gadget_get_string(&fsg_stringtab, | ||
| 968 | w_value & 0xff, req->buf); | ||
| 969 | break; | ||
| 970 | } | ||
| 971 | break; | ||
| 972 | |||
| 973 | /* One config, two speeds */ | ||
| 974 | case USB_REQ_SET_CONFIGURATION: | ||
| 975 | if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | | ||
| 976 | USB_RECIP_DEVICE)) | ||
| 977 | break; | ||
| 978 | VDBG(fsg, "set configuration\n"); | ||
| 979 | if (w_value == CONFIG_VALUE || w_value == 0) { | ||
| 980 | fsg->new_config = w_value; | ||
| 981 | |||
| 982 | /* Raise an exception to wipe out previous transaction | ||
| 983 | * state (queued bufs, etc) and set the new config. */ | ||
| 984 | raise_exception(fsg, FSG_STATE_CONFIG_CHANGE); | ||
| 985 | value = DELAYED_STATUS; | ||
| 986 | } | ||
| 987 | break; | ||
| 988 | case USB_REQ_GET_CONFIGURATION: | ||
| 989 | if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | | ||
| 990 | USB_RECIP_DEVICE)) | ||
| 991 | break; | ||
| 992 | VDBG(fsg, "get configuration\n"); | ||
| 993 | *(u8 *) req->buf = fsg->config; | ||
| 994 | value = 1; | ||
| 995 | break; | ||
| 996 | |||
| 997 | case USB_REQ_SET_INTERFACE: | ||
| 998 | if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD | | ||
| 999 | USB_RECIP_INTERFACE)) | ||
| 1000 | break; | ||
| 1001 | if (fsg->config && w_index == 0) { | ||
| 1002 | |||
| 1003 | /* Raise an exception to wipe out previous transaction | ||
| 1004 | * state (queued bufs, etc) and install the new | ||
| 1005 | * interface altsetting. */ | ||
| 1006 | raise_exception(fsg, FSG_STATE_INTERFACE_CHANGE); | ||
| 1007 | value = DELAYED_STATUS; | ||
| 1008 | } | ||
| 1009 | break; | ||
| 1010 | case USB_REQ_GET_INTERFACE: | ||
| 1011 | if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | | ||
| 1012 | USB_RECIP_INTERFACE)) | ||
| 1013 | break; | ||
| 1014 | if (!fsg->config) | ||
| 1015 | break; | ||
| 1016 | if (w_index != 0) { | ||
| 1017 | value = -EDOM; | ||
| 1018 | break; | ||
| 1019 | } | ||
| 1020 | VDBG(fsg, "get interface\n"); | ||
| 1021 | *(u8 *) req->buf = 0; | ||
| 1022 | value = 1; | ||
| 1023 | break; | ||
| 1024 | |||
| 1025 | default: | ||
| 1026 | VDBG(fsg, | ||
| 1027 | "unknown control req %02x.%02x v%04x i%04x l%u\n", | ||
| 1028 | ctrl->bRequestType, ctrl->bRequest, | ||
| 1029 | w_value, w_index, le16_to_cpu(ctrl->wLength)); | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | return value; | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | |||
| 1036 | static int fsg_setup(struct usb_gadget *gadget, | ||
| 1037 | const struct usb_ctrlrequest *ctrl) | ||
| 1038 | { | ||
| 1039 | struct fsg_dev *fsg = get_gadget_data(gadget); | ||
| 1040 | int rc; | ||
| 1041 | int w_length = le16_to_cpu(ctrl->wLength); | ||
| 1042 | |||
| 1043 | ++fsg->ep0_req_tag; // Record arrival of a new request | ||
| 1044 | fsg->ep0req->context = NULL; | ||
| 1045 | fsg->ep0req->length = 0; | ||
| 1046 | dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl)); | ||
| 1047 | |||
| 1048 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) | ||
| 1049 | rc = class_setup_req(fsg, ctrl); | ||
| 1050 | else | ||
| 1051 | rc = standard_setup_req(fsg, ctrl); | ||
| 1052 | |||
| 1053 | /* Respond with data/status or defer until later? */ | ||
| 1054 | if (rc >= 0 && rc != DELAYED_STATUS) { | ||
| 1055 | rc = min(rc, w_length); | ||
| 1056 | fsg->ep0req->length = rc; | ||
| 1057 | fsg->ep0req->zero = rc < w_length; | ||
| 1058 | fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? | ||
| 1059 | "ep0-in" : "ep0-out"); | ||
| 1060 | rc = ep0_queue(fsg); | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | /* Device either stalls (rc < 0) or reports success */ | ||
| 1064 | return rc; | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | |||
| 1068 | /*-------------------------------------------------------------------------*/ | ||
| 1069 | |||
| 1070 | /* All the following routines run in process context */ | ||
| 1071 | |||
| 1072 | |||
| 1073 | /* Use this for bulk or interrupt transfers, not ep0 */ | ||
| 1074 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | ||
| 1075 | struct usb_request *req, int *pbusy, | ||
| 1076 | enum fsg_buffer_state *state) | ||
| 1077 | { | ||
| 1078 | int rc; | ||
| 1079 | |||
| 1080 | if (ep == fsg->bulk_in) | ||
| 1081 | dump_msg(fsg, "bulk-in", req->buf, req->length); | ||
| 1082 | else if (ep == fsg->intr_in) | ||
| 1083 | dump_msg(fsg, "intr-in", req->buf, req->length); | ||
| 1084 | |||
| 1085 | spin_lock_irq(&fsg->lock); | ||
| 1086 | *pbusy = 1; | ||
| 1087 | *state = BUF_STATE_BUSY; | ||
| 1088 | spin_unlock_irq(&fsg->lock); | ||
| 1089 | rc = usb_ep_queue(ep, req, GFP_KERNEL); | ||
| 1090 | if (rc != 0) { | ||
| 1091 | *pbusy = 0; | ||
| 1092 | *state = BUF_STATE_EMPTY; | ||
| 1093 | |||
| 1094 | /* We can't do much more than wait for a reset */ | ||
| 1095 | |||
| 1096 | /* Note: currently the net2280 driver fails zero-length | ||
| 1097 | * submissions if DMA is enabled. */ | ||
| 1098 | if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP && | ||
| 1099 | req->length == 0)) | ||
| 1100 | WARNING(fsg, "error in submission: %s --> %d\n", | ||
| 1101 | ep->name, rc); | ||
| 1102 | } | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | |||
| 1106 | static int sleep_thread(struct fsg_dev *fsg) | ||
| 1107 | { | ||
| 1108 | int rc = 0; | ||
| 1109 | |||
| 1110 | /* Wait until a signal arrives or we are woken up */ | ||
| 1111 | for (;;) { | ||
| 1112 | try_to_freeze(); | ||
| 1113 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1114 | if (signal_pending(current)) { | ||
| 1115 | rc = -EINTR; | ||
| 1116 | break; | ||
| 1117 | } | ||
| 1118 | if (fsg->thread_wakeup_needed) | ||
| 1119 | break; | ||
| 1120 | schedule(); | ||
| 1121 | } | ||
| 1122 | __set_current_state(TASK_RUNNING); | ||
| 1123 | fsg->thread_wakeup_needed = 0; | ||
| 1124 | return rc; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | |||
| 1128 | /*-------------------------------------------------------------------------*/ | ||
| 1129 | |||
| 1130 | static int do_read(struct fsg_dev *fsg) | ||
| 1131 | { | ||
| 1132 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1133 | u32 lba; | ||
| 1134 | struct fsg_buffhd *bh; | ||
| 1135 | int rc; | ||
| 1136 | u32 amount_left; | ||
| 1137 | loff_t file_offset, file_offset_tmp; | ||
| 1138 | unsigned int amount; | ||
| 1139 | unsigned int partial_page; | ||
| 1140 | ssize_t nread; | ||
| 1141 | |||
| 1142 | /* Get the starting Logical Block Address and check that it's | ||
| 1143 | * not too big */ | ||
| 1144 | if (fsg->cmnd[0] == READ_6) | ||
| 1145 | lba = get_unaligned_be24(&fsg->cmnd[1]); | ||
| 1146 | else { | ||
| 1147 | lba = get_unaligned_be32(&fsg->cmnd[2]); | ||
| 1148 | |||
| 1149 | /* We allow DPO (Disable Page Out = don't save data in the | ||
| 1150 | * cache) and FUA (Force Unit Access = don't read from the | ||
| 1151 | * cache), but we don't implement them. */ | ||
| 1152 | if ((fsg->cmnd[1] & ~0x18) != 0) { | ||
| 1153 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1154 | return -EINVAL; | ||
| 1155 | } | ||
| 1156 | } | ||
| 1157 | if (lba >= curlun->num_sectors) { | ||
| 1158 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | ||
| 1159 | return -EINVAL; | ||
| 1160 | } | ||
| 1161 | file_offset = ((loff_t) lba) << 9; | ||
| 1162 | |||
| 1163 | /* Carry out the file reads */ | ||
| 1164 | amount_left = fsg->data_size_from_cmnd; | ||
| 1165 | if (unlikely(amount_left == 0)) | ||
| 1166 | return -EIO; // No default reply | ||
| 1167 | |||
| 1168 | for (;;) { | ||
| 1169 | |||
| 1170 | /* Figure out how much we need to read: | ||
| 1171 | * Try to read the remaining amount. | ||
| 1172 | * But don't read more than the buffer size. | ||
| 1173 | * And don't try to read past the end of the file. | ||
| 1174 | * Finally, if we're not at a page boundary, don't read past | ||
| 1175 | * the next page. | ||
| 1176 | * If this means reading 0 then we were asked to read past | ||
| 1177 | * the end of file. */ | ||
| 1178 | amount = min((unsigned int) amount_left, mod_data.buflen); | ||
| 1179 | amount = min((loff_t) amount, | ||
| 1180 | curlun->file_length - file_offset); | ||
| 1181 | partial_page = file_offset & (PAGE_CACHE_SIZE - 1); | ||
| 1182 | if (partial_page > 0) | ||
| 1183 | amount = min(amount, (unsigned int) PAGE_CACHE_SIZE - | ||
| 1184 | partial_page); | ||
| 1185 | |||
| 1186 | /* Wait for the next buffer to become available */ | ||
| 1187 | bh = fsg->next_buffhd_to_fill; | ||
| 1188 | while (bh->state != BUF_STATE_EMPTY) { | ||
| 1189 | rc = sleep_thread(fsg); | ||
| 1190 | if (rc) | ||
| 1191 | return rc; | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | /* If we were asked to read past the end of file, | ||
| 1195 | * end with an empty buffer. */ | ||
| 1196 | if (amount == 0) { | ||
| 1197 | curlun->sense_data = | ||
| 1198 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | ||
| 1199 | curlun->sense_data_info = file_offset >> 9; | ||
| 1200 | curlun->info_valid = 1; | ||
| 1201 | bh->inreq->length = 0; | ||
| 1202 | bh->state = BUF_STATE_FULL; | ||
| 1203 | break; | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | /* Perform the read */ | ||
| 1207 | file_offset_tmp = file_offset; | ||
| 1208 | nread = vfs_read(curlun->filp, | ||
| 1209 | (char __user *) bh->buf, | ||
| 1210 | amount, &file_offset_tmp); | ||
| 1211 | VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, | ||
| 1212 | (unsigned long long) file_offset, | ||
| 1213 | (int) nread); | ||
| 1214 | if (signal_pending(current)) | ||
| 1215 | return -EINTR; | ||
| 1216 | |||
| 1217 | if (nread < 0) { | ||
| 1218 | LDBG(curlun, "error in file read: %d\n", | ||
| 1219 | (int) nread); | ||
| 1220 | nread = 0; | ||
| 1221 | } else if (nread < amount) { | ||
| 1222 | LDBG(curlun, "partial file read: %d/%u\n", | ||
| 1223 | (int) nread, amount); | ||
| 1224 | nread -= (nread & 511); // Round down to a block | ||
| 1225 | } | ||
| 1226 | file_offset += nread; | ||
| 1227 | amount_left -= nread; | ||
| 1228 | fsg->residue -= nread; | ||
| 1229 | bh->inreq->length = nread; | ||
| 1230 | bh->state = BUF_STATE_FULL; | ||
| 1231 | |||
| 1232 | /* If an error occurred, report it and its position */ | ||
| 1233 | if (nread < amount) { | ||
| 1234 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | ||
| 1235 | curlun->sense_data_info = file_offset >> 9; | ||
| 1236 | curlun->info_valid = 1; | ||
| 1237 | break; | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | if (amount_left == 0) | ||
| 1241 | break; // No more left to read | ||
| 1242 | |||
| 1243 | /* Send this buffer and go read some more */ | ||
| 1244 | bh->inreq->zero = 0; | ||
| 1245 | start_transfer(fsg, fsg->bulk_in, bh->inreq, | ||
| 1246 | &bh->inreq_busy, &bh->state); | ||
| 1247 | fsg->next_buffhd_to_fill = bh->next; | ||
| 1248 | } | ||
| 1249 | |||
| 1250 | return -EIO; // No default reply | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | |||
| 1254 | /*-------------------------------------------------------------------------*/ | ||
| 1255 | |||
| 1256 | static int do_write(struct fsg_dev *fsg) | ||
| 1257 | { | ||
| 1258 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1259 | u32 lba; | ||
| 1260 | struct fsg_buffhd *bh; | ||
| 1261 | int get_some_more; | ||
| 1262 | u32 amount_left_to_req, amount_left_to_write; | ||
| 1263 | loff_t usb_offset, file_offset, file_offset_tmp; | ||
| 1264 | unsigned int amount; | ||
| 1265 | unsigned int partial_page; | ||
| 1266 | ssize_t nwritten; | ||
| 1267 | int rc; | ||
| 1268 | |||
| 1269 | if (curlun->ro) { | ||
| 1270 | curlun->sense_data = SS_WRITE_PROTECTED; | ||
| 1271 | return -EINVAL; | ||
| 1272 | } | ||
| 1273 | spin_lock(&curlun->filp->f_lock); | ||
| 1274 | curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait | ||
| 1275 | spin_unlock(&curlun->filp->f_lock); | ||
| 1276 | |||
| 1277 | /* Get the starting Logical Block Address and check that it's | ||
| 1278 | * not too big */ | ||
| 1279 | if (fsg->cmnd[0] == WRITE_6) | ||
| 1280 | lba = get_unaligned_be24(&fsg->cmnd[1]); | ||
| 1281 | else { | ||
| 1282 | lba = get_unaligned_be32(&fsg->cmnd[2]); | ||
| 1283 | |||
| 1284 | /* We allow DPO (Disable Page Out = don't save data in the | ||
| 1285 | * cache) and FUA (Force Unit Access = write directly to the | ||
| 1286 | * medium). We don't implement DPO; we implement FUA by | ||
| 1287 | * performing synchronous output. */ | ||
| 1288 | if ((fsg->cmnd[1] & ~0x18) != 0) { | ||
| 1289 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1290 | return -EINVAL; | ||
| 1291 | } | ||
| 1292 | /* FUA */ | ||
| 1293 | if (!curlun->nofua && (fsg->cmnd[1] & 0x08)) { | ||
| 1294 | spin_lock(&curlun->filp->f_lock); | ||
| 1295 | curlun->filp->f_flags |= O_DSYNC; | ||
| 1296 | spin_unlock(&curlun->filp->f_lock); | ||
| 1297 | } | ||
| 1298 | } | ||
| 1299 | if (lba >= curlun->num_sectors) { | ||
| 1300 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | ||
| 1301 | return -EINVAL; | ||
| 1302 | } | ||
| 1303 | |||
| 1304 | /* Carry out the file writes */ | ||
| 1305 | get_some_more = 1; | ||
| 1306 | file_offset = usb_offset = ((loff_t) lba) << 9; | ||
| 1307 | amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd; | ||
| 1308 | |||
| 1309 | while (amount_left_to_write > 0) { | ||
| 1310 | |||
| 1311 | /* Queue a request for more data from the host */ | ||
| 1312 | bh = fsg->next_buffhd_to_fill; | ||
| 1313 | if (bh->state == BUF_STATE_EMPTY && get_some_more) { | ||
| 1314 | |||
| 1315 | /* Figure out how much we want to get: | ||
| 1316 | * Try to get the remaining amount. | ||
| 1317 | * But don't get more than the buffer size. | ||
| 1318 | * And don't try to go past the end of the file. | ||
| 1319 | * If we're not at a page boundary, | ||
| 1320 | * don't go past the next page. | ||
| 1321 | * If this means getting 0, then we were asked | ||
| 1322 | * to write past the end of file. | ||
| 1323 | * Finally, round down to a block boundary. */ | ||
| 1324 | amount = min(amount_left_to_req, mod_data.buflen); | ||
| 1325 | amount = min((loff_t) amount, curlun->file_length - | ||
| 1326 | usb_offset); | ||
| 1327 | partial_page = usb_offset & (PAGE_CACHE_SIZE - 1); | ||
| 1328 | if (partial_page > 0) | ||
| 1329 | amount = min(amount, | ||
| 1330 | (unsigned int) PAGE_CACHE_SIZE - partial_page); | ||
| 1331 | |||
| 1332 | if (amount == 0) { | ||
| 1333 | get_some_more = 0; | ||
| 1334 | curlun->sense_data = | ||
| 1335 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | ||
| 1336 | curlun->sense_data_info = usb_offset >> 9; | ||
| 1337 | curlun->info_valid = 1; | ||
| 1338 | continue; | ||
| 1339 | } | ||
| 1340 | amount -= (amount & 511); | ||
| 1341 | if (amount == 0) { | ||
| 1342 | |||
| 1343 | /* Why were we were asked to transfer a | ||
| 1344 | * partial block? */ | ||
| 1345 | get_some_more = 0; | ||
| 1346 | continue; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | /* Get the next buffer */ | ||
| 1350 | usb_offset += amount; | ||
| 1351 | fsg->usb_amount_left -= amount; | ||
| 1352 | amount_left_to_req -= amount; | ||
| 1353 | if (amount_left_to_req == 0) | ||
| 1354 | get_some_more = 0; | ||
| 1355 | |||
| 1356 | /* amount is always divisible by 512, hence by | ||
| 1357 | * the bulk-out maxpacket size */ | ||
| 1358 | bh->outreq->length = bh->bulk_out_intended_length = | ||
| 1359 | amount; | ||
| 1360 | bh->outreq->short_not_ok = 1; | ||
| 1361 | start_transfer(fsg, fsg->bulk_out, bh->outreq, | ||
| 1362 | &bh->outreq_busy, &bh->state); | ||
| 1363 | fsg->next_buffhd_to_fill = bh->next; | ||
| 1364 | continue; | ||
| 1365 | } | ||
| 1366 | |||
| 1367 | /* Write the received data to the backing file */ | ||
| 1368 | bh = fsg->next_buffhd_to_drain; | ||
| 1369 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) | ||
| 1370 | break; // We stopped early | ||
| 1371 | if (bh->state == BUF_STATE_FULL) { | ||
| 1372 | smp_rmb(); | ||
| 1373 | fsg->next_buffhd_to_drain = bh->next; | ||
| 1374 | bh->state = BUF_STATE_EMPTY; | ||
| 1375 | |||
| 1376 | /* Did something go wrong with the transfer? */ | ||
| 1377 | if (bh->outreq->status != 0) { | ||
| 1378 | curlun->sense_data = SS_COMMUNICATION_FAILURE; | ||
| 1379 | curlun->sense_data_info = file_offset >> 9; | ||
| 1380 | curlun->info_valid = 1; | ||
| 1381 | break; | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | amount = bh->outreq->actual; | ||
| 1385 | if (curlun->file_length - file_offset < amount) { | ||
| 1386 | LERROR(curlun, | ||
| 1387 | "write %u @ %llu beyond end %llu\n", | ||
| 1388 | amount, (unsigned long long) file_offset, | ||
| 1389 | (unsigned long long) curlun->file_length); | ||
| 1390 | amount = curlun->file_length - file_offset; | ||
| 1391 | } | ||
| 1392 | |||
| 1393 | /* Perform the write */ | ||
| 1394 | file_offset_tmp = file_offset; | ||
| 1395 | nwritten = vfs_write(curlun->filp, | ||
| 1396 | (char __user *) bh->buf, | ||
| 1397 | amount, &file_offset_tmp); | ||
| 1398 | VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, | ||
| 1399 | (unsigned long long) file_offset, | ||
| 1400 | (int) nwritten); | ||
| 1401 | if (signal_pending(current)) | ||
| 1402 | return -EINTR; // Interrupted! | ||
| 1403 | |||
| 1404 | if (nwritten < 0) { | ||
| 1405 | LDBG(curlun, "error in file write: %d\n", | ||
| 1406 | (int) nwritten); | ||
| 1407 | nwritten = 0; | ||
| 1408 | } else if (nwritten < amount) { | ||
| 1409 | LDBG(curlun, "partial file write: %d/%u\n", | ||
| 1410 | (int) nwritten, amount); | ||
| 1411 | nwritten -= (nwritten & 511); | ||
| 1412 | // Round down to a block | ||
| 1413 | } | ||
| 1414 | file_offset += nwritten; | ||
| 1415 | amount_left_to_write -= nwritten; | ||
| 1416 | fsg->residue -= nwritten; | ||
| 1417 | |||
| 1418 | /* If an error occurred, report it and its position */ | ||
| 1419 | if (nwritten < amount) { | ||
| 1420 | curlun->sense_data = SS_WRITE_ERROR; | ||
| 1421 | curlun->sense_data_info = file_offset >> 9; | ||
| 1422 | curlun->info_valid = 1; | ||
| 1423 | break; | ||
| 1424 | } | ||
| 1425 | |||
| 1426 | /* Did the host decide to stop early? */ | ||
| 1427 | if (bh->outreq->actual != bh->outreq->length) { | ||
| 1428 | fsg->short_packet_received = 1; | ||
| 1429 | break; | ||
| 1430 | } | ||
| 1431 | continue; | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | /* Wait for something to happen */ | ||
| 1435 | rc = sleep_thread(fsg); | ||
| 1436 | if (rc) | ||
| 1437 | return rc; | ||
| 1438 | } | ||
| 1439 | |||
| 1440 | return -EIO; // No default reply | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | |||
| 1444 | /*-------------------------------------------------------------------------*/ | ||
| 1445 | |||
| 1446 | static int do_synchronize_cache(struct fsg_dev *fsg) | ||
| 1447 | { | ||
| 1448 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1449 | int rc; | ||
| 1450 | |||
| 1451 | /* We ignore the requested LBA and write out all file's | ||
| 1452 | * dirty data buffers. */ | ||
| 1453 | rc = fsg_lun_fsync_sub(curlun); | ||
| 1454 | if (rc) | ||
| 1455 | curlun->sense_data = SS_WRITE_ERROR; | ||
| 1456 | return 0; | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | |||
| 1460 | /*-------------------------------------------------------------------------*/ | ||
| 1461 | |||
| 1462 | static void invalidate_sub(struct fsg_lun *curlun) | ||
| 1463 | { | ||
| 1464 | struct file *filp = curlun->filp; | ||
| 1465 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
| 1466 | unsigned long rc; | ||
| 1467 | |||
| 1468 | rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); | ||
| 1469 | VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc); | ||
| 1470 | } | ||
| 1471 | |||
| 1472 | static int do_verify(struct fsg_dev *fsg) | ||
| 1473 | { | ||
| 1474 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1475 | u32 lba; | ||
| 1476 | u32 verification_length; | ||
| 1477 | struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; | ||
| 1478 | loff_t file_offset, file_offset_tmp; | ||
| 1479 | u32 amount_left; | ||
| 1480 | unsigned int amount; | ||
| 1481 | ssize_t nread; | ||
| 1482 | |||
| 1483 | /* Get the starting Logical Block Address and check that it's | ||
| 1484 | * not too big */ | ||
| 1485 | lba = get_unaligned_be32(&fsg->cmnd[2]); | ||
| 1486 | if (lba >= curlun->num_sectors) { | ||
| 1487 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | ||
| 1488 | return -EINVAL; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | /* We allow DPO (Disable Page Out = don't save data in the | ||
| 1492 | * cache) but we don't implement it. */ | ||
| 1493 | if ((fsg->cmnd[1] & ~0x10) != 0) { | ||
| 1494 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1495 | return -EINVAL; | ||
| 1496 | } | ||
| 1497 | |||
| 1498 | verification_length = get_unaligned_be16(&fsg->cmnd[7]); | ||
| 1499 | if (unlikely(verification_length == 0)) | ||
| 1500 | return -EIO; // No default reply | ||
| 1501 | |||
| 1502 | /* Prepare to carry out the file verify */ | ||
| 1503 | amount_left = verification_length << 9; | ||
| 1504 | file_offset = ((loff_t) lba) << 9; | ||
| 1505 | |||
| 1506 | /* Write out all the dirty buffers before invalidating them */ | ||
| 1507 | fsg_lun_fsync_sub(curlun); | ||
| 1508 | if (signal_pending(current)) | ||
| 1509 | return -EINTR; | ||
| 1510 | |||
| 1511 | invalidate_sub(curlun); | ||
| 1512 | if (signal_pending(current)) | ||
| 1513 | return -EINTR; | ||
| 1514 | |||
| 1515 | /* Just try to read the requested blocks */ | ||
| 1516 | while (amount_left > 0) { | ||
| 1517 | |||
| 1518 | /* Figure out how much we need to read: | ||
| 1519 | * Try to read the remaining amount, but not more than | ||
| 1520 | * the buffer size. | ||
| 1521 | * And don't try to read past the end of the file. | ||
| 1522 | * If this means reading 0 then we were asked to read | ||
| 1523 | * past the end of file. */ | ||
| 1524 | amount = min((unsigned int) amount_left, mod_data.buflen); | ||
| 1525 | amount = min((loff_t) amount, | ||
| 1526 | curlun->file_length - file_offset); | ||
| 1527 | if (amount == 0) { | ||
| 1528 | curlun->sense_data = | ||
| 1529 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | ||
| 1530 | curlun->sense_data_info = file_offset >> 9; | ||
| 1531 | curlun->info_valid = 1; | ||
| 1532 | break; | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | /* Perform the read */ | ||
| 1536 | file_offset_tmp = file_offset; | ||
| 1537 | nread = vfs_read(curlun->filp, | ||
| 1538 | (char __user *) bh->buf, | ||
| 1539 | amount, &file_offset_tmp); | ||
| 1540 | VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, | ||
| 1541 | (unsigned long long) file_offset, | ||
| 1542 | (int) nread); | ||
| 1543 | if (signal_pending(current)) | ||
| 1544 | return -EINTR; | ||
| 1545 | |||
| 1546 | if (nread < 0) { | ||
| 1547 | LDBG(curlun, "error in file verify: %d\n", | ||
| 1548 | (int) nread); | ||
| 1549 | nread = 0; | ||
| 1550 | } else if (nread < amount) { | ||
| 1551 | LDBG(curlun, "partial file verify: %d/%u\n", | ||
| 1552 | (int) nread, amount); | ||
| 1553 | nread -= (nread & 511); // Round down to a sector | ||
| 1554 | } | ||
| 1555 | if (nread == 0) { | ||
| 1556 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | ||
| 1557 | curlun->sense_data_info = file_offset >> 9; | ||
| 1558 | curlun->info_valid = 1; | ||
| 1559 | break; | ||
| 1560 | } | ||
| 1561 | file_offset += nread; | ||
| 1562 | amount_left -= nread; | ||
| 1563 | } | ||
| 1564 | return 0; | ||
| 1565 | } | ||
| 1566 | |||
| 1567 | |||
| 1568 | /*-------------------------------------------------------------------------*/ | ||
| 1569 | |||
| 1570 | static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 1571 | { | ||
| 1572 | u8 *buf = (u8 *) bh->buf; | ||
| 1573 | |||
| 1574 | static char vendor_id[] = "Linux "; | ||
| 1575 | static char product_disk_id[] = "File-Stor Gadget"; | ||
| 1576 | static char product_cdrom_id[] = "File-CD Gadget "; | ||
| 1577 | |||
| 1578 | if (!fsg->curlun) { // Unsupported LUNs are okay | ||
| 1579 | fsg->bad_lun_okay = 1; | ||
| 1580 | memset(buf, 0, 36); | ||
| 1581 | buf[0] = 0x7f; // Unsupported, no device-type | ||
| 1582 | buf[4] = 31; // Additional length | ||
| 1583 | return 36; | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | memset(buf, 0, 8); | ||
| 1587 | buf[0] = (mod_data.cdrom ? TYPE_ROM : TYPE_DISK); | ||
| 1588 | if (mod_data.removable) | ||
| 1589 | buf[1] = 0x80; | ||
| 1590 | buf[2] = 2; // ANSI SCSI level 2 | ||
| 1591 | buf[3] = 2; // SCSI-2 INQUIRY data format | ||
| 1592 | buf[4] = 31; // Additional length | ||
| 1593 | // No special options | ||
| 1594 | sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, | ||
| 1595 | (mod_data.cdrom ? product_cdrom_id : | ||
| 1596 | product_disk_id), | ||
| 1597 | mod_data.release); | ||
| 1598 | return 36; | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | |||
| 1602 | static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 1603 | { | ||
| 1604 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1605 | u8 *buf = (u8 *) bh->buf; | ||
| 1606 | u32 sd, sdinfo; | ||
| 1607 | int valid; | ||
| 1608 | |||
| 1609 | /* | ||
| 1610 | * From the SCSI-2 spec., section 7.9 (Unit attention condition): | ||
| 1611 | * | ||
| 1612 | * If a REQUEST SENSE command is received from an initiator | ||
| 1613 | * with a pending unit attention condition (before the target | ||
| 1614 | * generates the contingent allegiance condition), then the | ||
| 1615 | * target shall either: | ||
| 1616 | * a) report any pending sense data and preserve the unit | ||
| 1617 | * attention condition on the logical unit, or, | ||
| 1618 | * b) report the unit attention condition, may discard any | ||
| 1619 | * pending sense data, and clear the unit attention | ||
| 1620 | * condition on the logical unit for that initiator. | ||
| 1621 | * | ||
| 1622 | * FSG normally uses option a); enable this code to use option b). | ||
| 1623 | */ | ||
| 1624 | #if 0 | ||
| 1625 | if (curlun && curlun->unit_attention_data != SS_NO_SENSE) { | ||
| 1626 | curlun->sense_data = curlun->unit_attention_data; | ||
| 1627 | curlun->unit_attention_data = SS_NO_SENSE; | ||
| 1628 | } | ||
| 1629 | #endif | ||
| 1630 | |||
| 1631 | if (!curlun) { // Unsupported LUNs are okay | ||
| 1632 | fsg->bad_lun_okay = 1; | ||
| 1633 | sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; | ||
| 1634 | sdinfo = 0; | ||
| 1635 | valid = 0; | ||
| 1636 | } else { | ||
| 1637 | sd = curlun->sense_data; | ||
| 1638 | sdinfo = curlun->sense_data_info; | ||
| 1639 | valid = curlun->info_valid << 7; | ||
| 1640 | curlun->sense_data = SS_NO_SENSE; | ||
| 1641 | curlun->sense_data_info = 0; | ||
| 1642 | curlun->info_valid = 0; | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | memset(buf, 0, 18); | ||
| 1646 | buf[0] = valid | 0x70; // Valid, current error | ||
| 1647 | buf[2] = SK(sd); | ||
| 1648 | put_unaligned_be32(sdinfo, &buf[3]); /* Sense information */ | ||
| 1649 | buf[7] = 18 - 8; // Additional sense length | ||
| 1650 | buf[12] = ASC(sd); | ||
| 1651 | buf[13] = ASCQ(sd); | ||
| 1652 | return 18; | ||
| 1653 | } | ||
| 1654 | |||
| 1655 | |||
| 1656 | static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 1657 | { | ||
| 1658 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1659 | u32 lba = get_unaligned_be32(&fsg->cmnd[2]); | ||
| 1660 | int pmi = fsg->cmnd[8]; | ||
| 1661 | u8 *buf = (u8 *) bh->buf; | ||
| 1662 | |||
| 1663 | /* Check the PMI and LBA fields */ | ||
| 1664 | if (pmi > 1 || (pmi == 0 && lba != 0)) { | ||
| 1665 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1666 | return -EINVAL; | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); | ||
| 1670 | /* Max logical block */ | ||
| 1671 | put_unaligned_be32(512, &buf[4]); /* Block length */ | ||
| 1672 | return 8; | ||
| 1673 | } | ||
| 1674 | |||
| 1675 | |||
| 1676 | static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 1677 | { | ||
| 1678 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1679 | int msf = fsg->cmnd[1] & 0x02; | ||
| 1680 | u32 lba = get_unaligned_be32(&fsg->cmnd[2]); | ||
| 1681 | u8 *buf = (u8 *) bh->buf; | ||
| 1682 | |||
| 1683 | if ((fsg->cmnd[1] & ~0x02) != 0) { /* Mask away MSF */ | ||
| 1684 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1685 | return -EINVAL; | ||
| 1686 | } | ||
| 1687 | if (lba >= curlun->num_sectors) { | ||
| 1688 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | ||
| 1689 | return -EINVAL; | ||
| 1690 | } | ||
| 1691 | |||
| 1692 | memset(buf, 0, 8); | ||
| 1693 | buf[0] = 0x01; /* 2048 bytes of user data, rest is EC */ | ||
| 1694 | store_cdrom_address(&buf[4], msf, lba); | ||
| 1695 | return 8; | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | |||
| 1699 | static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 1700 | { | ||
| 1701 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1702 | int msf = fsg->cmnd[1] & 0x02; | ||
| 1703 | int start_track = fsg->cmnd[6]; | ||
| 1704 | u8 *buf = (u8 *) bh->buf; | ||
| 1705 | |||
| 1706 | if ((fsg->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ | ||
| 1707 | start_track > 1) { | ||
| 1708 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1709 | return -EINVAL; | ||
| 1710 | } | ||
| 1711 | |||
| 1712 | memset(buf, 0, 20); | ||
| 1713 | buf[1] = (20-2); /* TOC data length */ | ||
| 1714 | buf[2] = 1; /* First track number */ | ||
| 1715 | buf[3] = 1; /* Last track number */ | ||
| 1716 | buf[5] = 0x16; /* Data track, copying allowed */ | ||
| 1717 | buf[6] = 0x01; /* Only track is number 1 */ | ||
| 1718 | store_cdrom_address(&buf[8], msf, 0); | ||
| 1719 | |||
| 1720 | buf[13] = 0x16; /* Lead-out track is data */ | ||
| 1721 | buf[14] = 0xAA; /* Lead-out track number */ | ||
| 1722 | store_cdrom_address(&buf[16], msf, curlun->num_sectors); | ||
| 1723 | return 20; | ||
| 1724 | } | ||
| 1725 | |||
| 1726 | |||
| 1727 | static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 1728 | { | ||
| 1729 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1730 | int mscmnd = fsg->cmnd[0]; | ||
| 1731 | u8 *buf = (u8 *) bh->buf; | ||
| 1732 | u8 *buf0 = buf; | ||
| 1733 | int pc, page_code; | ||
| 1734 | int changeable_values, all_pages; | ||
| 1735 | int valid_page = 0; | ||
| 1736 | int len, limit; | ||
| 1737 | |||
| 1738 | if ((fsg->cmnd[1] & ~0x08) != 0) { // Mask away DBD | ||
| 1739 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1740 | return -EINVAL; | ||
| 1741 | } | ||
| 1742 | pc = fsg->cmnd[2] >> 6; | ||
| 1743 | page_code = fsg->cmnd[2] & 0x3f; | ||
| 1744 | if (pc == 3) { | ||
| 1745 | curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; | ||
| 1746 | return -EINVAL; | ||
| 1747 | } | ||
| 1748 | changeable_values = (pc == 1); | ||
| 1749 | all_pages = (page_code == 0x3f); | ||
| 1750 | |||
| 1751 | /* Write the mode parameter header. Fixed values are: default | ||
| 1752 | * medium type, no cache control (DPOFUA), and no block descriptors. | ||
| 1753 | * The only variable value is the WriteProtect bit. We will fill in | ||
| 1754 | * the mode data length later. */ | ||
| 1755 | memset(buf, 0, 8); | ||
| 1756 | if (mscmnd == MODE_SENSE) { | ||
| 1757 | buf[2] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA | ||
| 1758 | buf += 4; | ||
| 1759 | limit = 255; | ||
| 1760 | } else { // MODE_SENSE_10 | ||
| 1761 | buf[3] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA | ||
| 1762 | buf += 8; | ||
| 1763 | limit = 65535; // Should really be mod_data.buflen | ||
| 1764 | } | ||
| 1765 | |||
| 1766 | /* No block descriptors */ | ||
| 1767 | |||
| 1768 | /* The mode pages, in numerical order. The only page we support | ||
| 1769 | * is the Caching page. */ | ||
| 1770 | if (page_code == 0x08 || all_pages) { | ||
| 1771 | valid_page = 1; | ||
| 1772 | buf[0] = 0x08; // Page code | ||
| 1773 | buf[1] = 10; // Page length | ||
| 1774 | memset(buf+2, 0, 10); // None of the fields are changeable | ||
| 1775 | |||
| 1776 | if (!changeable_values) { | ||
| 1777 | buf[2] = 0x04; // Write cache enable, | ||
| 1778 | // Read cache not disabled | ||
| 1779 | // No cache retention priorities | ||
| 1780 | put_unaligned_be16(0xffff, &buf[4]); | ||
| 1781 | /* Don't disable prefetch */ | ||
| 1782 | /* Minimum prefetch = 0 */ | ||
| 1783 | put_unaligned_be16(0xffff, &buf[8]); | ||
| 1784 | /* Maximum prefetch */ | ||
| 1785 | put_unaligned_be16(0xffff, &buf[10]); | ||
| 1786 | /* Maximum prefetch ceiling */ | ||
| 1787 | } | ||
| 1788 | buf += 12; | ||
| 1789 | } | ||
| 1790 | |||
| 1791 | /* Check that a valid page was requested and the mode data length | ||
| 1792 | * isn't too long. */ | ||
| 1793 | len = buf - buf0; | ||
| 1794 | if (!valid_page || len > limit) { | ||
| 1795 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1796 | return -EINVAL; | ||
| 1797 | } | ||
| 1798 | |||
| 1799 | /* Store the mode data length */ | ||
| 1800 | if (mscmnd == MODE_SENSE) | ||
| 1801 | buf0[0] = len - 1; | ||
| 1802 | else | ||
| 1803 | put_unaligned_be16(len - 2, buf0); | ||
| 1804 | return len; | ||
| 1805 | } | ||
| 1806 | |||
| 1807 | |||
| 1808 | static int do_start_stop(struct fsg_dev *fsg) | ||
| 1809 | { | ||
| 1810 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1811 | int loej, start; | ||
| 1812 | |||
| 1813 | if (!mod_data.removable) { | ||
| 1814 | curlun->sense_data = SS_INVALID_COMMAND; | ||
| 1815 | return -EINVAL; | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | // int immed = fsg->cmnd[1] & 0x01; | ||
| 1819 | loej = fsg->cmnd[4] & 0x02; | ||
| 1820 | start = fsg->cmnd[4] & 0x01; | ||
| 1821 | |||
| 1822 | #ifdef CONFIG_USB_FILE_STORAGE_TEST | ||
| 1823 | if ((fsg->cmnd[1] & ~0x01) != 0 || // Mask away Immed | ||
| 1824 | (fsg->cmnd[4] & ~0x03) != 0) { // Mask LoEj, Start | ||
| 1825 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1826 | return -EINVAL; | ||
| 1827 | } | ||
| 1828 | |||
| 1829 | if (!start) { | ||
| 1830 | |||
| 1831 | /* Are we allowed to unload the media? */ | ||
| 1832 | if (curlun->prevent_medium_removal) { | ||
| 1833 | LDBG(curlun, "unload attempt prevented\n"); | ||
| 1834 | curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED; | ||
| 1835 | return -EINVAL; | ||
| 1836 | } | ||
| 1837 | if (loej) { // Simulate an unload/eject | ||
| 1838 | up_read(&fsg->filesem); | ||
| 1839 | down_write(&fsg->filesem); | ||
| 1840 | fsg_lun_close(curlun); | ||
| 1841 | up_write(&fsg->filesem); | ||
| 1842 | down_read(&fsg->filesem); | ||
| 1843 | } | ||
| 1844 | } else { | ||
| 1845 | |||
| 1846 | /* Our emulation doesn't support mounting; the medium is | ||
| 1847 | * available for use as soon as it is loaded. */ | ||
| 1848 | if (!fsg_lun_is_open(curlun)) { | ||
| 1849 | curlun->sense_data = SS_MEDIUM_NOT_PRESENT; | ||
| 1850 | return -EINVAL; | ||
| 1851 | } | ||
| 1852 | } | ||
| 1853 | #endif | ||
| 1854 | return 0; | ||
| 1855 | } | ||
| 1856 | |||
| 1857 | |||
| 1858 | static int do_prevent_allow(struct fsg_dev *fsg) | ||
| 1859 | { | ||
| 1860 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1861 | int prevent; | ||
| 1862 | |||
| 1863 | if (!mod_data.removable) { | ||
| 1864 | curlun->sense_data = SS_INVALID_COMMAND; | ||
| 1865 | return -EINVAL; | ||
| 1866 | } | ||
| 1867 | |||
| 1868 | prevent = fsg->cmnd[4] & 0x01; | ||
| 1869 | if ((fsg->cmnd[4] & ~0x01) != 0) { // Mask away Prevent | ||
| 1870 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 1871 | return -EINVAL; | ||
| 1872 | } | ||
| 1873 | |||
| 1874 | if (curlun->prevent_medium_removal && !prevent) | ||
| 1875 | fsg_lun_fsync_sub(curlun); | ||
| 1876 | curlun->prevent_medium_removal = prevent; | ||
| 1877 | return 0; | ||
| 1878 | } | ||
| 1879 | |||
| 1880 | |||
| 1881 | static int do_read_format_capacities(struct fsg_dev *fsg, | ||
| 1882 | struct fsg_buffhd *bh) | ||
| 1883 | { | ||
| 1884 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1885 | u8 *buf = (u8 *) bh->buf; | ||
| 1886 | |||
| 1887 | buf[0] = buf[1] = buf[2] = 0; | ||
| 1888 | buf[3] = 8; // Only the Current/Maximum Capacity Descriptor | ||
| 1889 | buf += 4; | ||
| 1890 | |||
| 1891 | put_unaligned_be32(curlun->num_sectors, &buf[0]); | ||
| 1892 | /* Number of blocks */ | ||
| 1893 | put_unaligned_be32(512, &buf[4]); /* Block length */ | ||
| 1894 | buf[4] = 0x02; /* Current capacity */ | ||
| 1895 | return 12; | ||
| 1896 | } | ||
| 1897 | |||
| 1898 | |||
| 1899 | static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 1900 | { | ||
| 1901 | struct fsg_lun *curlun = fsg->curlun; | ||
| 1902 | |||
| 1903 | /* We don't support MODE SELECT */ | ||
| 1904 | curlun->sense_data = SS_INVALID_COMMAND; | ||
| 1905 | return -EINVAL; | ||
| 1906 | } | ||
| 1907 | |||
| 1908 | |||
| 1909 | /*-------------------------------------------------------------------------*/ | ||
| 1910 | |||
| 1911 | static int halt_bulk_in_endpoint(struct fsg_dev *fsg) | ||
| 1912 | { | ||
| 1913 | int rc; | ||
| 1914 | |||
| 1915 | rc = fsg_set_halt(fsg, fsg->bulk_in); | ||
| 1916 | if (rc == -EAGAIN) | ||
| 1917 | VDBG(fsg, "delayed bulk-in endpoint halt\n"); | ||
| 1918 | while (rc != 0) { | ||
| 1919 | if (rc != -EAGAIN) { | ||
| 1920 | WARNING(fsg, "usb_ep_set_halt -> %d\n", rc); | ||
| 1921 | rc = 0; | ||
| 1922 | break; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | /* Wait for a short time and then try again */ | ||
| 1926 | if (msleep_interruptible(100) != 0) | ||
| 1927 | return -EINTR; | ||
| 1928 | rc = usb_ep_set_halt(fsg->bulk_in); | ||
| 1929 | } | ||
| 1930 | return rc; | ||
| 1931 | } | ||
| 1932 | |||
| 1933 | static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) | ||
| 1934 | { | ||
| 1935 | int rc; | ||
| 1936 | |||
| 1937 | DBG(fsg, "bulk-in set wedge\n"); | ||
| 1938 | rc = usb_ep_set_wedge(fsg->bulk_in); | ||
| 1939 | if (rc == -EAGAIN) | ||
| 1940 | VDBG(fsg, "delayed bulk-in endpoint wedge\n"); | ||
| 1941 | while (rc != 0) { | ||
| 1942 | if (rc != -EAGAIN) { | ||
| 1943 | WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc); | ||
| 1944 | rc = 0; | ||
| 1945 | break; | ||
| 1946 | } | ||
| 1947 | |||
| 1948 | /* Wait for a short time and then try again */ | ||
| 1949 | if (msleep_interruptible(100) != 0) | ||
| 1950 | return -EINTR; | ||
| 1951 | rc = usb_ep_set_wedge(fsg->bulk_in); | ||
| 1952 | } | ||
| 1953 | return rc; | ||
| 1954 | } | ||
| 1955 | |||
| 1956 | static int throw_away_data(struct fsg_dev *fsg) | ||
| 1957 | { | ||
| 1958 | struct fsg_buffhd *bh; | ||
| 1959 | u32 amount; | ||
| 1960 | int rc; | ||
| 1961 | |||
| 1962 | while ((bh = fsg->next_buffhd_to_drain)->state != BUF_STATE_EMPTY || | ||
| 1963 | fsg->usb_amount_left > 0) { | ||
| 1964 | |||
| 1965 | /* Throw away the data in a filled buffer */ | ||
| 1966 | if (bh->state == BUF_STATE_FULL) { | ||
| 1967 | smp_rmb(); | ||
| 1968 | bh->state = BUF_STATE_EMPTY; | ||
| 1969 | fsg->next_buffhd_to_drain = bh->next; | ||
| 1970 | |||
| 1971 | /* A short packet or an error ends everything */ | ||
| 1972 | if (bh->outreq->actual != bh->outreq->length || | ||
| 1973 | bh->outreq->status != 0) { | ||
| 1974 | raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); | ||
| 1975 | return -EINTR; | ||
| 1976 | } | ||
| 1977 | continue; | ||
| 1978 | } | ||
| 1979 | |||
| 1980 | /* Try to submit another request if we need one */ | ||
| 1981 | bh = fsg->next_buffhd_to_fill; | ||
| 1982 | if (bh->state == BUF_STATE_EMPTY && fsg->usb_amount_left > 0) { | ||
| 1983 | amount = min(fsg->usb_amount_left, | ||
| 1984 | (u32) mod_data.buflen); | ||
| 1985 | |||
| 1986 | /* amount is always divisible by 512, hence by | ||
| 1987 | * the bulk-out maxpacket size */ | ||
| 1988 | bh->outreq->length = bh->bulk_out_intended_length = | ||
| 1989 | amount; | ||
| 1990 | bh->outreq->short_not_ok = 1; | ||
| 1991 | start_transfer(fsg, fsg->bulk_out, bh->outreq, | ||
| 1992 | &bh->outreq_busy, &bh->state); | ||
| 1993 | fsg->next_buffhd_to_fill = bh->next; | ||
| 1994 | fsg->usb_amount_left -= amount; | ||
| 1995 | continue; | ||
| 1996 | } | ||
| 1997 | |||
| 1998 | /* Otherwise wait for something to happen */ | ||
| 1999 | rc = sleep_thread(fsg); | ||
| 2000 | if (rc) | ||
| 2001 | return rc; | ||
| 2002 | } | ||
| 2003 | return 0; | ||
| 2004 | } | ||
| 2005 | |||
| 2006 | |||
| 2007 | static int finish_reply(struct fsg_dev *fsg) | ||
| 2008 | { | ||
| 2009 | struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; | ||
| 2010 | int rc = 0; | ||
| 2011 | |||
| 2012 | switch (fsg->data_dir) { | ||
| 2013 | case DATA_DIR_NONE: | ||
| 2014 | break; // Nothing to send | ||
| 2015 | |||
| 2016 | /* If we don't know whether the host wants to read or write, | ||
| 2017 | * this must be CB or CBI with an unknown command. We mustn't | ||
| 2018 | * try to send or receive any data. So stall both bulk pipes | ||
| 2019 | * if we can and wait for a reset. */ | ||
| 2020 | case DATA_DIR_UNKNOWN: | ||
| 2021 | if (mod_data.can_stall) { | ||
| 2022 | fsg_set_halt(fsg, fsg->bulk_out); | ||
| 2023 | rc = halt_bulk_in_endpoint(fsg); | ||
| 2024 | } | ||
| 2025 | break; | ||
| 2026 | |||
| 2027 | /* All but the last buffer of data must have already been sent */ | ||
| 2028 | case DATA_DIR_TO_HOST: | ||
| 2029 | if (fsg->data_size == 0) | ||
| 2030 | ; // Nothing to send | ||
| 2031 | |||
| 2032 | /* If there's no residue, simply send the last buffer */ | ||
| 2033 | else if (fsg->residue == 0) { | ||
| 2034 | bh->inreq->zero = 0; | ||
| 2035 | start_transfer(fsg, fsg->bulk_in, bh->inreq, | ||
| 2036 | &bh->inreq_busy, &bh->state); | ||
| 2037 | fsg->next_buffhd_to_fill = bh->next; | ||
| 2038 | } | ||
| 2039 | |||
| 2040 | /* There is a residue. For CB and CBI, simply mark the end | ||
| 2041 | * of the data with a short packet. However, if we are | ||
| 2042 | * allowed to stall, there was no data at all (residue == | ||
| 2043 | * data_size), and the command failed (invalid LUN or | ||
| 2044 | * sense data is set), then halt the bulk-in endpoint | ||
| 2045 | * instead. */ | ||
| 2046 | else if (!transport_is_bbb()) { | ||
| 2047 | if (mod_data.can_stall && | ||
| 2048 | fsg->residue == fsg->data_size && | ||
| 2049 | (!fsg->curlun || fsg->curlun->sense_data != SS_NO_SENSE)) { | ||
| 2050 | bh->state = BUF_STATE_EMPTY; | ||
| 2051 | rc = halt_bulk_in_endpoint(fsg); | ||
| 2052 | } else { | ||
| 2053 | bh->inreq->zero = 1; | ||
| 2054 | start_transfer(fsg, fsg->bulk_in, bh->inreq, | ||
| 2055 | &bh->inreq_busy, &bh->state); | ||
| 2056 | fsg->next_buffhd_to_fill = bh->next; | ||
| 2057 | } | ||
| 2058 | } | ||
| 2059 | |||
| 2060 | /* | ||
| 2061 | * For Bulk-only, mark the end of the data with a short | ||
| 2062 | * packet. If we are allowed to stall, halt the bulk-in | ||
| 2063 | * endpoint. (Note: This violates the Bulk-Only Transport | ||
| 2064 | * specification, which requires us to pad the data if we | ||
| 2065 | * don't halt the endpoint. Presumably nobody will mind.) | ||
| 2066 | */ | ||
| 2067 | else { | ||
| 2068 | bh->inreq->zero = 1; | ||
| 2069 | start_transfer(fsg, fsg->bulk_in, bh->inreq, | ||
| 2070 | &bh->inreq_busy, &bh->state); | ||
| 2071 | fsg->next_buffhd_to_fill = bh->next; | ||
| 2072 | if (mod_data.can_stall) | ||
| 2073 | rc = halt_bulk_in_endpoint(fsg); | ||
| 2074 | } | ||
| 2075 | break; | ||
| 2076 | |||
| 2077 | /* We have processed all we want from the data the host has sent. | ||
| 2078 | * There may still be outstanding bulk-out requests. */ | ||
| 2079 | case DATA_DIR_FROM_HOST: | ||
| 2080 | if (fsg->residue == 0) | ||
| 2081 | ; // Nothing to receive | ||
| 2082 | |||
| 2083 | /* Did the host stop sending unexpectedly early? */ | ||
| 2084 | else if (fsg->short_packet_received) { | ||
| 2085 | raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); | ||
| 2086 | rc = -EINTR; | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | /* We haven't processed all the incoming data. Even though | ||
| 2090 | * we may be allowed to stall, doing so would cause a race. | ||
| 2091 | * The controller may already have ACK'ed all the remaining | ||
| 2092 | * bulk-out packets, in which case the host wouldn't see a | ||
| 2093 | * STALL. Not realizing the endpoint was halted, it wouldn't | ||
| 2094 | * clear the halt -- leading to problems later on. */ | ||
| 2095 | #if 0 | ||
| 2096 | else if (mod_data.can_stall) { | ||
| 2097 | fsg_set_halt(fsg, fsg->bulk_out); | ||
| 2098 | raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); | ||
| 2099 | rc = -EINTR; | ||
| 2100 | } | ||
| 2101 | #endif | ||
| 2102 | |||
| 2103 | /* We can't stall. Read in the excess data and throw it | ||
| 2104 | * all away. */ | ||
| 2105 | else | ||
| 2106 | rc = throw_away_data(fsg); | ||
| 2107 | break; | ||
| 2108 | } | ||
| 2109 | return rc; | ||
| 2110 | } | ||
| 2111 | |||
| 2112 | |||
| 2113 | static int send_status(struct fsg_dev *fsg) | ||
| 2114 | { | ||
| 2115 | struct fsg_lun *curlun = fsg->curlun; | ||
| 2116 | struct fsg_buffhd *bh; | ||
| 2117 | int rc; | ||
| 2118 | u8 status = USB_STATUS_PASS; | ||
| 2119 | u32 sd, sdinfo = 0; | ||
| 2120 | |||
| 2121 | /* Wait for the next buffer to become available */ | ||
| 2122 | bh = fsg->next_buffhd_to_fill; | ||
| 2123 | while (bh->state != BUF_STATE_EMPTY) { | ||
| 2124 | rc = sleep_thread(fsg); | ||
| 2125 | if (rc) | ||
| 2126 | return rc; | ||
| 2127 | } | ||
| 2128 | |||
| 2129 | if (curlun) { | ||
| 2130 | sd = curlun->sense_data; | ||
| 2131 | sdinfo = curlun->sense_data_info; | ||
| 2132 | } else if (fsg->bad_lun_okay) | ||
| 2133 | sd = SS_NO_SENSE; | ||
| 2134 | else | ||
| 2135 | sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; | ||
| 2136 | |||
| 2137 | if (fsg->phase_error) { | ||
| 2138 | DBG(fsg, "sending phase-error status\n"); | ||
| 2139 | status = USB_STATUS_PHASE_ERROR; | ||
| 2140 | sd = SS_INVALID_COMMAND; | ||
| 2141 | } else if (sd != SS_NO_SENSE) { | ||
| 2142 | DBG(fsg, "sending command-failure status\n"); | ||
| 2143 | status = USB_STATUS_FAIL; | ||
| 2144 | VDBG(fsg, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;" | ||
| 2145 | " info x%x\n", | ||
| 2146 | SK(sd), ASC(sd), ASCQ(sd), sdinfo); | ||
| 2147 | } | ||
| 2148 | |||
| 2149 | if (transport_is_bbb()) { | ||
| 2150 | struct bulk_cs_wrap *csw = bh->buf; | ||
| 2151 | |||
| 2152 | /* Store and send the Bulk-only CSW */ | ||
| 2153 | csw->Signature = cpu_to_le32(USB_BULK_CS_SIG); | ||
| 2154 | csw->Tag = fsg->tag; | ||
| 2155 | csw->Residue = cpu_to_le32(fsg->residue); | ||
| 2156 | csw->Status = status; | ||
| 2157 | |||
| 2158 | bh->inreq->length = USB_BULK_CS_WRAP_LEN; | ||
| 2159 | bh->inreq->zero = 0; | ||
| 2160 | start_transfer(fsg, fsg->bulk_in, bh->inreq, | ||
| 2161 | &bh->inreq_busy, &bh->state); | ||
| 2162 | |||
| 2163 | } else if (mod_data.transport_type == USB_PR_CB) { | ||
| 2164 | |||
| 2165 | /* Control-Bulk transport has no status phase! */ | ||
| 2166 | return 0; | ||
| 2167 | |||
| 2168 | } else { // USB_PR_CBI | ||
| 2169 | struct interrupt_data *buf = bh->buf; | ||
| 2170 | |||
| 2171 | /* Store and send the Interrupt data. UFI sends the ASC | ||
| 2172 | * and ASCQ bytes. Everything else sends a Type (which | ||
| 2173 | * is always 0) and the status Value. */ | ||
| 2174 | if (mod_data.protocol_type == USB_SC_UFI) { | ||
| 2175 | buf->bType = ASC(sd); | ||
| 2176 | buf->bValue = ASCQ(sd); | ||
| 2177 | } else { | ||
| 2178 | buf->bType = 0; | ||
| 2179 | buf->bValue = status; | ||
| 2180 | } | ||
| 2181 | fsg->intreq->length = CBI_INTERRUPT_DATA_LEN; | ||
| 2182 | |||
| 2183 | fsg->intr_buffhd = bh; // Point to the right buffhd | ||
| 2184 | fsg->intreq->buf = bh->inreq->buf; | ||
| 2185 | fsg->intreq->context = bh; | ||
| 2186 | start_transfer(fsg, fsg->intr_in, fsg->intreq, | ||
| 2187 | &fsg->intreq_busy, &bh->state); | ||
| 2188 | } | ||
| 2189 | |||
| 2190 | fsg->next_buffhd_to_fill = bh->next; | ||
| 2191 | return 0; | ||
| 2192 | } | ||
| 2193 | |||
| 2194 | |||
| 2195 | /*-------------------------------------------------------------------------*/ | ||
| 2196 | |||
| 2197 | /* Check whether the command is properly formed and whether its data size | ||
| 2198 | * and direction agree with the values we already have. */ | ||
| 2199 | static int check_command(struct fsg_dev *fsg, int cmnd_size, | ||
| 2200 | enum data_direction data_dir, unsigned int mask, | ||
| 2201 | int needs_medium, const char *name) | ||
| 2202 | { | ||
| 2203 | int i; | ||
| 2204 | int lun = fsg->cmnd[1] >> 5; | ||
| 2205 | static const char dirletter[4] = {'u', 'o', 'i', 'n'}; | ||
| 2206 | char hdlen[20]; | ||
| 2207 | struct fsg_lun *curlun; | ||
| 2208 | |||
| 2209 | /* Adjust the expected cmnd_size for protocol encapsulation padding. | ||
| 2210 | * Transparent SCSI doesn't pad. */ | ||
| 2211 | if (protocol_is_scsi()) | ||
| 2212 | ; | ||
| 2213 | |||
| 2214 | /* There's some disagreement as to whether RBC pads commands or not. | ||
| 2215 | * We'll play it safe and accept either form. */ | ||
| 2216 | else if (mod_data.protocol_type == USB_SC_RBC) { | ||
| 2217 | if (fsg->cmnd_size == 12) | ||
| 2218 | cmnd_size = 12; | ||
| 2219 | |||
| 2220 | /* All the other protocols pad to 12 bytes */ | ||
| 2221 | } else | ||
| 2222 | cmnd_size = 12; | ||
| 2223 | |||
| 2224 | hdlen[0] = 0; | ||
| 2225 | if (fsg->data_dir != DATA_DIR_UNKNOWN) | ||
| 2226 | sprintf(hdlen, ", H%c=%u", dirletter[(int) fsg->data_dir], | ||
| 2227 | fsg->data_size); | ||
| 2228 | VDBG(fsg, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n", | ||
| 2229 | name, cmnd_size, dirletter[(int) data_dir], | ||
| 2230 | fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen); | ||
| 2231 | |||
| 2232 | /* We can't reply at all until we know the correct data direction | ||
| 2233 | * and size. */ | ||
| 2234 | if (fsg->data_size_from_cmnd == 0) | ||
| 2235 | data_dir = DATA_DIR_NONE; | ||
| 2236 | if (fsg->data_dir == DATA_DIR_UNKNOWN) { // CB or CBI | ||
| 2237 | fsg->data_dir = data_dir; | ||
| 2238 | fsg->data_size = fsg->data_size_from_cmnd; | ||
| 2239 | |||
| 2240 | } else { // Bulk-only | ||
| 2241 | if (fsg->data_size < fsg->data_size_from_cmnd) { | ||
| 2242 | |||
| 2243 | /* Host data size < Device data size is a phase error. | ||
| 2244 | * Carry out the command, but only transfer as much | ||
| 2245 | * as we are allowed. */ | ||
| 2246 | fsg->data_size_from_cmnd = fsg->data_size; | ||
| 2247 | fsg->phase_error = 1; | ||
| 2248 | } | ||
| 2249 | } | ||
| 2250 | fsg->residue = fsg->usb_amount_left = fsg->data_size; | ||
| 2251 | |||
| 2252 | /* Conflicting data directions is a phase error */ | ||
| 2253 | if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) { | ||
| 2254 | fsg->phase_error = 1; | ||
| 2255 | return -EINVAL; | ||
| 2256 | } | ||
| 2257 | |||
| 2258 | /* Verify the length of the command itself */ | ||
| 2259 | if (cmnd_size != fsg->cmnd_size) { | ||
| 2260 | |||
| 2261 | /* Special case workaround: There are plenty of buggy SCSI | ||
| 2262 | * implementations. Many have issues with cbw->Length | ||
| 2263 | * field passing a wrong command size. For those cases we | ||
| 2264 | * always try to work around the problem by using the length | ||
| 2265 | * sent by the host side provided it is at least as large | ||
| 2266 | * as the correct command length. | ||
| 2267 | * Examples of such cases would be MS-Windows, which issues | ||
| 2268 | * REQUEST SENSE with cbw->Length == 12 where it should | ||
| 2269 | * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and | ||
| 2270 | * REQUEST SENSE with cbw->Length == 10 where it should | ||
| 2271 | * be 6 as well. | ||
| 2272 | */ | ||
| 2273 | if (cmnd_size <= fsg->cmnd_size) { | ||
| 2274 | DBG(fsg, "%s is buggy! Expected length %d " | ||
| 2275 | "but we got %d\n", name, | ||
| 2276 | cmnd_size, fsg->cmnd_size); | ||
| 2277 | cmnd_size = fsg->cmnd_size; | ||
| 2278 | } else { | ||
| 2279 | fsg->phase_error = 1; | ||
| 2280 | return -EINVAL; | ||
| 2281 | } | ||
| 2282 | } | ||
| 2283 | |||
| 2284 | /* Check that the LUN values are consistent */ | ||
| 2285 | if (transport_is_bbb()) { | ||
| 2286 | if (fsg->lun != lun) | ||
| 2287 | DBG(fsg, "using LUN %d from CBW, " | ||
| 2288 | "not LUN %d from CDB\n", | ||
| 2289 | fsg->lun, lun); | ||
| 2290 | } else | ||
| 2291 | fsg->lun = lun; // Use LUN from the command | ||
| 2292 | |||
| 2293 | /* Check the LUN */ | ||
| 2294 | if (fsg->lun < fsg->nluns) { | ||
| 2295 | fsg->curlun = curlun = &fsg->luns[fsg->lun]; | ||
| 2296 | if (fsg->cmnd[0] != REQUEST_SENSE) { | ||
| 2297 | curlun->sense_data = SS_NO_SENSE; | ||
| 2298 | curlun->sense_data_info = 0; | ||
| 2299 | curlun->info_valid = 0; | ||
| 2300 | } | ||
| 2301 | } else { | ||
| 2302 | fsg->curlun = curlun = NULL; | ||
| 2303 | fsg->bad_lun_okay = 0; | ||
| 2304 | |||
| 2305 | /* INQUIRY and REQUEST SENSE commands are explicitly allowed | ||
| 2306 | * to use unsupported LUNs; all others may not. */ | ||
| 2307 | if (fsg->cmnd[0] != INQUIRY && | ||
| 2308 | fsg->cmnd[0] != REQUEST_SENSE) { | ||
| 2309 | DBG(fsg, "unsupported LUN %d\n", fsg->lun); | ||
| 2310 | return -EINVAL; | ||
| 2311 | } | ||
| 2312 | } | ||
| 2313 | |||
| 2314 | /* If a unit attention condition exists, only INQUIRY and | ||
| 2315 | * REQUEST SENSE commands are allowed; anything else must fail. */ | ||
| 2316 | if (curlun && curlun->unit_attention_data != SS_NO_SENSE && | ||
| 2317 | fsg->cmnd[0] != INQUIRY && | ||
| 2318 | fsg->cmnd[0] != REQUEST_SENSE) { | ||
| 2319 | curlun->sense_data = curlun->unit_attention_data; | ||
| 2320 | curlun->unit_attention_data = SS_NO_SENSE; | ||
| 2321 | return -EINVAL; | ||
| 2322 | } | ||
| 2323 | |||
| 2324 | /* Check that only command bytes listed in the mask are non-zero */ | ||
| 2325 | fsg->cmnd[1] &= 0x1f; // Mask away the LUN | ||
| 2326 | for (i = 1; i < cmnd_size; ++i) { | ||
| 2327 | if (fsg->cmnd[i] && !(mask & (1 << i))) { | ||
| 2328 | if (curlun) | ||
| 2329 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
| 2330 | return -EINVAL; | ||
| 2331 | } | ||
| 2332 | } | ||
| 2333 | |||
| 2334 | /* If the medium isn't mounted and the command needs to access | ||
| 2335 | * it, return an error. */ | ||
| 2336 | if (curlun && !fsg_lun_is_open(curlun) && needs_medium) { | ||
| 2337 | curlun->sense_data = SS_MEDIUM_NOT_PRESENT; | ||
| 2338 | return -EINVAL; | ||
| 2339 | } | ||
| 2340 | |||
| 2341 | return 0; | ||
| 2342 | } | ||
| 2343 | |||
| 2344 | |||
| 2345 | static int do_scsi_command(struct fsg_dev *fsg) | ||
| 2346 | { | ||
| 2347 | struct fsg_buffhd *bh; | ||
| 2348 | int rc; | ||
| 2349 | int reply = -EINVAL; | ||
| 2350 | int i; | ||
| 2351 | static char unknown[16]; | ||
| 2352 | |||
| 2353 | dump_cdb(fsg); | ||
| 2354 | |||
| 2355 | /* Wait for the next buffer to become available for data or status */ | ||
| 2356 | bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill; | ||
| 2357 | while (bh->state != BUF_STATE_EMPTY) { | ||
| 2358 | rc = sleep_thread(fsg); | ||
| 2359 | if (rc) | ||
| 2360 | return rc; | ||
| 2361 | } | ||
| 2362 | fsg->phase_error = 0; | ||
| 2363 | fsg->short_packet_received = 0; | ||
| 2364 | |||
| 2365 | down_read(&fsg->filesem); // We're using the backing file | ||
| 2366 | switch (fsg->cmnd[0]) { | ||
| 2367 | |||
| 2368 | case INQUIRY: | ||
| 2369 | fsg->data_size_from_cmnd = fsg->cmnd[4]; | ||
| 2370 | if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, | ||
| 2371 | (1<<4), 0, | ||
| 2372 | "INQUIRY")) == 0) | ||
| 2373 | reply = do_inquiry(fsg, bh); | ||
| 2374 | break; | ||
| 2375 | |||
| 2376 | case MODE_SELECT: | ||
| 2377 | fsg->data_size_from_cmnd = fsg->cmnd[4]; | ||
| 2378 | if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, | ||
| 2379 | (1<<1) | (1<<4), 0, | ||
| 2380 | "MODE SELECT(6)")) == 0) | ||
| 2381 | reply = do_mode_select(fsg, bh); | ||
| 2382 | break; | ||
| 2383 | |||
| 2384 | case MODE_SELECT_10: | ||
| 2385 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); | ||
| 2386 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, | ||
| 2387 | (1<<1) | (3<<7), 0, | ||
| 2388 | "MODE SELECT(10)")) == 0) | ||
| 2389 | reply = do_mode_select(fsg, bh); | ||
| 2390 | break; | ||
| 2391 | |||
| 2392 | case MODE_SENSE: | ||
| 2393 | fsg->data_size_from_cmnd = fsg->cmnd[4]; | ||
| 2394 | if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, | ||
| 2395 | (1<<1) | (1<<2) | (1<<4), 0, | ||
| 2396 | "MODE SENSE(6)")) == 0) | ||
| 2397 | reply = do_mode_sense(fsg, bh); | ||
| 2398 | break; | ||
| 2399 | |||
| 2400 | case MODE_SENSE_10: | ||
| 2401 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); | ||
| 2402 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | ||
| 2403 | (1<<1) | (1<<2) | (3<<7), 0, | ||
| 2404 | "MODE SENSE(10)")) == 0) | ||
| 2405 | reply = do_mode_sense(fsg, bh); | ||
| 2406 | break; | ||
| 2407 | |||
| 2408 | case ALLOW_MEDIUM_REMOVAL: | ||
| 2409 | fsg->data_size_from_cmnd = 0; | ||
| 2410 | if ((reply = check_command(fsg, 6, DATA_DIR_NONE, | ||
| 2411 | (1<<4), 0, | ||
| 2412 | "PREVENT-ALLOW MEDIUM REMOVAL")) == 0) | ||
| 2413 | reply = do_prevent_allow(fsg); | ||
| 2414 | break; | ||
| 2415 | |||
| 2416 | case READ_6: | ||
| 2417 | i = fsg->cmnd[4]; | ||
| 2418 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; | ||
| 2419 | if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, | ||
| 2420 | (7<<1) | (1<<4), 1, | ||
| 2421 | "READ(6)")) == 0) | ||
| 2422 | reply = do_read(fsg); | ||
| 2423 | break; | ||
| 2424 | |||
| 2425 | case READ_10: | ||
| 2426 | fsg->data_size_from_cmnd = | ||
| 2427 | get_unaligned_be16(&fsg->cmnd[7]) << 9; | ||
| 2428 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | ||
| 2429 | (1<<1) | (0xf<<2) | (3<<7), 1, | ||
| 2430 | "READ(10)")) == 0) | ||
| 2431 | reply = do_read(fsg); | ||
| 2432 | break; | ||
| 2433 | |||
| 2434 | case READ_12: | ||
| 2435 | fsg->data_size_from_cmnd = | ||
| 2436 | get_unaligned_be32(&fsg->cmnd[6]) << 9; | ||
| 2437 | if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, | ||
| 2438 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | ||
| 2439 | "READ(12)")) == 0) | ||
| 2440 | reply = do_read(fsg); | ||
| 2441 | break; | ||
| 2442 | |||
| 2443 | case READ_CAPACITY: | ||
| 2444 | fsg->data_size_from_cmnd = 8; | ||
| 2445 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | ||
| 2446 | (0xf<<2) | (1<<8), 1, | ||
| 2447 | "READ CAPACITY")) == 0) | ||
| 2448 | reply = do_read_capacity(fsg, bh); | ||
| 2449 | break; | ||
| 2450 | |||
| 2451 | case READ_HEADER: | ||
| 2452 | if (!mod_data.cdrom) | ||
| 2453 | goto unknown_cmnd; | ||
| 2454 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); | ||
| 2455 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | ||
| 2456 | (3<<7) | (0x1f<<1), 1, | ||
| 2457 | "READ HEADER")) == 0) | ||
| 2458 | reply = do_read_header(fsg, bh); | ||
| 2459 | break; | ||
| 2460 | |||
| 2461 | case READ_TOC: | ||
| 2462 | if (!mod_data.cdrom) | ||
| 2463 | goto unknown_cmnd; | ||
| 2464 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); | ||
| 2465 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | ||
| 2466 | (7<<6) | (1<<1), 1, | ||
| 2467 | "READ TOC")) == 0) | ||
| 2468 | reply = do_read_toc(fsg, bh); | ||
| 2469 | break; | ||
| 2470 | |||
| 2471 | case READ_FORMAT_CAPACITIES: | ||
| 2472 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); | ||
| 2473 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | ||
| 2474 | (3<<7), 1, | ||
| 2475 | "READ FORMAT CAPACITIES")) == 0) | ||
| 2476 | reply = do_read_format_capacities(fsg, bh); | ||
| 2477 | break; | ||
| 2478 | |||
| 2479 | case REQUEST_SENSE: | ||
| 2480 | fsg->data_size_from_cmnd = fsg->cmnd[4]; | ||
| 2481 | if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, | ||
| 2482 | (1<<4), 0, | ||
| 2483 | "REQUEST SENSE")) == 0) | ||
| 2484 | reply = do_request_sense(fsg, bh); | ||
| 2485 | break; | ||
| 2486 | |||
| 2487 | case START_STOP: | ||
| 2488 | fsg->data_size_from_cmnd = 0; | ||
| 2489 | if ((reply = check_command(fsg, 6, DATA_DIR_NONE, | ||
| 2490 | (1<<1) | (1<<4), 0, | ||
| 2491 | "START-STOP UNIT")) == 0) | ||
| 2492 | reply = do_start_stop(fsg); | ||
| 2493 | break; | ||
| 2494 | |||
| 2495 | case SYNCHRONIZE_CACHE: | ||
| 2496 | fsg->data_size_from_cmnd = 0; | ||
| 2497 | if ((reply = check_command(fsg, 10, DATA_DIR_NONE, | ||
| 2498 | (0xf<<2) | (3<<7), 1, | ||
| 2499 | "SYNCHRONIZE CACHE")) == 0) | ||
| 2500 | reply = do_synchronize_cache(fsg); | ||
| 2501 | break; | ||
| 2502 | |||
| 2503 | case TEST_UNIT_READY: | ||
| 2504 | fsg->data_size_from_cmnd = 0; | ||
| 2505 | reply = check_command(fsg, 6, DATA_DIR_NONE, | ||
| 2506 | 0, 1, | ||
| 2507 | "TEST UNIT READY"); | ||
| 2508 | break; | ||
| 2509 | |||
| 2510 | /* Although optional, this command is used by MS-Windows. We | ||
| 2511 | * support a minimal version: BytChk must be 0. */ | ||
| 2512 | case VERIFY: | ||
| 2513 | fsg->data_size_from_cmnd = 0; | ||
| 2514 | if ((reply = check_command(fsg, 10, DATA_DIR_NONE, | ||
| 2515 | (1<<1) | (0xf<<2) | (3<<7), 1, | ||
| 2516 | "VERIFY")) == 0) | ||
| 2517 | reply = do_verify(fsg); | ||
| 2518 | break; | ||
| 2519 | |||
| 2520 | case WRITE_6: | ||
| 2521 | i = fsg->cmnd[4]; | ||
| 2522 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; | ||
| 2523 | if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, | ||
| 2524 | (7<<1) | (1<<4), 1, | ||
| 2525 | "WRITE(6)")) == 0) | ||
| 2526 | reply = do_write(fsg); | ||
| 2527 | break; | ||
| 2528 | |||
| 2529 | case WRITE_10: | ||
| 2530 | fsg->data_size_from_cmnd = | ||
| 2531 | get_unaligned_be16(&fsg->cmnd[7]) << 9; | ||
| 2532 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, | ||
| 2533 | (1<<1) | (0xf<<2) | (3<<7), 1, | ||
| 2534 | "WRITE(10)")) == 0) | ||
| 2535 | reply = do_write(fsg); | ||
| 2536 | break; | ||
| 2537 | |||
| 2538 | case WRITE_12: | ||
| 2539 | fsg->data_size_from_cmnd = | ||
| 2540 | get_unaligned_be32(&fsg->cmnd[6]) << 9; | ||
| 2541 | if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, | ||
| 2542 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | ||
| 2543 | "WRITE(12)")) == 0) | ||
| 2544 | reply = do_write(fsg); | ||
| 2545 | break; | ||
| 2546 | |||
| 2547 | /* Some mandatory commands that we recognize but don't implement. | ||
| 2548 | * They don't mean much in this setting. It's left as an exercise | ||
| 2549 | * for anyone interested to implement RESERVE and RELEASE in terms | ||
| 2550 | * of Posix locks. */ | ||
| 2551 | case FORMAT_UNIT: | ||
| 2552 | case RELEASE: | ||
| 2553 | case RESERVE: | ||
| 2554 | case SEND_DIAGNOSTIC: | ||
| 2555 | // Fall through | ||
| 2556 | |||
| 2557 | default: | ||
| 2558 | unknown_cmnd: | ||
| 2559 | fsg->data_size_from_cmnd = 0; | ||
| 2560 | sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]); | ||
| 2561 | if ((reply = check_command(fsg, fsg->cmnd_size, | ||
| 2562 | DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) { | ||
| 2563 | fsg->curlun->sense_data = SS_INVALID_COMMAND; | ||
| 2564 | reply = -EINVAL; | ||
| 2565 | } | ||
| 2566 | break; | ||
| 2567 | } | ||
| 2568 | up_read(&fsg->filesem); | ||
| 2569 | |||
| 2570 | if (reply == -EINTR || signal_pending(current)) | ||
| 2571 | return -EINTR; | ||
| 2572 | |||
| 2573 | /* Set up the single reply buffer for finish_reply() */ | ||
| 2574 | if (reply == -EINVAL) | ||
| 2575 | reply = 0; // Error reply length | ||
| 2576 | if (reply >= 0 && fsg->data_dir == DATA_DIR_TO_HOST) { | ||
| 2577 | reply = min((u32) reply, fsg->data_size_from_cmnd); | ||
| 2578 | bh->inreq->length = reply; | ||
| 2579 | bh->state = BUF_STATE_FULL; | ||
| 2580 | fsg->residue -= reply; | ||
| 2581 | } // Otherwise it's already set | ||
| 2582 | |||
| 2583 | return 0; | ||
| 2584 | } | ||
| 2585 | |||
| 2586 | |||
| 2587 | /*-------------------------------------------------------------------------*/ | ||
| 2588 | |||
| 2589 | static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
| 2590 | { | ||
| 2591 | struct usb_request *req = bh->outreq; | ||
| 2592 | struct fsg_bulk_cb_wrap *cbw = req->buf; | ||
| 2593 | |||
| 2594 | /* Was this a real packet? Should it be ignored? */ | ||
| 2595 | if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) | ||
| 2596 | return -EINVAL; | ||
| 2597 | |||
| 2598 | /* Is the CBW valid? */ | ||
| 2599 | if (req->actual != USB_BULK_CB_WRAP_LEN || | ||
| 2600 | cbw->Signature != cpu_to_le32( | ||
| 2601 | USB_BULK_CB_SIG)) { | ||
| 2602 | DBG(fsg, "invalid CBW: len %u sig 0x%x\n", | ||
| 2603 | req->actual, | ||
| 2604 | le32_to_cpu(cbw->Signature)); | ||
| 2605 | |||
| 2606 | /* The Bulk-only spec says we MUST stall the IN endpoint | ||
| 2607 | * (6.6.1), so it's unavoidable. It also says we must | ||
| 2608 | * retain this state until the next reset, but there's | ||
| 2609 | * no way to tell the controller driver it should ignore | ||
| 2610 | * Clear-Feature(HALT) requests. | ||
| 2611 | * | ||
| 2612 | * We aren't required to halt the OUT endpoint; instead | ||
| 2613 | * we can simply accept and discard any data received | ||
| 2614 | * until the next reset. */ | ||
| 2615 | wedge_bulk_in_endpoint(fsg); | ||
| 2616 | set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); | ||
| 2617 | return -EINVAL; | ||
| 2618 | } | ||
| 2619 | |||
| 2620 | /* Is the CBW meaningful? */ | ||
| 2621 | if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG || | ||
| 2622 | cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) { | ||
| 2623 | DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " | ||
| 2624 | "cmdlen %u\n", | ||
| 2625 | cbw->Lun, cbw->Flags, cbw->Length); | ||
| 2626 | |||
| 2627 | /* We can do anything we want here, so let's stall the | ||
| 2628 | * bulk pipes if we are allowed to. */ | ||
| 2629 | if (mod_data.can_stall) { | ||
| 2630 | fsg_set_halt(fsg, fsg->bulk_out); | ||
| 2631 | halt_bulk_in_endpoint(fsg); | ||
| 2632 | } | ||
| 2633 | return -EINVAL; | ||
| 2634 | } | ||
| 2635 | |||
| 2636 | /* Save the command for later */ | ||
| 2637 | fsg->cmnd_size = cbw->Length; | ||
| 2638 | memcpy(fsg->cmnd, cbw->CDB, fsg->cmnd_size); | ||
| 2639 | if (cbw->Flags & USB_BULK_IN_FLAG) | ||
| 2640 | fsg->data_dir = DATA_DIR_TO_HOST; | ||
| 2641 | else | ||
| 2642 | fsg->data_dir = DATA_DIR_FROM_HOST; | ||
| 2643 | fsg->data_size = le32_to_cpu(cbw->DataTransferLength); | ||
| 2644 | if (fsg->data_size == 0) | ||
| 2645 | fsg->data_dir = DATA_DIR_NONE; | ||
| 2646 | fsg->lun = cbw->Lun; | ||
| 2647 | fsg->tag = cbw->Tag; | ||
| 2648 | return 0; | ||
| 2649 | } | ||
| 2650 | |||
| 2651 | |||
| 2652 | static int get_next_command(struct fsg_dev *fsg) | ||
| 2653 | { | ||
| 2654 | struct fsg_buffhd *bh; | ||
| 2655 | int rc = 0; | ||
| 2656 | |||
| 2657 | if (transport_is_bbb()) { | ||
| 2658 | |||
| 2659 | /* Wait for the next buffer to become available */ | ||
| 2660 | bh = fsg->next_buffhd_to_fill; | ||
| 2661 | while (bh->state != BUF_STATE_EMPTY) { | ||
| 2662 | rc = sleep_thread(fsg); | ||
| 2663 | if (rc) | ||
| 2664 | return rc; | ||
| 2665 | } | ||
| 2666 | |||
| 2667 | /* Queue a request to read a Bulk-only CBW */ | ||
| 2668 | set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); | ||
| 2669 | bh->outreq->short_not_ok = 1; | ||
| 2670 | start_transfer(fsg, fsg->bulk_out, bh->outreq, | ||
| 2671 | &bh->outreq_busy, &bh->state); | ||
| 2672 | |||
| 2673 | /* We will drain the buffer in software, which means we | ||
| 2674 | * can reuse it for the next filling. No need to advance | ||
| 2675 | * next_buffhd_to_fill. */ | ||
| 2676 | |||
| 2677 | /* Wait for the CBW to arrive */ | ||
| 2678 | while (bh->state != BUF_STATE_FULL) { | ||
| 2679 | rc = sleep_thread(fsg); | ||
| 2680 | if (rc) | ||
| 2681 | return rc; | ||
| 2682 | } | ||
| 2683 | smp_rmb(); | ||
| 2684 | rc = received_cbw(fsg, bh); | ||
| 2685 | bh->state = BUF_STATE_EMPTY; | ||
| 2686 | |||
| 2687 | } else { // USB_PR_CB or USB_PR_CBI | ||
| 2688 | |||
| 2689 | /* Wait for the next command to arrive */ | ||
| 2690 | while (fsg->cbbuf_cmnd_size == 0) { | ||
| 2691 | rc = sleep_thread(fsg); | ||
| 2692 | if (rc) | ||
| 2693 | return rc; | ||
| 2694 | } | ||
| 2695 | |||
| 2696 | /* Is the previous status interrupt request still busy? | ||
| 2697 | * The host is allowed to skip reading the status, | ||
| 2698 | * so we must cancel it. */ | ||
| 2699 | if (fsg->intreq_busy) | ||
| 2700 | usb_ep_dequeue(fsg->intr_in, fsg->intreq); | ||
| 2701 | |||
| 2702 | /* Copy the command and mark the buffer empty */ | ||
| 2703 | fsg->data_dir = DATA_DIR_UNKNOWN; | ||
| 2704 | spin_lock_irq(&fsg->lock); | ||
| 2705 | fsg->cmnd_size = fsg->cbbuf_cmnd_size; | ||
| 2706 | memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size); | ||
| 2707 | fsg->cbbuf_cmnd_size = 0; | ||
| 2708 | spin_unlock_irq(&fsg->lock); | ||
| 2709 | } | ||
| 2710 | return rc; | ||
| 2711 | } | ||
| 2712 | |||
| 2713 | |||
| 2714 | /*-------------------------------------------------------------------------*/ | ||
| 2715 | |||
| 2716 | static int enable_endpoint(struct fsg_dev *fsg, struct usb_ep *ep, | ||
| 2717 | const struct usb_endpoint_descriptor *d) | ||
| 2718 | { | ||
| 2719 | int rc; | ||
| 2720 | |||
| 2721 | ep->driver_data = fsg; | ||
| 2722 | ep->desc = d; | ||
| 2723 | rc = usb_ep_enable(ep); | ||
| 2724 | if (rc) | ||
| 2725 | ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc); | ||
| 2726 | return rc; | ||
| 2727 | } | ||
| 2728 | |||
| 2729 | static int alloc_request(struct fsg_dev *fsg, struct usb_ep *ep, | ||
| 2730 | struct usb_request **preq) | ||
| 2731 | { | ||
| 2732 | *preq = usb_ep_alloc_request(ep, GFP_ATOMIC); | ||
| 2733 | if (*preq) | ||
| 2734 | return 0; | ||
| 2735 | ERROR(fsg, "can't allocate request for %s\n", ep->name); | ||
| 2736 | return -ENOMEM; | ||
| 2737 | } | ||
| 2738 | |||
| 2739 | /* | ||
| 2740 | * Reset interface setting and re-init endpoint state (toggle etc). | ||
| 2741 | * Call with altsetting < 0 to disable the interface. The only other | ||
| 2742 | * available altsetting is 0, which enables the interface. | ||
| 2743 | */ | ||
| 2744 | static int do_set_interface(struct fsg_dev *fsg, int altsetting) | ||
| 2745 | { | ||
| 2746 | int rc = 0; | ||
| 2747 | int i; | ||
| 2748 | const struct usb_endpoint_descriptor *d; | ||
| 2749 | |||
| 2750 | if (fsg->running) | ||
| 2751 | DBG(fsg, "reset interface\n"); | ||
| 2752 | |||
| 2753 | reset: | ||
| 2754 | /* Deallocate the requests */ | ||
| 2755 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | ||
| 2756 | struct fsg_buffhd *bh = &fsg->buffhds[i]; | ||
| 2757 | |||
| 2758 | if (bh->inreq) { | ||
| 2759 | usb_ep_free_request(fsg->bulk_in, bh->inreq); | ||
| 2760 | bh->inreq = NULL; | ||
| 2761 | } | ||
| 2762 | if (bh->outreq) { | ||
| 2763 | usb_ep_free_request(fsg->bulk_out, bh->outreq); | ||
| 2764 | bh->outreq = NULL; | ||
| 2765 | } | ||
| 2766 | } | ||
| 2767 | if (fsg->intreq) { | ||
| 2768 | usb_ep_free_request(fsg->intr_in, fsg->intreq); | ||
| 2769 | fsg->intreq = NULL; | ||
| 2770 | } | ||
| 2771 | |||
| 2772 | /* Disable the endpoints */ | ||
| 2773 | if (fsg->bulk_in_enabled) { | ||
| 2774 | usb_ep_disable(fsg->bulk_in); | ||
| 2775 | fsg->bulk_in_enabled = 0; | ||
| 2776 | } | ||
| 2777 | if (fsg->bulk_out_enabled) { | ||
| 2778 | usb_ep_disable(fsg->bulk_out); | ||
| 2779 | fsg->bulk_out_enabled = 0; | ||
| 2780 | } | ||
| 2781 | if (fsg->intr_in_enabled) { | ||
| 2782 | usb_ep_disable(fsg->intr_in); | ||
| 2783 | fsg->intr_in_enabled = 0; | ||
| 2784 | } | ||
| 2785 | |||
| 2786 | fsg->running = 0; | ||
| 2787 | if (altsetting < 0 || rc != 0) | ||
| 2788 | return rc; | ||
| 2789 | |||
| 2790 | DBG(fsg, "set interface %d\n", altsetting); | ||
| 2791 | |||
| 2792 | /* Enable the endpoints */ | ||
| 2793 | d = fsg_ep_desc(fsg->gadget, | ||
| 2794 | &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc); | ||
| 2795 | if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0) | ||
| 2796 | goto reset; | ||
| 2797 | fsg->bulk_in_enabled = 1; | ||
| 2798 | |||
| 2799 | d = fsg_ep_desc(fsg->gadget, | ||
| 2800 | &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc); | ||
| 2801 | if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) | ||
| 2802 | goto reset; | ||
| 2803 | fsg->bulk_out_enabled = 1; | ||
| 2804 | fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize); | ||
| 2805 | clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); | ||
| 2806 | |||
| 2807 | if (transport_is_cbi()) { | ||
| 2808 | d = fsg_ep_desc(fsg->gadget, | ||
| 2809 | &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc); | ||
| 2810 | if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0) | ||
| 2811 | goto reset; | ||
| 2812 | fsg->intr_in_enabled = 1; | ||
| 2813 | } | ||
| 2814 | |||
| 2815 | /* Allocate the requests */ | ||
| 2816 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | ||
| 2817 | struct fsg_buffhd *bh = &fsg->buffhds[i]; | ||
| 2818 | |||
| 2819 | if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0) | ||
| 2820 | goto reset; | ||
| 2821 | if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) | ||
| 2822 | goto reset; | ||
| 2823 | bh->inreq->buf = bh->outreq->buf = bh->buf; | ||
| 2824 | bh->inreq->context = bh->outreq->context = bh; | ||
| 2825 | bh->inreq->complete = bulk_in_complete; | ||
| 2826 | bh->outreq->complete = bulk_out_complete; | ||
| 2827 | } | ||
| 2828 | if (transport_is_cbi()) { | ||
| 2829 | if ((rc = alloc_request(fsg, fsg->intr_in, &fsg->intreq)) != 0) | ||
| 2830 | goto reset; | ||
| 2831 | fsg->intreq->complete = intr_in_complete; | ||
| 2832 | } | ||
| 2833 | |||
| 2834 | fsg->running = 1; | ||
| 2835 | for (i = 0; i < fsg->nluns; ++i) | ||
| 2836 | fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED; | ||
| 2837 | return rc; | ||
| 2838 | } | ||
| 2839 | |||
| 2840 | |||
| 2841 | /* | ||
| 2842 | * Change our operational configuration. This code must agree with the code | ||
| 2843 | * that returns config descriptors, and with interface altsetting code. | ||
| 2844 | * | ||
| 2845 | * It's also responsible for power management interactions. Some | ||
| 2846 | * configurations might not work with our current power sources. | ||
| 2847 | * For now we just assume the gadget is always self-powered. | ||
| 2848 | */ | ||
| 2849 | static int do_set_config(struct fsg_dev *fsg, u8 new_config) | ||
| 2850 | { | ||
| 2851 | int rc = 0; | ||
| 2852 | |||
| 2853 | /* Disable the single interface */ | ||
| 2854 | if (fsg->config != 0) { | ||
| 2855 | DBG(fsg, "reset config\n"); | ||
| 2856 | fsg->config = 0; | ||
| 2857 | rc = do_set_interface(fsg, -1); | ||
| 2858 | } | ||
| 2859 | |||
| 2860 | /* Enable the interface */ | ||
| 2861 | if (new_config != 0) { | ||
| 2862 | fsg->config = new_config; | ||
| 2863 | if ((rc = do_set_interface(fsg, 0)) != 0) | ||
| 2864 | fsg->config = 0; // Reset on errors | ||
| 2865 | else { | ||
| 2866 | char *speed; | ||
| 2867 | |||
| 2868 | switch (fsg->gadget->speed) { | ||
| 2869 | case USB_SPEED_LOW: speed = "low"; break; | ||
| 2870 | case USB_SPEED_FULL: speed = "full"; break; | ||
| 2871 | case USB_SPEED_HIGH: speed = "high"; break; | ||
| 2872 | default: speed = "?"; break; | ||
| 2873 | } | ||
| 2874 | INFO(fsg, "%s speed config #%d\n", speed, fsg->config); | ||
| 2875 | } | ||
| 2876 | } | ||
| 2877 | return rc; | ||
| 2878 | } | ||
| 2879 | |||
| 2880 | |||
| 2881 | /*-------------------------------------------------------------------------*/ | ||
| 2882 | |||
| 2883 | static void handle_exception(struct fsg_dev *fsg) | ||
| 2884 | { | ||
| 2885 | siginfo_t info; | ||
| 2886 | int sig; | ||
| 2887 | int i; | ||
| 2888 | int num_active; | ||
| 2889 | struct fsg_buffhd *bh; | ||
| 2890 | enum fsg_state old_state; | ||
| 2891 | u8 new_config; | ||
| 2892 | struct fsg_lun *curlun; | ||
| 2893 | unsigned int exception_req_tag; | ||
| 2894 | int rc; | ||
| 2895 | |||
| 2896 | /* Clear the existing signals. Anything but SIGUSR1 is converted | ||
| 2897 | * into a high-priority EXIT exception. */ | ||
| 2898 | for (;;) { | ||
| 2899 | sig = dequeue_signal_lock(current, ¤t->blocked, &info); | ||
| 2900 | if (!sig) | ||
| 2901 | break; | ||
| 2902 | if (sig != SIGUSR1) { | ||
| 2903 | if (fsg->state < FSG_STATE_EXIT) | ||
| 2904 | DBG(fsg, "Main thread exiting on signal\n"); | ||
| 2905 | raise_exception(fsg, FSG_STATE_EXIT); | ||
| 2906 | } | ||
| 2907 | } | ||
| 2908 | |||
| 2909 | /* Cancel all the pending transfers */ | ||
| 2910 | if (fsg->intreq_busy) | ||
| 2911 | usb_ep_dequeue(fsg->intr_in, fsg->intreq); | ||
| 2912 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | ||
| 2913 | bh = &fsg->buffhds[i]; | ||
| 2914 | if (bh->inreq_busy) | ||
| 2915 | usb_ep_dequeue(fsg->bulk_in, bh->inreq); | ||
| 2916 | if (bh->outreq_busy) | ||
| 2917 | usb_ep_dequeue(fsg->bulk_out, bh->outreq); | ||
| 2918 | } | ||
| 2919 | |||
| 2920 | /* Wait until everything is idle */ | ||
| 2921 | for (;;) { | ||
| 2922 | num_active = fsg->intreq_busy; | ||
| 2923 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | ||
| 2924 | bh = &fsg->buffhds[i]; | ||
| 2925 | num_active += bh->inreq_busy + bh->outreq_busy; | ||
| 2926 | } | ||
| 2927 | if (num_active == 0) | ||
| 2928 | break; | ||
| 2929 | if (sleep_thread(fsg)) | ||
| 2930 | return; | ||
| 2931 | } | ||
| 2932 | |||
| 2933 | /* Clear out the controller's fifos */ | ||
| 2934 | if (fsg->bulk_in_enabled) | ||
| 2935 | usb_ep_fifo_flush(fsg->bulk_in); | ||
| 2936 | if (fsg->bulk_out_enabled) | ||
| 2937 | usb_ep_fifo_flush(fsg->bulk_out); | ||
| 2938 | if (fsg->intr_in_enabled) | ||
| 2939 | usb_ep_fifo_flush(fsg->intr_in); | ||
| 2940 | |||
| 2941 | /* Reset the I/O buffer states and pointers, the SCSI | ||
| 2942 | * state, and the exception. Then invoke the handler. */ | ||
| 2943 | spin_lock_irq(&fsg->lock); | ||
| 2944 | |||
| 2945 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | ||
| 2946 | bh = &fsg->buffhds[i]; | ||
| 2947 | bh->state = BUF_STATE_EMPTY; | ||
| 2948 | } | ||
| 2949 | fsg->next_buffhd_to_fill = fsg->next_buffhd_to_drain = | ||
| 2950 | &fsg->buffhds[0]; | ||
| 2951 | |||
| 2952 | exception_req_tag = fsg->exception_req_tag; | ||
| 2953 | new_config = fsg->new_config; | ||
| 2954 | old_state = fsg->state; | ||
| 2955 | |||
| 2956 | if (old_state == FSG_STATE_ABORT_BULK_OUT) | ||
| 2957 | fsg->state = FSG_STATE_STATUS_PHASE; | ||
| 2958 | else { | ||
| 2959 | for (i = 0; i < fsg->nluns; ++i) { | ||
| 2960 | curlun = &fsg->luns[i]; | ||
| 2961 | curlun->prevent_medium_removal = 0; | ||
| 2962 | curlun->sense_data = curlun->unit_attention_data = | ||
| 2963 | SS_NO_SENSE; | ||
| 2964 | curlun->sense_data_info = 0; | ||
| 2965 | curlun->info_valid = 0; | ||
| 2966 | } | ||
| 2967 | fsg->state = FSG_STATE_IDLE; | ||
| 2968 | } | ||
| 2969 | spin_unlock_irq(&fsg->lock); | ||
| 2970 | |||
| 2971 | /* Carry out any extra actions required for the exception */ | ||
| 2972 | switch (old_state) { | ||
| 2973 | default: | ||
| 2974 | break; | ||
| 2975 | |||
| 2976 | case FSG_STATE_ABORT_BULK_OUT: | ||
| 2977 | send_status(fsg); | ||
| 2978 | spin_lock_irq(&fsg->lock); | ||
| 2979 | if (fsg->state == FSG_STATE_STATUS_PHASE) | ||
| 2980 | fsg->state = FSG_STATE_IDLE; | ||
| 2981 | spin_unlock_irq(&fsg->lock); | ||
| 2982 | break; | ||
| 2983 | |||
| 2984 | case FSG_STATE_RESET: | ||
| 2985 | /* In case we were forced against our will to halt a | ||
| 2986 | * bulk endpoint, clear the halt now. (The SuperH UDC | ||
| 2987 | * requires this.) */ | ||
| 2988 | if (test_and_clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) | ||
| 2989 | usb_ep_clear_halt(fsg->bulk_in); | ||
| 2990 | |||
| 2991 | if (transport_is_bbb()) { | ||
| 2992 | if (fsg->ep0_req_tag == exception_req_tag) | ||
| 2993 | ep0_queue(fsg); // Complete the status stage | ||
| 2994 | |||
| 2995 | } else if (transport_is_cbi()) | ||
| 2996 | send_status(fsg); // Status by interrupt pipe | ||
| 2997 | |||
| 2998 | /* Technically this should go here, but it would only be | ||
| 2999 | * a waste of time. Ditto for the INTERFACE_CHANGE and | ||
| 3000 | * CONFIG_CHANGE cases. */ | ||
| 3001 | // for (i = 0; i < fsg->nluns; ++i) | ||
| 3002 | // fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED; | ||
| 3003 | break; | ||
| 3004 | |||
| 3005 | case FSG_STATE_INTERFACE_CHANGE: | ||
| 3006 | rc = do_set_interface(fsg, 0); | ||
| 3007 | if (fsg->ep0_req_tag != exception_req_tag) | ||
| 3008 | break; | ||
| 3009 | if (rc != 0) // STALL on errors | ||
| 3010 | fsg_set_halt(fsg, fsg->ep0); | ||
| 3011 | else // Complete the status stage | ||
| 3012 | ep0_queue(fsg); | ||
| 3013 | break; | ||
| 3014 | |||
| 3015 | case FSG_STATE_CONFIG_CHANGE: | ||
| 3016 | rc = do_set_config(fsg, new_config); | ||
| 3017 | if (fsg->ep0_req_tag != exception_req_tag) | ||
| 3018 | break; | ||
| 3019 | if (rc != 0) // STALL on errors | ||
| 3020 | fsg_set_halt(fsg, fsg->ep0); | ||
| 3021 | else // Complete the status stage | ||
| 3022 | ep0_queue(fsg); | ||
| 3023 | break; | ||
| 3024 | |||
| 3025 | case FSG_STATE_DISCONNECT: | ||
| 3026 | for (i = 0; i < fsg->nluns; ++i) | ||
| 3027 | fsg_lun_fsync_sub(fsg->luns + i); | ||
| 3028 | do_set_config(fsg, 0); // Unconfigured state | ||
| 3029 | break; | ||
| 3030 | |||
| 3031 | case FSG_STATE_EXIT: | ||
| 3032 | case FSG_STATE_TERMINATED: | ||
| 3033 | do_set_config(fsg, 0); // Free resources | ||
| 3034 | spin_lock_irq(&fsg->lock); | ||
| 3035 | fsg->state = FSG_STATE_TERMINATED; // Stop the thread | ||
| 3036 | spin_unlock_irq(&fsg->lock); | ||
| 3037 | break; | ||
| 3038 | } | ||
| 3039 | } | ||
| 3040 | |||
| 3041 | |||
| 3042 | /*-------------------------------------------------------------------------*/ | ||
| 3043 | |||
| 3044 | static int fsg_main_thread(void *fsg_) | ||
| 3045 | { | ||
| 3046 | struct fsg_dev *fsg = fsg_; | ||
| 3047 | |||
| 3048 | /* Allow the thread to be killed by a signal, but set the signal mask | ||
| 3049 | * to block everything but INT, TERM, KILL, and USR1. */ | ||
| 3050 | allow_signal(SIGINT); | ||
| 3051 | allow_signal(SIGTERM); | ||
| 3052 | allow_signal(SIGKILL); | ||
| 3053 | allow_signal(SIGUSR1); | ||
| 3054 | |||
| 3055 | /* Allow the thread to be frozen */ | ||
| 3056 | set_freezable(); | ||
| 3057 | |||
| 3058 | /* Arrange for userspace references to be interpreted as kernel | ||
| 3059 | * pointers. That way we can pass a kernel pointer to a routine | ||
| 3060 | * that expects a __user pointer and it will work okay. */ | ||
| 3061 | set_fs(get_ds()); | ||
| 3062 | |||
| 3063 | /* The main loop */ | ||
| 3064 | while (fsg->state != FSG_STATE_TERMINATED) { | ||
| 3065 | if (exception_in_progress(fsg) || signal_pending(current)) { | ||
| 3066 | handle_exception(fsg); | ||
| 3067 | continue; | ||
| 3068 | } | ||
| 3069 | |||
| 3070 | if (!fsg->running) { | ||
| 3071 | sleep_thread(fsg); | ||
| 3072 | continue; | ||
| 3073 | } | ||
| 3074 | |||
| 3075 | if (get_next_command(fsg)) | ||
| 3076 | continue; | ||
| 3077 | |||
| 3078 | spin_lock_irq(&fsg->lock); | ||
| 3079 | if (!exception_in_progress(fsg)) | ||
| 3080 | fsg->state = FSG_STATE_DATA_PHASE; | ||
| 3081 | spin_unlock_irq(&fsg->lock); | ||
| 3082 | |||
| 3083 | if (do_scsi_command(fsg) || finish_reply(fsg)) | ||
| 3084 | continue; | ||
| 3085 | |||
| 3086 | spin_lock_irq(&fsg->lock); | ||
| 3087 | if (!exception_in_progress(fsg)) | ||
| 3088 | fsg->state = FSG_STATE_STATUS_PHASE; | ||
| 3089 | spin_unlock_irq(&fsg->lock); | ||
| 3090 | |||
| 3091 | if (send_status(fsg)) | ||
| 3092 | continue; | ||
| 3093 | |||
| 3094 | spin_lock_irq(&fsg->lock); | ||
| 3095 | if (!exception_in_progress(fsg)) | ||
| 3096 | fsg->state = FSG_STATE_IDLE; | ||
| 3097 | spin_unlock_irq(&fsg->lock); | ||
| 3098 | } | ||
| 3099 | |||
| 3100 | spin_lock_irq(&fsg->lock); | ||
| 3101 | fsg->thread_task = NULL; | ||
| 3102 | spin_unlock_irq(&fsg->lock); | ||
| 3103 | |||
| 3104 | /* If we are exiting because of a signal, unregister the | ||
| 3105 | * gadget driver. */ | ||
| 3106 | if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) | ||
| 3107 | usb_gadget_unregister_driver(&fsg_driver); | ||
| 3108 | |||
| 3109 | /* Let the unbind and cleanup routines know the thread has exited */ | ||
| 3110 | complete_and_exit(&fsg->thread_notifier, 0); | ||
| 3111 | } | ||
| 3112 | |||
| 3113 | |||
| 3114 | /*-------------------------------------------------------------------------*/ | ||
| 3115 | |||
| 3116 | |||
| 3117 | /* The write permissions and store_xxx pointers are set in fsg_bind() */ | ||
| 3118 | static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL); | ||
| 3119 | static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, NULL); | ||
| 3120 | static DEVICE_ATTR(file, 0444, fsg_show_file, NULL); | ||
| 3121 | |||
| 3122 | |||
| 3123 | /*-------------------------------------------------------------------------*/ | ||
| 3124 | |||
| 3125 | static void fsg_release(struct kref *ref) | ||
| 3126 | { | ||
| 3127 | struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref); | ||
| 3128 | |||
| 3129 | kfree(fsg->luns); | ||
| 3130 | kfree(fsg); | ||
| 3131 | } | ||
| 3132 | |||
| 3133 | static void lun_release(struct device *dev) | ||
| 3134 | { | ||
| 3135 | struct rw_semaphore *filesem = dev_get_drvdata(dev); | ||
| 3136 | struct fsg_dev *fsg = | ||
| 3137 | container_of(filesem, struct fsg_dev, filesem); | ||
| 3138 | |||
| 3139 | kref_put(&fsg->ref, fsg_release); | ||
| 3140 | } | ||
| 3141 | |||
| 3142 | static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) | ||
| 3143 | { | ||
| 3144 | struct fsg_dev *fsg = get_gadget_data(gadget); | ||
| 3145 | int i; | ||
| 3146 | struct fsg_lun *curlun; | ||
| 3147 | struct usb_request *req = fsg->ep0req; | ||
| 3148 | |||
| 3149 | DBG(fsg, "unbind\n"); | ||
| 3150 | clear_bit(REGISTERED, &fsg->atomic_bitflags); | ||
| 3151 | |||
| 3152 | /* Unregister the sysfs attribute files and the LUNs */ | ||
| 3153 | for (i = 0; i < fsg->nluns; ++i) { | ||
| 3154 | curlun = &fsg->luns[i]; | ||
| 3155 | if (curlun->registered) { | ||
| 3156 | device_remove_file(&curlun->dev, &dev_attr_nofua); | ||
| 3157 | device_remove_file(&curlun->dev, &dev_attr_ro); | ||
| 3158 | device_remove_file(&curlun->dev, &dev_attr_file); | ||
| 3159 | fsg_lun_close(curlun); | ||
| 3160 | device_unregister(&curlun->dev); | ||
| 3161 | curlun->registered = 0; | ||
| 3162 | } | ||
| 3163 | } | ||
| 3164 | |||
| 3165 | /* If the thread isn't already dead, tell it to exit now */ | ||
| 3166 | if (fsg->state != FSG_STATE_TERMINATED) { | ||
| 3167 | raise_exception(fsg, FSG_STATE_EXIT); | ||
| 3168 | wait_for_completion(&fsg->thread_notifier); | ||
| 3169 | |||
| 3170 | /* The cleanup routine waits for this completion also */ | ||
| 3171 | complete(&fsg->thread_notifier); | ||
| 3172 | } | ||
| 3173 | |||
| 3174 | /* Free the data buffers */ | ||
| 3175 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) | ||
| 3176 | kfree(fsg->buffhds[i].buf); | ||
| 3177 | |||
| 3178 | /* Free the request and buffer for endpoint 0 */ | ||
| 3179 | if (req) { | ||
| 3180 | kfree(req->buf); | ||
| 3181 | usb_ep_free_request(fsg->ep0, req); | ||
| 3182 | } | ||
| 3183 | |||
| 3184 | set_gadget_data(gadget, NULL); | ||
| 3185 | } | ||
| 3186 | |||
| 3187 | |||
| 3188 | static int __init check_parameters(struct fsg_dev *fsg) | ||
| 3189 | { | ||
| 3190 | int prot; | ||
| 3191 | int gcnum; | ||
| 3192 | |||
| 3193 | /* Store the default values */ | ||
| 3194 | mod_data.transport_type = USB_PR_BULK; | ||
| 3195 | mod_data.transport_name = "Bulk-only"; | ||
| 3196 | mod_data.protocol_type = USB_SC_SCSI; | ||
| 3197 | mod_data.protocol_name = "Transparent SCSI"; | ||
| 3198 | |||
| 3199 | /* Some peripheral controllers are known not to be able to | ||
| 3200 | * halt bulk endpoints correctly. If one of them is present, | ||
| 3201 | * disable stalls. | ||
| 3202 | */ | ||
| 3203 | if (gadget_is_at91(fsg->gadget)) | ||
| 3204 | mod_data.can_stall = 0; | ||
| 3205 | |||
| 3206 | if (mod_data.release == 0xffff) { // Parameter wasn't set | ||
| 3207 | gcnum = usb_gadget_controller_number(fsg->gadget); | ||
| 3208 | if (gcnum >= 0) | ||
| 3209 | mod_data.release = 0x0300 + gcnum; | ||
| 3210 | else { | ||
| 3211 | WARNING(fsg, "controller '%s' not recognized\n", | ||
| 3212 | fsg->gadget->name); | ||
| 3213 | mod_data.release = 0x0399; | ||
| 3214 | } | ||
| 3215 | } | ||
| 3216 | |||
| 3217 | prot = simple_strtol(mod_data.protocol_parm, NULL, 0); | ||
| 3218 | |||
| 3219 | #ifdef CONFIG_USB_FILE_STORAGE_TEST | ||
| 3220 | if (strnicmp(mod_data.transport_parm, "BBB", 10) == 0) { | ||
| 3221 | ; // Use default setting | ||
| 3222 | } else if (strnicmp(mod_data.transport_parm, "CB", 10) == 0) { | ||
| 3223 | mod_data.transport_type = USB_PR_CB; | ||
| 3224 | mod_data.transport_name = "Control-Bulk"; | ||
| 3225 | } else if (strnicmp(mod_data.transport_parm, "CBI", 10) == 0) { | ||
| 3226 | mod_data.transport_type = USB_PR_CBI; | ||
| 3227 | mod_data.transport_name = "Control-Bulk-Interrupt"; | ||
| 3228 | } else { | ||
| 3229 | ERROR(fsg, "invalid transport: %s\n", mod_data.transport_parm); | ||
| 3230 | return -EINVAL; | ||
| 3231 | } | ||
| 3232 | |||
| 3233 | if (strnicmp(mod_data.protocol_parm, "SCSI", 10) == 0 || | ||
| 3234 | prot == USB_SC_SCSI) { | ||
| 3235 | ; // Use default setting | ||
| 3236 | } else if (strnicmp(mod_data.protocol_parm, "RBC", 10) == 0 || | ||
| 3237 | prot == USB_SC_RBC) { | ||
| 3238 | mod_data.protocol_type = USB_SC_RBC; | ||
| 3239 | mod_data.protocol_name = "RBC"; | ||
| 3240 | } else if (strnicmp(mod_data.protocol_parm, "8020", 4) == 0 || | ||
| 3241 | strnicmp(mod_data.protocol_parm, "ATAPI", 10) == 0 || | ||
| 3242 | prot == USB_SC_8020) { | ||
| 3243 | mod_data.protocol_type = USB_SC_8020; | ||
| 3244 | mod_data.protocol_name = "8020i (ATAPI)"; | ||
| 3245 | } else if (strnicmp(mod_data.protocol_parm, "QIC", 3) == 0 || | ||
| 3246 | prot == USB_SC_QIC) { | ||
| 3247 | mod_data.protocol_type = USB_SC_QIC; | ||
| 3248 | mod_data.protocol_name = "QIC-157"; | ||
| 3249 | } else if (strnicmp(mod_data.protocol_parm, "UFI", 10) == 0 || | ||
| 3250 | prot == USB_SC_UFI) { | ||
| 3251 | mod_data.protocol_type = USB_SC_UFI; | ||
| 3252 | mod_data.protocol_name = "UFI"; | ||
| 3253 | } else if (strnicmp(mod_data.protocol_parm, "8070", 4) == 0 || | ||
| 3254 | prot == USB_SC_8070) { | ||
| 3255 | mod_data.protocol_type = USB_SC_8070; | ||
| 3256 | mod_data.protocol_name = "8070i"; | ||
| 3257 | } else { | ||
| 3258 | ERROR(fsg, "invalid protocol: %s\n", mod_data.protocol_parm); | ||
| 3259 | return -EINVAL; | ||
| 3260 | } | ||
| 3261 | |||
| 3262 | mod_data.buflen &= PAGE_CACHE_MASK; | ||
| 3263 | if (mod_data.buflen <= 0) { | ||
| 3264 | ERROR(fsg, "invalid buflen\n"); | ||
| 3265 | return -ETOOSMALL; | ||
| 3266 | } | ||
| 3267 | |||
| 3268 | #endif /* CONFIG_USB_FILE_STORAGE_TEST */ | ||
| 3269 | |||
| 3270 | /* Serial string handling. | ||
| 3271 | * On a real device, the serial string would be loaded | ||
| 3272 | * from permanent storage. */ | ||
| 3273 | if (mod_data.serial) { | ||
| 3274 | const char *ch; | ||
| 3275 | unsigned len = 0; | ||
| 3276 | |||
| 3277 | /* Sanity check : | ||
| 3278 | * The CB[I] specification limits the serial string to | ||
| 3279 | * 12 uppercase hexadecimal characters. | ||
| 3280 | * BBB need at least 12 uppercase hexadecimal characters, | ||
| 3281 | * with a maximum of 126. */ | ||
| 3282 | for (ch = mod_data.serial; *ch; ++ch) { | ||
| 3283 | ++len; | ||
| 3284 | if ((*ch < '0' || *ch > '9') && | ||
| 3285 | (*ch < 'A' || *ch > 'F')) { /* not uppercase hex */ | ||
| 3286 | WARNING(fsg, | ||
| 3287 | "Invalid serial string character: %c\n", | ||
| 3288 | *ch); | ||
| 3289 | goto no_serial; | ||
| 3290 | } | ||
| 3291 | } | ||
| 3292 | if (len > 126 || | ||
| 3293 | (mod_data.transport_type == USB_PR_BULK && len < 12) || | ||
| 3294 | (mod_data.transport_type != USB_PR_BULK && len > 12)) { | ||
| 3295 | WARNING(fsg, "Invalid serial string length!\n"); | ||
| 3296 | goto no_serial; | ||
| 3297 | } | ||
| 3298 | fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial; | ||
| 3299 | } else { | ||
| 3300 | WARNING(fsg, "No serial-number string provided!\n"); | ||
| 3301 | no_serial: | ||
| 3302 | device_desc.iSerialNumber = 0; | ||
| 3303 | } | ||
| 3304 | |||
| 3305 | return 0; | ||
| 3306 | } | ||
| 3307 | |||
| 3308 | |||
| 3309 | static int __init fsg_bind(struct usb_gadget *gadget) | ||
| 3310 | { | ||
| 3311 | struct fsg_dev *fsg = the_fsg; | ||
| 3312 | int rc; | ||
| 3313 | int i; | ||
| 3314 | struct fsg_lun *curlun; | ||
| 3315 | struct usb_ep *ep; | ||
| 3316 | struct usb_request *req; | ||
| 3317 | char *pathbuf, *p; | ||
| 3318 | |||
| 3319 | fsg->gadget = gadget; | ||
| 3320 | set_gadget_data(gadget, fsg); | ||
| 3321 | fsg->ep0 = gadget->ep0; | ||
| 3322 | fsg->ep0->driver_data = fsg; | ||
| 3323 | |||
| 3324 | if ((rc = check_parameters(fsg)) != 0) | ||
| 3325 | goto out; | ||
| 3326 | |||
| 3327 | if (mod_data.removable) { // Enable the store_xxx attributes | ||
| 3328 | dev_attr_file.attr.mode = 0644; | ||
| 3329 | dev_attr_file.store = fsg_store_file; | ||
| 3330 | if (!mod_data.cdrom) { | ||
| 3331 | dev_attr_ro.attr.mode = 0644; | ||
| 3332 | dev_attr_ro.store = fsg_store_ro; | ||
| 3333 | } | ||
| 3334 | } | ||
| 3335 | |||
| 3336 | /* Only for removable media? */ | ||
| 3337 | dev_attr_nofua.attr.mode = 0644; | ||
| 3338 | dev_attr_nofua.store = fsg_store_nofua; | ||
| 3339 | |||
| 3340 | /* Find out how many LUNs there should be */ | ||
| 3341 | i = mod_data.nluns; | ||
| 3342 | if (i == 0) | ||
| 3343 | i = max(mod_data.num_filenames, 1u); | ||
| 3344 | if (i > FSG_MAX_LUNS) { | ||
| 3345 | ERROR(fsg, "invalid number of LUNs: %d\n", i); | ||
| 3346 | rc = -EINVAL; | ||
| 3347 | goto out; | ||
| 3348 | } | ||
| 3349 | |||
| 3350 | /* Create the LUNs, open their backing files, and register the | ||
| 3351 | * LUN devices in sysfs. */ | ||
| 3352 | fsg->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL); | ||
| 3353 | if (!fsg->luns) { | ||
| 3354 | rc = -ENOMEM; | ||
| 3355 | goto out; | ||
| 3356 | } | ||
| 3357 | fsg->nluns = i; | ||
| 3358 | |||
| 3359 | for (i = 0; i < fsg->nluns; ++i) { | ||
| 3360 | curlun = &fsg->luns[i]; | ||
| 3361 | curlun->cdrom = !!mod_data.cdrom; | ||
| 3362 | curlun->ro = mod_data.cdrom || mod_data.ro[i]; | ||
| 3363 | curlun->initially_ro = curlun->ro; | ||
| 3364 | curlun->removable = mod_data.removable; | ||
| 3365 | curlun->nofua = mod_data.nofua[i]; | ||
| 3366 | curlun->dev.release = lun_release; | ||
| 3367 | curlun->dev.parent = &gadget->dev; | ||
| 3368 | curlun->dev.driver = &fsg_driver.driver; | ||
| 3369 | dev_set_drvdata(&curlun->dev, &fsg->filesem); | ||
| 3370 | dev_set_name(&curlun->dev,"%s-lun%d", | ||
| 3371 | dev_name(&gadget->dev), i); | ||
| 3372 | |||
| 3373 | kref_get(&fsg->ref); | ||
| 3374 | rc = device_register(&curlun->dev); | ||
| 3375 | if (rc) { | ||
| 3376 | INFO(fsg, "failed to register LUN%d: %d\n", i, rc); | ||
| 3377 | put_device(&curlun->dev); | ||
| 3378 | goto out; | ||
| 3379 | } | ||
| 3380 | curlun->registered = 1; | ||
| 3381 | |||
| 3382 | rc = device_create_file(&curlun->dev, &dev_attr_ro); | ||
| 3383 | if (rc) | ||
| 3384 | goto out; | ||
| 3385 | rc = device_create_file(&curlun->dev, &dev_attr_nofua); | ||
| 3386 | if (rc) | ||
| 3387 | goto out; | ||
| 3388 | rc = device_create_file(&curlun->dev, &dev_attr_file); | ||
| 3389 | if (rc) | ||
| 3390 | goto out; | ||
| 3391 | |||
| 3392 | if (mod_data.file[i] && *mod_data.file[i]) { | ||
| 3393 | rc = fsg_lun_open(curlun, mod_data.file[i]); | ||
| 3394 | if (rc) | ||
| 3395 | goto out; | ||
| 3396 | } else if (!mod_data.removable) { | ||
| 3397 | ERROR(fsg, "no file given for LUN%d\n", i); | ||
| 3398 | rc = -EINVAL; | ||
| 3399 | goto out; | ||
| 3400 | } | ||
| 3401 | } | ||
| 3402 | |||
| 3403 | /* Find all the endpoints we will use */ | ||
| 3404 | usb_ep_autoconfig_reset(gadget); | ||
| 3405 | ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); | ||
| 3406 | if (!ep) | ||
| 3407 | goto autoconf_fail; | ||
| 3408 | ep->driver_data = fsg; // claim the endpoint | ||
| 3409 | fsg->bulk_in = ep; | ||
| 3410 | |||
| 3411 | ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc); | ||
| 3412 | if (!ep) | ||
| 3413 | goto autoconf_fail; | ||
| 3414 | ep->driver_data = fsg; // claim the endpoint | ||
| 3415 | fsg->bulk_out = ep; | ||
| 3416 | |||
| 3417 | if (transport_is_cbi()) { | ||
| 3418 | ep = usb_ep_autoconfig(gadget, &fsg_fs_intr_in_desc); | ||
| 3419 | if (!ep) | ||
| 3420 | goto autoconf_fail; | ||
| 3421 | ep->driver_data = fsg; // claim the endpoint | ||
| 3422 | fsg->intr_in = ep; | ||
| 3423 | } | ||
| 3424 | |||
| 3425 | /* Fix up the descriptors */ | ||
| 3426 | device_desc.idVendor = cpu_to_le16(mod_data.vendor); | ||
| 3427 | device_desc.idProduct = cpu_to_le16(mod_data.product); | ||
| 3428 | device_desc.bcdDevice = cpu_to_le16(mod_data.release); | ||
| 3429 | |||
| 3430 | i = (transport_is_cbi() ? 3 : 2); // Number of endpoints | ||
| 3431 | fsg_intf_desc.bNumEndpoints = i; | ||
| 3432 | fsg_intf_desc.bInterfaceSubClass = mod_data.protocol_type; | ||
| 3433 | fsg_intf_desc.bInterfaceProtocol = mod_data.transport_type; | ||
| 3434 | fsg_fs_function[i + FSG_FS_FUNCTION_PRE_EP_ENTRIES] = NULL; | ||
| 3435 | |||
| 3436 | if (gadget_is_dualspeed(gadget)) { | ||
| 3437 | fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL; | ||
| 3438 | |||
| 3439 | /* Assume endpoint addresses are the same for both speeds */ | ||
| 3440 | fsg_hs_bulk_in_desc.bEndpointAddress = | ||
| 3441 | fsg_fs_bulk_in_desc.bEndpointAddress; | ||
| 3442 | fsg_hs_bulk_out_desc.bEndpointAddress = | ||
| 3443 | fsg_fs_bulk_out_desc.bEndpointAddress; | ||
| 3444 | fsg_hs_intr_in_desc.bEndpointAddress = | ||
| 3445 | fsg_fs_intr_in_desc.bEndpointAddress; | ||
| 3446 | } | ||
| 3447 | |||
| 3448 | if (gadget_is_otg(gadget)) | ||
| 3449 | fsg_otg_desc.bmAttributes |= USB_OTG_HNP; | ||
| 3450 | |||
| 3451 | rc = -ENOMEM; | ||
| 3452 | |||
| 3453 | /* Allocate the request and buffer for endpoint 0 */ | ||
| 3454 | fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL); | ||
| 3455 | if (!req) | ||
| 3456 | goto out; | ||
| 3457 | req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL); | ||
| 3458 | if (!req->buf) | ||
| 3459 | goto out; | ||
| 3460 | req->complete = ep0_complete; | ||
| 3461 | |||
| 3462 | /* Allocate the data buffers */ | ||
| 3463 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | ||
| 3464 | struct fsg_buffhd *bh = &fsg->buffhds[i]; | ||
| 3465 | |||
| 3466 | /* Allocate for the bulk-in endpoint. We assume that | ||
| 3467 | * the buffer will also work with the bulk-out (and | ||
| 3468 | * interrupt-in) endpoint. */ | ||
| 3469 | bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL); | ||
| 3470 | if (!bh->buf) | ||
| 3471 | goto out; | ||
| 3472 | bh->next = bh + 1; | ||
| 3473 | } | ||
| 3474 | fsg->buffhds[FSG_NUM_BUFFERS - 1].next = &fsg->buffhds[0]; | ||
| 3475 | |||
| 3476 | /* This should reflect the actual gadget power source */ | ||
| 3477 | usb_gadget_set_selfpowered(gadget); | ||
| 3478 | |||
| 3479 | snprintf(fsg_string_manufacturer, sizeof fsg_string_manufacturer, | ||
| 3480 | "%s %s with %s", | ||
| 3481 | init_utsname()->sysname, init_utsname()->release, | ||
| 3482 | gadget->name); | ||
| 3483 | |||
| 3484 | fsg->thread_task = kthread_create(fsg_main_thread, fsg, | ||
| 3485 | "file-storage-gadget"); | ||
| 3486 | if (IS_ERR(fsg->thread_task)) { | ||
| 3487 | rc = PTR_ERR(fsg->thread_task); | ||
| 3488 | goto out; | ||
| 3489 | } | ||
| 3490 | |||
| 3491 | INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); | ||
| 3492 | INFO(fsg, "NOTE: This driver is deprecated. " | ||
| 3493 | "Consider using g_mass_storage instead.\n"); | ||
| 3494 | INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); | ||
| 3495 | |||
| 3496 | pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); | ||
| 3497 | for (i = 0; i < fsg->nluns; ++i) { | ||
| 3498 | curlun = &fsg->luns[i]; | ||
| 3499 | if (fsg_lun_is_open(curlun)) { | ||
| 3500 | p = NULL; | ||
| 3501 | if (pathbuf) { | ||
| 3502 | p = d_path(&curlun->filp->f_path, | ||
| 3503 | pathbuf, PATH_MAX); | ||
| 3504 | if (IS_ERR(p)) | ||
| 3505 | p = NULL; | ||
| 3506 | } | ||
| 3507 | LINFO(curlun, "ro=%d, nofua=%d, file: %s\n", | ||
| 3508 | curlun->ro, curlun->nofua, (p ? p : "(error)")); | ||
| 3509 | } | ||
| 3510 | } | ||
| 3511 | kfree(pathbuf); | ||
| 3512 | |||
| 3513 | DBG(fsg, "transport=%s (x%02x)\n", | ||
| 3514 | mod_data.transport_name, mod_data.transport_type); | ||
| 3515 | DBG(fsg, "protocol=%s (x%02x)\n", | ||
| 3516 | mod_data.protocol_name, mod_data.protocol_type); | ||
| 3517 | DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n", | ||
| 3518 | mod_data.vendor, mod_data.product, mod_data.release); | ||
| 3519 | DBG(fsg, "removable=%d, stall=%d, cdrom=%d, buflen=%u\n", | ||
| 3520 | mod_data.removable, mod_data.can_stall, | ||
| 3521 | mod_data.cdrom, mod_data.buflen); | ||
| 3522 | DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); | ||
| 3523 | |||
| 3524 | set_bit(REGISTERED, &fsg->atomic_bitflags); | ||
| 3525 | |||
| 3526 | /* Tell the thread to start working */ | ||
| 3527 | wake_up_process(fsg->thread_task); | ||
| 3528 | return 0; | ||
| 3529 | |||
| 3530 | autoconf_fail: | ||
| 3531 | ERROR(fsg, "unable to autoconfigure all endpoints\n"); | ||
| 3532 | rc = -ENOTSUPP; | ||
| 3533 | |||
| 3534 | out: | ||
| 3535 | fsg->state = FSG_STATE_TERMINATED; // The thread is dead | ||
| 3536 | fsg_unbind(gadget); | ||
| 3537 | complete(&fsg->thread_notifier); | ||
| 3538 | return rc; | ||
| 3539 | } | ||
| 3540 | |||
| 3541 | |||
| 3542 | /*-------------------------------------------------------------------------*/ | ||
| 3543 | |||
| 3544 | static void fsg_suspend(struct usb_gadget *gadget) | ||
| 3545 | { | ||
| 3546 | struct fsg_dev *fsg = get_gadget_data(gadget); | ||
| 3547 | |||
| 3548 | DBG(fsg, "suspend\n"); | ||
| 3549 | set_bit(SUSPENDED, &fsg->atomic_bitflags); | ||
| 3550 | } | ||
| 3551 | |||
| 3552 | static void fsg_resume(struct usb_gadget *gadget) | ||
| 3553 | { | ||
| 3554 | struct fsg_dev *fsg = get_gadget_data(gadget); | ||
| 3555 | |||
| 3556 | DBG(fsg, "resume\n"); | ||
| 3557 | clear_bit(SUSPENDED, &fsg->atomic_bitflags); | ||
| 3558 | } | ||
| 3559 | |||
| 3560 | |||
| 3561 | /*-------------------------------------------------------------------------*/ | ||
| 3562 | |||
| 3563 | static struct usb_gadget_driver fsg_driver = { | ||
| 3564 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
| 3565 | .speed = USB_SPEED_HIGH, | ||
| 3566 | #else | ||
| 3567 | .speed = USB_SPEED_FULL, | ||
| 3568 | #endif | ||
| 3569 | .function = (char *) fsg_string_product, | ||
| 3570 | .unbind = fsg_unbind, | ||
| 3571 | .disconnect = fsg_disconnect, | ||
| 3572 | .setup = fsg_setup, | ||
| 3573 | .suspend = fsg_suspend, | ||
| 3574 | .resume = fsg_resume, | ||
| 3575 | |||
| 3576 | .driver = { | ||
| 3577 | .name = DRIVER_NAME, | ||
| 3578 | .owner = THIS_MODULE, | ||
| 3579 | // .release = ... | ||
| 3580 | // .suspend = ... | ||
| 3581 | // .resume = ... | ||
| 3582 | }, | ||
| 3583 | }; | ||
| 3584 | |||
| 3585 | |||
| 3586 | static int __init fsg_alloc(void) | ||
| 3587 | { | ||
| 3588 | struct fsg_dev *fsg; | ||
| 3589 | |||
| 3590 | fsg = kzalloc(sizeof *fsg, GFP_KERNEL); | ||
| 3591 | if (!fsg) | ||
| 3592 | return -ENOMEM; | ||
| 3593 | spin_lock_init(&fsg->lock); | ||
| 3594 | init_rwsem(&fsg->filesem); | ||
| 3595 | kref_init(&fsg->ref); | ||
| 3596 | init_completion(&fsg->thread_notifier); | ||
| 3597 | |||
| 3598 | the_fsg = fsg; | ||
| 3599 | return 0; | ||
| 3600 | } | ||
| 3601 | |||
| 3602 | |||
| 3603 | static int __init fsg_init(void) | ||
| 3604 | { | ||
| 3605 | int rc; | ||
| 3606 | struct fsg_dev *fsg; | ||
| 3607 | |||
| 3608 | if ((rc = fsg_alloc()) != 0) | ||
| 3609 | return rc; | ||
| 3610 | fsg = the_fsg; | ||
| 3611 | if ((rc = usb_gadget_probe_driver(&fsg_driver, fsg_bind)) != 0) | ||
| 3612 | kref_put(&fsg->ref, fsg_release); | ||
| 3613 | return rc; | ||
| 3614 | } | ||
| 3615 | module_init(fsg_init); | ||
| 3616 | |||
| 3617 | |||
| 3618 | static void __exit fsg_cleanup(void) | ||
| 3619 | { | ||
| 3620 | struct fsg_dev *fsg = the_fsg; | ||
| 3621 | |||
| 3622 | /* Unregister the driver iff the thread hasn't already done so */ | ||
| 3623 | if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) | ||
| 3624 | usb_gadget_unregister_driver(&fsg_driver); | ||
| 3625 | |||
| 3626 | /* Wait for the thread to finish up */ | ||
| 3627 | wait_for_completion(&fsg->thread_notifier); | ||
| 3628 | |||
| 3629 | kref_put(&fsg->ref, fsg_release); | ||
| 3630 | } | ||
| 3631 | module_exit(fsg_cleanup); | ||
diff --git a/drivers/usb/gadget/fsl_tegra_udc.c b/drivers/usb/gadget/fsl_tegra_udc.c new file mode 100644 index 00000000000..b254258726f --- /dev/null +++ b/drivers/usb/gadget/fsl_tegra_udc.c | |||
| @@ -0,0 +1,155 @@ | |||
| 1 | /* | ||
| 2 | * Description: | ||
| 3 | * Helper functions to support the tegra USB controller | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License as published by the | ||
| 7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 8 | * option) any later version. | ||
| 9 | */ | ||
| 10 | #include <linux/fsl_devices.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | #include <linux/err.h> | ||
| 13 | #include <linux/io.h> | ||
| 14 | #include <mach/usb_phy.h> | ||
| 15 | |||
| 16 | static struct tegra_usb_phy *phy; | ||
| 17 | static struct clk *udc_clk; | ||
| 18 | static struct clk *emc_clk; | ||
| 19 | static struct clk *sclk_clk; | ||
| 20 | static void *udc_base; | ||
| 21 | |||
| 22 | int fsl_udc_clk_init(struct platform_device *pdev) | ||
| 23 | { | ||
| 24 | struct resource *res; | ||
| 25 | int err; | ||
| 26 | int instance; | ||
| 27 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; | ||
| 28 | |||
| 29 | |||
| 30 | udc_clk = clk_get(&pdev->dev, NULL); | ||
| 31 | if (IS_ERR(udc_clk)) { | ||
| 32 | dev_err(&pdev->dev, "Can't get udc clock\n"); | ||
| 33 | return PTR_ERR(udc_clk); | ||
| 34 | } | ||
| 35 | |||
| 36 | clk_enable(udc_clk); | ||
| 37 | |||
| 38 | sclk_clk = clk_get(&pdev->dev, "sclk"); | ||
| 39 | if (IS_ERR(sclk_clk)) { | ||
| 40 | dev_err(&pdev->dev, "Can't get sclk clock\n"); | ||
| 41 | err = PTR_ERR(sclk_clk); | ||
| 42 | goto err_sclk; | ||
| 43 | } | ||
| 44 | |||
| 45 | clk_set_rate(sclk_clk, 80000000); | ||
| 46 | clk_enable(sclk_clk); | ||
| 47 | |||
| 48 | emc_clk = clk_get(&pdev->dev, "emc"); | ||
| 49 | if (IS_ERR(emc_clk)) { | ||
| 50 | dev_err(&pdev->dev, "Can't get emc clock\n"); | ||
| 51 | err = PTR_ERR(emc_clk); | ||
| 52 | goto err_emc; | ||
| 53 | } | ||
| 54 | |||
| 55 | clk_enable(emc_clk); | ||
| 56 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
| 57 | /* Set DDR busy hints to 150MHz. For Tegra 2x SOC, DDR rate is half of EMC rate */ | ||
| 58 | clk_set_rate(emc_clk, 300000000); | ||
| 59 | #else | ||
| 60 | /* Set DDR busy hints to 100MHz. For Tegra 3x SOC DDR rate equals to EMC rate */ | ||
| 61 | clk_set_rate(emc_clk, 100000000); | ||
| 62 | #endif | ||
| 63 | |||
| 64 | /* we have to remap the registers ourselves as fsl_udc does not | ||
| 65 | * export them for us. | ||
| 66 | */ | ||
| 67 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 68 | if (!res) { | ||
| 69 | err = -ENXIO; | ||
| 70 | goto err0; | ||
| 71 | } | ||
| 72 | udc_base = ioremap(res->start, resource_size(res)); | ||
| 73 | if (!udc_base) { | ||
| 74 | err = -ENOMEM; | ||
| 75 | goto err0; | ||
| 76 | } | ||
| 77 | |||
| 78 | instance = pdev->id; | ||
| 79 | if (instance == -1) | ||
| 80 | instance = 0; | ||
| 81 | |||
| 82 | phy = tegra_usb_phy_open(instance, udc_base, pdata->phy_config, | ||
| 83 | TEGRA_USB_PHY_MODE_DEVICE, pdata->usb_phy_type); | ||
| 84 | if (IS_ERR(phy)) { | ||
| 85 | dev_err(&pdev->dev, "Can't open phy\n"); | ||
| 86 | err = PTR_ERR(phy); | ||
| 87 | goto err1; | ||
| 88 | } | ||
| 89 | tegra_usb_phy_power_on(phy, true); | ||
| 90 | |||
| 91 | return 0; | ||
| 92 | err1: | ||
| 93 | iounmap(udc_base); | ||
| 94 | err0: | ||
| 95 | clk_disable(emc_clk); | ||
| 96 | clk_put(emc_clk); | ||
| 97 | err_emc: | ||
| 98 | clk_disable(sclk_clk); | ||
| 99 | clk_put(sclk_clk); | ||
| 100 | err_sclk: | ||
| 101 | clk_disable(udc_clk); | ||
| 102 | clk_put(udc_clk); | ||
| 103 | return err; | ||
| 104 | } | ||
| 105 | |||
| 106 | void fsl_udc_clk_finalize(struct platform_device *pdev) | ||
| 107 | { | ||
| 108 | } | ||
| 109 | |||
| 110 | void fsl_udc_clk_release(void) | ||
| 111 | { | ||
| 112 | tegra_usb_phy_close(phy); | ||
| 113 | |||
| 114 | iounmap(udc_base); | ||
| 115 | |||
| 116 | clk_disable(udc_clk); | ||
| 117 | clk_put(udc_clk); | ||
| 118 | |||
| 119 | clk_disable(sclk_clk); | ||
| 120 | clk_put(sclk_clk); | ||
| 121 | |||
| 122 | clk_disable(emc_clk); | ||
| 123 | clk_put(emc_clk); | ||
| 124 | } | ||
| 125 | |||
| 126 | void fsl_udc_clk_suspend(bool is_dpd) | ||
| 127 | { | ||
| 128 | tegra_usb_phy_power_off(phy, is_dpd); | ||
| 129 | clk_disable(udc_clk); | ||
| 130 | clk_disable(sclk_clk); | ||
| 131 | clk_disable(emc_clk); | ||
| 132 | } | ||
| 133 | |||
| 134 | void fsl_udc_clk_resume(bool is_dpd) | ||
| 135 | { | ||
| 136 | clk_enable(emc_clk); | ||
| 137 | clk_enable(sclk_clk); | ||
| 138 | clk_enable(udc_clk); | ||
| 139 | tegra_usb_phy_power_on(phy, is_dpd); | ||
| 140 | } | ||
| 141 | |||
| 142 | void fsl_udc_clk_enable(void) | ||
| 143 | { | ||
| 144 | clk_enable(udc_clk); | ||
| 145 | } | ||
| 146 | |||
| 147 | void fsl_udc_clk_disable(void) | ||
| 148 | { | ||
| 149 | clk_disable(udc_clk); | ||
| 150 | } | ||
| 151 | |||
| 152 | bool fsl_udc_charger_detect(void) | ||
| 153 | { | ||
| 154 | return tegra_usb_phy_charger_detect(phy); | ||
| 155 | } | ||
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c new file mode 100644 index 00000000000..a06e2c27b43 --- /dev/null +++ b/drivers/usb/gadget/langwell_udc.c | |||
| @@ -0,0 +1,3607 @@ | |||
| 1 | /* | ||
| 2 | * Intel Langwell USB Device Controller driver | ||
| 3 | * Copyright (C) 2008-2009, Intel Corporation. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along with | ||
| 15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | |||
| 20 | |||
| 21 | /* #undef DEBUG */ | ||
| 22 | /* #undef VERBOSE_DEBUG */ | ||
| 23 | |||
| 24 | #if defined(CONFIG_USB_LANGWELL_OTG) | ||
| 25 | #define OTG_TRANSCEIVER | ||
| 26 | #endif | ||
| 27 | |||
| 28 | |||
| 29 | #include <linux/module.h> | ||
| 30 | #include <linux/pci.h> | ||
| 31 | #include <linux/dma-mapping.h> | ||
| 32 | #include <linux/kernel.h> | ||
| 33 | #include <linux/delay.h> | ||
| 34 | #include <linux/ioport.h> | ||
| 35 | #include <linux/sched.h> | ||
| 36 | #include <linux/slab.h> | ||
| 37 | #include <linux/errno.h> | ||
| 38 | #include <linux/init.h> | ||
| 39 | #include <linux/timer.h> | ||
| 40 | #include <linux/list.h> | ||
| 41 | #include <linux/interrupt.h> | ||
| 42 | #include <linux/moduleparam.h> | ||
| 43 | #include <linux/device.h> | ||
| 44 | #include <linux/usb/ch9.h> | ||
| 45 | #include <linux/usb/gadget.h> | ||
| 46 | #include <linux/usb/otg.h> | ||
| 47 | #include <linux/pm.h> | ||
| 48 | #include <linux/io.h> | ||
| 49 | #include <linux/irq.h> | ||
| 50 | #include <asm/system.h> | ||
| 51 | #include <asm/unaligned.h> | ||
| 52 | |||
| 53 | #include "langwell_udc.h" | ||
| 54 | |||
| 55 | |||
| 56 | #define DRIVER_DESC "Intel Langwell USB Device Controller driver" | ||
| 57 | #define DRIVER_VERSION "16 May 2009" | ||
| 58 | |||
| 59 | static const char driver_name[] = "langwell_udc"; | ||
| 60 | static const char driver_desc[] = DRIVER_DESC; | ||
| 61 | |||
| 62 | |||
| 63 | /* controller device global variable */ | ||
| 64 | static struct langwell_udc *the_controller; | ||
| 65 | |||
| 66 | /* for endpoint 0 operations */ | ||
| 67 | static const struct usb_endpoint_descriptor | ||
| 68 | langwell_ep0_desc = { | ||
| 69 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 70 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 71 | .bEndpointAddress = 0, | ||
| 72 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
| 73 | .wMaxPacketSize = EP0_MAX_PKT_SIZE, | ||
| 74 | }; | ||
| 75 | |||
| 76 | |||
| 77 | /*-------------------------------------------------------------------------*/ | ||
| 78 | /* debugging */ | ||
| 79 | |||
| 80 | #ifdef VERBOSE_DEBUG | ||
| 81 | static inline void print_all_registers(struct langwell_udc *dev) | ||
| 82 | { | ||
| 83 | int i; | ||
| 84 | |||
| 85 | /* Capability Registers */ | ||
| 86 | dev_dbg(&dev->pdev->dev, | ||
| 87 | "Capability Registers (offset: 0x%04x, length: 0x%08x)\n", | ||
| 88 | CAP_REG_OFFSET, (u32)sizeof(struct langwell_cap_regs)); | ||
| 89 | dev_dbg(&dev->pdev->dev, "caplength=0x%02x\n", | ||
| 90 | readb(&dev->cap_regs->caplength)); | ||
| 91 | dev_dbg(&dev->pdev->dev, "hciversion=0x%04x\n", | ||
| 92 | readw(&dev->cap_regs->hciversion)); | ||
| 93 | dev_dbg(&dev->pdev->dev, "hcsparams=0x%08x\n", | ||
| 94 | readl(&dev->cap_regs->hcsparams)); | ||
| 95 | dev_dbg(&dev->pdev->dev, "hccparams=0x%08x\n", | ||
| 96 | readl(&dev->cap_regs->hccparams)); | ||
| 97 | dev_dbg(&dev->pdev->dev, "dciversion=0x%04x\n", | ||
| 98 | readw(&dev->cap_regs->dciversion)); | ||
| 99 | dev_dbg(&dev->pdev->dev, "dccparams=0x%08x\n", | ||
| 100 | readl(&dev->cap_regs->dccparams)); | ||
| 101 | |||
| 102 | /* Operational Registers */ | ||
| 103 | dev_dbg(&dev->pdev->dev, | ||
| 104 | "Operational Registers (offset: 0x%04x, length: 0x%08x)\n", | ||
| 105 | OP_REG_OFFSET, (u32)sizeof(struct langwell_op_regs)); | ||
| 106 | dev_dbg(&dev->pdev->dev, "extsts=0x%08x\n", | ||
| 107 | readl(&dev->op_regs->extsts)); | ||
| 108 | dev_dbg(&dev->pdev->dev, "extintr=0x%08x\n", | ||
| 109 | readl(&dev->op_regs->extintr)); | ||
| 110 | dev_dbg(&dev->pdev->dev, "usbcmd=0x%08x\n", | ||
| 111 | readl(&dev->op_regs->usbcmd)); | ||
| 112 | dev_dbg(&dev->pdev->dev, "usbsts=0x%08x\n", | ||
| 113 | readl(&dev->op_regs->usbsts)); | ||
| 114 | dev_dbg(&dev->pdev->dev, "usbintr=0x%08x\n", | ||
| 115 | readl(&dev->op_regs->usbintr)); | ||
| 116 | dev_dbg(&dev->pdev->dev, "frindex=0x%08x\n", | ||
| 117 | readl(&dev->op_regs->frindex)); | ||
| 118 | dev_dbg(&dev->pdev->dev, "ctrldssegment=0x%08x\n", | ||
| 119 | readl(&dev->op_regs->ctrldssegment)); | ||
| 120 | dev_dbg(&dev->pdev->dev, "deviceaddr=0x%08x\n", | ||
| 121 | readl(&dev->op_regs->deviceaddr)); | ||
| 122 | dev_dbg(&dev->pdev->dev, "endpointlistaddr=0x%08x\n", | ||
| 123 | readl(&dev->op_regs->endpointlistaddr)); | ||
| 124 | dev_dbg(&dev->pdev->dev, "ttctrl=0x%08x\n", | ||
| 125 | readl(&dev->op_regs->ttctrl)); | ||
| 126 | dev_dbg(&dev->pdev->dev, "burstsize=0x%08x\n", | ||
| 127 | readl(&dev->op_regs->burstsize)); | ||
| 128 | dev_dbg(&dev->pdev->dev, "txfilltuning=0x%08x\n", | ||
| 129 | readl(&dev->op_regs->txfilltuning)); | ||
| 130 | dev_dbg(&dev->pdev->dev, "txttfilltuning=0x%08x\n", | ||
| 131 | readl(&dev->op_regs->txttfilltuning)); | ||
| 132 | dev_dbg(&dev->pdev->dev, "ic_usb=0x%08x\n", | ||
| 133 | readl(&dev->op_regs->ic_usb)); | ||
| 134 | dev_dbg(&dev->pdev->dev, "ulpi_viewport=0x%08x\n", | ||
| 135 | readl(&dev->op_regs->ulpi_viewport)); | ||
| 136 | dev_dbg(&dev->pdev->dev, "configflag=0x%08x\n", | ||
| 137 | readl(&dev->op_regs->configflag)); | ||
| 138 | dev_dbg(&dev->pdev->dev, "portsc1=0x%08x\n", | ||
| 139 | readl(&dev->op_regs->portsc1)); | ||
| 140 | dev_dbg(&dev->pdev->dev, "devlc=0x%08x\n", | ||
| 141 | readl(&dev->op_regs->devlc)); | ||
| 142 | dev_dbg(&dev->pdev->dev, "otgsc=0x%08x\n", | ||
| 143 | readl(&dev->op_regs->otgsc)); | ||
| 144 | dev_dbg(&dev->pdev->dev, "usbmode=0x%08x\n", | ||
| 145 | readl(&dev->op_regs->usbmode)); | ||
| 146 | dev_dbg(&dev->pdev->dev, "endptnak=0x%08x\n", | ||
| 147 | readl(&dev->op_regs->endptnak)); | ||
| 148 | dev_dbg(&dev->pdev->dev, "endptnaken=0x%08x\n", | ||
| 149 | readl(&dev->op_regs->endptnaken)); | ||
| 150 | dev_dbg(&dev->pdev->dev, "endptsetupstat=0x%08x\n", | ||
| 151 | readl(&dev->op_regs->endptsetupstat)); | ||
| 152 | dev_dbg(&dev->pdev->dev, "endptprime=0x%08x\n", | ||
| 153 | readl(&dev->op_regs->endptprime)); | ||
| 154 | dev_dbg(&dev->pdev->dev, "endptflush=0x%08x\n", | ||
| 155 | readl(&dev->op_regs->endptflush)); | ||
| 156 | dev_dbg(&dev->pdev->dev, "endptstat=0x%08x\n", | ||
| 157 | readl(&dev->op_regs->endptstat)); | ||
| 158 | dev_dbg(&dev->pdev->dev, "endptcomplete=0x%08x\n", | ||
| 159 | readl(&dev->op_regs->endptcomplete)); | ||
| 160 | |||
| 161 | for (i = 0; i < dev->ep_max / 2; i++) { | ||
| 162 | dev_dbg(&dev->pdev->dev, "endptctrl[%d]=0x%08x\n", | ||
| 163 | i, readl(&dev->op_regs->endptctrl[i])); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | #else | ||
| 167 | |||
| 168 | #define print_all_registers(dev) do { } while (0) | ||
| 169 | |||
| 170 | #endif /* VERBOSE_DEBUG */ | ||
| 171 | |||
| 172 | |||
| 173 | /*-------------------------------------------------------------------------*/ | ||
| 174 | |||
| 175 | #define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \ | ||
| 176 | USB_DIR_IN) : (usb_endpoint_dir_in((ep)->desc))) | ||
| 177 | |||
| 178 | #define DIR_STRING(ep) (is_in(ep) ? "in" : "out") | ||
| 179 | |||
| 180 | |||
| 181 | static char *type_string(const struct usb_endpoint_descriptor *desc) | ||
| 182 | { | ||
| 183 | switch (usb_endpoint_type(desc)) { | ||
| 184 | case USB_ENDPOINT_XFER_BULK: | ||
| 185 | return "bulk"; | ||
| 186 | case USB_ENDPOINT_XFER_ISOC: | ||
| 187 | return "iso"; | ||
| 188 | case USB_ENDPOINT_XFER_INT: | ||
| 189 | return "int"; | ||
| 190 | }; | ||
| 191 | |||
| 192 | return "control"; | ||
| 193 | } | ||
| 194 | |||
| 195 | |||
| 196 | /* configure endpoint control registers */ | ||
| 197 | static void ep_reset(struct langwell_ep *ep, unsigned char ep_num, | ||
| 198 | unsigned char is_in, unsigned char ep_type) | ||
| 199 | { | ||
| 200 | struct langwell_udc *dev; | ||
| 201 | u32 endptctrl; | ||
| 202 | |||
| 203 | dev = ep->dev; | ||
| 204 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 205 | |||
| 206 | endptctrl = readl(&dev->op_regs->endptctrl[ep_num]); | ||
| 207 | if (is_in) { /* TX */ | ||
| 208 | if (ep_num) | ||
| 209 | endptctrl |= EPCTRL_TXR; | ||
| 210 | endptctrl |= EPCTRL_TXE; | ||
| 211 | endptctrl |= ep_type << EPCTRL_TXT_SHIFT; | ||
| 212 | } else { /* RX */ | ||
| 213 | if (ep_num) | ||
| 214 | endptctrl |= EPCTRL_RXR; | ||
| 215 | endptctrl |= EPCTRL_RXE; | ||
| 216 | endptctrl |= ep_type << EPCTRL_RXT_SHIFT; | ||
| 217 | } | ||
| 218 | |||
| 219 | writel(endptctrl, &dev->op_regs->endptctrl[ep_num]); | ||
| 220 | |||
| 221 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 222 | } | ||
| 223 | |||
| 224 | |||
| 225 | /* reset ep0 dQH and endptctrl */ | ||
| 226 | static void ep0_reset(struct langwell_udc *dev) | ||
| 227 | { | ||
| 228 | struct langwell_ep *ep; | ||
| 229 | int i; | ||
| 230 | |||
| 231 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 232 | |||
| 233 | /* ep0 in and out */ | ||
| 234 | for (i = 0; i < 2; i++) { | ||
| 235 | ep = &dev->ep[i]; | ||
| 236 | ep->dev = dev; | ||
| 237 | |||
| 238 | /* ep0 dQH */ | ||
| 239 | ep->dqh = &dev->ep_dqh[i]; | ||
| 240 | |||
| 241 | /* configure ep0 endpoint capabilities in dQH */ | ||
| 242 | ep->dqh->dqh_ios = 1; | ||
| 243 | ep->dqh->dqh_mpl = EP0_MAX_PKT_SIZE; | ||
| 244 | |||
| 245 | /* enable ep0-in HW zero length termination select */ | ||
| 246 | if (is_in(ep)) | ||
| 247 | ep->dqh->dqh_zlt = 0; | ||
| 248 | ep->dqh->dqh_mult = 0; | ||
| 249 | |||
| 250 | ep->dqh->dtd_next = DTD_TERM; | ||
| 251 | |||
| 252 | /* configure ep0 control registers */ | ||
| 253 | ep_reset(&dev->ep[0], 0, i, USB_ENDPOINT_XFER_CONTROL); | ||
| 254 | } | ||
| 255 | |||
| 256 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 257 | } | ||
| 258 | |||
| 259 | |||
| 260 | /*-------------------------------------------------------------------------*/ | ||
| 261 | |||
| 262 | /* endpoints operations */ | ||
| 263 | |||
| 264 | /* configure endpoint, making it usable */ | ||
| 265 | static int langwell_ep_enable(struct usb_ep *_ep, | ||
| 266 | const struct usb_endpoint_descriptor *desc) | ||
| 267 | { | ||
| 268 | struct langwell_udc *dev; | ||
| 269 | struct langwell_ep *ep; | ||
| 270 | u16 max = 0; | ||
| 271 | unsigned long flags; | ||
| 272 | int i, retval = 0; | ||
| 273 | unsigned char zlt, ios = 0, mult = 0; | ||
| 274 | |||
| 275 | ep = container_of(_ep, struct langwell_ep, ep); | ||
| 276 | dev = ep->dev; | ||
| 277 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 278 | |||
| 279 | if (!_ep || !desc || ep->desc | ||
| 280 | || desc->bDescriptorType != USB_DT_ENDPOINT) | ||
| 281 | return -EINVAL; | ||
| 282 | |||
| 283 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 284 | return -ESHUTDOWN; | ||
| 285 | |||
| 286 | max = le16_to_cpu(desc->wMaxPacketSize); | ||
| 287 | |||
| 288 | /* | ||
| 289 | * disable HW zero length termination select | ||
| 290 | * driver handles zero length packet through req->req.zero | ||
| 291 | */ | ||
| 292 | zlt = 1; | ||
| 293 | |||
| 294 | /* | ||
| 295 | * sanity check type, direction, address, and then | ||
| 296 | * initialize the endpoint capabilities fields in dQH | ||
| 297 | */ | ||
| 298 | switch (usb_endpoint_type(desc)) { | ||
| 299 | case USB_ENDPOINT_XFER_CONTROL: | ||
| 300 | ios = 1; | ||
| 301 | break; | ||
| 302 | case USB_ENDPOINT_XFER_BULK: | ||
| 303 | if ((dev->gadget.speed == USB_SPEED_HIGH | ||
| 304 | && max != 512) | ||
| 305 | || (dev->gadget.speed == USB_SPEED_FULL | ||
| 306 | && max > 64)) { | ||
| 307 | goto done; | ||
| 308 | } | ||
| 309 | break; | ||
| 310 | case USB_ENDPOINT_XFER_INT: | ||
| 311 | if (strstr(ep->ep.name, "-iso")) /* bulk is ok */ | ||
| 312 | goto done; | ||
| 313 | |||
| 314 | switch (dev->gadget.speed) { | ||
| 315 | case USB_SPEED_HIGH: | ||
| 316 | if (max <= 1024) | ||
| 317 | break; | ||
| 318 | case USB_SPEED_FULL: | ||
| 319 | if (max <= 64) | ||
| 320 | break; | ||
| 321 | default: | ||
| 322 | if (max <= 8) | ||
| 323 | break; | ||
| 324 | goto done; | ||
| 325 | } | ||
| 326 | break; | ||
| 327 | case USB_ENDPOINT_XFER_ISOC: | ||
| 328 | if (strstr(ep->ep.name, "-bulk") | ||
| 329 | || strstr(ep->ep.name, "-int")) | ||
| 330 | goto done; | ||
| 331 | |||
| 332 | switch (dev->gadget.speed) { | ||
| 333 | case USB_SPEED_HIGH: | ||
| 334 | if (max <= 1024) | ||
| 335 | break; | ||
| 336 | case USB_SPEED_FULL: | ||
| 337 | if (max <= 1023) | ||
| 338 | break; | ||
| 339 | default: | ||
| 340 | goto done; | ||
| 341 | } | ||
| 342 | /* | ||
| 343 | * FIXME: | ||
| 344 | * calculate transactions needed for high bandwidth iso | ||
| 345 | */ | ||
| 346 | mult = (unsigned char)(1 + ((max >> 11) & 0x03)); | ||
| 347 | max = max & 0x8ff; /* bit 0~10 */ | ||
| 348 | /* 3 transactions at most */ | ||
| 349 | if (mult > 3) | ||
| 350 | goto done; | ||
| 351 | break; | ||
| 352 | default: | ||
| 353 | goto done; | ||
| 354 | } | ||
| 355 | |||
| 356 | spin_lock_irqsave(&dev->lock, flags); | ||
| 357 | |||
| 358 | ep->ep.maxpacket = max; | ||
| 359 | ep->desc = desc; | ||
| 360 | ep->stopped = 0; | ||
| 361 | ep->ep_num = usb_endpoint_num(desc); | ||
| 362 | |||
| 363 | /* ep_type */ | ||
| 364 | ep->ep_type = usb_endpoint_type(desc); | ||
| 365 | |||
| 366 | /* configure endpoint control registers */ | ||
| 367 | ep_reset(ep, ep->ep_num, is_in(ep), ep->ep_type); | ||
| 368 | |||
| 369 | /* configure endpoint capabilities in dQH */ | ||
| 370 | i = ep->ep_num * 2 + is_in(ep); | ||
| 371 | ep->dqh = &dev->ep_dqh[i]; | ||
| 372 | ep->dqh->dqh_ios = ios; | ||
| 373 | ep->dqh->dqh_mpl = cpu_to_le16(max); | ||
| 374 | ep->dqh->dqh_zlt = zlt; | ||
| 375 | ep->dqh->dqh_mult = mult; | ||
| 376 | ep->dqh->dtd_next = DTD_TERM; | ||
| 377 | |||
| 378 | dev_dbg(&dev->pdev->dev, "enabled %s (ep%d%s-%s), max %04x\n", | ||
| 379 | _ep->name, | ||
| 380 | ep->ep_num, | ||
| 381 | DIR_STRING(ep), | ||
| 382 | type_string(desc), | ||
| 383 | max); | ||
| 384 | |||
| 385 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 386 | done: | ||
| 387 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 388 | return retval; | ||
| 389 | } | ||
| 390 | |||
| 391 | |||
| 392 | /*-------------------------------------------------------------------------*/ | ||
| 393 | |||
| 394 | /* retire a request */ | ||
| 395 | static void done(struct langwell_ep *ep, struct langwell_request *req, | ||
| 396 | int status) | ||
| 397 | { | ||
| 398 | struct langwell_udc *dev = ep->dev; | ||
| 399 | unsigned stopped = ep->stopped; | ||
| 400 | struct langwell_dtd *curr_dtd, *next_dtd; | ||
| 401 | int i; | ||
| 402 | |||
| 403 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 404 | |||
| 405 | /* remove the req from ep->queue */ | ||
| 406 | list_del_init(&req->queue); | ||
| 407 | |||
| 408 | if (req->req.status == -EINPROGRESS) | ||
| 409 | req->req.status = status; | ||
| 410 | else | ||
| 411 | status = req->req.status; | ||
| 412 | |||
| 413 | /* free dTD for the request */ | ||
| 414 | next_dtd = req->head; | ||
| 415 | for (i = 0; i < req->dtd_count; i++) { | ||
| 416 | curr_dtd = next_dtd; | ||
| 417 | if (i != req->dtd_count - 1) | ||
| 418 | next_dtd = curr_dtd->next_dtd_virt; | ||
| 419 | dma_pool_free(dev->dtd_pool, curr_dtd, curr_dtd->dtd_dma); | ||
| 420 | } | ||
| 421 | |||
| 422 | if (req->mapped) { | ||
| 423 | dma_unmap_single(&dev->pdev->dev, | ||
| 424 | req->req.dma, req->req.length, | ||
| 425 | is_in(ep) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
| 426 | req->req.dma = DMA_ADDR_INVALID; | ||
| 427 | req->mapped = 0; | ||
| 428 | } else | ||
| 429 | dma_sync_single_for_cpu(&dev->pdev->dev, req->req.dma, | ||
| 430 | req->req.length, | ||
| 431 | is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 432 | |||
| 433 | if (status != -ESHUTDOWN) | ||
| 434 | dev_dbg(&dev->pdev->dev, | ||
| 435 | "complete %s, req %p, stat %d, len %u/%u\n", | ||
| 436 | ep->ep.name, &req->req, status, | ||
| 437 | req->req.actual, req->req.length); | ||
| 438 | |||
| 439 | /* don't modify queue heads during completion callback */ | ||
| 440 | ep->stopped = 1; | ||
| 441 | |||
| 442 | spin_unlock(&dev->lock); | ||
| 443 | /* complete routine from gadget driver */ | ||
| 444 | if (req->req.complete) | ||
| 445 | req->req.complete(&ep->ep, &req->req); | ||
| 446 | |||
| 447 | spin_lock(&dev->lock); | ||
| 448 | ep->stopped = stopped; | ||
| 449 | |||
| 450 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 451 | } | ||
| 452 | |||
| 453 | |||
| 454 | static void langwell_ep_fifo_flush(struct usb_ep *_ep); | ||
| 455 | |||
| 456 | /* delete all endpoint requests, called with spinlock held */ | ||
| 457 | static void nuke(struct langwell_ep *ep, int status) | ||
| 458 | { | ||
| 459 | /* called with spinlock held */ | ||
| 460 | ep->stopped = 1; | ||
| 461 | |||
| 462 | /* endpoint fifo flush */ | ||
| 463 | if (&ep->ep && ep->desc) | ||
| 464 | langwell_ep_fifo_flush(&ep->ep); | ||
| 465 | |||
| 466 | while (!list_empty(&ep->queue)) { | ||
| 467 | struct langwell_request *req = NULL; | ||
| 468 | req = list_entry(ep->queue.next, struct langwell_request, | ||
| 469 | queue); | ||
| 470 | done(ep, req, status); | ||
| 471 | } | ||
| 472 | } | ||
| 473 | |||
| 474 | |||
| 475 | /*-------------------------------------------------------------------------*/ | ||
| 476 | |||
| 477 | /* endpoint is no longer usable */ | ||
| 478 | static int langwell_ep_disable(struct usb_ep *_ep) | ||
| 479 | { | ||
| 480 | struct langwell_ep *ep; | ||
| 481 | unsigned long flags; | ||
| 482 | struct langwell_udc *dev; | ||
| 483 | int ep_num; | ||
| 484 | u32 endptctrl; | ||
| 485 | |||
| 486 | ep = container_of(_ep, struct langwell_ep, ep); | ||
| 487 | dev = ep->dev; | ||
| 488 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 489 | |||
| 490 | if (!_ep || !ep->desc) | ||
| 491 | return -EINVAL; | ||
| 492 | |||
| 493 | spin_lock_irqsave(&dev->lock, flags); | ||
| 494 | |||
| 495 | /* disable endpoint control register */ | ||
| 496 | ep_num = ep->ep_num; | ||
| 497 | endptctrl = readl(&dev->op_regs->endptctrl[ep_num]); | ||
| 498 | if (is_in(ep)) | ||
| 499 | endptctrl &= ~EPCTRL_TXE; | ||
| 500 | else | ||
| 501 | endptctrl &= ~EPCTRL_RXE; | ||
| 502 | writel(endptctrl, &dev->op_regs->endptctrl[ep_num]); | ||
| 503 | |||
| 504 | /* nuke all pending requests (does flush) */ | ||
| 505 | nuke(ep, -ESHUTDOWN); | ||
| 506 | |||
| 507 | ep->desc = NULL; | ||
| 508 | ep->stopped = 1; | ||
| 509 | |||
| 510 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 511 | |||
| 512 | dev_dbg(&dev->pdev->dev, "disabled %s\n", _ep->name); | ||
| 513 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 514 | |||
| 515 | return 0; | ||
| 516 | } | ||
| 517 | |||
| 518 | |||
| 519 | /* allocate a request object to use with this endpoint */ | ||
| 520 | static struct usb_request *langwell_alloc_request(struct usb_ep *_ep, | ||
| 521 | gfp_t gfp_flags) | ||
| 522 | { | ||
| 523 | struct langwell_ep *ep; | ||
| 524 | struct langwell_udc *dev; | ||
| 525 | struct langwell_request *req = NULL; | ||
| 526 | |||
| 527 | if (!_ep) | ||
| 528 | return NULL; | ||
| 529 | |||
| 530 | ep = container_of(_ep, struct langwell_ep, ep); | ||
| 531 | dev = ep->dev; | ||
| 532 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 533 | |||
| 534 | req = kzalloc(sizeof(*req), gfp_flags); | ||
| 535 | if (!req) | ||
| 536 | return NULL; | ||
| 537 | |||
| 538 | req->req.dma = DMA_ADDR_INVALID; | ||
| 539 | INIT_LIST_HEAD(&req->queue); | ||
| 540 | |||
| 541 | dev_vdbg(&dev->pdev->dev, "alloc request for %s\n", _ep->name); | ||
| 542 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 543 | return &req->req; | ||
| 544 | } | ||
| 545 | |||
| 546 | |||
| 547 | /* free a request object */ | ||
| 548 | static void langwell_free_request(struct usb_ep *_ep, | ||
| 549 | struct usb_request *_req) | ||
| 550 | { | ||
| 551 | struct langwell_ep *ep; | ||
| 552 | struct langwell_udc *dev; | ||
| 553 | struct langwell_request *req = NULL; | ||
| 554 | |||
| 555 | ep = container_of(_ep, struct langwell_ep, ep); | ||
| 556 | dev = ep->dev; | ||
| 557 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 558 | |||
| 559 | if (!_ep || !_req) | ||
| 560 | return; | ||
| 561 | |||
| 562 | req = container_of(_req, struct langwell_request, req); | ||
| 563 | WARN_ON(!list_empty(&req->queue)); | ||
| 564 | |||
| 565 | if (_req) | ||
| 566 | kfree(req); | ||
| 567 | |||
| 568 | dev_vdbg(&dev->pdev->dev, "free request for %s\n", _ep->name); | ||
| 569 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 570 | } | ||
| 571 | |||
| 572 | |||
| 573 | /*-------------------------------------------------------------------------*/ | ||
| 574 | |||
| 575 | /* queue dTD and PRIME endpoint */ | ||
| 576 | static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req) | ||
| 577 | { | ||
| 578 | u32 bit_mask, usbcmd, endptstat, dtd_dma; | ||
| 579 | u8 dtd_status; | ||
| 580 | int i; | ||
| 581 | struct langwell_dqh *dqh; | ||
| 582 | struct langwell_udc *dev; | ||
| 583 | |||
| 584 | dev = ep->dev; | ||
| 585 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 586 | |||
| 587 | i = ep->ep_num * 2 + is_in(ep); | ||
| 588 | dqh = &dev->ep_dqh[i]; | ||
| 589 | |||
| 590 | if (ep->ep_num) | ||
| 591 | dev_vdbg(&dev->pdev->dev, "%s\n", ep->name); | ||
| 592 | else | ||
| 593 | /* ep0 */ | ||
| 594 | dev_vdbg(&dev->pdev->dev, "%s-%s\n", ep->name, DIR_STRING(ep)); | ||
| 595 | |||
| 596 | dev_vdbg(&dev->pdev->dev, "ep_dqh[%d] addr: 0x%p\n", | ||
| 597 | i, &(dev->ep_dqh[i])); | ||
| 598 | |||
| 599 | bit_mask = is_in(ep) ? | ||
| 600 | (1 << (ep->ep_num + 16)) : (1 << (ep->ep_num)); | ||
| 601 | |||
| 602 | dev_vdbg(&dev->pdev->dev, "bit_mask = 0x%08x\n", bit_mask); | ||
| 603 | |||
| 604 | /* check if the pipe is empty */ | ||
| 605 | if (!(list_empty(&ep->queue))) { | ||
| 606 | /* add dTD to the end of linked list */ | ||
| 607 | struct langwell_request *lastreq; | ||
| 608 | lastreq = list_entry(ep->queue.prev, | ||
| 609 | struct langwell_request, queue); | ||
| 610 | |||
| 611 | lastreq->tail->dtd_next = | ||
| 612 | cpu_to_le32(req->head->dtd_dma & DTD_NEXT_MASK); | ||
| 613 | |||
| 614 | /* read prime bit, if 1 goto out */ | ||
| 615 | if (readl(&dev->op_regs->endptprime) & bit_mask) | ||
| 616 | goto out; | ||
| 617 | |||
| 618 | do { | ||
| 619 | /* set ATDTW bit in USBCMD */ | ||
| 620 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 621 | writel(usbcmd | CMD_ATDTW, &dev->op_regs->usbcmd); | ||
| 622 | |||
| 623 | /* read correct status bit */ | ||
| 624 | endptstat = readl(&dev->op_regs->endptstat) & bit_mask; | ||
| 625 | |||
| 626 | } while (!(readl(&dev->op_regs->usbcmd) & CMD_ATDTW)); | ||
| 627 | |||
| 628 | /* write ATDTW bit to 0 */ | ||
| 629 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 630 | writel(usbcmd & ~CMD_ATDTW, &dev->op_regs->usbcmd); | ||
| 631 | |||
| 632 | if (endptstat) | ||
| 633 | goto out; | ||
| 634 | } | ||
| 635 | |||
| 636 | /* write dQH next pointer and terminate bit to 0 */ | ||
| 637 | dtd_dma = req->head->dtd_dma & DTD_NEXT_MASK; | ||
| 638 | dqh->dtd_next = cpu_to_le32(dtd_dma); | ||
| 639 | |||
| 640 | /* clear active and halt bit */ | ||
| 641 | dtd_status = (u8) ~(DTD_STS_ACTIVE | DTD_STS_HALTED); | ||
| 642 | dqh->dtd_status &= dtd_status; | ||
| 643 | dev_vdbg(&dev->pdev->dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status); | ||
| 644 | |||
| 645 | /* ensure that updates to the dQH will occur before priming */ | ||
| 646 | wmb(); | ||
| 647 | |||
| 648 | /* write 1 to endptprime register to PRIME endpoint */ | ||
| 649 | bit_mask = is_in(ep) ? (1 << (ep->ep_num + 16)) : (1 << ep->ep_num); | ||
| 650 | dev_vdbg(&dev->pdev->dev, "endprime bit_mask = 0x%08x\n", bit_mask); | ||
| 651 | writel(bit_mask, &dev->op_regs->endptprime); | ||
| 652 | out: | ||
| 653 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 654 | return 0; | ||
| 655 | } | ||
| 656 | |||
| 657 | |||
| 658 | /* fill in the dTD structure to build a transfer descriptor */ | ||
| 659 | static struct langwell_dtd *build_dtd(struct langwell_request *req, | ||
| 660 | unsigned *length, dma_addr_t *dma, int *is_last) | ||
| 661 | { | ||
| 662 | u32 buf_ptr; | ||
| 663 | struct langwell_dtd *dtd; | ||
| 664 | struct langwell_udc *dev; | ||
| 665 | int i; | ||
| 666 | |||
| 667 | dev = req->ep->dev; | ||
| 668 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 669 | |||
| 670 | /* the maximum transfer length, up to 16k bytes */ | ||
| 671 | *length = min(req->req.length - req->req.actual, | ||
| 672 | (unsigned)DTD_MAX_TRANSFER_LENGTH); | ||
| 673 | |||
| 674 | /* create dTD dma_pool resource */ | ||
| 675 | dtd = dma_pool_alloc(dev->dtd_pool, GFP_KERNEL, dma); | ||
| 676 | if (dtd == NULL) | ||
| 677 | return dtd; | ||
| 678 | dtd->dtd_dma = *dma; | ||
| 679 | |||
| 680 | /* initialize buffer page pointers */ | ||
| 681 | buf_ptr = (u32)(req->req.dma + req->req.actual); | ||
| 682 | for (i = 0; i < 5; i++) | ||
| 683 | dtd->dtd_buf[i] = cpu_to_le32(buf_ptr + i * PAGE_SIZE); | ||
| 684 | |||
| 685 | req->req.actual += *length; | ||
| 686 | |||
| 687 | /* fill in total bytes with transfer size */ | ||
| 688 | dtd->dtd_total = cpu_to_le16(*length); | ||
| 689 | dev_vdbg(&dev->pdev->dev, "dtd->dtd_total = %d\n", dtd->dtd_total); | ||
| 690 | |||
| 691 | /* set is_last flag if req->req.zero is set or not */ | ||
| 692 | if (req->req.zero) { | ||
| 693 | if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0) | ||
| 694 | *is_last = 1; | ||
| 695 | else | ||
| 696 | *is_last = 0; | ||
| 697 | } else if (req->req.length == req->req.actual) { | ||
| 698 | *is_last = 1; | ||
| 699 | } else | ||
| 700 | *is_last = 0; | ||
| 701 | |||
| 702 | if (*is_last == 0) | ||
| 703 | dev_vdbg(&dev->pdev->dev, "multi-dtd request!\n"); | ||
| 704 | |||
| 705 | /* set interrupt on complete bit for the last dTD */ | ||
| 706 | if (*is_last && !req->req.no_interrupt) | ||
| 707 | dtd->dtd_ioc = 1; | ||
| 708 | |||
| 709 | /* set multiplier override 0 for non-ISO and non-TX endpoint */ | ||
| 710 | dtd->dtd_multo = 0; | ||
| 711 | |||
| 712 | /* set the active bit of status field to 1 */ | ||
| 713 | dtd->dtd_status = DTD_STS_ACTIVE; | ||
| 714 | dev_vdbg(&dev->pdev->dev, "dtd->dtd_status = 0x%02x\n", | ||
| 715 | dtd->dtd_status); | ||
| 716 | |||
| 717 | dev_vdbg(&dev->pdev->dev, "length = %d, dma addr= 0x%08x\n", | ||
| 718 | *length, (int)*dma); | ||
| 719 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 720 | return dtd; | ||
| 721 | } | ||
| 722 | |||
| 723 | |||
| 724 | /* generate dTD linked list for a request */ | ||
| 725 | static int req_to_dtd(struct langwell_request *req) | ||
| 726 | { | ||
| 727 | unsigned count; | ||
| 728 | int is_last, is_first = 1; | ||
| 729 | struct langwell_dtd *dtd, *last_dtd = NULL; | ||
| 730 | struct langwell_udc *dev; | ||
| 731 | dma_addr_t dma; | ||
| 732 | |||
| 733 | dev = req->ep->dev; | ||
| 734 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 735 | do { | ||
| 736 | dtd = build_dtd(req, &count, &dma, &is_last); | ||
| 737 | if (dtd == NULL) | ||
| 738 | return -ENOMEM; | ||
| 739 | |||
| 740 | if (is_first) { | ||
| 741 | is_first = 0; | ||
| 742 | req->head = dtd; | ||
| 743 | } else { | ||
| 744 | last_dtd->dtd_next = cpu_to_le32(dma); | ||
| 745 | last_dtd->next_dtd_virt = dtd; | ||
| 746 | } | ||
| 747 | last_dtd = dtd; | ||
| 748 | req->dtd_count++; | ||
| 749 | } while (!is_last); | ||
| 750 | |||
| 751 | /* set terminate bit to 1 for the last dTD */ | ||
| 752 | dtd->dtd_next = DTD_TERM; | ||
| 753 | |||
| 754 | req->tail = dtd; | ||
| 755 | |||
| 756 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 757 | return 0; | ||
| 758 | } | ||
| 759 | |||
| 760 | /*-------------------------------------------------------------------------*/ | ||
| 761 | |||
| 762 | /* queue (submits) an I/O requests to an endpoint */ | ||
| 763 | static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
| 764 | gfp_t gfp_flags) | ||
| 765 | { | ||
| 766 | struct langwell_request *req; | ||
| 767 | struct langwell_ep *ep; | ||
| 768 | struct langwell_udc *dev; | ||
| 769 | unsigned long flags; | ||
| 770 | int is_iso = 0, zlflag = 0; | ||
| 771 | |||
| 772 | /* always require a cpu-view buffer */ | ||
| 773 | req = container_of(_req, struct langwell_request, req); | ||
| 774 | ep = container_of(_ep, struct langwell_ep, ep); | ||
| 775 | |||
| 776 | if (!_req || !_req->complete || !_req->buf | ||
| 777 | || !list_empty(&req->queue)) { | ||
| 778 | return -EINVAL; | ||
| 779 | } | ||
| 780 | |||
| 781 | if (unlikely(!_ep || !ep->desc)) | ||
| 782 | return -EINVAL; | ||
| 783 | |||
| 784 | dev = ep->dev; | ||
| 785 | req->ep = ep; | ||
| 786 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 787 | |||
| 788 | if (usb_endpoint_xfer_isoc(ep->desc)) { | ||
| 789 | if (req->req.length > ep->ep.maxpacket) | ||
| 790 | return -EMSGSIZE; | ||
| 791 | is_iso = 1; | ||
| 792 | } | ||
| 793 | |||
| 794 | if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) | ||
| 795 | return -ESHUTDOWN; | ||
| 796 | |||
| 797 | /* set up dma mapping in case the caller didn't */ | ||
| 798 | if (_req->dma == DMA_ADDR_INVALID) { | ||
| 799 | /* WORKAROUND: WARN_ON(size == 0) */ | ||
| 800 | if (_req->length == 0) { | ||
| 801 | dev_vdbg(&dev->pdev->dev, "req->length: 0->1\n"); | ||
| 802 | zlflag = 1; | ||
| 803 | _req->length++; | ||
| 804 | } | ||
| 805 | |||
| 806 | _req->dma = dma_map_single(&dev->pdev->dev, | ||
| 807 | _req->buf, _req->length, | ||
| 808 | is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 809 | if (zlflag && (_req->length == 1)) { | ||
| 810 | dev_vdbg(&dev->pdev->dev, "req->length: 1->0\n"); | ||
| 811 | zlflag = 0; | ||
| 812 | _req->length = 0; | ||
| 813 | } | ||
| 814 | |||
| 815 | req->mapped = 1; | ||
| 816 | dev_vdbg(&dev->pdev->dev, "req->mapped = 1\n"); | ||
| 817 | } else { | ||
| 818 | dma_sync_single_for_device(&dev->pdev->dev, | ||
| 819 | _req->dma, _req->length, | ||
| 820 | is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 821 | req->mapped = 0; | ||
| 822 | dev_vdbg(&dev->pdev->dev, "req->mapped = 0\n"); | ||
| 823 | } | ||
| 824 | |||
| 825 | dev_dbg(&dev->pdev->dev, | ||
| 826 | "%s queue req %p, len %u, buf %p, dma 0x%08x\n", | ||
| 827 | _ep->name, | ||
| 828 | _req, _req->length, _req->buf, (int)_req->dma); | ||
| 829 | |||
| 830 | _req->status = -EINPROGRESS; | ||
| 831 | _req->actual = 0; | ||
| 832 | req->dtd_count = 0; | ||
| 833 | |||
| 834 | spin_lock_irqsave(&dev->lock, flags); | ||
| 835 | |||
| 836 | /* build and put dTDs to endpoint queue */ | ||
| 837 | if (!req_to_dtd(req)) { | ||
| 838 | queue_dtd(ep, req); | ||
| 839 | } else { | ||
| 840 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 841 | return -ENOMEM; | ||
| 842 | } | ||
| 843 | |||
| 844 | /* update ep0 state */ | ||
| 845 | if (ep->ep_num == 0) | ||
| 846 | dev->ep0_state = DATA_STATE_XMIT; | ||
| 847 | |||
| 848 | if (likely(req != NULL)) { | ||
| 849 | list_add_tail(&req->queue, &ep->queue); | ||
| 850 | dev_vdbg(&dev->pdev->dev, "list_add_tail()\n"); | ||
| 851 | } | ||
| 852 | |||
| 853 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 854 | |||
| 855 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 856 | return 0; | ||
| 857 | } | ||
| 858 | |||
| 859 | |||
| 860 | /* dequeue (cancels, unlinks) an I/O request from an endpoint */ | ||
| 861 | static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
| 862 | { | ||
| 863 | struct langwell_ep *ep; | ||
| 864 | struct langwell_udc *dev; | ||
| 865 | struct langwell_request *req; | ||
| 866 | unsigned long flags; | ||
| 867 | int stopped, ep_num, retval = 0; | ||
| 868 | u32 endptctrl; | ||
| 869 | |||
| 870 | ep = container_of(_ep, struct langwell_ep, ep); | ||
| 871 | dev = ep->dev; | ||
| 872 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 873 | |||
| 874 | if (!_ep || !ep->desc || !_req) | ||
| 875 | return -EINVAL; | ||
| 876 | |||
| 877 | if (!dev->driver) | ||
| 878 | return -ESHUTDOWN; | ||
| 879 | |||
| 880 | spin_lock_irqsave(&dev->lock, flags); | ||
| 881 | stopped = ep->stopped; | ||
| 882 | |||
| 883 | /* quiesce dma while we patch the queue */ | ||
| 884 | ep->stopped = 1; | ||
| 885 | ep_num = ep->ep_num; | ||
| 886 | |||
| 887 | /* disable endpoint control register */ | ||
| 888 | endptctrl = readl(&dev->op_regs->endptctrl[ep_num]); | ||
| 889 | if (is_in(ep)) | ||
| 890 | endptctrl &= ~EPCTRL_TXE; | ||
| 891 | else | ||
| 892 | endptctrl &= ~EPCTRL_RXE; | ||
| 893 | writel(endptctrl, &dev->op_regs->endptctrl[ep_num]); | ||
| 894 | |||
| 895 | /* make sure it's still queued on this endpoint */ | ||
| 896 | list_for_each_entry(req, &ep->queue, queue) { | ||
| 897 | if (&req->req == _req) | ||
| 898 | break; | ||
| 899 | } | ||
| 900 | |||
| 901 | if (&req->req != _req) { | ||
| 902 | retval = -EINVAL; | ||
| 903 | goto done; | ||
| 904 | } | ||
| 905 | |||
| 906 | /* queue head may be partially complete. */ | ||
| 907 | if (ep->queue.next == &req->queue) { | ||
| 908 | dev_dbg(&dev->pdev->dev, "unlink (%s) dma\n", _ep->name); | ||
| 909 | _req->status = -ECONNRESET; | ||
| 910 | langwell_ep_fifo_flush(&ep->ep); | ||
| 911 | |||
| 912 | /* not the last request in endpoint queue */ | ||
| 913 | if (likely(ep->queue.next == &req->queue)) { | ||
| 914 | struct langwell_dqh *dqh; | ||
| 915 | struct langwell_request *next_req; | ||
| 916 | |||
| 917 | dqh = ep->dqh; | ||
| 918 | next_req = list_entry(req->queue.next, | ||
| 919 | struct langwell_request, queue); | ||
| 920 | |||
| 921 | /* point the dQH to the first dTD of next request */ | ||
| 922 | writel((u32) next_req->head, &dqh->dqh_current); | ||
| 923 | } | ||
| 924 | } else { | ||
| 925 | struct langwell_request *prev_req; | ||
| 926 | |||
| 927 | prev_req = list_entry(req->queue.prev, | ||
| 928 | struct langwell_request, queue); | ||
| 929 | writel(readl(&req->tail->dtd_next), | ||
| 930 | &prev_req->tail->dtd_next); | ||
| 931 | } | ||
| 932 | |||
| 933 | done(ep, req, -ECONNRESET); | ||
| 934 | |||
| 935 | done: | ||
| 936 | /* enable endpoint again */ | ||
| 937 | endptctrl = readl(&dev->op_regs->endptctrl[ep_num]); | ||
| 938 | if (is_in(ep)) | ||
| 939 | endptctrl |= EPCTRL_TXE; | ||
| 940 | else | ||
| 941 | endptctrl |= EPCTRL_RXE; | ||
| 942 | writel(endptctrl, &dev->op_regs->endptctrl[ep_num]); | ||
| 943 | |||
| 944 | ep->stopped = stopped; | ||
| 945 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 946 | |||
| 947 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 948 | return retval; | ||
| 949 | } | ||
| 950 | |||
| 951 | |||
| 952 | /*-------------------------------------------------------------------------*/ | ||
| 953 | |||
| 954 | /* endpoint set/clear halt */ | ||
| 955 | static void ep_set_halt(struct langwell_ep *ep, int value) | ||
| 956 | { | ||
| 957 | u32 endptctrl = 0; | ||
| 958 | int ep_num; | ||
| 959 | struct langwell_udc *dev = ep->dev; | ||
| 960 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 961 | |||
| 962 | ep_num = ep->ep_num; | ||
| 963 | endptctrl = readl(&dev->op_regs->endptctrl[ep_num]); | ||
| 964 | |||
| 965 | /* value: 1 - set halt, 0 - clear halt */ | ||
| 966 | if (value) { | ||
| 967 | /* set the stall bit */ | ||
| 968 | if (is_in(ep)) | ||
| 969 | endptctrl |= EPCTRL_TXS; | ||
| 970 | else | ||
| 971 | endptctrl |= EPCTRL_RXS; | ||
| 972 | } else { | ||
| 973 | /* clear the stall bit and reset data toggle */ | ||
| 974 | if (is_in(ep)) { | ||
| 975 | endptctrl &= ~EPCTRL_TXS; | ||
| 976 | endptctrl |= EPCTRL_TXR; | ||
| 977 | } else { | ||
| 978 | endptctrl &= ~EPCTRL_RXS; | ||
| 979 | endptctrl |= EPCTRL_RXR; | ||
| 980 | } | ||
| 981 | } | ||
| 982 | |||
| 983 | writel(endptctrl, &dev->op_regs->endptctrl[ep_num]); | ||
| 984 | |||
| 985 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 986 | } | ||
| 987 | |||
| 988 | |||
| 989 | /* set the endpoint halt feature */ | ||
| 990 | static int langwell_ep_set_halt(struct usb_ep *_ep, int value) | ||
| 991 | { | ||
| 992 | struct langwell_ep *ep; | ||
| 993 | struct langwell_udc *dev; | ||
| 994 | unsigned long flags; | ||
| 995 | int retval = 0; | ||
| 996 | |||
| 997 | ep = container_of(_ep, struct langwell_ep, ep); | ||
| 998 | dev = ep->dev; | ||
| 999 | |||
| 1000 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1001 | |||
| 1002 | if (!_ep || !ep->desc) | ||
| 1003 | return -EINVAL; | ||
| 1004 | |||
| 1005 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1006 | return -ESHUTDOWN; | ||
| 1007 | |||
| 1008 | if (usb_endpoint_xfer_isoc(ep->desc)) | ||
| 1009 | return -EOPNOTSUPP; | ||
| 1010 | |||
| 1011 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1012 | |||
| 1013 | /* | ||
| 1014 | * attempt to halt IN ep will fail if any transfer requests | ||
| 1015 | * are still queue | ||
| 1016 | */ | ||
| 1017 | if (!list_empty(&ep->queue) && is_in(ep) && value) { | ||
| 1018 | /* IN endpoint FIFO holds bytes */ | ||
| 1019 | dev_dbg(&dev->pdev->dev, "%s FIFO holds bytes\n", _ep->name); | ||
| 1020 | retval = -EAGAIN; | ||
| 1021 | goto done; | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | /* endpoint set/clear halt */ | ||
| 1025 | if (ep->ep_num) { | ||
| 1026 | ep_set_halt(ep, value); | ||
| 1027 | } else { /* endpoint 0 */ | ||
| 1028 | dev->ep0_state = WAIT_FOR_SETUP; | ||
| 1029 | dev->ep0_dir = USB_DIR_OUT; | ||
| 1030 | } | ||
| 1031 | done: | ||
| 1032 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1033 | dev_dbg(&dev->pdev->dev, "%s %s halt\n", | ||
| 1034 | _ep->name, value ? "set" : "clear"); | ||
| 1035 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1036 | return retval; | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | |||
| 1040 | /* set the halt feature and ignores clear requests */ | ||
| 1041 | static int langwell_ep_set_wedge(struct usb_ep *_ep) | ||
| 1042 | { | ||
| 1043 | struct langwell_ep *ep; | ||
| 1044 | struct langwell_udc *dev; | ||
| 1045 | |||
| 1046 | ep = container_of(_ep, struct langwell_ep, ep); | ||
| 1047 | dev = ep->dev; | ||
| 1048 | |||
| 1049 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1050 | |||
| 1051 | if (!_ep || !ep->desc) | ||
| 1052 | return -EINVAL; | ||
| 1053 | |||
| 1054 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1055 | return usb_ep_set_halt(_ep); | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | |||
| 1059 | /* flush contents of a fifo */ | ||
| 1060 | static void langwell_ep_fifo_flush(struct usb_ep *_ep) | ||
| 1061 | { | ||
| 1062 | struct langwell_ep *ep; | ||
| 1063 | struct langwell_udc *dev; | ||
| 1064 | u32 flush_bit; | ||
| 1065 | unsigned long timeout; | ||
| 1066 | |||
| 1067 | ep = container_of(_ep, struct langwell_ep, ep); | ||
| 1068 | dev = ep->dev; | ||
| 1069 | |||
| 1070 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1071 | |||
| 1072 | if (!_ep || !ep->desc) { | ||
| 1073 | dev_vdbg(&dev->pdev->dev, "ep or ep->desc is NULL\n"); | ||
| 1074 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1075 | return; | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | dev_vdbg(&dev->pdev->dev, "%s-%s fifo flush\n", | ||
| 1079 | _ep->name, DIR_STRING(ep)); | ||
| 1080 | |||
| 1081 | /* flush endpoint buffer */ | ||
| 1082 | if (ep->ep_num == 0) | ||
| 1083 | flush_bit = (1 << 16) | 1; | ||
| 1084 | else if (is_in(ep)) | ||
| 1085 | flush_bit = 1 << (ep->ep_num + 16); /* TX */ | ||
| 1086 | else | ||
| 1087 | flush_bit = 1 << ep->ep_num; /* RX */ | ||
| 1088 | |||
| 1089 | /* wait until flush complete */ | ||
| 1090 | timeout = jiffies + FLUSH_TIMEOUT; | ||
| 1091 | do { | ||
| 1092 | writel(flush_bit, &dev->op_regs->endptflush); | ||
| 1093 | while (readl(&dev->op_regs->endptflush)) { | ||
| 1094 | if (time_after(jiffies, timeout)) { | ||
| 1095 | dev_err(&dev->pdev->dev, "ep flush timeout\n"); | ||
| 1096 | goto done; | ||
| 1097 | } | ||
| 1098 | cpu_relax(); | ||
| 1099 | } | ||
| 1100 | } while (readl(&dev->op_regs->endptstat) & flush_bit); | ||
| 1101 | done: | ||
| 1102 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | |||
| 1106 | /* endpoints operations structure */ | ||
| 1107 | static const struct usb_ep_ops langwell_ep_ops = { | ||
| 1108 | |||
| 1109 | /* configure endpoint, making it usable */ | ||
| 1110 | .enable = langwell_ep_enable, | ||
| 1111 | |||
| 1112 | /* endpoint is no longer usable */ | ||
| 1113 | .disable = langwell_ep_disable, | ||
| 1114 | |||
| 1115 | /* allocate a request object to use with this endpoint */ | ||
| 1116 | .alloc_request = langwell_alloc_request, | ||
| 1117 | |||
| 1118 | /* free a request object */ | ||
| 1119 | .free_request = langwell_free_request, | ||
| 1120 | |||
| 1121 | /* queue (submits) an I/O requests to an endpoint */ | ||
| 1122 | .queue = langwell_ep_queue, | ||
| 1123 | |||
| 1124 | /* dequeue (cancels, unlinks) an I/O request from an endpoint */ | ||
| 1125 | .dequeue = langwell_ep_dequeue, | ||
| 1126 | |||
| 1127 | /* set the endpoint halt feature */ | ||
| 1128 | .set_halt = langwell_ep_set_halt, | ||
| 1129 | |||
| 1130 | /* set the halt feature and ignores clear requests */ | ||
| 1131 | .set_wedge = langwell_ep_set_wedge, | ||
| 1132 | |||
| 1133 | /* flush contents of a fifo */ | ||
| 1134 | .fifo_flush = langwell_ep_fifo_flush, | ||
| 1135 | }; | ||
| 1136 | |||
| 1137 | |||
| 1138 | /*-------------------------------------------------------------------------*/ | ||
| 1139 | |||
| 1140 | /* device controller usb_gadget_ops structure */ | ||
| 1141 | |||
| 1142 | /* returns the current frame number */ | ||
| 1143 | static int langwell_get_frame(struct usb_gadget *_gadget) | ||
| 1144 | { | ||
| 1145 | struct langwell_udc *dev; | ||
| 1146 | u16 retval; | ||
| 1147 | |||
| 1148 | if (!_gadget) | ||
| 1149 | return -ENODEV; | ||
| 1150 | |||
| 1151 | dev = container_of(_gadget, struct langwell_udc, gadget); | ||
| 1152 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1153 | |||
| 1154 | retval = readl(&dev->op_regs->frindex) & FRINDEX_MASK; | ||
| 1155 | |||
| 1156 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1157 | return retval; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | |||
| 1161 | /* enter or exit PHY low power state */ | ||
| 1162 | static void langwell_phy_low_power(struct langwell_udc *dev, bool flag) | ||
| 1163 | { | ||
| 1164 | u32 devlc; | ||
| 1165 | u8 devlc_byte2; | ||
| 1166 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1167 | |||
| 1168 | devlc = readl(&dev->op_regs->devlc); | ||
| 1169 | dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc); | ||
| 1170 | |||
| 1171 | if (flag) | ||
| 1172 | devlc |= LPM_PHCD; | ||
| 1173 | else | ||
| 1174 | devlc &= ~LPM_PHCD; | ||
| 1175 | |||
| 1176 | /* FIXME: workaround for Langwell A1/A2/A3 sighting */ | ||
| 1177 | devlc_byte2 = (devlc >> 16) & 0xff; | ||
| 1178 | writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2); | ||
| 1179 | |||
| 1180 | devlc = readl(&dev->op_regs->devlc); | ||
| 1181 | dev_vdbg(&dev->pdev->dev, | ||
| 1182 | "%s PHY low power suspend, devlc = 0x%08x\n", | ||
| 1183 | flag ? "enter" : "exit", devlc); | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | |||
| 1187 | /* tries to wake up the host connected to this gadget */ | ||
| 1188 | static int langwell_wakeup(struct usb_gadget *_gadget) | ||
| 1189 | { | ||
| 1190 | struct langwell_udc *dev; | ||
| 1191 | u32 portsc1; | ||
| 1192 | unsigned long flags; | ||
| 1193 | |||
| 1194 | if (!_gadget) | ||
| 1195 | return 0; | ||
| 1196 | |||
| 1197 | dev = container_of(_gadget, struct langwell_udc, gadget); | ||
| 1198 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1199 | |||
| 1200 | /* remote wakeup feature not enabled by host */ | ||
| 1201 | if (!dev->remote_wakeup) { | ||
| 1202 | dev_info(&dev->pdev->dev, "remote wakeup is disabled\n"); | ||
| 1203 | return -ENOTSUPP; | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1207 | |||
| 1208 | portsc1 = readl(&dev->op_regs->portsc1); | ||
| 1209 | if (!(portsc1 & PORTS_SUSP)) { | ||
| 1210 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1211 | return 0; | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | /* LPM L1 to L0 or legacy remote wakeup */ | ||
| 1215 | if (dev->lpm && dev->lpm_state == LPM_L1) | ||
| 1216 | dev_info(&dev->pdev->dev, "LPM L1 to L0 remote wakeup\n"); | ||
| 1217 | else | ||
| 1218 | dev_info(&dev->pdev->dev, "device remote wakeup\n"); | ||
| 1219 | |||
| 1220 | /* exit PHY low power suspend */ | ||
| 1221 | if (dev->pdev->device != 0x0829) | ||
| 1222 | langwell_phy_low_power(dev, 0); | ||
| 1223 | |||
| 1224 | /* force port resume */ | ||
| 1225 | portsc1 |= PORTS_FPR; | ||
| 1226 | writel(portsc1, &dev->op_regs->portsc1); | ||
| 1227 | |||
| 1228 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1229 | |||
| 1230 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1231 | return 0; | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | |||
| 1235 | /* notify controller that VBUS is powered or not */ | ||
| 1236 | static int langwell_vbus_session(struct usb_gadget *_gadget, int is_active) | ||
| 1237 | { | ||
| 1238 | struct langwell_udc *dev; | ||
| 1239 | unsigned long flags; | ||
| 1240 | u32 usbcmd; | ||
| 1241 | |||
| 1242 | if (!_gadget) | ||
| 1243 | return -ENODEV; | ||
| 1244 | |||
| 1245 | dev = container_of(_gadget, struct langwell_udc, gadget); | ||
| 1246 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1247 | |||
| 1248 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1249 | dev_vdbg(&dev->pdev->dev, "VBUS status: %s\n", | ||
| 1250 | is_active ? "on" : "off"); | ||
| 1251 | |||
| 1252 | dev->vbus_active = (is_active != 0); | ||
| 1253 | if (dev->driver && dev->softconnected && dev->vbus_active) { | ||
| 1254 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 1255 | usbcmd |= CMD_RUNSTOP; | ||
| 1256 | writel(usbcmd, &dev->op_regs->usbcmd); | ||
| 1257 | } else { | ||
| 1258 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 1259 | usbcmd &= ~CMD_RUNSTOP; | ||
| 1260 | writel(usbcmd, &dev->op_regs->usbcmd); | ||
| 1261 | } | ||
| 1262 | |||
| 1263 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1264 | |||
| 1265 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1266 | return 0; | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | |||
| 1270 | /* constrain controller's VBUS power usage */ | ||
| 1271 | static int langwell_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | ||
| 1272 | { | ||
| 1273 | struct langwell_udc *dev; | ||
| 1274 | |||
| 1275 | if (!_gadget) | ||
| 1276 | return -ENODEV; | ||
| 1277 | |||
| 1278 | dev = container_of(_gadget, struct langwell_udc, gadget); | ||
| 1279 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1280 | |||
| 1281 | if (dev->transceiver) { | ||
| 1282 | dev_vdbg(&dev->pdev->dev, "otg_set_power\n"); | ||
| 1283 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1284 | return otg_set_power(dev->transceiver, mA); | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1288 | return -ENOTSUPP; | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | |||
| 1292 | /* D+ pullup, software-controlled connect/disconnect to USB host */ | ||
| 1293 | static int langwell_pullup(struct usb_gadget *_gadget, int is_on) | ||
| 1294 | { | ||
| 1295 | struct langwell_udc *dev; | ||
| 1296 | u32 usbcmd; | ||
| 1297 | unsigned long flags; | ||
| 1298 | |||
| 1299 | if (!_gadget) | ||
| 1300 | return -ENODEV; | ||
| 1301 | |||
| 1302 | dev = container_of(_gadget, struct langwell_udc, gadget); | ||
| 1303 | |||
| 1304 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1305 | |||
| 1306 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1307 | dev->softconnected = (is_on != 0); | ||
| 1308 | |||
| 1309 | if (dev->driver && dev->softconnected && dev->vbus_active) { | ||
| 1310 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 1311 | usbcmd |= CMD_RUNSTOP; | ||
| 1312 | writel(usbcmd, &dev->op_regs->usbcmd); | ||
| 1313 | } else { | ||
| 1314 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 1315 | usbcmd &= ~CMD_RUNSTOP; | ||
| 1316 | writel(usbcmd, &dev->op_regs->usbcmd); | ||
| 1317 | } | ||
| 1318 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1319 | |||
| 1320 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1321 | return 0; | ||
| 1322 | } | ||
| 1323 | |||
| 1324 | static int langwell_start(struct usb_gadget_driver *driver, | ||
| 1325 | int (*bind)(struct usb_gadget *)); | ||
| 1326 | static int langwell_stop(struct usb_gadget_driver *driver); | ||
| 1327 | /* device controller usb_gadget_ops structure */ | ||
| 1328 | static const struct usb_gadget_ops langwell_ops = { | ||
| 1329 | |||
| 1330 | /* returns the current frame number */ | ||
| 1331 | .get_frame = langwell_get_frame, | ||
| 1332 | |||
| 1333 | /* tries to wake up the host connected to this gadget */ | ||
| 1334 | .wakeup = langwell_wakeup, | ||
| 1335 | |||
| 1336 | /* set the device selfpowered feature, always selfpowered */ | ||
| 1337 | /* .set_selfpowered = langwell_set_selfpowered, */ | ||
| 1338 | |||
| 1339 | /* notify controller that VBUS is powered or not */ | ||
| 1340 | .vbus_session = langwell_vbus_session, | ||
| 1341 | |||
| 1342 | /* constrain controller's VBUS power usage */ | ||
| 1343 | .vbus_draw = langwell_vbus_draw, | ||
| 1344 | |||
| 1345 | /* D+ pullup, software-controlled connect/disconnect to USB host */ | ||
| 1346 | .pullup = langwell_pullup, | ||
| 1347 | |||
| 1348 | .start = langwell_start, | ||
| 1349 | .stop = langwell_stop, | ||
| 1350 | }; | ||
| 1351 | |||
| 1352 | |||
| 1353 | /*-------------------------------------------------------------------------*/ | ||
| 1354 | |||
| 1355 | /* device controller operations */ | ||
| 1356 | |||
| 1357 | /* reset device controller */ | ||
| 1358 | static int langwell_udc_reset(struct langwell_udc *dev) | ||
| 1359 | { | ||
| 1360 | u32 usbcmd, usbmode, devlc, endpointlistaddr; | ||
| 1361 | u8 devlc_byte0, devlc_byte2; | ||
| 1362 | unsigned long timeout; | ||
| 1363 | |||
| 1364 | if (!dev) | ||
| 1365 | return -EINVAL; | ||
| 1366 | |||
| 1367 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1368 | |||
| 1369 | /* set controller to stop state */ | ||
| 1370 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 1371 | usbcmd &= ~CMD_RUNSTOP; | ||
| 1372 | writel(usbcmd, &dev->op_regs->usbcmd); | ||
| 1373 | |||
| 1374 | /* reset device controller */ | ||
| 1375 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 1376 | usbcmd |= CMD_RST; | ||
| 1377 | writel(usbcmd, &dev->op_regs->usbcmd); | ||
| 1378 | |||
| 1379 | /* wait for reset to complete */ | ||
| 1380 | timeout = jiffies + RESET_TIMEOUT; | ||
| 1381 | while (readl(&dev->op_regs->usbcmd) & CMD_RST) { | ||
| 1382 | if (time_after(jiffies, timeout)) { | ||
| 1383 | dev_err(&dev->pdev->dev, "device reset timeout\n"); | ||
| 1384 | return -ETIMEDOUT; | ||
| 1385 | } | ||
| 1386 | cpu_relax(); | ||
| 1387 | } | ||
| 1388 | |||
| 1389 | /* set controller to device mode */ | ||
| 1390 | usbmode = readl(&dev->op_regs->usbmode); | ||
| 1391 | usbmode |= MODE_DEVICE; | ||
| 1392 | |||
| 1393 | /* turn setup lockout off, require setup tripwire in usbcmd */ | ||
| 1394 | usbmode |= MODE_SLOM; | ||
| 1395 | |||
| 1396 | writel(usbmode, &dev->op_regs->usbmode); | ||
| 1397 | usbmode = readl(&dev->op_regs->usbmode); | ||
| 1398 | dev_vdbg(&dev->pdev->dev, "usbmode=0x%08x\n", usbmode); | ||
| 1399 | |||
| 1400 | /* Write-Clear setup status */ | ||
| 1401 | writel(0, &dev->op_regs->usbsts); | ||
| 1402 | |||
| 1403 | /* if support USB LPM, ACK all LPM token */ | ||
| 1404 | if (dev->lpm) { | ||
| 1405 | devlc = readl(&dev->op_regs->devlc); | ||
| 1406 | dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc); | ||
| 1407 | /* FIXME: workaround for Langwell A1/A2/A3 sighting */ | ||
| 1408 | devlc &= ~LPM_STL; /* don't STALL LPM token */ | ||
| 1409 | devlc &= ~LPM_NYT_ACK; /* ACK LPM token */ | ||
| 1410 | devlc_byte0 = devlc & 0xff; | ||
| 1411 | devlc_byte2 = (devlc >> 16) & 0xff; | ||
| 1412 | writeb(devlc_byte0, (u8 *)&dev->op_regs->devlc); | ||
| 1413 | writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2); | ||
| 1414 | devlc = readl(&dev->op_regs->devlc); | ||
| 1415 | dev_vdbg(&dev->pdev->dev, | ||
| 1416 | "ACK LPM token, devlc = 0x%08x\n", devlc); | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | /* fill endpointlistaddr register */ | ||
| 1420 | endpointlistaddr = dev->ep_dqh_dma; | ||
| 1421 | endpointlistaddr &= ENDPOINTLISTADDR_MASK; | ||
| 1422 | writel(endpointlistaddr, &dev->op_regs->endpointlistaddr); | ||
| 1423 | |||
| 1424 | dev_vdbg(&dev->pdev->dev, | ||
| 1425 | "dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n", | ||
| 1426 | dev->ep_dqh, endpointlistaddr, | ||
| 1427 | readl(&dev->op_regs->endpointlistaddr)); | ||
| 1428 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1429 | return 0; | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | |||
| 1433 | /* reinitialize device controller endpoints */ | ||
| 1434 | static int eps_reinit(struct langwell_udc *dev) | ||
| 1435 | { | ||
| 1436 | struct langwell_ep *ep; | ||
| 1437 | char name[14]; | ||
| 1438 | int i; | ||
| 1439 | |||
| 1440 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1441 | |||
| 1442 | /* initialize ep0 */ | ||
| 1443 | ep = &dev->ep[0]; | ||
| 1444 | ep->dev = dev; | ||
| 1445 | strncpy(ep->name, "ep0", sizeof(ep->name)); | ||
| 1446 | ep->ep.name = ep->name; | ||
| 1447 | ep->ep.ops = &langwell_ep_ops; | ||
| 1448 | ep->stopped = 0; | ||
| 1449 | ep->ep.maxpacket = EP0_MAX_PKT_SIZE; | ||
| 1450 | ep->ep_num = 0; | ||
| 1451 | ep->desc = &langwell_ep0_desc; | ||
| 1452 | INIT_LIST_HEAD(&ep->queue); | ||
| 1453 | |||
| 1454 | ep->ep_type = USB_ENDPOINT_XFER_CONTROL; | ||
| 1455 | |||
| 1456 | /* initialize other endpoints */ | ||
| 1457 | for (i = 2; i < dev->ep_max; i++) { | ||
| 1458 | ep = &dev->ep[i]; | ||
| 1459 | if (i % 2) | ||
| 1460 | snprintf(name, sizeof(name), "ep%din", i / 2); | ||
| 1461 | else | ||
| 1462 | snprintf(name, sizeof(name), "ep%dout", i / 2); | ||
| 1463 | ep->dev = dev; | ||
| 1464 | strncpy(ep->name, name, sizeof(ep->name)); | ||
| 1465 | ep->ep.name = ep->name; | ||
| 1466 | |||
| 1467 | ep->ep.ops = &langwell_ep_ops; | ||
| 1468 | ep->stopped = 0; | ||
| 1469 | ep->ep.maxpacket = (unsigned short) ~0; | ||
| 1470 | ep->ep_num = i / 2; | ||
| 1471 | |||
| 1472 | INIT_LIST_HEAD(&ep->queue); | ||
| 1473 | list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list); | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1477 | return 0; | ||
| 1478 | } | ||
| 1479 | |||
| 1480 | |||
| 1481 | /* enable interrupt and set controller to run state */ | ||
| 1482 | static void langwell_udc_start(struct langwell_udc *dev) | ||
| 1483 | { | ||
| 1484 | u32 usbintr, usbcmd; | ||
| 1485 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1486 | |||
| 1487 | /* enable interrupts */ | ||
| 1488 | usbintr = INTR_ULPIE /* ULPI */ | ||
| 1489 | | INTR_SLE /* suspend */ | ||
| 1490 | /* | INTR_SRE SOF received */ | ||
| 1491 | | INTR_URE /* USB reset */ | ||
| 1492 | | INTR_AAE /* async advance */ | ||
| 1493 | | INTR_SEE /* system error */ | ||
| 1494 | | INTR_FRE /* frame list rollover */ | ||
| 1495 | | INTR_PCE /* port change detect */ | ||
| 1496 | | INTR_UEE /* USB error interrupt */ | ||
| 1497 | | INTR_UE; /* USB interrupt */ | ||
| 1498 | writel(usbintr, &dev->op_regs->usbintr); | ||
| 1499 | |||
| 1500 | /* clear stopped bit */ | ||
| 1501 | dev->stopped = 0; | ||
| 1502 | |||
| 1503 | /* set controller to run */ | ||
| 1504 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 1505 | usbcmd |= CMD_RUNSTOP; | ||
| 1506 | writel(usbcmd, &dev->op_regs->usbcmd); | ||
| 1507 | |||
| 1508 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1509 | } | ||
| 1510 | |||
| 1511 | |||
| 1512 | /* disable interrupt and set controller to stop state */ | ||
| 1513 | static void langwell_udc_stop(struct langwell_udc *dev) | ||
| 1514 | { | ||
| 1515 | u32 usbcmd; | ||
| 1516 | |||
| 1517 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1518 | |||
| 1519 | /* disable all interrupts */ | ||
| 1520 | writel(0, &dev->op_regs->usbintr); | ||
| 1521 | |||
| 1522 | /* set stopped bit */ | ||
| 1523 | dev->stopped = 1; | ||
| 1524 | |||
| 1525 | /* set controller to stop state */ | ||
| 1526 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 1527 | usbcmd &= ~CMD_RUNSTOP; | ||
| 1528 | writel(usbcmd, &dev->op_regs->usbcmd); | ||
| 1529 | |||
| 1530 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | |||
| 1534 | /* stop all USB activities */ | ||
| 1535 | static void stop_activity(struct langwell_udc *dev, | ||
| 1536 | struct usb_gadget_driver *driver) | ||
| 1537 | { | ||
| 1538 | struct langwell_ep *ep; | ||
| 1539 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1540 | |||
| 1541 | nuke(&dev->ep[0], -ESHUTDOWN); | ||
| 1542 | |||
| 1543 | list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) { | ||
| 1544 | nuke(ep, -ESHUTDOWN); | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | /* report disconnect; the driver is already quiesced */ | ||
| 1548 | if (driver) { | ||
| 1549 | spin_unlock(&dev->lock); | ||
| 1550 | driver->disconnect(&dev->gadget); | ||
| 1551 | spin_lock(&dev->lock); | ||
| 1552 | } | ||
| 1553 | |||
| 1554 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | |||
| 1558 | /*-------------------------------------------------------------------------*/ | ||
| 1559 | |||
| 1560 | /* device "function" sysfs attribute file */ | ||
| 1561 | static ssize_t show_function(struct device *_dev, | ||
| 1562 | struct device_attribute *attr, char *buf) | ||
| 1563 | { | ||
| 1564 | struct langwell_udc *dev = the_controller; | ||
| 1565 | |||
| 1566 | if (!dev->driver || !dev->driver->function | ||
| 1567 | || strlen(dev->driver->function) > PAGE_SIZE) | ||
| 1568 | return 0; | ||
| 1569 | |||
| 1570 | return scnprintf(buf, PAGE_SIZE, "%s\n", dev->driver->function); | ||
| 1571 | } | ||
| 1572 | static DEVICE_ATTR(function, S_IRUGO, show_function, NULL); | ||
| 1573 | |||
| 1574 | |||
| 1575 | /* device "langwell_udc" sysfs attribute file */ | ||
| 1576 | static ssize_t show_langwell_udc(struct device *_dev, | ||
| 1577 | struct device_attribute *attr, char *buf) | ||
| 1578 | { | ||
| 1579 | struct langwell_udc *dev = the_controller; | ||
| 1580 | struct langwell_request *req; | ||
| 1581 | struct langwell_ep *ep = NULL; | ||
| 1582 | char *next; | ||
| 1583 | unsigned size; | ||
| 1584 | unsigned t; | ||
| 1585 | unsigned i; | ||
| 1586 | unsigned long flags; | ||
| 1587 | u32 tmp_reg; | ||
| 1588 | |||
| 1589 | next = buf; | ||
| 1590 | size = PAGE_SIZE; | ||
| 1591 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1592 | |||
| 1593 | /* driver basic information */ | ||
| 1594 | t = scnprintf(next, size, | ||
| 1595 | DRIVER_DESC "\n" | ||
| 1596 | "%s version: %s\n" | ||
| 1597 | "Gadget driver: %s\n\n", | ||
| 1598 | driver_name, DRIVER_VERSION, | ||
| 1599 | dev->driver ? dev->driver->driver.name : "(none)"); | ||
| 1600 | size -= t; | ||
| 1601 | next += t; | ||
| 1602 | |||
| 1603 | /* device registers */ | ||
| 1604 | tmp_reg = readl(&dev->op_regs->usbcmd); | ||
| 1605 | t = scnprintf(next, size, | ||
| 1606 | "USBCMD reg:\n" | ||
| 1607 | "SetupTW: %d\n" | ||
| 1608 | "Run/Stop: %s\n\n", | ||
| 1609 | (tmp_reg & CMD_SUTW) ? 1 : 0, | ||
| 1610 | (tmp_reg & CMD_RUNSTOP) ? "Run" : "Stop"); | ||
| 1611 | size -= t; | ||
| 1612 | next += t; | ||
| 1613 | |||
| 1614 | tmp_reg = readl(&dev->op_regs->usbsts); | ||
| 1615 | t = scnprintf(next, size, | ||
| 1616 | "USB Status Reg:\n" | ||
| 1617 | "Device Suspend: %d\n" | ||
| 1618 | "Reset Received: %d\n" | ||
| 1619 | "System Error: %s\n" | ||
| 1620 | "USB Error Interrupt: %s\n\n", | ||
| 1621 | (tmp_reg & STS_SLI) ? 1 : 0, | ||
| 1622 | (tmp_reg & STS_URI) ? 1 : 0, | ||
| 1623 | (tmp_reg & STS_SEI) ? "Error" : "No error", | ||
| 1624 | (tmp_reg & STS_UEI) ? "Error detected" : "No error"); | ||
| 1625 | size -= t; | ||
| 1626 | next += t; | ||
| 1627 | |||
| 1628 | tmp_reg = readl(&dev->op_regs->usbintr); | ||
| 1629 | t = scnprintf(next, size, | ||
| 1630 | "USB Intrrupt Enable Reg:\n" | ||
| 1631 | "Sleep Enable: %d\n" | ||
| 1632 | "SOF Received Enable: %d\n" | ||
| 1633 | "Reset Enable: %d\n" | ||
| 1634 | "System Error Enable: %d\n" | ||
| 1635 | "Port Change Dectected Enable: %d\n" | ||
| 1636 | "USB Error Intr Enable: %d\n" | ||
| 1637 | "USB Intr Enable: %d\n\n", | ||
| 1638 | (tmp_reg & INTR_SLE) ? 1 : 0, | ||
| 1639 | (tmp_reg & INTR_SRE) ? 1 : 0, | ||
| 1640 | (tmp_reg & INTR_URE) ? 1 : 0, | ||
| 1641 | (tmp_reg & INTR_SEE) ? 1 : 0, | ||
| 1642 | (tmp_reg & INTR_PCE) ? 1 : 0, | ||
| 1643 | (tmp_reg & INTR_UEE) ? 1 : 0, | ||
| 1644 | (tmp_reg & INTR_UE) ? 1 : 0); | ||
| 1645 | size -= t; | ||
| 1646 | next += t; | ||
| 1647 | |||
| 1648 | tmp_reg = readl(&dev->op_regs->frindex); | ||
| 1649 | t = scnprintf(next, size, | ||
| 1650 | "USB Frame Index Reg:\n" | ||
| 1651 | "Frame Number is 0x%08x\n\n", | ||
| 1652 | (tmp_reg & FRINDEX_MASK)); | ||
| 1653 | size -= t; | ||
| 1654 | next += t; | ||
| 1655 | |||
| 1656 | tmp_reg = readl(&dev->op_regs->deviceaddr); | ||
| 1657 | t = scnprintf(next, size, | ||
| 1658 | "USB Device Address Reg:\n" | ||
| 1659 | "Device Addr is 0x%x\n\n", | ||
| 1660 | USBADR(tmp_reg)); | ||
| 1661 | size -= t; | ||
| 1662 | next += t; | ||
| 1663 | |||
| 1664 | tmp_reg = readl(&dev->op_regs->endpointlistaddr); | ||
| 1665 | t = scnprintf(next, size, | ||
| 1666 | "USB Endpoint List Address Reg:\n" | ||
| 1667 | "Endpoint List Pointer is 0x%x\n\n", | ||
| 1668 | EPBASE(tmp_reg)); | ||
| 1669 | size -= t; | ||
| 1670 | next += t; | ||
| 1671 | |||
| 1672 | tmp_reg = readl(&dev->op_regs->portsc1); | ||
| 1673 | t = scnprintf(next, size, | ||
| 1674 | "USB Port Status & Control Reg:\n" | ||
| 1675 | "Port Reset: %s\n" | ||
| 1676 | "Port Suspend Mode: %s\n" | ||
| 1677 | "Over-current Change: %s\n" | ||
| 1678 | "Port Enable/Disable Change: %s\n" | ||
| 1679 | "Port Enabled/Disabled: %s\n" | ||
| 1680 | "Current Connect Status: %s\n" | ||
| 1681 | "LPM Suspend Status: %s\n\n", | ||
| 1682 | (tmp_reg & PORTS_PR) ? "Reset" : "Not Reset", | ||
| 1683 | (tmp_reg & PORTS_SUSP) ? "Suspend " : "Not Suspend", | ||
| 1684 | (tmp_reg & PORTS_OCC) ? "Detected" : "No", | ||
| 1685 | (tmp_reg & PORTS_PEC) ? "Changed" : "Not Changed", | ||
| 1686 | (tmp_reg & PORTS_PE) ? "Enable" : "Not Correct", | ||
| 1687 | (tmp_reg & PORTS_CCS) ? "Attached" : "Not Attached", | ||
| 1688 | (tmp_reg & PORTS_SLP) ? "LPM L1" : "LPM L0"); | ||
| 1689 | size -= t; | ||
| 1690 | next += t; | ||
| 1691 | |||
| 1692 | tmp_reg = readl(&dev->op_regs->devlc); | ||
| 1693 | t = scnprintf(next, size, | ||
| 1694 | "Device LPM Control Reg:\n" | ||
| 1695 | "Parallel Transceiver : %d\n" | ||
| 1696 | "Serial Transceiver : %d\n" | ||
| 1697 | "Port Speed: %s\n" | ||
| 1698 | "Port Force Full Speed Connenct: %s\n" | ||
| 1699 | "PHY Low Power Suspend Clock: %s\n" | ||
| 1700 | "BmAttributes: %d\n\n", | ||
| 1701 | LPM_PTS(tmp_reg), | ||
| 1702 | (tmp_reg & LPM_STS) ? 1 : 0, | ||
| 1703 | ({ | ||
| 1704 | char *s; | ||
| 1705 | switch (LPM_PSPD(tmp_reg)) { | ||
| 1706 | case LPM_SPEED_FULL: | ||
| 1707 | s = "Full Speed"; break; | ||
| 1708 | case LPM_SPEED_LOW: | ||
| 1709 | s = "Low Speed"; break; | ||
| 1710 | case LPM_SPEED_HIGH: | ||
| 1711 | s = "High Speed"; break; | ||
| 1712 | default: | ||
| 1713 | s = "Unknown Speed"; break; | ||
| 1714 | } | ||
| 1715 | s; | ||
| 1716 | }), | ||
| 1717 | (tmp_reg & LPM_PFSC) ? "Force Full Speed" : "Not Force", | ||
| 1718 | (tmp_reg & LPM_PHCD) ? "Disabled" : "Enabled", | ||
| 1719 | LPM_BA(tmp_reg)); | ||
| 1720 | size -= t; | ||
| 1721 | next += t; | ||
| 1722 | |||
| 1723 | tmp_reg = readl(&dev->op_regs->usbmode); | ||
| 1724 | t = scnprintf(next, size, | ||
| 1725 | "USB Mode Reg:\n" | ||
| 1726 | "Controller Mode is : %s\n\n", ({ | ||
| 1727 | char *s; | ||
| 1728 | switch (MODE_CM(tmp_reg)) { | ||
| 1729 | case MODE_IDLE: | ||
| 1730 | s = "Idle"; break; | ||
| 1731 | case MODE_DEVICE: | ||
| 1732 | s = "Device Controller"; break; | ||
| 1733 | case MODE_HOST: | ||
| 1734 | s = "Host Controller"; break; | ||
| 1735 | default: | ||
| 1736 | s = "None"; break; | ||
| 1737 | } | ||
| 1738 | s; | ||
| 1739 | })); | ||
| 1740 | size -= t; | ||
| 1741 | next += t; | ||
| 1742 | |||
| 1743 | tmp_reg = readl(&dev->op_regs->endptsetupstat); | ||
| 1744 | t = scnprintf(next, size, | ||
| 1745 | "Endpoint Setup Status Reg:\n" | ||
| 1746 | "SETUP on ep 0x%04x\n\n", | ||
| 1747 | tmp_reg & SETUPSTAT_MASK); | ||
| 1748 | size -= t; | ||
| 1749 | next += t; | ||
| 1750 | |||
| 1751 | for (i = 0; i < dev->ep_max / 2; i++) { | ||
| 1752 | tmp_reg = readl(&dev->op_regs->endptctrl[i]); | ||
| 1753 | t = scnprintf(next, size, "EP Ctrl Reg [%d]: 0x%08x\n", | ||
| 1754 | i, tmp_reg); | ||
| 1755 | size -= t; | ||
| 1756 | next += t; | ||
| 1757 | } | ||
| 1758 | tmp_reg = readl(&dev->op_regs->endptprime); | ||
| 1759 | t = scnprintf(next, size, "EP Prime Reg: 0x%08x\n\n", tmp_reg); | ||
| 1760 | size -= t; | ||
| 1761 | next += t; | ||
| 1762 | |||
| 1763 | /* langwell_udc, langwell_ep, langwell_request structure information */ | ||
| 1764 | ep = &dev->ep[0]; | ||
| 1765 | t = scnprintf(next, size, "%s MaxPacketSize: 0x%x, ep_num: %d\n", | ||
| 1766 | ep->ep.name, ep->ep.maxpacket, ep->ep_num); | ||
| 1767 | size -= t; | ||
| 1768 | next += t; | ||
| 1769 | |||
| 1770 | if (list_empty(&ep->queue)) { | ||
| 1771 | t = scnprintf(next, size, "its req queue is empty\n\n"); | ||
| 1772 | size -= t; | ||
| 1773 | next += t; | ||
| 1774 | } else { | ||
| 1775 | list_for_each_entry(req, &ep->queue, queue) { | ||
| 1776 | t = scnprintf(next, size, | ||
| 1777 | "req %p actual 0x%x length 0x%x buf %p\n", | ||
| 1778 | &req->req, req->req.actual, | ||
| 1779 | req->req.length, req->req.buf); | ||
| 1780 | size -= t; | ||
| 1781 | next += t; | ||
| 1782 | } | ||
| 1783 | } | ||
| 1784 | /* other gadget->eplist ep */ | ||
| 1785 | list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) { | ||
| 1786 | if (ep->desc) { | ||
| 1787 | t = scnprintf(next, size, | ||
| 1788 | "\n%s MaxPacketSize: 0x%x, " | ||
| 1789 | "ep_num: %d\n", | ||
| 1790 | ep->ep.name, ep->ep.maxpacket, | ||
| 1791 | ep->ep_num); | ||
| 1792 | size -= t; | ||
| 1793 | next += t; | ||
| 1794 | |||
| 1795 | if (list_empty(&ep->queue)) { | ||
| 1796 | t = scnprintf(next, size, | ||
| 1797 | "its req queue is empty\n\n"); | ||
| 1798 | size -= t; | ||
| 1799 | next += t; | ||
| 1800 | } else { | ||
| 1801 | list_for_each_entry(req, &ep->queue, queue) { | ||
| 1802 | t = scnprintf(next, size, | ||
| 1803 | "req %p actual 0x%x length " | ||
| 1804 | "0x%x buf %p\n", | ||
| 1805 | &req->req, req->req.actual, | ||
| 1806 | req->req.length, req->req.buf); | ||
| 1807 | size -= t; | ||
| 1808 | next += t; | ||
| 1809 | } | ||
| 1810 | } | ||
| 1811 | } | ||
| 1812 | } | ||
| 1813 | |||
| 1814 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1815 | return PAGE_SIZE - size; | ||
| 1816 | } | ||
| 1817 | static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL); | ||
| 1818 | |||
| 1819 | |||
| 1820 | /* device "remote_wakeup" sysfs attribute file */ | ||
| 1821 | static ssize_t store_remote_wakeup(struct device *_dev, | ||
| 1822 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 1823 | { | ||
| 1824 | struct langwell_udc *dev = the_controller; | ||
| 1825 | unsigned long flags; | ||
| 1826 | ssize_t rc = count; | ||
| 1827 | |||
| 1828 | if (count > 2) | ||
| 1829 | return -EINVAL; | ||
| 1830 | |||
| 1831 | if (count > 0 && buf[count-1] == '\n') | ||
| 1832 | ((char *) buf)[count-1] = 0; | ||
| 1833 | |||
| 1834 | if (buf[0] != '1') | ||
| 1835 | return -EINVAL; | ||
| 1836 | |||
| 1837 | /* force remote wakeup enabled in case gadget driver doesn't support */ | ||
| 1838 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1839 | dev->remote_wakeup = 1; | ||
| 1840 | dev->dev_status |= (1 << USB_DEVICE_REMOTE_WAKEUP); | ||
| 1841 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1842 | |||
| 1843 | langwell_wakeup(&dev->gadget); | ||
| 1844 | |||
| 1845 | return rc; | ||
| 1846 | } | ||
| 1847 | static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup); | ||
| 1848 | |||
| 1849 | |||
| 1850 | /*-------------------------------------------------------------------------*/ | ||
| 1851 | |||
| 1852 | /* | ||
| 1853 | * when a driver is successfully registered, it will receive | ||
| 1854 | * control requests including set_configuration(), which enables | ||
| 1855 | * non-control requests. then usb traffic follows until a | ||
| 1856 | * disconnect is reported. then a host may connect again, or | ||
| 1857 | * the driver might get unbound. | ||
| 1858 | */ | ||
| 1859 | |||
| 1860 | static int langwell_start(struct usb_gadget_driver *driver, | ||
| 1861 | int (*bind)(struct usb_gadget *)) | ||
| 1862 | { | ||
| 1863 | struct langwell_udc *dev = the_controller; | ||
| 1864 | unsigned long flags; | ||
| 1865 | int retval; | ||
| 1866 | |||
| 1867 | if (!dev) | ||
| 1868 | return -ENODEV; | ||
| 1869 | |||
| 1870 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1871 | |||
| 1872 | if (dev->driver) | ||
| 1873 | return -EBUSY; | ||
| 1874 | |||
| 1875 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1876 | |||
| 1877 | /* hook up the driver ... */ | ||
| 1878 | driver->driver.bus = NULL; | ||
| 1879 | dev->driver = driver; | ||
| 1880 | dev->gadget.dev.driver = &driver->driver; | ||
| 1881 | |||
| 1882 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1883 | |||
| 1884 | retval = bind(&dev->gadget); | ||
| 1885 | if (retval) { | ||
| 1886 | dev_dbg(&dev->pdev->dev, "bind to driver %s --> %d\n", | ||
| 1887 | driver->driver.name, retval); | ||
| 1888 | dev->driver = NULL; | ||
| 1889 | dev->gadget.dev.driver = NULL; | ||
| 1890 | return retval; | ||
| 1891 | } | ||
| 1892 | |||
| 1893 | retval = device_create_file(&dev->pdev->dev, &dev_attr_function); | ||
| 1894 | if (retval) | ||
| 1895 | goto err_unbind; | ||
| 1896 | |||
| 1897 | dev->usb_state = USB_STATE_ATTACHED; | ||
| 1898 | dev->ep0_state = WAIT_FOR_SETUP; | ||
| 1899 | dev->ep0_dir = USB_DIR_OUT; | ||
| 1900 | |||
| 1901 | /* enable interrupt and set controller to run state */ | ||
| 1902 | if (dev->got_irq) | ||
| 1903 | langwell_udc_start(dev); | ||
| 1904 | |||
| 1905 | dev_vdbg(&dev->pdev->dev, | ||
| 1906 | "After langwell_udc_start(), print all registers:\n"); | ||
| 1907 | print_all_registers(dev); | ||
| 1908 | |||
| 1909 | dev_info(&dev->pdev->dev, "register driver: %s\n", | ||
| 1910 | driver->driver.name); | ||
| 1911 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1912 | return 0; | ||
| 1913 | |||
| 1914 | err_unbind: | ||
| 1915 | driver->unbind(&dev->gadget); | ||
| 1916 | dev->gadget.dev.driver = NULL; | ||
| 1917 | dev->driver = NULL; | ||
| 1918 | |||
| 1919 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1920 | return retval; | ||
| 1921 | } | ||
| 1922 | |||
| 1923 | /* unregister gadget driver */ | ||
| 1924 | static int langwell_stop(struct usb_gadget_driver *driver) | ||
| 1925 | { | ||
| 1926 | struct langwell_udc *dev = the_controller; | ||
| 1927 | unsigned long flags; | ||
| 1928 | |||
| 1929 | if (!dev) | ||
| 1930 | return -ENODEV; | ||
| 1931 | |||
| 1932 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1933 | |||
| 1934 | if (unlikely(!driver || !driver->unbind)) | ||
| 1935 | return -EINVAL; | ||
| 1936 | |||
| 1937 | /* exit PHY low power suspend */ | ||
| 1938 | if (dev->pdev->device != 0x0829) | ||
| 1939 | langwell_phy_low_power(dev, 0); | ||
| 1940 | |||
| 1941 | /* unbind OTG transceiver */ | ||
| 1942 | if (dev->transceiver) | ||
| 1943 | (void)otg_set_peripheral(dev->transceiver, 0); | ||
| 1944 | |||
| 1945 | /* disable interrupt and set controller to stop state */ | ||
| 1946 | langwell_udc_stop(dev); | ||
| 1947 | |||
| 1948 | dev->usb_state = USB_STATE_ATTACHED; | ||
| 1949 | dev->ep0_state = WAIT_FOR_SETUP; | ||
| 1950 | dev->ep0_dir = USB_DIR_OUT; | ||
| 1951 | |||
| 1952 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1953 | |||
| 1954 | /* stop all usb activities */ | ||
| 1955 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1956 | stop_activity(dev, driver); | ||
| 1957 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1958 | |||
| 1959 | /* unbind gadget driver */ | ||
| 1960 | driver->unbind(&dev->gadget); | ||
| 1961 | dev->gadget.dev.driver = NULL; | ||
| 1962 | dev->driver = NULL; | ||
| 1963 | |||
| 1964 | device_remove_file(&dev->pdev->dev, &dev_attr_function); | ||
| 1965 | |||
| 1966 | dev_info(&dev->pdev->dev, "unregistered driver '%s'\n", | ||
| 1967 | driver->driver.name); | ||
| 1968 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 1969 | return 0; | ||
| 1970 | } | ||
| 1971 | |||
| 1972 | /*-------------------------------------------------------------------------*/ | ||
| 1973 | |||
| 1974 | /* | ||
| 1975 | * setup tripwire is used as a semaphore to ensure that the setup data | ||
| 1976 | * payload is extracted from a dQH without being corrupted | ||
| 1977 | */ | ||
| 1978 | static void setup_tripwire(struct langwell_udc *dev) | ||
| 1979 | { | ||
| 1980 | u32 usbcmd, | ||
| 1981 | endptsetupstat; | ||
| 1982 | unsigned long timeout; | ||
| 1983 | struct langwell_dqh *dqh; | ||
| 1984 | |||
| 1985 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 1986 | |||
| 1987 | /* ep0 OUT dQH */ | ||
| 1988 | dqh = &dev->ep_dqh[EP_DIR_OUT]; | ||
| 1989 | |||
| 1990 | /* Write-Clear endptsetupstat */ | ||
| 1991 | endptsetupstat = readl(&dev->op_regs->endptsetupstat); | ||
| 1992 | writel(endptsetupstat, &dev->op_regs->endptsetupstat); | ||
| 1993 | |||
| 1994 | /* wait until endptsetupstat is cleared */ | ||
| 1995 | timeout = jiffies + SETUPSTAT_TIMEOUT; | ||
| 1996 | while (readl(&dev->op_regs->endptsetupstat)) { | ||
| 1997 | if (time_after(jiffies, timeout)) { | ||
| 1998 | dev_err(&dev->pdev->dev, "setup_tripwire timeout\n"); | ||
| 1999 | break; | ||
| 2000 | } | ||
| 2001 | cpu_relax(); | ||
| 2002 | } | ||
| 2003 | |||
| 2004 | /* while a hazard exists when setup packet arrives */ | ||
| 2005 | do { | ||
| 2006 | /* set setup tripwire bit */ | ||
| 2007 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 2008 | writel(usbcmd | CMD_SUTW, &dev->op_regs->usbcmd); | ||
| 2009 | |||
| 2010 | /* copy the setup packet to local buffer */ | ||
| 2011 | memcpy(&dev->local_setup_buff, &dqh->dqh_setup, 8); | ||
| 2012 | } while (!(readl(&dev->op_regs->usbcmd) & CMD_SUTW)); | ||
| 2013 | |||
| 2014 | /* Write-Clear setup tripwire bit */ | ||
| 2015 | usbcmd = readl(&dev->op_regs->usbcmd); | ||
| 2016 | writel(usbcmd & ~CMD_SUTW, &dev->op_regs->usbcmd); | ||
| 2017 | |||
| 2018 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2019 | } | ||
| 2020 | |||
| 2021 | |||
| 2022 | /* protocol ep0 stall, will automatically be cleared on new transaction */ | ||
| 2023 | static void ep0_stall(struct langwell_udc *dev) | ||
| 2024 | { | ||
| 2025 | u32 endptctrl; | ||
| 2026 | |||
| 2027 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2028 | |||
| 2029 | /* set TX and RX to stall */ | ||
| 2030 | endptctrl = readl(&dev->op_regs->endptctrl[0]); | ||
| 2031 | endptctrl |= EPCTRL_TXS | EPCTRL_RXS; | ||
| 2032 | writel(endptctrl, &dev->op_regs->endptctrl[0]); | ||
| 2033 | |||
| 2034 | /* update ep0 state */ | ||
| 2035 | dev->ep0_state = WAIT_FOR_SETUP; | ||
| 2036 | dev->ep0_dir = USB_DIR_OUT; | ||
| 2037 | |||
| 2038 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2039 | } | ||
| 2040 | |||
| 2041 | |||
| 2042 | /* PRIME a status phase for ep0 */ | ||
| 2043 | static int prime_status_phase(struct langwell_udc *dev, int dir) | ||
| 2044 | { | ||
| 2045 | struct langwell_request *req; | ||
| 2046 | struct langwell_ep *ep; | ||
| 2047 | int status = 0; | ||
| 2048 | |||
| 2049 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2050 | |||
| 2051 | if (dir == EP_DIR_IN) | ||
| 2052 | dev->ep0_dir = USB_DIR_IN; | ||
| 2053 | else | ||
| 2054 | dev->ep0_dir = USB_DIR_OUT; | ||
| 2055 | |||
| 2056 | ep = &dev->ep[0]; | ||
| 2057 | dev->ep0_state = WAIT_FOR_OUT_STATUS; | ||
| 2058 | |||
| 2059 | req = dev->status_req; | ||
| 2060 | |||
| 2061 | req->ep = ep; | ||
| 2062 | req->req.length = 0; | ||
| 2063 | req->req.status = -EINPROGRESS; | ||
| 2064 | req->req.actual = 0; | ||
| 2065 | req->req.complete = NULL; | ||
| 2066 | req->dtd_count = 0; | ||
| 2067 | |||
| 2068 | if (!req_to_dtd(req)) | ||
| 2069 | status = queue_dtd(ep, req); | ||
| 2070 | else | ||
| 2071 | return -ENOMEM; | ||
| 2072 | |||
| 2073 | if (status) | ||
| 2074 | dev_err(&dev->pdev->dev, "can't queue ep0 status request\n"); | ||
| 2075 | |||
| 2076 | list_add_tail(&req->queue, &ep->queue); | ||
| 2077 | |||
| 2078 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2079 | return status; | ||
| 2080 | } | ||
| 2081 | |||
| 2082 | |||
| 2083 | /* SET_ADDRESS request routine */ | ||
| 2084 | static void set_address(struct langwell_udc *dev, u16 value, | ||
| 2085 | u16 index, u16 length) | ||
| 2086 | { | ||
| 2087 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2088 | |||
| 2089 | /* save the new address to device struct */ | ||
| 2090 | dev->dev_addr = (u8) value; | ||
| 2091 | dev_vdbg(&dev->pdev->dev, "dev->dev_addr = %d\n", dev->dev_addr); | ||
| 2092 | |||
| 2093 | /* update usb state */ | ||
| 2094 | dev->usb_state = USB_STATE_ADDRESS; | ||
| 2095 | |||
| 2096 | /* STATUS phase */ | ||
| 2097 | if (prime_status_phase(dev, EP_DIR_IN)) | ||
| 2098 | ep0_stall(dev); | ||
| 2099 | |||
| 2100 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2101 | } | ||
| 2102 | |||
| 2103 | |||
| 2104 | /* return endpoint by windex */ | ||
| 2105 | static struct langwell_ep *get_ep_by_windex(struct langwell_udc *dev, | ||
| 2106 | u16 wIndex) | ||
| 2107 | { | ||
| 2108 | struct langwell_ep *ep; | ||
| 2109 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2110 | |||
| 2111 | if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0) | ||
| 2112 | return &dev->ep[0]; | ||
| 2113 | |||
| 2114 | list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) { | ||
| 2115 | u8 bEndpointAddress; | ||
| 2116 | if (!ep->desc) | ||
| 2117 | continue; | ||
| 2118 | |||
| 2119 | bEndpointAddress = ep->desc->bEndpointAddress; | ||
| 2120 | if ((wIndex ^ bEndpointAddress) & USB_DIR_IN) | ||
| 2121 | continue; | ||
| 2122 | |||
| 2123 | if ((wIndex & USB_ENDPOINT_NUMBER_MASK) | ||
| 2124 | == (bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) | ||
| 2125 | return ep; | ||
| 2126 | } | ||
| 2127 | |||
| 2128 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2129 | return NULL; | ||
| 2130 | } | ||
| 2131 | |||
| 2132 | |||
| 2133 | /* return whether endpoint is stalled, 0: not stalled; 1: stalled */ | ||
| 2134 | static int ep_is_stall(struct langwell_ep *ep) | ||
| 2135 | { | ||
| 2136 | struct langwell_udc *dev = ep->dev; | ||
| 2137 | u32 endptctrl; | ||
| 2138 | int retval; | ||
| 2139 | |||
| 2140 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2141 | |||
| 2142 | endptctrl = readl(&dev->op_regs->endptctrl[ep->ep_num]); | ||
| 2143 | if (is_in(ep)) | ||
| 2144 | retval = endptctrl & EPCTRL_TXS ? 1 : 0; | ||
| 2145 | else | ||
| 2146 | retval = endptctrl & EPCTRL_RXS ? 1 : 0; | ||
| 2147 | |||
| 2148 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2149 | return retval; | ||
| 2150 | } | ||
| 2151 | |||
| 2152 | |||
| 2153 | /* GET_STATUS request routine */ | ||
| 2154 | static void get_status(struct langwell_udc *dev, u8 request_type, u16 value, | ||
| 2155 | u16 index, u16 length) | ||
| 2156 | { | ||
| 2157 | struct langwell_request *req; | ||
| 2158 | struct langwell_ep *ep; | ||
| 2159 | u16 status_data = 0; /* 16 bits cpu view status data */ | ||
| 2160 | int status = 0; | ||
| 2161 | |||
| 2162 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2163 | |||
| 2164 | ep = &dev->ep[0]; | ||
| 2165 | |||
| 2166 | if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { | ||
| 2167 | /* get device status */ | ||
| 2168 | status_data = dev->dev_status; | ||
| 2169 | } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { | ||
| 2170 | /* get interface status */ | ||
| 2171 | status_data = 0; | ||
| 2172 | } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) { | ||
| 2173 | /* get endpoint status */ | ||
| 2174 | struct langwell_ep *epn; | ||
| 2175 | epn = get_ep_by_windex(dev, index); | ||
| 2176 | /* stall if endpoint doesn't exist */ | ||
| 2177 | if (!epn) | ||
| 2178 | goto stall; | ||
| 2179 | |||
| 2180 | status_data = ep_is_stall(epn) << USB_ENDPOINT_HALT; | ||
| 2181 | } | ||
| 2182 | |||
| 2183 | dev_dbg(&dev->pdev->dev, "get status data: 0x%04x\n", status_data); | ||
| 2184 | |||
| 2185 | dev->ep0_dir = USB_DIR_IN; | ||
| 2186 | |||
| 2187 | /* borrow the per device status_req */ | ||
| 2188 | req = dev->status_req; | ||
| 2189 | |||
| 2190 | /* fill in the reqest structure */ | ||
| 2191 | *((u16 *) req->req.buf) = cpu_to_le16(status_data); | ||
| 2192 | req->ep = ep; | ||
| 2193 | req->req.length = 2; | ||
| 2194 | req->req.status = -EINPROGRESS; | ||
| 2195 | req->req.actual = 0; | ||
| 2196 | req->req.complete = NULL; | ||
| 2197 | req->dtd_count = 0; | ||
| 2198 | |||
| 2199 | /* prime the data phase */ | ||
| 2200 | if (!req_to_dtd(req)) | ||
| 2201 | status = queue_dtd(ep, req); | ||
| 2202 | else /* no mem */ | ||
| 2203 | goto stall; | ||
| 2204 | |||
| 2205 | if (status) { | ||
| 2206 | dev_err(&dev->pdev->dev, | ||
| 2207 | "response error on GET_STATUS request\n"); | ||
| 2208 | goto stall; | ||
| 2209 | } | ||
| 2210 | |||
| 2211 | list_add_tail(&req->queue, &ep->queue); | ||
| 2212 | dev->ep0_state = DATA_STATE_XMIT; | ||
| 2213 | |||
| 2214 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2215 | return; | ||
| 2216 | stall: | ||
| 2217 | ep0_stall(dev); | ||
| 2218 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2219 | } | ||
| 2220 | |||
| 2221 | |||
| 2222 | /* setup packet interrupt handler */ | ||
| 2223 | static void handle_setup_packet(struct langwell_udc *dev, | ||
| 2224 | struct usb_ctrlrequest *setup) | ||
| 2225 | { | ||
| 2226 | u16 wValue = le16_to_cpu(setup->wValue); | ||
| 2227 | u16 wIndex = le16_to_cpu(setup->wIndex); | ||
| 2228 | u16 wLength = le16_to_cpu(setup->wLength); | ||
| 2229 | u32 portsc1; | ||
| 2230 | |||
| 2231 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2232 | |||
| 2233 | /* ep0 fifo flush */ | ||
| 2234 | nuke(&dev->ep[0], -ESHUTDOWN); | ||
| 2235 | |||
| 2236 | dev_dbg(&dev->pdev->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n", | ||
| 2237 | setup->bRequestType, setup->bRequest, | ||
| 2238 | wValue, wIndex, wLength); | ||
| 2239 | |||
| 2240 | /* RNDIS gadget delegate */ | ||
| 2241 | if ((setup->bRequestType == 0x21) && (setup->bRequest == 0x00)) { | ||
| 2242 | /* USB_CDC_SEND_ENCAPSULATED_COMMAND */ | ||
| 2243 | goto delegate; | ||
| 2244 | } | ||
| 2245 | |||
| 2246 | /* USB_CDC_GET_ENCAPSULATED_RESPONSE */ | ||
| 2247 | if ((setup->bRequestType == 0xa1) && (setup->bRequest == 0x01)) { | ||
| 2248 | /* USB_CDC_GET_ENCAPSULATED_RESPONSE */ | ||
| 2249 | goto delegate; | ||
| 2250 | } | ||
| 2251 | |||
| 2252 | /* We process some stardard setup requests here */ | ||
| 2253 | switch (setup->bRequest) { | ||
| 2254 | case USB_REQ_GET_STATUS: | ||
| 2255 | dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_GET_STATUS\n"); | ||
| 2256 | /* get status, DATA and STATUS phase */ | ||
| 2257 | if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) | ||
| 2258 | != (USB_DIR_IN | USB_TYPE_STANDARD)) | ||
| 2259 | break; | ||
| 2260 | get_status(dev, setup->bRequestType, wValue, wIndex, wLength); | ||
| 2261 | goto end; | ||
| 2262 | |||
| 2263 | case USB_REQ_SET_ADDRESS: | ||
| 2264 | dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_SET_ADDRESS\n"); | ||
| 2265 | /* STATUS phase */ | ||
| 2266 | if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | ||
| 2267 | | USB_RECIP_DEVICE)) | ||
| 2268 | break; | ||
| 2269 | set_address(dev, wValue, wIndex, wLength); | ||
| 2270 | goto end; | ||
| 2271 | |||
| 2272 | case USB_REQ_CLEAR_FEATURE: | ||
| 2273 | case USB_REQ_SET_FEATURE: | ||
| 2274 | /* STATUS phase */ | ||
| 2275 | { | ||
| 2276 | int rc = -EOPNOTSUPP; | ||
| 2277 | if (setup->bRequest == USB_REQ_SET_FEATURE) | ||
| 2278 | dev_dbg(&dev->pdev->dev, | ||
| 2279 | "SETUP: USB_REQ_SET_FEATURE\n"); | ||
| 2280 | else if (setup->bRequest == USB_REQ_CLEAR_FEATURE) | ||
| 2281 | dev_dbg(&dev->pdev->dev, | ||
| 2282 | "SETUP: USB_REQ_CLEAR_FEATURE\n"); | ||
| 2283 | |||
| 2284 | if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) | ||
| 2285 | == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { | ||
| 2286 | struct langwell_ep *epn; | ||
| 2287 | epn = get_ep_by_windex(dev, wIndex); | ||
| 2288 | /* stall if endpoint doesn't exist */ | ||
| 2289 | if (!epn) { | ||
| 2290 | ep0_stall(dev); | ||
| 2291 | goto end; | ||
| 2292 | } | ||
| 2293 | |||
| 2294 | if (wValue != 0 || wLength != 0 | ||
| 2295 | || epn->ep_num > dev->ep_max) | ||
| 2296 | break; | ||
| 2297 | |||
| 2298 | spin_unlock(&dev->lock); | ||
| 2299 | rc = langwell_ep_set_halt(&epn->ep, | ||
| 2300 | (setup->bRequest == USB_REQ_SET_FEATURE) | ||
| 2301 | ? 1 : 0); | ||
| 2302 | spin_lock(&dev->lock); | ||
| 2303 | |||
| 2304 | } else if ((setup->bRequestType & (USB_RECIP_MASK | ||
| 2305 | | USB_TYPE_MASK)) == (USB_RECIP_DEVICE | ||
| 2306 | | USB_TYPE_STANDARD)) { | ||
| 2307 | rc = 0; | ||
| 2308 | switch (wValue) { | ||
| 2309 | case USB_DEVICE_REMOTE_WAKEUP: | ||
| 2310 | if (setup->bRequest == USB_REQ_SET_FEATURE) { | ||
| 2311 | dev->remote_wakeup = 1; | ||
| 2312 | dev->dev_status |= (1 << wValue); | ||
| 2313 | } else { | ||
| 2314 | dev->remote_wakeup = 0; | ||
| 2315 | dev->dev_status &= ~(1 << wValue); | ||
| 2316 | } | ||
| 2317 | break; | ||
| 2318 | case USB_DEVICE_TEST_MODE: | ||
| 2319 | dev_dbg(&dev->pdev->dev, "SETUP: TEST MODE\n"); | ||
| 2320 | if ((wIndex & 0xff) || | ||
| 2321 | (dev->gadget.speed != USB_SPEED_HIGH)) | ||
| 2322 | ep0_stall(dev); | ||
| 2323 | |||
| 2324 | switch (wIndex >> 8) { | ||
| 2325 | case TEST_J: | ||
| 2326 | case TEST_K: | ||
| 2327 | case TEST_SE0_NAK: | ||
| 2328 | case TEST_PACKET: | ||
| 2329 | case TEST_FORCE_EN: | ||
| 2330 | if (prime_status_phase(dev, EP_DIR_IN)) | ||
| 2331 | ep0_stall(dev); | ||
| 2332 | portsc1 = readl(&dev->op_regs->portsc1); | ||
| 2333 | portsc1 |= (wIndex & 0xf00) << 8; | ||
| 2334 | writel(portsc1, &dev->op_regs->portsc1); | ||
| 2335 | goto end; | ||
| 2336 | default: | ||
| 2337 | rc = -EOPNOTSUPP; | ||
| 2338 | } | ||
| 2339 | break; | ||
| 2340 | default: | ||
| 2341 | rc = -EOPNOTSUPP; | ||
| 2342 | break; | ||
| 2343 | } | ||
| 2344 | |||
| 2345 | if (!gadget_is_otg(&dev->gadget)) | ||
| 2346 | break; | ||
| 2347 | else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) { | ||
| 2348 | dev->gadget.b_hnp_enable = 1; | ||
| 2349 | #ifdef OTG_TRANSCEIVER | ||
| 2350 | if (!dev->lotg->otg.default_a) | ||
| 2351 | dev->lotg->hsm.b_hnp_enable = 1; | ||
| 2352 | #endif | ||
| 2353 | } else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT) | ||
| 2354 | dev->gadget.a_hnp_support = 1; | ||
| 2355 | else if (setup->bRequest == | ||
| 2356 | USB_DEVICE_A_ALT_HNP_SUPPORT) | ||
| 2357 | dev->gadget.a_alt_hnp_support = 1; | ||
| 2358 | else | ||
| 2359 | break; | ||
| 2360 | } else | ||
| 2361 | break; | ||
| 2362 | |||
| 2363 | if (rc == 0) { | ||
| 2364 | if (prime_status_phase(dev, EP_DIR_IN)) | ||
| 2365 | ep0_stall(dev); | ||
| 2366 | } | ||
| 2367 | goto end; | ||
| 2368 | } | ||
| 2369 | |||
| 2370 | case USB_REQ_GET_DESCRIPTOR: | ||
| 2371 | dev_dbg(&dev->pdev->dev, | ||
| 2372 | "SETUP: USB_REQ_GET_DESCRIPTOR\n"); | ||
| 2373 | goto delegate; | ||
| 2374 | |||
| 2375 | case USB_REQ_SET_DESCRIPTOR: | ||
| 2376 | dev_dbg(&dev->pdev->dev, | ||
| 2377 | "SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n"); | ||
| 2378 | goto delegate; | ||
| 2379 | |||
| 2380 | case USB_REQ_GET_CONFIGURATION: | ||
| 2381 | dev_dbg(&dev->pdev->dev, | ||
| 2382 | "SETUP: USB_REQ_GET_CONFIGURATION\n"); | ||
| 2383 | goto delegate; | ||
| 2384 | |||
| 2385 | case USB_REQ_SET_CONFIGURATION: | ||
| 2386 | dev_dbg(&dev->pdev->dev, | ||
| 2387 | "SETUP: USB_REQ_SET_CONFIGURATION\n"); | ||
| 2388 | goto delegate; | ||
| 2389 | |||
| 2390 | case USB_REQ_GET_INTERFACE: | ||
| 2391 | dev_dbg(&dev->pdev->dev, | ||
| 2392 | "SETUP: USB_REQ_GET_INTERFACE\n"); | ||
| 2393 | goto delegate; | ||
| 2394 | |||
| 2395 | case USB_REQ_SET_INTERFACE: | ||
| 2396 | dev_dbg(&dev->pdev->dev, | ||
| 2397 | "SETUP: USB_REQ_SET_INTERFACE\n"); | ||
| 2398 | goto delegate; | ||
| 2399 | |||
| 2400 | case USB_REQ_SYNCH_FRAME: | ||
| 2401 | dev_dbg(&dev->pdev->dev, | ||
| 2402 | "SETUP: USB_REQ_SYNCH_FRAME unsupported\n"); | ||
| 2403 | goto delegate; | ||
| 2404 | |||
| 2405 | default: | ||
| 2406 | /* delegate USB standard requests to the gadget driver */ | ||
| 2407 | goto delegate; | ||
| 2408 | delegate: | ||
| 2409 | /* USB requests handled by gadget */ | ||
| 2410 | if (wLength) { | ||
| 2411 | /* DATA phase from gadget, STATUS phase from udc */ | ||
| 2412 | dev->ep0_dir = (setup->bRequestType & USB_DIR_IN) | ||
| 2413 | ? USB_DIR_IN : USB_DIR_OUT; | ||
| 2414 | dev_vdbg(&dev->pdev->dev, | ||
| 2415 | "dev->ep0_dir = 0x%x, wLength = %d\n", | ||
| 2416 | dev->ep0_dir, wLength); | ||
| 2417 | spin_unlock(&dev->lock); | ||
| 2418 | if (dev->driver->setup(&dev->gadget, | ||
| 2419 | &dev->local_setup_buff) < 0) | ||
| 2420 | ep0_stall(dev); | ||
| 2421 | spin_lock(&dev->lock); | ||
| 2422 | dev->ep0_state = (setup->bRequestType & USB_DIR_IN) | ||
| 2423 | ? DATA_STATE_XMIT : DATA_STATE_RECV; | ||
| 2424 | } else { | ||
| 2425 | /* no DATA phase, IN STATUS phase from gadget */ | ||
| 2426 | dev->ep0_dir = USB_DIR_IN; | ||
| 2427 | dev_vdbg(&dev->pdev->dev, | ||
| 2428 | "dev->ep0_dir = 0x%x, wLength = %d\n", | ||
| 2429 | dev->ep0_dir, wLength); | ||
| 2430 | spin_unlock(&dev->lock); | ||
| 2431 | if (dev->driver->setup(&dev->gadget, | ||
| 2432 | &dev->local_setup_buff) < 0) | ||
| 2433 | ep0_stall(dev); | ||
| 2434 | spin_lock(&dev->lock); | ||
| 2435 | dev->ep0_state = WAIT_FOR_OUT_STATUS; | ||
| 2436 | } | ||
| 2437 | break; | ||
| 2438 | } | ||
| 2439 | end: | ||
| 2440 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2441 | } | ||
| 2442 | |||
| 2443 | |||
| 2444 | /* transfer completion, process endpoint request and free the completed dTDs | ||
| 2445 | * for this request | ||
| 2446 | */ | ||
| 2447 | static int process_ep_req(struct langwell_udc *dev, int index, | ||
| 2448 | struct langwell_request *curr_req) | ||
| 2449 | { | ||
| 2450 | struct langwell_dtd *curr_dtd; | ||
| 2451 | struct langwell_dqh *curr_dqh; | ||
| 2452 | int td_complete, actual, remaining_length; | ||
| 2453 | int i, dir; | ||
| 2454 | u8 dtd_status = 0; | ||
| 2455 | int retval = 0; | ||
| 2456 | |||
| 2457 | curr_dqh = &dev->ep_dqh[index]; | ||
| 2458 | dir = index % 2; | ||
| 2459 | |||
| 2460 | curr_dtd = curr_req->head; | ||
| 2461 | td_complete = 0; | ||
| 2462 | actual = curr_req->req.length; | ||
| 2463 | |||
| 2464 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2465 | |||
| 2466 | for (i = 0; i < curr_req->dtd_count; i++) { | ||
| 2467 | |||
| 2468 | /* command execution states by dTD */ | ||
| 2469 | dtd_status = curr_dtd->dtd_status; | ||
| 2470 | |||
| 2471 | barrier(); | ||
| 2472 | remaining_length = le16_to_cpu(curr_dtd->dtd_total); | ||
| 2473 | actual -= remaining_length; | ||
| 2474 | |||
| 2475 | if (!dtd_status) { | ||
| 2476 | /* transfers completed successfully */ | ||
| 2477 | if (!remaining_length) { | ||
| 2478 | td_complete++; | ||
| 2479 | dev_vdbg(&dev->pdev->dev, | ||
| 2480 | "dTD transmitted successfully\n"); | ||
| 2481 | } else { | ||
| 2482 | if (dir) { | ||
| 2483 | dev_vdbg(&dev->pdev->dev, | ||
| 2484 | "TX dTD remains data\n"); | ||
| 2485 | retval = -EPROTO; | ||
| 2486 | break; | ||
| 2487 | |||
| 2488 | } else { | ||
| 2489 | td_complete++; | ||
| 2490 | break; | ||
| 2491 | } | ||
| 2492 | } | ||
| 2493 | } else { | ||
| 2494 | /* transfers completed with errors */ | ||
| 2495 | if (dtd_status & DTD_STS_ACTIVE) { | ||
| 2496 | dev_dbg(&dev->pdev->dev, | ||
| 2497 | "dTD status ACTIVE dQH[%d]\n", index); | ||
| 2498 | retval = 1; | ||
| 2499 | return retval; | ||
| 2500 | } else if (dtd_status & DTD_STS_HALTED) { | ||
| 2501 | dev_err(&dev->pdev->dev, | ||
| 2502 | "dTD error %08x dQH[%d]\n", | ||
| 2503 | dtd_status, index); | ||
| 2504 | /* clear the errors and halt condition */ | ||
| 2505 | curr_dqh->dtd_status = 0; | ||
| 2506 | retval = -EPIPE; | ||
| 2507 | break; | ||
| 2508 | } else if (dtd_status & DTD_STS_DBE) { | ||
| 2509 | dev_dbg(&dev->pdev->dev, | ||
| 2510 | "data buffer (overflow) error\n"); | ||
| 2511 | retval = -EPROTO; | ||
| 2512 | break; | ||
| 2513 | } else if (dtd_status & DTD_STS_TRE) { | ||
| 2514 | dev_dbg(&dev->pdev->dev, | ||
| 2515 | "transaction(ISO) error\n"); | ||
| 2516 | retval = -EILSEQ; | ||
| 2517 | break; | ||
| 2518 | } else | ||
| 2519 | dev_err(&dev->pdev->dev, | ||
| 2520 | "unknown error (0x%x)!\n", | ||
| 2521 | dtd_status); | ||
| 2522 | } | ||
| 2523 | |||
| 2524 | if (i != curr_req->dtd_count - 1) | ||
| 2525 | curr_dtd = (struct langwell_dtd *) | ||
| 2526 | curr_dtd->next_dtd_virt; | ||
| 2527 | } | ||
| 2528 | |||
| 2529 | if (retval) | ||
| 2530 | return retval; | ||
| 2531 | |||
| 2532 | curr_req->req.actual = actual; | ||
| 2533 | |||
| 2534 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2535 | return 0; | ||
| 2536 | } | ||
| 2537 | |||
| 2538 | |||
| 2539 | /* complete DATA or STATUS phase of ep0 prime status phase if needed */ | ||
| 2540 | static void ep0_req_complete(struct langwell_udc *dev, | ||
| 2541 | struct langwell_ep *ep0, struct langwell_request *req) | ||
| 2542 | { | ||
| 2543 | u32 new_addr; | ||
| 2544 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2545 | |||
| 2546 | if (dev->usb_state == USB_STATE_ADDRESS) { | ||
| 2547 | /* set the new address */ | ||
| 2548 | new_addr = (u32)dev->dev_addr; | ||
| 2549 | writel(new_addr << USBADR_SHIFT, &dev->op_regs->deviceaddr); | ||
| 2550 | |||
| 2551 | new_addr = USBADR(readl(&dev->op_regs->deviceaddr)); | ||
| 2552 | dev_vdbg(&dev->pdev->dev, "new_addr = %d\n", new_addr); | ||
| 2553 | } | ||
| 2554 | |||
| 2555 | done(ep0, req, 0); | ||
| 2556 | |||
| 2557 | switch (dev->ep0_state) { | ||
| 2558 | case DATA_STATE_XMIT: | ||
| 2559 | /* receive status phase */ | ||
| 2560 | if (prime_status_phase(dev, EP_DIR_OUT)) | ||
| 2561 | ep0_stall(dev); | ||
| 2562 | break; | ||
| 2563 | case DATA_STATE_RECV: | ||
| 2564 | /* send status phase */ | ||
| 2565 | if (prime_status_phase(dev, EP_DIR_IN)) | ||
| 2566 | ep0_stall(dev); | ||
| 2567 | break; | ||
| 2568 | case WAIT_FOR_OUT_STATUS: | ||
| 2569 | dev->ep0_state = WAIT_FOR_SETUP; | ||
| 2570 | break; | ||
| 2571 | case WAIT_FOR_SETUP: | ||
| 2572 | dev_err(&dev->pdev->dev, "unexpect ep0 packets\n"); | ||
| 2573 | break; | ||
| 2574 | default: | ||
| 2575 | ep0_stall(dev); | ||
| 2576 | break; | ||
| 2577 | } | ||
| 2578 | |||
| 2579 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2580 | } | ||
| 2581 | |||
| 2582 | |||
| 2583 | /* USB transfer completion interrupt */ | ||
| 2584 | static void handle_trans_complete(struct langwell_udc *dev) | ||
| 2585 | { | ||
| 2586 | u32 complete_bits; | ||
| 2587 | int i, ep_num, dir, bit_mask, status; | ||
| 2588 | struct langwell_ep *epn; | ||
| 2589 | struct langwell_request *curr_req, *temp_req; | ||
| 2590 | |||
| 2591 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2592 | |||
| 2593 | complete_bits = readl(&dev->op_regs->endptcomplete); | ||
| 2594 | dev_vdbg(&dev->pdev->dev, "endptcomplete register: 0x%08x\n", | ||
| 2595 | complete_bits); | ||
| 2596 | |||
| 2597 | /* Write-Clear the bits in endptcomplete register */ | ||
| 2598 | writel(complete_bits, &dev->op_regs->endptcomplete); | ||
| 2599 | |||
| 2600 | if (!complete_bits) { | ||
| 2601 | dev_dbg(&dev->pdev->dev, "complete_bits = 0\n"); | ||
| 2602 | goto done; | ||
| 2603 | } | ||
| 2604 | |||
| 2605 | for (i = 0; i < dev->ep_max; i++) { | ||
| 2606 | ep_num = i / 2; | ||
| 2607 | dir = i % 2; | ||
| 2608 | |||
| 2609 | bit_mask = 1 << (ep_num + 16 * dir); | ||
| 2610 | |||
| 2611 | if (!(complete_bits & bit_mask)) | ||
| 2612 | continue; | ||
| 2613 | |||
| 2614 | /* ep0 */ | ||
| 2615 | if (i == 1) | ||
| 2616 | epn = &dev->ep[0]; | ||
| 2617 | else | ||
| 2618 | epn = &dev->ep[i]; | ||
| 2619 | |||
| 2620 | if (epn->name == NULL) { | ||
| 2621 | dev_warn(&dev->pdev->dev, "invalid endpoint\n"); | ||
| 2622 | continue; | ||
| 2623 | } | ||
| 2624 | |||
| 2625 | if (i < 2) | ||
| 2626 | /* ep0 in and out */ | ||
| 2627 | dev_dbg(&dev->pdev->dev, "%s-%s transfer completed\n", | ||
| 2628 | epn->name, | ||
| 2629 | is_in(epn) ? "in" : "out"); | ||
| 2630 | else | ||
| 2631 | dev_dbg(&dev->pdev->dev, "%s transfer completed\n", | ||
| 2632 | epn->name); | ||
| 2633 | |||
| 2634 | /* process the req queue until an uncomplete request */ | ||
| 2635 | list_for_each_entry_safe(curr_req, temp_req, | ||
| 2636 | &epn->queue, queue) { | ||
| 2637 | status = process_ep_req(dev, i, curr_req); | ||
| 2638 | dev_vdbg(&dev->pdev->dev, "%s req status: %d\n", | ||
| 2639 | epn->name, status); | ||
| 2640 | |||
| 2641 | if (status) | ||
| 2642 | break; | ||
| 2643 | |||
| 2644 | /* write back status to req */ | ||
| 2645 | curr_req->req.status = status; | ||
| 2646 | |||
| 2647 | /* ep0 request completion */ | ||
| 2648 | if (ep_num == 0) { | ||
| 2649 | ep0_req_complete(dev, epn, curr_req); | ||
| 2650 | break; | ||
| 2651 | } else { | ||
| 2652 | done(epn, curr_req, status); | ||
| 2653 | } | ||
| 2654 | } | ||
| 2655 | } | ||
| 2656 | done: | ||
| 2657 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2658 | } | ||
| 2659 | |||
| 2660 | |||
| 2661 | /* port change detect interrupt handler */ | ||
| 2662 | static void handle_port_change(struct langwell_udc *dev) | ||
| 2663 | { | ||
| 2664 | u32 portsc1, devlc; | ||
| 2665 | u32 speed; | ||
| 2666 | |||
| 2667 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2668 | |||
| 2669 | if (dev->bus_reset) | ||
| 2670 | dev->bus_reset = 0; | ||
| 2671 | |||
| 2672 | portsc1 = readl(&dev->op_regs->portsc1); | ||
| 2673 | devlc = readl(&dev->op_regs->devlc); | ||
| 2674 | dev_vdbg(&dev->pdev->dev, "portsc1 = 0x%08x, devlc = 0x%08x\n", | ||
| 2675 | portsc1, devlc); | ||
| 2676 | |||
| 2677 | /* bus reset is finished */ | ||
| 2678 | if (!(portsc1 & PORTS_PR)) { | ||
| 2679 | /* get the speed */ | ||
| 2680 | speed = LPM_PSPD(devlc); | ||
| 2681 | switch (speed) { | ||
| 2682 | case LPM_SPEED_HIGH: | ||
| 2683 | dev->gadget.speed = USB_SPEED_HIGH; | ||
| 2684 | break; | ||
| 2685 | case LPM_SPEED_FULL: | ||
| 2686 | dev->gadget.speed = USB_SPEED_FULL; | ||
| 2687 | break; | ||
| 2688 | case LPM_SPEED_LOW: | ||
| 2689 | dev->gadget.speed = USB_SPEED_LOW; | ||
| 2690 | break; | ||
| 2691 | default: | ||
| 2692 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 2693 | break; | ||
| 2694 | } | ||
| 2695 | dev_vdbg(&dev->pdev->dev, | ||
| 2696 | "speed = %d, dev->gadget.speed = %d\n", | ||
| 2697 | speed, dev->gadget.speed); | ||
| 2698 | } | ||
| 2699 | |||
| 2700 | /* LPM L0 to L1 */ | ||
| 2701 | if (dev->lpm && dev->lpm_state == LPM_L0) | ||
| 2702 | if (portsc1 & PORTS_SUSP && portsc1 & PORTS_SLP) { | ||
| 2703 | dev_info(&dev->pdev->dev, "LPM L0 to L1\n"); | ||
| 2704 | dev->lpm_state = LPM_L1; | ||
| 2705 | } | ||
| 2706 | |||
| 2707 | /* LPM L1 to L0, force resume or remote wakeup finished */ | ||
| 2708 | if (dev->lpm && dev->lpm_state == LPM_L1) | ||
| 2709 | if (!(portsc1 & PORTS_SUSP)) { | ||
| 2710 | dev_info(&dev->pdev->dev, "LPM L1 to L0\n"); | ||
| 2711 | dev->lpm_state = LPM_L0; | ||
| 2712 | } | ||
| 2713 | |||
| 2714 | /* update USB state */ | ||
| 2715 | if (!dev->resume_state) | ||
| 2716 | dev->usb_state = USB_STATE_DEFAULT; | ||
| 2717 | |||
| 2718 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2719 | } | ||
| 2720 | |||
| 2721 | |||
| 2722 | /* USB reset interrupt handler */ | ||
| 2723 | static void handle_usb_reset(struct langwell_udc *dev) | ||
| 2724 | { | ||
| 2725 | u32 deviceaddr, | ||
| 2726 | endptsetupstat, | ||
| 2727 | endptcomplete; | ||
| 2728 | unsigned long timeout; | ||
| 2729 | |||
| 2730 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2731 | |||
| 2732 | /* Write-Clear the device address */ | ||
| 2733 | deviceaddr = readl(&dev->op_regs->deviceaddr); | ||
| 2734 | writel(deviceaddr & ~USBADR_MASK, &dev->op_regs->deviceaddr); | ||
| 2735 | |||
| 2736 | dev->dev_addr = 0; | ||
| 2737 | |||
| 2738 | /* clear usb state */ | ||
| 2739 | dev->resume_state = 0; | ||
| 2740 | |||
| 2741 | /* LPM L1 to L0, reset */ | ||
| 2742 | if (dev->lpm) | ||
| 2743 | dev->lpm_state = LPM_L0; | ||
| 2744 | |||
| 2745 | dev->ep0_dir = USB_DIR_OUT; | ||
| 2746 | dev->ep0_state = WAIT_FOR_SETUP; | ||
| 2747 | |||
| 2748 | /* remote wakeup reset to 0 when the device is reset */ | ||
| 2749 | dev->remote_wakeup = 0; | ||
| 2750 | dev->dev_status = 1 << USB_DEVICE_SELF_POWERED; | ||
| 2751 | dev->gadget.b_hnp_enable = 0; | ||
| 2752 | dev->gadget.a_hnp_support = 0; | ||
| 2753 | dev->gadget.a_alt_hnp_support = 0; | ||
| 2754 | |||
| 2755 | /* Write-Clear all the setup token semaphores */ | ||
| 2756 | endptsetupstat = readl(&dev->op_regs->endptsetupstat); | ||
| 2757 | writel(endptsetupstat, &dev->op_regs->endptsetupstat); | ||
| 2758 | |||
| 2759 | /* Write-Clear all the endpoint complete status bits */ | ||
| 2760 | endptcomplete = readl(&dev->op_regs->endptcomplete); | ||
| 2761 | writel(endptcomplete, &dev->op_regs->endptcomplete); | ||
| 2762 | |||
| 2763 | /* wait until all endptprime bits cleared */ | ||
| 2764 | timeout = jiffies + PRIME_TIMEOUT; | ||
| 2765 | while (readl(&dev->op_regs->endptprime)) { | ||
| 2766 | if (time_after(jiffies, timeout)) { | ||
| 2767 | dev_err(&dev->pdev->dev, "USB reset timeout\n"); | ||
| 2768 | break; | ||
| 2769 | } | ||
| 2770 | cpu_relax(); | ||
| 2771 | } | ||
| 2772 | |||
| 2773 | /* write 1s to endptflush register to clear any primed buffers */ | ||
| 2774 | writel((u32) ~0, &dev->op_regs->endptflush); | ||
| 2775 | |||
| 2776 | if (readl(&dev->op_regs->portsc1) & PORTS_PR) { | ||
| 2777 | dev_vdbg(&dev->pdev->dev, "USB bus reset\n"); | ||
| 2778 | /* bus is reseting */ | ||
| 2779 | dev->bus_reset = 1; | ||
| 2780 | |||
| 2781 | /* reset all the queues, stop all USB activities */ | ||
| 2782 | stop_activity(dev, dev->driver); | ||
| 2783 | dev->usb_state = USB_STATE_DEFAULT; | ||
| 2784 | } else { | ||
| 2785 | dev_vdbg(&dev->pdev->dev, "device controller reset\n"); | ||
| 2786 | /* controller reset */ | ||
| 2787 | langwell_udc_reset(dev); | ||
| 2788 | |||
| 2789 | /* reset all the queues, stop all USB activities */ | ||
| 2790 | stop_activity(dev, dev->driver); | ||
| 2791 | |||
| 2792 | /* reset ep0 dQH and endptctrl */ | ||
| 2793 | ep0_reset(dev); | ||
| 2794 | |||
| 2795 | /* enable interrupt and set controller to run state */ | ||
| 2796 | langwell_udc_start(dev); | ||
| 2797 | |||
| 2798 | dev->usb_state = USB_STATE_ATTACHED; | ||
| 2799 | } | ||
| 2800 | |||
| 2801 | #ifdef OTG_TRANSCEIVER | ||
| 2802 | /* refer to USB OTG 6.6.2.3 b_hnp_en is cleared */ | ||
| 2803 | if (!dev->lotg->otg.default_a) | ||
| 2804 | dev->lotg->hsm.b_hnp_enable = 0; | ||
| 2805 | #endif | ||
| 2806 | |||
| 2807 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2808 | } | ||
| 2809 | |||
| 2810 | |||
| 2811 | /* USB bus suspend/resume interrupt */ | ||
| 2812 | static void handle_bus_suspend(struct langwell_udc *dev) | ||
| 2813 | { | ||
| 2814 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2815 | |||
| 2816 | dev->resume_state = dev->usb_state; | ||
| 2817 | dev->usb_state = USB_STATE_SUSPENDED; | ||
| 2818 | |||
| 2819 | #ifdef OTG_TRANSCEIVER | ||
| 2820 | if (dev->lotg->otg.default_a) { | ||
| 2821 | if (dev->lotg->hsm.b_bus_suspend_vld == 1) { | ||
| 2822 | dev->lotg->hsm.b_bus_suspend = 1; | ||
| 2823 | /* notify transceiver the state changes */ | ||
| 2824 | if (spin_trylock(&dev->lotg->wq_lock)) { | ||
| 2825 | langwell_update_transceiver(); | ||
| 2826 | spin_unlock(&dev->lotg->wq_lock); | ||
| 2827 | } | ||
| 2828 | } | ||
| 2829 | dev->lotg->hsm.b_bus_suspend_vld++; | ||
| 2830 | } else { | ||
| 2831 | if (!dev->lotg->hsm.a_bus_suspend) { | ||
| 2832 | dev->lotg->hsm.a_bus_suspend = 1; | ||
| 2833 | /* notify transceiver the state changes */ | ||
| 2834 | if (spin_trylock(&dev->lotg->wq_lock)) { | ||
| 2835 | langwell_update_transceiver(); | ||
| 2836 | spin_unlock(&dev->lotg->wq_lock); | ||
| 2837 | } | ||
| 2838 | } | ||
| 2839 | } | ||
| 2840 | #endif | ||
| 2841 | |||
| 2842 | /* report suspend to the driver */ | ||
| 2843 | if (dev->driver) { | ||
| 2844 | if (dev->driver->suspend) { | ||
| 2845 | spin_unlock(&dev->lock); | ||
| 2846 | dev->driver->suspend(&dev->gadget); | ||
| 2847 | spin_lock(&dev->lock); | ||
| 2848 | dev_dbg(&dev->pdev->dev, "suspend %s\n", | ||
| 2849 | dev->driver->driver.name); | ||
| 2850 | } | ||
| 2851 | } | ||
| 2852 | |||
| 2853 | /* enter PHY low power suspend */ | ||
| 2854 | if (dev->pdev->device != 0x0829) | ||
| 2855 | langwell_phy_low_power(dev, 0); | ||
| 2856 | |||
| 2857 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2858 | } | ||
| 2859 | |||
| 2860 | |||
| 2861 | static void handle_bus_resume(struct langwell_udc *dev) | ||
| 2862 | { | ||
| 2863 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2864 | |||
| 2865 | dev->usb_state = dev->resume_state; | ||
| 2866 | dev->resume_state = 0; | ||
| 2867 | |||
| 2868 | /* exit PHY low power suspend */ | ||
| 2869 | if (dev->pdev->device != 0x0829) | ||
| 2870 | langwell_phy_low_power(dev, 0); | ||
| 2871 | |||
| 2872 | #ifdef OTG_TRANSCEIVER | ||
| 2873 | if (dev->lotg->otg.default_a == 0) | ||
| 2874 | dev->lotg->hsm.a_bus_suspend = 0; | ||
| 2875 | #endif | ||
| 2876 | |||
| 2877 | /* report resume to the driver */ | ||
| 2878 | if (dev->driver) { | ||
| 2879 | if (dev->driver->resume) { | ||
| 2880 | spin_unlock(&dev->lock); | ||
| 2881 | dev->driver->resume(&dev->gadget); | ||
| 2882 | spin_lock(&dev->lock); | ||
| 2883 | dev_dbg(&dev->pdev->dev, "resume %s\n", | ||
| 2884 | dev->driver->driver.name); | ||
| 2885 | } | ||
| 2886 | } | ||
| 2887 | |||
| 2888 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2889 | } | ||
| 2890 | |||
| 2891 | |||
| 2892 | /* USB device controller interrupt handler */ | ||
| 2893 | static irqreturn_t langwell_irq(int irq, void *_dev) | ||
| 2894 | { | ||
| 2895 | struct langwell_udc *dev = _dev; | ||
| 2896 | u32 usbsts, | ||
| 2897 | usbintr, | ||
| 2898 | irq_sts, | ||
| 2899 | portsc1; | ||
| 2900 | |||
| 2901 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 2902 | |||
| 2903 | if (dev->stopped) { | ||
| 2904 | dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n"); | ||
| 2905 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2906 | return IRQ_NONE; | ||
| 2907 | } | ||
| 2908 | |||
| 2909 | spin_lock(&dev->lock); | ||
| 2910 | |||
| 2911 | /* USB status */ | ||
| 2912 | usbsts = readl(&dev->op_regs->usbsts); | ||
| 2913 | |||
| 2914 | /* USB interrupt enable */ | ||
| 2915 | usbintr = readl(&dev->op_regs->usbintr); | ||
| 2916 | |||
| 2917 | irq_sts = usbsts & usbintr; | ||
| 2918 | dev_vdbg(&dev->pdev->dev, | ||
| 2919 | "usbsts = 0x%08x, usbintr = 0x%08x, irq_sts = 0x%08x\n", | ||
| 2920 | usbsts, usbintr, irq_sts); | ||
| 2921 | |||
| 2922 | if (!irq_sts) { | ||
| 2923 | dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n"); | ||
| 2924 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2925 | spin_unlock(&dev->lock); | ||
| 2926 | return IRQ_NONE; | ||
| 2927 | } | ||
| 2928 | |||
| 2929 | /* Write-Clear interrupt status bits */ | ||
| 2930 | writel(irq_sts, &dev->op_regs->usbsts); | ||
| 2931 | |||
| 2932 | /* resume from suspend */ | ||
| 2933 | portsc1 = readl(&dev->op_regs->portsc1); | ||
| 2934 | if (dev->usb_state == USB_STATE_SUSPENDED) | ||
| 2935 | if (!(portsc1 & PORTS_SUSP)) | ||
| 2936 | handle_bus_resume(dev); | ||
| 2937 | |||
| 2938 | /* USB interrupt */ | ||
| 2939 | if (irq_sts & STS_UI) { | ||
| 2940 | dev_vdbg(&dev->pdev->dev, "USB interrupt\n"); | ||
| 2941 | |||
| 2942 | /* setup packet received from ep0 */ | ||
| 2943 | if (readl(&dev->op_regs->endptsetupstat) | ||
| 2944 | & EP0SETUPSTAT_MASK) { | ||
| 2945 | dev_vdbg(&dev->pdev->dev, | ||
| 2946 | "USB SETUP packet received interrupt\n"); | ||
| 2947 | /* setup tripwire semaphone */ | ||
| 2948 | setup_tripwire(dev); | ||
| 2949 | handle_setup_packet(dev, &dev->local_setup_buff); | ||
| 2950 | } | ||
| 2951 | |||
| 2952 | /* USB transfer completion */ | ||
| 2953 | if (readl(&dev->op_regs->endptcomplete)) { | ||
| 2954 | dev_vdbg(&dev->pdev->dev, | ||
| 2955 | "USB transfer completion interrupt\n"); | ||
| 2956 | handle_trans_complete(dev); | ||
| 2957 | } | ||
| 2958 | } | ||
| 2959 | |||
| 2960 | /* SOF received interrupt (for ISO transfer) */ | ||
| 2961 | if (irq_sts & STS_SRI) { | ||
| 2962 | /* FIXME */ | ||
| 2963 | /* dev_vdbg(&dev->pdev->dev, "SOF received interrupt\n"); */ | ||
| 2964 | } | ||
| 2965 | |||
| 2966 | /* port change detect interrupt */ | ||
| 2967 | if (irq_sts & STS_PCI) { | ||
| 2968 | dev_vdbg(&dev->pdev->dev, "port change detect interrupt\n"); | ||
| 2969 | handle_port_change(dev); | ||
| 2970 | } | ||
| 2971 | |||
| 2972 | /* suspend interrrupt */ | ||
| 2973 | if (irq_sts & STS_SLI) { | ||
| 2974 | dev_vdbg(&dev->pdev->dev, "suspend interrupt\n"); | ||
| 2975 | handle_bus_suspend(dev); | ||
| 2976 | } | ||
| 2977 | |||
| 2978 | /* USB reset interrupt */ | ||
| 2979 | if (irq_sts & STS_URI) { | ||
| 2980 | dev_vdbg(&dev->pdev->dev, "USB reset interrupt\n"); | ||
| 2981 | handle_usb_reset(dev); | ||
| 2982 | } | ||
| 2983 | |||
| 2984 | /* USB error or system error interrupt */ | ||
| 2985 | if (irq_sts & (STS_UEI | STS_SEI)) { | ||
| 2986 | /* FIXME */ | ||
| 2987 | dev_warn(&dev->pdev->dev, "error IRQ, irq_sts: %x\n", irq_sts); | ||
| 2988 | } | ||
| 2989 | |||
| 2990 | spin_unlock(&dev->lock); | ||
| 2991 | |||
| 2992 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 2993 | return IRQ_HANDLED; | ||
| 2994 | } | ||
| 2995 | |||
| 2996 | |||
| 2997 | /*-------------------------------------------------------------------------*/ | ||
| 2998 | |||
| 2999 | /* release device structure */ | ||
| 3000 | static void gadget_release(struct device *_dev) | ||
| 3001 | { | ||
| 3002 | struct langwell_udc *dev = the_controller; | ||
| 3003 | |||
| 3004 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 3005 | |||
| 3006 | complete(dev->done); | ||
| 3007 | |||
| 3008 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 3009 | kfree(dev); | ||
| 3010 | } | ||
| 3011 | |||
| 3012 | |||
| 3013 | /* enable SRAM caching if SRAM detected */ | ||
| 3014 | static void sram_init(struct langwell_udc *dev) | ||
| 3015 | { | ||
| 3016 | struct pci_dev *pdev = dev->pdev; | ||
| 3017 | |||
| 3018 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 3019 | |||
| 3020 | dev->sram_addr = pci_resource_start(pdev, 1); | ||
| 3021 | dev->sram_size = pci_resource_len(pdev, 1); | ||
| 3022 | dev_info(&dev->pdev->dev, "Found private SRAM at %x size:%x\n", | ||
| 3023 | dev->sram_addr, dev->sram_size); | ||
| 3024 | dev->got_sram = 1; | ||
| 3025 | |||
| 3026 | if (pci_request_region(pdev, 1, kobject_name(&pdev->dev.kobj))) { | ||
| 3027 | dev_warn(&dev->pdev->dev, "SRAM request failed\n"); | ||
| 3028 | dev->got_sram = 0; | ||
| 3029 | } else if (!dma_declare_coherent_memory(&pdev->dev, dev->sram_addr, | ||
| 3030 | dev->sram_addr, dev->sram_size, DMA_MEMORY_MAP)) { | ||
| 3031 | dev_warn(&dev->pdev->dev, "SRAM DMA declare failed\n"); | ||
| 3032 | pci_release_region(pdev, 1); | ||
| 3033 | dev->got_sram = 0; | ||
| 3034 | } | ||
| 3035 | |||
| 3036 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 3037 | } | ||
| 3038 | |||
| 3039 | |||
| 3040 | /* release SRAM caching */ | ||
| 3041 | static void sram_deinit(struct langwell_udc *dev) | ||
| 3042 | { | ||
| 3043 | struct pci_dev *pdev = dev->pdev; | ||
| 3044 | |||
| 3045 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 3046 | |||
| 3047 | dma_release_declared_memory(&pdev->dev); | ||
| 3048 | pci_release_region(pdev, 1); | ||
| 3049 | |||
| 3050 | dev->got_sram = 0; | ||
| 3051 | |||
| 3052 | dev_info(&dev->pdev->dev, "release SRAM caching\n"); | ||
| 3053 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 3054 | } | ||
| 3055 | |||
| 3056 | |||
| 3057 | /* tear down the binding between this driver and the pci device */ | ||
| 3058 | static void langwell_udc_remove(struct pci_dev *pdev) | ||
| 3059 | { | ||
| 3060 | struct langwell_udc *dev = the_controller; | ||
| 3061 | |||
| 3062 | DECLARE_COMPLETION(done); | ||
| 3063 | |||
| 3064 | BUG_ON(dev->driver); | ||
| 3065 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 3066 | |||
| 3067 | dev->done = &done; | ||
| 3068 | |||
| 3069 | #ifndef OTG_TRANSCEIVER | ||
| 3070 | /* free dTD dma_pool and dQH */ | ||
| 3071 | if (dev->dtd_pool) | ||
| 3072 | dma_pool_destroy(dev->dtd_pool); | ||
| 3073 | |||
| 3074 | if (dev->ep_dqh) | ||
| 3075 | dma_free_coherent(&pdev->dev, dev->ep_dqh_size, | ||
| 3076 | dev->ep_dqh, dev->ep_dqh_dma); | ||
| 3077 | |||
| 3078 | /* release SRAM caching */ | ||
| 3079 | if (dev->has_sram && dev->got_sram) | ||
| 3080 | sram_deinit(dev); | ||
| 3081 | #endif | ||
| 3082 | |||
| 3083 | if (dev->status_req) { | ||
| 3084 | kfree(dev->status_req->req.buf); | ||
| 3085 | kfree(dev->status_req); | ||
| 3086 | } | ||
| 3087 | |||
| 3088 | kfree(dev->ep); | ||
| 3089 | |||
| 3090 | /* disable IRQ handler */ | ||
| 3091 | if (dev->got_irq) | ||
| 3092 | free_irq(pdev->irq, dev); | ||
| 3093 | |||
| 3094 | #ifndef OTG_TRANSCEIVER | ||
| 3095 | if (dev->cap_regs) | ||
| 3096 | iounmap(dev->cap_regs); | ||
| 3097 | |||
| 3098 | if (dev->region) | ||
| 3099 | release_mem_region(pci_resource_start(pdev, 0), | ||
| 3100 | pci_resource_len(pdev, 0)); | ||
| 3101 | |||
| 3102 | if (dev->enabled) | ||
| 3103 | pci_disable_device(pdev); | ||
| 3104 | #else | ||
| 3105 | if (dev->transceiver) { | ||
| 3106 | otg_put_transceiver(dev->transceiver); | ||
| 3107 | dev->transceiver = NULL; | ||
| 3108 | dev->lotg = NULL; | ||
| 3109 | } | ||
| 3110 | #endif | ||
| 3111 | |||
| 3112 | dev->cap_regs = NULL; | ||
| 3113 | |||
| 3114 | dev_info(&dev->pdev->dev, "unbind\n"); | ||
| 3115 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 3116 | |||
| 3117 | device_unregister(&dev->gadget.dev); | ||
| 3118 | device_remove_file(&pdev->dev, &dev_attr_langwell_udc); | ||
| 3119 | device_remove_file(&pdev->dev, &dev_attr_remote_wakeup); | ||
| 3120 | |||
| 3121 | #ifndef OTG_TRANSCEIVER | ||
| 3122 | pci_set_drvdata(pdev, NULL); | ||
| 3123 | #endif | ||
| 3124 | |||
| 3125 | /* free dev, wait for the release() finished */ | ||
| 3126 | wait_for_completion(&done); | ||
| 3127 | |||
| 3128 | the_controller = NULL; | ||
| 3129 | } | ||
| 3130 | |||
| 3131 | |||
| 3132 | /* | ||
| 3133 | * wrap this driver around the specified device, but | ||
| 3134 | * don't respond over USB until a gadget driver binds to us. | ||
| 3135 | */ | ||
| 3136 | static int langwell_udc_probe(struct pci_dev *pdev, | ||
| 3137 | const struct pci_device_id *id) | ||
| 3138 | { | ||
| 3139 | struct langwell_udc *dev; | ||
| 3140 | #ifndef OTG_TRANSCEIVER | ||
| 3141 | unsigned long resource, len; | ||
| 3142 | #endif | ||
| 3143 | void __iomem *base = NULL; | ||
| 3144 | size_t size; | ||
| 3145 | int retval; | ||
| 3146 | |||
| 3147 | if (the_controller) { | ||
| 3148 | dev_warn(&pdev->dev, "ignoring\n"); | ||
| 3149 | return -EBUSY; | ||
| 3150 | } | ||
| 3151 | |||
| 3152 | /* alloc, and start init */ | ||
| 3153 | dev = kzalloc(sizeof *dev, GFP_KERNEL); | ||
| 3154 | if (dev == NULL) { | ||
| 3155 | retval = -ENOMEM; | ||
| 3156 | goto error; | ||
| 3157 | } | ||
| 3158 | |||
| 3159 | /* initialize device spinlock */ | ||
| 3160 | spin_lock_init(&dev->lock); | ||
| 3161 | |||
| 3162 | dev->pdev = pdev; | ||
| 3163 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 3164 | |||
| 3165 | #ifdef OTG_TRANSCEIVER | ||
| 3166 | /* PCI device is already enabled by otg_transceiver driver */ | ||
| 3167 | dev->enabled = 1; | ||
| 3168 | |||
| 3169 | /* mem region and register base */ | ||
| 3170 | dev->region = 1; | ||
| 3171 | dev->transceiver = otg_get_transceiver(); | ||
| 3172 | dev->lotg = otg_to_langwell(dev->transceiver); | ||
| 3173 | base = dev->lotg->regs; | ||
| 3174 | #else | ||
| 3175 | pci_set_drvdata(pdev, dev); | ||
| 3176 | |||
| 3177 | /* now all the pci goodies ... */ | ||
| 3178 | if (pci_enable_device(pdev) < 0) { | ||
| 3179 | retval = -ENODEV; | ||
| 3180 | goto error; | ||
| 3181 | } | ||
| 3182 | dev->enabled = 1; | ||
| 3183 | |||
| 3184 | /* control register: BAR 0 */ | ||
| 3185 | resource = pci_resource_start(pdev, 0); | ||
| 3186 | len = pci_resource_len(pdev, 0); | ||
| 3187 | if (!request_mem_region(resource, len, driver_name)) { | ||
| 3188 | dev_err(&dev->pdev->dev, "controller already in use\n"); | ||
| 3189 | retval = -EBUSY; | ||
| 3190 | goto error; | ||
| 3191 | } | ||
| 3192 | dev->region = 1; | ||
| 3193 | |||
| 3194 | base = ioremap_nocache(resource, len); | ||
| 3195 | #endif | ||
| 3196 | if (base == NULL) { | ||
| 3197 | dev_err(&dev->pdev->dev, "can't map memory\n"); | ||
| 3198 | retval = -EFAULT; | ||
| 3199 | goto error; | ||
| 3200 | } | ||
| 3201 | |||
| 3202 | dev->cap_regs = (struct langwell_cap_regs __iomem *) base; | ||
| 3203 | dev_vdbg(&dev->pdev->dev, "dev->cap_regs: %p\n", dev->cap_regs); | ||
| 3204 | dev->op_regs = (struct langwell_op_regs __iomem *) | ||
| 3205 | (base + OP_REG_OFFSET); | ||
| 3206 | dev_vdbg(&dev->pdev->dev, "dev->op_regs: %p\n", dev->op_regs); | ||
| 3207 | |||
| 3208 | /* irq setup after old hardware is cleaned up */ | ||
| 3209 | if (!pdev->irq) { | ||
| 3210 | dev_err(&dev->pdev->dev, "No IRQ. Check PCI setup!\n"); | ||
| 3211 | retval = -ENODEV; | ||
| 3212 | goto error; | ||
| 3213 | } | ||
| 3214 | |||
| 3215 | dev->has_sram = 1; | ||
| 3216 | dev->got_sram = 0; | ||
| 3217 | dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram); | ||
| 3218 | |||
| 3219 | #ifndef OTG_TRANSCEIVER | ||
| 3220 | /* enable SRAM caching if detected */ | ||
| 3221 | if (dev->has_sram && !dev->got_sram) | ||
| 3222 | sram_init(dev); | ||
| 3223 | |||
| 3224 | dev_info(&dev->pdev->dev, | ||
| 3225 | "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n", | ||
| 3226 | pdev->irq, resource, len, base); | ||
| 3227 | /* enables bus-mastering for device dev */ | ||
| 3228 | pci_set_master(pdev); | ||
| 3229 | |||
| 3230 | if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED, | ||
| 3231 | driver_name, dev) != 0) { | ||
| 3232 | dev_err(&dev->pdev->dev, | ||
| 3233 | "request interrupt %d failed\n", pdev->irq); | ||
| 3234 | retval = -EBUSY; | ||
| 3235 | goto error; | ||
| 3236 | } | ||
| 3237 | dev->got_irq = 1; | ||
| 3238 | #endif | ||
| 3239 | |||
| 3240 | /* set stopped bit */ | ||
| 3241 | dev->stopped = 1; | ||
| 3242 | |||
| 3243 | /* capabilities and endpoint number */ | ||
| 3244 | dev->lpm = (readl(&dev->cap_regs->hccparams) & HCC_LEN) ? 1 : 0; | ||
| 3245 | dev->dciversion = readw(&dev->cap_regs->dciversion); | ||
| 3246 | dev->devcap = (readl(&dev->cap_regs->dccparams) & DEVCAP) ? 1 : 0; | ||
| 3247 | dev_vdbg(&dev->pdev->dev, "dev->lpm: %d\n", dev->lpm); | ||
| 3248 | dev_vdbg(&dev->pdev->dev, "dev->dciversion: 0x%04x\n", | ||
| 3249 | dev->dciversion); | ||
| 3250 | dev_vdbg(&dev->pdev->dev, "dccparams: 0x%08x\n", | ||
| 3251 | readl(&dev->cap_regs->dccparams)); | ||
| 3252 | dev_vdbg(&dev->pdev->dev, "dev->devcap: %d\n", dev->devcap); | ||
| 3253 | if (!dev->devcap) { | ||
| 3254 | dev_err(&dev->pdev->dev, "can't support device mode\n"); | ||
| 3255 | retval = -ENODEV; | ||
| 3256 | goto error; | ||
| 3257 | } | ||
| 3258 | |||
| 3259 | /* a pair of endpoints (out/in) for each address */ | ||
| 3260 | dev->ep_max = DEN(readl(&dev->cap_regs->dccparams)) * 2; | ||
| 3261 | dev_vdbg(&dev->pdev->dev, "dev->ep_max: %d\n", dev->ep_max); | ||
| 3262 | |||
| 3263 | /* allocate endpoints memory */ | ||
| 3264 | dev->ep = kzalloc(sizeof(struct langwell_ep) * dev->ep_max, | ||
| 3265 | GFP_KERNEL); | ||
| 3266 | if (!dev->ep) { | ||
| 3267 | dev_err(&dev->pdev->dev, "allocate endpoints memory failed\n"); | ||
| 3268 | retval = -ENOMEM; | ||
| 3269 | goto error; | ||
| 3270 | } | ||
| 3271 | |||
| 3272 | /* allocate device dQH memory */ | ||
| 3273 | size = dev->ep_max * sizeof(struct langwell_dqh); | ||
| 3274 | dev_vdbg(&dev->pdev->dev, "orig size = %zd\n", size); | ||
| 3275 | if (size < DQH_ALIGNMENT) | ||
| 3276 | size = DQH_ALIGNMENT; | ||
| 3277 | else if ((size % DQH_ALIGNMENT) != 0) { | ||
| 3278 | size += DQH_ALIGNMENT + 1; | ||
| 3279 | size &= ~(DQH_ALIGNMENT - 1); | ||
| 3280 | } | ||
| 3281 | dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size, | ||
| 3282 | &dev->ep_dqh_dma, GFP_KERNEL); | ||
| 3283 | if (!dev->ep_dqh) { | ||
| 3284 | dev_err(&dev->pdev->dev, "allocate dQH memory failed\n"); | ||
| 3285 | retval = -ENOMEM; | ||
| 3286 | goto error; | ||
| 3287 | } | ||
| 3288 | dev->ep_dqh_size = size; | ||
| 3289 | dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %zd\n", dev->ep_dqh_size); | ||
| 3290 | |||
| 3291 | /* initialize ep0 status request structure */ | ||
| 3292 | dev->status_req = kzalloc(sizeof(struct langwell_request), GFP_KERNEL); | ||
| 3293 | if (!dev->status_req) { | ||
| 3294 | dev_err(&dev->pdev->dev, | ||
| 3295 | "allocate status_req memory failed\n"); | ||
| 3296 | retval = -ENOMEM; | ||
| 3297 | goto error; | ||
| 3298 | } | ||
| 3299 | INIT_LIST_HEAD(&dev->status_req->queue); | ||
| 3300 | |||
| 3301 | /* allocate a small amount of memory to get valid address */ | ||
| 3302 | dev->status_req->req.buf = kmalloc(8, GFP_KERNEL); | ||
| 3303 | dev->status_req->req.dma = virt_to_phys(dev->status_req->req.buf); | ||
| 3304 | |||
| 3305 | dev->resume_state = USB_STATE_NOTATTACHED; | ||
| 3306 | dev->usb_state = USB_STATE_POWERED; | ||
| 3307 | dev->ep0_dir = USB_DIR_OUT; | ||
| 3308 | |||
| 3309 | /* remote wakeup reset to 0 when the device is reset */ | ||
| 3310 | dev->remote_wakeup = 0; | ||
| 3311 | dev->dev_status = 1 << USB_DEVICE_SELF_POWERED; | ||
| 3312 | |||
| 3313 | #ifndef OTG_TRANSCEIVER | ||
| 3314 | /* reset device controller */ | ||
| 3315 | langwell_udc_reset(dev); | ||
| 3316 | #endif | ||
| 3317 | |||
| 3318 | /* initialize gadget structure */ | ||
| 3319 | dev->gadget.ops = &langwell_ops; /* usb_gadget_ops */ | ||
| 3320 | dev->gadget.ep0 = &dev->ep[0].ep; /* gadget ep0 */ | ||
| 3321 | INIT_LIST_HEAD(&dev->gadget.ep_list); /* ep_list */ | ||
| 3322 | dev->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ | ||
| 3323 | dev->gadget.is_dualspeed = 1; /* support dual speed */ | ||
| 3324 | #ifdef OTG_TRANSCEIVER | ||
| 3325 | dev->gadget.is_otg = 1; /* support otg mode */ | ||
| 3326 | #endif | ||
| 3327 | |||
| 3328 | /* the "gadget" abstracts/virtualizes the controller */ | ||
| 3329 | dev_set_name(&dev->gadget.dev, "gadget"); | ||
| 3330 | dev->gadget.dev.parent = &pdev->dev; | ||
| 3331 | dev->gadget.dev.dma_mask = pdev->dev.dma_mask; | ||
| 3332 | dev->gadget.dev.release = gadget_release; | ||
| 3333 | dev->gadget.name = driver_name; /* gadget name */ | ||
| 3334 | |||
| 3335 | /* controller endpoints reinit */ | ||
| 3336 | eps_reinit(dev); | ||
| 3337 | |||
| 3338 | #ifndef OTG_TRANSCEIVER | ||
| 3339 | /* reset ep0 dQH and endptctrl */ | ||
| 3340 | ep0_reset(dev); | ||
| 3341 | #endif | ||
| 3342 | |||
| 3343 | /* create dTD dma_pool resource */ | ||
| 3344 | dev->dtd_pool = dma_pool_create("langwell_dtd", | ||
| 3345 | &dev->pdev->dev, | ||
| 3346 | sizeof(struct langwell_dtd), | ||
| 3347 | DTD_ALIGNMENT, | ||
| 3348 | DMA_BOUNDARY); | ||
| 3349 | |||
| 3350 | if (!dev->dtd_pool) { | ||
| 3351 | retval = -ENOMEM; | ||
| 3352 | goto error; | ||
| 3353 | } | ||
| 3354 | |||
| 3355 | /* done */ | ||
| 3356 | dev_info(&dev->pdev->dev, "%s\n", driver_desc); | ||
| 3357 | dev_info(&dev->pdev->dev, "irq %d, pci mem %p\n", pdev->irq, base); | ||
| 3358 | dev_info(&dev->pdev->dev, "Driver version: " DRIVER_VERSION "\n"); | ||
| 3359 | dev_info(&dev->pdev->dev, "Support (max) %d endpoints\n", dev->ep_max); | ||
| 3360 | dev_info(&dev->pdev->dev, "Device interface version: 0x%04x\n", | ||
| 3361 | dev->dciversion); | ||
| 3362 | dev_info(&dev->pdev->dev, "Controller mode: %s\n", | ||
| 3363 | dev->devcap ? "Device" : "Host"); | ||
| 3364 | dev_info(&dev->pdev->dev, "Support USB LPM: %s\n", | ||
| 3365 | dev->lpm ? "Yes" : "No"); | ||
| 3366 | |||
| 3367 | dev_vdbg(&dev->pdev->dev, | ||
| 3368 | "After langwell_udc_probe(), print all registers:\n"); | ||
| 3369 | print_all_registers(dev); | ||
| 3370 | |||
| 3371 | the_controller = dev; | ||
| 3372 | |||
| 3373 | retval = device_register(&dev->gadget.dev); | ||
| 3374 | if (retval) | ||
| 3375 | goto error; | ||
| 3376 | |||
| 3377 | retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget); | ||
| 3378 | if (retval) | ||
| 3379 | goto error; | ||
| 3380 | |||
| 3381 | retval = device_create_file(&pdev->dev, &dev_attr_langwell_udc); | ||
| 3382 | if (retval) | ||
| 3383 | goto error; | ||
| 3384 | |||
| 3385 | retval = device_create_file(&pdev->dev, &dev_attr_remote_wakeup); | ||
| 3386 | if (retval) | ||
| 3387 | goto error_attr1; | ||
| 3388 | |||
| 3389 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 3390 | return 0; | ||
| 3391 | |||
| 3392 | error_attr1: | ||
| 3393 | device_remove_file(&pdev->dev, &dev_attr_langwell_udc); | ||
| 3394 | error: | ||
| 3395 | if (dev) { | ||
| 3396 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 3397 | langwell_udc_remove(pdev); | ||
| 3398 | } | ||
| 3399 | |||
| 3400 | return retval; | ||
| 3401 | } | ||
| 3402 | |||
| 3403 | |||
| 3404 | /* device controller suspend */ | ||
| 3405 | static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) | ||
| 3406 | { | ||
| 3407 | struct langwell_udc *dev = the_controller; | ||
| 3408 | |||
| 3409 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 3410 | |||
| 3411 | usb_del_gadget_udc(&dev->gadget); | ||
| 3412 | /* disable interrupt and set controller to stop state */ | ||
| 3413 | langwell_udc_stop(dev); | ||
| 3414 | |||
| 3415 | /* disable IRQ handler */ | ||
| 3416 | if (dev->got_irq) | ||
| 3417 | free_irq(pdev->irq, dev); | ||
| 3418 | dev->got_irq = 0; | ||
| 3419 | |||
| 3420 | /* save PCI state */ | ||
| 3421 | pci_save_state(pdev); | ||
| 3422 | |||
| 3423 | spin_lock_irq(&dev->lock); | ||
| 3424 | /* stop all usb activities */ | ||
| 3425 | stop_activity(dev, dev->driver); | ||
| 3426 | spin_unlock_irq(&dev->lock); | ||
| 3427 | |||
| 3428 | /* free dTD dma_pool and dQH */ | ||
| 3429 | if (dev->dtd_pool) | ||
| 3430 | dma_pool_destroy(dev->dtd_pool); | ||
| 3431 | |||
| 3432 | if (dev->ep_dqh) | ||
| 3433 | dma_free_coherent(&pdev->dev, dev->ep_dqh_size, | ||
| 3434 | dev->ep_dqh, dev->ep_dqh_dma); | ||
| 3435 | |||
| 3436 | /* release SRAM caching */ | ||
| 3437 | if (dev->has_sram && dev->got_sram) | ||
| 3438 | sram_deinit(dev); | ||
| 3439 | |||
| 3440 | /* set device power state */ | ||
| 3441 | pci_set_power_state(pdev, PCI_D3hot); | ||
| 3442 | |||
| 3443 | /* enter PHY low power suspend */ | ||
| 3444 | if (dev->pdev->device != 0x0829) | ||
| 3445 | langwell_phy_low_power(dev, 1); | ||
| 3446 | |||
| 3447 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 3448 | return 0; | ||
| 3449 | } | ||
| 3450 | |||
| 3451 | |||
| 3452 | /* device controller resume */ | ||
| 3453 | static int langwell_udc_resume(struct pci_dev *pdev) | ||
| 3454 | { | ||
| 3455 | struct langwell_udc *dev = the_controller; | ||
| 3456 | size_t size; | ||
| 3457 | |||
| 3458 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 3459 | |||
| 3460 | /* exit PHY low power suspend */ | ||
| 3461 | if (dev->pdev->device != 0x0829) | ||
| 3462 | langwell_phy_low_power(dev, 0); | ||
| 3463 | |||
| 3464 | /* set device D0 power state */ | ||
| 3465 | pci_set_power_state(pdev, PCI_D0); | ||
| 3466 | |||
| 3467 | /* enable SRAM caching if detected */ | ||
| 3468 | if (dev->has_sram && !dev->got_sram) | ||
| 3469 | sram_init(dev); | ||
| 3470 | |||
| 3471 | /* allocate device dQH memory */ | ||
| 3472 | size = dev->ep_max * sizeof(struct langwell_dqh); | ||
| 3473 | dev_vdbg(&dev->pdev->dev, "orig size = %zd\n", size); | ||
| 3474 | if (size < DQH_ALIGNMENT) | ||
| 3475 | size = DQH_ALIGNMENT; | ||
| 3476 | else if ((size % DQH_ALIGNMENT) != 0) { | ||
| 3477 | size += DQH_ALIGNMENT + 1; | ||
| 3478 | size &= ~(DQH_ALIGNMENT - 1); | ||
| 3479 | } | ||
| 3480 | dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size, | ||
| 3481 | &dev->ep_dqh_dma, GFP_KERNEL); | ||
| 3482 | if (!dev->ep_dqh) { | ||
| 3483 | dev_err(&dev->pdev->dev, "allocate dQH memory failed\n"); | ||
| 3484 | return -ENOMEM; | ||
| 3485 | } | ||
| 3486 | dev->ep_dqh_size = size; | ||
| 3487 | dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %zd\n", dev->ep_dqh_size); | ||
| 3488 | |||
| 3489 | /* create dTD dma_pool resource */ | ||
| 3490 | dev->dtd_pool = dma_pool_create("langwell_dtd", | ||
| 3491 | &dev->pdev->dev, | ||
| 3492 | sizeof(struct langwell_dtd), | ||
| 3493 | DTD_ALIGNMENT, | ||
| 3494 | DMA_BOUNDARY); | ||
| 3495 | |||
| 3496 | if (!dev->dtd_pool) | ||
| 3497 | return -ENOMEM; | ||
| 3498 | |||
| 3499 | /* restore PCI state */ | ||
| 3500 | pci_restore_state(pdev); | ||
| 3501 | |||
| 3502 | /* enable IRQ handler */ | ||
| 3503 | if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED, | ||
| 3504 | driver_name, dev) != 0) { | ||
| 3505 | dev_err(&dev->pdev->dev, "request interrupt %d failed\n", | ||
| 3506 | pdev->irq); | ||
| 3507 | return -EBUSY; | ||
| 3508 | } | ||
| 3509 | dev->got_irq = 1; | ||
| 3510 | |||
| 3511 | /* reset and start controller to run state */ | ||
| 3512 | if (dev->stopped) { | ||
| 3513 | /* reset device controller */ | ||
| 3514 | langwell_udc_reset(dev); | ||
| 3515 | |||
| 3516 | /* reset ep0 dQH and endptctrl */ | ||
| 3517 | ep0_reset(dev); | ||
| 3518 | |||
| 3519 | /* start device if gadget is loaded */ | ||
| 3520 | if (dev->driver) | ||
| 3521 | langwell_udc_start(dev); | ||
| 3522 | } | ||
| 3523 | |||
| 3524 | /* reset USB status */ | ||
| 3525 | dev->usb_state = USB_STATE_ATTACHED; | ||
| 3526 | dev->ep0_state = WAIT_FOR_SETUP; | ||
| 3527 | dev->ep0_dir = USB_DIR_OUT; | ||
| 3528 | |||
| 3529 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 3530 | return 0; | ||
| 3531 | } | ||
| 3532 | |||
| 3533 | |||
| 3534 | /* pci driver shutdown */ | ||
| 3535 | static void langwell_udc_shutdown(struct pci_dev *pdev) | ||
| 3536 | { | ||
| 3537 | struct langwell_udc *dev = the_controller; | ||
| 3538 | u32 usbmode; | ||
| 3539 | |||
| 3540 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
| 3541 | |||
| 3542 | /* reset controller mode to IDLE */ | ||
| 3543 | usbmode = readl(&dev->op_regs->usbmode); | ||
| 3544 | dev_dbg(&dev->pdev->dev, "usbmode = 0x%08x\n", usbmode); | ||
| 3545 | usbmode &= (~3 | MODE_IDLE); | ||
| 3546 | writel(usbmode, &dev->op_regs->usbmode); | ||
| 3547 | |||
| 3548 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
| 3549 | } | ||
| 3550 | |||
| 3551 | /*-------------------------------------------------------------------------*/ | ||
| 3552 | |||
| 3553 | static const struct pci_device_id pci_ids[] = { { | ||
| 3554 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 3555 | .class_mask = ~0, | ||
| 3556 | .vendor = 0x8086, | ||
| 3557 | .device = 0x0811, | ||
| 3558 | .subvendor = PCI_ANY_ID, | ||
| 3559 | .subdevice = PCI_ANY_ID, | ||
| 3560 | }, { /* end: all zeroes */ } | ||
| 3561 | }; | ||
| 3562 | |||
| 3563 | MODULE_DEVICE_TABLE(pci, pci_ids); | ||
| 3564 | |||
| 3565 | |||
| 3566 | static struct pci_driver langwell_pci_driver = { | ||
| 3567 | .name = (char *) driver_name, | ||
| 3568 | .id_table = pci_ids, | ||
| 3569 | |||
| 3570 | .probe = langwell_udc_probe, | ||
| 3571 | .remove = langwell_udc_remove, | ||
| 3572 | |||
| 3573 | /* device controller suspend/resume */ | ||
| 3574 | .suspend = langwell_udc_suspend, | ||
| 3575 | .resume = langwell_udc_resume, | ||
| 3576 | |||
| 3577 | .shutdown = langwell_udc_shutdown, | ||
| 3578 | }; | ||
| 3579 | |||
| 3580 | |||
| 3581 | static int __init init(void) | ||
| 3582 | { | ||
| 3583 | #ifdef OTG_TRANSCEIVER | ||
| 3584 | return langwell_register_peripheral(&langwell_pci_driver); | ||
| 3585 | #else | ||
| 3586 | return pci_register_driver(&langwell_pci_driver); | ||
| 3587 | #endif | ||
| 3588 | } | ||
| 3589 | module_init(init); | ||
| 3590 | |||
| 3591 | |||
| 3592 | static void __exit cleanup(void) | ||
| 3593 | { | ||
| 3594 | #ifdef OTG_TRANSCEIVER | ||
| 3595 | return langwell_unregister_peripheral(&langwell_pci_driver); | ||
| 3596 | #else | ||
| 3597 | pci_unregister_driver(&langwell_pci_driver); | ||
| 3598 | #endif | ||
| 3599 | } | ||
| 3600 | module_exit(cleanup); | ||
| 3601 | |||
| 3602 | |||
| 3603 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 3604 | MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>"); | ||
| 3605 | MODULE_VERSION(DRIVER_VERSION); | ||
| 3606 | MODULE_LICENSE("GPL"); | ||
| 3607 | |||
diff --git a/drivers/usb/gadget/langwell_udc.h b/drivers/usb/gadget/langwell_udc.h new file mode 100644 index 00000000000..f1d9c1bb04f --- /dev/null +++ b/drivers/usb/gadget/langwell_udc.h | |||
| @@ -0,0 +1,233 @@ | |||
| 1 | /* | ||
| 2 | * Intel Langwell USB Device Controller driver | ||
| 3 | * Copyright (C) 2008-2009, Intel Corporation. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along with | ||
| 15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/usb/langwell_udc.h> | ||
| 21 | #include <linux/usb/langwell_otg.h> | ||
| 22 | |||
| 23 | /*-------------------------------------------------------------------------*/ | ||
| 24 | |||
| 25 | /* driver data structures and utilities */ | ||
| 26 | |||
| 27 | /* | ||
| 28 | * dTD: Device Endpoint Transfer Descriptor | ||
| 29 | * describe to the device controller the location and quantity of | ||
| 30 | * data to be send/received for given transfer | ||
| 31 | */ | ||
| 32 | struct langwell_dtd { | ||
| 33 | u32 dtd_next; | ||
| 34 | /* bits 31:5, next transfer element pointer */ | ||
| 35 | #define DTD_NEXT(d) (((d)>>5)&0x7ffffff) | ||
| 36 | #define DTD_NEXT_MASK (0x7ffffff << 5) | ||
| 37 | /* terminate */ | ||
| 38 | #define DTD_TERM BIT(0) | ||
| 39 | /* bits 7:0, execution back states */ | ||
| 40 | u32 dtd_status:8; | ||
| 41 | #define DTD_STATUS(d) (((d)>>0)&0xff) | ||
| 42 | #define DTD_STS_ACTIVE BIT(7) /* active */ | ||
| 43 | #define DTD_STS_HALTED BIT(6) /* halted */ | ||
| 44 | #define DTD_STS_DBE BIT(5) /* data buffer error */ | ||
| 45 | #define DTD_STS_TRE BIT(3) /* transaction error */ | ||
| 46 | /* bits 9:8 */ | ||
| 47 | u32 dtd_res0:2; | ||
| 48 | /* bits 11:10, multipier override */ | ||
| 49 | u32 dtd_multo:2; | ||
| 50 | #define DTD_MULTO (BIT(11) | BIT(10)) | ||
| 51 | /* bits 14:12 */ | ||
| 52 | u32 dtd_res1:3; | ||
| 53 | /* bit 15, interrupt on complete */ | ||
| 54 | u32 dtd_ioc:1; | ||
| 55 | #define DTD_IOC BIT(15) | ||
| 56 | /* bits 30:16, total bytes */ | ||
| 57 | u32 dtd_total:15; | ||
| 58 | #define DTD_TOTAL(d) (((d)>>16)&0x7fff) | ||
| 59 | #define DTD_MAX_TRANSFER_LENGTH 0x4000 | ||
| 60 | /* bit 31 */ | ||
| 61 | u32 dtd_res2:1; | ||
| 62 | /* dTD buffer pointer page 0 to 4 */ | ||
| 63 | u32 dtd_buf[5]; | ||
| 64 | #define DTD_OFFSET_MASK 0xfff | ||
| 65 | /* bits 31:12, buffer pointer */ | ||
| 66 | #define DTD_BUFFER(d) (((d)>>12)&0x3ff) | ||
| 67 | /* bits 11:0, current offset */ | ||
| 68 | #define DTD_C_OFFSET(d) (((d)>>0)&0xfff) | ||
| 69 | /* bits 10:0, frame number */ | ||
| 70 | #define DTD_FRAME(d) (((d)>>0)&0x7ff) | ||
| 71 | |||
| 72 | /* driver-private parts */ | ||
| 73 | |||
| 74 | /* dtd dma address */ | ||
| 75 | dma_addr_t dtd_dma; | ||
| 76 | /* next dtd virtual address */ | ||
| 77 | struct langwell_dtd *next_dtd_virt; | ||
| 78 | }; | ||
| 79 | |||
| 80 | |||
| 81 | /* | ||
| 82 | * dQH: Device Endpoint Queue Head | ||
| 83 | * describe where all transfers are managed | ||
| 84 | * 48-byte data structure, aligned on 64-byte boundary | ||
| 85 | * | ||
| 86 | * These are associated with dTD structure | ||
| 87 | */ | ||
| 88 | struct langwell_dqh { | ||
| 89 | /* endpoint capabilities and characteristics */ | ||
| 90 | u32 dqh_res0:15; /* bits 14:0 */ | ||
| 91 | u32 dqh_ios:1; /* bit 15, interrupt on setup */ | ||
| 92 | #define DQH_IOS BIT(15) | ||
| 93 | u32 dqh_mpl:11; /* bits 26:16, maximum packet length */ | ||
| 94 | #define DQH_MPL (0x7ff << 16) | ||
| 95 | u32 dqh_res1:2; /* bits 28:27 */ | ||
| 96 | u32 dqh_zlt:1; /* bit 29, zero length termination */ | ||
| 97 | #define DQH_ZLT BIT(29) | ||
| 98 | u32 dqh_mult:2; /* bits 31:30 */ | ||
| 99 | #define DQH_MULT (BIT(30) | BIT(31)) | ||
| 100 | |||
| 101 | /* current dTD pointer */ | ||
| 102 | u32 dqh_current; /* locate the transfer in progress */ | ||
| 103 | #define DQH_C_DTD(e) \ | ||
| 104 | (((e)>>5)&0x7ffffff) /* bits 31:5, current dTD pointer */ | ||
| 105 | |||
| 106 | /* transfer overlay, hardware parts of a struct langwell_dtd */ | ||
| 107 | u32 dtd_next; | ||
| 108 | u32 dtd_status:8; /* bits 7:0, execution back states */ | ||
| 109 | u32 dtd_res0:2; /* bits 9:8 */ | ||
| 110 | u32 dtd_multo:2; /* bits 11:10, multipier override */ | ||
| 111 | u32 dtd_res1:3; /* bits 14:12 */ | ||
| 112 | u32 dtd_ioc:1; /* bit 15, interrupt on complete */ | ||
| 113 | u32 dtd_total:15; /* bits 30:16, total bytes */ | ||
| 114 | u32 dtd_res2:1; /* bit 31 */ | ||
| 115 | u32 dtd_buf[5]; /* dTD buffer pointer page 0 to 4 */ | ||
| 116 | |||
| 117 | u32 dqh_res2; | ||
| 118 | struct usb_ctrlrequest dqh_setup; /* setup packet buffer */ | ||
| 119 | } __attribute__ ((aligned(64))); | ||
| 120 | |||
| 121 | |||
| 122 | /* endpoint data structure */ | ||
| 123 | struct langwell_ep { | ||
| 124 | struct usb_ep ep; | ||
| 125 | dma_addr_t dma; | ||
| 126 | struct langwell_udc *dev; | ||
| 127 | unsigned long irqs; | ||
| 128 | struct list_head queue; | ||
| 129 | struct langwell_dqh *dqh; | ||
| 130 | const struct usb_endpoint_descriptor *desc; | ||
| 131 | char name[14]; | ||
| 132 | unsigned stopped:1, | ||
| 133 | ep_type:2, | ||
| 134 | ep_num:8; | ||
| 135 | }; | ||
| 136 | |||
| 137 | |||
| 138 | /* request data structure */ | ||
| 139 | struct langwell_request { | ||
| 140 | struct usb_request req; | ||
| 141 | struct langwell_dtd *dtd, *head, *tail; | ||
| 142 | struct langwell_ep *ep; | ||
| 143 | dma_addr_t dtd_dma; | ||
| 144 | struct list_head queue; | ||
| 145 | unsigned dtd_count; | ||
| 146 | unsigned mapped:1; | ||
| 147 | }; | ||
| 148 | |||
| 149 | |||
| 150 | /* ep0 transfer state */ | ||
| 151 | enum ep0_state { | ||
| 152 | WAIT_FOR_SETUP, | ||
| 153 | DATA_STATE_XMIT, | ||
| 154 | DATA_STATE_NEED_ZLP, | ||
| 155 | WAIT_FOR_OUT_STATUS, | ||
| 156 | DATA_STATE_RECV, | ||
| 157 | }; | ||
| 158 | |||
| 159 | |||
| 160 | /* device suspend state */ | ||
| 161 | enum lpm_state { | ||
| 162 | LPM_L0, /* on */ | ||
| 163 | LPM_L1, /* LPM L1 sleep */ | ||
| 164 | LPM_L2, /* suspend */ | ||
| 165 | LPM_L3, /* off */ | ||
| 166 | }; | ||
| 167 | |||
| 168 | |||
| 169 | /* device data structure */ | ||
| 170 | struct langwell_udc { | ||
| 171 | /* each pci device provides one gadget, several endpoints */ | ||
| 172 | struct usb_gadget gadget; | ||
| 173 | spinlock_t lock; /* device lock */ | ||
| 174 | struct langwell_ep *ep; | ||
| 175 | struct usb_gadget_driver *driver; | ||
| 176 | struct otg_transceiver *transceiver; | ||
| 177 | u8 dev_addr; | ||
| 178 | u32 usb_state; | ||
| 179 | u32 resume_state; | ||
| 180 | u32 bus_reset; | ||
| 181 | enum lpm_state lpm_state; | ||
| 182 | enum ep0_state ep0_state; | ||
| 183 | u32 ep0_dir; | ||
| 184 | u16 dciversion; | ||
| 185 | unsigned ep_max; | ||
| 186 | unsigned devcap:1, | ||
| 187 | enabled:1, | ||
| 188 | region:1, | ||
| 189 | got_irq:1, | ||
| 190 | powered:1, | ||
| 191 | remote_wakeup:1, | ||
| 192 | rate:1, | ||
| 193 | is_reset:1, | ||
| 194 | softconnected:1, | ||
| 195 | vbus_active:1, | ||
| 196 | suspended:1, | ||
| 197 | stopped:1, | ||
| 198 | lpm:1, /* LPM capability */ | ||
| 199 | has_sram:1, /* SRAM caching */ | ||
| 200 | got_sram:1; | ||
| 201 | |||
| 202 | /* pci state used to access those endpoints */ | ||
| 203 | struct pci_dev *pdev; | ||
| 204 | |||
| 205 | /* Langwell otg transceiver */ | ||
| 206 | struct langwell_otg *lotg; | ||
| 207 | |||
| 208 | /* control registers */ | ||
| 209 | struct langwell_cap_regs __iomem *cap_regs; | ||
| 210 | struct langwell_op_regs __iomem *op_regs; | ||
| 211 | |||
| 212 | struct usb_ctrlrequest local_setup_buff; | ||
| 213 | struct langwell_dqh *ep_dqh; | ||
| 214 | size_t ep_dqh_size; | ||
| 215 | dma_addr_t ep_dqh_dma; | ||
| 216 | |||
| 217 | /* ep0 status request */ | ||
| 218 | struct langwell_request *status_req; | ||
| 219 | |||
| 220 | /* dma pool */ | ||
| 221 | struct dma_pool *dtd_pool; | ||
| 222 | |||
| 223 | /* make sure release() is done */ | ||
| 224 | struct completion *done; | ||
| 225 | |||
| 226 | /* for private SRAM caching */ | ||
| 227 | unsigned int sram_addr; | ||
| 228 | unsigned int sram_size; | ||
| 229 | |||
| 230 | /* device status data for get_status request */ | ||
| 231 | u16 dev_status; | ||
| 232 | }; | ||
| 233 | |||
diff --git a/drivers/usb/gadget/mv_udc_phy.c b/drivers/usb/gadget/mv_udc_phy.c new file mode 100644 index 00000000000..d4dea97e38a --- /dev/null +++ b/drivers/usb/gadget/mv_udc_phy.c | |||
| @@ -0,0 +1,214 @@ | |||
| 1 | #include <linux/delay.h> | ||
| 2 | #include <linux/timer.h> | ||
| 3 | #include <linux/io.h> | ||
| 4 | #include <linux/errno.h> | ||
| 5 | |||
| 6 | #include <mach/cputype.h> | ||
| 7 | |||
| 8 | #ifdef CONFIG_ARCH_MMP | ||
| 9 | |||
| 10 | #define UTMI_REVISION 0x0 | ||
| 11 | #define UTMI_CTRL 0x4 | ||
| 12 | #define UTMI_PLL 0x8 | ||
| 13 | #define UTMI_TX 0xc | ||
| 14 | #define UTMI_RX 0x10 | ||
| 15 | #define UTMI_IVREF 0x14 | ||
| 16 | #define UTMI_T0 0x18 | ||
| 17 | #define UTMI_T1 0x1c | ||
| 18 | #define UTMI_T2 0x20 | ||
| 19 | #define UTMI_T3 0x24 | ||
| 20 | #define UTMI_T4 0x28 | ||
| 21 | #define UTMI_T5 0x2c | ||
| 22 | #define UTMI_RESERVE 0x30 | ||
| 23 | #define UTMI_USB_INT 0x34 | ||
| 24 | #define UTMI_DBG_CTL 0x38 | ||
| 25 | #define UTMI_OTG_ADDON 0x3c | ||
| 26 | |||
| 27 | /* For UTMICTRL Register */ | ||
| 28 | #define UTMI_CTRL_USB_CLK_EN (1 << 31) | ||
| 29 | /* pxa168 */ | ||
| 30 | #define UTMI_CTRL_SUSPEND_SET1 (1 << 30) | ||
| 31 | #define UTMI_CTRL_SUSPEND_SET2 (1 << 29) | ||
| 32 | #define UTMI_CTRL_RXBUF_PDWN (1 << 24) | ||
| 33 | #define UTMI_CTRL_TXBUF_PDWN (1 << 11) | ||
| 34 | |||
| 35 | #define UTMI_CTRL_INPKT_DELAY_SHIFT 30 | ||
| 36 | #define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT 28 | ||
| 37 | #define UTMI_CTRL_PU_REF_SHIFT 20 | ||
| 38 | #define UTMI_CTRL_ARC_PULLDN_SHIFT 12 | ||
| 39 | #define UTMI_CTRL_PLL_PWR_UP_SHIFT 1 | ||
| 40 | #define UTMI_CTRL_PWR_UP_SHIFT 0 | ||
| 41 | /* For UTMI_PLL Register */ | ||
| 42 | #define UTMI_PLL_CLK_BLK_EN_SHIFT 24 | ||
| 43 | #define UTMI_PLL_FBDIV_SHIFT 4 | ||
| 44 | #define UTMI_PLL_REFDIV_SHIFT 0 | ||
| 45 | #define UTMI_PLL_FBDIV_MASK 0x00000FF0 | ||
| 46 | #define UTMI_PLL_REFDIV_MASK 0x0000000F | ||
| 47 | #define UTMI_PLL_ICP_MASK 0x00007000 | ||
| 48 | #define UTMI_PLL_KVCO_MASK 0x00031000 | ||
| 49 | #define UTMI_PLL_PLLCALI12_SHIFT 29 | ||
| 50 | #define UTMI_PLL_PLLCALI12_MASK (0x3 << 29) | ||
| 51 | #define UTMI_PLL_PLLVDD18_SHIFT 27 | ||
| 52 | #define UTMI_PLL_PLLVDD18_MASK (0x3 << 27) | ||
| 53 | #define UTMI_PLL_PLLVDD12_SHIFT 25 | ||
| 54 | #define UTMI_PLL_PLLVDD12_MASK (0x3 << 25) | ||
| 55 | #define UTMI_PLL_KVCO_SHIFT 15 | ||
| 56 | #define UTMI_PLL_ICP_SHIFT 12 | ||
| 57 | /* For UTMI_TX Register */ | ||
| 58 | #define UTMI_TX_REG_EXT_FS_RCAL_SHIFT 27 | ||
| 59 | #define UTMI_TX_REG_EXT_FS_RCAL_MASK (0xf << 27) | ||
| 60 | #define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK 26 | ||
| 61 | #define UTMI_TX_REG_EXT_FS_RCAL_EN (0x1 << 26) | ||
| 62 | #define UTMI_TX_LOW_VDD_EN_SHIFT 11 | ||
| 63 | #define UTMI_TX_IMPCAL_VTH_SHIFT 14 | ||
| 64 | #define UTMI_TX_IMPCAL_VTH_MASK (0x7 << 14) | ||
| 65 | #define UTMI_TX_CK60_PHSEL_SHIFT 17 | ||
| 66 | #define UTMI_TX_CK60_PHSEL_MASK (0xf << 17) | ||
| 67 | #define UTMI_TX_TXVDD12_SHIFT 22 | ||
| 68 | #define UTMI_TX_TXVDD12_MASK (0x3 << 22) | ||
| 69 | #define UTMI_TX_AMP_SHIFT 0 | ||
| 70 | #define UTMI_TX_AMP_MASK (0x7 << 0) | ||
| 71 | /* For UTMI_RX Register */ | ||
| 72 | #define UTMI_RX_SQ_THRESH_SHIFT 4 | ||
| 73 | #define UTMI_RX_SQ_THRESH_MASK (0xf << 4) | ||
| 74 | #define UTMI_REG_SQ_LENGTH_SHIFT 15 | ||
| 75 | #define UTMI_REG_SQ_LENGTH_MASK (0x3 << 15) | ||
| 76 | |||
| 77 | #define REG_RCAL_START 0x00001000 | ||
| 78 | #define VCOCAL_START 0x00200000 | ||
| 79 | #define KVCO_EXT 0x00400000 | ||
| 80 | #define PLL_READY 0x00800000 | ||
| 81 | #define CLK_BLK_EN 0x01000000 | ||
| 82 | #endif | ||
| 83 | |||
| 84 | static unsigned int u2o_read(unsigned int base, unsigned int offset) | ||
| 85 | { | ||
| 86 | return readl(base + offset); | ||
| 87 | } | ||
| 88 | |||
| 89 | static void u2o_set(unsigned int base, unsigned int offset, unsigned int value) | ||
| 90 | { | ||
| 91 | unsigned int reg; | ||
| 92 | |||
| 93 | reg = readl(base + offset); | ||
| 94 | reg |= value; | ||
| 95 | writel(reg, base + offset); | ||
| 96 | readl(base + offset); | ||
| 97 | } | ||
| 98 | |||
| 99 | static void u2o_clear(unsigned int base, unsigned int offset, | ||
| 100 | unsigned int value) | ||
| 101 | { | ||
| 102 | unsigned int reg; | ||
| 103 | |||
| 104 | reg = readl(base + offset); | ||
| 105 | reg &= ~value; | ||
| 106 | writel(reg, base + offset); | ||
| 107 | readl(base + offset); | ||
| 108 | } | ||
| 109 | |||
| 110 | static void u2o_write(unsigned int base, unsigned int offset, | ||
| 111 | unsigned int value) | ||
| 112 | { | ||
| 113 | writel(value, base + offset); | ||
| 114 | readl(base + offset); | ||
| 115 | } | ||
| 116 | |||
| 117 | #ifdef CONFIG_ARCH_MMP | ||
| 118 | int mv_udc_phy_init(unsigned int base) | ||
| 119 | { | ||
| 120 | unsigned long timeout; | ||
| 121 | |||
| 122 | /* Initialize the USB PHY power */ | ||
| 123 | if (cpu_is_pxa910()) { | ||
| 124 | u2o_set(base, UTMI_CTRL, (1 << UTMI_CTRL_INPKT_DELAY_SOF_SHIFT) | ||
| 125 | | (1 << UTMI_CTRL_PU_REF_SHIFT)); | ||
| 126 | } | ||
| 127 | |||
| 128 | u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PLL_PWR_UP_SHIFT); | ||
| 129 | u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PWR_UP_SHIFT); | ||
| 130 | |||
| 131 | /* UTMI_PLL settings */ | ||
| 132 | u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK | ||
| 133 | | UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK | ||
| 134 | | UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK | ||
| 135 | | UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK); | ||
| 136 | |||
| 137 | u2o_set(base, UTMI_PLL, (0xee << UTMI_PLL_FBDIV_SHIFT) | ||
| 138 | | (0xb << UTMI_PLL_REFDIV_SHIFT) | ||
| 139 | | (3 << UTMI_PLL_PLLVDD18_SHIFT) | ||
| 140 | | (3 << UTMI_PLL_PLLVDD12_SHIFT) | ||
| 141 | | (3 << UTMI_PLL_PLLCALI12_SHIFT) | ||
| 142 | | (1 << UTMI_PLL_ICP_SHIFT) | (3 << UTMI_PLL_KVCO_SHIFT)); | ||
| 143 | |||
| 144 | /* UTMI_TX */ | ||
| 145 | u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK | ||
| 146 | | UTMI_TX_TXVDD12_MASK | ||
| 147 | | UTMI_TX_CK60_PHSEL_MASK | UTMI_TX_IMPCAL_VTH_MASK | ||
| 148 | | UTMI_TX_REG_EXT_FS_RCAL_MASK | UTMI_TX_AMP_MASK); | ||
| 149 | u2o_set(base, UTMI_TX, (3 << UTMI_TX_TXVDD12_SHIFT) | ||
| 150 | | (4 << UTMI_TX_CK60_PHSEL_SHIFT) | ||
| 151 | | (4 << UTMI_TX_IMPCAL_VTH_SHIFT) | ||
| 152 | | (8 << UTMI_TX_REG_EXT_FS_RCAL_SHIFT) | ||
| 153 | | (3 << UTMI_TX_AMP_SHIFT)); | ||
| 154 | |||
| 155 | /* UTMI_RX */ | ||
| 156 | u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK | ||
| 157 | | UTMI_REG_SQ_LENGTH_MASK); | ||
| 158 | if (cpu_is_pxa168()) | ||
| 159 | u2o_set(base, UTMI_RX, (7 << UTMI_RX_SQ_THRESH_SHIFT) | ||
| 160 | | (2 << UTMI_REG_SQ_LENGTH_SHIFT)); | ||
| 161 | else | ||
| 162 | u2o_set(base, UTMI_RX, (0x7 << UTMI_RX_SQ_THRESH_SHIFT) | ||
| 163 | | (2 << UTMI_REG_SQ_LENGTH_SHIFT)); | ||
| 164 | |||
| 165 | /* UTMI_IVREF */ | ||
| 166 | if (cpu_is_pxa168()) | ||
| 167 | /* | ||
| 168 | * fixing Microsoft Altair board interface with NEC hub issue - | ||
| 169 | * Set UTMI_IVREF from 0x4a3 to 0x4bf | ||
| 170 | */ | ||
| 171 | u2o_write(base, UTMI_IVREF, 0x4bf); | ||
| 172 | |||
| 173 | /* calibrate */ | ||
| 174 | timeout = jiffies + 100; | ||
| 175 | while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) { | ||
| 176 | if (time_after(jiffies, timeout)) | ||
| 177 | return -ETIME; | ||
| 178 | cpu_relax(); | ||
| 179 | } | ||
| 180 | |||
| 181 | /* toggle VCOCAL_START bit of UTMI_PLL */ | ||
| 182 | udelay(200); | ||
| 183 | u2o_set(base, UTMI_PLL, VCOCAL_START); | ||
| 184 | udelay(40); | ||
| 185 | u2o_clear(base, UTMI_PLL, VCOCAL_START); | ||
| 186 | |||
| 187 | /* toggle REG_RCAL_START bit of UTMI_TX */ | ||
| 188 | udelay(200); | ||
| 189 | u2o_set(base, UTMI_TX, REG_RCAL_START); | ||
| 190 | udelay(40); | ||
| 191 | u2o_clear(base, UTMI_TX, REG_RCAL_START); | ||
| 192 | udelay(200); | ||
| 193 | |||
| 194 | /* make sure phy is ready */ | ||
| 195 | timeout = jiffies + 100; | ||
| 196 | while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) { | ||
| 197 | if (time_after(jiffies, timeout)) | ||
| 198 | return -ETIME; | ||
| 199 | cpu_relax(); | ||
| 200 | } | ||
| 201 | |||
| 202 | if (cpu_is_pxa168()) { | ||
| 203 | u2o_set(base, UTMI_RESERVE, 1 << 5); | ||
| 204 | /* Turn on UTMI PHY OTG extension */ | ||
| 205 | u2o_write(base, UTMI_OTG_ADDON, 1); | ||
| 206 | } | ||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | #else | ||
| 210 | int mv_udc_phy_init(unsigned int base) | ||
| 211 | { | ||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | #endif | ||
diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c new file mode 100644 index 00000000000..59ffe1ecf1c --- /dev/null +++ b/drivers/usb/gadget/u_audio.c | |||
| @@ -0,0 +1,327 @@ | |||
| 1 | /* | ||
| 2 | * u_audio.c -- ALSA audio utilities for Gadget stack | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org> | ||
| 5 | * Copyright (C) 2008 Analog Devices, Inc | ||
| 6 | * | ||
| 7 | * Enter bugs at http://blackfin.uclinux.org/ | ||
| 8 | * | ||
| 9 | * Licensed under the GPL-2 or later. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/slab.h> | ||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/ctype.h> | ||
| 17 | #include <linux/random.h> | ||
| 18 | #include <linux/syscalls.h> | ||
| 19 | |||
| 20 | #include "u_audio.h" | ||
| 21 | |||
| 22 | /* | ||
| 23 | * This component encapsulates the ALSA devices for USB audio gadget | ||
| 24 | */ | ||
| 25 | |||
| 26 | #define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" | ||
| 27 | #define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" | ||
| 28 | #define FILE_CONTROL "/dev/snd/controlC0" | ||
| 29 | |||
| 30 | static char *fn_play = FILE_PCM_PLAYBACK; | ||
| 31 | module_param(fn_play, charp, S_IRUGO); | ||
| 32 | MODULE_PARM_DESC(fn_play, "Playback PCM device file name"); | ||
| 33 | |||
| 34 | static char *fn_cap = FILE_PCM_CAPTURE; | ||
| 35 | module_param(fn_cap, charp, S_IRUGO); | ||
| 36 | MODULE_PARM_DESC(fn_cap, "Capture PCM device file name"); | ||
| 37 | |||
| 38 | static char *fn_cntl = FILE_CONTROL; | ||
| 39 | module_param(fn_cntl, charp, S_IRUGO); | ||
| 40 | MODULE_PARM_DESC(fn_cntl, "Control device file name"); | ||
| 41 | |||
| 42 | /*-------------------------------------------------------------------------*/ | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Some ALSA internal helper functions | ||
| 46 | */ | ||
| 47 | static int snd_interval_refine_set(struct snd_interval *i, unsigned int val) | ||
| 48 | { | ||
| 49 | struct snd_interval t; | ||
| 50 | t.empty = 0; | ||
| 51 | t.min = t.max = val; | ||
| 52 | t.openmin = t.openmax = 0; | ||
| 53 | t.integer = 1; | ||
| 54 | return snd_interval_refine(i, &t); | ||
| 55 | } | ||
| 56 | |||
| 57 | static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, | ||
| 58 | snd_pcm_hw_param_t var, unsigned int val, | ||
| 59 | int dir) | ||
| 60 | { | ||
| 61 | int changed; | ||
| 62 | if (hw_is_mask(var)) { | ||
| 63 | struct snd_mask *m = hw_param_mask(params, var); | ||
| 64 | if (val == 0 && dir < 0) { | ||
| 65 | changed = -EINVAL; | ||
| 66 | snd_mask_none(m); | ||
| 67 | } else { | ||
| 68 | if (dir > 0) | ||
| 69 | val++; | ||
| 70 | else if (dir < 0) | ||
| 71 | val--; | ||
| 72 | changed = snd_mask_refine_set( | ||
| 73 | hw_param_mask(params, var), val); | ||
| 74 | } | ||
| 75 | } else if (hw_is_interval(var)) { | ||
| 76 | struct snd_interval *i = hw_param_interval(params, var); | ||
| 77 | if (val == 0 && dir < 0) { | ||
| 78 | changed = -EINVAL; | ||
| 79 | snd_interval_none(i); | ||
| 80 | } else if (dir == 0) | ||
| 81 | changed = snd_interval_refine_set(i, val); | ||
| 82 | else { | ||
| 83 | struct snd_interval t; | ||
| 84 | t.openmin = 1; | ||
| 85 | t.openmax = 1; | ||
| 86 | t.empty = 0; | ||
| 87 | t.integer = 0; | ||
| 88 | if (dir < 0) { | ||
| 89 | t.min = val - 1; | ||
| 90 | t.max = val; | ||
| 91 | } else { | ||
| 92 | t.min = val; | ||
| 93 | t.max = val+1; | ||
| 94 | } | ||
| 95 | changed = snd_interval_refine(i, &t); | ||
| 96 | } | ||
| 97 | } else | ||
| 98 | return -EINVAL; | ||
| 99 | if (changed) { | ||
| 100 | params->cmask |= 1 << var; | ||
| 101 | params->rmask |= 1 << var; | ||
| 102 | } | ||
| 103 | return changed; | ||
| 104 | } | ||
| 105 | /*-------------------------------------------------------------------------*/ | ||
| 106 | |||
| 107 | /** | ||
| 108 | * Set default hardware params | ||
| 109 | */ | ||
| 110 | static int playback_default_hw_params(struct gaudio_snd_dev *snd) | ||
| 111 | { | ||
| 112 | struct snd_pcm_substream *substream = snd->substream; | ||
| 113 | struct snd_pcm_hw_params *params; | ||
| 114 | snd_pcm_sframes_t result; | ||
| 115 | |||
| 116 | /* | ||
| 117 | * SNDRV_PCM_ACCESS_RW_INTERLEAVED, | ||
| 118 | * SNDRV_PCM_FORMAT_S16_LE | ||
| 119 | * CHANNELS: 2 | ||
| 120 | * RATE: 48000 | ||
| 121 | */ | ||
| 122 | snd->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED; | ||
| 123 | snd->format = SNDRV_PCM_FORMAT_S16_LE; | ||
| 124 | snd->channels = 2; | ||
| 125 | snd->rate = 48000; | ||
| 126 | |||
| 127 | params = kzalloc(sizeof(*params), GFP_KERNEL); | ||
| 128 | if (!params) | ||
| 129 | return -ENOMEM; | ||
| 130 | |||
| 131 | _snd_pcm_hw_params_any(params); | ||
| 132 | _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS, | ||
| 133 | snd->access, 0); | ||
| 134 | _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT, | ||
| 135 | snd->format, 0); | ||
| 136 | _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
| 137 | snd->channels, 0); | ||
| 138 | _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE, | ||
| 139 | snd->rate, 0); | ||
| 140 | |||
| 141 | snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); | ||
| 142 | snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, params); | ||
| 143 | |||
| 144 | result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); | ||
| 145 | if (result < 0) { | ||
| 146 | ERROR(snd->card, | ||
| 147 | "Preparing sound card failed: %d\n", (int)result); | ||
| 148 | kfree(params); | ||
| 149 | return result; | ||
| 150 | } | ||
| 151 | |||
| 152 | /* Store the hardware parameters */ | ||
| 153 | snd->access = params_access(params); | ||
| 154 | snd->format = params_format(params); | ||
| 155 | snd->channels = params_channels(params); | ||
| 156 | snd->rate = params_rate(params); | ||
| 157 | |||
| 158 | kfree(params); | ||
| 159 | |||
| 160 | INFO(snd->card, | ||
| 161 | "Hardware params: access %x, format %x, channels %d, rate %d\n", | ||
| 162 | snd->access, snd->format, snd->channels, snd->rate); | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | /** | ||
| 168 | * Playback audio buffer data by ALSA PCM device | ||
| 169 | */ | ||
| 170 | static size_t u_audio_playback(struct gaudio *card, void *buf, size_t count) | ||
| 171 | { | ||
| 172 | struct gaudio_snd_dev *snd = &card->playback; | ||
| 173 | struct snd_pcm_substream *substream = snd->substream; | ||
| 174 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 175 | mm_segment_t old_fs; | ||
| 176 | ssize_t result; | ||
| 177 | snd_pcm_sframes_t frames; | ||
| 178 | |||
| 179 | try_again: | ||
| 180 | if (runtime->status->state == SNDRV_PCM_STATE_XRUN || | ||
| 181 | runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { | ||
| 182 | result = snd_pcm_kernel_ioctl(substream, | ||
| 183 | SNDRV_PCM_IOCTL_PREPARE, NULL); | ||
| 184 | if (result < 0) { | ||
| 185 | ERROR(card, "Preparing sound card failed: %d\n", | ||
| 186 | (int)result); | ||
| 187 | return result; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | frames = bytes_to_frames(runtime, count); | ||
| 192 | old_fs = get_fs(); | ||
| 193 | set_fs(KERNEL_DS); | ||
| 194 | result = snd_pcm_lib_write(snd->substream, buf, frames); | ||
| 195 | if (result != frames) { | ||
| 196 | ERROR(card, "Playback error: %d\n", (int)result); | ||
| 197 | set_fs(old_fs); | ||
| 198 | goto try_again; | ||
| 199 | } | ||
| 200 | set_fs(old_fs); | ||
| 201 | |||
| 202 | return 0; | ||
| 203 | } | ||
| 204 | |||
| 205 | static int u_audio_get_playback_channels(struct gaudio *card) | ||
| 206 | { | ||
| 207 | return card->playback.channels; | ||
| 208 | } | ||
| 209 | |||
| 210 | static int u_audio_get_playback_rate(struct gaudio *card) | ||
| 211 | { | ||
| 212 | return card->playback.rate; | ||
| 213 | } | ||
| 214 | |||
| 215 | /** | ||
| 216 | * Open ALSA PCM and control device files | ||
| 217 | * Initial the PCM or control device | ||
| 218 | */ | ||
| 219 | static int gaudio_open_snd_dev(struct gaudio *card) | ||
| 220 | { | ||
| 221 | struct snd_pcm_file *pcm_file; | ||
| 222 | struct gaudio_snd_dev *snd; | ||
| 223 | |||
| 224 | if (!card) | ||
| 225 | return -ENODEV; | ||
| 226 | |||
| 227 | /* Open control device */ | ||
| 228 | snd = &card->control; | ||
| 229 | snd->filp = filp_open(fn_cntl, O_RDWR, 0); | ||
| 230 | if (IS_ERR(snd->filp)) { | ||
| 231 | int ret = PTR_ERR(snd->filp); | ||
| 232 | ERROR(card, "unable to open sound control device file: %s\n", | ||
| 233 | fn_cntl); | ||
| 234 | snd->filp = NULL; | ||
| 235 | return ret; | ||
| 236 | } | ||
| 237 | snd->card = card; | ||
| 238 | |||
| 239 | /* Open PCM playback device and setup substream */ | ||
| 240 | snd = &card->playback; | ||
| 241 | snd->filp = filp_open(fn_play, O_WRONLY, 0); | ||
| 242 | if (IS_ERR(snd->filp)) { | ||
| 243 | ERROR(card, "No such PCM playback device: %s\n", fn_play); | ||
| 244 | snd->filp = NULL; | ||
| 245 | } | ||
| 246 | pcm_file = snd->filp->private_data; | ||
| 247 | snd->substream = pcm_file->substream; | ||
| 248 | snd->card = card; | ||
| 249 | playback_default_hw_params(snd); | ||
| 250 | |||
| 251 | /* Open PCM capture device and setup substream */ | ||
| 252 | snd = &card->capture; | ||
| 253 | snd->filp = filp_open(fn_cap, O_RDONLY, 0); | ||
| 254 | if (IS_ERR(snd->filp)) { | ||
| 255 | ERROR(card, "No such PCM capture device: %s\n", fn_cap); | ||
| 256 | snd->substream = NULL; | ||
| 257 | snd->card = NULL; | ||
| 258 | snd->filp = NULL; | ||
| 259 | } else { | ||
| 260 | pcm_file = snd->filp->private_data; | ||
| 261 | snd->substream = pcm_file->substream; | ||
| 262 | snd->card = card; | ||
| 263 | } | ||
| 264 | |||
| 265 | return 0; | ||
| 266 | } | ||
| 267 | |||
| 268 | /** | ||
| 269 | * Close ALSA PCM and control device files | ||
| 270 | */ | ||
| 271 | static int gaudio_close_snd_dev(struct gaudio *gau) | ||
| 272 | { | ||
| 273 | struct gaudio_snd_dev *snd; | ||
| 274 | |||
| 275 | /* Close control device */ | ||
| 276 | snd = &gau->control; | ||
| 277 | if (snd->filp) | ||
| 278 | filp_close(snd->filp, current->files); | ||
| 279 | |||
| 280 | /* Close PCM playback device and setup substream */ | ||
| 281 | snd = &gau->playback; | ||
| 282 | if (snd->filp) | ||
| 283 | filp_close(snd->filp, current->files); | ||
| 284 | |||
| 285 | /* Close PCM capture device and setup substream */ | ||
| 286 | snd = &gau->capture; | ||
| 287 | if (snd->filp) | ||
| 288 | filp_close(snd->filp, current->files); | ||
| 289 | |||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | |||
| 293 | static struct gaudio *the_card; | ||
| 294 | /** | ||
| 295 | * gaudio_setup - setup ALSA interface and preparing for USB transfer | ||
| 296 | * | ||
| 297 | * This sets up PCM, mixer or MIDI ALSA devices fore USB gadget using. | ||
| 298 | * | ||
| 299 | * Returns negative errno, or zero on success | ||
| 300 | */ | ||
| 301 | int __init gaudio_setup(struct gaudio *card) | ||
| 302 | { | ||
| 303 | int ret; | ||
| 304 | |||
| 305 | ret = gaudio_open_snd_dev(card); | ||
| 306 | if (ret) | ||
| 307 | ERROR(card, "we need at least one control device\n"); | ||
| 308 | else if (!the_card) | ||
| 309 | the_card = card; | ||
| 310 | |||
| 311 | return ret; | ||
| 312 | |||
| 313 | } | ||
| 314 | |||
| 315 | /** | ||
| 316 | * gaudio_cleanup - remove ALSA device interface | ||
| 317 | * | ||
| 318 | * This is called to free all resources allocated by @gaudio_setup(). | ||
| 319 | */ | ||
| 320 | void gaudio_cleanup(void) | ||
| 321 | { | ||
| 322 | if (the_card) { | ||
| 323 | gaudio_close_snd_dev(the_card); | ||
| 324 | the_card = NULL; | ||
| 325 | } | ||
| 326 | } | ||
| 327 | |||
diff --git a/drivers/usb/gadget/u_audio.h b/drivers/usb/gadget/u_audio.h new file mode 100644 index 00000000000..08ffce3298e --- /dev/null +++ b/drivers/usb/gadget/u_audio.h | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* | ||
| 2 | * u_audio.h -- interface to USB gadget "ALSA AUDIO" utilities | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org> | ||
| 5 | * Copyright (C) 2008 Analog Devices, Inc | ||
| 6 | * | ||
| 7 | * Enter bugs at http://blackfin.uclinux.org/ | ||
| 8 | * | ||
| 9 | * Licensed under the GPL-2 or later. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __U_AUDIO_H | ||
| 13 | #define __U_AUDIO_H | ||
| 14 | |||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/usb/audio.h> | ||
| 18 | #include <linux/usb/composite.h> | ||
| 19 | |||
| 20 | #include <sound/core.h> | ||
| 21 | #include <sound/pcm.h> | ||
| 22 | #include <sound/pcm_params.h> | ||
| 23 | |||
| 24 | #include "gadget_chips.h" | ||
| 25 | |||
| 26 | /* | ||
| 27 | * This represents the USB side of an audio card device, managed by a USB | ||
| 28 | * function which provides control and stream interfaces. | ||
| 29 | */ | ||
| 30 | |||
| 31 | struct gaudio_snd_dev { | ||
| 32 | struct gaudio *card; | ||
| 33 | struct file *filp; | ||
| 34 | struct snd_pcm_substream *substream; | ||
| 35 | int access; | ||
| 36 | int format; | ||
| 37 | int channels; | ||
| 38 | int rate; | ||
| 39 | }; | ||
| 40 | |||
| 41 | struct gaudio { | ||
| 42 | struct usb_function func; | ||
| 43 | struct usb_gadget *gadget; | ||
| 44 | |||
| 45 | /* ALSA sound device interfaces */ | ||
| 46 | struct gaudio_snd_dev control; | ||
| 47 | struct gaudio_snd_dev playback; | ||
| 48 | struct gaudio_snd_dev capture; | ||
| 49 | |||
| 50 | /* TODO */ | ||
| 51 | }; | ||
| 52 | |||
| 53 | int gaudio_setup(struct gaudio *card); | ||
| 54 | void gaudio_cleanup(void); | ||
| 55 | |||
| 56 | #endif /* __U_AUDIO_H */ | ||
