diff options
Diffstat (limited to 'drivers/usb')
39 files changed, 25590 insertions, 0 deletions
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c new file mode 100644 index 00000000000..2278dad886e --- /dev/null +++ b/drivers/usb/core/inode.c | |||
@@ -0,0 +1,776 @@ | |||
1 | /*****************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * inode.c -- Inode/Dentry functions for the USB device file system. | ||
5 | * | ||
6 | * Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) | ||
7 | * Copyright (C) 2001,2002,2004 Greg Kroah-Hartman (greg@kroah.com) | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | * History: | ||
24 | * 0.1 04.01.2000 Created | ||
25 | * 0.2 10.12.2001 converted to use the vfs layer better | ||
26 | */ | ||
27 | |||
28 | /*****************************************************************************/ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/fs.h> | ||
32 | #include <linux/mount.h> | ||
33 | #include <linux/pagemap.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/proc_fs.h> | ||
36 | #include <linux/usb.h> | ||
37 | #include <linux/namei.h> | ||
38 | #include <linux/usbdevice_fs.h> | ||
39 | #include <linux/parser.h> | ||
40 | #include <linux/notifier.h> | ||
41 | #include <linux/seq_file.h> | ||
42 | #include <linux/usb/hcd.h> | ||
43 | #include <asm/byteorder.h> | ||
44 | #include "usb.h" | ||
45 | |||
46 | #define USBFS_DEFAULT_DEVMODE (S_IWUSR | S_IRUGO) | ||
47 | #define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO) | ||
48 | #define USBFS_DEFAULT_LISTMODE S_IRUGO | ||
49 | |||
50 | static const struct file_operations default_file_operations; | ||
51 | static struct vfsmount *usbfs_mount; | ||
52 | static int usbfs_mount_count; /* = 0 */ | ||
53 | static int ignore_mount = 0; | ||
54 | |||
55 | static struct dentry *devices_usbfs_dentry; | ||
56 | static int num_buses; /* = 0 */ | ||
57 | |||
58 | static uid_t devuid; /* = 0 */ | ||
59 | static uid_t busuid; /* = 0 */ | ||
60 | static uid_t listuid; /* = 0 */ | ||
61 | static gid_t devgid; /* = 0 */ | ||
62 | static gid_t busgid; /* = 0 */ | ||
63 | static gid_t listgid; /* = 0 */ | ||
64 | static umode_t devmode = USBFS_DEFAULT_DEVMODE; | ||
65 | static umode_t busmode = USBFS_DEFAULT_BUSMODE; | ||
66 | static umode_t listmode = USBFS_DEFAULT_LISTMODE; | ||
67 | |||
68 | static int usbfs_show_options(struct seq_file *seq, struct vfsmount *mnt) | ||
69 | { | ||
70 | if (devuid != 0) | ||
71 | seq_printf(seq, ",devuid=%u", devuid); | ||
72 | if (devgid != 0) | ||
73 | seq_printf(seq, ",devgid=%u", devgid); | ||
74 | if (devmode != USBFS_DEFAULT_DEVMODE) | ||
75 | seq_printf(seq, ",devmode=%o", devmode); | ||
76 | if (busuid != 0) | ||
77 | seq_printf(seq, ",busuid=%u", busuid); | ||
78 | if (busgid != 0) | ||
79 | seq_printf(seq, ",busgid=%u", busgid); | ||
80 | if (busmode != USBFS_DEFAULT_BUSMODE) | ||
81 | seq_printf(seq, ",busmode=%o", busmode); | ||
82 | if (listuid != 0) | ||
83 | seq_printf(seq, ",listuid=%u", listuid); | ||
84 | if (listgid != 0) | ||
85 | seq_printf(seq, ",listgid=%u", listgid); | ||
86 | if (listmode != USBFS_DEFAULT_LISTMODE) | ||
87 | seq_printf(seq, ",listmode=%o", listmode); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | enum { | ||
93 | Opt_devuid, Opt_devgid, Opt_devmode, | ||
94 | Opt_busuid, Opt_busgid, Opt_busmode, | ||
95 | Opt_listuid, Opt_listgid, Opt_listmode, | ||
96 | Opt_err, | ||
97 | }; | ||
98 | |||
99 | static const match_table_t tokens = { | ||
100 | {Opt_devuid, "devuid=%u"}, | ||
101 | {Opt_devgid, "devgid=%u"}, | ||
102 | {Opt_devmode, "devmode=%o"}, | ||
103 | {Opt_busuid, "busuid=%u"}, | ||
104 | {Opt_busgid, "busgid=%u"}, | ||
105 | {Opt_busmode, "busmode=%o"}, | ||
106 | {Opt_listuid, "listuid=%u"}, | ||
107 | {Opt_listgid, "listgid=%u"}, | ||
108 | {Opt_listmode, "listmode=%o"}, | ||
109 | {Opt_err, NULL} | ||
110 | }; | ||
111 | |||
112 | static int parse_options(struct super_block *s, char *data) | ||
113 | { | ||
114 | char *p; | ||
115 | int option; | ||
116 | |||
117 | /* (re)set to defaults. */ | ||
118 | devuid = 0; | ||
119 | busuid = 0; | ||
120 | listuid = 0; | ||
121 | devgid = 0; | ||
122 | busgid = 0; | ||
123 | listgid = 0; | ||
124 | devmode = USBFS_DEFAULT_DEVMODE; | ||
125 | busmode = USBFS_DEFAULT_BUSMODE; | ||
126 | listmode = USBFS_DEFAULT_LISTMODE; | ||
127 | |||
128 | while ((p = strsep(&data, ",")) != NULL) { | ||
129 | substring_t args[MAX_OPT_ARGS]; | ||
130 | int token; | ||
131 | if (!*p) | ||
132 | continue; | ||
133 | |||
134 | token = match_token(p, tokens, args); | ||
135 | switch (token) { | ||
136 | case Opt_devuid: | ||
137 | if (match_int(&args[0], &option)) | ||
138 | return -EINVAL; | ||
139 | devuid = option; | ||
140 | break; | ||
141 | case Opt_devgid: | ||
142 | if (match_int(&args[0], &option)) | ||
143 | return -EINVAL; | ||
144 | devgid = option; | ||
145 | break; | ||
146 | case Opt_devmode: | ||
147 | if (match_octal(&args[0], &option)) | ||
148 | return -EINVAL; | ||
149 | devmode = option & S_IRWXUGO; | ||
150 | break; | ||
151 | case Opt_busuid: | ||
152 | if (match_int(&args[0], &option)) | ||
153 | return -EINVAL; | ||
154 | busuid = option; | ||
155 | break; | ||
156 | case Opt_busgid: | ||
157 | if (match_int(&args[0], &option)) | ||
158 | return -EINVAL; | ||
159 | busgid = option; | ||
160 | break; | ||
161 | case Opt_busmode: | ||
162 | if (match_octal(&args[0], &option)) | ||
163 | return -EINVAL; | ||
164 | busmode = option & S_IRWXUGO; | ||
165 | break; | ||
166 | case Opt_listuid: | ||
167 | if (match_int(&args[0], &option)) | ||
168 | return -EINVAL; | ||
169 | listuid = option; | ||
170 | break; | ||
171 | case Opt_listgid: | ||
172 | if (match_int(&args[0], &option)) | ||
173 | return -EINVAL; | ||
174 | listgid = option; | ||
175 | break; | ||
176 | case Opt_listmode: | ||
177 | if (match_octal(&args[0], &option)) | ||
178 | return -EINVAL; | ||
179 | listmode = option & S_IRWXUGO; | ||
180 | break; | ||
181 | default: | ||
182 | printk(KERN_ERR "usbfs: unrecognised mount option " | ||
183 | "\"%s\" or missing value\n", p); | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static void update_special(struct dentry *special) | ||
192 | { | ||
193 | special->d_inode->i_uid = listuid; | ||
194 | special->d_inode->i_gid = listgid; | ||
195 | special->d_inode->i_mode = S_IFREG | listmode; | ||
196 | } | ||
197 | |||
198 | static void update_dev(struct dentry *dev) | ||
199 | { | ||
200 | dev->d_inode->i_uid = devuid; | ||
201 | dev->d_inode->i_gid = devgid; | ||
202 | dev->d_inode->i_mode = S_IFREG | devmode; | ||
203 | } | ||
204 | |||
205 | static void update_bus(struct dentry *bus) | ||
206 | { | ||
207 | struct dentry *dev = NULL; | ||
208 | |||
209 | bus->d_inode->i_uid = busuid; | ||
210 | bus->d_inode->i_gid = busgid; | ||
211 | bus->d_inode->i_mode = S_IFDIR | busmode; | ||
212 | |||
213 | mutex_lock(&bus->d_inode->i_mutex); | ||
214 | |||
215 | list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child) | ||
216 | if (dev->d_inode) | ||
217 | update_dev(dev); | ||
218 | |||
219 | mutex_unlock(&bus->d_inode->i_mutex); | ||
220 | } | ||
221 | |||
222 | static void update_sb(struct super_block *sb) | ||
223 | { | ||
224 | struct dentry *root = sb->s_root; | ||
225 | struct dentry *bus = NULL; | ||
226 | |||
227 | if (!root) | ||
228 | return; | ||
229 | |||
230 | mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT); | ||
231 | |||
232 | list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) { | ||
233 | if (bus->d_inode) { | ||
234 | switch (S_IFMT & bus->d_inode->i_mode) { | ||
235 | case S_IFDIR: | ||
236 | update_bus(bus); | ||
237 | break; | ||
238 | case S_IFREG: | ||
239 | update_special(bus); | ||
240 | break; | ||
241 | default: | ||
242 | printk(KERN_WARNING "usbfs: Unknown node %s " | ||
243 | "mode %x found on remount!\n", | ||
244 | bus->d_name.name, bus->d_inode->i_mode); | ||
245 | break; | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | |||
250 | mutex_unlock(&root->d_inode->i_mutex); | ||
251 | } | ||
252 | |||
253 | static int remount(struct super_block *sb, int *flags, char *data) | ||
254 | { | ||
255 | /* If this is not a real mount, | ||
256 | * i.e. it's a simple_pin_fs from create_special_files, | ||
257 | * then ignore it. | ||
258 | */ | ||
259 | if (ignore_mount) | ||
260 | return 0; | ||
261 | |||
262 | if (parse_options(sb, data)) { | ||
263 | printk(KERN_WARNING "usbfs: mount parameter error.\n"); | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | if (usbfs_mount && usbfs_mount->mnt_sb) | ||
268 | update_sb(usbfs_mount->mnt_sb); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t dev) | ||
274 | { | ||
275 | struct inode *inode = new_inode(sb); | ||
276 | |||
277 | if (inode) { | ||
278 | inode->i_ino = get_next_ino(); | ||
279 | inode->i_mode = mode; | ||
280 | inode->i_uid = current_fsuid(); | ||
281 | inode->i_gid = current_fsgid(); | ||
282 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
283 | switch (mode & S_IFMT) { | ||
284 | default: | ||
285 | init_special_inode(inode, mode, dev); | ||
286 | break; | ||
287 | case S_IFREG: | ||
288 | inode->i_fop = &default_file_operations; | ||
289 | break; | ||
290 | case S_IFDIR: | ||
291 | inode->i_op = &simple_dir_inode_operations; | ||
292 | inode->i_fop = &simple_dir_operations; | ||
293 | |||
294 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ | ||
295 | inc_nlink(inode); | ||
296 | break; | ||
297 | } | ||
298 | } | ||
299 | return inode; | ||
300 | } | ||
301 | |||
302 | /* SMP-safe */ | ||
303 | static int usbfs_mknod (struct inode *dir, struct dentry *dentry, int mode, | ||
304 | dev_t dev) | ||
305 | { | ||
306 | struct inode *inode = usbfs_get_inode(dir->i_sb, mode, dev); | ||
307 | int error = -EPERM; | ||
308 | |||
309 | if (dentry->d_inode) | ||
310 | return -EEXIST; | ||
311 | |||
312 | if (inode) { | ||
313 | d_instantiate(dentry, inode); | ||
314 | dget(dentry); | ||
315 | error = 0; | ||
316 | } | ||
317 | return error; | ||
318 | } | ||
319 | |||
320 | static int usbfs_mkdir (struct inode *dir, struct dentry *dentry, int mode) | ||
321 | { | ||
322 | int res; | ||
323 | |||
324 | mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; | ||
325 | res = usbfs_mknod (dir, dentry, mode, 0); | ||
326 | if (!res) | ||
327 | inc_nlink(dir); | ||
328 | return res; | ||
329 | } | ||
330 | |||
331 | static int usbfs_create (struct inode *dir, struct dentry *dentry, int mode) | ||
332 | { | ||
333 | mode = (mode & S_IALLUGO) | S_IFREG; | ||
334 | return usbfs_mknod (dir, dentry, mode, 0); | ||
335 | } | ||
336 | |||
337 | static inline int usbfs_positive (struct dentry *dentry) | ||
338 | { | ||
339 | return dentry->d_inode && !d_unhashed(dentry); | ||
340 | } | ||
341 | |||
342 | static int usbfs_empty (struct dentry *dentry) | ||
343 | { | ||
344 | struct list_head *list; | ||
345 | |||
346 | spin_lock(&dentry->d_lock); | ||
347 | list_for_each(list, &dentry->d_subdirs) { | ||
348 | struct dentry *de = list_entry(list, struct dentry, d_u.d_child); | ||
349 | |||
350 | spin_lock_nested(&de->d_lock, DENTRY_D_LOCK_NESTED); | ||
351 | if (usbfs_positive(de)) { | ||
352 | spin_unlock(&de->d_lock); | ||
353 | spin_unlock(&dentry->d_lock); | ||
354 | return 0; | ||
355 | } | ||
356 | spin_unlock(&de->d_lock); | ||
357 | } | ||
358 | spin_unlock(&dentry->d_lock); | ||
359 | return 1; | ||
360 | } | ||
361 | |||
362 | static int usbfs_unlink (struct inode *dir, struct dentry *dentry) | ||
363 | { | ||
364 | struct inode *inode = dentry->d_inode; | ||
365 | mutex_lock(&inode->i_mutex); | ||
366 | drop_nlink(dentry->d_inode); | ||
367 | dput(dentry); | ||
368 | mutex_unlock(&inode->i_mutex); | ||
369 | d_delete(dentry); | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static int usbfs_rmdir(struct inode *dir, struct dentry *dentry) | ||
374 | { | ||
375 | int error = -ENOTEMPTY; | ||
376 | struct inode * inode = dentry->d_inode; | ||
377 | |||
378 | mutex_lock(&inode->i_mutex); | ||
379 | dentry_unhash(dentry); | ||
380 | if (usbfs_empty(dentry)) { | ||
381 | dont_mount(dentry); | ||
382 | drop_nlink(dentry->d_inode); | ||
383 | drop_nlink(dentry->d_inode); | ||
384 | dput(dentry); | ||
385 | inode->i_flags |= S_DEAD; | ||
386 | drop_nlink(dir); | ||
387 | error = 0; | ||
388 | } | ||
389 | mutex_unlock(&inode->i_mutex); | ||
390 | if (!error) | ||
391 | d_delete(dentry); | ||
392 | return error; | ||
393 | } | ||
394 | |||
395 | |||
396 | /* default file operations */ | ||
397 | static ssize_t default_read_file (struct file *file, char __user *buf, | ||
398 | size_t count, loff_t *ppos) | ||
399 | { | ||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static ssize_t default_write_file (struct file *file, const char __user *buf, | ||
404 | size_t count, loff_t *ppos) | ||
405 | { | ||
406 | return count; | ||
407 | } | ||
408 | |||
409 | static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) | ||
410 | { | ||
411 | loff_t retval = -EINVAL; | ||
412 | |||
413 | mutex_lock(&file->f_path.dentry->d_inode->i_mutex); | ||
414 | switch(orig) { | ||
415 | case 0: | ||
416 | if (offset > 0) { | ||
417 | file->f_pos = offset; | ||
418 | retval = file->f_pos; | ||
419 | } | ||
420 | break; | ||
421 | case 1: | ||
422 | if ((offset + file->f_pos) > 0) { | ||
423 | file->f_pos += offset; | ||
424 | retval = file->f_pos; | ||
425 | } | ||
426 | break; | ||
427 | default: | ||
428 | break; | ||
429 | } | ||
430 | mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); | ||
431 | return retval; | ||
432 | } | ||
433 | |||
434 | static int default_open (struct inode *inode, struct file *file) | ||
435 | { | ||
436 | if (inode->i_private) | ||
437 | file->private_data = inode->i_private; | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static const struct file_operations default_file_operations = { | ||
443 | .read = default_read_file, | ||
444 | .write = default_write_file, | ||
445 | .open = default_open, | ||
446 | .llseek = default_file_lseek, | ||
447 | }; | ||
448 | |||
449 | static const struct super_operations usbfs_ops = { | ||
450 | .statfs = simple_statfs, | ||
451 | .drop_inode = generic_delete_inode, | ||
452 | .remount_fs = remount, | ||
453 | .show_options = usbfs_show_options, | ||
454 | }; | ||
455 | |||
456 | static int usbfs_fill_super(struct super_block *sb, void *data, int silent) | ||
457 | { | ||
458 | struct inode *inode; | ||
459 | struct dentry *root; | ||
460 | |||
461 | sb->s_blocksize = PAGE_CACHE_SIZE; | ||
462 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | ||
463 | sb->s_magic = USBDEVICE_SUPER_MAGIC; | ||
464 | sb->s_op = &usbfs_ops; | ||
465 | sb->s_time_gran = 1; | ||
466 | inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0); | ||
467 | |||
468 | if (!inode) { | ||
469 | dbg("%s: could not get inode!",__func__); | ||
470 | return -ENOMEM; | ||
471 | } | ||
472 | |||
473 | root = d_alloc_root(inode); | ||
474 | if (!root) { | ||
475 | dbg("%s: could not get root dentry!",__func__); | ||
476 | iput(inode); | ||
477 | return -ENOMEM; | ||
478 | } | ||
479 | sb->s_root = root; | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* | ||
484 | * fs_create_by_name - create a file, given a name | ||
485 | * @name: name of file | ||
486 | * @mode: type of file | ||
487 | * @parent: dentry of directory to create it in | ||
488 | * @dentry: resulting dentry of file | ||
489 | * | ||
490 | * This function handles both regular files and directories. | ||
491 | */ | ||
492 | static int fs_create_by_name (const char *name, mode_t mode, | ||
493 | struct dentry *parent, struct dentry **dentry) | ||
494 | { | ||
495 | int error = 0; | ||
496 | |||
497 | /* If the parent is not specified, we create it in the root. | ||
498 | * We need the root dentry to do this, which is in the super | ||
499 | * block. A pointer to that is in the struct vfsmount that we | ||
500 | * have around. | ||
501 | */ | ||
502 | if (!parent ) { | ||
503 | if (usbfs_mount && usbfs_mount->mnt_sb) { | ||
504 | parent = usbfs_mount->mnt_sb->s_root; | ||
505 | } | ||
506 | } | ||
507 | |||
508 | if (!parent) { | ||
509 | dbg("Ah! can not find a parent!"); | ||
510 | return -EFAULT; | ||
511 | } | ||
512 | |||
513 | *dentry = NULL; | ||
514 | mutex_lock(&parent->d_inode->i_mutex); | ||
515 | *dentry = lookup_one_len(name, parent, strlen(name)); | ||
516 | if (!IS_ERR(*dentry)) { | ||
517 | if ((mode & S_IFMT) == S_IFDIR) | ||
518 | error = usbfs_mkdir (parent->d_inode, *dentry, mode); | ||
519 | else | ||
520 | error = usbfs_create (parent->d_inode, *dentry, mode); | ||
521 | } else | ||
522 | error = PTR_ERR(*dentry); | ||
523 | mutex_unlock(&parent->d_inode->i_mutex); | ||
524 | |||
525 | return error; | ||
526 | } | ||
527 | |||
528 | static struct dentry *fs_create_file (const char *name, mode_t mode, | ||
529 | struct dentry *parent, void *data, | ||
530 | const struct file_operations *fops, | ||
531 | uid_t uid, gid_t gid) | ||
532 | { | ||
533 | struct dentry *dentry; | ||
534 | int error; | ||
535 | |||
536 | dbg("creating file '%s'",name); | ||
537 | |||
538 | error = fs_create_by_name (name, mode, parent, &dentry); | ||
539 | if (error) { | ||
540 | dentry = NULL; | ||
541 | } else { | ||
542 | if (dentry->d_inode) { | ||
543 | if (data) | ||
544 | dentry->d_inode->i_private = data; | ||
545 | if (fops) | ||
546 | dentry->d_inode->i_fop = fops; | ||
547 | dentry->d_inode->i_uid = uid; | ||
548 | dentry->d_inode->i_gid = gid; | ||
549 | } | ||
550 | } | ||
551 | |||
552 | return dentry; | ||
553 | } | ||
554 | |||
555 | static void fs_remove_file (struct dentry *dentry) | ||
556 | { | ||
557 | struct dentry *parent = dentry->d_parent; | ||
558 | |||
559 | if (!parent || !parent->d_inode) | ||
560 | return; | ||
561 | |||
562 | mutex_lock_nested(&parent->d_inode->i_mutex, I_MUTEX_PARENT); | ||
563 | if (usbfs_positive(dentry)) { | ||
564 | if (dentry->d_inode) { | ||
565 | if (S_ISDIR(dentry->d_inode->i_mode)) | ||
566 | usbfs_rmdir(parent->d_inode, dentry); | ||
567 | else | ||
568 | usbfs_unlink(parent->d_inode, dentry); | ||
569 | dput(dentry); | ||
570 | } | ||
571 | } | ||
572 | mutex_unlock(&parent->d_inode->i_mutex); | ||
573 | } | ||
574 | |||
575 | /* --------------------------------------------------------------------- */ | ||
576 | |||
577 | static struct dentry *usb_mount(struct file_system_type *fs_type, | ||
578 | int flags, const char *dev_name, void *data) | ||
579 | { | ||
580 | return mount_single(fs_type, flags, data, usbfs_fill_super); | ||
581 | } | ||
582 | |||
583 | static struct file_system_type usb_fs_type = { | ||
584 | .owner = THIS_MODULE, | ||
585 | .name = "usbfs", | ||
586 | .mount = usb_mount, | ||
587 | .kill_sb = kill_litter_super, | ||
588 | }; | ||
589 | |||
590 | /* --------------------------------------------------------------------- */ | ||
591 | |||
592 | static int create_special_files (void) | ||
593 | { | ||
594 | struct dentry *parent; | ||
595 | int retval; | ||
596 | |||
597 | /* the simple_pin_fs calls will call remount with no options | ||
598 | * without this flag that would overwrite the real mount options (if any) | ||
599 | */ | ||
600 | ignore_mount = 1; | ||
601 | |||
602 | /* create the devices special file */ | ||
603 | retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count); | ||
604 | if (retval) { | ||
605 | printk(KERN_ERR "Unable to get usbfs mount\n"); | ||
606 | goto exit; | ||
607 | } | ||
608 | |||
609 | ignore_mount = 0; | ||
610 | |||
611 | parent = usbfs_mount->mnt_sb->s_root; | ||
612 | devices_usbfs_dentry = fs_create_file ("devices", | ||
613 | listmode | S_IFREG, parent, | ||
614 | NULL, &usbfs_devices_fops, | ||
615 | listuid, listgid); | ||
616 | if (devices_usbfs_dentry == NULL) { | ||
617 | printk(KERN_ERR "Unable to create devices usbfs file\n"); | ||
618 | retval = -ENODEV; | ||
619 | goto error_clean_mounts; | ||
620 | } | ||
621 | |||
622 | goto exit; | ||
623 | |||
624 | error_clean_mounts: | ||
625 | simple_release_fs(&usbfs_mount, &usbfs_mount_count); | ||
626 | exit: | ||
627 | return retval; | ||
628 | } | ||
629 | |||
630 | static void remove_special_files (void) | ||
631 | { | ||
632 | if (devices_usbfs_dentry) | ||
633 | fs_remove_file (devices_usbfs_dentry); | ||
634 | devices_usbfs_dentry = NULL; | ||
635 | simple_release_fs(&usbfs_mount, &usbfs_mount_count); | ||
636 | } | ||
637 | |||
638 | void usbfs_update_special (void) | ||
639 | { | ||
640 | struct inode *inode; | ||
641 | |||
642 | if (devices_usbfs_dentry) { | ||
643 | inode = devices_usbfs_dentry->d_inode; | ||
644 | if (inode) | ||
645 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
646 | } | ||
647 | } | ||
648 | |||
649 | static void usbfs_add_bus(struct usb_bus *bus) | ||
650 | { | ||
651 | struct dentry *parent; | ||
652 | char name[8]; | ||
653 | int retval; | ||
654 | |||
655 | /* create the special files if this is the first bus added */ | ||
656 | if (num_buses == 0) { | ||
657 | retval = create_special_files(); | ||
658 | if (retval) | ||
659 | return; | ||
660 | } | ||
661 | ++num_buses; | ||
662 | |||
663 | sprintf (name, "%03d", bus->busnum); | ||
664 | |||
665 | parent = usbfs_mount->mnt_sb->s_root; | ||
666 | bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent, | ||
667 | bus, NULL, busuid, busgid); | ||
668 | if (bus->usbfs_dentry == NULL) { | ||
669 | printk(KERN_ERR "Error creating usbfs bus entry\n"); | ||
670 | return; | ||
671 | } | ||
672 | } | ||
673 | |||
674 | static void usbfs_remove_bus(struct usb_bus *bus) | ||
675 | { | ||
676 | if (bus->usbfs_dentry) { | ||
677 | fs_remove_file (bus->usbfs_dentry); | ||
678 | bus->usbfs_dentry = NULL; | ||
679 | } | ||
680 | |||
681 | --num_buses; | ||
682 | if (num_buses <= 0) { | ||
683 | remove_special_files(); | ||
684 | num_buses = 0; | ||
685 | } | ||
686 | } | ||
687 | |||
688 | static void usbfs_add_device(struct usb_device *dev) | ||
689 | { | ||
690 | char name[8]; | ||
691 | int i; | ||
692 | int i_size; | ||
693 | |||
694 | sprintf (name, "%03d", dev->devnum); | ||
695 | dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG, | ||
696 | dev->bus->usbfs_dentry, dev, | ||
697 | &usbdev_file_operations, | ||
698 | devuid, devgid); | ||
699 | if (dev->usbfs_dentry == NULL) { | ||
700 | printk(KERN_ERR "Error creating usbfs device entry\n"); | ||
701 | return; | ||
702 | } | ||
703 | |||
704 | /* Set the size of the device's file to be | ||
705 | * equal to the size of the device descriptors. */ | ||
706 | i_size = sizeof (struct usb_device_descriptor); | ||
707 | for (i = 0; i < dev->descriptor.bNumConfigurations; ++i) { | ||
708 | struct usb_config_descriptor *config = | ||
709 | (struct usb_config_descriptor *)dev->rawdescriptors[i]; | ||
710 | i_size += le16_to_cpu(config->wTotalLength); | ||
711 | } | ||
712 | if (dev->usbfs_dentry->d_inode) | ||
713 | dev->usbfs_dentry->d_inode->i_size = i_size; | ||
714 | } | ||
715 | |||
716 | static void usbfs_remove_device(struct usb_device *dev) | ||
717 | { | ||
718 | if (dev->usbfs_dentry) { | ||
719 | fs_remove_file (dev->usbfs_dentry); | ||
720 | dev->usbfs_dentry = NULL; | ||
721 | } | ||
722 | } | ||
723 | |||
724 | static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev) | ||
725 | { | ||
726 | switch (action) { | ||
727 | case USB_DEVICE_ADD: | ||
728 | usbfs_add_device(dev); | ||
729 | break; | ||
730 | case USB_DEVICE_REMOVE: | ||
731 | usbfs_remove_device(dev); | ||
732 | break; | ||
733 | case USB_BUS_ADD: | ||
734 | usbfs_add_bus(dev); | ||
735 | break; | ||
736 | case USB_BUS_REMOVE: | ||
737 | usbfs_remove_bus(dev); | ||
738 | } | ||
739 | |||
740 | usbfs_update_special(); | ||
741 | usbfs_conn_disc_event(); | ||
742 | return NOTIFY_OK; | ||
743 | } | ||
744 | |||
745 | static struct notifier_block usbfs_nb = { | ||
746 | .notifier_call = usbfs_notify, | ||
747 | }; | ||
748 | |||
749 | /* --------------------------------------------------------------------- */ | ||
750 | |||
751 | static struct proc_dir_entry *usbdir = NULL; | ||
752 | |||
753 | int __init usbfs_init(void) | ||
754 | { | ||
755 | int retval; | ||
756 | |||
757 | retval = register_filesystem(&usb_fs_type); | ||
758 | if (retval) | ||
759 | return retval; | ||
760 | |||
761 | usb_register_notify(&usbfs_nb); | ||
762 | |||
763 | /* create mount point for usbfs */ | ||
764 | usbdir = proc_mkdir("bus/usb", NULL); | ||
765 | |||
766 | return 0; | ||
767 | } | ||
768 | |||
769 | void usbfs_cleanup(void) | ||
770 | { | ||
771 | usb_unregister_notify(&usbfs_nb); | ||
772 | unregister_filesystem(&usb_fs_type); | ||
773 | if (usbdir) | ||
774 | remove_proc_entry("bus/usb", NULL); | ||
775 | } | ||
776 | |||
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 */ | ||
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c new file mode 100644 index 00000000000..4d2e88d04da --- /dev/null +++ b/drivers/usb/host/ehci-ath79.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * Bus Glue for Atheros AR7XXX/AR9XXX built-in EHCI controller. | ||
3 | * | ||
4 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
6 | * | ||
7 | * Parts of this file are based on Atheros' 2.6.15 BSP | ||
8 | * Copyright (C) 2007 Atheros Communications, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License version 2 as published | ||
12 | * by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/platform_device.h> | ||
16 | |||
17 | enum { | ||
18 | EHCI_ATH79_IP_V1 = 0, | ||
19 | EHCI_ATH79_IP_V2, | ||
20 | }; | ||
21 | |||
22 | static const struct platform_device_id ehci_ath79_id_table[] = { | ||
23 | { | ||
24 | .name = "ar71xx-ehci", | ||
25 | .driver_data = EHCI_ATH79_IP_V1, | ||
26 | }, | ||
27 | { | ||
28 | .name = "ar724x-ehci", | ||
29 | .driver_data = EHCI_ATH79_IP_V2, | ||
30 | }, | ||
31 | { | ||
32 | .name = "ar913x-ehci", | ||
33 | .driver_data = EHCI_ATH79_IP_V2, | ||
34 | }, | ||
35 | { | ||
36 | /* terminating entry */ | ||
37 | }, | ||
38 | }; | ||
39 | |||
40 | MODULE_DEVICE_TABLE(platform, ehci_ath79_id_table); | ||
41 | |||
42 | static int ehci_ath79_init(struct usb_hcd *hcd) | ||
43 | { | ||
44 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
45 | struct platform_device *pdev = to_platform_device(hcd->self.controller); | ||
46 | const struct platform_device_id *id; | ||
47 | int ret; | ||
48 | |||
49 | id = platform_get_device_id(pdev); | ||
50 | if (!id) { | ||
51 | dev_err(hcd->self.controller, "missing device id\n"); | ||
52 | return -EINVAL; | ||
53 | } | ||
54 | |||
55 | switch (id->driver_data) { | ||
56 | case EHCI_ATH79_IP_V1: | ||
57 | ehci->has_synopsys_hc_bug = 1; | ||
58 | |||
59 | ehci->caps = hcd->regs; | ||
60 | ehci->regs = hcd->regs + | ||
61 | HC_LENGTH(ehci, | ||
62 | ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
63 | break; | ||
64 | |||
65 | case EHCI_ATH79_IP_V2: | ||
66 | hcd->has_tt = 1; | ||
67 | |||
68 | ehci->caps = hcd->regs + 0x100; | ||
69 | ehci->regs = hcd->regs + 0x100 + | ||
70 | HC_LENGTH(ehci, | ||
71 | ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
72 | break; | ||
73 | |||
74 | default: | ||
75 | BUG(); | ||
76 | } | ||
77 | |||
78 | dbg_hcs_params(ehci, "reset"); | ||
79 | dbg_hcc_params(ehci, "reset"); | ||
80 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
81 | ehci->sbrn = 0x20; | ||
82 | |||
83 | ehci_reset(ehci); | ||
84 | |||
85 | ret = ehci_init(hcd); | ||
86 | if (ret) | ||
87 | return ret; | ||
88 | |||
89 | ehci_port_power(ehci, 0); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static const struct hc_driver ehci_ath79_hc_driver = { | ||
95 | .description = hcd_name, | ||
96 | .product_desc = "Atheros built-in EHCI controller", | ||
97 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
98 | .irq = ehci_irq, | ||
99 | .flags = HCD_MEMORY | HCD_USB2, | ||
100 | |||
101 | .reset = ehci_ath79_init, | ||
102 | .start = ehci_run, | ||
103 | .stop = ehci_stop, | ||
104 | .shutdown = ehci_shutdown, | ||
105 | |||
106 | .urb_enqueue = ehci_urb_enqueue, | ||
107 | .urb_dequeue = ehci_urb_dequeue, | ||
108 | .endpoint_disable = ehci_endpoint_disable, | ||
109 | .endpoint_reset = ehci_endpoint_reset, | ||
110 | |||
111 | .get_frame_number = ehci_get_frame, | ||
112 | |||
113 | .hub_status_data = ehci_hub_status_data, | ||
114 | .hub_control = ehci_hub_control, | ||
115 | |||
116 | .relinquish_port = ehci_relinquish_port, | ||
117 | .port_handed_over = ehci_port_handed_over, | ||
118 | |||
119 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
120 | }; | ||
121 | |||
122 | static int ehci_ath79_probe(struct platform_device *pdev) | ||
123 | { | ||
124 | struct usb_hcd *hcd; | ||
125 | struct resource *res; | ||
126 | int irq; | ||
127 | int ret; | ||
128 | |||
129 | if (usb_disabled()) | ||
130 | return -ENODEV; | ||
131 | |||
132 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
133 | if (!res) { | ||
134 | dev_dbg(&pdev->dev, "no IRQ specified\n"); | ||
135 | return -ENODEV; | ||
136 | } | ||
137 | irq = res->start; | ||
138 | |||
139 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
140 | if (!res) { | ||
141 | dev_dbg(&pdev->dev, "no base address specified\n"); | ||
142 | return -ENODEV; | ||
143 | } | ||
144 | |||
145 | hcd = usb_create_hcd(&ehci_ath79_hc_driver, &pdev->dev, | ||
146 | dev_name(&pdev->dev)); | ||
147 | if (!hcd) | ||
148 | return -ENOMEM; | ||
149 | |||
150 | hcd->rsrc_start = res->start; | ||
151 | hcd->rsrc_len = resource_size(res); | ||
152 | |||
153 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
154 | dev_dbg(&pdev->dev, "controller already in use\n"); | ||
155 | ret = -EBUSY; | ||
156 | goto err_put_hcd; | ||
157 | } | ||
158 | |||
159 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
160 | if (!hcd->regs) { | ||
161 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
162 | ret = -EFAULT; | ||
163 | goto err_release_region; | ||
164 | } | ||
165 | |||
166 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | ||
167 | if (ret) | ||
168 | goto err_iounmap; | ||
169 | |||
170 | return 0; | ||
171 | |||
172 | err_iounmap: | ||
173 | iounmap(hcd->regs); | ||
174 | |||
175 | err_release_region: | ||
176 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
177 | err_put_hcd: | ||
178 | usb_put_hcd(hcd); | ||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | static int ehci_ath79_remove(struct platform_device *pdev) | ||
183 | { | ||
184 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
185 | |||
186 | usb_remove_hcd(hcd); | ||
187 | iounmap(hcd->regs); | ||
188 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
189 | usb_put_hcd(hcd); | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static struct platform_driver ehci_ath79_driver = { | ||
195 | .probe = ehci_ath79_probe, | ||
196 | .remove = ehci_ath79_remove, | ||
197 | .id_table = ehci_ath79_id_table, | ||
198 | .driver = { | ||
199 | .owner = THIS_MODULE, | ||
200 | .name = "ath79-ehci", | ||
201 | } | ||
202 | }; | ||
203 | |||
204 | MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ehci"); | ||
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c new file mode 100644 index 00000000000..42ae5740990 --- /dev/null +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /* | ||
2 | * EHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * Bus Glue for AMD Alchemy Au1xxx | ||
5 | * | ||
6 | * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org> | ||
7 | * | ||
8 | * Modified for AMD Alchemy Au1200 EHC | ||
9 | * by K.Boge <karsten.boge@amd.com> | ||
10 | * | ||
11 | * This file is licenced under the GPL. | ||
12 | */ | ||
13 | |||
14 | #include <linux/platform_device.h> | ||
15 | #include <asm/mach-au1x00/au1000.h> | ||
16 | |||
17 | #define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG) | ||
18 | #define USB_MCFG_PFEN (1<<31) | ||
19 | #define USB_MCFG_RDCOMB (1<<30) | ||
20 | #define USB_MCFG_SSDEN (1<<23) | ||
21 | #define USB_MCFG_PHYPLLEN (1<<19) | ||
22 | #define USB_MCFG_UCECLKEN (1<<18) | ||
23 | #define USB_MCFG_EHCCLKEN (1<<17) | ||
24 | #ifdef CONFIG_DMA_COHERENT | ||
25 | #define USB_MCFG_UCAM (1<<7) | ||
26 | #else | ||
27 | #define USB_MCFG_UCAM (0) | ||
28 | #endif | ||
29 | #define USB_MCFG_EBMEN (1<<3) | ||
30 | #define USB_MCFG_EMEMEN (1<<2) | ||
31 | |||
32 | #define USBH_ENABLE_CE (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN) | ||
33 | #define USBH_ENABLE_INIT (USB_MCFG_PFEN | USB_MCFG_RDCOMB | \ | ||
34 | USBH_ENABLE_CE | USB_MCFG_SSDEN | \ | ||
35 | USB_MCFG_UCAM | USB_MCFG_EBMEN | \ | ||
36 | USB_MCFG_EMEMEN) | ||
37 | |||
38 | #define USBH_DISABLE (USB_MCFG_EBMEN | USB_MCFG_EMEMEN) | ||
39 | |||
40 | extern int usb_disabled(void); | ||
41 | |||
42 | static void au1xxx_start_ehc(void) | ||
43 | { | ||
44 | /* enable clock to EHCI block and HS PHY PLL*/ | ||
45 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
46 | au_sync(); | ||
47 | udelay(1000); | ||
48 | |||
49 | /* enable EHCI mmio */ | ||
50 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG); | ||
51 | au_sync(); | ||
52 | udelay(1000); | ||
53 | } | ||
54 | |||
55 | static void au1xxx_stop_ehc(void) | ||
56 | { | ||
57 | unsigned long c; | ||
58 | |||
59 | /* Disable mem */ | ||
60 | au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG); | ||
61 | au_sync(); | ||
62 | udelay(1000); | ||
63 | |||
64 | /* Disable EHC clock. If the HS PHY is unused disable it too. */ | ||
65 | c = au_readl(USB_HOST_CONFIG) & ~USB_MCFG_EHCCLKEN; | ||
66 | if (!(c & USB_MCFG_UCECLKEN)) /* UDC disabled? */ | ||
67 | c &= ~USB_MCFG_PHYPLLEN; /* yes: disable HS PHY PLL */ | ||
68 | au_writel(c, USB_HOST_CONFIG); | ||
69 | au_sync(); | ||
70 | } | ||
71 | |||
72 | static int au1xxx_ehci_setup(struct usb_hcd *hcd) | ||
73 | { | ||
74 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
75 | int ret = ehci_init(hcd); | ||
76 | |||
77 | ehci->need_io_watchdog = 0; | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | static const struct hc_driver ehci_au1xxx_hc_driver = { | ||
82 | .description = hcd_name, | ||
83 | .product_desc = "Au1xxx EHCI", | ||
84 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
85 | |||
86 | /* | ||
87 | * generic hardware linkage | ||
88 | */ | ||
89 | .irq = ehci_irq, | ||
90 | .flags = HCD_MEMORY | HCD_USB2, | ||
91 | |||
92 | /* | ||
93 | * basic lifecycle operations | ||
94 | * | ||
95 | * FIXME -- ehci_init() doesn't do enough here. | ||
96 | * See ehci-ppc-soc for a complete implementation. | ||
97 | */ | ||
98 | .reset = au1xxx_ehci_setup, | ||
99 | .start = ehci_run, | ||
100 | .stop = ehci_stop, | ||
101 | .shutdown = ehci_shutdown, | ||
102 | |||
103 | /* | ||
104 | * managing i/o requests and associated device resources | ||
105 | */ | ||
106 | .urb_enqueue = ehci_urb_enqueue, | ||
107 | .urb_dequeue = ehci_urb_dequeue, | ||
108 | .endpoint_disable = ehci_endpoint_disable, | ||
109 | .endpoint_reset = ehci_endpoint_reset, | ||
110 | |||
111 | /* | ||
112 | * scheduling support | ||
113 | */ | ||
114 | .get_frame_number = ehci_get_frame, | ||
115 | |||
116 | /* | ||
117 | * root hub support | ||
118 | */ | ||
119 | .hub_status_data = ehci_hub_status_data, | ||
120 | .hub_control = ehci_hub_control, | ||
121 | .bus_suspend = ehci_bus_suspend, | ||
122 | .bus_resume = ehci_bus_resume, | ||
123 | .relinquish_port = ehci_relinquish_port, | ||
124 | .port_handed_over = ehci_port_handed_over, | ||
125 | |||
126 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
127 | }; | ||
128 | |||
129 | static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | ||
130 | { | ||
131 | struct usb_hcd *hcd; | ||
132 | struct ehci_hcd *ehci; | ||
133 | struct resource *res; | ||
134 | int ret; | ||
135 | |||
136 | if (usb_disabled()) | ||
137 | return -ENODEV; | ||
138 | |||
139 | #if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT) | ||
140 | /* Au1200 AB USB does not support coherent memory */ | ||
141 | if (!(read_c0_prid() & 0xff)) { | ||
142 | printk(KERN_INFO "%s: this is chip revision AB!\n", pdev->name); | ||
143 | printk(KERN_INFO "%s: update your board or re-configure" | ||
144 | " the kernel\n", pdev->name); | ||
145 | return -ENODEV; | ||
146 | } | ||
147 | #endif | ||
148 | |||
149 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | ||
150 | pr_debug("resource[1] is not IORESOURCE_IRQ"); | ||
151 | return -ENOMEM; | ||
152 | } | ||
153 | hcd = usb_create_hcd(&ehci_au1xxx_hc_driver, &pdev->dev, "Au1xxx"); | ||
154 | if (!hcd) | ||
155 | return -ENOMEM; | ||
156 | |||
157 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
158 | hcd->rsrc_start = res->start; | ||
159 | hcd->rsrc_len = resource_size(res); | ||
160 | |||
161 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
162 | pr_debug("request_mem_region failed"); | ||
163 | ret = -EBUSY; | ||
164 | goto err1; | ||
165 | } | ||
166 | |||
167 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
168 | if (!hcd->regs) { | ||
169 | pr_debug("ioremap failed"); | ||
170 | ret = -ENOMEM; | ||
171 | goto err2; | ||
172 | } | ||
173 | |||
174 | au1xxx_start_ehc(); | ||
175 | |||
176 | ehci = hcd_to_ehci(hcd); | ||
177 | ehci->caps = hcd->regs; | ||
178 | ehci->regs = hcd->regs + | ||
179 | HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); | ||
180 | /* cache this readonly data; minimize chip reads */ | ||
181 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | ||
182 | |||
183 | ret = usb_add_hcd(hcd, pdev->resource[1].start, | ||
184 | IRQF_DISABLED | IRQF_SHARED); | ||
185 | if (ret == 0) { | ||
186 | platform_set_drvdata(pdev, hcd); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | au1xxx_stop_ehc(); | ||
191 | iounmap(hcd->regs); | ||
192 | err2: | ||
193 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
194 | err1: | ||
195 | usb_put_hcd(hcd); | ||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev) | ||
200 | { | ||
201 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
202 | |||
203 | usb_remove_hcd(hcd); | ||
204 | iounmap(hcd->regs); | ||
205 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
206 | usb_put_hcd(hcd); | ||
207 | au1xxx_stop_ehc(); | ||
208 | platform_set_drvdata(pdev, NULL); | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | #ifdef CONFIG_PM | ||
214 | static int ehci_hcd_au1xxx_drv_suspend(struct device *dev) | ||
215 | { | ||
216 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
217 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
218 | unsigned long flags; | ||
219 | int rc = 0; | ||
220 | |||
221 | if (time_before(jiffies, ehci->next_statechange)) | ||
222 | msleep(10); | ||
223 | |||
224 | /* Root hub was already suspended. Disable irq emission and | ||
225 | * mark HW unaccessible. The PM and USB cores make sure that | ||
226 | * the root hub is either suspended or stopped. | ||
227 | */ | ||
228 | ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev)); | ||
229 | spin_lock_irqsave(&ehci->lock, flags); | ||
230 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); | ||
231 | (void)ehci_readl(ehci, &ehci->regs->intr_enable); | ||
232 | |||
233 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
234 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
235 | |||
236 | // could save FLADJ in case of Vaux power loss | ||
237 | // ... we'd only use it to handle clock skew | ||
238 | |||
239 | au1xxx_stop_ehc(); | ||
240 | |||
241 | return rc; | ||
242 | } | ||
243 | |||
244 | static int ehci_hcd_au1xxx_drv_resume(struct device *dev) | ||
245 | { | ||
246 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
247 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
248 | |||
249 | au1xxx_start_ehc(); | ||
250 | |||
251 | // maybe restore FLADJ | ||
252 | |||
253 | if (time_before(jiffies, ehci->next_statechange)) | ||
254 | msleep(100); | ||
255 | |||
256 | /* Mark hardware accessible again as we are out of D3 state by now */ | ||
257 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
258 | |||
259 | /* If CF is still set, we maintained PCI Vaux power. | ||
260 | * Just undo the effect of ehci_pci_suspend(). | ||
261 | */ | ||
262 | if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { | ||
263 | int mask = INTR_MASK; | ||
264 | |||
265 | ehci_prepare_ports_for_controller_resume(ehci); | ||
266 | if (!hcd->self.root_hub->do_remote_wakeup) | ||
267 | mask &= ~STS_PCD; | ||
268 | ehci_writel(ehci, mask, &ehci->regs->intr_enable); | ||
269 | ehci_readl(ehci, &ehci->regs->intr_enable); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | ehci_dbg(ehci, "lost power, restarting\n"); | ||
274 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
275 | |||
276 | /* Else reset, to cope with power loss or flush-to-storage | ||
277 | * style "resume" having let BIOS kick in during reboot. | ||
278 | */ | ||
279 | (void) ehci_halt(ehci); | ||
280 | (void) ehci_reset(ehci); | ||
281 | |||
282 | /* emptying the schedule aborts any urbs */ | ||
283 | spin_lock_irq(&ehci->lock); | ||
284 | if (ehci->reclaim) | ||
285 | end_unlink_async(ehci); | ||
286 | ehci_work(ehci); | ||
287 | spin_unlock_irq(&ehci->lock); | ||
288 | |||
289 | ehci_writel(ehci, ehci->command, &ehci->regs->command); | ||
290 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); | ||
291 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ | ||
292 | |||
293 | /* here we "know" root ports should always stay powered */ | ||
294 | ehci_port_power(ehci, 1); | ||
295 | |||
296 | hcd->state = HC_STATE_SUSPENDED; | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static const struct dev_pm_ops au1xxx_ehci_pmops = { | ||
302 | .suspend = ehci_hcd_au1xxx_drv_suspend, | ||
303 | .resume = ehci_hcd_au1xxx_drv_resume, | ||
304 | }; | ||
305 | |||
306 | #define AU1XXX_EHCI_PMOPS &au1xxx_ehci_pmops | ||
307 | |||
308 | #else | ||
309 | #define AU1XXX_EHCI_PMOPS NULL | ||
310 | #endif | ||
311 | |||
312 | static struct platform_driver ehci_hcd_au1xxx_driver = { | ||
313 | .probe = ehci_hcd_au1xxx_drv_probe, | ||
314 | .remove = ehci_hcd_au1xxx_drv_remove, | ||
315 | .shutdown = usb_hcd_platform_shutdown, | ||
316 | .driver = { | ||
317 | .name = "au1xxx-ehci", | ||
318 | .owner = THIS_MODULE, | ||
319 | .pm = AU1XXX_EHCI_PMOPS, | ||
320 | } | ||
321 | }; | ||
322 | |||
323 | MODULE_ALIAS("platform:au1xxx-ehci"); | ||
diff --git a/drivers/usb/host/ehci-cns3xxx.c b/drivers/usb/host/ehci-cns3xxx.c new file mode 100644 index 00000000000..6536abdea6e --- /dev/null +++ b/drivers/usb/host/ehci-cns3xxx.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cavium Networks | ||
3 | * | ||
4 | * This file is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License, Version 2, as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/platform_device.h> | ||
10 | #include <linux/atomic.h> | ||
11 | #include <mach/cns3xxx.h> | ||
12 | #include <mach/pm.h> | ||
13 | |||
14 | static int cns3xxx_ehci_init(struct usb_hcd *hcd) | ||
15 | { | ||
16 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
17 | int retval; | ||
18 | |||
19 | /* | ||
20 | * EHCI and OHCI share the same clock and power, | ||
21 | * resetting twice would cause the 1st controller been reset. | ||
22 | * Therefore only do power up at the first up device, and | ||
23 | * power down at the last down device. | ||
24 | * | ||
25 | * Set USB AHB INCR length to 16 | ||
26 | */ | ||
27 | if (atomic_inc_return(&usb_pwr_ref) == 1) { | ||
28 | cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); | ||
29 | cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
30 | cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); | ||
31 | __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), | ||
32 | MISC_CHIP_CONFIG_REG); | ||
33 | } | ||
34 | |||
35 | ehci->caps = hcd->regs; | ||
36 | ehci->regs = hcd->regs | ||
37 | + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
38 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
39 | |||
40 | hcd->has_tt = 0; | ||
41 | ehci_reset(ehci); | ||
42 | |||
43 | retval = ehci_init(hcd); | ||
44 | if (retval) | ||
45 | return retval; | ||
46 | |||
47 | ehci_port_power(ehci, 0); | ||
48 | |||
49 | return retval; | ||
50 | } | ||
51 | |||
52 | static const struct hc_driver cns3xxx_ehci_hc_driver = { | ||
53 | .description = hcd_name, | ||
54 | .product_desc = "CNS3XXX EHCI Host Controller", | ||
55 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
56 | .irq = ehci_irq, | ||
57 | .flags = HCD_MEMORY | HCD_USB2, | ||
58 | .reset = cns3xxx_ehci_init, | ||
59 | .start = ehci_run, | ||
60 | .stop = ehci_stop, | ||
61 | .shutdown = ehci_shutdown, | ||
62 | .urb_enqueue = ehci_urb_enqueue, | ||
63 | .urb_dequeue = ehci_urb_dequeue, | ||
64 | .endpoint_disable = ehci_endpoint_disable, | ||
65 | .endpoint_reset = ehci_endpoint_reset, | ||
66 | .get_frame_number = ehci_get_frame, | ||
67 | .hub_status_data = ehci_hub_status_data, | ||
68 | .hub_control = ehci_hub_control, | ||
69 | #ifdef CONFIG_PM | ||
70 | .bus_suspend = ehci_bus_suspend, | ||
71 | .bus_resume = ehci_bus_resume, | ||
72 | #endif | ||
73 | .relinquish_port = ehci_relinquish_port, | ||
74 | .port_handed_over = ehci_port_handed_over, | ||
75 | |||
76 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
77 | }; | ||
78 | |||
79 | static int cns3xxx_ehci_probe(struct platform_device *pdev) | ||
80 | { | ||
81 | struct device *dev = &pdev->dev; | ||
82 | struct usb_hcd *hcd; | ||
83 | const struct hc_driver *driver = &cns3xxx_ehci_hc_driver; | ||
84 | struct resource *res; | ||
85 | int irq; | ||
86 | int retval; | ||
87 | |||
88 | if (usb_disabled()) | ||
89 | return -ENODEV; | ||
90 | |||
91 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
92 | if (!res) { | ||
93 | dev_err(dev, "Found HC with no IRQ.\n"); | ||
94 | return -ENODEV; | ||
95 | } | ||
96 | irq = res->start; | ||
97 | |||
98 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | ||
99 | if (!hcd) | ||
100 | return -ENOMEM; | ||
101 | |||
102 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
103 | if (!res) { | ||
104 | dev_err(dev, "Found HC with no register addr.\n"); | ||
105 | retval = -ENODEV; | ||
106 | goto err1; | ||
107 | } | ||
108 | |||
109 | hcd->rsrc_start = res->start; | ||
110 | hcd->rsrc_len = resource_size(res); | ||
111 | |||
112 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
113 | driver->description)) { | ||
114 | dev_dbg(dev, "controller already in use\n"); | ||
115 | retval = -EBUSY; | ||
116 | goto err1; | ||
117 | } | ||
118 | |||
119 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
120 | if (hcd->regs == NULL) { | ||
121 | dev_dbg(dev, "error mapping memory\n"); | ||
122 | retval = -EFAULT; | ||
123 | goto err2; | ||
124 | } | ||
125 | |||
126 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
127 | if (retval == 0) | ||
128 | return retval; | ||
129 | |||
130 | iounmap(hcd->regs); | ||
131 | err2: | ||
132 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
133 | err1: | ||
134 | usb_put_hcd(hcd); | ||
135 | |||
136 | return retval; | ||
137 | } | ||
138 | |||
139 | static int cns3xxx_ehci_remove(struct platform_device *pdev) | ||
140 | { | ||
141 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
142 | |||
143 | usb_remove_hcd(hcd); | ||
144 | iounmap(hcd->regs); | ||
145 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
146 | |||
147 | /* | ||
148 | * EHCI and OHCI share the same clock and power, | ||
149 | * resetting twice would cause the 1st controller been reset. | ||
150 | * Therefore only do power up at the first up device, and | ||
151 | * power down at the last down device. | ||
152 | */ | ||
153 | if (atomic_dec_return(&usb_pwr_ref) == 0) | ||
154 | cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
155 | |||
156 | usb_put_hcd(hcd); | ||
157 | |||
158 | platform_set_drvdata(pdev, NULL); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | MODULE_ALIAS("platform:cns3xxx-ehci"); | ||
164 | |||
165 | static struct platform_driver cns3xxx_ehci_driver = { | ||
166 | .probe = cns3xxx_ehci_probe, | ||
167 | .remove = cns3xxx_ehci_remove, | ||
168 | .driver = { | ||
169 | .name = "cns3xxx-ehci", | ||
170 | }, | ||
171 | }; | ||
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c new file mode 100644 index 00000000000..c4460f3d009 --- /dev/null +++ b/drivers/usb/host/ehci-ixp4xx.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* | ||
2 | * IXP4XX EHCI Host Controller Driver | ||
3 | * | ||
4 | * Author: Vladimir Barinov <vbarinov@embeddedalley.com> | ||
5 | * | ||
6 | * Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com> | ||
7 | * | ||
8 | * 2007 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/platform_device.h> | ||
15 | |||
16 | static int ixp4xx_ehci_init(struct usb_hcd *hcd) | ||
17 | { | ||
18 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
19 | int retval = 0; | ||
20 | |||
21 | ehci->big_endian_desc = 1; | ||
22 | ehci->big_endian_mmio = 1; | ||
23 | |||
24 | ehci->caps = hcd->regs + 0x100; | ||
25 | ehci->regs = hcd->regs + 0x100 | ||
26 | + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
27 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
28 | |||
29 | hcd->has_tt = 1; | ||
30 | ehci_reset(ehci); | ||
31 | |||
32 | retval = ehci_init(hcd); | ||
33 | if (retval) | ||
34 | return retval; | ||
35 | |||
36 | ehci_port_power(ehci, 0); | ||
37 | |||
38 | return retval; | ||
39 | } | ||
40 | |||
41 | static const struct hc_driver ixp4xx_ehci_hc_driver = { | ||
42 | .description = hcd_name, | ||
43 | .product_desc = "IXP4XX EHCI Host Controller", | ||
44 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
45 | .irq = ehci_irq, | ||
46 | .flags = HCD_MEMORY | HCD_USB2, | ||
47 | .reset = ixp4xx_ehci_init, | ||
48 | .start = ehci_run, | ||
49 | .stop = ehci_stop, | ||
50 | .shutdown = ehci_shutdown, | ||
51 | .urb_enqueue = ehci_urb_enqueue, | ||
52 | .urb_dequeue = ehci_urb_dequeue, | ||
53 | .endpoint_disable = ehci_endpoint_disable, | ||
54 | .endpoint_reset = ehci_endpoint_reset, | ||
55 | .get_frame_number = ehci_get_frame, | ||
56 | .hub_status_data = ehci_hub_status_data, | ||
57 | .hub_control = ehci_hub_control, | ||
58 | #if defined(CONFIG_PM) | ||
59 | .bus_suspend = ehci_bus_suspend, | ||
60 | .bus_resume = ehci_bus_resume, | ||
61 | #endif | ||
62 | .relinquish_port = ehci_relinquish_port, | ||
63 | .port_handed_over = ehci_port_handed_over, | ||
64 | |||
65 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
66 | }; | ||
67 | |||
68 | static int ixp4xx_ehci_probe(struct platform_device *pdev) | ||
69 | { | ||
70 | struct usb_hcd *hcd; | ||
71 | const struct hc_driver *driver = &ixp4xx_ehci_hc_driver; | ||
72 | struct resource *res; | ||
73 | int irq; | ||
74 | int retval; | ||
75 | |||
76 | if (usb_disabled()) | ||
77 | return -ENODEV; | ||
78 | |||
79 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
80 | if (!res) { | ||
81 | dev_err(&pdev->dev, | ||
82 | "Found HC with no IRQ. Check %s setup!\n", | ||
83 | dev_name(&pdev->dev)); | ||
84 | return -ENODEV; | ||
85 | } | ||
86 | irq = res->start; | ||
87 | |||
88 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | ||
89 | if (!hcd) { | ||
90 | retval = -ENOMEM; | ||
91 | goto fail_create_hcd; | ||
92 | } | ||
93 | |||
94 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
95 | if (!res) { | ||
96 | dev_err(&pdev->dev, | ||
97 | "Found HC with no register addr. Check %s setup!\n", | ||
98 | dev_name(&pdev->dev)); | ||
99 | retval = -ENODEV; | ||
100 | goto fail_request_resource; | ||
101 | } | ||
102 | hcd->rsrc_start = res->start; | ||
103 | hcd->rsrc_len = resource_size(res); | ||
104 | |||
105 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
106 | driver->description)) { | ||
107 | dev_dbg(&pdev->dev, "controller already in use\n"); | ||
108 | retval = -EBUSY; | ||
109 | goto fail_request_resource; | ||
110 | } | ||
111 | |||
112 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | ||
113 | if (hcd->regs == NULL) { | ||
114 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
115 | retval = -EFAULT; | ||
116 | goto fail_ioremap; | ||
117 | } | ||
118 | |||
119 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
120 | if (retval) | ||
121 | goto fail_add_hcd; | ||
122 | |||
123 | return retval; | ||
124 | |||
125 | fail_add_hcd: | ||
126 | iounmap(hcd->regs); | ||
127 | fail_ioremap: | ||
128 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
129 | fail_request_resource: | ||
130 | usb_put_hcd(hcd); | ||
131 | fail_create_hcd: | ||
132 | dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); | ||
133 | return retval; | ||
134 | } | ||
135 | |||
136 | static int ixp4xx_ehci_remove(struct platform_device *pdev) | ||
137 | { | ||
138 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
139 | |||
140 | usb_remove_hcd(hcd); | ||
141 | iounmap(hcd->regs); | ||
142 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
143 | usb_put_hcd(hcd); | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | MODULE_ALIAS("platform:ixp4xx-ehci"); | ||
149 | |||
150 | static struct platform_driver ixp4xx_ehci_driver = { | ||
151 | .probe = ixp4xx_ehci_probe, | ||
152 | .remove = ixp4xx_ehci_remove, | ||
153 | .driver = { | ||
154 | .name = "ixp4xx-ehci", | ||
155 | }, | ||
156 | }; | ||
diff --git a/drivers/usb/host/ehci-lpm.c b/drivers/usb/host/ehci-lpm.c new file mode 100644 index 00000000000..2111627a19d --- /dev/null +++ b/drivers/usb/host/ehci-lpm.c | |||
@@ -0,0 +1,84 @@ | |||
1 | /* ehci-lpm.c EHCI HCD LPM support code | ||
2 | * Copyright (c) 2008 - 2010, Intel Corporation. | ||
3 | * Author: Jacob Pan <jacob.jun.pan@intel.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | /* this file is part of ehci-hcd.c */ | ||
20 | static int __maybe_unused ehci_lpm_set_da(struct ehci_hcd *ehci, | ||
21 | int dev_addr, int port_num) | ||
22 | { | ||
23 | u32 __iomem portsc; | ||
24 | |||
25 | ehci_dbg(ehci, "set dev address %d for port %d\n", dev_addr, port_num); | ||
26 | if (port_num > HCS_N_PORTS(ehci->hcs_params)) { | ||
27 | ehci_dbg(ehci, "invalid port number %d\n", port_num); | ||
28 | return -ENODEV; | ||
29 | } | ||
30 | portsc = ehci_readl(ehci, &ehci->regs->port_status[port_num-1]); | ||
31 | portsc &= ~PORT_DEV_ADDR; | ||
32 | portsc |= dev_addr<<25; | ||
33 | ehci_writel(ehci, portsc, &ehci->regs->port_status[port_num-1]); | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * this function is used to check if the device support LPM | ||
39 | * if yes, mark the PORTSC register with PORT_LPM bit | ||
40 | */ | ||
41 | static int __maybe_unused ehci_lpm_check(struct ehci_hcd *ehci, int port) | ||
42 | { | ||
43 | u32 __iomem *portsc ; | ||
44 | u32 val32; | ||
45 | int retval; | ||
46 | |||
47 | portsc = &ehci->regs->port_status[port-1]; | ||
48 | val32 = ehci_readl(ehci, portsc); | ||
49 | if (!(val32 & PORT_DEV_ADDR)) { | ||
50 | ehci_dbg(ehci, "LPM: no device attached\n"); | ||
51 | return -ENODEV; | ||
52 | } | ||
53 | val32 |= PORT_LPM; | ||
54 | ehci_writel(ehci, val32, portsc); | ||
55 | msleep(5); | ||
56 | val32 |= PORT_SUSPEND; | ||
57 | ehci_dbg(ehci, "Sending LPM 0x%08x to port %d\n", val32, port); | ||
58 | ehci_writel(ehci, val32, portsc); | ||
59 | /* wait for ACK */ | ||
60 | msleep(10); | ||
61 | retval = handshake(ehci, &ehci->regs->port_status[port-1], PORT_SSTS, | ||
62 | PORTSC_SUSPEND_STS_ACK, 125); | ||
63 | dbg_port(ehci, "LPM", port, val32); | ||
64 | if (retval != -ETIMEDOUT) { | ||
65 | ehci_dbg(ehci, "LPM: device ACK for LPM\n"); | ||
66 | val32 |= PORT_LPM; | ||
67 | /* | ||
68 | * now device should be in L1 sleep, let's wake up the device | ||
69 | * so that we can complete enumeration. | ||
70 | */ | ||
71 | ehci_writel(ehci, val32, portsc); | ||
72 | msleep(10); | ||
73 | val32 |= PORT_RESUME; | ||
74 | ehci_writel(ehci, val32, portsc); | ||
75 | } else { | ||
76 | ehci_dbg(ehci, "LPM: device does not ACK, disable LPM %d\n", | ||
77 | retval); | ||
78 | val32 &= ~PORT_LPM; | ||
79 | retval = -ETIMEDOUT; | ||
80 | ehci_writel(ehci, val32, portsc); | ||
81 | } | ||
82 | |||
83 | return retval; | ||
84 | } | ||
diff --git a/drivers/usb/host/ohci-ath79.c b/drivers/usb/host/ohci-ath79.c new file mode 100644 index 00000000000..c620c50f677 --- /dev/null +++ b/drivers/usb/host/ohci-ath79.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * Bus Glue for Atheros AR71XX/AR724X built-in OHCI controller. | ||
5 | * | ||
6 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
7 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
8 | * | ||
9 | * Parts of this file are based on Atheros' 2.6.15 BSP | ||
10 | * Copyright (C) 2007 Atheros Communications, Inc. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License version 2 as published | ||
14 | * by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #include <linux/platform_device.h> | ||
18 | |||
19 | static int __devinit ohci_ath79_start(struct usb_hcd *hcd) | ||
20 | { | ||
21 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
22 | int ret; | ||
23 | |||
24 | ret = ohci_init(ohci); | ||
25 | if (ret < 0) | ||
26 | return ret; | ||
27 | |||
28 | ret = ohci_run(ohci); | ||
29 | if (ret < 0) | ||
30 | goto err; | ||
31 | |||
32 | return 0; | ||
33 | |||
34 | err: | ||
35 | ohci_stop(hcd); | ||
36 | return ret; | ||
37 | } | ||
38 | |||
39 | static const struct hc_driver ohci_ath79_hc_driver = { | ||
40 | .description = hcd_name, | ||
41 | .product_desc = "Atheros built-in OHCI controller", | ||
42 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
43 | |||
44 | .irq = ohci_irq, | ||
45 | .flags = HCD_USB11 | HCD_MEMORY, | ||
46 | |||
47 | .start = ohci_ath79_start, | ||
48 | .stop = ohci_stop, | ||
49 | .shutdown = ohci_shutdown, | ||
50 | |||
51 | .urb_enqueue = ohci_urb_enqueue, | ||
52 | .urb_dequeue = ohci_urb_dequeue, | ||
53 | .endpoint_disable = ohci_endpoint_disable, | ||
54 | |||
55 | /* | ||
56 | * scheduling support | ||
57 | */ | ||
58 | .get_frame_number = ohci_get_frame, | ||
59 | |||
60 | /* | ||
61 | * root hub support | ||
62 | */ | ||
63 | .hub_status_data = ohci_hub_status_data, | ||
64 | .hub_control = ohci_hub_control, | ||
65 | .start_port_reset = ohci_start_port_reset, | ||
66 | }; | ||
67 | |||
68 | static int ohci_ath79_probe(struct platform_device *pdev) | ||
69 | { | ||
70 | struct usb_hcd *hcd; | ||
71 | struct resource *res; | ||
72 | int irq; | ||
73 | int ret; | ||
74 | |||
75 | if (usb_disabled()) | ||
76 | return -ENODEV; | ||
77 | |||
78 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
79 | if (!res) { | ||
80 | dev_dbg(&pdev->dev, "no IRQ specified\n"); | ||
81 | return -ENODEV; | ||
82 | } | ||
83 | irq = res->start; | ||
84 | |||
85 | hcd = usb_create_hcd(&ohci_ath79_hc_driver, &pdev->dev, | ||
86 | dev_name(&pdev->dev)); | ||
87 | if (!hcd) | ||
88 | return -ENOMEM; | ||
89 | |||
90 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
91 | if (!res) { | ||
92 | dev_dbg(&pdev->dev, "no base address specified\n"); | ||
93 | ret = -ENODEV; | ||
94 | goto err_put_hcd; | ||
95 | } | ||
96 | hcd->rsrc_start = res->start; | ||
97 | hcd->rsrc_len = resource_size(res); | ||
98 | |||
99 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
100 | dev_dbg(&pdev->dev, "controller already in use\n"); | ||
101 | ret = -EBUSY; | ||
102 | goto err_put_hcd; | ||
103 | } | ||
104 | |||
105 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
106 | if (!hcd->regs) { | ||
107 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
108 | ret = -EFAULT; | ||
109 | goto err_release_region; | ||
110 | } | ||
111 | |||
112 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
113 | |||
114 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | ||
115 | if (ret) | ||
116 | goto err_stop_hcd; | ||
117 | |||
118 | return 0; | ||
119 | |||
120 | err_stop_hcd: | ||
121 | iounmap(hcd->regs); | ||
122 | err_release_region: | ||
123 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
124 | err_put_hcd: | ||
125 | usb_put_hcd(hcd); | ||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | static int ohci_ath79_remove(struct platform_device *pdev) | ||
130 | { | ||
131 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
132 | |||
133 | usb_remove_hcd(hcd); | ||
134 | iounmap(hcd->regs); | ||
135 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
136 | usb_put_hcd(hcd); | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static struct platform_driver ohci_hcd_ath79_driver = { | ||
142 | .probe = ohci_ath79_probe, | ||
143 | .remove = ohci_ath79_remove, | ||
144 | .shutdown = usb_hcd_platform_shutdown, | ||
145 | .driver = { | ||
146 | .name = "ath79-ohci", | ||
147 | .owner = THIS_MODULE, | ||
148 | }, | ||
149 | }; | ||
150 | |||
151 | MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ohci"); | ||
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c new file mode 100644 index 00000000000..958d985f295 --- /dev/null +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -0,0 +1,319 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * | ||
8 | * Bus Glue for AMD Alchemy Au1xxx | ||
9 | * | ||
10 | * Written by Christopher Hoover <ch@hpl.hp.com> | ||
11 | * Based on fragments of previous driver by Russell King et al. | ||
12 | * | ||
13 | * Modified for LH7A404 from ohci-sa1111.c | ||
14 | * by Durgesh Pattamatta <pattamattad@sharpsec.com> | ||
15 | * Modified for AMD Alchemy Au1xxx | ||
16 | * by Matt Porter <mporter@kernel.crashing.org> | ||
17 | * | ||
18 | * This file is licenced under the GPL. | ||
19 | */ | ||
20 | |||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/signal.h> | ||
23 | |||
24 | #include <asm/mach-au1x00/au1000.h> | ||
25 | |||
26 | #ifndef CONFIG_SOC_AU1200 | ||
27 | |||
28 | #define USBH_ENABLE_BE (1<<0) | ||
29 | #define USBH_ENABLE_C (1<<1) | ||
30 | #define USBH_ENABLE_E (1<<2) | ||
31 | #define USBH_ENABLE_CE (1<<3) | ||
32 | #define USBH_ENABLE_RD (1<<4) | ||
33 | |||
34 | #ifdef __LITTLE_ENDIAN | ||
35 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C) | ||
36 | #elif defined(__BIG_ENDIAN) | ||
37 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | \ | ||
38 | USBH_ENABLE_BE) | ||
39 | #else | ||
40 | #error not byte order defined | ||
41 | #endif | ||
42 | |||
43 | #else /* Au1200 */ | ||
44 | |||
45 | #define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG) | ||
46 | #define USB_MCFG_PFEN (1<<31) | ||
47 | #define USB_MCFG_RDCOMB (1<<30) | ||
48 | #define USB_MCFG_SSDEN (1<<23) | ||
49 | #define USB_MCFG_OHCCLKEN (1<<16) | ||
50 | #ifdef CONFIG_DMA_COHERENT | ||
51 | #define USB_MCFG_UCAM (1<<7) | ||
52 | #else | ||
53 | #define USB_MCFG_UCAM (0) | ||
54 | #endif | ||
55 | #define USB_MCFG_OBMEN (1<<1) | ||
56 | #define USB_MCFG_OMEMEN (1<<0) | ||
57 | |||
58 | #define USBH_ENABLE_CE USB_MCFG_OHCCLKEN | ||
59 | |||
60 | #define USBH_ENABLE_INIT (USB_MCFG_PFEN | USB_MCFG_RDCOMB | \ | ||
61 | USBH_ENABLE_CE | USB_MCFG_SSDEN | \ | ||
62 | USB_MCFG_UCAM | \ | ||
63 | USB_MCFG_OBMEN | USB_MCFG_OMEMEN) | ||
64 | |||
65 | #define USBH_DISABLE (USB_MCFG_OBMEN | USB_MCFG_OMEMEN) | ||
66 | |||
67 | #endif /* Au1200 */ | ||
68 | |||
69 | extern int usb_disabled(void); | ||
70 | |||
71 | static void au1xxx_start_ohc(void) | ||
72 | { | ||
73 | /* enable host controller */ | ||
74 | #ifndef CONFIG_SOC_AU1200 | ||
75 | au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
76 | au_sync(); | ||
77 | udelay(1000); | ||
78 | |||
79 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG); | ||
80 | au_sync(); | ||
81 | udelay(1000); | ||
82 | |||
83 | /* wait for reset complete (read register twice; see au1500 errata) */ | ||
84 | while (au_readl(USB_HOST_CONFIG), | ||
85 | !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) | ||
86 | udelay(1000); | ||
87 | |||
88 | #else /* Au1200 */ | ||
89 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
90 | au_sync(); | ||
91 | udelay(1000); | ||
92 | |||
93 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG); | ||
94 | au_sync(); | ||
95 | udelay(2000); | ||
96 | #endif /* Au1200 */ | ||
97 | } | ||
98 | |||
99 | static void au1xxx_stop_ohc(void) | ||
100 | { | ||
101 | #ifdef CONFIG_SOC_AU1200 | ||
102 | /* Disable mem */ | ||
103 | au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG); | ||
104 | au_sync(); | ||
105 | udelay(1000); | ||
106 | #endif | ||
107 | /* Disable clock */ | ||
108 | au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
109 | au_sync(); | ||
110 | } | ||
111 | |||
112 | static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd) | ||
113 | { | ||
114 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
115 | int ret; | ||
116 | |||
117 | ohci_dbg(ohci, "ohci_au1xxx_start, ohci:%p", ohci); | ||
118 | |||
119 | if ((ret = ohci_init(ohci)) < 0) | ||
120 | return ret; | ||
121 | |||
122 | if ((ret = ohci_run(ohci)) < 0) { | ||
123 | err ("can't start %s", hcd->self.bus_name); | ||
124 | ohci_stop(hcd); | ||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static const struct hc_driver ohci_au1xxx_hc_driver = { | ||
132 | .description = hcd_name, | ||
133 | .product_desc = "Au1xxx OHCI", | ||
134 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
135 | |||
136 | /* | ||
137 | * generic hardware linkage | ||
138 | */ | ||
139 | .irq = ohci_irq, | ||
140 | .flags = HCD_USB11 | HCD_MEMORY, | ||
141 | |||
142 | /* | ||
143 | * basic lifecycle operations | ||
144 | */ | ||
145 | .start = ohci_au1xxx_start, | ||
146 | .stop = ohci_stop, | ||
147 | .shutdown = ohci_shutdown, | ||
148 | |||
149 | /* | ||
150 | * managing i/o requests and associated device resources | ||
151 | */ | ||
152 | .urb_enqueue = ohci_urb_enqueue, | ||
153 | .urb_dequeue = ohci_urb_dequeue, | ||
154 | .endpoint_disable = ohci_endpoint_disable, | ||
155 | |||
156 | /* | ||
157 | * scheduling support | ||
158 | */ | ||
159 | .get_frame_number = ohci_get_frame, | ||
160 | |||
161 | /* | ||
162 | * root hub support | ||
163 | */ | ||
164 | .hub_status_data = ohci_hub_status_data, | ||
165 | .hub_control = ohci_hub_control, | ||
166 | #ifdef CONFIG_PM | ||
167 | .bus_suspend = ohci_bus_suspend, | ||
168 | .bus_resume = ohci_bus_resume, | ||
169 | #endif | ||
170 | .start_port_reset = ohci_start_port_reset, | ||
171 | }; | ||
172 | |||
173 | static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | ||
174 | { | ||
175 | int ret; | ||
176 | struct usb_hcd *hcd; | ||
177 | |||
178 | if (usb_disabled()) | ||
179 | return -ENODEV; | ||
180 | |||
181 | #if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT) | ||
182 | /* Au1200 AB USB does not support coherent memory */ | ||
183 | if (!(read_c0_prid() & 0xff)) { | ||
184 | printk(KERN_INFO "%s: this is chip revision AB !!\n", | ||
185 | pdev->name); | ||
186 | printk(KERN_INFO "%s: update your board or re-configure " | ||
187 | "the kernel\n", pdev->name); | ||
188 | return -ENODEV; | ||
189 | } | ||
190 | #endif | ||
191 | |||
192 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | ||
193 | pr_debug("resource[1] is not IORESOURCE_IRQ\n"); | ||
194 | return -ENOMEM; | ||
195 | } | ||
196 | |||
197 | hcd = usb_create_hcd(&ohci_au1xxx_hc_driver, &pdev->dev, "au1xxx"); | ||
198 | if (!hcd) | ||
199 | return -ENOMEM; | ||
200 | |||
201 | hcd->rsrc_start = pdev->resource[0].start; | ||
202 | hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; | ||
203 | |||
204 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
205 | pr_debug("request_mem_region failed\n"); | ||
206 | ret = -EBUSY; | ||
207 | goto err1; | ||
208 | } | ||
209 | |||
210 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
211 | if (!hcd->regs) { | ||
212 | pr_debug("ioremap failed\n"); | ||
213 | ret = -ENOMEM; | ||
214 | goto err2; | ||
215 | } | ||
216 | |||
217 | au1xxx_start_ohc(); | ||
218 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
219 | |||
220 | ret = usb_add_hcd(hcd, pdev->resource[1].start, | ||
221 | IRQF_DISABLED | IRQF_SHARED); | ||
222 | if (ret == 0) { | ||
223 | platform_set_drvdata(pdev, hcd); | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | au1xxx_stop_ohc(); | ||
228 | iounmap(hcd->regs); | ||
229 | err2: | ||
230 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
231 | err1: | ||
232 | usb_put_hcd(hcd); | ||
233 | return ret; | ||
234 | } | ||
235 | |||
236 | static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) | ||
237 | { | ||
238 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
239 | |||
240 | usb_remove_hcd(hcd); | ||
241 | au1xxx_stop_ohc(); | ||
242 | iounmap(hcd->regs); | ||
243 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
244 | usb_put_hcd(hcd); | ||
245 | platform_set_drvdata(pdev, NULL); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | #ifdef CONFIG_PM | ||
251 | static int ohci_hcd_au1xxx_drv_suspend(struct device *dev) | ||
252 | { | ||
253 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
254 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
255 | unsigned long flags; | ||
256 | int rc; | ||
257 | |||
258 | rc = 0; | ||
259 | |||
260 | /* Root hub was already suspended. Disable irq emission and | ||
261 | * mark HW unaccessible, bail out if RH has been resumed. Use | ||
262 | * the spinlock to properly synchronize with possible pending | ||
263 | * RH suspend or resume activity. | ||
264 | * | ||
265 | * This is still racy as hcd->state is manipulated outside of | ||
266 | * any locks =P But that will be a different fix. | ||
267 | */ | ||
268 | spin_lock_irqsave(&ohci->lock, flags); | ||
269 | if (hcd->state != HC_STATE_SUSPENDED) { | ||
270 | rc = -EINVAL; | ||
271 | goto bail; | ||
272 | } | ||
273 | ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | ||
274 | (void)ohci_readl(ohci, &ohci->regs->intrdisable); | ||
275 | |||
276 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
277 | |||
278 | au1xxx_stop_ohc(); | ||
279 | bail: | ||
280 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
281 | |||
282 | return rc; | ||
283 | } | ||
284 | |||
285 | static int ohci_hcd_au1xxx_drv_resume(struct device *dev) | ||
286 | { | ||
287 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
288 | |||
289 | au1xxx_start_ohc(); | ||
290 | |||
291 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
292 | ohci_finish_controller_resume(hcd); | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static const struct dev_pm_ops au1xxx_ohci_pmops = { | ||
298 | .suspend = ohci_hcd_au1xxx_drv_suspend, | ||
299 | .resume = ohci_hcd_au1xxx_drv_resume, | ||
300 | }; | ||
301 | |||
302 | #define AU1XXX_OHCI_PMOPS &au1xxx_ohci_pmops | ||
303 | |||
304 | #else | ||
305 | #define AU1XXX_OHCI_PMOPS NULL | ||
306 | #endif | ||
307 | |||
308 | static struct platform_driver ohci_hcd_au1xxx_driver = { | ||
309 | .probe = ohci_hcd_au1xxx_drv_probe, | ||
310 | .remove = ohci_hcd_au1xxx_drv_remove, | ||
311 | .shutdown = usb_hcd_platform_shutdown, | ||
312 | .driver = { | ||
313 | .name = "au1xxx-ohci", | ||
314 | .owner = THIS_MODULE, | ||
315 | .pm = AU1XXX_OHCI_PMOPS, | ||
316 | }, | ||
317 | }; | ||
318 | |||
319 | MODULE_ALIAS("platform:au1xxx-ohci"); | ||
diff --git a/drivers/usb/host/ohci-cns3xxx.c b/drivers/usb/host/ohci-cns3xxx.c new file mode 100644 index 00000000000..5a00a1e1c6c --- /dev/null +++ b/drivers/usb/host/ohci-cns3xxx.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cavium Networks | ||
3 | * | ||
4 | * This file is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License, Version 2, as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/platform_device.h> | ||
10 | #include <linux/atomic.h> | ||
11 | #include <mach/cns3xxx.h> | ||
12 | #include <mach/pm.h> | ||
13 | |||
14 | static int __devinit | ||
15 | cns3xxx_ohci_start(struct usb_hcd *hcd) | ||
16 | { | ||
17 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
18 | int ret; | ||
19 | |||
20 | /* | ||
21 | * EHCI and OHCI share the same clock and power, | ||
22 | * resetting twice would cause the 1st controller been reset. | ||
23 | * Therefore only do power up at the first up device, and | ||
24 | * power down at the last down device. | ||
25 | * | ||
26 | * Set USB AHB INCR length to 16 | ||
27 | */ | ||
28 | if (atomic_inc_return(&usb_pwr_ref) == 1) { | ||
29 | cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); | ||
30 | cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
31 | cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); | ||
32 | __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), | ||
33 | MISC_CHIP_CONFIG_REG); | ||
34 | } | ||
35 | |||
36 | ret = ohci_init(ohci); | ||
37 | if (ret < 0) | ||
38 | return ret; | ||
39 | |||
40 | ohci->num_ports = 1; | ||
41 | |||
42 | ret = ohci_run(ohci); | ||
43 | if (ret < 0) { | ||
44 | err("can't start %s", hcd->self.bus_name); | ||
45 | ohci_stop(hcd); | ||
46 | return ret; | ||
47 | } | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static const struct hc_driver cns3xxx_ohci_hc_driver = { | ||
52 | .description = hcd_name, | ||
53 | .product_desc = "CNS3XXX OHCI Host controller", | ||
54 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
55 | .irq = ohci_irq, | ||
56 | .flags = HCD_USB11 | HCD_MEMORY, | ||
57 | .start = cns3xxx_ohci_start, | ||
58 | .stop = ohci_stop, | ||
59 | .shutdown = ohci_shutdown, | ||
60 | .urb_enqueue = ohci_urb_enqueue, | ||
61 | .urb_dequeue = ohci_urb_dequeue, | ||
62 | .endpoint_disable = ohci_endpoint_disable, | ||
63 | .get_frame_number = ohci_get_frame, | ||
64 | .hub_status_data = ohci_hub_status_data, | ||
65 | .hub_control = ohci_hub_control, | ||
66 | #ifdef CONFIG_PM | ||
67 | .bus_suspend = ohci_bus_suspend, | ||
68 | .bus_resume = ohci_bus_resume, | ||
69 | #endif | ||
70 | .start_port_reset = ohci_start_port_reset, | ||
71 | }; | ||
72 | |||
73 | static int cns3xxx_ohci_probe(struct platform_device *pdev) | ||
74 | { | ||
75 | struct device *dev = &pdev->dev; | ||
76 | struct usb_hcd *hcd; | ||
77 | const struct hc_driver *driver = &cns3xxx_ohci_hc_driver; | ||
78 | struct resource *res; | ||
79 | int irq; | ||
80 | int retval; | ||
81 | |||
82 | if (usb_disabled()) | ||
83 | return -ENODEV; | ||
84 | |||
85 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
86 | if (!res) { | ||
87 | dev_err(dev, "Found HC with no IRQ.\n"); | ||
88 | return -ENODEV; | ||
89 | } | ||
90 | irq = res->start; | ||
91 | |||
92 | hcd = usb_create_hcd(driver, dev, dev_name(dev)); | ||
93 | if (!hcd) | ||
94 | return -ENOMEM; | ||
95 | |||
96 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
97 | if (!res) { | ||
98 | dev_err(dev, "Found HC with no register addr.\n"); | ||
99 | retval = -ENODEV; | ||
100 | goto err1; | ||
101 | } | ||
102 | hcd->rsrc_start = res->start; | ||
103 | hcd->rsrc_len = resource_size(res); | ||
104 | |||
105 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
106 | driver->description)) { | ||
107 | dev_dbg(dev, "controller already in use\n"); | ||
108 | retval = -EBUSY; | ||
109 | goto err1; | ||
110 | } | ||
111 | |||
112 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
113 | if (!hcd->regs) { | ||
114 | dev_dbg(dev, "error mapping memory\n"); | ||
115 | retval = -EFAULT; | ||
116 | goto err2; | ||
117 | } | ||
118 | |||
119 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
120 | |||
121 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
122 | if (retval == 0) | ||
123 | return retval; | ||
124 | |||
125 | iounmap(hcd->regs); | ||
126 | err2: | ||
127 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
128 | err1: | ||
129 | usb_put_hcd(hcd); | ||
130 | return retval; | ||
131 | } | ||
132 | |||
133 | static int cns3xxx_ohci_remove(struct platform_device *pdev) | ||
134 | { | ||
135 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
136 | |||
137 | usb_remove_hcd(hcd); | ||
138 | iounmap(hcd->regs); | ||
139 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
140 | |||
141 | /* | ||
142 | * EHCI and OHCI share the same clock and power, | ||
143 | * resetting twice would cause the 1st controller been reset. | ||
144 | * Therefore only do power up at the first up device, and | ||
145 | * power down at the last down device. | ||
146 | */ | ||
147 | if (atomic_dec_return(&usb_pwr_ref) == 0) | ||
148 | cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
149 | |||
150 | usb_put_hcd(hcd); | ||
151 | |||
152 | platform_set_drvdata(pdev, NULL); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | MODULE_ALIAS("platform:cns3xxx-ohci"); | ||
158 | |||
159 | static struct platform_driver ohci_hcd_cns3xxx_driver = { | ||
160 | .probe = cns3xxx_ohci_probe, | ||
161 | .remove = cns3xxx_ohci_remove, | ||
162 | .driver = { | ||
163 | .name = "cns3xxx-ohci", | ||
164 | }, | ||
165 | }; | ||
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c new file mode 100644 index 00000000000..653d6a60edb --- /dev/null +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -0,0 +1,453 @@ | |||
1 | /* | ||
2 | * drivers/usb/host/ohci-pnx4008.c | ||
3 | * | ||
4 | * driver for Philips PNX4008 USB Host | ||
5 | * | ||
6 | * Authors: Dmitry Chigirev <source@mvista.com> | ||
7 | * Vitaly Wool <vitalywool@gmail.com> | ||
8 | * | ||
9 | * register initialization is based on code examples provided by Philips | ||
10 | * Copyright (c) 2005 Koninklijke Philips Electronics N.V. | ||
11 | * | ||
12 | * NOTE: This driver does not have suspend/resume functionality | ||
13 | * This driver is intended for engineering development purposes only | ||
14 | * | ||
15 | * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under | ||
16 | * the terms of the GNU General Public License version 2. This program | ||
17 | * is licensed "as is" without any warranty of any kind, whether express | ||
18 | * or implied. | ||
19 | */ | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/i2c.h> | ||
23 | |||
24 | #include <mach/hardware.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | #include <mach/platform.h> | ||
28 | #include <mach/irqs.h> | ||
29 | #include <mach/gpio.h> | ||
30 | |||
31 | #define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64) | ||
32 | |||
33 | /* USB_CTRL bit defines */ | ||
34 | #define USB_SLAVE_HCLK_EN (1 << 24) | ||
35 | #define USB_HOST_NEED_CLK_EN (1 << 21) | ||
36 | |||
37 | #define USB_OTG_CLK_CTRL IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0xFF4) | ||
38 | #define USB_OTG_CLK_STAT IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0xFF8) | ||
39 | |||
40 | /* USB_OTG_CLK_CTRL bit defines */ | ||
41 | #define AHB_M_CLOCK_ON (1 << 4) | ||
42 | #define OTG_CLOCK_ON (1 << 3) | ||
43 | #define I2C_CLOCK_ON (1 << 2) | ||
44 | #define DEV_CLOCK_ON (1 << 1) | ||
45 | #define HOST_CLOCK_ON (1 << 0) | ||
46 | |||
47 | #define USB_OTG_STAT_CONTROL IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0x110) | ||
48 | |||
49 | /* USB_OTG_STAT_CONTROL bit defines */ | ||
50 | #define TRANSPARENT_I2C_EN (1 << 7) | ||
51 | #define HOST_EN (1 << 0) | ||
52 | |||
53 | /* ISP1301 USB transceiver I2C registers */ | ||
54 | #define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */ | ||
55 | |||
56 | #define MC1_SPEED_REG (1 << 0) | ||
57 | #define MC1_SUSPEND_REG (1 << 1) | ||
58 | #define MC1_DAT_SE0 (1 << 2) | ||
59 | #define MC1_TRANSPARENT (1 << 3) | ||
60 | #define MC1_BDIS_ACON_EN (1 << 4) | ||
61 | #define MC1_OE_INT_EN (1 << 5) | ||
62 | #define MC1_UART_EN (1 << 6) | ||
63 | #define MC1_MASK 0x7f | ||
64 | |||
65 | #define ISP1301_MODE_CONTROL_2 0x12 /* u8 read, set, +1 clear */ | ||
66 | |||
67 | #define MC2_GLOBAL_PWR_DN (1 << 0) | ||
68 | #define MC2_SPD_SUSP_CTRL (1 << 1) | ||
69 | #define MC2_BI_DI (1 << 2) | ||
70 | #define MC2_TRANSP_BDIR0 (1 << 3) | ||
71 | #define MC2_TRANSP_BDIR1 (1 << 4) | ||
72 | #define MC2_AUDIO_EN (1 << 5) | ||
73 | #define MC2_PSW_EN (1 << 6) | ||
74 | #define MC2_EN2V7 (1 << 7) | ||
75 | |||
76 | #define ISP1301_OTG_CONTROL_1 0x06 /* u8 read, set, +1 clear */ | ||
77 | # define OTG1_DP_PULLUP (1 << 0) | ||
78 | # define OTG1_DM_PULLUP (1 << 1) | ||
79 | # define OTG1_DP_PULLDOWN (1 << 2) | ||
80 | # define OTG1_DM_PULLDOWN (1 << 3) | ||
81 | # define OTG1_ID_PULLDOWN (1 << 4) | ||
82 | # define OTG1_VBUS_DRV (1 << 5) | ||
83 | # define OTG1_VBUS_DISCHRG (1 << 6) | ||
84 | # define OTG1_VBUS_CHRG (1 << 7) | ||
85 | #define ISP1301_OTG_STATUS 0x10 /* u8 readonly */ | ||
86 | # define OTG_B_SESS_END (1 << 6) | ||
87 | # define OTG_B_SESS_VLD (1 << 7) | ||
88 | |||
89 | #define ISP1301_I2C_ADDR 0x2C | ||
90 | |||
91 | #define ISP1301_I2C_MODE_CONTROL_1 0x4 | ||
92 | #define ISP1301_I2C_MODE_CONTROL_2 0x12 | ||
93 | #define ISP1301_I2C_OTG_CONTROL_1 0x6 | ||
94 | #define ISP1301_I2C_OTG_CONTROL_2 0x10 | ||
95 | #define ISP1301_I2C_INTERRUPT_SOURCE 0x8 | ||
96 | #define ISP1301_I2C_INTERRUPT_LATCH 0xA | ||
97 | #define ISP1301_I2C_INTERRUPT_FALLING 0xC | ||
98 | #define ISP1301_I2C_INTERRUPT_RISING 0xE | ||
99 | #define ISP1301_I2C_REG_CLEAR_ADDR 1 | ||
100 | |||
101 | static struct i2c_driver isp1301_driver; | ||
102 | static struct i2c_client *isp1301_i2c_client; | ||
103 | |||
104 | extern int usb_disabled(void); | ||
105 | extern int ocpi_enable(void); | ||
106 | |||
107 | static struct clk *usb_clk; | ||
108 | |||
109 | static const unsigned short normal_i2c[] = | ||
110 | { ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END }; | ||
111 | |||
112 | static int isp1301_probe(struct i2c_client *client, | ||
113 | const struct i2c_device_id *id) | ||
114 | { | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int isp1301_remove(struct i2c_client *client) | ||
119 | { | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static const struct i2c_device_id isp1301_id[] = { | ||
124 | { "isp1301_pnx", 0 }, | ||
125 | { } | ||
126 | }; | ||
127 | |||
128 | static struct i2c_driver isp1301_driver = { | ||
129 | .driver = { | ||
130 | .name = "isp1301_pnx", | ||
131 | }, | ||
132 | .probe = isp1301_probe, | ||
133 | .remove = isp1301_remove, | ||
134 | .id_table = isp1301_id, | ||
135 | }; | ||
136 | |||
137 | static void i2c_write(u8 buf, u8 subaddr) | ||
138 | { | ||
139 | char tmpbuf[2]; | ||
140 | |||
141 | tmpbuf[0] = subaddr; /*register number */ | ||
142 | tmpbuf[1] = buf; /*register data */ | ||
143 | i2c_master_send(isp1301_i2c_client, &tmpbuf[0], 2); | ||
144 | } | ||
145 | |||
146 | static void isp1301_configure(void) | ||
147 | { | ||
148 | /* PNX4008 only supports DAT_SE0 USB mode */ | ||
149 | /* PNX4008 R2A requires setting the MAX603 to output 3.6V */ | ||
150 | /* Power up externel charge-pump */ | ||
151 | |||
152 | i2c_write(MC1_DAT_SE0 | MC1_SPEED_REG, ISP1301_I2C_MODE_CONTROL_1); | ||
153 | i2c_write(~(MC1_DAT_SE0 | MC1_SPEED_REG), | ||
154 | ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR); | ||
155 | i2c_write(MC2_BI_DI | MC2_PSW_EN | MC2_SPD_SUSP_CTRL, | ||
156 | ISP1301_I2C_MODE_CONTROL_2); | ||
157 | i2c_write(~(MC2_BI_DI | MC2_PSW_EN | MC2_SPD_SUSP_CTRL), | ||
158 | ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR); | ||
159 | i2c_write(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN, | ||
160 | ISP1301_I2C_OTG_CONTROL_1); | ||
161 | i2c_write(~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN), | ||
162 | ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR); | ||
163 | i2c_write(0xFF, | ||
164 | ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR); | ||
165 | i2c_write(0xFF, | ||
166 | ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR); | ||
167 | i2c_write(0xFF, | ||
168 | ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR); | ||
169 | |||
170 | } | ||
171 | |||
172 | static inline void isp1301_vbus_on(void) | ||
173 | { | ||
174 | i2c_write(OTG1_VBUS_DRV, ISP1301_I2C_OTG_CONTROL_1); | ||
175 | } | ||
176 | |||
177 | static inline void isp1301_vbus_off(void) | ||
178 | { | ||
179 | i2c_write(OTG1_VBUS_DRV, | ||
180 | ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR); | ||
181 | } | ||
182 | |||
183 | static void pnx4008_start_hc(void) | ||
184 | { | ||
185 | unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN; | ||
186 | __raw_writel(tmp, USB_OTG_STAT_CONTROL); | ||
187 | isp1301_vbus_on(); | ||
188 | } | ||
189 | |||
190 | static void pnx4008_stop_hc(void) | ||
191 | { | ||
192 | unsigned long tmp; | ||
193 | isp1301_vbus_off(); | ||
194 | tmp = __raw_readl(USB_OTG_STAT_CONTROL) & ~HOST_EN; | ||
195 | __raw_writel(tmp, USB_OTG_STAT_CONTROL); | ||
196 | } | ||
197 | |||
198 | static int __devinit ohci_pnx4008_start(struct usb_hcd *hcd) | ||
199 | { | ||
200 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
201 | int ret; | ||
202 | |||
203 | if ((ret = ohci_init(ohci)) < 0) | ||
204 | return ret; | ||
205 | |||
206 | if ((ret = ohci_run(ohci)) < 0) { | ||
207 | dev_err(hcd->self.controller, "can't start\n"); | ||
208 | ohci_stop(hcd); | ||
209 | return ret; | ||
210 | } | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static const struct hc_driver ohci_pnx4008_hc_driver = { | ||
215 | .description = hcd_name, | ||
216 | .product_desc = "pnx4008 OHCI", | ||
217 | |||
218 | /* | ||
219 | * generic hardware linkage | ||
220 | */ | ||
221 | .irq = ohci_irq, | ||
222 | .flags = HCD_USB11 | HCD_MEMORY, | ||
223 | |||
224 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
225 | /* | ||
226 | * basic lifecycle operations | ||
227 | */ | ||
228 | .start = ohci_pnx4008_start, | ||
229 | .stop = ohci_stop, | ||
230 | .shutdown = ohci_shutdown, | ||
231 | |||
232 | /* | ||
233 | * managing i/o requests and associated device resources | ||
234 | */ | ||
235 | .urb_enqueue = ohci_urb_enqueue, | ||
236 | .urb_dequeue = ohci_urb_dequeue, | ||
237 | .endpoint_disable = ohci_endpoint_disable, | ||
238 | |||
239 | /* | ||
240 | * scheduling support | ||
241 | */ | ||
242 | .get_frame_number = ohci_get_frame, | ||
243 | |||
244 | /* | ||
245 | * root hub support | ||
246 | */ | ||
247 | .hub_status_data = ohci_hub_status_data, | ||
248 | .hub_control = ohci_hub_control, | ||
249 | #ifdef CONFIG_PM | ||
250 | .bus_suspend = ohci_bus_suspend, | ||
251 | .bus_resume = ohci_bus_resume, | ||
252 | #endif | ||
253 | .start_port_reset = ohci_start_port_reset, | ||
254 | }; | ||
255 | |||
256 | #define USB_CLOCK_MASK (AHB_M_CLOCK_ON| OTG_CLOCK_ON | HOST_CLOCK_ON | I2C_CLOCK_ON) | ||
257 | |||
258 | static void pnx4008_set_usb_bits(void) | ||
259 | { | ||
260 | start_int_set_falling_edge(SE_USB_OTG_ATX_INT_N); | ||
261 | start_int_ack(SE_USB_OTG_ATX_INT_N); | ||
262 | start_int_umask(SE_USB_OTG_ATX_INT_N); | ||
263 | |||
264 | start_int_set_rising_edge(SE_USB_OTG_TIMER_INT); | ||
265 | start_int_ack(SE_USB_OTG_TIMER_INT); | ||
266 | start_int_umask(SE_USB_OTG_TIMER_INT); | ||
267 | |||
268 | start_int_set_rising_edge(SE_USB_I2C_INT); | ||
269 | start_int_ack(SE_USB_I2C_INT); | ||
270 | start_int_umask(SE_USB_I2C_INT); | ||
271 | |||
272 | start_int_set_rising_edge(SE_USB_INT); | ||
273 | start_int_ack(SE_USB_INT); | ||
274 | start_int_umask(SE_USB_INT); | ||
275 | |||
276 | start_int_set_rising_edge(SE_USB_NEED_CLK_INT); | ||
277 | start_int_ack(SE_USB_NEED_CLK_INT); | ||
278 | start_int_umask(SE_USB_NEED_CLK_INT); | ||
279 | |||
280 | start_int_set_rising_edge(SE_USB_AHB_NEED_CLK_INT); | ||
281 | start_int_ack(SE_USB_AHB_NEED_CLK_INT); | ||
282 | start_int_umask(SE_USB_AHB_NEED_CLK_INT); | ||
283 | } | ||
284 | |||
285 | static void pnx4008_unset_usb_bits(void) | ||
286 | { | ||
287 | start_int_mask(SE_USB_OTG_ATX_INT_N); | ||
288 | start_int_mask(SE_USB_OTG_TIMER_INT); | ||
289 | start_int_mask(SE_USB_I2C_INT); | ||
290 | start_int_mask(SE_USB_INT); | ||
291 | start_int_mask(SE_USB_NEED_CLK_INT); | ||
292 | start_int_mask(SE_USB_AHB_NEED_CLK_INT); | ||
293 | } | ||
294 | |||
295 | static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) | ||
296 | { | ||
297 | struct usb_hcd *hcd = 0; | ||
298 | struct ohci_hcd *ohci; | ||
299 | const struct hc_driver *driver = &ohci_pnx4008_hc_driver; | ||
300 | struct i2c_adapter *i2c_adap; | ||
301 | struct i2c_board_info i2c_info; | ||
302 | |||
303 | int ret = 0, irq; | ||
304 | |||
305 | dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (pnx4008)\n", hcd_name); | ||
306 | if (usb_disabled()) { | ||
307 | err("USB is disabled"); | ||
308 | ret = -ENODEV; | ||
309 | goto out; | ||
310 | } | ||
311 | |||
312 | if (pdev->num_resources != 2 | ||
313 | || pdev->resource[0].flags != IORESOURCE_MEM | ||
314 | || pdev->resource[1].flags != IORESOURCE_IRQ) { | ||
315 | err("Invalid resource configuration"); | ||
316 | ret = -ENODEV; | ||
317 | goto out; | ||
318 | } | ||
319 | |||
320 | /* Enable AHB slave USB clock, needed for further USB clock control */ | ||
321 | __raw_writel(USB_SLAVE_HCLK_EN | (1 << 19), USB_CTRL); | ||
322 | |||
323 | ret = i2c_add_driver(&isp1301_driver); | ||
324 | if (ret < 0) { | ||
325 | err("failed to add ISP1301 driver"); | ||
326 | goto out; | ||
327 | } | ||
328 | i2c_adap = i2c_get_adapter(2); | ||
329 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); | ||
330 | strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE); | ||
331 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, | ||
332 | normal_i2c, NULL); | ||
333 | i2c_put_adapter(i2c_adap); | ||
334 | if (!isp1301_i2c_client) { | ||
335 | err("failed to connect I2C to ISP1301 USB Transceiver"); | ||
336 | ret = -ENODEV; | ||
337 | goto out_i2c_driver; | ||
338 | } | ||
339 | |||
340 | isp1301_configure(); | ||
341 | |||
342 | /* Enable USB PLL */ | ||
343 | usb_clk = clk_get(&pdev->dev, "ck_pll5"); | ||
344 | if (IS_ERR(usb_clk)) { | ||
345 | err("failed to acquire USB PLL"); | ||
346 | ret = PTR_ERR(usb_clk); | ||
347 | goto out1; | ||
348 | } | ||
349 | |||
350 | ret = clk_enable(usb_clk); | ||
351 | if (ret < 0) { | ||
352 | err("failed to start USB PLL"); | ||
353 | goto out2; | ||
354 | } | ||
355 | |||
356 | ret = clk_set_rate(usb_clk, 48000); | ||
357 | if (ret < 0) { | ||
358 | err("failed to set USB clock rate"); | ||
359 | goto out3; | ||
360 | } | ||
361 | |||
362 | __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); | ||
363 | |||
364 | /* Set to enable all needed USB clocks */ | ||
365 | __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL); | ||
366 | |||
367 | while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) != | ||
368 | USB_CLOCK_MASK) ; | ||
369 | |||
370 | hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev)); | ||
371 | if (!hcd) { | ||
372 | err("Failed to allocate HC buffer"); | ||
373 | ret = -ENOMEM; | ||
374 | goto out3; | ||
375 | } | ||
376 | |||
377 | /* Set all USB bits in the Start Enable register */ | ||
378 | pnx4008_set_usb_bits(); | ||
379 | |||
380 | hcd->rsrc_start = pdev->resource[0].start; | ||
381 | hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; | ||
382 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
383 | dev_dbg(&pdev->dev, "request_mem_region failed\n"); | ||
384 | ret = -ENOMEM; | ||
385 | goto out4; | ||
386 | } | ||
387 | hcd->regs = (void __iomem *)pdev->resource[0].start; | ||
388 | |||
389 | irq = platform_get_irq(pdev, 0); | ||
390 | if (irq < 0) { | ||
391 | ret = -ENXIO; | ||
392 | goto out4; | ||
393 | } | ||
394 | |||
395 | pnx4008_start_hc(); | ||
396 | platform_set_drvdata(pdev, hcd); | ||
397 | ohci = hcd_to_ohci(hcd); | ||
398 | ohci_hcd_init(ohci); | ||
399 | |||
400 | dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq); | ||
401 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | ||
402 | if (ret == 0) | ||
403 | return ret; | ||
404 | |||
405 | pnx4008_stop_hc(); | ||
406 | out4: | ||
407 | pnx4008_unset_usb_bits(); | ||
408 | usb_put_hcd(hcd); | ||
409 | out3: | ||
410 | clk_disable(usb_clk); | ||
411 | out2: | ||
412 | clk_put(usb_clk); | ||
413 | out1: | ||
414 | i2c_unregister_device(isp1301_i2c_client); | ||
415 | isp1301_i2c_client = NULL; | ||
416 | out_i2c_driver: | ||
417 | i2c_del_driver(&isp1301_driver); | ||
418 | out: | ||
419 | return ret; | ||
420 | } | ||
421 | |||
422 | static int usb_hcd_pnx4008_remove(struct platform_device *pdev) | ||
423 | { | ||
424 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
425 | |||
426 | usb_remove_hcd(hcd); | ||
427 | pnx4008_stop_hc(); | ||
428 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
429 | usb_put_hcd(hcd); | ||
430 | pnx4008_unset_usb_bits(); | ||
431 | clk_disable(usb_clk); | ||
432 | clk_put(usb_clk); | ||
433 | i2c_unregister_device(isp1301_i2c_client); | ||
434 | isp1301_i2c_client = NULL; | ||
435 | i2c_del_driver(&isp1301_driver); | ||
436 | |||
437 | platform_set_drvdata(pdev, NULL); | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | /* work with hotplug and coldplug */ | ||
443 | MODULE_ALIAS("platform:usb-ohci"); | ||
444 | |||
445 | static struct platform_driver usb_hcd_pnx4008_driver = { | ||
446 | .driver = { | ||
447 | .name = "usb-ohci", | ||
448 | .owner = THIS_MODULE, | ||
449 | }, | ||
450 | .probe = usb_hcd_pnx4008_probe, | ||
451 | .remove = usb_hcd_pnx4008_remove, | ||
452 | }; | ||
453 | |||
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c new file mode 100644 index 00000000000..28467e288a9 --- /dev/null +++ b/drivers/usb/host/ohci-pnx8550.c | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * (C) Copyright 2005 Embedded Alley Solutions, Inc. | ||
8 | * | ||
9 | * Bus Glue for PNX8550 | ||
10 | * | ||
11 | * Written by Christopher Hoover <ch@hpl.hp.com> | ||
12 | * Based on fragments of previous driver by Russell King et al. | ||
13 | * | ||
14 | * Modified for LH7A404 from ohci-sa1111.c | ||
15 | * by Durgesh Pattamatta <pattamattad@sharpsec.com> | ||
16 | * | ||
17 | * Modified for PNX8550 from ohci-sa1111.c and sa-omap.c | ||
18 | * by Vitaly Wool <vitalywool@gmail.com> | ||
19 | * | ||
20 | * This file is licenced under the GPL. | ||
21 | */ | ||
22 | |||
23 | #include <linux/device.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <asm/mach-pnx8550/usb.h> | ||
26 | #include <asm/mach-pnx8550/int.h> | ||
27 | #include <asm/mach-pnx8550/pci.h> | ||
28 | |||
29 | #ifndef CONFIG_PNX8550 | ||
30 | #error "This file is PNX8550 bus glue. CONFIG_PNX8550 must be defined." | ||
31 | #endif | ||
32 | |||
33 | extern int usb_disabled(void); | ||
34 | |||
35 | /*-------------------------------------------------------------------------*/ | ||
36 | |||
37 | static void pnx8550_start_hc(struct platform_device *dev) | ||
38 | { | ||
39 | /* | ||
40 | * Set register CLK48CTL to enable and 48MHz | ||
41 | */ | ||
42 | outl(0x00000003, PCI_BASE | 0x0004770c); | ||
43 | |||
44 | /* | ||
45 | * Set register CLK12CTL to enable and 48MHz | ||
46 | */ | ||
47 | outl(0x00000003, PCI_BASE | 0x00047710); | ||
48 | |||
49 | udelay(100); | ||
50 | } | ||
51 | |||
52 | static void pnx8550_stop_hc(struct platform_device *dev) | ||
53 | { | ||
54 | udelay(10); | ||
55 | } | ||
56 | |||
57 | |||
58 | /*-------------------------------------------------------------------------*/ | ||
59 | |||
60 | /* configure so an HC device and id are always provided */ | ||
61 | /* always called with process context; sleeping is OK */ | ||
62 | |||
63 | |||
64 | /** | ||
65 | * usb_hcd_pnx8550_probe - initialize pnx8550-based HCDs | ||
66 | * Context: !in_interrupt() | ||
67 | * | ||
68 | * Allocates basic resources for this USB host controller, and | ||
69 | * then invokes the start() method for the HCD associated with it | ||
70 | * through the hotplug entry's driver_data. | ||
71 | * | ||
72 | */ | ||
73 | int usb_hcd_pnx8550_probe (const struct hc_driver *driver, | ||
74 | struct platform_device *dev) | ||
75 | { | ||
76 | int retval; | ||
77 | struct usb_hcd *hcd; | ||
78 | |||
79 | if (dev->resource[0].flags != IORESOURCE_MEM || | ||
80 | dev->resource[1].flags != IORESOURCE_IRQ) { | ||
81 | dev_err (&dev->dev,"invalid resource type\n"); | ||
82 | return -ENOMEM; | ||
83 | } | ||
84 | |||
85 | hcd = usb_create_hcd (driver, &dev->dev, "pnx8550"); | ||
86 | if (!hcd) | ||
87 | return -ENOMEM; | ||
88 | hcd->rsrc_start = dev->resource[0].start; | ||
89 | hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; | ||
90 | |||
91 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
92 | dev_err(&dev->dev, "request_mem_region [0x%08llx, 0x%08llx] " | ||
93 | "failed\n", hcd->rsrc_start, hcd->rsrc_len); | ||
94 | retval = -EBUSY; | ||
95 | goto err1; | ||
96 | } | ||
97 | |||
98 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
99 | if (!hcd->regs) { | ||
100 | dev_err(&dev->dev, "ioremap [[0x%08llx, 0x%08llx] failed\n", | ||
101 | hcd->rsrc_start, hcd->rsrc_len); | ||
102 | retval = -ENOMEM; | ||
103 | goto err2; | ||
104 | } | ||
105 | |||
106 | pnx8550_start_hc(dev); | ||
107 | |||
108 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
109 | |||
110 | retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED); | ||
111 | if (retval == 0) | ||
112 | return retval; | ||
113 | |||
114 | pnx8550_stop_hc(dev); | ||
115 | iounmap(hcd->regs); | ||
116 | err2: | ||
117 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
118 | err1: | ||
119 | usb_put_hcd(hcd); | ||
120 | return retval; | ||
121 | } | ||
122 | |||
123 | |||
124 | /* may be called without controller electrically present */ | ||
125 | /* may be called with controller, bus, and devices active */ | ||
126 | |||
127 | /** | ||
128 | * usb_hcd_pnx8550_remove - shutdown processing for pnx8550-based HCDs | ||
129 | * @dev: USB Host Controller being removed | ||
130 | * Context: !in_interrupt() | ||
131 | * | ||
132 | * Reverses the effect of usb_hcd_pnx8550_probe(), first invoking | ||
133 | * the HCD's stop() method. It is always called from a thread | ||
134 | * context, normally "rmmod", "apmd", or something similar. | ||
135 | * | ||
136 | */ | ||
137 | void usb_hcd_pnx8550_remove (struct usb_hcd *hcd, struct platform_device *dev) | ||
138 | { | ||
139 | usb_remove_hcd(hcd); | ||
140 | pnx8550_stop_hc(dev); | ||
141 | iounmap(hcd->regs); | ||
142 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
143 | usb_put_hcd(hcd); | ||
144 | } | ||
145 | |||
146 | /*-------------------------------------------------------------------------*/ | ||
147 | |||
148 | static int __devinit | ||
149 | ohci_pnx8550_start (struct usb_hcd *hcd) | ||
150 | { | ||
151 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
152 | int ret; | ||
153 | |||
154 | ohci_dbg (ohci, "ohci_pnx8550_start, ohci:%p", ohci); | ||
155 | |||
156 | if ((ret = ohci_init(ohci)) < 0) | ||
157 | return ret; | ||
158 | |||
159 | if ((ret = ohci_run (ohci)) < 0) { | ||
160 | err ("can't start %s", hcd->self.bus_name); | ||
161 | ohci_stop (hcd); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /*-------------------------------------------------------------------------*/ | ||
169 | |||
170 | static const struct hc_driver ohci_pnx8550_hc_driver = { | ||
171 | .description = hcd_name, | ||
172 | .product_desc = "PNX8550 OHCI", | ||
173 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
174 | |||
175 | /* | ||
176 | * generic hardware linkage | ||
177 | */ | ||
178 | .irq = ohci_irq, | ||
179 | .flags = HCD_USB11 | HCD_MEMORY, | ||
180 | |||
181 | /* | ||
182 | * basic lifecycle operations | ||
183 | */ | ||
184 | .start = ohci_pnx8550_start, | ||
185 | .stop = ohci_stop, | ||
186 | |||
187 | /* | ||
188 | * managing i/o requests and associated device resources | ||
189 | */ | ||
190 | .urb_enqueue = ohci_urb_enqueue, | ||
191 | .urb_dequeue = ohci_urb_dequeue, | ||
192 | .endpoint_disable = ohci_endpoint_disable, | ||
193 | |||
194 | /* | ||
195 | * scheduling support | ||
196 | */ | ||
197 | .get_frame_number = ohci_get_frame, | ||
198 | |||
199 | /* | ||
200 | * root hub support | ||
201 | */ | ||
202 | .hub_status_data = ohci_hub_status_data, | ||
203 | .hub_control = ohci_hub_control, | ||
204 | #ifdef CONFIG_PM | ||
205 | .bus_suspend = ohci_bus_suspend, | ||
206 | .bus_resume = ohci_bus_resume, | ||
207 | #endif | ||
208 | .start_port_reset = ohci_start_port_reset, | ||
209 | }; | ||
210 | |||
211 | /*-------------------------------------------------------------------------*/ | ||
212 | |||
213 | static int ohci_hcd_pnx8550_drv_probe(struct platform_device *pdev) | ||
214 | { | ||
215 | int ret; | ||
216 | |||
217 | if (usb_disabled()) | ||
218 | return -ENODEV; | ||
219 | |||
220 | ret = usb_hcd_pnx8550_probe(&ohci_pnx8550_hc_driver, pdev); | ||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | static int ohci_hcd_pnx8550_drv_remove(struct platform_device *pdev) | ||
225 | { | ||
226 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
227 | |||
228 | usb_hcd_pnx8550_remove(hcd, pdev); | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | MODULE_ALIAS("platform:pnx8550-ohci"); | ||
233 | |||
234 | static struct platform_driver ohci_hcd_pnx8550_driver = { | ||
235 | .driver = { | ||
236 | .name = "pnx8550-ohci", | ||
237 | .owner = THIS_MODULE, | ||
238 | }, | ||
239 | .probe = ohci_hcd_pnx8550_drv_probe, | ||
240 | .remove = ohci_hcd_pnx8550_drv_remove, | ||
241 | }; | ||
242 | |||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c new file mode 100644 index 00000000000..c0f595c4448 --- /dev/null +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * (C) Copyright 2003-2005 MontaVista Software Inc. | ||
8 | * | ||
9 | * Bus Glue for PPC On-Chip OHCI driver | ||
10 | * Tested on Freescale MPC5200 and IBM STB04xxx | ||
11 | * | ||
12 | * Modified by Dale Farnsworth <dale@farnsworth.org> from ohci-sa1111.c | ||
13 | * | ||
14 | * This file is licenced under the GPL. | ||
15 | */ | ||
16 | |||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/signal.h> | ||
19 | |||
20 | /* configure so an HC device and id are always provided */ | ||
21 | /* always called with process context; sleeping is OK */ | ||
22 | |||
23 | /** | ||
24 | * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs | ||
25 | * Context: !in_interrupt() | ||
26 | * | ||
27 | * Allocates basic resources for this USB host controller. | ||
28 | * | ||
29 | * Store this function in the HCD's struct pci_driver as probe(). | ||
30 | */ | ||
31 | static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | ||
32 | struct platform_device *pdev) | ||
33 | { | ||
34 | int retval; | ||
35 | struct usb_hcd *hcd; | ||
36 | struct ohci_hcd *ohci; | ||
37 | struct resource *res; | ||
38 | int irq; | ||
39 | |||
40 | pr_debug("initializing PPC-SOC USB Controller\n"); | ||
41 | |||
42 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
43 | if (!res) { | ||
44 | pr_debug("%s: no irq\n", __FILE__); | ||
45 | return -ENODEV; | ||
46 | } | ||
47 | irq = res->start; | ||
48 | |||
49 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
50 | if (!res) { | ||
51 | pr_debug("%s: no reg addr\n", __FILE__); | ||
52 | return -ENODEV; | ||
53 | } | ||
54 | |||
55 | hcd = usb_create_hcd(driver, &pdev->dev, "PPC-SOC USB"); | ||
56 | if (!hcd) | ||
57 | return -ENOMEM; | ||
58 | hcd->rsrc_start = res->start; | ||
59 | hcd->rsrc_len = resource_size(res); | ||
60 | |||
61 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
62 | pr_debug("%s: request_mem_region failed\n", __FILE__); | ||
63 | retval = -EBUSY; | ||
64 | goto err1; | ||
65 | } | ||
66 | |||
67 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
68 | if (!hcd->regs) { | ||
69 | pr_debug("%s: ioremap failed\n", __FILE__); | ||
70 | retval = -ENOMEM; | ||
71 | goto err2; | ||
72 | } | ||
73 | |||
74 | ohci = hcd_to_ohci(hcd); | ||
75 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | ||
76 | |||
77 | #ifdef CONFIG_PPC_MPC52xx | ||
78 | /* MPC52xx doesn't need frame_no shift */ | ||
79 | ohci->flags |= OHCI_QUIRK_FRAME_NO; | ||
80 | #endif | ||
81 | ohci_hcd_init(ohci); | ||
82 | |||
83 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | ||
84 | if (retval == 0) | ||
85 | return retval; | ||
86 | |||
87 | pr_debug("Removing PPC-SOC USB Controller\n"); | ||
88 | |||
89 | iounmap(hcd->regs); | ||
90 | err2: | ||
91 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
92 | err1: | ||
93 | usb_put_hcd(hcd); | ||
94 | return retval; | ||
95 | } | ||
96 | |||
97 | |||
98 | /* may be called without controller electrically present */ | ||
99 | /* may be called with controller, bus, and devices active */ | ||
100 | |||
101 | /** | ||
102 | * usb_hcd_ppc_soc_remove - shutdown processing for On-Chip HCDs | ||
103 | * @pdev: USB Host Controller being removed | ||
104 | * Context: !in_interrupt() | ||
105 | * | ||
106 | * Reverses the effect of usb_hcd_ppc_soc_probe(). | ||
107 | * It is always called from a thread | ||
108 | * context, normally "rmmod", "apmd", or something similar. | ||
109 | * | ||
110 | */ | ||
111 | static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd, | ||
112 | struct platform_device *pdev) | ||
113 | { | ||
114 | usb_remove_hcd(hcd); | ||
115 | |||
116 | pr_debug("stopping PPC-SOC USB Controller\n"); | ||
117 | |||
118 | iounmap(hcd->regs); | ||
119 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
120 | usb_put_hcd(hcd); | ||
121 | } | ||
122 | |||
123 | static int __devinit | ||
124 | ohci_ppc_soc_start(struct usb_hcd *hcd) | ||
125 | { | ||
126 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
127 | int ret; | ||
128 | |||
129 | if ((ret = ohci_init(ohci)) < 0) | ||
130 | return ret; | ||
131 | |||
132 | if ((ret = ohci_run(ohci)) < 0) { | ||
133 | err("can't start %s", ohci_to_hcd(ohci)->self.bus_name); | ||
134 | ohci_stop(hcd); | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static const struct hc_driver ohci_ppc_soc_hc_driver = { | ||
142 | .description = hcd_name, | ||
143 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
144 | |||
145 | /* | ||
146 | * generic hardware linkage | ||
147 | */ | ||
148 | .irq = ohci_irq, | ||
149 | .flags = HCD_USB11 | HCD_MEMORY, | ||
150 | |||
151 | /* | ||
152 | * basic lifecycle operations | ||
153 | */ | ||
154 | .start = ohci_ppc_soc_start, | ||
155 | .stop = ohci_stop, | ||
156 | .shutdown = ohci_shutdown, | ||
157 | |||
158 | /* | ||
159 | * managing i/o requests and associated device resources | ||
160 | */ | ||
161 | .urb_enqueue = ohci_urb_enqueue, | ||
162 | .urb_dequeue = ohci_urb_dequeue, | ||
163 | .endpoint_disable = ohci_endpoint_disable, | ||
164 | |||
165 | /* | ||
166 | * scheduling support | ||
167 | */ | ||
168 | .get_frame_number = ohci_get_frame, | ||
169 | |||
170 | /* | ||
171 | * root hub support | ||
172 | */ | ||
173 | .hub_status_data = ohci_hub_status_data, | ||
174 | .hub_control = ohci_hub_control, | ||
175 | #ifdef CONFIG_PM | ||
176 | .bus_suspend = ohci_bus_suspend, | ||
177 | .bus_resume = ohci_bus_resume, | ||
178 | #endif | ||
179 | .start_port_reset = ohci_start_port_reset, | ||
180 | }; | ||
181 | |||
182 | static int ohci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) | ||
183 | { | ||
184 | int ret; | ||
185 | |||
186 | if (usb_disabled()) | ||
187 | return -ENODEV; | ||
188 | |||
189 | ret = usb_hcd_ppc_soc_probe(&ohci_ppc_soc_hc_driver, pdev); | ||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev) | ||
194 | { | ||
195 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
196 | |||
197 | usb_hcd_ppc_soc_remove(hcd, pdev); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static struct platform_driver ohci_hcd_ppc_soc_driver = { | ||
202 | .probe = ohci_hcd_ppc_soc_drv_probe, | ||
203 | .remove = ohci_hcd_ppc_soc_drv_remove, | ||
204 | .shutdown = usb_hcd_platform_shutdown, | ||
205 | #ifdef CONFIG_PM | ||
206 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ | ||
207 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ | ||
208 | #endif | ||
209 | .driver = { | ||
210 | .name = "ppc-soc-ohci", | ||
211 | .owner = THIS_MODULE, | ||
212 | }, | ||
213 | }; | ||
214 | |||
215 | MODULE_ALIAS("platform:ppc-soc-ohci"); | ||
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c new file mode 100644 index 00000000000..14cecb52a9f --- /dev/null +++ b/drivers/usb/host/ohci-sh.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * Copyright (C) 2008 Renesas Solutions Corp. | ||
5 | * | ||
6 | * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | ||
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 as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/platform_device.h> | ||
24 | |||
25 | static int ohci_sh_start(struct usb_hcd *hcd) | ||
26 | { | ||
27 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
28 | |||
29 | ohci_hcd_init(ohci); | ||
30 | ohci_init(ohci); | ||
31 | ohci_run(ohci); | ||
32 | hcd->state = HC_STATE_RUNNING; | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static const struct hc_driver ohci_sh_hc_driver = { | ||
37 | .description = hcd_name, | ||
38 | .product_desc = "SuperH OHCI", | ||
39 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
40 | |||
41 | /* | ||
42 | * generic hardware linkage | ||
43 | */ | ||
44 | .irq = ohci_irq, | ||
45 | .flags = HCD_USB11 | HCD_MEMORY, | ||
46 | |||
47 | /* | ||
48 | * basic lifecycle operations | ||
49 | */ | ||
50 | .start = ohci_sh_start, | ||
51 | .stop = ohci_stop, | ||
52 | .shutdown = ohci_shutdown, | ||
53 | |||
54 | /* | ||
55 | * managing i/o requests and associated device resources | ||
56 | */ | ||
57 | .urb_enqueue = ohci_urb_enqueue, | ||
58 | .urb_dequeue = ohci_urb_dequeue, | ||
59 | .endpoint_disable = ohci_endpoint_disable, | ||
60 | |||
61 | /* | ||
62 | * scheduling support | ||
63 | */ | ||
64 | .get_frame_number = ohci_get_frame, | ||
65 | |||
66 | /* | ||
67 | * root hub support | ||
68 | */ | ||
69 | .hub_status_data = ohci_hub_status_data, | ||
70 | .hub_control = ohci_hub_control, | ||
71 | #ifdef CONFIG_PM | ||
72 | .bus_suspend = ohci_bus_suspend, | ||
73 | .bus_resume = ohci_bus_resume, | ||
74 | #endif | ||
75 | .start_port_reset = ohci_start_port_reset, | ||
76 | }; | ||
77 | |||
78 | /*-------------------------------------------------------------------------*/ | ||
79 | |||
80 | static int ohci_hcd_sh_probe(struct platform_device *pdev) | ||
81 | { | ||
82 | struct resource *res = NULL; | ||
83 | struct usb_hcd *hcd = NULL; | ||
84 | int irq = -1; | ||
85 | int ret; | ||
86 | |||
87 | if (usb_disabled()) | ||
88 | return -ENODEV; | ||
89 | |||
90 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
91 | if (!res) { | ||
92 | err("platform_get_resource error."); | ||
93 | return -ENODEV; | ||
94 | } | ||
95 | |||
96 | irq = platform_get_irq(pdev, 0); | ||
97 | if (irq < 0) { | ||
98 | err("platform_get_irq error."); | ||
99 | return -ENODEV; | ||
100 | } | ||
101 | |||
102 | /* initialize hcd */ | ||
103 | hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name); | ||
104 | if (!hcd) { | ||
105 | err("Failed to create hcd"); | ||
106 | return -ENOMEM; | ||
107 | } | ||
108 | |||
109 | hcd->regs = (void __iomem *)res->start; | ||
110 | hcd->rsrc_start = res->start; | ||
111 | hcd->rsrc_len = resource_size(res); | ||
112 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | ||
113 | if (ret != 0) { | ||
114 | err("Failed to add hcd"); | ||
115 | usb_put_hcd(hcd); | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | static int ohci_hcd_sh_remove(struct platform_device *pdev) | ||
123 | { | ||
124 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
125 | |||
126 | usb_remove_hcd(hcd); | ||
127 | usb_put_hcd(hcd); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static struct platform_driver ohci_hcd_sh_driver = { | ||
133 | .probe = ohci_hcd_sh_probe, | ||
134 | .remove = ohci_hcd_sh_remove, | ||
135 | .shutdown = usb_hcd_platform_shutdown, | ||
136 | .driver = { | ||
137 | .name = "sh_ohci", | ||
138 | .owner = THIS_MODULE, | ||
139 | }, | ||
140 | }; | ||
141 | |||
142 | MODULE_ALIAS("platform:sh_ohci"); | ||
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c new file mode 100644 index 00000000000..c4aea3b8315 --- /dev/null +++ b/drivers/usb/host/ohci-ssb.c | |||
@@ -0,0 +1,260 @@ | |||
1 | /* | ||
2 | * Sonics Silicon Backplane | ||
3 | * Broadcom USB-core OHCI driver | ||
4 | * | ||
5 | * Copyright 2007 Michael Buesch <m@bues.ch> | ||
6 | * | ||
7 | * Derived from the OHCI-PCI driver | ||
8 | * Copyright 1999 Roman Weissgaerber | ||
9 | * Copyright 2000-2002 David Brownell | ||
10 | * Copyright 1999 Linus Torvalds | ||
11 | * Copyright 1999 Gregory P. Smith | ||
12 | * | ||
13 | * Derived from the USBcore related parts of Broadcom-SB | ||
14 | * Copyright 2005 Broadcom Corporation | ||
15 | * | ||
16 | * Licensed under the GNU/GPL. See COPYING for details. | ||
17 | */ | ||
18 | #include <linux/ssb/ssb.h> | ||
19 | |||
20 | |||
21 | #define SSB_OHCI_TMSLOW_HOSTMODE (1 << 29) | ||
22 | |||
23 | struct ssb_ohci_device { | ||
24 | struct ohci_hcd ohci; /* _must_ be at the beginning. */ | ||
25 | |||
26 | u32 enable_flags; | ||
27 | }; | ||
28 | |||
29 | static inline | ||
30 | struct ssb_ohci_device *hcd_to_ssb_ohci(struct usb_hcd *hcd) | ||
31 | { | ||
32 | return (struct ssb_ohci_device *)(hcd->hcd_priv); | ||
33 | } | ||
34 | |||
35 | |||
36 | static int ssb_ohci_reset(struct usb_hcd *hcd) | ||
37 | { | ||
38 | struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); | ||
39 | struct ohci_hcd *ohci = &ohcidev->ohci; | ||
40 | int err; | ||
41 | |||
42 | ohci_hcd_init(ohci); | ||
43 | err = ohci_init(ohci); | ||
44 | |||
45 | return err; | ||
46 | } | ||
47 | |||
48 | static int ssb_ohci_start(struct usb_hcd *hcd) | ||
49 | { | ||
50 | struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); | ||
51 | struct ohci_hcd *ohci = &ohcidev->ohci; | ||
52 | int err; | ||
53 | |||
54 | err = ohci_run(ohci); | ||
55 | if (err < 0) { | ||
56 | ohci_err(ohci, "can't start\n"); | ||
57 | ohci_stop(hcd); | ||
58 | } | ||
59 | |||
60 | return err; | ||
61 | } | ||
62 | |||
63 | static const struct hc_driver ssb_ohci_hc_driver = { | ||
64 | .description = "ssb-usb-ohci", | ||
65 | .product_desc = "SSB OHCI Controller", | ||
66 | .hcd_priv_size = sizeof(struct ssb_ohci_device), | ||
67 | |||
68 | .irq = ohci_irq, | ||
69 | .flags = HCD_MEMORY | HCD_USB11, | ||
70 | |||
71 | .reset = ssb_ohci_reset, | ||
72 | .start = ssb_ohci_start, | ||
73 | .stop = ohci_stop, | ||
74 | .shutdown = ohci_shutdown, | ||
75 | |||
76 | .urb_enqueue = ohci_urb_enqueue, | ||
77 | .urb_dequeue = ohci_urb_dequeue, | ||
78 | .endpoint_disable = ohci_endpoint_disable, | ||
79 | |||
80 | .get_frame_number = ohci_get_frame, | ||
81 | |||
82 | .hub_status_data = ohci_hub_status_data, | ||
83 | .hub_control = ohci_hub_control, | ||
84 | #ifdef CONFIG_PM | ||
85 | .bus_suspend = ohci_bus_suspend, | ||
86 | .bus_resume = ohci_bus_resume, | ||
87 | #endif | ||
88 | |||
89 | .start_port_reset = ohci_start_port_reset, | ||
90 | }; | ||
91 | |||
92 | static void ssb_ohci_detach(struct ssb_device *dev) | ||
93 | { | ||
94 | struct usb_hcd *hcd = ssb_get_drvdata(dev); | ||
95 | |||
96 | if (hcd->driver->shutdown) | ||
97 | hcd->driver->shutdown(hcd); | ||
98 | usb_remove_hcd(hcd); | ||
99 | iounmap(hcd->regs); | ||
100 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
101 | usb_put_hcd(hcd); | ||
102 | ssb_device_disable(dev, 0); | ||
103 | } | ||
104 | |||
105 | static int ssb_ohci_attach(struct ssb_device *dev) | ||
106 | { | ||
107 | struct ssb_ohci_device *ohcidev; | ||
108 | struct usb_hcd *hcd; | ||
109 | int err = -ENOMEM; | ||
110 | u32 tmp, flags = 0; | ||
111 | |||
112 | if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) || | ||
113 | dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32))) | ||
114 | return -EOPNOTSUPP; | ||
115 | |||
116 | if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) { | ||
117 | /* Put the device into host-mode. */ | ||
118 | flags |= SSB_OHCI_TMSLOW_HOSTMODE; | ||
119 | ssb_device_enable(dev, flags); | ||
120 | } else if (dev->id.coreid == SSB_DEV_USB20_HOST) { | ||
121 | /* | ||
122 | * USB 2.0 special considerations: | ||
123 | * | ||
124 | * In addition to the standard SSB reset sequence, the Host | ||
125 | * Control Register must be programmed to bring the USB core | ||
126 | * and various phy components out of reset. | ||
127 | */ | ||
128 | ssb_device_enable(dev, 0); | ||
129 | ssb_write32(dev, 0x200, 0x7ff); | ||
130 | |||
131 | /* Change Flush control reg */ | ||
132 | tmp = ssb_read32(dev, 0x400); | ||
133 | tmp &= ~8; | ||
134 | ssb_write32(dev, 0x400, tmp); | ||
135 | tmp = ssb_read32(dev, 0x400); | ||
136 | |||
137 | /* Change Shim control reg */ | ||
138 | tmp = ssb_read32(dev, 0x304); | ||
139 | tmp &= ~0x100; | ||
140 | ssb_write32(dev, 0x304, tmp); | ||
141 | tmp = ssb_read32(dev, 0x304); | ||
142 | |||
143 | udelay(1); | ||
144 | |||
145 | /* Work around for 5354 failures */ | ||
146 | if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) { | ||
147 | /* Change syn01 reg */ | ||
148 | tmp = 0x00fe00fe; | ||
149 | ssb_write32(dev, 0x894, tmp); | ||
150 | |||
151 | /* Change syn03 reg */ | ||
152 | tmp = ssb_read32(dev, 0x89c); | ||
153 | tmp |= 0x1; | ||
154 | ssb_write32(dev, 0x89c, tmp); | ||
155 | } | ||
156 | } else | ||
157 | ssb_device_enable(dev, 0); | ||
158 | |||
159 | hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev, | ||
160 | dev_name(dev->dev)); | ||
161 | if (!hcd) | ||
162 | goto err_dev_disable; | ||
163 | ohcidev = hcd_to_ssb_ohci(hcd); | ||
164 | ohcidev->enable_flags = flags; | ||
165 | |||
166 | tmp = ssb_read32(dev, SSB_ADMATCH0); | ||
167 | hcd->rsrc_start = ssb_admatch_base(tmp); | ||
168 | hcd->rsrc_len = ssb_admatch_size(tmp); | ||
169 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | ||
170 | if (!hcd->regs) | ||
171 | goto err_put_hcd; | ||
172 | err = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED); | ||
173 | if (err) | ||
174 | goto err_iounmap; | ||
175 | |||
176 | ssb_set_drvdata(dev, hcd); | ||
177 | |||
178 | return err; | ||
179 | |||
180 | err_iounmap: | ||
181 | iounmap(hcd->regs); | ||
182 | err_put_hcd: | ||
183 | usb_put_hcd(hcd); | ||
184 | err_dev_disable: | ||
185 | ssb_device_disable(dev, flags); | ||
186 | return err; | ||
187 | } | ||
188 | |||
189 | static int ssb_ohci_probe(struct ssb_device *dev, | ||
190 | const struct ssb_device_id *id) | ||
191 | { | ||
192 | int err; | ||
193 | u16 chipid_top; | ||
194 | |||
195 | /* USBcores are only connected on embedded devices. */ | ||
196 | chipid_top = (dev->bus->chip_id & 0xFF00); | ||
197 | if (chipid_top != 0x4700 && chipid_top != 0x5300) | ||
198 | return -ENODEV; | ||
199 | |||
200 | /* TODO: Probably need checks here; is the core connected? */ | ||
201 | |||
202 | if (usb_disabled()) | ||
203 | return -ENODEV; | ||
204 | |||
205 | /* We currently always attach SSB_DEV_USB11_HOSTDEV | ||
206 | * as HOST OHCI. If we want to attach it as Client device, | ||
207 | * we must branch here and call into the (yet to | ||
208 | * be written) Client mode driver. Same for remove(). */ | ||
209 | |||
210 | err = ssb_ohci_attach(dev); | ||
211 | |||
212 | return err; | ||
213 | } | ||
214 | |||
215 | static void ssb_ohci_remove(struct ssb_device *dev) | ||
216 | { | ||
217 | ssb_ohci_detach(dev); | ||
218 | } | ||
219 | |||
220 | #ifdef CONFIG_PM | ||
221 | |||
222 | static int ssb_ohci_suspend(struct ssb_device *dev, pm_message_t state) | ||
223 | { | ||
224 | ssb_device_disable(dev, 0); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static int ssb_ohci_resume(struct ssb_device *dev) | ||
230 | { | ||
231 | struct usb_hcd *hcd = ssb_get_drvdata(dev); | ||
232 | struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); | ||
233 | |||
234 | ssb_device_enable(dev, ohcidev->enable_flags); | ||
235 | |||
236 | ohci_finish_controller_resume(hcd); | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | #else /* !CONFIG_PM */ | ||
241 | #define ssb_ohci_suspend NULL | ||
242 | #define ssb_ohci_resume NULL | ||
243 | #endif /* CONFIG_PM */ | ||
244 | |||
245 | static const struct ssb_device_id ssb_ohci_table[] = { | ||
246 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV), | ||
247 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV), | ||
248 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV), | ||
249 | SSB_DEVTABLE_END | ||
250 | }; | ||
251 | MODULE_DEVICE_TABLE(ssb, ssb_ohci_table); | ||
252 | |||
253 | static struct ssb_driver ssb_ohci_driver = { | ||
254 | .name = KBUILD_MODNAME, | ||
255 | .id_table = ssb_ohci_table, | ||
256 | .probe = ssb_ohci_probe, | ||
257 | .remove = ssb_ohci_remove, | ||
258 | .suspend = ssb_ohci_suspend, | ||
259 | .resume = ssb_ohci_resume, | ||
260 | }; | ||
diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c new file mode 100644 index 00000000000..f08f784086f --- /dev/null +++ b/drivers/usb/otg/langwell_otg.c | |||
@@ -0,0 +1,2347 @@ | |||
1 | /* | ||
2 | * Intel Langwell USB OTG transceiver driver | ||
3 | * Copyright (C) 2008 - 2010, 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 | /* This driver helps to switch Langwell OTG controller function between host | ||
20 | * and peripheral. It works with EHCI driver and Langwell client controller | ||
21 | * driver together. | ||
22 | */ | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/pci.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/moduleparam.h> | ||
31 | #include <linux/usb/ch9.h> | ||
32 | #include <linux/usb/gadget.h> | ||
33 | #include <linux/usb.h> | ||
34 | #include <linux/usb/otg.h> | ||
35 | #include <linux/usb/hcd.h> | ||
36 | #include <linux/notifier.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include <asm/intel_scu_ipc.h> | ||
39 | |||
40 | #include <linux/usb/langwell_otg.h> | ||
41 | |||
42 | #define DRIVER_DESC "Intel Langwell USB OTG transceiver driver" | ||
43 | #define DRIVER_VERSION "July 10, 2010" | ||
44 | |||
45 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
46 | MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>"); | ||
47 | MODULE_VERSION(DRIVER_VERSION); | ||
48 | MODULE_LICENSE("GPL"); | ||
49 | |||
50 | static const char driver_name[] = "langwell_otg"; | ||
51 | |||
52 | static int langwell_otg_probe(struct pci_dev *pdev, | ||
53 | const struct pci_device_id *id); | ||
54 | static void langwell_otg_remove(struct pci_dev *pdev); | ||
55 | static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message); | ||
56 | static int langwell_otg_resume(struct pci_dev *pdev); | ||
57 | |||
58 | static int langwell_otg_set_host(struct otg_transceiver *otg, | ||
59 | struct usb_bus *host); | ||
60 | static int langwell_otg_set_peripheral(struct otg_transceiver *otg, | ||
61 | struct usb_gadget *gadget); | ||
62 | static int langwell_otg_start_srp(struct otg_transceiver *otg); | ||
63 | |||
64 | static const struct pci_device_id pci_ids[] = {{ | ||
65 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
66 | .class_mask = ~0, | ||
67 | .vendor = 0x8086, | ||
68 | .device = 0x0811, | ||
69 | .subvendor = PCI_ANY_ID, | ||
70 | .subdevice = PCI_ANY_ID, | ||
71 | }, { /* end: all zeroes */ } | ||
72 | }; | ||
73 | |||
74 | static struct pci_driver otg_pci_driver = { | ||
75 | .name = (char *) driver_name, | ||
76 | .id_table = pci_ids, | ||
77 | |||
78 | .probe = langwell_otg_probe, | ||
79 | .remove = langwell_otg_remove, | ||
80 | |||
81 | .suspend = langwell_otg_suspend, | ||
82 | .resume = langwell_otg_resume, | ||
83 | }; | ||
84 | |||
85 | /* HSM timers */ | ||
86 | static inline struct langwell_otg_timer *otg_timer_initializer | ||
87 | (void (*function)(unsigned long), unsigned long expires, unsigned long data) | ||
88 | { | ||
89 | struct langwell_otg_timer *timer; | ||
90 | timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL); | ||
91 | if (timer == NULL) | ||
92 | return timer; | ||
93 | |||
94 | timer->function = function; | ||
95 | timer->expires = expires; | ||
96 | timer->data = data; | ||
97 | return timer; | ||
98 | } | ||
99 | |||
100 | static struct langwell_otg_timer *a_wait_vrise_tmr, *a_aidl_bdis_tmr, | ||
101 | *b_se0_srp_tmr, *b_srp_init_tmr; | ||
102 | |||
103 | static struct list_head active_timers; | ||
104 | |||
105 | static struct langwell_otg *the_transceiver; | ||
106 | |||
107 | /* host/client notify transceiver when event affects HNP state */ | ||
108 | void langwell_update_transceiver(void) | ||
109 | { | ||
110 | struct langwell_otg *lnw = the_transceiver; | ||
111 | |||
112 | dev_dbg(lnw->dev, "transceiver is updated\n"); | ||
113 | |||
114 | if (!lnw->qwork) | ||
115 | return ; | ||
116 | |||
117 | queue_work(lnw->qwork, &lnw->work); | ||
118 | } | ||
119 | EXPORT_SYMBOL(langwell_update_transceiver); | ||
120 | |||
121 | static int langwell_otg_set_host(struct otg_transceiver *otg, | ||
122 | struct usb_bus *host) | ||
123 | { | ||
124 | otg->host = host; | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int langwell_otg_set_peripheral(struct otg_transceiver *otg, | ||
130 | struct usb_gadget *gadget) | ||
131 | { | ||
132 | otg->gadget = gadget; | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int langwell_otg_set_power(struct otg_transceiver *otg, | ||
138 | unsigned mA) | ||
139 | { | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | /* A-device drives vbus, controlled through IPC commands */ | ||
144 | static int langwell_otg_set_vbus(struct otg_transceiver *otg, bool enabled) | ||
145 | { | ||
146 | struct langwell_otg *lnw = the_transceiver; | ||
147 | u8 sub_id; | ||
148 | |||
149 | dev_dbg(lnw->dev, "%s <--- %s\n", __func__, enabled ? "on" : "off"); | ||
150 | |||
151 | if (enabled) | ||
152 | sub_id = 0x8; /* Turn on the VBus */ | ||
153 | else | ||
154 | sub_id = 0x9; /* Turn off the VBus */ | ||
155 | |||
156 | if (intel_scu_ipc_simple_command(0xef, sub_id)) { | ||
157 | dev_dbg(lnw->dev, "Failed to set Vbus via IPC commands\n"); | ||
158 | return -EBUSY; | ||
159 | } | ||
160 | |||
161 | dev_dbg(lnw->dev, "%s --->\n", __func__); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | /* charge vbus or discharge vbus through a resistor to ground */ | ||
167 | static void langwell_otg_chrg_vbus(int on) | ||
168 | { | ||
169 | struct langwell_otg *lnw = the_transceiver; | ||
170 | u32 val; | ||
171 | |||
172 | val = readl(lnw->iotg.base + CI_OTGSC); | ||
173 | |||
174 | if (on) | ||
175 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC, | ||
176 | lnw->iotg.base + CI_OTGSC); | ||
177 | else | ||
178 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD, | ||
179 | lnw->iotg.base + CI_OTGSC); | ||
180 | } | ||
181 | |||
182 | /* Start SRP */ | ||
183 | static int langwell_otg_start_srp(struct otg_transceiver *otg) | ||
184 | { | ||
185 | struct langwell_otg *lnw = the_transceiver; | ||
186 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
187 | u32 val; | ||
188 | |||
189 | dev_dbg(lnw->dev, "%s --->\n", __func__); | ||
190 | |||
191 | val = readl(iotg->base + CI_OTGSC); | ||
192 | |||
193 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP, | ||
194 | iotg->base + CI_OTGSC); | ||
195 | |||
196 | /* Check if the data plus is finished or not */ | ||
197 | msleep(8); | ||
198 | val = readl(iotg->base + CI_OTGSC); | ||
199 | if (val & (OTGSC_HADP | OTGSC_DP)) | ||
200 | dev_dbg(lnw->dev, "DataLine SRP Error\n"); | ||
201 | |||
202 | /* Disable interrupt - b_sess_vld */ | ||
203 | val = readl(iotg->base + CI_OTGSC); | ||
204 | val &= (~(OTGSC_BSVIE | OTGSC_BSEIE)); | ||
205 | writel(val, iotg->base + CI_OTGSC); | ||
206 | |||
207 | /* Start VBus SRP, drive vbus to generate VBus pulse */ | ||
208 | iotg->otg.set_vbus(&iotg->otg, true); | ||
209 | msleep(15); | ||
210 | iotg->otg.set_vbus(&iotg->otg, false); | ||
211 | |||
212 | /* Enable interrupt - b_sess_vld*/ | ||
213 | val = readl(iotg->base + CI_OTGSC); | ||
214 | dev_dbg(lnw->dev, "after VBUS pulse otgsc = %x\n", val); | ||
215 | |||
216 | val |= (OTGSC_BSVIE | OTGSC_BSEIE); | ||
217 | writel(val, iotg->base + CI_OTGSC); | ||
218 | |||
219 | /* If Vbus is valid, then update the hsm */ | ||
220 | if (val & OTGSC_BSV) { | ||
221 | dev_dbg(lnw->dev, "no b_sess_vld interrupt\n"); | ||
222 | |||
223 | lnw->iotg.hsm.b_sess_vld = 1; | ||
224 | langwell_update_transceiver(); | ||
225 | } | ||
226 | |||
227 | dev_dbg(lnw->dev, "%s <---\n", __func__); | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | /* stop SOF via bus_suspend */ | ||
232 | static void langwell_otg_loc_sof(int on) | ||
233 | { | ||
234 | struct langwell_otg *lnw = the_transceiver; | ||
235 | struct usb_hcd *hcd; | ||
236 | int err; | ||
237 | |||
238 | dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "suspend" : "resume"); | ||
239 | |||
240 | hcd = bus_to_hcd(lnw->iotg.otg.host); | ||
241 | if (on) | ||
242 | err = hcd->driver->bus_resume(hcd); | ||
243 | else | ||
244 | err = hcd->driver->bus_suspend(hcd); | ||
245 | |||
246 | if (err) | ||
247 | dev_dbg(lnw->dev, "Fail to resume/suspend USB bus - %d\n", err); | ||
248 | |||
249 | dev_dbg(lnw->dev, "%s <---\n", __func__); | ||
250 | } | ||
251 | |||
252 | static int langwell_otg_check_otgsc(void) | ||
253 | { | ||
254 | struct langwell_otg *lnw = the_transceiver; | ||
255 | u32 otgsc, usbcfg; | ||
256 | |||
257 | dev_dbg(lnw->dev, "check sync OTGSC and USBCFG registers\n"); | ||
258 | |||
259 | otgsc = readl(lnw->iotg.base + CI_OTGSC); | ||
260 | usbcfg = readl(lnw->usbcfg); | ||
261 | |||
262 | dev_dbg(lnw->dev, "OTGSC = %08x, USBCFG = %08x\n", | ||
263 | otgsc, usbcfg); | ||
264 | dev_dbg(lnw->dev, "OTGSC_AVV = %d\n", !!(otgsc & OTGSC_AVV)); | ||
265 | dev_dbg(lnw->dev, "USBCFG.VBUSVAL = %d\n", | ||
266 | !!(usbcfg & USBCFG_VBUSVAL)); | ||
267 | dev_dbg(lnw->dev, "OTGSC_ASV = %d\n", !!(otgsc & OTGSC_ASV)); | ||
268 | dev_dbg(lnw->dev, "USBCFG.AVALID = %d\n", | ||
269 | !!(usbcfg & USBCFG_AVALID)); | ||
270 | dev_dbg(lnw->dev, "OTGSC_BSV = %d\n", !!(otgsc & OTGSC_BSV)); | ||
271 | dev_dbg(lnw->dev, "USBCFG.BVALID = %d\n", | ||
272 | !!(usbcfg & USBCFG_BVALID)); | ||
273 | dev_dbg(lnw->dev, "OTGSC_BSE = %d\n", !!(otgsc & OTGSC_BSE)); | ||
274 | dev_dbg(lnw->dev, "USBCFG.SESEND = %d\n", | ||
275 | !!(usbcfg & USBCFG_SESEND)); | ||
276 | |||
277 | /* Check USBCFG VBusValid/AValid/BValid/SessEnd */ | ||
278 | if (!!(otgsc & OTGSC_AVV) ^ !!(usbcfg & USBCFG_VBUSVAL)) { | ||
279 | dev_dbg(lnw->dev, "OTGSC.AVV != USBCFG.VBUSVAL\n"); | ||
280 | goto err; | ||
281 | } | ||
282 | if (!!(otgsc & OTGSC_ASV) ^ !!(usbcfg & USBCFG_AVALID)) { | ||
283 | dev_dbg(lnw->dev, "OTGSC.ASV != USBCFG.AVALID\n"); | ||
284 | goto err; | ||
285 | } | ||
286 | if (!!(otgsc & OTGSC_BSV) ^ !!(usbcfg & USBCFG_BVALID)) { | ||
287 | dev_dbg(lnw->dev, "OTGSC.BSV != USBCFG.BVALID\n"); | ||
288 | goto err; | ||
289 | } | ||
290 | if (!!(otgsc & OTGSC_BSE) ^ !!(usbcfg & USBCFG_SESEND)) { | ||
291 | dev_dbg(lnw->dev, "OTGSC.BSE != USBCFG.SESSEN\n"); | ||
292 | goto err; | ||
293 | } | ||
294 | |||
295 | dev_dbg(lnw->dev, "OTGSC and USBCFG are synced\n"); | ||
296 | |||
297 | return 0; | ||
298 | |||
299 | err: | ||
300 | dev_warn(lnw->dev, "OTGSC isn't equal to USBCFG\n"); | ||
301 | return -EPIPE; | ||
302 | } | ||
303 | |||
304 | |||
305 | static void langwell_otg_phy_low_power(int on) | ||
306 | { | ||
307 | struct langwell_otg *lnw = the_transceiver; | ||
308 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
309 | u8 val, phcd; | ||
310 | int retval; | ||
311 | |||
312 | dev_dbg(lnw->dev, "%s ---> %s mode\n", | ||
313 | __func__, on ? "Low power" : "Normal"); | ||
314 | |||
315 | phcd = 0x40; | ||
316 | |||
317 | val = readb(iotg->base + CI_HOSTPC1 + 2); | ||
318 | |||
319 | if (on) { | ||
320 | /* Due to hardware issue, after set PHCD, sync will failed | ||
321 | * between USBCFG and OTGSC, so before set PHCD, check if | ||
322 | * sync is in process now. If the answer is "yes", then do | ||
323 | * not touch PHCD bit */ | ||
324 | retval = langwell_otg_check_otgsc(); | ||
325 | if (retval) { | ||
326 | dev_dbg(lnw->dev, "Skip PHCD programming..\n"); | ||
327 | return ; | ||
328 | } | ||
329 | |||
330 | writeb(val | phcd, iotg->base + CI_HOSTPC1 + 2); | ||
331 | } else | ||
332 | writeb(val & ~phcd, iotg->base + CI_HOSTPC1 + 2); | ||
333 | |||
334 | dev_dbg(lnw->dev, "%s <--- done\n", __func__); | ||
335 | } | ||
336 | |||
337 | /* After drv vbus, add 5 ms delay to set PHCD */ | ||
338 | static void langwell_otg_phy_low_power_wait(int on) | ||
339 | { | ||
340 | struct langwell_otg *lnw = the_transceiver; | ||
341 | |||
342 | dev_dbg(lnw->dev, "add 5ms delay before programing PHCD\n"); | ||
343 | |||
344 | mdelay(5); | ||
345 | langwell_otg_phy_low_power(on); | ||
346 | } | ||
347 | |||
348 | /* Enable/Disable OTG interrupt */ | ||
349 | static void langwell_otg_intr(int on) | ||
350 | { | ||
351 | struct langwell_otg *lnw = the_transceiver; | ||
352 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
353 | u32 val; | ||
354 | |||
355 | dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off"); | ||
356 | |||
357 | val = readl(iotg->base + CI_OTGSC); | ||
358 | |||
359 | /* OTGSC_INT_MASK doesn't contains 1msInt */ | ||
360 | if (on) { | ||
361 | val = val | (OTGSC_INT_MASK); | ||
362 | writel(val, iotg->base + CI_OTGSC); | ||
363 | } else { | ||
364 | val = val & ~(OTGSC_INT_MASK); | ||
365 | writel(val, iotg->base + CI_OTGSC); | ||
366 | } | ||
367 | |||
368 | dev_dbg(lnw->dev, "%s <---\n", __func__); | ||
369 | } | ||
370 | |||
371 | /* set HAAR: Hardware Assist Auto-Reset */ | ||
372 | static void langwell_otg_HAAR(int on) | ||
373 | { | ||
374 | struct langwell_otg *lnw = the_transceiver; | ||
375 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
376 | u32 val; | ||
377 | |||
378 | dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off"); | ||
379 | |||
380 | val = readl(iotg->base + CI_OTGSC); | ||
381 | if (on) | ||
382 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR, | ||
383 | iotg->base + CI_OTGSC); | ||
384 | else | ||
385 | writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR, | ||
386 | iotg->base + CI_OTGSC); | ||
387 | |||
388 | dev_dbg(lnw->dev, "%s <---\n", __func__); | ||
389 | } | ||
390 | |||
391 | /* set HABA: Hardware Assist B-Disconnect to A-Connect */ | ||
392 | static void langwell_otg_HABA(int on) | ||
393 | { | ||
394 | struct langwell_otg *lnw = the_transceiver; | ||
395 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
396 | u32 val; | ||
397 | |||
398 | dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off"); | ||
399 | |||
400 | val = readl(iotg->base + CI_OTGSC); | ||
401 | if (on) | ||
402 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA, | ||
403 | iotg->base + CI_OTGSC); | ||
404 | else | ||
405 | writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA, | ||
406 | iotg->base + CI_OTGSC); | ||
407 | |||
408 | dev_dbg(lnw->dev, "%s <---\n", __func__); | ||
409 | } | ||
410 | |||
411 | static int langwell_otg_check_se0_srp(int on) | ||
412 | { | ||
413 | struct langwell_otg *lnw = the_transceiver; | ||
414 | int delay_time = TB_SE0_SRP * 10; | ||
415 | u32 val; | ||
416 | |||
417 | dev_dbg(lnw->dev, "%s --->\n", __func__); | ||
418 | |||
419 | do { | ||
420 | udelay(100); | ||
421 | if (!delay_time--) | ||
422 | break; | ||
423 | val = readl(lnw->iotg.base + CI_PORTSC1); | ||
424 | val &= PORTSC_LS; | ||
425 | } while (!val); | ||
426 | |||
427 | dev_dbg(lnw->dev, "%s <---\n", __func__); | ||
428 | return val; | ||
429 | } | ||
430 | |||
431 | /* The timeout callback function to set time out bit */ | ||
432 | static void set_tmout(unsigned long indicator) | ||
433 | { | ||
434 | *(int *)indicator = 1; | ||
435 | } | ||
436 | |||
437 | void langwell_otg_nsf_msg(unsigned long indicator) | ||
438 | { | ||
439 | struct langwell_otg *lnw = the_transceiver; | ||
440 | |||
441 | switch (indicator) { | ||
442 | case 2: | ||
443 | case 4: | ||
444 | case 6: | ||
445 | case 7: | ||
446 | dev_warn(lnw->dev, | ||
447 | "OTG:NSF-%lu - deivce not responding\n", indicator); | ||
448 | break; | ||
449 | case 3: | ||
450 | dev_warn(lnw->dev, | ||
451 | "OTG:NSF-%lu - deivce not supported\n", indicator); | ||
452 | break; | ||
453 | default: | ||
454 | dev_warn(lnw->dev, "Do not have this kind of NSF\n"); | ||
455 | break; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | /* Initialize timers */ | ||
460 | static int langwell_otg_init_timers(struct otg_hsm *hsm) | ||
461 | { | ||
462 | /* HSM used timers */ | ||
463 | a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, | ||
464 | (unsigned long)&hsm->a_wait_vrise_tmout); | ||
465 | if (a_wait_vrise_tmr == NULL) | ||
466 | return -ENOMEM; | ||
467 | a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, | ||
468 | (unsigned long)&hsm->a_aidl_bdis_tmout); | ||
469 | if (a_aidl_bdis_tmr == NULL) | ||
470 | return -ENOMEM; | ||
471 | b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, | ||
472 | (unsigned long)&hsm->b_se0_srp); | ||
473 | if (b_se0_srp_tmr == NULL) | ||
474 | return -ENOMEM; | ||
475 | b_srp_init_tmr = otg_timer_initializer(&set_tmout, TB_SRP_INIT, | ||
476 | (unsigned long)&hsm->b_srp_init_tmout); | ||
477 | if (b_srp_init_tmr == NULL) | ||
478 | return -ENOMEM; | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* Free timers */ | ||
484 | static void langwell_otg_free_timers(void) | ||
485 | { | ||
486 | kfree(a_wait_vrise_tmr); | ||
487 | kfree(a_aidl_bdis_tmr); | ||
488 | kfree(b_se0_srp_tmr); | ||
489 | kfree(b_srp_init_tmr); | ||
490 | } | ||
491 | |||
492 | /* The timeout callback function to set time out bit */ | ||
493 | static void langwell_otg_timer_fn(unsigned long indicator) | ||
494 | { | ||
495 | struct langwell_otg *lnw = the_transceiver; | ||
496 | |||
497 | *(int *)indicator = 1; | ||
498 | |||
499 | dev_dbg(lnw->dev, "kernel timer - timeout\n"); | ||
500 | |||
501 | langwell_update_transceiver(); | ||
502 | } | ||
503 | |||
504 | /* kernel timer used instead of HW based interrupt */ | ||
505 | static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers) | ||
506 | { | ||
507 | struct langwell_otg *lnw = the_transceiver; | ||
508 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
509 | unsigned long j = jiffies; | ||
510 | unsigned long data, time; | ||
511 | |||
512 | switch (timers) { | ||
513 | case TA_WAIT_VRISE_TMR: | ||
514 | iotg->hsm.a_wait_vrise_tmout = 0; | ||
515 | data = (unsigned long)&iotg->hsm.a_wait_vrise_tmout; | ||
516 | time = TA_WAIT_VRISE; | ||
517 | break; | ||
518 | case TA_WAIT_BCON_TMR: | ||
519 | iotg->hsm.a_wait_bcon_tmout = 0; | ||
520 | data = (unsigned long)&iotg->hsm.a_wait_bcon_tmout; | ||
521 | time = TA_WAIT_BCON; | ||
522 | break; | ||
523 | case TA_AIDL_BDIS_TMR: | ||
524 | iotg->hsm.a_aidl_bdis_tmout = 0; | ||
525 | data = (unsigned long)&iotg->hsm.a_aidl_bdis_tmout; | ||
526 | time = TA_AIDL_BDIS; | ||
527 | break; | ||
528 | case TB_ASE0_BRST_TMR: | ||
529 | iotg->hsm.b_ase0_brst_tmout = 0; | ||
530 | data = (unsigned long)&iotg->hsm.b_ase0_brst_tmout; | ||
531 | time = TB_ASE0_BRST; | ||
532 | break; | ||
533 | case TB_SRP_INIT_TMR: | ||
534 | iotg->hsm.b_srp_init_tmout = 0; | ||
535 | data = (unsigned long)&iotg->hsm.b_srp_init_tmout; | ||
536 | time = TB_SRP_INIT; | ||
537 | break; | ||
538 | case TB_SRP_FAIL_TMR: | ||
539 | iotg->hsm.b_srp_fail_tmout = 0; | ||
540 | data = (unsigned long)&iotg->hsm.b_srp_fail_tmout; | ||
541 | time = TB_SRP_FAIL; | ||
542 | break; | ||
543 | case TB_BUS_SUSPEND_TMR: | ||
544 | iotg->hsm.b_bus_suspend_tmout = 0; | ||
545 | data = (unsigned long)&iotg->hsm.b_bus_suspend_tmout; | ||
546 | time = TB_BUS_SUSPEND; | ||
547 | break; | ||
548 | default: | ||
549 | dev_dbg(lnw->dev, "unknown timer, cannot enable it\n"); | ||
550 | return; | ||
551 | } | ||
552 | |||
553 | lnw->hsm_timer.data = data; | ||
554 | lnw->hsm_timer.function = langwell_otg_timer_fn; | ||
555 | lnw->hsm_timer.expires = j + time * HZ / 1000; /* milliseconds */ | ||
556 | |||
557 | add_timer(&lnw->hsm_timer); | ||
558 | |||
559 | dev_dbg(lnw->dev, "add timer successfully\n"); | ||
560 | } | ||
561 | |||
562 | /* Add timer to timer list */ | ||
563 | static void langwell_otg_add_timer(void *gtimer) | ||
564 | { | ||
565 | struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; | ||
566 | struct langwell_otg_timer *tmp_timer; | ||
567 | struct intel_mid_otg_xceiv *iotg = &the_transceiver->iotg; | ||
568 | u32 val32; | ||
569 | |||
570 | /* Check if the timer is already in the active list, | ||
571 | * if so update timer count | ||
572 | */ | ||
573 | list_for_each_entry(tmp_timer, &active_timers, list) | ||
574 | if (tmp_timer == timer) { | ||
575 | timer->count = timer->expires; | ||
576 | return; | ||
577 | } | ||
578 | timer->count = timer->expires; | ||
579 | |||
580 | if (list_empty(&active_timers)) { | ||
581 | val32 = readl(iotg->base + CI_OTGSC); | ||
582 | writel(val32 | OTGSC_1MSE, iotg->base + CI_OTGSC); | ||
583 | } | ||
584 | |||
585 | list_add_tail(&timer->list, &active_timers); | ||
586 | } | ||
587 | |||
588 | /* Remove timer from the timer list; clear timeout status */ | ||
589 | static void langwell_otg_del_timer(void *gtimer) | ||
590 | { | ||
591 | struct langwell_otg *lnw = the_transceiver; | ||
592 | struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; | ||
593 | struct langwell_otg_timer *tmp_timer, *del_tmp; | ||
594 | u32 val32; | ||
595 | |||
596 | list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) | ||
597 | if (tmp_timer == timer) | ||
598 | list_del(&timer->list); | ||
599 | |||
600 | if (list_empty(&active_timers)) { | ||
601 | val32 = readl(lnw->iotg.base + CI_OTGSC); | ||
602 | writel(val32 & ~OTGSC_1MSE, lnw->iotg.base + CI_OTGSC); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /* Reduce timer count by 1, and find timeout conditions.*/ | ||
607 | static int langwell_otg_tick_timer(u32 *int_sts) | ||
608 | { | ||
609 | struct langwell_otg *lnw = the_transceiver; | ||
610 | struct langwell_otg_timer *tmp_timer, *del_tmp; | ||
611 | int expired = 0; | ||
612 | |||
613 | list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { | ||
614 | tmp_timer->count--; | ||
615 | /* check if timer expires */ | ||
616 | if (!tmp_timer->count) { | ||
617 | list_del(&tmp_timer->list); | ||
618 | tmp_timer->function(tmp_timer->data); | ||
619 | expired = 1; | ||
620 | } | ||
621 | } | ||
622 | |||
623 | if (list_empty(&active_timers)) { | ||
624 | dev_dbg(lnw->dev, "tick timer: disable 1ms int\n"); | ||
625 | *int_sts = *int_sts & ~OTGSC_1MSE; | ||
626 | } | ||
627 | return expired; | ||
628 | } | ||
629 | |||
630 | static void reset_otg(void) | ||
631 | { | ||
632 | struct langwell_otg *lnw = the_transceiver; | ||
633 | int delay_time = 1000; | ||
634 | u32 val; | ||
635 | |||
636 | dev_dbg(lnw->dev, "reseting OTG controller ...\n"); | ||
637 | val = readl(lnw->iotg.base + CI_USBCMD); | ||
638 | writel(val | USBCMD_RST, lnw->iotg.base + CI_USBCMD); | ||
639 | do { | ||
640 | udelay(100); | ||
641 | if (!delay_time--) | ||
642 | dev_dbg(lnw->dev, "reset timeout\n"); | ||
643 | val = readl(lnw->iotg.base + CI_USBCMD); | ||
644 | val &= USBCMD_RST; | ||
645 | } while (val != 0); | ||
646 | dev_dbg(lnw->dev, "reset done.\n"); | ||
647 | } | ||
648 | |||
649 | static void set_host_mode(void) | ||
650 | { | ||
651 | struct langwell_otg *lnw = the_transceiver; | ||
652 | u32 val; | ||
653 | |||
654 | reset_otg(); | ||
655 | val = readl(lnw->iotg.base + CI_USBMODE); | ||
656 | val = (val & (~USBMODE_CM)) | USBMODE_HOST; | ||
657 | writel(val, lnw->iotg.base + CI_USBMODE); | ||
658 | } | ||
659 | |||
660 | static void set_client_mode(void) | ||
661 | { | ||
662 | struct langwell_otg *lnw = the_transceiver; | ||
663 | u32 val; | ||
664 | |||
665 | reset_otg(); | ||
666 | val = readl(lnw->iotg.base + CI_USBMODE); | ||
667 | val = (val & (~USBMODE_CM)) | USBMODE_DEVICE; | ||
668 | writel(val, lnw->iotg.base + CI_USBMODE); | ||
669 | } | ||
670 | |||
671 | static void init_hsm(void) | ||
672 | { | ||
673 | struct langwell_otg *lnw = the_transceiver; | ||
674 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
675 | u32 val32; | ||
676 | |||
677 | /* read OTGSC after reset */ | ||
678 | val32 = readl(lnw->iotg.base + CI_OTGSC); | ||
679 | dev_dbg(lnw->dev, "%s: OTGSC init value = 0x%x\n", __func__, val32); | ||
680 | |||
681 | /* set init state */ | ||
682 | if (val32 & OTGSC_ID) { | ||
683 | iotg->hsm.id = 1; | ||
684 | iotg->otg.default_a = 0; | ||
685 | set_client_mode(); | ||
686 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
687 | } else { | ||
688 | iotg->hsm.id = 0; | ||
689 | iotg->otg.default_a = 1; | ||
690 | set_host_mode(); | ||
691 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
692 | } | ||
693 | |||
694 | /* set session indicator */ | ||
695 | if (val32 & OTGSC_BSE) | ||
696 | iotg->hsm.b_sess_end = 1; | ||
697 | if (val32 & OTGSC_BSV) | ||
698 | iotg->hsm.b_sess_vld = 1; | ||
699 | if (val32 & OTGSC_ASV) | ||
700 | iotg->hsm.a_sess_vld = 1; | ||
701 | if (val32 & OTGSC_AVV) | ||
702 | iotg->hsm.a_vbus_vld = 1; | ||
703 | |||
704 | /* defautly power the bus */ | ||
705 | iotg->hsm.a_bus_req = 1; | ||
706 | iotg->hsm.a_bus_drop = 0; | ||
707 | /* defautly don't request bus as B device */ | ||
708 | iotg->hsm.b_bus_req = 0; | ||
709 | /* no system error */ | ||
710 | iotg->hsm.a_clr_err = 0; | ||
711 | |||
712 | langwell_otg_phy_low_power_wait(1); | ||
713 | } | ||
714 | |||
715 | static void update_hsm(void) | ||
716 | { | ||
717 | struct langwell_otg *lnw = the_transceiver; | ||
718 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
719 | u32 val32; | ||
720 | |||
721 | /* read OTGSC */ | ||
722 | val32 = readl(lnw->iotg.base + CI_OTGSC); | ||
723 | dev_dbg(lnw->dev, "%s: OTGSC value = 0x%x\n", __func__, val32); | ||
724 | |||
725 | iotg->hsm.id = !!(val32 & OTGSC_ID); | ||
726 | iotg->hsm.b_sess_end = !!(val32 & OTGSC_BSE); | ||
727 | iotg->hsm.b_sess_vld = !!(val32 & OTGSC_BSV); | ||
728 | iotg->hsm.a_sess_vld = !!(val32 & OTGSC_ASV); | ||
729 | iotg->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV); | ||
730 | } | ||
731 | |||
732 | static irqreturn_t otg_dummy_irq(int irq, void *_dev) | ||
733 | { | ||
734 | struct langwell_otg *lnw = the_transceiver; | ||
735 | void __iomem *reg_base = _dev; | ||
736 | u32 val; | ||
737 | u32 int_mask = 0; | ||
738 | |||
739 | val = readl(reg_base + CI_USBMODE); | ||
740 | if ((val & USBMODE_CM) != USBMODE_DEVICE) | ||
741 | return IRQ_NONE; | ||
742 | |||
743 | val = readl(reg_base + CI_USBSTS); | ||
744 | int_mask = val & INTR_DUMMY_MASK; | ||
745 | |||
746 | if (int_mask == 0) | ||
747 | return IRQ_NONE; | ||
748 | |||
749 | /* clear hsm.b_conn here since host driver can't detect it | ||
750 | * otg_dummy_irq called means B-disconnect happened. | ||
751 | */ | ||
752 | if (lnw->iotg.hsm.b_conn) { | ||
753 | lnw->iotg.hsm.b_conn = 0; | ||
754 | if (spin_trylock(&lnw->wq_lock)) { | ||
755 | langwell_update_transceiver(); | ||
756 | spin_unlock(&lnw->wq_lock); | ||
757 | } | ||
758 | } | ||
759 | |||
760 | /* Clear interrupts */ | ||
761 | writel(int_mask, reg_base + CI_USBSTS); | ||
762 | return IRQ_HANDLED; | ||
763 | } | ||
764 | |||
765 | static irqreturn_t otg_irq(int irq, void *_dev) | ||
766 | { | ||
767 | struct langwell_otg *lnw = _dev; | ||
768 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
769 | u32 int_sts, int_en; | ||
770 | u32 int_mask = 0; | ||
771 | int flag = 0; | ||
772 | |||
773 | int_sts = readl(lnw->iotg.base + CI_OTGSC); | ||
774 | int_en = (int_sts & OTGSC_INTEN_MASK) >> 8; | ||
775 | int_mask = int_sts & int_en; | ||
776 | if (int_mask == 0) | ||
777 | return IRQ_NONE; | ||
778 | |||
779 | if (int_mask & OTGSC_IDIS) { | ||
780 | dev_dbg(lnw->dev, "%s: id change int\n", __func__); | ||
781 | iotg->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0; | ||
782 | dev_dbg(lnw->dev, "id = %d\n", iotg->hsm.id); | ||
783 | flag = 1; | ||
784 | } | ||
785 | if (int_mask & OTGSC_DPIS) { | ||
786 | dev_dbg(lnw->dev, "%s: data pulse int\n", __func__); | ||
787 | iotg->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0; | ||
788 | dev_dbg(lnw->dev, "data pulse = %d\n", iotg->hsm.a_srp_det); | ||
789 | flag = 1; | ||
790 | } | ||
791 | if (int_mask & OTGSC_BSEIS) { | ||
792 | dev_dbg(lnw->dev, "%s: b session end int\n", __func__); | ||
793 | iotg->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0; | ||
794 | dev_dbg(lnw->dev, "b_sess_end = %d\n", iotg->hsm.b_sess_end); | ||
795 | flag = 1; | ||
796 | } | ||
797 | if (int_mask & OTGSC_BSVIS) { | ||
798 | dev_dbg(lnw->dev, "%s: b session valid int\n", __func__); | ||
799 | iotg->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0; | ||
800 | dev_dbg(lnw->dev, "b_sess_vld = %d\n", iotg->hsm.b_sess_end); | ||
801 | flag = 1; | ||
802 | } | ||
803 | if (int_mask & OTGSC_ASVIS) { | ||
804 | dev_dbg(lnw->dev, "%s: a session valid int\n", __func__); | ||
805 | iotg->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0; | ||
806 | dev_dbg(lnw->dev, "a_sess_vld = %d\n", iotg->hsm.a_sess_vld); | ||
807 | flag = 1; | ||
808 | } | ||
809 | if (int_mask & OTGSC_AVVIS) { | ||
810 | dev_dbg(lnw->dev, "%s: a vbus valid int\n", __func__); | ||
811 | iotg->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0; | ||
812 | dev_dbg(lnw->dev, "a_vbus_vld = %d\n", iotg->hsm.a_vbus_vld); | ||
813 | flag = 1; | ||
814 | } | ||
815 | |||
816 | if (int_mask & OTGSC_1MSS) { | ||
817 | /* need to schedule otg_work if any timer is expired */ | ||
818 | if (langwell_otg_tick_timer(&int_sts)) | ||
819 | flag = 1; | ||
820 | } | ||
821 | |||
822 | writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask, | ||
823 | lnw->iotg.base + CI_OTGSC); | ||
824 | if (flag) | ||
825 | langwell_update_transceiver(); | ||
826 | |||
827 | return IRQ_HANDLED; | ||
828 | } | ||
829 | |||
830 | static int langwell_otg_iotg_notify(struct notifier_block *nb, | ||
831 | unsigned long action, void *data) | ||
832 | { | ||
833 | struct langwell_otg *lnw = the_transceiver; | ||
834 | struct intel_mid_otg_xceiv *iotg = data; | ||
835 | int flag = 0; | ||
836 | |||
837 | if (iotg == NULL) | ||
838 | return NOTIFY_BAD; | ||
839 | |||
840 | if (lnw == NULL) | ||
841 | return NOTIFY_BAD; | ||
842 | |||
843 | switch (action) { | ||
844 | case MID_OTG_NOTIFY_CONNECT: | ||
845 | dev_dbg(lnw->dev, "Lnw OTG Notify Connect Event\n"); | ||
846 | if (iotg->otg.default_a == 1) | ||
847 | iotg->hsm.b_conn = 1; | ||
848 | else | ||
849 | iotg->hsm.a_conn = 1; | ||
850 | flag = 1; | ||
851 | break; | ||
852 | case MID_OTG_NOTIFY_DISCONN: | ||
853 | dev_dbg(lnw->dev, "Lnw OTG Notify Disconnect Event\n"); | ||
854 | if (iotg->otg.default_a == 1) | ||
855 | iotg->hsm.b_conn = 0; | ||
856 | else | ||
857 | iotg->hsm.a_conn = 0; | ||
858 | flag = 1; | ||
859 | break; | ||
860 | case MID_OTG_NOTIFY_HSUSPEND: | ||
861 | dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus suspend Event\n"); | ||
862 | if (iotg->otg.default_a == 1) | ||
863 | iotg->hsm.a_suspend_req = 1; | ||
864 | else | ||
865 | iotg->hsm.b_bus_req = 0; | ||
866 | flag = 1; | ||
867 | break; | ||
868 | case MID_OTG_NOTIFY_HRESUME: | ||
869 | dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus resume Event\n"); | ||
870 | if (iotg->otg.default_a == 1) | ||
871 | iotg->hsm.b_bus_resume = 1; | ||
872 | flag = 1; | ||
873 | break; | ||
874 | case MID_OTG_NOTIFY_CSUSPEND: | ||
875 | dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus suspend Event\n"); | ||
876 | if (iotg->otg.default_a == 1) { | ||
877 | if (iotg->hsm.b_bus_suspend_vld == 2) { | ||
878 | iotg->hsm.b_bus_suspend = 1; | ||
879 | iotg->hsm.b_bus_suspend_vld = 0; | ||
880 | flag = 1; | ||
881 | } else { | ||
882 | iotg->hsm.b_bus_suspend_vld++; | ||
883 | flag = 0; | ||
884 | } | ||
885 | } else { | ||
886 | if (iotg->hsm.a_bus_suspend == 0) { | ||
887 | iotg->hsm.a_bus_suspend = 1; | ||
888 | flag = 1; | ||
889 | } | ||
890 | } | ||
891 | break; | ||
892 | case MID_OTG_NOTIFY_CRESUME: | ||
893 | dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus resume Event\n"); | ||
894 | if (iotg->otg.default_a == 0) | ||
895 | iotg->hsm.a_bus_suspend = 0; | ||
896 | flag = 0; | ||
897 | break; | ||
898 | case MID_OTG_NOTIFY_HOSTADD: | ||
899 | dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver Add\n"); | ||
900 | flag = 1; | ||
901 | break; | ||
902 | case MID_OTG_NOTIFY_HOSTREMOVE: | ||
903 | dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver remove\n"); | ||
904 | flag = 1; | ||
905 | break; | ||
906 | case MID_OTG_NOTIFY_CLIENTADD: | ||
907 | dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver Add\n"); | ||
908 | flag = 1; | ||
909 | break; | ||
910 | case MID_OTG_NOTIFY_CLIENTREMOVE: | ||
911 | dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver remove\n"); | ||
912 | flag = 1; | ||
913 | break; | ||
914 | default: | ||
915 | dev_dbg(lnw->dev, "Lnw OTG Nofity unknown notify message\n"); | ||
916 | return NOTIFY_DONE; | ||
917 | } | ||
918 | |||
919 | if (flag) | ||
920 | langwell_update_transceiver(); | ||
921 | |||
922 | return NOTIFY_OK; | ||
923 | } | ||
924 | |||
925 | static void langwell_otg_work(struct work_struct *work) | ||
926 | { | ||
927 | struct langwell_otg *lnw; | ||
928 | struct intel_mid_otg_xceiv *iotg; | ||
929 | int retval; | ||
930 | struct pci_dev *pdev; | ||
931 | |||
932 | lnw = container_of(work, struct langwell_otg, work); | ||
933 | iotg = &lnw->iotg; | ||
934 | pdev = to_pci_dev(lnw->dev); | ||
935 | |||
936 | dev_dbg(lnw->dev, "%s: old state = %s\n", __func__, | ||
937 | otg_state_string(iotg->otg.state)); | ||
938 | |||
939 | switch (iotg->otg.state) { | ||
940 | case OTG_STATE_UNDEFINED: | ||
941 | case OTG_STATE_B_IDLE: | ||
942 | if (!iotg->hsm.id) { | ||
943 | langwell_otg_del_timer(b_srp_init_tmr); | ||
944 | del_timer_sync(&lnw->hsm_timer); | ||
945 | |||
946 | iotg->otg.default_a = 1; | ||
947 | iotg->hsm.a_srp_det = 0; | ||
948 | |||
949 | langwell_otg_chrg_vbus(0); | ||
950 | set_host_mode(); | ||
951 | langwell_otg_phy_low_power(1); | ||
952 | |||
953 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
954 | langwell_update_transceiver(); | ||
955 | } else if (iotg->hsm.b_sess_vld) { | ||
956 | langwell_otg_del_timer(b_srp_init_tmr); | ||
957 | del_timer_sync(&lnw->hsm_timer); | ||
958 | iotg->hsm.b_sess_end = 0; | ||
959 | iotg->hsm.a_bus_suspend = 0; | ||
960 | langwell_otg_chrg_vbus(0); | ||
961 | |||
962 | if (lnw->iotg.start_peripheral) { | ||
963 | lnw->iotg.start_peripheral(&lnw->iotg); | ||
964 | iotg->otg.state = OTG_STATE_B_PERIPHERAL; | ||
965 | } else | ||
966 | dev_dbg(lnw->dev, "client driver not loaded\n"); | ||
967 | |||
968 | } else if (iotg->hsm.b_srp_init_tmout) { | ||
969 | iotg->hsm.b_srp_init_tmout = 0; | ||
970 | dev_warn(lnw->dev, "SRP init timeout\n"); | ||
971 | } else if (iotg->hsm.b_srp_fail_tmout) { | ||
972 | iotg->hsm.b_srp_fail_tmout = 0; | ||
973 | iotg->hsm.b_bus_req = 0; | ||
974 | |||
975 | /* No silence failure */ | ||
976 | langwell_otg_nsf_msg(6); | ||
977 | } else if (iotg->hsm.b_bus_req && iotg->hsm.b_sess_end) { | ||
978 | del_timer_sync(&lnw->hsm_timer); | ||
979 | /* workaround for b_se0_srp detection */ | ||
980 | retval = langwell_otg_check_se0_srp(0); | ||
981 | if (retval) { | ||
982 | iotg->hsm.b_bus_req = 0; | ||
983 | dev_dbg(lnw->dev, "LS isn't SE0, try later\n"); | ||
984 | } else { | ||
985 | /* clear the PHCD before start srp */ | ||
986 | langwell_otg_phy_low_power(0); | ||
987 | |||
988 | /* Start SRP */ | ||
989 | langwell_otg_add_timer(b_srp_init_tmr); | ||
990 | iotg->otg.start_srp(&iotg->otg); | ||
991 | langwell_otg_del_timer(b_srp_init_tmr); | ||
992 | langwell_otg_add_ktimer(TB_SRP_FAIL_TMR); | ||
993 | |||
994 | /* reset PHY low power mode here */ | ||
995 | langwell_otg_phy_low_power_wait(1); | ||
996 | } | ||
997 | } | ||
998 | break; | ||
999 | case OTG_STATE_B_SRP_INIT: | ||
1000 | if (!iotg->hsm.id) { | ||
1001 | iotg->otg.default_a = 1; | ||
1002 | iotg->hsm.a_srp_det = 0; | ||
1003 | |||
1004 | /* Turn off VBus */ | ||
1005 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1006 | langwell_otg_chrg_vbus(0); | ||
1007 | set_host_mode(); | ||
1008 | langwell_otg_phy_low_power(1); | ||
1009 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
1010 | langwell_update_transceiver(); | ||
1011 | } else if (iotg->hsm.b_sess_vld) { | ||
1012 | langwell_otg_chrg_vbus(0); | ||
1013 | if (lnw->iotg.start_peripheral) { | ||
1014 | lnw->iotg.start_peripheral(&lnw->iotg); | ||
1015 | iotg->otg.state = OTG_STATE_B_PERIPHERAL; | ||
1016 | } else | ||
1017 | dev_dbg(lnw->dev, "client driver not loaded\n"); | ||
1018 | } | ||
1019 | break; | ||
1020 | case OTG_STATE_B_PERIPHERAL: | ||
1021 | if (!iotg->hsm.id) { | ||
1022 | iotg->otg.default_a = 1; | ||
1023 | iotg->hsm.a_srp_det = 0; | ||
1024 | |||
1025 | langwell_otg_chrg_vbus(0); | ||
1026 | |||
1027 | if (lnw->iotg.stop_peripheral) | ||
1028 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
1029 | else | ||
1030 | dev_dbg(lnw->dev, | ||
1031 | "client driver has been removed.\n"); | ||
1032 | |||
1033 | set_host_mode(); | ||
1034 | langwell_otg_phy_low_power(1); | ||
1035 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
1036 | langwell_update_transceiver(); | ||
1037 | } else if (!iotg->hsm.b_sess_vld) { | ||
1038 | iotg->hsm.b_hnp_enable = 0; | ||
1039 | |||
1040 | if (lnw->iotg.stop_peripheral) | ||
1041 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
1042 | else | ||
1043 | dev_dbg(lnw->dev, | ||
1044 | "client driver has been removed.\n"); | ||
1045 | |||
1046 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1047 | } else if (iotg->hsm.b_bus_req && iotg->otg.gadget && | ||
1048 | iotg->otg.gadget->b_hnp_enable && | ||
1049 | iotg->hsm.a_bus_suspend) { | ||
1050 | |||
1051 | if (lnw->iotg.stop_peripheral) | ||
1052 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
1053 | else | ||
1054 | dev_dbg(lnw->dev, | ||
1055 | "client driver has been removed.\n"); | ||
1056 | |||
1057 | langwell_otg_HAAR(1); | ||
1058 | iotg->hsm.a_conn = 0; | ||
1059 | |||
1060 | if (lnw->iotg.start_host) { | ||
1061 | lnw->iotg.start_host(&lnw->iotg); | ||
1062 | iotg->otg.state = OTG_STATE_B_WAIT_ACON; | ||
1063 | } else | ||
1064 | dev_dbg(lnw->dev, | ||
1065 | "host driver not loaded.\n"); | ||
1066 | |||
1067 | iotg->hsm.a_bus_resume = 0; | ||
1068 | langwell_otg_add_ktimer(TB_ASE0_BRST_TMR); | ||
1069 | } | ||
1070 | break; | ||
1071 | |||
1072 | case OTG_STATE_B_WAIT_ACON: | ||
1073 | if (!iotg->hsm.id) { | ||
1074 | /* delete hsm timer for b_ase0_brst_tmr */ | ||
1075 | del_timer_sync(&lnw->hsm_timer); | ||
1076 | |||
1077 | iotg->otg.default_a = 1; | ||
1078 | iotg->hsm.a_srp_det = 0; | ||
1079 | |||
1080 | langwell_otg_chrg_vbus(0); | ||
1081 | |||
1082 | langwell_otg_HAAR(0); | ||
1083 | if (lnw->iotg.stop_host) | ||
1084 | lnw->iotg.stop_host(&lnw->iotg); | ||
1085 | else | ||
1086 | dev_dbg(lnw->dev, | ||
1087 | "host driver has been removed.\n"); | ||
1088 | |||
1089 | set_host_mode(); | ||
1090 | langwell_otg_phy_low_power(1); | ||
1091 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
1092 | langwell_update_transceiver(); | ||
1093 | } else if (!iotg->hsm.b_sess_vld) { | ||
1094 | /* delete hsm timer for b_ase0_brst_tmr */ | ||
1095 | del_timer_sync(&lnw->hsm_timer); | ||
1096 | |||
1097 | iotg->hsm.b_hnp_enable = 0; | ||
1098 | iotg->hsm.b_bus_req = 0; | ||
1099 | |||
1100 | langwell_otg_chrg_vbus(0); | ||
1101 | langwell_otg_HAAR(0); | ||
1102 | |||
1103 | if (lnw->iotg.stop_host) | ||
1104 | lnw->iotg.stop_host(&lnw->iotg); | ||
1105 | else | ||
1106 | dev_dbg(lnw->dev, | ||
1107 | "host driver has been removed.\n"); | ||
1108 | |||
1109 | set_client_mode(); | ||
1110 | langwell_otg_phy_low_power(1); | ||
1111 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1112 | } else if (iotg->hsm.a_conn) { | ||
1113 | /* delete hsm timer for b_ase0_brst_tmr */ | ||
1114 | del_timer_sync(&lnw->hsm_timer); | ||
1115 | |||
1116 | langwell_otg_HAAR(0); | ||
1117 | iotg->otg.state = OTG_STATE_B_HOST; | ||
1118 | langwell_update_transceiver(); | ||
1119 | } else if (iotg->hsm.a_bus_resume || | ||
1120 | iotg->hsm.b_ase0_brst_tmout) { | ||
1121 | /* delete hsm timer for b_ase0_brst_tmr */ | ||
1122 | del_timer_sync(&lnw->hsm_timer); | ||
1123 | |||
1124 | langwell_otg_HAAR(0); | ||
1125 | langwell_otg_nsf_msg(7); | ||
1126 | |||
1127 | if (lnw->iotg.stop_host) | ||
1128 | lnw->iotg.stop_host(&lnw->iotg); | ||
1129 | else | ||
1130 | dev_dbg(lnw->dev, | ||
1131 | "host driver has been removed.\n"); | ||
1132 | |||
1133 | iotg->hsm.a_bus_suspend = 0; | ||
1134 | iotg->hsm.b_bus_req = 0; | ||
1135 | |||
1136 | if (lnw->iotg.start_peripheral) | ||
1137 | lnw->iotg.start_peripheral(&lnw->iotg); | ||
1138 | else | ||
1139 | dev_dbg(lnw->dev, | ||
1140 | "client driver not loaded.\n"); | ||
1141 | |||
1142 | iotg->otg.state = OTG_STATE_B_PERIPHERAL; | ||
1143 | } | ||
1144 | break; | ||
1145 | |||
1146 | case OTG_STATE_B_HOST: | ||
1147 | if (!iotg->hsm.id) { | ||
1148 | iotg->otg.default_a = 1; | ||
1149 | iotg->hsm.a_srp_det = 0; | ||
1150 | |||
1151 | langwell_otg_chrg_vbus(0); | ||
1152 | |||
1153 | if (lnw->iotg.stop_host) | ||
1154 | lnw->iotg.stop_host(&lnw->iotg); | ||
1155 | else | ||
1156 | dev_dbg(lnw->dev, | ||
1157 | "host driver has been removed.\n"); | ||
1158 | |||
1159 | set_host_mode(); | ||
1160 | langwell_otg_phy_low_power(1); | ||
1161 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
1162 | langwell_update_transceiver(); | ||
1163 | } else if (!iotg->hsm.b_sess_vld) { | ||
1164 | iotg->hsm.b_hnp_enable = 0; | ||
1165 | iotg->hsm.b_bus_req = 0; | ||
1166 | |||
1167 | langwell_otg_chrg_vbus(0); | ||
1168 | if (lnw->iotg.stop_host) | ||
1169 | lnw->iotg.stop_host(&lnw->iotg); | ||
1170 | else | ||
1171 | dev_dbg(lnw->dev, | ||
1172 | "host driver has been removed.\n"); | ||
1173 | |||
1174 | set_client_mode(); | ||
1175 | langwell_otg_phy_low_power(1); | ||
1176 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1177 | } else if ((!iotg->hsm.b_bus_req) || | ||
1178 | (!iotg->hsm.a_conn)) { | ||
1179 | iotg->hsm.b_bus_req = 0; | ||
1180 | langwell_otg_loc_sof(0); | ||
1181 | |||
1182 | if (lnw->iotg.stop_host) | ||
1183 | lnw->iotg.stop_host(&lnw->iotg); | ||
1184 | else | ||
1185 | dev_dbg(lnw->dev, | ||
1186 | "host driver has been removed.\n"); | ||
1187 | |||
1188 | iotg->hsm.a_bus_suspend = 0; | ||
1189 | |||
1190 | if (lnw->iotg.start_peripheral) | ||
1191 | lnw->iotg.start_peripheral(&lnw->iotg); | ||
1192 | else | ||
1193 | dev_dbg(lnw->dev, | ||
1194 | "client driver not loaded.\n"); | ||
1195 | |||
1196 | iotg->otg.state = OTG_STATE_B_PERIPHERAL; | ||
1197 | } | ||
1198 | break; | ||
1199 | |||
1200 | case OTG_STATE_A_IDLE: | ||
1201 | iotg->otg.default_a = 1; | ||
1202 | if (iotg->hsm.id) { | ||
1203 | iotg->otg.default_a = 0; | ||
1204 | iotg->hsm.b_bus_req = 0; | ||
1205 | iotg->hsm.vbus_srp_up = 0; | ||
1206 | |||
1207 | langwell_otg_chrg_vbus(0); | ||
1208 | set_client_mode(); | ||
1209 | langwell_otg_phy_low_power(1); | ||
1210 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1211 | langwell_update_transceiver(); | ||
1212 | } else if (!iotg->hsm.a_bus_drop && | ||
1213 | (iotg->hsm.a_srp_det || iotg->hsm.a_bus_req)) { | ||
1214 | langwell_otg_phy_low_power(0); | ||
1215 | |||
1216 | /* Turn on VBus */ | ||
1217 | iotg->otg.set_vbus(&iotg->otg, true); | ||
1218 | |||
1219 | iotg->hsm.vbus_srp_up = 0; | ||
1220 | iotg->hsm.a_wait_vrise_tmout = 0; | ||
1221 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
1222 | iotg->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
1223 | langwell_update_transceiver(); | ||
1224 | } else if (!iotg->hsm.a_bus_drop && iotg->hsm.a_sess_vld) { | ||
1225 | iotg->hsm.vbus_srp_up = 1; | ||
1226 | } else if (!iotg->hsm.a_sess_vld && iotg->hsm.vbus_srp_up) { | ||
1227 | msleep(10); | ||
1228 | langwell_otg_phy_low_power(0); | ||
1229 | |||
1230 | /* Turn on VBus */ | ||
1231 | iotg->otg.set_vbus(&iotg->otg, true); | ||
1232 | iotg->hsm.a_srp_det = 1; | ||
1233 | iotg->hsm.vbus_srp_up = 0; | ||
1234 | iotg->hsm.a_wait_vrise_tmout = 0; | ||
1235 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
1236 | iotg->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
1237 | langwell_update_transceiver(); | ||
1238 | } else if (!iotg->hsm.a_sess_vld && | ||
1239 | !iotg->hsm.vbus_srp_up) { | ||
1240 | langwell_otg_phy_low_power(1); | ||
1241 | } | ||
1242 | break; | ||
1243 | case OTG_STATE_A_WAIT_VRISE: | ||
1244 | if (iotg->hsm.id) { | ||
1245 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
1246 | iotg->hsm.b_bus_req = 0; | ||
1247 | iotg->otg.default_a = 0; | ||
1248 | |||
1249 | /* Turn off VBus */ | ||
1250 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1251 | set_client_mode(); | ||
1252 | langwell_otg_phy_low_power_wait(1); | ||
1253 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1254 | } else if (iotg->hsm.a_vbus_vld) { | ||
1255 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
1256 | iotg->hsm.b_conn = 0; | ||
1257 | if (lnw->iotg.start_host) | ||
1258 | lnw->iotg.start_host(&lnw->iotg); | ||
1259 | else { | ||
1260 | dev_dbg(lnw->dev, "host driver not loaded.\n"); | ||
1261 | break; | ||
1262 | } | ||
1263 | |||
1264 | langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); | ||
1265 | iotg->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1266 | } else if (iotg->hsm.a_wait_vrise_tmout) { | ||
1267 | iotg->hsm.b_conn = 0; | ||
1268 | if (iotg->hsm.a_vbus_vld) { | ||
1269 | if (lnw->iotg.start_host) | ||
1270 | lnw->iotg.start_host(&lnw->iotg); | ||
1271 | else { | ||
1272 | dev_dbg(lnw->dev, | ||
1273 | "host driver not loaded.\n"); | ||
1274 | break; | ||
1275 | } | ||
1276 | langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); | ||
1277 | iotg->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1278 | } else { | ||
1279 | |||
1280 | /* Turn off VBus */ | ||
1281 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1282 | langwell_otg_phy_low_power_wait(1); | ||
1283 | iotg->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1284 | } | ||
1285 | } | ||
1286 | break; | ||
1287 | case OTG_STATE_A_WAIT_BCON: | ||
1288 | if (iotg->hsm.id) { | ||
1289 | /* delete hsm timer for a_wait_bcon_tmr */ | ||
1290 | del_timer_sync(&lnw->hsm_timer); | ||
1291 | |||
1292 | iotg->otg.default_a = 0; | ||
1293 | iotg->hsm.b_bus_req = 0; | ||
1294 | |||
1295 | if (lnw->iotg.stop_host) | ||
1296 | lnw->iotg.stop_host(&lnw->iotg); | ||
1297 | else | ||
1298 | dev_dbg(lnw->dev, | ||
1299 | "host driver has been removed.\n"); | ||
1300 | |||
1301 | /* Turn off VBus */ | ||
1302 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1303 | set_client_mode(); | ||
1304 | langwell_otg_phy_low_power_wait(1); | ||
1305 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1306 | langwell_update_transceiver(); | ||
1307 | } else if (!iotg->hsm.a_vbus_vld) { | ||
1308 | /* delete hsm timer for a_wait_bcon_tmr */ | ||
1309 | del_timer_sync(&lnw->hsm_timer); | ||
1310 | |||
1311 | if (lnw->iotg.stop_host) | ||
1312 | lnw->iotg.stop_host(&lnw->iotg); | ||
1313 | else | ||
1314 | dev_dbg(lnw->dev, | ||
1315 | "host driver has been removed.\n"); | ||
1316 | |||
1317 | /* Turn off VBus */ | ||
1318 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1319 | langwell_otg_phy_low_power_wait(1); | ||
1320 | iotg->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1321 | } else if (iotg->hsm.a_bus_drop || | ||
1322 | (iotg->hsm.a_wait_bcon_tmout && | ||
1323 | !iotg->hsm.a_bus_req)) { | ||
1324 | /* delete hsm timer for a_wait_bcon_tmr */ | ||
1325 | del_timer_sync(&lnw->hsm_timer); | ||
1326 | |||
1327 | if (lnw->iotg.stop_host) | ||
1328 | lnw->iotg.stop_host(&lnw->iotg); | ||
1329 | else | ||
1330 | dev_dbg(lnw->dev, | ||
1331 | "host driver has been removed.\n"); | ||
1332 | |||
1333 | /* Turn off VBus */ | ||
1334 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1335 | iotg->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1336 | } else if (iotg->hsm.b_conn) { | ||
1337 | /* delete hsm timer for a_wait_bcon_tmr */ | ||
1338 | del_timer_sync(&lnw->hsm_timer); | ||
1339 | |||
1340 | iotg->hsm.a_suspend_req = 0; | ||
1341 | iotg->otg.state = OTG_STATE_A_HOST; | ||
1342 | if (iotg->hsm.a_srp_det && iotg->otg.host && | ||
1343 | !iotg->otg.host->b_hnp_enable) { | ||
1344 | /* SRP capable peripheral-only device */ | ||
1345 | iotg->hsm.a_bus_req = 1; | ||
1346 | iotg->hsm.a_srp_det = 0; | ||
1347 | } else if (!iotg->hsm.a_bus_req && iotg->otg.host && | ||
1348 | iotg->otg.host->b_hnp_enable) { | ||
1349 | /* It is not safe enough to do a fast | ||
1350 | * transition from A_WAIT_BCON to | ||
1351 | * A_SUSPEND */ | ||
1352 | msleep(10000); | ||
1353 | if (iotg->hsm.a_bus_req) | ||
1354 | break; | ||
1355 | |||
1356 | if (request_irq(pdev->irq, | ||
1357 | otg_dummy_irq, IRQF_SHARED, | ||
1358 | driver_name, iotg->base) != 0) { | ||
1359 | dev_dbg(lnw->dev, | ||
1360 | "request interrupt %d fail\n", | ||
1361 | pdev->irq); | ||
1362 | } | ||
1363 | |||
1364 | langwell_otg_HABA(1); | ||
1365 | iotg->hsm.b_bus_resume = 0; | ||
1366 | iotg->hsm.a_aidl_bdis_tmout = 0; | ||
1367 | |||
1368 | langwell_otg_loc_sof(0); | ||
1369 | /* clear PHCD to enable HW timer */ | ||
1370 | langwell_otg_phy_low_power(0); | ||
1371 | langwell_otg_add_timer(a_aidl_bdis_tmr); | ||
1372 | iotg->otg.state = OTG_STATE_A_SUSPEND; | ||
1373 | } else if (!iotg->hsm.a_bus_req && iotg->otg.host && | ||
1374 | !iotg->otg.host->b_hnp_enable) { | ||
1375 | if (lnw->iotg.stop_host) | ||
1376 | lnw->iotg.stop_host(&lnw->iotg); | ||
1377 | else | ||
1378 | dev_dbg(lnw->dev, | ||
1379 | "host driver removed.\n"); | ||
1380 | |||
1381 | /* Turn off VBus */ | ||
1382 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1383 | iotg->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1384 | } | ||
1385 | } | ||
1386 | break; | ||
1387 | case OTG_STATE_A_HOST: | ||
1388 | if (iotg->hsm.id) { | ||
1389 | iotg->otg.default_a = 0; | ||
1390 | iotg->hsm.b_bus_req = 0; | ||
1391 | |||
1392 | if (lnw->iotg.stop_host) | ||
1393 | lnw->iotg.stop_host(&lnw->iotg); | ||
1394 | else | ||
1395 | dev_dbg(lnw->dev, | ||
1396 | "host driver has been removed.\n"); | ||
1397 | |||
1398 | /* Turn off VBus */ | ||
1399 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1400 | set_client_mode(); | ||
1401 | langwell_otg_phy_low_power_wait(1); | ||
1402 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1403 | langwell_update_transceiver(); | ||
1404 | } else if (iotg->hsm.a_bus_drop || | ||
1405 | (iotg->otg.host && | ||
1406 | !iotg->otg.host->b_hnp_enable && | ||
1407 | !iotg->hsm.a_bus_req)) { | ||
1408 | if (lnw->iotg.stop_host) | ||
1409 | lnw->iotg.stop_host(&lnw->iotg); | ||
1410 | else | ||
1411 | dev_dbg(lnw->dev, | ||
1412 | "host driver has been removed.\n"); | ||
1413 | |||
1414 | /* Turn off VBus */ | ||
1415 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1416 | iotg->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1417 | } else if (!iotg->hsm.a_vbus_vld) { | ||
1418 | if (lnw->iotg.stop_host) | ||
1419 | lnw->iotg.stop_host(&lnw->iotg); | ||
1420 | else | ||
1421 | dev_dbg(lnw->dev, | ||
1422 | "host driver has been removed.\n"); | ||
1423 | |||
1424 | /* Turn off VBus */ | ||
1425 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1426 | langwell_otg_phy_low_power_wait(1); | ||
1427 | iotg->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1428 | } else if (iotg->otg.host && | ||
1429 | iotg->otg.host->b_hnp_enable && | ||
1430 | !iotg->hsm.a_bus_req) { | ||
1431 | /* Set HABA to enable hardware assistance to signal | ||
1432 | * A-connect after receiver B-disconnect. Hardware | ||
1433 | * will then set client mode and enable URE, SLE and | ||
1434 | * PCE after the assistance. otg_dummy_irq is used to | ||
1435 | * clean these ints when client driver is not resumed. | ||
1436 | */ | ||
1437 | if (request_irq(pdev->irq, otg_dummy_irq, IRQF_SHARED, | ||
1438 | driver_name, iotg->base) != 0) { | ||
1439 | dev_dbg(lnw->dev, | ||
1440 | "request interrupt %d failed\n", | ||
1441 | pdev->irq); | ||
1442 | } | ||
1443 | |||
1444 | /* set HABA */ | ||
1445 | langwell_otg_HABA(1); | ||
1446 | iotg->hsm.b_bus_resume = 0; | ||
1447 | iotg->hsm.a_aidl_bdis_tmout = 0; | ||
1448 | langwell_otg_loc_sof(0); | ||
1449 | /* clear PHCD to enable HW timer */ | ||
1450 | langwell_otg_phy_low_power(0); | ||
1451 | langwell_otg_add_timer(a_aidl_bdis_tmr); | ||
1452 | iotg->otg.state = OTG_STATE_A_SUSPEND; | ||
1453 | } else if (!iotg->hsm.b_conn || !iotg->hsm.a_bus_req) { | ||
1454 | langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); | ||
1455 | iotg->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1456 | } | ||
1457 | break; | ||
1458 | case OTG_STATE_A_SUSPEND: | ||
1459 | if (iotg->hsm.id) { | ||
1460 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1461 | langwell_otg_HABA(0); | ||
1462 | free_irq(pdev->irq, iotg->base); | ||
1463 | iotg->otg.default_a = 0; | ||
1464 | iotg->hsm.b_bus_req = 0; | ||
1465 | |||
1466 | if (lnw->iotg.stop_host) | ||
1467 | lnw->iotg.stop_host(&lnw->iotg); | ||
1468 | else | ||
1469 | dev_dbg(lnw->dev, | ||
1470 | "host driver has been removed.\n"); | ||
1471 | |||
1472 | /* Turn off VBus */ | ||
1473 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1474 | set_client_mode(); | ||
1475 | langwell_otg_phy_low_power(1); | ||
1476 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1477 | langwell_update_transceiver(); | ||
1478 | } else if (iotg->hsm.a_bus_req || | ||
1479 | iotg->hsm.b_bus_resume) { | ||
1480 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1481 | langwell_otg_HABA(0); | ||
1482 | free_irq(pdev->irq, iotg->base); | ||
1483 | iotg->hsm.a_suspend_req = 0; | ||
1484 | langwell_otg_loc_sof(1); | ||
1485 | iotg->otg.state = OTG_STATE_A_HOST; | ||
1486 | } else if (iotg->hsm.a_aidl_bdis_tmout || | ||
1487 | iotg->hsm.a_bus_drop) { | ||
1488 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1489 | langwell_otg_HABA(0); | ||
1490 | free_irq(pdev->irq, iotg->base); | ||
1491 | if (lnw->iotg.stop_host) | ||
1492 | lnw->iotg.stop_host(&lnw->iotg); | ||
1493 | else | ||
1494 | dev_dbg(lnw->dev, | ||
1495 | "host driver has been removed.\n"); | ||
1496 | |||
1497 | /* Turn off VBus */ | ||
1498 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1499 | iotg->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1500 | } else if (!iotg->hsm.b_conn && iotg->otg.host && | ||
1501 | iotg->otg.host->b_hnp_enable) { | ||
1502 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1503 | langwell_otg_HABA(0); | ||
1504 | free_irq(pdev->irq, iotg->base); | ||
1505 | |||
1506 | if (lnw->iotg.stop_host) | ||
1507 | lnw->iotg.stop_host(&lnw->iotg); | ||
1508 | else | ||
1509 | dev_dbg(lnw->dev, | ||
1510 | "host driver has been removed.\n"); | ||
1511 | |||
1512 | iotg->hsm.b_bus_suspend = 0; | ||
1513 | iotg->hsm.b_bus_suspend_vld = 0; | ||
1514 | |||
1515 | /* msleep(200); */ | ||
1516 | if (lnw->iotg.start_peripheral) | ||
1517 | lnw->iotg.start_peripheral(&lnw->iotg); | ||
1518 | else | ||
1519 | dev_dbg(lnw->dev, | ||
1520 | "client driver not loaded.\n"); | ||
1521 | |||
1522 | langwell_otg_add_ktimer(TB_BUS_SUSPEND_TMR); | ||
1523 | iotg->otg.state = OTG_STATE_A_PERIPHERAL; | ||
1524 | break; | ||
1525 | } else if (!iotg->hsm.a_vbus_vld) { | ||
1526 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1527 | langwell_otg_HABA(0); | ||
1528 | free_irq(pdev->irq, iotg->base); | ||
1529 | if (lnw->iotg.stop_host) | ||
1530 | lnw->iotg.stop_host(&lnw->iotg); | ||
1531 | else | ||
1532 | dev_dbg(lnw->dev, | ||
1533 | "host driver has been removed.\n"); | ||
1534 | |||
1535 | /* Turn off VBus */ | ||
1536 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1537 | langwell_otg_phy_low_power_wait(1); | ||
1538 | iotg->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1539 | } | ||
1540 | break; | ||
1541 | case OTG_STATE_A_PERIPHERAL: | ||
1542 | if (iotg->hsm.id) { | ||
1543 | /* delete hsm timer for b_bus_suspend_tmr */ | ||
1544 | del_timer_sync(&lnw->hsm_timer); | ||
1545 | iotg->otg.default_a = 0; | ||
1546 | iotg->hsm.b_bus_req = 0; | ||
1547 | if (lnw->iotg.stop_peripheral) | ||
1548 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
1549 | else | ||
1550 | dev_dbg(lnw->dev, | ||
1551 | "client driver has been removed.\n"); | ||
1552 | |||
1553 | /* Turn off VBus */ | ||
1554 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1555 | set_client_mode(); | ||
1556 | langwell_otg_phy_low_power_wait(1); | ||
1557 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1558 | langwell_update_transceiver(); | ||
1559 | } else if (!iotg->hsm.a_vbus_vld) { | ||
1560 | /* delete hsm timer for b_bus_suspend_tmr */ | ||
1561 | del_timer_sync(&lnw->hsm_timer); | ||
1562 | |||
1563 | if (lnw->iotg.stop_peripheral) | ||
1564 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
1565 | else | ||
1566 | dev_dbg(lnw->dev, | ||
1567 | "client driver has been removed.\n"); | ||
1568 | |||
1569 | /* Turn off VBus */ | ||
1570 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1571 | langwell_otg_phy_low_power_wait(1); | ||
1572 | iotg->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1573 | } else if (iotg->hsm.a_bus_drop) { | ||
1574 | /* delete hsm timer for b_bus_suspend_tmr */ | ||
1575 | del_timer_sync(&lnw->hsm_timer); | ||
1576 | |||
1577 | if (lnw->iotg.stop_peripheral) | ||
1578 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
1579 | else | ||
1580 | dev_dbg(lnw->dev, | ||
1581 | "client driver has been removed.\n"); | ||
1582 | |||
1583 | /* Turn off VBus */ | ||
1584 | iotg->otg.set_vbus(&iotg->otg, false); | ||
1585 | iotg->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1586 | } else if (iotg->hsm.b_bus_suspend) { | ||
1587 | /* delete hsm timer for b_bus_suspend_tmr */ | ||
1588 | del_timer_sync(&lnw->hsm_timer); | ||
1589 | |||
1590 | if (lnw->iotg.stop_peripheral) | ||
1591 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
1592 | else | ||
1593 | dev_dbg(lnw->dev, | ||
1594 | "client driver has been removed.\n"); | ||
1595 | |||
1596 | if (lnw->iotg.start_host) | ||
1597 | lnw->iotg.start_host(&lnw->iotg); | ||
1598 | else | ||
1599 | dev_dbg(lnw->dev, | ||
1600 | "host driver not loaded.\n"); | ||
1601 | langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); | ||
1602 | iotg->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1603 | } else if (iotg->hsm.b_bus_suspend_tmout) { | ||
1604 | u32 val; | ||
1605 | val = readl(lnw->iotg.base + CI_PORTSC1); | ||
1606 | if (!(val & PORTSC_SUSP)) | ||
1607 | break; | ||
1608 | |||
1609 | if (lnw->iotg.stop_peripheral) | ||
1610 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
1611 | else | ||
1612 | dev_dbg(lnw->dev, | ||
1613 | "client driver has been removed.\n"); | ||
1614 | |||
1615 | if (lnw->iotg.start_host) | ||
1616 | lnw->iotg.start_host(&lnw->iotg); | ||
1617 | else | ||
1618 | dev_dbg(lnw->dev, | ||
1619 | "host driver not loaded.\n"); | ||
1620 | langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); | ||
1621 | iotg->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1622 | } | ||
1623 | break; | ||
1624 | case OTG_STATE_A_VBUS_ERR: | ||
1625 | if (iotg->hsm.id) { | ||
1626 | iotg->otg.default_a = 0; | ||
1627 | iotg->hsm.a_clr_err = 0; | ||
1628 | iotg->hsm.a_srp_det = 0; | ||
1629 | set_client_mode(); | ||
1630 | langwell_otg_phy_low_power(1); | ||
1631 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1632 | langwell_update_transceiver(); | ||
1633 | } else if (iotg->hsm.a_clr_err) { | ||
1634 | iotg->hsm.a_clr_err = 0; | ||
1635 | iotg->hsm.a_srp_det = 0; | ||
1636 | reset_otg(); | ||
1637 | init_hsm(); | ||
1638 | if (iotg->otg.state == OTG_STATE_A_IDLE) | ||
1639 | langwell_update_transceiver(); | ||
1640 | } else { | ||
1641 | /* FW will clear PHCD bit when any VBus | ||
1642 | * event detected. Reset PHCD to 1 again */ | ||
1643 | langwell_otg_phy_low_power(1); | ||
1644 | } | ||
1645 | break; | ||
1646 | case OTG_STATE_A_WAIT_VFALL: | ||
1647 | if (iotg->hsm.id) { | ||
1648 | iotg->otg.default_a = 0; | ||
1649 | set_client_mode(); | ||
1650 | langwell_otg_phy_low_power(1); | ||
1651 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
1652 | langwell_update_transceiver(); | ||
1653 | } else if (iotg->hsm.a_bus_req) { | ||
1654 | |||
1655 | /* Turn on VBus */ | ||
1656 | iotg->otg.set_vbus(&iotg->otg, true); | ||
1657 | iotg->hsm.a_wait_vrise_tmout = 0; | ||
1658 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
1659 | iotg->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
1660 | } else if (!iotg->hsm.a_sess_vld) { | ||
1661 | iotg->hsm.a_srp_det = 0; | ||
1662 | set_host_mode(); | ||
1663 | langwell_otg_phy_low_power(1); | ||
1664 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
1665 | } | ||
1666 | break; | ||
1667 | default: | ||
1668 | ; | ||
1669 | } | ||
1670 | |||
1671 | dev_dbg(lnw->dev, "%s: new state = %s\n", __func__, | ||
1672 | otg_state_string(iotg->otg.state)); | ||
1673 | } | ||
1674 | |||
1675 | static ssize_t | ||
1676 | show_registers(struct device *_dev, struct device_attribute *attr, char *buf) | ||
1677 | { | ||
1678 | struct langwell_otg *lnw = the_transceiver; | ||
1679 | char *next; | ||
1680 | unsigned size, t; | ||
1681 | |||
1682 | next = buf; | ||
1683 | size = PAGE_SIZE; | ||
1684 | |||
1685 | t = scnprintf(next, size, | ||
1686 | "\n" | ||
1687 | "USBCMD = 0x%08x\n" | ||
1688 | "USBSTS = 0x%08x\n" | ||
1689 | "USBINTR = 0x%08x\n" | ||
1690 | "ASYNCLISTADDR = 0x%08x\n" | ||
1691 | "PORTSC1 = 0x%08x\n" | ||
1692 | "HOSTPC1 = 0x%08x\n" | ||
1693 | "OTGSC = 0x%08x\n" | ||
1694 | "USBMODE = 0x%08x\n", | ||
1695 | readl(lnw->iotg.base + 0x30), | ||
1696 | readl(lnw->iotg.base + 0x34), | ||
1697 | readl(lnw->iotg.base + 0x38), | ||
1698 | readl(lnw->iotg.base + 0x48), | ||
1699 | readl(lnw->iotg.base + 0x74), | ||
1700 | readl(lnw->iotg.base + 0xb4), | ||
1701 | readl(lnw->iotg.base + 0xf4), | ||
1702 | readl(lnw->iotg.base + 0xf8) | ||
1703 | ); | ||
1704 | size -= t; | ||
1705 | next += t; | ||
1706 | |||
1707 | return PAGE_SIZE - size; | ||
1708 | } | ||
1709 | static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL); | ||
1710 | |||
1711 | static ssize_t | ||
1712 | show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) | ||
1713 | { | ||
1714 | struct langwell_otg *lnw = the_transceiver; | ||
1715 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
1716 | char *next; | ||
1717 | unsigned size, t; | ||
1718 | |||
1719 | next = buf; | ||
1720 | size = PAGE_SIZE; | ||
1721 | |||
1722 | if (iotg->otg.host) | ||
1723 | iotg->hsm.a_set_b_hnp_en = iotg->otg.host->b_hnp_enable; | ||
1724 | |||
1725 | if (iotg->otg.gadget) | ||
1726 | iotg->hsm.b_hnp_enable = iotg->otg.gadget->b_hnp_enable; | ||
1727 | |||
1728 | t = scnprintf(next, size, | ||
1729 | "\n" | ||
1730 | "current state = %s\n" | ||
1731 | "a_bus_resume = \t%d\n" | ||
1732 | "a_bus_suspend = \t%d\n" | ||
1733 | "a_conn = \t%d\n" | ||
1734 | "a_sess_vld = \t%d\n" | ||
1735 | "a_srp_det = \t%d\n" | ||
1736 | "a_vbus_vld = \t%d\n" | ||
1737 | "b_bus_resume = \t%d\n" | ||
1738 | "b_bus_suspend = \t%d\n" | ||
1739 | "b_conn = \t%d\n" | ||
1740 | "b_se0_srp = \t%d\n" | ||
1741 | "b_sess_end = \t%d\n" | ||
1742 | "b_sess_vld = \t%d\n" | ||
1743 | "id = \t%d\n" | ||
1744 | "a_set_b_hnp_en = \t%d\n" | ||
1745 | "b_srp_done = \t%d\n" | ||
1746 | "b_hnp_enable = \t%d\n" | ||
1747 | "a_wait_vrise_tmout = \t%d\n" | ||
1748 | "a_wait_bcon_tmout = \t%d\n" | ||
1749 | "a_aidl_bdis_tmout = \t%d\n" | ||
1750 | "b_ase0_brst_tmout = \t%d\n" | ||
1751 | "a_bus_drop = \t%d\n" | ||
1752 | "a_bus_req = \t%d\n" | ||
1753 | "a_clr_err = \t%d\n" | ||
1754 | "a_suspend_req = \t%d\n" | ||
1755 | "b_bus_req = \t%d\n" | ||
1756 | "b_bus_suspend_tmout = \t%d\n" | ||
1757 | "b_bus_suspend_vld = \t%d\n", | ||
1758 | otg_state_string(iotg->otg.state), | ||
1759 | iotg->hsm.a_bus_resume, | ||
1760 | iotg->hsm.a_bus_suspend, | ||
1761 | iotg->hsm.a_conn, | ||
1762 | iotg->hsm.a_sess_vld, | ||
1763 | iotg->hsm.a_srp_det, | ||
1764 | iotg->hsm.a_vbus_vld, | ||
1765 | iotg->hsm.b_bus_resume, | ||
1766 | iotg->hsm.b_bus_suspend, | ||
1767 | iotg->hsm.b_conn, | ||
1768 | iotg->hsm.b_se0_srp, | ||
1769 | iotg->hsm.b_sess_end, | ||
1770 | iotg->hsm.b_sess_vld, | ||
1771 | iotg->hsm.id, | ||
1772 | iotg->hsm.a_set_b_hnp_en, | ||
1773 | iotg->hsm.b_srp_done, | ||
1774 | iotg->hsm.b_hnp_enable, | ||
1775 | iotg->hsm.a_wait_vrise_tmout, | ||
1776 | iotg->hsm.a_wait_bcon_tmout, | ||
1777 | iotg->hsm.a_aidl_bdis_tmout, | ||
1778 | iotg->hsm.b_ase0_brst_tmout, | ||
1779 | iotg->hsm.a_bus_drop, | ||
1780 | iotg->hsm.a_bus_req, | ||
1781 | iotg->hsm.a_clr_err, | ||
1782 | iotg->hsm.a_suspend_req, | ||
1783 | iotg->hsm.b_bus_req, | ||
1784 | iotg->hsm.b_bus_suspend_tmout, | ||
1785 | iotg->hsm.b_bus_suspend_vld | ||
1786 | ); | ||
1787 | size -= t; | ||
1788 | next += t; | ||
1789 | |||
1790 | return PAGE_SIZE - size; | ||
1791 | } | ||
1792 | static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL); | ||
1793 | |||
1794 | static ssize_t | ||
1795 | get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) | ||
1796 | { | ||
1797 | struct langwell_otg *lnw = the_transceiver; | ||
1798 | char *next; | ||
1799 | unsigned size, t; | ||
1800 | |||
1801 | next = buf; | ||
1802 | size = PAGE_SIZE; | ||
1803 | |||
1804 | t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_req); | ||
1805 | size -= t; | ||
1806 | next += t; | ||
1807 | |||
1808 | return PAGE_SIZE - size; | ||
1809 | } | ||
1810 | |||
1811 | static ssize_t | ||
1812 | set_a_bus_req(struct device *dev, struct device_attribute *attr, | ||
1813 | const char *buf, size_t count) | ||
1814 | { | ||
1815 | struct langwell_otg *lnw = the_transceiver; | ||
1816 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
1817 | |||
1818 | if (!iotg->otg.default_a) | ||
1819 | return -1; | ||
1820 | if (count > 2) | ||
1821 | return -1; | ||
1822 | |||
1823 | if (buf[0] == '0') { | ||
1824 | iotg->hsm.a_bus_req = 0; | ||
1825 | dev_dbg(lnw->dev, "User request: a_bus_req = 0\n"); | ||
1826 | } else if (buf[0] == '1') { | ||
1827 | /* If a_bus_drop is TRUE, a_bus_req can't be set */ | ||
1828 | if (iotg->hsm.a_bus_drop) | ||
1829 | return -1; | ||
1830 | iotg->hsm.a_bus_req = 1; | ||
1831 | dev_dbg(lnw->dev, "User request: a_bus_req = 1\n"); | ||
1832 | } | ||
1833 | if (spin_trylock(&lnw->wq_lock)) { | ||
1834 | langwell_update_transceiver(); | ||
1835 | spin_unlock(&lnw->wq_lock); | ||
1836 | } | ||
1837 | return count; | ||
1838 | } | ||
1839 | static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req); | ||
1840 | |||
1841 | static ssize_t | ||
1842 | get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) | ||
1843 | { | ||
1844 | struct langwell_otg *lnw = the_transceiver; | ||
1845 | char *next; | ||
1846 | unsigned size, t; | ||
1847 | |||
1848 | next = buf; | ||
1849 | size = PAGE_SIZE; | ||
1850 | |||
1851 | t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_drop); | ||
1852 | size -= t; | ||
1853 | next += t; | ||
1854 | |||
1855 | return PAGE_SIZE - size; | ||
1856 | } | ||
1857 | |||
1858 | static ssize_t | ||
1859 | set_a_bus_drop(struct device *dev, struct device_attribute *attr, | ||
1860 | const char *buf, size_t count) | ||
1861 | { | ||
1862 | struct langwell_otg *lnw = the_transceiver; | ||
1863 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
1864 | |||
1865 | if (!iotg->otg.default_a) | ||
1866 | return -1; | ||
1867 | if (count > 2) | ||
1868 | return -1; | ||
1869 | |||
1870 | if (buf[0] == '0') { | ||
1871 | iotg->hsm.a_bus_drop = 0; | ||
1872 | dev_dbg(lnw->dev, "User request: a_bus_drop = 0\n"); | ||
1873 | } else if (buf[0] == '1') { | ||
1874 | iotg->hsm.a_bus_drop = 1; | ||
1875 | iotg->hsm.a_bus_req = 0; | ||
1876 | dev_dbg(lnw->dev, "User request: a_bus_drop = 1\n"); | ||
1877 | dev_dbg(lnw->dev, "User request: and a_bus_req = 0\n"); | ||
1878 | } | ||
1879 | if (spin_trylock(&lnw->wq_lock)) { | ||
1880 | langwell_update_transceiver(); | ||
1881 | spin_unlock(&lnw->wq_lock); | ||
1882 | } | ||
1883 | return count; | ||
1884 | } | ||
1885 | static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop, set_a_bus_drop); | ||
1886 | |||
1887 | static ssize_t | ||
1888 | get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) | ||
1889 | { | ||
1890 | struct langwell_otg *lnw = the_transceiver; | ||
1891 | char *next; | ||
1892 | unsigned size, t; | ||
1893 | |||
1894 | next = buf; | ||
1895 | size = PAGE_SIZE; | ||
1896 | |||
1897 | t = scnprintf(next, size, "%d", lnw->iotg.hsm.b_bus_req); | ||
1898 | size -= t; | ||
1899 | next += t; | ||
1900 | |||
1901 | return PAGE_SIZE - size; | ||
1902 | } | ||
1903 | |||
1904 | static ssize_t | ||
1905 | set_b_bus_req(struct device *dev, struct device_attribute *attr, | ||
1906 | const char *buf, size_t count) | ||
1907 | { | ||
1908 | struct langwell_otg *lnw = the_transceiver; | ||
1909 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
1910 | |||
1911 | if (iotg->otg.default_a) | ||
1912 | return -1; | ||
1913 | |||
1914 | if (count > 2) | ||
1915 | return -1; | ||
1916 | |||
1917 | if (buf[0] == '0') { | ||
1918 | iotg->hsm.b_bus_req = 0; | ||
1919 | dev_dbg(lnw->dev, "User request: b_bus_req = 0\n"); | ||
1920 | } else if (buf[0] == '1') { | ||
1921 | iotg->hsm.b_bus_req = 1; | ||
1922 | dev_dbg(lnw->dev, "User request: b_bus_req = 1\n"); | ||
1923 | } | ||
1924 | if (spin_trylock(&lnw->wq_lock)) { | ||
1925 | langwell_update_transceiver(); | ||
1926 | spin_unlock(&lnw->wq_lock); | ||
1927 | } | ||
1928 | return count; | ||
1929 | } | ||
1930 | static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req); | ||
1931 | |||
1932 | static ssize_t | ||
1933 | set_a_clr_err(struct device *dev, struct device_attribute *attr, | ||
1934 | const char *buf, size_t count) | ||
1935 | { | ||
1936 | struct langwell_otg *lnw = the_transceiver; | ||
1937 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
1938 | |||
1939 | if (!iotg->otg.default_a) | ||
1940 | return -1; | ||
1941 | if (count > 2) | ||
1942 | return -1; | ||
1943 | |||
1944 | if (buf[0] == '1') { | ||
1945 | iotg->hsm.a_clr_err = 1; | ||
1946 | dev_dbg(lnw->dev, "User request: a_clr_err = 1\n"); | ||
1947 | } | ||
1948 | if (spin_trylock(&lnw->wq_lock)) { | ||
1949 | langwell_update_transceiver(); | ||
1950 | spin_unlock(&lnw->wq_lock); | ||
1951 | } | ||
1952 | return count; | ||
1953 | } | ||
1954 | static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); | ||
1955 | |||
1956 | static struct attribute *inputs_attrs[] = { | ||
1957 | &dev_attr_a_bus_req.attr, | ||
1958 | &dev_attr_a_bus_drop.attr, | ||
1959 | &dev_attr_b_bus_req.attr, | ||
1960 | &dev_attr_a_clr_err.attr, | ||
1961 | NULL, | ||
1962 | }; | ||
1963 | |||
1964 | static struct attribute_group debug_dev_attr_group = { | ||
1965 | .name = "inputs", | ||
1966 | .attrs = inputs_attrs, | ||
1967 | }; | ||
1968 | |||
1969 | static int langwell_otg_probe(struct pci_dev *pdev, | ||
1970 | const struct pci_device_id *id) | ||
1971 | { | ||
1972 | unsigned long resource, len; | ||
1973 | void __iomem *base = NULL; | ||
1974 | int retval; | ||
1975 | u32 val32; | ||
1976 | struct langwell_otg *lnw; | ||
1977 | char qname[] = "langwell_otg_queue"; | ||
1978 | |||
1979 | retval = 0; | ||
1980 | dev_dbg(&pdev->dev, "\notg controller is detected.\n"); | ||
1981 | if (pci_enable_device(pdev) < 0) { | ||
1982 | retval = -ENODEV; | ||
1983 | goto done; | ||
1984 | } | ||
1985 | |||
1986 | lnw = kzalloc(sizeof *lnw, GFP_KERNEL); | ||
1987 | if (lnw == NULL) { | ||
1988 | retval = -ENOMEM; | ||
1989 | goto done; | ||
1990 | } | ||
1991 | the_transceiver = lnw; | ||
1992 | |||
1993 | /* control register: BAR 0 */ | ||
1994 | resource = pci_resource_start(pdev, 0); | ||
1995 | len = pci_resource_len(pdev, 0); | ||
1996 | if (!request_mem_region(resource, len, driver_name)) { | ||
1997 | retval = -EBUSY; | ||
1998 | goto err; | ||
1999 | } | ||
2000 | lnw->region = 1; | ||
2001 | |||
2002 | base = ioremap_nocache(resource, len); | ||
2003 | if (base == NULL) { | ||
2004 | retval = -EFAULT; | ||
2005 | goto err; | ||
2006 | } | ||
2007 | lnw->iotg.base = base; | ||
2008 | |||
2009 | if (!request_mem_region(USBCFG_ADDR, USBCFG_LEN, driver_name)) { | ||
2010 | retval = -EBUSY; | ||
2011 | goto err; | ||
2012 | } | ||
2013 | lnw->cfg_region = 1; | ||
2014 | |||
2015 | /* For the SCCB.USBCFG register */ | ||
2016 | base = ioremap_nocache(USBCFG_ADDR, USBCFG_LEN); | ||
2017 | if (base == NULL) { | ||
2018 | retval = -EFAULT; | ||
2019 | goto err; | ||
2020 | } | ||
2021 | lnw->usbcfg = base; | ||
2022 | |||
2023 | if (!pdev->irq) { | ||
2024 | dev_dbg(&pdev->dev, "No IRQ.\n"); | ||
2025 | retval = -ENODEV; | ||
2026 | goto err; | ||
2027 | } | ||
2028 | |||
2029 | lnw->qwork = create_singlethread_workqueue(qname); | ||
2030 | if (!lnw->qwork) { | ||
2031 | dev_dbg(&pdev->dev, "cannot create workqueue %s\n", qname); | ||
2032 | retval = -ENOMEM; | ||
2033 | goto err; | ||
2034 | } | ||
2035 | INIT_WORK(&lnw->work, langwell_otg_work); | ||
2036 | |||
2037 | /* OTG common part */ | ||
2038 | lnw->dev = &pdev->dev; | ||
2039 | lnw->iotg.otg.dev = lnw->dev; | ||
2040 | lnw->iotg.otg.label = driver_name; | ||
2041 | lnw->iotg.otg.set_host = langwell_otg_set_host; | ||
2042 | lnw->iotg.otg.set_peripheral = langwell_otg_set_peripheral; | ||
2043 | lnw->iotg.otg.set_power = langwell_otg_set_power; | ||
2044 | lnw->iotg.otg.set_vbus = langwell_otg_set_vbus; | ||
2045 | lnw->iotg.otg.start_srp = langwell_otg_start_srp; | ||
2046 | lnw->iotg.otg.state = OTG_STATE_UNDEFINED; | ||
2047 | |||
2048 | if (otg_set_transceiver(&lnw->iotg.otg)) { | ||
2049 | dev_dbg(lnw->dev, "can't set transceiver\n"); | ||
2050 | retval = -EBUSY; | ||
2051 | goto err; | ||
2052 | } | ||
2053 | |||
2054 | reset_otg(); | ||
2055 | init_hsm(); | ||
2056 | |||
2057 | spin_lock_init(&lnw->lock); | ||
2058 | spin_lock_init(&lnw->wq_lock); | ||
2059 | INIT_LIST_HEAD(&active_timers); | ||
2060 | retval = langwell_otg_init_timers(&lnw->iotg.hsm); | ||
2061 | if (retval) { | ||
2062 | dev_dbg(&pdev->dev, "Failed to init timers\n"); | ||
2063 | goto err; | ||
2064 | } | ||
2065 | |||
2066 | init_timer(&lnw->hsm_timer); | ||
2067 | ATOMIC_INIT_NOTIFIER_HEAD(&lnw->iotg.iotg_notifier); | ||
2068 | |||
2069 | lnw->iotg_notifier.notifier_call = langwell_otg_iotg_notify; | ||
2070 | |||
2071 | retval = intel_mid_otg_register_notifier(&lnw->iotg, | ||
2072 | &lnw->iotg_notifier); | ||
2073 | if (retval) { | ||
2074 | dev_dbg(lnw->dev, "Failed to register notifier\n"); | ||
2075 | goto err; | ||
2076 | } | ||
2077 | |||
2078 | if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, | ||
2079 | driver_name, lnw) != 0) { | ||
2080 | dev_dbg(lnw->dev, "request interrupt %d failed\n", pdev->irq); | ||
2081 | retval = -EBUSY; | ||
2082 | goto err; | ||
2083 | } | ||
2084 | |||
2085 | /* enable OTGSC int */ | ||
2086 | val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE | | ||
2087 | OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU; | ||
2088 | writel(val32, lnw->iotg.base + CI_OTGSC); | ||
2089 | |||
2090 | retval = device_create_file(&pdev->dev, &dev_attr_registers); | ||
2091 | if (retval < 0) { | ||
2092 | dev_dbg(lnw->dev, | ||
2093 | "Can't register sysfs attribute: %d\n", retval); | ||
2094 | goto err; | ||
2095 | } | ||
2096 | |||
2097 | retval = device_create_file(&pdev->dev, &dev_attr_hsm); | ||
2098 | if (retval < 0) { | ||
2099 | dev_dbg(lnw->dev, "Can't hsm sysfs attribute: %d\n", retval); | ||
2100 | goto err; | ||
2101 | } | ||
2102 | |||
2103 | retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group); | ||
2104 | if (retval < 0) { | ||
2105 | dev_dbg(lnw->dev, | ||
2106 | "Can't register sysfs attr group: %d\n", retval); | ||
2107 | goto err; | ||
2108 | } | ||
2109 | |||
2110 | if (lnw->iotg.otg.state == OTG_STATE_A_IDLE) | ||
2111 | langwell_update_transceiver(); | ||
2112 | |||
2113 | return 0; | ||
2114 | |||
2115 | err: | ||
2116 | if (the_transceiver) | ||
2117 | langwell_otg_remove(pdev); | ||
2118 | done: | ||
2119 | return retval; | ||
2120 | } | ||
2121 | |||
2122 | static void langwell_otg_remove(struct pci_dev *pdev) | ||
2123 | { | ||
2124 | struct langwell_otg *lnw = the_transceiver; | ||
2125 | |||
2126 | if (lnw->qwork) { | ||
2127 | flush_workqueue(lnw->qwork); | ||
2128 | destroy_workqueue(lnw->qwork); | ||
2129 | } | ||
2130 | intel_mid_otg_unregister_notifier(&lnw->iotg, &lnw->iotg_notifier); | ||
2131 | langwell_otg_free_timers(); | ||
2132 | |||
2133 | /* disable OTGSC interrupt as OTGSC doesn't change in reset */ | ||
2134 | writel(0, lnw->iotg.base + CI_OTGSC); | ||
2135 | |||
2136 | if (pdev->irq) | ||
2137 | free_irq(pdev->irq, lnw); | ||
2138 | if (lnw->usbcfg) | ||
2139 | iounmap(lnw->usbcfg); | ||
2140 | if (lnw->cfg_region) | ||
2141 | release_mem_region(USBCFG_ADDR, USBCFG_LEN); | ||
2142 | if (lnw->iotg.base) | ||
2143 | iounmap(lnw->iotg.base); | ||
2144 | if (lnw->region) | ||
2145 | release_mem_region(pci_resource_start(pdev, 0), | ||
2146 | pci_resource_len(pdev, 0)); | ||
2147 | |||
2148 | otg_set_transceiver(NULL); | ||
2149 | pci_disable_device(pdev); | ||
2150 | sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group); | ||
2151 | device_remove_file(&pdev->dev, &dev_attr_hsm); | ||
2152 | device_remove_file(&pdev->dev, &dev_attr_registers); | ||
2153 | kfree(lnw); | ||
2154 | lnw = NULL; | ||
2155 | } | ||
2156 | |||
2157 | static void transceiver_suspend(struct pci_dev *pdev) | ||
2158 | { | ||
2159 | pci_save_state(pdev); | ||
2160 | pci_set_power_state(pdev, PCI_D3hot); | ||
2161 | langwell_otg_phy_low_power(1); | ||
2162 | } | ||
2163 | |||
2164 | static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message) | ||
2165 | { | ||
2166 | struct langwell_otg *lnw = the_transceiver; | ||
2167 | struct intel_mid_otg_xceiv *iotg = &lnw->iotg; | ||
2168 | int ret = 0; | ||
2169 | |||
2170 | /* Disbale OTG interrupts */ | ||
2171 | langwell_otg_intr(0); | ||
2172 | |||
2173 | if (pdev->irq) | ||
2174 | free_irq(pdev->irq, lnw); | ||
2175 | |||
2176 | /* Prevent more otg_work */ | ||
2177 | flush_workqueue(lnw->qwork); | ||
2178 | destroy_workqueue(lnw->qwork); | ||
2179 | lnw->qwork = NULL; | ||
2180 | |||
2181 | /* start actions */ | ||
2182 | switch (iotg->otg.state) { | ||
2183 | case OTG_STATE_A_WAIT_VFALL: | ||
2184 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
2185 | case OTG_STATE_A_IDLE: | ||
2186 | case OTG_STATE_B_IDLE: | ||
2187 | case OTG_STATE_A_VBUS_ERR: | ||
2188 | transceiver_suspend(pdev); | ||
2189 | break; | ||
2190 | case OTG_STATE_A_WAIT_VRISE: | ||
2191 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
2192 | iotg->hsm.a_srp_det = 0; | ||
2193 | |||
2194 | /* Turn off VBus */ | ||
2195 | iotg->otg.set_vbus(&iotg->otg, false); | ||
2196 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
2197 | transceiver_suspend(pdev); | ||
2198 | break; | ||
2199 | case OTG_STATE_A_WAIT_BCON: | ||
2200 | del_timer_sync(&lnw->hsm_timer); | ||
2201 | if (lnw->iotg.stop_host) | ||
2202 | lnw->iotg.stop_host(&lnw->iotg); | ||
2203 | else | ||
2204 | dev_dbg(&pdev->dev, "host driver has been removed.\n"); | ||
2205 | |||
2206 | iotg->hsm.a_srp_det = 0; | ||
2207 | |||
2208 | /* Turn off VBus */ | ||
2209 | iotg->otg.set_vbus(&iotg->otg, false); | ||
2210 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
2211 | transceiver_suspend(pdev); | ||
2212 | break; | ||
2213 | case OTG_STATE_A_HOST: | ||
2214 | if (lnw->iotg.stop_host) | ||
2215 | lnw->iotg.stop_host(&lnw->iotg); | ||
2216 | else | ||
2217 | dev_dbg(&pdev->dev, "host driver has been removed.\n"); | ||
2218 | |||
2219 | iotg->hsm.a_srp_det = 0; | ||
2220 | |||
2221 | /* Turn off VBus */ | ||
2222 | iotg->otg.set_vbus(&iotg->otg, false); | ||
2223 | |||
2224 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
2225 | transceiver_suspend(pdev); | ||
2226 | break; | ||
2227 | case OTG_STATE_A_SUSPEND: | ||
2228 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
2229 | langwell_otg_HABA(0); | ||
2230 | if (lnw->iotg.stop_host) | ||
2231 | lnw->iotg.stop_host(&lnw->iotg); | ||
2232 | else | ||
2233 | dev_dbg(lnw->dev, "host driver has been removed.\n"); | ||
2234 | iotg->hsm.a_srp_det = 0; | ||
2235 | |||
2236 | /* Turn off VBus */ | ||
2237 | iotg->otg.set_vbus(&iotg->otg, false); | ||
2238 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
2239 | transceiver_suspend(pdev); | ||
2240 | break; | ||
2241 | case OTG_STATE_A_PERIPHERAL: | ||
2242 | del_timer_sync(&lnw->hsm_timer); | ||
2243 | |||
2244 | if (lnw->iotg.stop_peripheral) | ||
2245 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
2246 | else | ||
2247 | dev_dbg(&pdev->dev, | ||
2248 | "client driver has been removed.\n"); | ||
2249 | iotg->hsm.a_srp_det = 0; | ||
2250 | |||
2251 | /* Turn off VBus */ | ||
2252 | iotg->otg.set_vbus(&iotg->otg, false); | ||
2253 | iotg->otg.state = OTG_STATE_A_IDLE; | ||
2254 | transceiver_suspend(pdev); | ||
2255 | break; | ||
2256 | case OTG_STATE_B_HOST: | ||
2257 | if (lnw->iotg.stop_host) | ||
2258 | lnw->iotg.stop_host(&lnw->iotg); | ||
2259 | else | ||
2260 | dev_dbg(&pdev->dev, "host driver has been removed.\n"); | ||
2261 | iotg->hsm.b_bus_req = 0; | ||
2262 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
2263 | transceiver_suspend(pdev); | ||
2264 | break; | ||
2265 | case OTG_STATE_B_PERIPHERAL: | ||
2266 | if (lnw->iotg.stop_peripheral) | ||
2267 | lnw->iotg.stop_peripheral(&lnw->iotg); | ||
2268 | else | ||
2269 | dev_dbg(&pdev->dev, | ||
2270 | "client driver has been removed.\n"); | ||
2271 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
2272 | transceiver_suspend(pdev); | ||
2273 | break; | ||
2274 | case OTG_STATE_B_WAIT_ACON: | ||
2275 | /* delete hsm timer for b_ase0_brst_tmr */ | ||
2276 | del_timer_sync(&lnw->hsm_timer); | ||
2277 | |||
2278 | langwell_otg_HAAR(0); | ||
2279 | |||
2280 | if (lnw->iotg.stop_host) | ||
2281 | lnw->iotg.stop_host(&lnw->iotg); | ||
2282 | else | ||
2283 | dev_dbg(&pdev->dev, "host driver has been removed.\n"); | ||
2284 | iotg->hsm.b_bus_req = 0; | ||
2285 | iotg->otg.state = OTG_STATE_B_IDLE; | ||
2286 | transceiver_suspend(pdev); | ||
2287 | break; | ||
2288 | default: | ||
2289 | dev_dbg(lnw->dev, "error state before suspend\n"); | ||
2290 | break; | ||
2291 | } | ||
2292 | |||
2293 | return ret; | ||
2294 | } | ||
2295 | |||
2296 | static void transceiver_resume(struct pci_dev *pdev) | ||
2297 | { | ||
2298 | pci_restore_state(pdev); | ||
2299 | pci_set_power_state(pdev, PCI_D0); | ||
2300 | } | ||
2301 | |||
2302 | static int langwell_otg_resume(struct pci_dev *pdev) | ||
2303 | { | ||
2304 | struct langwell_otg *lnw = the_transceiver; | ||
2305 | int ret = 0; | ||
2306 | |||
2307 | transceiver_resume(pdev); | ||
2308 | |||
2309 | lnw->qwork = create_singlethread_workqueue("langwell_otg_queue"); | ||
2310 | if (!lnw->qwork) { | ||
2311 | dev_dbg(&pdev->dev, "cannot create langwell otg workqueuen"); | ||
2312 | ret = -ENOMEM; | ||
2313 | goto error; | ||
2314 | } | ||
2315 | |||
2316 | if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, | ||
2317 | driver_name, lnw) != 0) { | ||
2318 | dev_dbg(&pdev->dev, "request interrupt %d failed\n", pdev->irq); | ||
2319 | ret = -EBUSY; | ||
2320 | goto error; | ||
2321 | } | ||
2322 | |||
2323 | /* enable OTG interrupts */ | ||
2324 | langwell_otg_intr(1); | ||
2325 | |||
2326 | update_hsm(); | ||
2327 | |||
2328 | langwell_update_transceiver(); | ||
2329 | |||
2330 | return ret; | ||
2331 | error: | ||
2332 | langwell_otg_intr(0); | ||
2333 | transceiver_suspend(pdev); | ||
2334 | return ret; | ||
2335 | } | ||
2336 | |||
2337 | static int __init langwell_otg_init(void) | ||
2338 | { | ||
2339 | return pci_register_driver(&otg_pci_driver); | ||
2340 | } | ||
2341 | module_init(langwell_otg_init); | ||
2342 | |||
2343 | static void __exit langwell_otg_cleanup(void) | ||
2344 | { | ||
2345 | pci_unregister_driver(&otg_pci_driver); | ||
2346 | } | ||
2347 | module_exit(langwell_otg_cleanup); | ||
diff --git a/drivers/usb/otg/otg-wakelock.c b/drivers/usb/otg/otg-wakelock.c new file mode 100644 index 00000000000..2f11472dd2b --- /dev/null +++ b/drivers/usb/otg/otg-wakelock.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* | ||
2 | * otg-wakelock.c | ||
3 | * | ||
4 | * Copyright (C) 2011 Google, Inc. | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/notifier.h> | ||
20 | #include <linux/wakelock.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/usb/otg.h> | ||
23 | |||
24 | #define TEMPORARY_HOLD_TIME 2000 | ||
25 | |||
26 | static bool enabled = true; | ||
27 | static struct otg_transceiver *otgwl_xceiv; | ||
28 | static struct notifier_block otgwl_nb; | ||
29 | |||
30 | /* | ||
31 | * otgwl_spinlock is held while the VBUS lock is grabbed or dropped and the | ||
32 | * held field is updated to match. | ||
33 | */ | ||
34 | |||
35 | static DEFINE_SPINLOCK(otgwl_spinlock); | ||
36 | |||
37 | /* | ||
38 | * Only one lock, but since these 3 fields are associated with each other... | ||
39 | */ | ||
40 | |||
41 | struct otgwl_lock { | ||
42 | char name[40]; | ||
43 | struct wake_lock wakelock; | ||
44 | bool held; | ||
45 | }; | ||
46 | |||
47 | /* | ||
48 | * VBUS present lock. Also used as a timed lock on charger | ||
49 | * connect/disconnect and USB host disconnect, to allow the system | ||
50 | * to react to the change in power. | ||
51 | */ | ||
52 | |||
53 | static struct otgwl_lock vbus_lock; | ||
54 | |||
55 | static void otgwl_hold(struct otgwl_lock *lock) | ||
56 | { | ||
57 | if (!lock->held) { | ||
58 | wake_lock(&lock->wakelock); | ||
59 | lock->held = true; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | static void otgwl_temporary_hold(struct otgwl_lock *lock) | ||
64 | { | ||
65 | wake_lock_timeout(&lock->wakelock, | ||
66 | msecs_to_jiffies(TEMPORARY_HOLD_TIME)); | ||
67 | lock->held = false; | ||
68 | } | ||
69 | |||
70 | static void otgwl_drop(struct otgwl_lock *lock) | ||
71 | { | ||
72 | if (lock->held) { | ||
73 | wake_unlock(&lock->wakelock); | ||
74 | lock->held = false; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static void otgwl_handle_event(unsigned long event) | ||
79 | { | ||
80 | unsigned long irqflags; | ||
81 | |||
82 | spin_lock_irqsave(&otgwl_spinlock, irqflags); | ||
83 | |||
84 | if (!enabled) { | ||
85 | otgwl_drop(&vbus_lock); | ||
86 | spin_unlock_irqrestore(&otgwl_spinlock, irqflags); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | switch (event) { | ||
91 | case USB_EVENT_VBUS: | ||
92 | case USB_EVENT_ENUMERATED: | ||
93 | otgwl_hold(&vbus_lock); | ||
94 | break; | ||
95 | |||
96 | case USB_EVENT_NONE: | ||
97 | case USB_EVENT_ID: | ||
98 | case USB_EVENT_CHARGER: | ||
99 | otgwl_temporary_hold(&vbus_lock); | ||
100 | break; | ||
101 | |||
102 | default: | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | spin_unlock_irqrestore(&otgwl_spinlock, irqflags); | ||
107 | } | ||
108 | |||
109 | static int otgwl_otg_notifications(struct notifier_block *nb, | ||
110 | unsigned long event, void *unused) | ||
111 | { | ||
112 | otgwl_handle_event(event); | ||
113 | return NOTIFY_OK; | ||
114 | } | ||
115 | |||
116 | static int set_enabled(const char *val, const struct kernel_param *kp) | ||
117 | { | ||
118 | int rv = param_set_bool(val, kp); | ||
119 | |||
120 | if (rv) | ||
121 | return rv; | ||
122 | |||
123 | if (otgwl_xceiv) | ||
124 | otgwl_handle_event(otgwl_xceiv->last_event); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static struct kernel_param_ops enabled_param_ops = { | ||
130 | .set = set_enabled, | ||
131 | .get = param_get_bool, | ||
132 | }; | ||
133 | |||
134 | module_param_cb(enabled, &enabled_param_ops, &enabled, 0644); | ||
135 | MODULE_PARM_DESC(enabled, "enable wakelock when VBUS present"); | ||
136 | |||
137 | static int __init otg_wakelock_init(void) | ||
138 | { | ||
139 | int ret; | ||
140 | |||
141 | otgwl_xceiv = otg_get_transceiver(); | ||
142 | |||
143 | if (!otgwl_xceiv) { | ||
144 | pr_err("%s: No OTG transceiver found\n", __func__); | ||
145 | return -ENODEV; | ||
146 | } | ||
147 | |||
148 | snprintf(vbus_lock.name, sizeof(vbus_lock.name), "vbus-%s", | ||
149 | dev_name(otgwl_xceiv->dev)); | ||
150 | wake_lock_init(&vbus_lock.wakelock, WAKE_LOCK_SUSPEND, | ||
151 | vbus_lock.name); | ||
152 | |||
153 | otgwl_nb.notifier_call = otgwl_otg_notifications; | ||
154 | ret = otg_register_notifier(otgwl_xceiv, &otgwl_nb); | ||
155 | |||
156 | if (ret) { | ||
157 | pr_err("%s: otg_register_notifier on transceiver %s" | ||
158 | " failed\n", __func__, | ||
159 | dev_name(otgwl_xceiv->dev)); | ||
160 | otgwl_xceiv = NULL; | ||
161 | wake_lock_destroy(&vbus_lock.wakelock); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | otgwl_handle_event(otgwl_xceiv->last_event); | ||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | late_initcall(otg_wakelock_init); | ||
diff --git a/drivers/usb/otg/otg_id.c b/drivers/usb/otg/otg_id.c new file mode 100644 index 00000000000..8037edbf314 --- /dev/null +++ b/drivers/usb/otg/otg_id.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Google, Inc. | ||
3 | * | ||
4 | * Author: | ||
5 | * Colin Cross <ccross@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/kernel.h> | ||
19 | #include <linux/mutex.h> | ||
20 | #include <linux/notifier.h> | ||
21 | #include <linux/usb/otg_id.h> | ||
22 | |||
23 | static DEFINE_MUTEX(otg_id_lock); | ||
24 | static struct plist_head otg_id_plist = | ||
25 | PLIST_HEAD_INIT(otg_id_plist); | ||
26 | static struct otg_id_notifier_block *otg_id_active; | ||
27 | static bool otg_id_cancelling; | ||
28 | static bool otg_id_inited; | ||
29 | static int otg_id_suspended; | ||
30 | static bool otg_id_pending; | ||
31 | |||
32 | static void otg_id_cancel(void) | ||
33 | { | ||
34 | if (otg_id_active) { | ||
35 | otg_id_cancelling = true; | ||
36 | mutex_unlock(&otg_id_lock); | ||
37 | |||
38 | otg_id_active->cancel(otg_id_active); | ||
39 | |||
40 | mutex_lock(&otg_id_lock); | ||
41 | otg_id_cancelling = false; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | static void __otg_id_notify(void) | ||
46 | { | ||
47 | int ret; | ||
48 | struct otg_id_notifier_block *otg_id_nb; | ||
49 | bool proxy_wait = false; | ||
50 | if (plist_head_empty(&otg_id_plist)) | ||
51 | return; | ||
52 | |||
53 | plist_for_each_entry(otg_id_nb, &otg_id_plist, p) { | ||
54 | if (proxy_wait) { | ||
55 | if (otg_id_nb->proxy_wait) | ||
56 | ret = otg_id_nb->proxy_wait(otg_id_nb); | ||
57 | } else { | ||
58 | ret = otg_id_nb->detect(otg_id_nb); | ||
59 | } | ||
60 | if (ret == OTG_ID_HANDLED) { | ||
61 | otg_id_active = otg_id_nb; | ||
62 | return; | ||
63 | } | ||
64 | if (ret == OTG_ID_PROXY_WAIT) | ||
65 | proxy_wait = true; | ||
66 | |||
67 | } | ||
68 | |||
69 | WARN(1, "otg id event not handled"); | ||
70 | otg_id_active = NULL; | ||
71 | } | ||
72 | |||
73 | int otg_id_init(void) | ||
74 | { | ||
75 | mutex_lock(&otg_id_lock); | ||
76 | |||
77 | otg_id_inited = true; | ||
78 | __otg_id_notify(); | ||
79 | |||
80 | mutex_unlock(&otg_id_lock); | ||
81 | return 0; | ||
82 | } | ||
83 | late_initcall(otg_id_init); | ||
84 | |||
85 | /** | ||
86 | * otg_id_register_notifier | ||
87 | * @otg_id_nb: notifier block containing priority and callback function | ||
88 | * | ||
89 | * Register a notifier that will be called on any USB cable state change. | ||
90 | * The priority determines the order the callback will be called in, a higher | ||
91 | * number will be called first. A callback function needs to determine the | ||
92 | * type of USB cable that is connected. If it can determine the type, it | ||
93 | * should notify the appropriate drivers (for example, call an otg notifier | ||
94 | * with USB_EVENT_VBUS), and return OTG_ID_HANDLED. Once a callback has | ||
95 | * returned OTG_ID_HANDLED, it is responsible for calling otg_id_notify() when | ||
96 | * the detected USB cable is disconnected. | ||
97 | */ | ||
98 | int otg_id_register_notifier(struct otg_id_notifier_block *otg_id_nb) | ||
99 | { | ||
100 | plist_node_init(&otg_id_nb->p, otg_id_nb->priority); | ||
101 | |||
102 | mutex_lock(&otg_id_lock); | ||
103 | plist_add(&otg_id_nb->p, &otg_id_plist); | ||
104 | |||
105 | if (otg_id_inited) { | ||
106 | otg_id_cancel(); | ||
107 | __otg_id_notify(); | ||
108 | } | ||
109 | |||
110 | mutex_unlock(&otg_id_lock); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | void otg_id_unregister_notifier(struct otg_id_notifier_block *otg_id_nb) | ||
116 | { | ||
117 | mutex_lock(&otg_id_lock); | ||
118 | |||
119 | plist_del(&otg_id_nb->p, &otg_id_plist); | ||
120 | |||
121 | if (otg_id_inited && (otg_id_active == otg_id_nb)) { | ||
122 | otg_id_cancel(); | ||
123 | __otg_id_notify(); | ||
124 | } | ||
125 | |||
126 | mutex_unlock(&otg_id_lock); | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * otg_id_notify | ||
131 | * | ||
132 | * Notify listeners on any USB cable state change. | ||
133 | * | ||
134 | * A driver may only call otg_id_notify if it returned OTG_ID_HANDLED the last | ||
135 | * time it's notifier was called, and it's cancel function has not been called. | ||
136 | */ | ||
137 | void otg_id_notify(void) | ||
138 | { | ||
139 | mutex_lock(&otg_id_lock); | ||
140 | |||
141 | if (otg_id_cancelling) | ||
142 | goto out; | ||
143 | |||
144 | if (otg_id_suspended != 0) { | ||
145 | otg_id_pending = true; | ||
146 | goto out; | ||
147 | } | ||
148 | |||
149 | __otg_id_notify(); | ||
150 | out: | ||
151 | mutex_unlock(&otg_id_lock); | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * otg_id_suspend | ||
156 | * | ||
157 | * Mark the otg_id subsystem as going into suspend. From here on out, | ||
158 | * any notifications will be deferred until the last otg_id client resumes. | ||
159 | * If there is a pending notification when calling this function, it will | ||
160 | * return a negative errno and expects that the caller will abort suspend. | ||
161 | * Returs 0 on success. | ||
162 | */ | ||
163 | int otg_id_suspend(void) | ||
164 | { | ||
165 | int ret = 0; | ||
166 | |||
167 | mutex_lock(&otg_id_lock); | ||
168 | |||
169 | /* | ||
170 | * if there's a pending notification, tell the caller to abort suspend | ||
171 | */ | ||
172 | if (otg_id_suspended != 0 && otg_id_pending) { | ||
173 | pr_info("otg_id: pending notification, should abort suspend\n"); | ||
174 | ret = -EBUSY; | ||
175 | goto out; | ||
176 | } | ||
177 | |||
178 | otg_id_suspended++; | ||
179 | out: | ||
180 | mutex_unlock(&otg_id_lock); | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * otg_id_resume | ||
186 | * | ||
187 | * Inform the otg_id subsystem that a client is resuming. If this is the | ||
188 | * last client to be resumed and there's a pending notification, | ||
189 | * otg_id_notify() is called. | ||
190 | */ | ||
191 | void otg_id_resume(void) | ||
192 | { | ||
193 | mutex_lock(&otg_id_lock); | ||
194 | if (WARN(!otg_id_suspended, "unbalanced otg_id_resume\n")) | ||
195 | goto out; | ||
196 | if (--otg_id_suspended == 0) { | ||
197 | if (otg_id_pending) { | ||
198 | pr_info("otg_id: had pending notification\n"); | ||
199 | otg_id_pending = false; | ||
200 | __otg_id_notify(); | ||
201 | } | ||
202 | } | ||
203 | out: | ||
204 | mutex_unlock(&otg_id_lock); | ||
205 | } | ||
diff --git a/drivers/usb/otg/tegra-otg.c b/drivers/usb/otg/tegra-otg.c new file mode 100644 index 00000000000..4c04e6e183f --- /dev/null +++ b/drivers/usb/otg/tegra-otg.c | |||
@@ -0,0 +1,540 @@ | |||
1 | /* | ||
2 | * drivers/usb/otg/tegra-otg.c | ||
3 | * | ||
4 | * OTG transceiver driver for Tegra UTMI phy | ||
5 | * | ||
6 | * Copyright (C) 2010 NVIDIA Corp. | ||
7 | * Copyright (C) 2010 Google, Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/usb.h> | ||
25 | #include <linux/usb/otg.h> | ||
26 | #include <linux/usb/gadget.h> | ||
27 | #include <linux/usb/hcd.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/platform_data/tegra_usb.h> | ||
30 | #include <linux/clk.h> | ||
31 | #include <linux/io.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/err.h> | ||
34 | |||
35 | #define USB_PHY_WAKEUP 0x408 | ||
36 | #define USB_ID_INT_EN (1 << 0) | ||
37 | #define USB_ID_INT_STATUS (1 << 1) | ||
38 | #define USB_ID_STATUS (1 << 2) | ||
39 | #define USB_ID_PIN_WAKEUP_EN (1 << 6) | ||
40 | #define USB_VBUS_WAKEUP_EN (1 << 30) | ||
41 | #define USB_VBUS_INT_EN (1 << 8) | ||
42 | #define USB_VBUS_INT_STATUS (1 << 9) | ||
43 | #define USB_VBUS_STATUS (1 << 10) | ||
44 | #define USB_INTS (USB_VBUS_INT_STATUS | USB_ID_INT_STATUS) | ||
45 | |||
46 | typedef void (*callback_t)(enum usb_otg_state to, | ||
47 | enum usb_otg_state from, void *args); | ||
48 | |||
49 | struct tegra_otg_data { | ||
50 | struct otg_transceiver otg; | ||
51 | unsigned long int_status; | ||
52 | spinlock_t lock; | ||
53 | void __iomem *regs; | ||
54 | struct clk *clk; | ||
55 | int irq; | ||
56 | struct platform_device *pdev; | ||
57 | struct work_struct work; | ||
58 | unsigned int intr_reg_data; | ||
59 | bool detect_vbus; | ||
60 | bool clk_enabled; | ||
61 | callback_t charger_cb; | ||
62 | void *charger_cb_data; | ||
63 | |||
64 | }; | ||
65 | static struct tegra_otg_data *tegra_clone; | ||
66 | |||
67 | static inline unsigned long otg_readl(struct tegra_otg_data *tegra, | ||
68 | unsigned int offset) | ||
69 | { | ||
70 | return readl(tegra->regs + offset); | ||
71 | } | ||
72 | |||
73 | static inline void otg_writel(struct tegra_otg_data *tegra, unsigned long val, | ||
74 | unsigned int offset) | ||
75 | { | ||
76 | writel(val, tegra->regs + offset); | ||
77 | } | ||
78 | |||
79 | static void tegra_otg_enable_clk(void) | ||
80 | { | ||
81 | if (!tegra_clone->clk_enabled) | ||
82 | clk_enable(tegra_clone->clk); | ||
83 | tegra_clone->clk_enabled = true; | ||
84 | } | ||
85 | |||
86 | static void tegra_otg_disable_clk(void) | ||
87 | { | ||
88 | if (tegra_clone->clk_enabled) | ||
89 | clk_disable(tegra_clone->clk); | ||
90 | tegra_clone->clk_enabled = false; | ||
91 | } | ||
92 | |||
93 | static const char *tegra_state_name(enum usb_otg_state state) | ||
94 | { | ||
95 | switch (state) { | ||
96 | case OTG_STATE_A_HOST: | ||
97 | return "HOST"; | ||
98 | case OTG_STATE_B_PERIPHERAL: | ||
99 | return "PERIPHERAL"; | ||
100 | case OTG_STATE_A_SUSPEND: | ||
101 | return "SUSPEND"; | ||
102 | case OTG_STATE_UNDEFINED: | ||
103 | return "UNDEFINED"; | ||
104 | default: | ||
105 | return "INVALID"; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static struct platform_device * | ||
110 | tegra_usb_otg_host_register(struct platform_device *ehci_device, | ||
111 | struct tegra_ehci_platform_data *pdata) | ||
112 | { | ||
113 | struct platform_device *pdev; | ||
114 | void *platform_data; | ||
115 | int val; | ||
116 | |||
117 | pdev = platform_device_alloc(ehci_device->name, ehci_device->id); | ||
118 | if (!pdev) | ||
119 | return NULL; | ||
120 | |||
121 | val = platform_device_add_resources(pdev, ehci_device->resource, | ||
122 | ehci_device->num_resources); | ||
123 | if (val) | ||
124 | goto error; | ||
125 | |||
126 | pdev->dev.dma_mask = ehci_device->dev.dma_mask; | ||
127 | pdev->dev.coherent_dma_mask = ehci_device->dev.coherent_dma_mask; | ||
128 | |||
129 | platform_data = kmalloc(sizeof(struct tegra_ehci_platform_data), | ||
130 | GFP_KERNEL); | ||
131 | if (!platform_data) | ||
132 | goto error; | ||
133 | |||
134 | memcpy(platform_data, pdata, sizeof(struct tegra_ehci_platform_data)); | ||
135 | pdev->dev.platform_data = platform_data; | ||
136 | |||
137 | val = platform_device_add(pdev); | ||
138 | if (val) | ||
139 | goto error_add; | ||
140 | |||
141 | return pdev; | ||
142 | |||
143 | error_add: | ||
144 | kfree(platform_data); | ||
145 | error: | ||
146 | pr_err("%s: failed to add the host controller device\n", __func__); | ||
147 | platform_device_put(pdev); | ||
148 | return NULL; | ||
149 | } | ||
150 | |||
151 | static void tegra_usb_otg_host_unregister(struct platform_device *pdev) | ||
152 | { | ||
153 | kfree(pdev->dev.platform_data); | ||
154 | pdev->dev.platform_data = NULL; | ||
155 | platform_device_unregister(pdev); | ||
156 | } | ||
157 | |||
158 | void tegra_start_host(struct tegra_otg_data *tegra) | ||
159 | { | ||
160 | struct tegra_otg_platform_data *pdata = tegra->otg.dev->platform_data; | ||
161 | if (!tegra->pdev) { | ||
162 | tegra->pdev = tegra_usb_otg_host_register(pdata->ehci_device, | ||
163 | pdata->ehci_pdata); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | void tegra_stop_host(struct tegra_otg_data *tegra) | ||
168 | { | ||
169 | if (tegra->pdev) { | ||
170 | tegra_usb_otg_host_unregister(tegra->pdev); | ||
171 | tegra->pdev = NULL; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | int register_otg_callback(callback_t cb, void *args) | ||
176 | { | ||
177 | if (!tegra_clone) | ||
178 | return -ENODEV; | ||
179 | tegra_clone->charger_cb = cb; | ||
180 | tegra_clone->charger_cb_data = args; | ||
181 | return 0; | ||
182 | } | ||
183 | EXPORT_SYMBOL_GPL(register_otg_callback); | ||
184 | |||
185 | static void irq_work(struct work_struct *work) | ||
186 | { | ||
187 | struct tegra_otg_data *tegra = | ||
188 | container_of(work, struct tegra_otg_data, work); | ||
189 | struct otg_transceiver *otg = &tegra->otg; | ||
190 | enum usb_otg_state from = otg->state; | ||
191 | enum usb_otg_state to = OTG_STATE_UNDEFINED; | ||
192 | unsigned long flags; | ||
193 | unsigned long status; | ||
194 | |||
195 | if (tegra->detect_vbus) { | ||
196 | tegra->detect_vbus = false; | ||
197 | tegra_otg_enable_clk(); | ||
198 | return; | ||
199 | } | ||
200 | |||
201 | clk_enable(tegra->clk); | ||
202 | |||
203 | spin_lock_irqsave(&tegra->lock, flags); | ||
204 | |||
205 | status = tegra->int_status; | ||
206 | |||
207 | if (tegra->int_status & USB_ID_INT_STATUS) { | ||
208 | if (status & USB_ID_STATUS) { | ||
209 | if ((status & USB_VBUS_STATUS) && (from != OTG_STATE_A_HOST)) | ||
210 | to = OTG_STATE_B_PERIPHERAL; | ||
211 | else | ||
212 | to = OTG_STATE_A_SUSPEND; | ||
213 | } | ||
214 | else | ||
215 | to = OTG_STATE_A_HOST; | ||
216 | } | ||
217 | if (from != OTG_STATE_A_HOST) { | ||
218 | if (tegra->int_status & USB_VBUS_INT_STATUS) { | ||
219 | if (status & USB_VBUS_STATUS) | ||
220 | to = OTG_STATE_B_PERIPHERAL; | ||
221 | else | ||
222 | to = OTG_STATE_A_SUSPEND; | ||
223 | } | ||
224 | } | ||
225 | spin_unlock_irqrestore(&tegra->lock, flags); | ||
226 | |||
227 | if (to != OTG_STATE_UNDEFINED) { | ||
228 | otg->state = to; | ||
229 | |||
230 | dev_info(tegra->otg.dev, "%s --> %s\n", tegra_state_name(from), | ||
231 | tegra_state_name(to)); | ||
232 | |||
233 | if (tegra->charger_cb) | ||
234 | tegra->charger_cb(to, from, tegra->charger_cb_data); | ||
235 | |||
236 | if (to == OTG_STATE_A_SUSPEND) { | ||
237 | if (from == OTG_STATE_A_HOST) | ||
238 | tegra_stop_host(tegra); | ||
239 | else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget) | ||
240 | usb_gadget_vbus_disconnect(otg->gadget); | ||
241 | } else if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) { | ||
242 | if (from == OTG_STATE_A_SUSPEND) | ||
243 | usb_gadget_vbus_connect(otg->gadget); | ||
244 | } else if (to == OTG_STATE_A_HOST) { | ||
245 | if (from == OTG_STATE_A_SUSPEND) | ||
246 | tegra_start_host(tegra); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | |||
251 | clk_disable(tegra->clk); | ||
252 | tegra_otg_disable_clk(); | ||
253 | } | ||
254 | |||
255 | static irqreturn_t tegra_otg_irq(int irq, void *data) | ||
256 | { | ||
257 | struct tegra_otg_data *tegra = data; | ||
258 | unsigned long flags; | ||
259 | unsigned long val; | ||
260 | |||
261 | spin_lock_irqsave(&tegra->lock, flags); | ||
262 | |||
263 | val = otg_readl(tegra, USB_PHY_WAKEUP); | ||
264 | if (val & (USB_VBUS_INT_EN | USB_ID_INT_EN)) { | ||
265 | otg_writel(tegra, val, USB_PHY_WAKEUP); | ||
266 | if ((val & USB_ID_INT_STATUS) || (val & USB_VBUS_INT_STATUS)) { | ||
267 | tegra->int_status = val; | ||
268 | tegra->detect_vbus = false; | ||
269 | schedule_work(&tegra->work); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | spin_unlock_irqrestore(&tegra->lock, flags); | ||
274 | |||
275 | return IRQ_HANDLED; | ||
276 | } | ||
277 | |||
278 | void tegra_otg_check_vbus_detection(void) | ||
279 | { | ||
280 | tegra_clone->detect_vbus = true; | ||
281 | schedule_work(&tegra_clone->work); | ||
282 | } | ||
283 | EXPORT_SYMBOL(tegra_otg_check_vbus_detection); | ||
284 | |||
285 | static int tegra_otg_set_peripheral(struct otg_transceiver *otg, | ||
286 | struct usb_gadget *gadget) | ||
287 | { | ||
288 | struct tegra_otg_data *tegra; | ||
289 | unsigned long val; | ||
290 | |||
291 | tegra = container_of(otg, struct tegra_otg_data, otg); | ||
292 | otg->gadget = gadget; | ||
293 | |||
294 | clk_enable(tegra->clk); | ||
295 | val = otg_readl(tegra, USB_PHY_WAKEUP); | ||
296 | val |= (USB_VBUS_INT_EN | USB_VBUS_WAKEUP_EN); | ||
297 | val |= (USB_ID_INT_EN | USB_ID_PIN_WAKEUP_EN); | ||
298 | otg_writel(tegra, val, USB_PHY_WAKEUP); | ||
299 | /* Add delay to make sure register is updated */ | ||
300 | udelay(1); | ||
301 | clk_disable(tegra->clk); | ||
302 | |||
303 | if ((val & USB_ID_STATUS) && (val & USB_VBUS_STATUS)) { | ||
304 | val |= USB_VBUS_INT_STATUS; | ||
305 | } else if (!(val & USB_ID_STATUS)) { | ||
306 | val |= USB_ID_INT_STATUS; | ||
307 | } else { | ||
308 | val &= ~(USB_ID_INT_STATUS | USB_VBUS_INT_STATUS); | ||
309 | } | ||
310 | |||
311 | if ((val & USB_ID_INT_STATUS) || (val & USB_VBUS_INT_STATUS)) { | ||
312 | tegra->int_status = val; | ||
313 | tegra->detect_vbus = false; | ||
314 | schedule_work (&tegra->work); | ||
315 | } | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int tegra_otg_set_host(struct otg_transceiver *otg, | ||
321 | struct usb_bus *host) | ||
322 | { | ||
323 | struct tegra_otg_data *tegra; | ||
324 | unsigned long val; | ||
325 | |||
326 | tegra = container_of(otg, struct tegra_otg_data, otg); | ||
327 | otg->host = host; | ||
328 | |||
329 | clk_enable(tegra->clk); | ||
330 | val = otg_readl(tegra, USB_PHY_WAKEUP); | ||
331 | val &= ~(USB_VBUS_INT_STATUS | USB_ID_INT_STATUS); | ||
332 | |||
333 | val |= (USB_ID_INT_EN | USB_ID_PIN_WAKEUP_EN); | ||
334 | otg_writel(tegra, val, USB_PHY_WAKEUP); | ||
335 | clk_disable(tegra->clk); | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static int tegra_otg_set_power(struct otg_transceiver *otg, unsigned mA) | ||
341 | { | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int tegra_otg_set_suspend(struct otg_transceiver *otg, int suspend) | ||
346 | { | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int tegra_otg_probe(struct platform_device *pdev) | ||
351 | { | ||
352 | struct tegra_otg_data *tegra; | ||
353 | struct tegra_otg_platform_data *otg_pdata; | ||
354 | struct tegra_ehci_platform_data *ehci_pdata; | ||
355 | struct resource *res; | ||
356 | int err; | ||
357 | |||
358 | tegra = kzalloc(sizeof(struct tegra_otg_data), GFP_KERNEL); | ||
359 | if (!tegra) | ||
360 | return -ENOMEM; | ||
361 | |||
362 | tegra->otg.dev = &pdev->dev; | ||
363 | otg_pdata = tegra->otg.dev->platform_data; | ||
364 | ehci_pdata = otg_pdata->ehci_pdata; | ||
365 | tegra->otg.label = "tegra-otg"; | ||
366 | tegra->otg.state = OTG_STATE_UNDEFINED; | ||
367 | tegra->otg.set_host = tegra_otg_set_host; | ||
368 | tegra->otg.set_peripheral = tegra_otg_set_peripheral; | ||
369 | tegra->otg.set_suspend = tegra_otg_set_suspend; | ||
370 | tegra->otg.set_power = tegra_otg_set_power; | ||
371 | spin_lock_init(&tegra->lock); | ||
372 | |||
373 | platform_set_drvdata(pdev, tegra); | ||
374 | tegra_clone = tegra; | ||
375 | tegra->clk_enabled = false; | ||
376 | |||
377 | tegra->clk = clk_get(&pdev->dev, NULL); | ||
378 | if (IS_ERR(tegra->clk)) { | ||
379 | dev_err(&pdev->dev, "Can't get otg clock\n"); | ||
380 | err = PTR_ERR(tegra->clk); | ||
381 | goto err_clk; | ||
382 | } | ||
383 | |||
384 | err = clk_enable(tegra->clk); | ||
385 | if (err) | ||
386 | goto err_clken; | ||
387 | |||
388 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
389 | if (!res) { | ||
390 | dev_err(&pdev->dev, "Failed to get I/O memory\n"); | ||
391 | err = -ENXIO; | ||
392 | goto err_io; | ||
393 | } | ||
394 | tegra->regs = ioremap(res->start, resource_size(res)); | ||
395 | if (!tegra->regs) { | ||
396 | err = -ENOMEM; | ||
397 | goto err_io; | ||
398 | } | ||
399 | |||
400 | tegra->otg.state = OTG_STATE_A_SUSPEND; | ||
401 | |||
402 | err = otg_set_transceiver(&tegra->otg); | ||
403 | if (err) { | ||
404 | dev_err(&pdev->dev, "can't register transceiver (%d)\n", err); | ||
405 | goto err_otg; | ||
406 | } | ||
407 | |||
408 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
409 | if (!res) { | ||
410 | dev_err(&pdev->dev, "Failed to get IRQ\n"); | ||
411 | err = -ENXIO; | ||
412 | goto err_irq; | ||
413 | } | ||
414 | tegra->irq = res->start; | ||
415 | err = request_threaded_irq(tegra->irq, tegra_otg_irq, | ||
416 | NULL, | ||
417 | IRQF_SHARED, "tegra-otg", tegra); | ||
418 | if (err) { | ||
419 | dev_err(&pdev->dev, "Failed to register IRQ\n"); | ||
420 | goto err_irq; | ||
421 | } | ||
422 | INIT_WORK (&tegra->work, irq_work); | ||
423 | |||
424 | if (!ehci_pdata->default_enable) | ||
425 | clk_disable(tegra->clk); | ||
426 | dev_info(&pdev->dev, "otg transceiver registered\n"); | ||
427 | return 0; | ||
428 | |||
429 | err_irq: | ||
430 | otg_set_transceiver(NULL); | ||
431 | err_otg: | ||
432 | iounmap(tegra->regs); | ||
433 | err_io: | ||
434 | clk_disable(tegra->clk); | ||
435 | err_clken: | ||
436 | clk_put(tegra->clk); | ||
437 | err_clk: | ||
438 | platform_set_drvdata(pdev, NULL); | ||
439 | kfree(tegra); | ||
440 | return err; | ||
441 | } | ||
442 | |||
443 | static int __exit tegra_otg_remove(struct platform_device *pdev) | ||
444 | { | ||
445 | struct tegra_otg_data *tegra = platform_get_drvdata(pdev); | ||
446 | |||
447 | free_irq(tegra->irq, tegra); | ||
448 | otg_set_transceiver(NULL); | ||
449 | iounmap(tegra->regs); | ||
450 | clk_disable(tegra->clk); | ||
451 | clk_put(tegra->clk); | ||
452 | platform_set_drvdata(pdev, NULL); | ||
453 | kfree(tegra); | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | #ifdef CONFIG_PM | ||
459 | static int tegra_otg_suspend(struct device *dev) | ||
460 | { | ||
461 | struct platform_device *pdev = to_platform_device(dev); | ||
462 | struct tegra_otg_data *tegra_otg = platform_get_drvdata(pdev); | ||
463 | struct otg_transceiver *otg = &tegra_otg->otg; | ||
464 | enum usb_otg_state from = otg->state; | ||
465 | /* store the interupt enable for cable ID and VBUS */ | ||
466 | clk_enable(tegra_otg->clk); | ||
467 | tegra_otg->intr_reg_data = readl(tegra_otg->regs + USB_PHY_WAKEUP); | ||
468 | writel(0, (tegra_otg->regs + USB_PHY_WAKEUP)); | ||
469 | clk_disable(tegra_otg->clk); | ||
470 | |||
471 | if (from == OTG_STATE_B_PERIPHERAL && otg->gadget) { | ||
472 | usb_gadget_vbus_disconnect(otg->gadget); | ||
473 | otg->state = OTG_STATE_A_SUSPEND; | ||
474 | } | ||
475 | tegra_otg_disable_clk(); | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static void tegra_otg_resume(struct device *dev) | ||
480 | { | ||
481 | struct platform_device *pdev = to_platform_device(dev); | ||
482 | struct tegra_otg_data *tegra_otg = platform_get_drvdata(pdev); | ||
483 | int val; | ||
484 | unsigned long flags; | ||
485 | |||
486 | tegra_otg_enable_clk(); | ||
487 | |||
488 | /* Following delay is intentional. | ||
489 | * It is placed here after observing system hang. | ||
490 | * Root cause is not confirmed. | ||
491 | */ | ||
492 | msleep(1); | ||
493 | /* restore the interupt enable for cable ID and VBUS */ | ||
494 | clk_enable(tegra_otg->clk); | ||
495 | writel(tegra_otg->intr_reg_data, (tegra_otg->regs + USB_PHY_WAKEUP)); | ||
496 | val = readl(tegra_otg->regs + USB_PHY_WAKEUP); | ||
497 | clk_disable(tegra_otg->clk); | ||
498 | |||
499 | /* A device might be connected while CPU is in sleep mode. In this case no interrupt | ||
500 | * will be triggered | ||
501 | * force irq_work to recheck connected devices | ||
502 | */ | ||
503 | if (!(val & USB_ID_STATUS)) { | ||
504 | spin_lock_irqsave(&tegra_otg->lock, flags); | ||
505 | tegra_otg->int_status = (val | USB_ID_INT_STATUS ); | ||
506 | schedule_work(&tegra_otg->work); | ||
507 | spin_unlock_irqrestore(&tegra_otg->lock, flags); | ||
508 | } | ||
509 | |||
510 | return; | ||
511 | } | ||
512 | |||
513 | static const struct dev_pm_ops tegra_otg_pm_ops = { | ||
514 | .complete = tegra_otg_resume, | ||
515 | .suspend = tegra_otg_suspend, | ||
516 | }; | ||
517 | #endif | ||
518 | |||
519 | static struct platform_driver tegra_otg_driver = { | ||
520 | .driver = { | ||
521 | .name = "tegra-otg", | ||
522 | #ifdef CONFIG_PM | ||
523 | .pm = &tegra_otg_pm_ops, | ||
524 | #endif | ||
525 | }, | ||
526 | .remove = __exit_p(tegra_otg_remove), | ||
527 | .probe = tegra_otg_probe, | ||
528 | }; | ||
529 | |||
530 | static int __init tegra_otg_init(void) | ||
531 | { | ||
532 | return platform_driver_register(&tegra_otg_driver); | ||
533 | } | ||
534 | subsys_initcall(tegra_otg_init); | ||
535 | |||
536 | static void __exit tegra_otg_exit(void) | ||
537 | { | ||
538 | platform_driver_unregister(&tegra_otg_driver); | ||
539 | } | ||
540 | module_exit(tegra_otg_exit); | ||
diff --git a/drivers/usb/serial/ChangeLog.history b/drivers/usb/serial/ChangeLog.history new file mode 100644 index 00000000000..f13fd488ebe --- /dev/null +++ b/drivers/usb/serial/ChangeLog.history | |||
@@ -0,0 +1,730 @@ | |||
1 | This is the contents of some of the drivers/usb/serial/ files that had old | ||
2 | changelog comments. They were quite old, and out of date, and we don't keep | ||
3 | them anymore, so I've put them here, away from the source files, in case | ||
4 | people still care to see them. | ||
5 | |||
6 | - Greg Kroah-Hartman <greg@kroah.com> October 20, 2005 | ||
7 | |||
8 | ----------------------------------------------------------------------- | ||
9 | usb-serial.h Change Log comments: | ||
10 | |||
11 | (03/26/2002) gkh | ||
12 | removed the port->tty check from port_paranoia_check() due to serial | ||
13 | consoles not having a tty device assigned to them. | ||
14 | |||
15 | (12/03/2001) gkh | ||
16 | removed active from the port structure. | ||
17 | added documentation to the usb_serial_device_type structure | ||
18 | |||
19 | (10/10/2001) gkh | ||
20 | added vendor and product to serial structure. Needed to determine device | ||
21 | owner when the device is disconnected. | ||
22 | |||
23 | (05/30/2001) gkh | ||
24 | added sem to port structure and removed port_lock | ||
25 | |||
26 | (10/05/2000) gkh | ||
27 | Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help | ||
28 | fix bug with urb->dev not being set properly, now that the usb core | ||
29 | needs it. | ||
30 | |||
31 | (09/11/2000) gkh | ||
32 | Added usb_serial_debug_data function to help get rid of #DEBUG in the | ||
33 | drivers. | ||
34 | |||
35 | (08/28/2000) gkh | ||
36 | Added port_lock to port structure. | ||
37 | |||
38 | (08/08/2000) gkh | ||
39 | Added open_count to port structure. | ||
40 | |||
41 | (07/23/2000) gkh | ||
42 | Added bulk_out_endpointAddress to port structure. | ||
43 | |||
44 | (07/19/2000) gkh, pberger, and borchers | ||
45 | Modifications to allow usb-serial drivers to be modules. | ||
46 | |||
47 | ----------------------------------------------------------------------- | ||
48 | usb-serial.c Change Log comments: | ||
49 | |||
50 | (12/10/2002) gkh | ||
51 | Split the ports off into their own struct device, and added a | ||
52 | usb-serial bus driver. | ||
53 | |||
54 | (11/19/2002) gkh | ||
55 | removed a few #ifdefs for the generic code and cleaned up the failure | ||
56 | logic in initialization. | ||
57 | |||
58 | (10/02/2002) gkh | ||
59 | moved the console code to console.c and out of this file. | ||
60 | |||
61 | (06/05/2002) gkh | ||
62 | moved location of startup() call in serial_probe() until after all | ||
63 | of the port information and endpoints are initialized. This makes | ||
64 | things easier for some drivers. | ||
65 | |||
66 | (04/10/2002) gkh | ||
67 | added serial_read_proc function which creates a | ||
68 | /proc/tty/driver/usb-serial file. | ||
69 | |||
70 | (03/27/2002) gkh | ||
71 | Got USB serial console code working properly and merged into the main | ||
72 | version of the tree. Thanks to Randy Dunlap for the initial version | ||
73 | of this code, and for pushing me to finish it up. | ||
74 | The USB serial console works with any usb serial driver device. | ||
75 | |||
76 | (03/21/2002) gkh | ||
77 | Moved all manipulation of port->open_count into the core. Now the | ||
78 | individual driver's open and close functions are called only when the | ||
79 | first open() and last close() is called. Making the drivers a bit | ||
80 | smaller and simpler. | ||
81 | Fixed a bug if a driver didn't have the owner field set. | ||
82 | |||
83 | (02/26/2002) gkh | ||
84 | Moved all locking into the main serial_* functions, instead of having | ||
85 | the individual drivers have to grab the port semaphore. This should | ||
86 | reduce races. | ||
87 | Reworked the MOD_INC logic a bit to always increment and decrement, even | ||
88 | if the generic driver is being used. | ||
89 | |||
90 | (10/10/2001) gkh | ||
91 | usb_serial_disconnect() now sets the serial->dev pointer is to NULL to | ||
92 | help prevent child drivers from accessing the device since it is now | ||
93 | gone. | ||
94 | |||
95 | (09/13/2001) gkh | ||
96 | Moved generic driver initialize after we have registered with the USB | ||
97 | core. Thanks to Randy Dunlap for pointing this problem out. | ||
98 | |||
99 | (07/03/2001) gkh | ||
100 | Fixed module paramater size. Thanks to John Brockmeyer for the pointer. | ||
101 | Fixed vendor and product getting defined through the MODULE_PARM macro | ||
102 | if the Generic driver wasn't compiled in. | ||
103 | Fixed problem with generic_shutdown() not being called for drivers that | ||
104 | don't have a shutdown() function. | ||
105 | |||
106 | (06/06/2001) gkh | ||
107 | added evil hack that is needed for the prolific pl2303 device due to the | ||
108 | crazy way its endpoints are set up. | ||
109 | |||
110 | (05/30/2001) gkh | ||
111 | switched from using spinlock to a semaphore, which fixes lots of problems. | ||
112 | |||
113 | (04/08/2001) gb | ||
114 | Identify version on module load. | ||
115 | |||
116 | 2001_02_05 gkh | ||
117 | Fixed buffer overflows bug with the generic serial driver. Thanks to | ||
118 | Todd Squires <squirest@ct0.com> for fixing this. | ||
119 | |||
120 | (01/10/2001) gkh | ||
121 | Fixed bug where the generic serial adaptor grabbed _any_ device that was | ||
122 | offered to it. | ||
123 | |||
124 | (12/12/2000) gkh | ||
125 | Removed MOD_INC and MOD_DEC from poll and disconnect functions, and | ||
126 | moved them to the serial_open and serial_close functions. | ||
127 | Also fixed bug with there not being a MOD_DEC for the generic driver | ||
128 | (thanks to Gary Brubaker for finding this.) | ||
129 | |||
130 | (11/29/2000) gkh | ||
131 | Small NULL pointer initialization cleanup which saves a bit of disk image | ||
132 | |||
133 | (11/01/2000) Adam J. Richter | ||
134 | instead of using idVendor/idProduct pairs, usb serial drivers | ||
135 | now identify their hardware interest with usb_device_id tables, | ||
136 | which they usually have anyhow for use with MODULE_DEVICE_TABLE. | ||
137 | |||
138 | (10/05/2000) gkh | ||
139 | Fixed bug with urb->dev not being set properly, now that the usb | ||
140 | core needs it. | ||
141 | |||
142 | (09/11/2000) gkh | ||
143 | Removed DEBUG #ifdefs with call to usb_serial_debug_data | ||
144 | |||
145 | (08/28/2000) gkh | ||
146 | Added port_lock to port structure. | ||
147 | Added locks for SMP safeness to generic driver | ||
148 | Fixed the ability to open a generic device's port more than once. | ||
149 | |||
150 | (07/23/2000) gkh | ||
151 | Added bulk_out_endpointAddress to port structure. | ||
152 | |||
153 | (07/19/2000) gkh, pberger, and borchers | ||
154 | Modifications to allow usb-serial drivers to be modules. | ||
155 | |||
156 | (07/03/2000) gkh | ||
157 | Added more debugging to serial_ioctl call | ||
158 | |||
159 | (06/25/2000) gkh | ||
160 | Changed generic_write_bulk_callback to not call wake_up_interruptible | ||
161 | directly, but to have port_softint do it at a safer time. | ||
162 | |||
163 | (06/23/2000) gkh | ||
164 | Cleaned up debugging statements in a quest to find UHCI timeout bug. | ||
165 | |||
166 | (05/22/2000) gkh | ||
167 | Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be | ||
168 | removed from the individual device source files. | ||
169 | |||
170 | (05/03/2000) gkh | ||
171 | Added the Digi Acceleport driver from Al Borchers and Peter Berger. | ||
172 | |||
173 | (05/02/2000) gkh | ||
174 | Changed devfs and tty register code to work properly now. This was based on | ||
175 | the ACM driver changes by Vojtech Pavlik. | ||
176 | |||
177 | (04/27/2000) Ryan VanderBijl | ||
178 | Put calls to *_paranoia_checks into one function. | ||
179 | |||
180 | (04/23/2000) gkh | ||
181 | Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports. | ||
182 | Moved when the startup code printed out the devices that are supported. | ||
183 | |||
184 | (04/19/2000) gkh | ||
185 | Added driver for ZyXEL omni.net lcd plus ISDN TA | ||
186 | Made startup info message specify which drivers were compiled in. | ||
187 | |||
188 | (04/03/2000) gkh | ||
189 | Changed the probe process to remove the module unload races. | ||
190 | Changed where the tty layer gets initialized to have devfs work nicer. | ||
191 | Added initial devfs support. | ||
192 | |||
193 | (03/26/2000) gkh | ||
194 | Split driver up into device specific pieces. | ||
195 | |||
196 | (03/19/2000) gkh | ||
197 | Fixed oops that could happen when device was removed while a program | ||
198 | was talking to the device. | ||
199 | Removed the static urbs and now all urbs are created and destroyed | ||
200 | dynamically. | ||
201 | Reworked the internal interface. Now everything is based on the | ||
202 | usb_serial_port structure instead of the larger usb_serial structure. | ||
203 | This fixes the bug that a multiport device could not have more than | ||
204 | one port open at one time. | ||
205 | |||
206 | (03/17/2000) gkh | ||
207 | Added config option for debugging messages. | ||
208 | Added patch for keyspan pda from Brian Warner. | ||
209 | |||
210 | (03/06/2000) gkh | ||
211 | Added the keyspan pda code from Brian Warner <warner@lothar.com> | ||
212 | Moved a bunch of the port specific stuff into its own structure. This | ||
213 | is in anticipation of the true multiport devices (there's a bug if you | ||
214 | try to access more than one port of any multiport device right now) | ||
215 | |||
216 | (02/21/2000) gkh | ||
217 | Made it so that any serial devices only have to specify which functions | ||
218 | they want to overload from the generic function calls (great, | ||
219 | inheritance in C, in a driver, just what I wanted...) | ||
220 | Added support for set_termios and ioctl function calls. No drivers take | ||
221 | advantage of this yet. | ||
222 | Removed the #ifdef MODULE, now there is no module specific code. | ||
223 | Cleaned up a few comments in usb-serial.h that were wrong (thanks again | ||
224 | to Miles Lott). | ||
225 | Small fix to get_free_serial. | ||
226 | |||
227 | (02/14/2000) gkh | ||
228 | Removed the Belkin and Peracom functionality from the driver due to | ||
229 | the lack of support from the vendor, and me not wanting people to | ||
230 | accidenatly buy the device, expecting it to work with Linux. | ||
231 | Added read_bulk_callback and write_bulk_callback to the type structure | ||
232 | for the needs of the FTDI and WhiteHEAT driver. | ||
233 | Changed all reverences to FTDI to FTDI_SIO at the request of Bill | ||
234 | Ryder. | ||
235 | Changed the output urb size back to the max endpoint size to make | ||
236 | the ftdi_sio driver have it easier, and due to the fact that it didn't | ||
237 | really increase the speed any. | ||
238 | |||
239 | (02/11/2000) gkh | ||
240 | Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a | ||
241 | patch from Miles Lott (milos@insync.net). | ||
242 | Fixed bug with not restoring the minor range that a device grabs, if | ||
243 | the startup function fails (thanks Miles for finding this). | ||
244 | |||
245 | (02/05/2000) gkh | ||
246 | Added initial framework for the Keyspan PDA serial converter so that | ||
247 | Brian Warner has a place to put his code. | ||
248 | Made the ezusb specific functions generic enough that different | ||
249 | devices can use them (whiteheat and keyspan_pda both need them). | ||
250 | Split out a whole bunch of structure and other stuff to a separate | ||
251 | usb-serial.h file. | ||
252 | Made the Visor connection messages a little more understandable, now | ||
253 | that Miles Lott (milos@insync.net) has gotten the Generic channel to | ||
254 | work. Also made them always show up in the log file. | ||
255 | |||
256 | (01/25/2000) gkh | ||
257 | Added initial framework for FTDI serial converter so that Bill Ryder | ||
258 | has a place to put his code. | ||
259 | Added the vendor specific info from Handspring. Now we can print out | ||
260 | informational debug messages as well as understand what is happening. | ||
261 | |||
262 | (01/23/2000) gkh | ||
263 | Fixed problem of crash when trying to open a port that didn't have a | ||
264 | device assigned to it. Made the minor node finding a little smarter, | ||
265 | now it looks to find a continuous space for the new device. | ||
266 | |||
267 | (01/21/2000) gkh | ||
268 | Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net) | ||
269 | Fixed get_serial_by_minor which was all messed up for multi port | ||
270 | devices. Fixed multi port problem for generic devices. Now the number | ||
271 | of ports is determined by the number of bulk out endpoints for the | ||
272 | generic device. | ||
273 | |||
274 | (01/19/2000) gkh | ||
275 | Removed lots of cruft that was around from the old (pre urb) driver | ||
276 | interface. | ||
277 | Made the serial_table dynamic. This should save lots of memory when | ||
278 | the number of minor nodes goes up to 256. | ||
279 | Added initial support for devices that have more than one port. | ||
280 | Added more debugging comments for the Visor, and added a needed | ||
281 | set_configuration call. | ||
282 | |||
283 | (01/17/2000) gkh | ||
284 | Fixed the WhiteHEAT firmware (my processing tool had a bug) | ||
285 | and added new debug loader firmware for it. | ||
286 | Removed the put_char function as it isn't really needed. | ||
287 | Added visor startup commands as found by the Win98 dump. | ||
288 | |||
289 | (01/13/2000) gkh | ||
290 | Fixed the vendor id for the generic driver to the one I meant it to be. | ||
291 | |||
292 | (01/12/2000) gkh | ||
293 | Forget the version numbering...that's pretty useless... | ||
294 | Made the driver able to be compiled so that the user can select which | ||
295 | converter they want to use. This allows people who only want the Visor | ||
296 | support to not pay the memory size price of the WhiteHEAT. | ||
297 | Fixed bug where the generic driver (idVendor=0000 and idProduct=0000) | ||
298 | grabbed the root hub. Not good. | ||
299 | |||
300 | version 0.4.0 (01/10/2000) gkh | ||
301 | Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT | ||
302 | device. Added startup function to allow firmware to be downloaded to | ||
303 | a device if it needs to be. | ||
304 | Added firmware download logic to the WhiteHEAT device. | ||
305 | Started to add #defines to split up the different drivers for potential | ||
306 | configuration option. | ||
307 | |||
308 | version 0.3.1 (12/30/99) gkh | ||
309 | Fixed problems with urb for bulk out. | ||
310 | Added initial support for multiple sets of endpoints. This enables | ||
311 | the Handspring Visor to be attached successfully. Only the first | ||
312 | bulk in / bulk out endpoint pair is being used right now. | ||
313 | |||
314 | version 0.3.0 (12/27/99) gkh | ||
315 | Added initial support for the Handspring Visor based on a patch from | ||
316 | Miles Lott (milos@sneety.insync.net) | ||
317 | Cleaned up the code a bunch and converted over to using urbs only. | ||
318 | |||
319 | version 0.2.3 (12/21/99) gkh | ||
320 | Added initial support for the Connect Tech WhiteHEAT converter. | ||
321 | Incremented the number of ports in expectation of getting the | ||
322 | WhiteHEAT to work properly (4 ports per connection). | ||
323 | Added notification on insertion and removal of what port the | ||
324 | device is/was connected to (and what kind of device it was). | ||
325 | |||
326 | version 0.2.2 (12/16/99) gkh | ||
327 | Changed major number to the new allocated number. We're legal now! | ||
328 | |||
329 | version 0.2.1 (12/14/99) gkh | ||
330 | Fixed bug that happens when device node is opened when there isn't a | ||
331 | device attached to it. Thanks to marek@webdesign.no for noticing this. | ||
332 | |||
333 | version 0.2.0 (11/10/99) gkh | ||
334 | Split up internals to make it easier to add different types of serial | ||
335 | converters to the code. | ||
336 | Added a "generic" driver that gets it's vendor and product id | ||
337 | from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net) | ||
338 | for the idea and sample code (from the usb scanner driver.) | ||
339 | Cleared up any licensing questions by releasing it under the GNU GPL. | ||
340 | |||
341 | version 0.1.2 (10/25/99) gkh | ||
342 | Fixed bug in detecting device. | ||
343 | |||
344 | version 0.1.1 (10/05/99) gkh | ||
345 | Changed the major number to not conflict with anything else. | ||
346 | |||
347 | version 0.1 (09/28/99) gkh | ||
348 | Can recognize the two different devices and start up a read from | ||
349 | device when asked to. Writes also work. No control signals yet, this | ||
350 | all is vendor specific data (i.e. no spec), also no control for | ||
351 | different baud rates or other bit settings. | ||
352 | Currently we are using the same devid as the acm driver. This needs | ||
353 | to change. | ||
354 | |||
355 | ----------------------------------------------------------------------- | ||
356 | visor.c Change Log comments: | ||
357 | |||
358 | (06/03/2003) Judd Montgomery <judd at jpilot.org> | ||
359 | Added support for module parameter options for untested/unknown | ||
360 | devices. | ||
361 | |||
362 | (03/09/2003) gkh | ||
363 | Added support for the Sony Clie NZ90V device. Thanks to Martin Brachtl | ||
364 | <brachtl@redgrep.cz> for the information. | ||
365 | |||
366 | (03/05/2003) gkh | ||
367 | Think Treo support is now working. | ||
368 | |||
369 | (04/03/2002) gkh | ||
370 | Added support for the Sony OS 4.1 devices. Thanks to Hiroyuki ARAKI | ||
371 | <hiro@zob.ne.jp> for the information. | ||
372 | |||
373 | (03/27/2002) gkh | ||
374 | Removed assumptions that port->tty was always valid (is not true | ||
375 | for usb serial console devices.) | ||
376 | |||
377 | (03/23/2002) gkh | ||
378 | Added support for the Palm i705 device, thanks to Thomas Riemer | ||
379 | <tom@netmech.com> for the information. | ||
380 | |||
381 | (03/21/2002) gkh | ||
382 | Added support for the Palm m130 device, thanks to Udo Eisenbarth | ||
383 | <udo.eisenbarth@web.de> for the information. | ||
384 | |||
385 | (02/27/2002) gkh | ||
386 | Reworked the urb handling logic. We have no more pool, but dynamically | ||
387 | allocate the urb and the transfer buffer on the fly. In testing this | ||
388 | does not incure any measurable overhead. This also relies on the fact | ||
389 | that we have proper reference counting logic for urbs. | ||
390 | |||
391 | (02/21/2002) SilaS | ||
392 | Added initial support for the Palm m515 devices. | ||
393 | |||
394 | (02/14/2002) gkh | ||
395 | Added support for the Clie S-360 device. | ||
396 | |||
397 | (12/18/2001) gkh | ||
398 | Added better Clie support for 3.5 devices. Thanks to Geoffrey Levand | ||
399 | for the patch. | ||
400 | |||
401 | (11/11/2001) gkh | ||
402 | Added support for the m125 devices, and added check to prevent oopses | ||
403 | for Clié devices that lie about the number of ports they have. | ||
404 | |||
405 | (08/30/2001) gkh | ||
406 | Added support for the Clie devices, both the 3.5 and 4.0 os versions. | ||
407 | Many thanks to Daniel Burke, and Bryan Payne for helping with this. | ||
408 | |||
409 | (08/23/2001) gkh | ||
410 | fixed a few potential bugs pointed out by Oliver Neukum. | ||
411 | |||
412 | (05/30/2001) gkh | ||
413 | switched from using spinlock to a semaphore, which fixes lots of problems. | ||
414 | |||
415 | (05/28/2000) gkh | ||
416 | Added initial support for the Palm m500 and Palm m505 devices. | ||
417 | |||
418 | (04/08/2001) gb | ||
419 | Identify version on module load. | ||
420 | |||
421 | (01/21/2000) gkh | ||
422 | Added write_room and chars_in_buffer, as they were previously using the | ||
423 | generic driver versions which is all wrong now that we are using an urb | ||
424 | pool. Thanks to Wolfgang Grandegger for pointing this out to me. | ||
425 | Removed count assignment in the write function, which was not needed anymore | ||
426 | either. Thanks to Al Borchers for pointing this out. | ||
427 | |||
428 | (12/12/2000) gkh | ||
429 | Moved MOD_DEC to end of visor_close to be nicer, as the final write | ||
430 | message can sleep. | ||
431 | |||
432 | (11/12/2000) gkh | ||
433 | Fixed bug with data being dropped on the floor by forcing tty->low_latency | ||
434 | to be on. Hopefully this fixes the OHCI issue! | ||
435 | |||
436 | (11/01/2000) Adam J. Richter | ||
437 | usb_device_id table support | ||
438 | |||
439 | (10/05/2000) gkh | ||
440 | Fixed bug with urb->dev not being set properly, now that the usb | ||
441 | core needs it. | ||
442 | |||
443 | (09/11/2000) gkh | ||
444 | Got rid of always calling kmalloc for every urb we wrote out to the | ||
445 | device. | ||
446 | Added visor_read_callback so we can keep track of bytes in and out for | ||
447 | those people who like to know the speed of their device. | ||
448 | Removed DEBUG #ifdefs with call to usb_serial_debug_data | ||
449 | |||
450 | (09/06/2000) gkh | ||
451 | Fixed oops in visor_exit. Need to uncomment usb_unlink_urb call _after_ | ||
452 | the host controller drivers set urb->dev = NULL when the urb is finished. | ||
453 | |||
454 | (08/28/2000) gkh | ||
455 | Added locks for SMP safeness. | ||
456 | |||
457 | (08/08/2000) gkh | ||
458 | Fixed endian problem in visor_startup. | ||
459 | Fixed MOD_INC and MOD_DEC logic and the ability to open a port more | ||
460 | than once. | ||
461 | |||
462 | (07/23/2000) gkh | ||
463 | Added pool of write urbs to speed up transfers to the visor. | ||
464 | |||
465 | (07/19/2000) gkh | ||
466 | Added module_init and module_exit functions to handle the fact that this | ||
467 | driver is a loadable module now. | ||
468 | |||
469 | (07/03/2000) gkh | ||
470 | Added visor_set_ioctl and visor_set_termios functions (they don't do much | ||
471 | of anything, but are good for debugging.) | ||
472 | |||
473 | (06/25/2000) gkh | ||
474 | Fixed bug in visor_unthrottle that should help with the disconnect in PPP | ||
475 | bug that people have been reporting. | ||
476 | |||
477 | (06/23/2000) gkh | ||
478 | Cleaned up debugging statements in a quest to find UHCI timeout bug. | ||
479 | |||
480 | (04/27/2000) Ryan VanderBijl | ||
481 | Fixed memory leak in visor_close | ||
482 | |||
483 | (03/26/2000) gkh | ||
484 | Split driver up into device specific pieces. | ||
485 | |||
486 | ----------------------------------------------------------------------- | ||
487 | pl2303.c Change Log comments: | ||
488 | |||
489 | 2002_Mar_26 gkh | ||
490 | allowed driver to work properly if there is no tty assigned to a port | ||
491 | (this happens for serial console devices.) | ||
492 | |||
493 | 2001_Oct_06 gkh | ||
494 | Added RTS and DTR line control. Thanks to joe@bndlg.de for parts of it. | ||
495 | |||
496 | 2001_Sep_19 gkh | ||
497 | Added break support. | ||
498 | |||
499 | 2001_Aug_30 gkh | ||
500 | fixed oops in write_bulk_callback. | ||
501 | |||
502 | 2001_Aug_28 gkh | ||
503 | reworked buffer logic to be like other usb-serial drivers. Hopefully | ||
504 | removing some reported problems. | ||
505 | |||
506 | 2001_Jun_06 gkh | ||
507 | finished porting to 2.4 format. | ||
508 | |||
509 | |||
510 | ----------------------------------------------------------------------- | ||
511 | io_edgeport.c Change Log comments: | ||
512 | |||
513 | 2003_04_03 al borchers | ||
514 | - fixed a bug (that shows up with dosemu) where the tty struct is | ||
515 | used in a callback after it has been freed | ||
516 | |||
517 | 2.3 2002_03_08 greg kroah-hartman | ||
518 | - fixed bug when multiple devices were attached at the same time. | ||
519 | |||
520 | 2.2 2001_11_14 greg kroah-hartman | ||
521 | - fixed bug in edge_close that kept the port from being used more | ||
522 | than once. | ||
523 | - fixed memory leak on device removal. | ||
524 | - fixed potential double free of memory when command urb submitting | ||
525 | failed. | ||
526 | - other small cleanups when the device is removed | ||
527 | |||
528 | 2.1 2001_07_09 greg kroah-hartman | ||
529 | - added support for TIOCMBIS and TIOCMBIC. | ||
530 | |||
531 | (04/08/2001) gb | ||
532 | - Identify version on module load. | ||
533 | |||
534 | 2.0 2001_03_05 greg kroah-hartman | ||
535 | - reworked entire driver to fit properly in with the other usb-serial | ||
536 | drivers. Occasional oopses still happen, but it's a good start. | ||
537 | |||
538 | 1.2.3 (02/23/2001) greg kroah-hartman | ||
539 | - changed device table to work properly for 2.4.x final format. | ||
540 | - fixed problem with dropping data at high data rates. | ||
541 | |||
542 | 1.2.2 (11/27/2000) greg kroah-hartman | ||
543 | - cleaned up more NTisms. | ||
544 | - Added device table for 2.4.0-test11 | ||
545 | |||
546 | 1.2.1 (11/08/2000) greg kroah-hartman | ||
547 | - Started to clean up NTisms. | ||
548 | - Fixed problem with dev field of urb for kernels >= 2.4.0-test9 | ||
549 | |||
550 | 1.2 (10/17/2000) David Iacovelli | ||
551 | Remove all EPIC code and GPL source | ||
552 | Fix RELEVANT_IFLAG macro to include flow control | ||
553 | changes port configuration changes. | ||
554 | Fix redefinition of SERIAL_MAGIC | ||
555 | Change all timeout values to 5 seconds | ||
556 | Tried to fix the UHCI multiple urb submission, but failed miserably. | ||
557 | it seems to work fine with OHCI. | ||
558 | ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must | ||
559 | find a way to work arount this UHCI bug ) | ||
560 | |||
561 | 1.1 (10/11/2000) David Iacovelli | ||
562 | Fix XON/XOFF flow control to support both IXON and IXOFF | ||
563 | |||
564 | 0.9.27 (06/30/2000) David Iacovelli | ||
565 | Added transmit queue and now allocate urb for command writes. | ||
566 | |||
567 | 0.9.26 (06/29/2000) David Iacovelli | ||
568 | Add support for 80251 based edgeport | ||
569 | |||
570 | 0.9.25 (06/27/2000) David Iacovelli | ||
571 | Do not close the port if it has multiple opens. | ||
572 | |||
573 | 0.9.24 (05/26/2000) David Iacovelli | ||
574 | Add IOCTLs to support RXTX and JAVA POS | ||
575 | and first cut at running BlackBox Demo | ||
576 | |||
577 | 0.9.23 (05/24/2000) David Iacovelli | ||
578 | Add IOCTLs to support RXTX and JAVA POS | ||
579 | |||
580 | 0.9.22 (05/23/2000) David Iacovelli | ||
581 | fixed bug in enumeration. If epconfig turns on mapping by | ||
582 | path after a device is already plugged in, we now update | ||
583 | the mapping correctly | ||
584 | |||
585 | 0.9.21 (05/16/2000) David Iacovelli | ||
586 | Added BlockUntilChaseResp() to also wait for txcredits | ||
587 | Updated the way we allocate and handle write URBs | ||
588 | Add debug code to dump buffers | ||
589 | |||
590 | 0.9.20 (05/01/2000) David Iacovelli | ||
591 | change driver to use usb/tts/ | ||
592 | |||
593 | 0.9.19 (05/01/2000) David Iacovelli | ||
594 | Update code to compile if DEBUG is off | ||
595 | |||
596 | 0.9.18 (04/28/2000) David Iacovelli | ||
597 | cleanup and test tty_register with devfs | ||
598 | |||
599 | 0.9.17 (04/27/2000) greg kroah-hartman | ||
600 | changed tty_register around to be like the way it | ||
601 | was before, but now it works properly with devfs. | ||
602 | |||
603 | 0.9.16 (04/26/2000) david iacovelli | ||
604 | Fixed bug in GetProductInfo() | ||
605 | |||
606 | 0.9.15 (04/25/2000) david iacovelli | ||
607 | Updated enumeration | ||
608 | |||
609 | 0.9.14 (04/24/2000) david iacovelli | ||
610 | Removed all config/status IOCTLS and | ||
611 | converted to using /proc/edgeport | ||
612 | still playing with devfs | ||
613 | |||
614 | 0.9.13 (04/24/2000) david iacovelli | ||
615 | Removed configuration based on ttyUSB0 | ||
616 | Added support for configuration using /prod/edgeport | ||
617 | first attempt at using devfs (not working yet!) | ||
618 | Added IOCTL to GetProductInfo() | ||
619 | Added support for custom baud rates | ||
620 | Add support for random port numbers | ||
621 | |||
622 | 0.9.12 (04/18/2000) david iacovelli | ||
623 | added additional configuration IOCTLs | ||
624 | use ttyUSB0 for configuration | ||
625 | |||
626 | 0.9.11 (04/17/2000) greg kroah-hartman | ||
627 | fixed module initialization race conditions. | ||
628 | made all urbs dynamically allocated. | ||
629 | made driver devfs compatible. now it only registers the tty device | ||
630 | when the device is actually plugged in. | ||
631 | |||
632 | 0.9.10 (04/13/2000) greg kroah-hartman | ||
633 | added proc interface framework. | ||
634 | |||
635 | 0.9.9 (04/13/2000) david iacovelli | ||
636 | added enumeration code and ioctls to configure the device | ||
637 | |||
638 | 0.9.8 (04/12/2000) david iacovelli | ||
639 | Change interrupt read start when device is plugged in | ||
640 | and stop when device is removed | ||
641 | process interrupt reads when all ports are closed | ||
642 | (keep value of rxBytesAvail consistent with the edgeport) | ||
643 | set the USB_BULK_QUEUE flag so that we can shove a bunch | ||
644 | of urbs at once down the pipe | ||
645 | |||
646 | 0.9.7 (04/10/2000) david iacovelli | ||
647 | start to add enumeration code. | ||
648 | generate serial number for epic devices | ||
649 | add support for kdb | ||
650 | |||
651 | 0.9.6 (03/30/2000) david iacovelli | ||
652 | add IOCTL to get string, manufacture, and boot descriptors | ||
653 | |||
654 | 0.9.5 (03/14/2000) greg kroah-hartman | ||
655 | more error checking added to SerialOpen to try to fix UHCI open problem | ||
656 | |||
657 | 0.9.4 (03/09/2000) greg kroah-hartman | ||
658 | added more error checking to handle oops when data is hanging | ||
659 | around and tty is abruptly closed. | ||
660 | |||
661 | 0.9.3 (03/09/2000) david iacovelli | ||
662 | Add epic support for xon/xoff chars | ||
663 | play with performance | ||
664 | |||
665 | 0.9.2 (03/08/2000) greg kroah-hartman | ||
666 | changed most "info" calls to "dbg" | ||
667 | implemented flow control properly in the termios call | ||
668 | |||
669 | 0.9.1 (03/08/2000) david iacovelli | ||
670 | added EPIC support | ||
671 | enabled bootloader update | ||
672 | |||
673 | 0.9 (03/08/2000) greg kroah-hartman | ||
674 | Release to IO networks. | ||
675 | Integrated changes that David made | ||
676 | made getting urbs for writing SMP safe | ||
677 | |||
678 | 0.8 (03/07/2000) greg kroah-hartman | ||
679 | Release to IO networks. | ||
680 | Fixed problems that were seen in code by David. | ||
681 | Now both Edgeport/4 and Edgeport/2 works properly. | ||
682 | Changed most of the functions to use port instead of serial. | ||
683 | |||
684 | 0.7 (02/27/2000) greg kroah-hartman | ||
685 | Milestone 3 release. | ||
686 | Release to IO Networks | ||
687 | ioctl for waiting on line change implemented. | ||
688 | ioctl for getting statistics implemented. | ||
689 | multiport support working. | ||
690 | lsr and msr registers are now handled properly. | ||
691 | change break now hooked up and working. | ||
692 | support for all known Edgeport devices. | ||
693 | |||
694 | 0.6 (02/22/2000) greg kroah-hartman | ||
695 | Release to IO networks. | ||
696 | CHASE is implemented correctly when port is closed. | ||
697 | SerialOpen now blocks correctly until port is fully opened. | ||
698 | |||
699 | 0.5 (02/20/2000) greg kroah-hartman | ||
700 | Release to IO networks. | ||
701 | Known problems: | ||
702 | modem status register changes are not sent on to the user | ||
703 | CHASE is not implemented when the port is closed. | ||
704 | |||
705 | 0.4 (02/16/2000) greg kroah-hartman | ||
706 | Second cut at the CeBit demo. | ||
707 | Doesn't leak memory on every write to the port | ||
708 | Still small leaks on startup. | ||
709 | Added support for Edgeport/2 and Edgeport/8 | ||
710 | |||
711 | 0.3 (02/15/2000) greg kroah-hartman | ||
712 | CeBit demo release. | ||
713 | Force the line settings to 4800, 8, 1, e for the demo. | ||
714 | Warning! This version leaks memory like crazy! | ||
715 | |||
716 | 0.2 (01/30/2000) greg kroah-hartman | ||
717 | Milestone 1 release. | ||
718 | Device is found by USB subsystem, enumerated, firmware is downloaded | ||
719 | and the descriptors are printed to the debug log, config is set, and | ||
720 | green light starts to blink. Open port works, and data can be sent | ||
721 | and received at the default settings of the UART. Loopback connector | ||
722 | and debug log confirms this. | ||
723 | |||
724 | 0.1 (01/23/2000) greg kroah-hartman | ||
725 | Initial release to help IO Networks try to set up their test system. | ||
726 | Edgeport4 is recognized, firmware is downloaded, config is set so | ||
727 | device blinks green light every 3 sec. Port is bound, but opening, | ||
728 | closing, and sending data do not work properly. | ||
729 | |||
730 | |||
diff --git a/drivers/usb/serial/baseband_usb_chr.c b/drivers/usb/serial/baseband_usb_chr.c new file mode 100644 index 00000000000..6d691a40312 --- /dev/null +++ b/drivers/usb/serial/baseband_usb_chr.c | |||
@@ -0,0 +1,1124 @@ | |||
1 | /* | ||
2 | * baseband_usb_chr.c | ||
3 | * | ||
4 | * USB character driver to communicate with baseband modems. | ||
5 | * | ||
6 | * Copyright (c) 2011, NVIDIA Corporation. | ||
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 as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/types.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/moduleparam.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/cdev.h> | ||
29 | #include <linux/fs.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/list.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/usb.h> | ||
35 | #include <linux/workqueue.h> | ||
36 | #include <asm/ioctls.h> | ||
37 | #include <linux/uaccess.h> | ||
38 | #include "baseband_usb_chr.h" | ||
39 | |||
40 | MODULE_LICENSE("GPL"); | ||
41 | |||
42 | unsigned long baseband_usb_chr_vid = 0x058b; | ||
43 | unsigned long baseband_usb_chr_pid = 0x0041; | ||
44 | unsigned long baseband_usb_chr_intf = 0x01; | ||
45 | |||
46 | module_param(baseband_usb_chr_vid, ulong, 0644); | ||
47 | MODULE_PARM_DESC(baseband_usb_chr_vid, "baseband (usb chr) - USB VID"); | ||
48 | module_param(baseband_usb_chr_pid, ulong, 0644); | ||
49 | MODULE_PARM_DESC(baseband_usb_chr_pid, "baseband (usb chr) - USB PID"); | ||
50 | module_param(baseband_usb_chr_intf, ulong, 0644); | ||
51 | MODULE_PARM_DESC(baseband_usb_chr_intf, "baseband (usb chr) - USB interface"); | ||
52 | |||
53 | static struct baseband_usb *baseband_usb_chr; | ||
54 | static bool usb_device_connection; | ||
55 | |||
56 | static atomic_t g_rx_count = ATOMIC_INIT(0); | ||
57 | |||
58 | /* baseband ipc functions */ | ||
59 | |||
60 | static void baseband_ipc_dump(const char *prefix, unsigned long int offset, | ||
61 | const void *buf, size_t bufsiz) | ||
62 | { | ||
63 | size_t i; | ||
64 | |||
65 | for (i = 0; i < bufsiz; i += 16) { | ||
66 | pr_debug("%s" | ||
67 | "[%lx+%x] %p " | ||
68 | "%02x %02x %02x %02x " | ||
69 | "%02x %02x %02x %02x " | ||
70 | "%02x %02x %02x %02x " | ||
71 | "%02x %02x %02x %02x\n", | ||
72 | prefix, | ||
73 | offset, | ||
74 | i, | ||
75 | ((const unsigned char *) buf) + i, | ||
76 | (i + 0 < bufsiz) ? ((const unsigned char *) buf)[i+0] | ||
77 | : 0xff, | ||
78 | (i + 1 < bufsiz) ? ((const unsigned char *) buf)[i+1] | ||
79 | : 0xff, | ||
80 | (i + 2 < bufsiz) ? ((const unsigned char *) buf)[i+2] | ||
81 | : 0xff, | ||
82 | (i + 3 < bufsiz) ? ((const unsigned char *) buf)[i+3] | ||
83 | : 0xff, | ||
84 | (i + 4 < bufsiz) ? ((const unsigned char *) buf)[i+4] | ||
85 | : 0xff, | ||
86 | (i + 5 < bufsiz) ? ((const unsigned char *) buf)[i+5] | ||
87 | : 0xff, | ||
88 | (i + 6 < bufsiz) ? ((const unsigned char *) buf)[i+6] | ||
89 | : 0xff, | ||
90 | (i + 7 < bufsiz) ? ((const unsigned char *) buf)[i+7] | ||
91 | : 0xff, | ||
92 | (i + 8 < bufsiz) ? ((const unsigned char *) buf)[i+8] | ||
93 | : 0xff, | ||
94 | (i + 9 < bufsiz) ? ((const unsigned char *) buf)[i+9] | ||
95 | : 0xff, | ||
96 | (i + 10 < bufsiz) ? ((const unsigned char *) buf)[i+10] | ||
97 | : 0xff, | ||
98 | (i + 11 < bufsiz) ? ((const unsigned char *) buf)[i+11] | ||
99 | : 0xff, | ||
100 | (i + 12 < bufsiz) ? ((const unsigned char *) buf)[i+12] | ||
101 | : 0xff, | ||
102 | (i + 13 < bufsiz) ? ((const unsigned char *) buf)[i+13] | ||
103 | : 0xff, | ||
104 | (i + 14 < bufsiz) ? ((const unsigned char *) buf)[i+14] | ||
105 | : 0xff, | ||
106 | (i + 15 < bufsiz) ? ((const unsigned char *) buf)[i+15] | ||
107 | : 0xff); | ||
108 | } | ||
109 | |||
110 | } | ||
111 | |||
112 | static size_t peek_ipc_tx_bufsiz(struct baseband_ipc *ipc, | ||
113 | size_t bufsiz) | ||
114 | { | ||
115 | struct baseband_ipc_buf *ipc_buf, *ipc_buf_next; | ||
116 | size_t tx_bufsiz; | ||
117 | |||
118 | pr_debug("peek_ipc_tx_bufsiz\n"); | ||
119 | |||
120 | /* check input */ | ||
121 | if (!ipc) { | ||
122 | pr_err("!ipc\n"); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | /* acquire tx buffer semaphores */ | ||
127 | if (down_interruptible(&ipc->buf_sem)) { | ||
128 | pr_err("peek_ipc_tx_bufsiz - " | ||
129 | "cannot acquire buffer semaphore\n"); | ||
130 | return -ERESTARTSYS; | ||
131 | } | ||
132 | |||
133 | /* calculate maximum number of tx buffers which can be sent */ | ||
134 | tx_bufsiz = 0; | ||
135 | list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx.buf, list) | ||
136 | { | ||
137 | pr_debug("peek_ipc_tx_bufsiz - " | ||
138 | "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n", | ||
139 | ipc_buf, ipc_buf->offset, ipc_buf->count); | ||
140 | if (ipc_buf->count > bufsiz - tx_bufsiz) | ||
141 | break; | ||
142 | else | ||
143 | tx_bufsiz += ipc_buf->count; | ||
144 | } | ||
145 | |||
146 | /* release tx buffer semaphores */ | ||
147 | up(&ipc->buf_sem); | ||
148 | |||
149 | return tx_bufsiz; | ||
150 | } | ||
151 | |||
152 | static size_t get_ipc_tx_buf(struct baseband_ipc *ipc, | ||
153 | void *buf, size_t bufsiz) | ||
154 | { | ||
155 | struct baseband_ipc_buf *ipc_buf, *ipc_buf_next; | ||
156 | size_t tx_bufsiz; | ||
157 | |||
158 | pr_debug("get_ipc_tx_buf\n"); | ||
159 | |||
160 | /* check input */ | ||
161 | if (!ipc || !buf) { | ||
162 | pr_err("!ipc || !buf\n"); | ||
163 | return 0; | ||
164 | } | ||
165 | if (!bufsiz) | ||
166 | return 0; | ||
167 | |||
168 | /* acquire tx buffer semaphores */ | ||
169 | if (down_interruptible(&ipc->buf_sem)) { | ||
170 | pr_err("get_ipc_tx_buf - " | ||
171 | "cannot acquire buffer semaphore\n"); | ||
172 | return -ERESTARTSYS; | ||
173 | } | ||
174 | |||
175 | /* get tx data from tx linked list */ | ||
176 | tx_bufsiz = 0; | ||
177 | list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx.buf, list) | ||
178 | { | ||
179 | pr_debug("get_ipc_tx_buf - " | ||
180 | "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n", | ||
181 | ipc_buf, ipc_buf->offset, ipc_buf->count); | ||
182 | pr_debug("get_ipc_tx_buf - " | ||
183 | "ipc_buf->data [0] %x [1] %x [2] %x [3] %x\n", | ||
184 | ipc_buf->data[0], | ||
185 | ipc_buf->data[1], | ||
186 | ipc_buf->data[2], | ||
187 | ipc_buf->data[3]); | ||
188 | if (ipc_buf->count > bufsiz - tx_bufsiz) { | ||
189 | /* copy part of tx buffer */ | ||
190 | memcpy(buf + tx_bufsiz, | ||
191 | ipc_buf->data + ipc_buf->offset, | ||
192 | bufsiz - tx_bufsiz); | ||
193 | ipc_buf->offset += bufsiz - tx_bufsiz; | ||
194 | ipc_buf->count -= bufsiz - tx_bufsiz; | ||
195 | tx_bufsiz = bufsiz; | ||
196 | } else { | ||
197 | /* copy all data from tx buffer */ | ||
198 | memcpy(buf + tx_bufsiz, | ||
199 | ipc_buf->data + ipc_buf->offset, | ||
200 | ipc_buf->count); | ||
201 | tx_bufsiz += ipc_buf->count; | ||
202 | ipc_buf->offset = 0; | ||
203 | ipc_buf->count = 0; | ||
204 | /* add tx buffer to tx free list */ | ||
205 | list_move_tail(&ipc_buf->list, &ipc->tx_free.buf); | ||
206 | wake_up(&ipc->tx_free.wait); | ||
207 | } | ||
208 | /* check if done */ | ||
209 | if (tx_bufsiz == bufsiz) | ||
210 | break; | ||
211 | } | ||
212 | |||
213 | /* release tx buffer semaphores */ | ||
214 | up(&ipc->buf_sem); | ||
215 | |||
216 | return tx_bufsiz; | ||
217 | } | ||
218 | |||
219 | static size_t put_ipc_rx_buf(struct baseband_ipc *ipc, | ||
220 | const void *buf, size_t bufsiz) | ||
221 | { | ||
222 | struct baseband_ipc_buf *ipc_buf, *ipc_buf_next; | ||
223 | size_t rx_bufsiz; | ||
224 | |||
225 | pr_debug("put_ipc_rx_buf\n"); | ||
226 | |||
227 | /* check input */ | ||
228 | if (!ipc || !buf) { | ||
229 | pr_err("!ipc || !buf\n"); | ||
230 | return 0; | ||
231 | } | ||
232 | if (!bufsiz) | ||
233 | return 0; | ||
234 | |||
235 | /* acquire rx buffer semaphores */ | ||
236 | retry: | ||
237 | if (down_interruptible(&ipc->buf_sem)) { | ||
238 | pr_err("put_ipc_rx_buf - " | ||
239 | "cannot acquire buffer semaphore\n"); | ||
240 | return -ERESTARTSYS; | ||
241 | } | ||
242 | |||
243 | /* put rx data in rx linked list */ | ||
244 | rx_bufsiz = 0; | ||
245 | list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx_free.buf, list) | ||
246 | { | ||
247 | pr_debug("put_ipc_rx_buf - " | ||
248 | "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n", | ||
249 | ipc_buf, ipc_buf->offset, ipc_buf->count); | ||
250 | if (sizeof(ipc_buf->data) > bufsiz - rx_bufsiz) { | ||
251 | /* partially fill rx free buffer */ | ||
252 | memcpy(ipc_buf->data, | ||
253 | buf + rx_bufsiz, | ||
254 | bufsiz - rx_bufsiz); | ||
255 | ipc_buf->offset = 0; | ||
256 | ipc_buf->count = bufsiz - rx_bufsiz; | ||
257 | rx_bufsiz = bufsiz; | ||
258 | } else { | ||
259 | /* fill entire rx free buffer */ | ||
260 | memcpy(ipc_buf->data, | ||
261 | buf + rx_bufsiz, | ||
262 | sizeof(ipc_buf->data)); | ||
263 | ipc_buf->offset = 0; | ||
264 | ipc_buf->count = sizeof(ipc_buf->data); | ||
265 | rx_bufsiz += sizeof(ipc_buf->data); | ||
266 | } | ||
267 | /* add filled rx free buffer to rx linked list */ | ||
268 | list_move_tail(&ipc_buf->list, &ipc->rx.buf); | ||
269 | wake_up(&ipc->rx.wait); | ||
270 | /* check if done */ | ||
271 | if (rx_bufsiz == bufsiz) | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | /* release rx buffer semaphores */ | ||
276 | up(&ipc->buf_sem); | ||
277 | |||
278 | /* wait for rx free buffer available */ | ||
279 | if (!rx_bufsiz) { | ||
280 | if (wait_event_interruptible(ipc->rx_free.wait, | ||
281 | !list_empty(&ipc->rx_free.buf))) { | ||
282 | pr_err("put_ipc_rx_buf - " | ||
283 | "interrupted wait\n"); | ||
284 | return -ERESTARTSYS; | ||
285 | } | ||
286 | goto retry; | ||
287 | } | ||
288 | |||
289 | return rx_bufsiz; | ||
290 | |||
291 | } | ||
292 | |||
293 | static ssize_t baseband_ipc_file_read(struct baseband_ipc *ipc, | ||
294 | struct file *file, char *buf, size_t count, loff_t *pos) | ||
295 | { | ||
296 | struct baseband_ipc_buf *ipc_buf, *ipc_buf_next; | ||
297 | size_t read_count; | ||
298 | |||
299 | pr_debug("baseband_ipc_file_read\n"); | ||
300 | |||
301 | /* check input */ | ||
302 | if (!ipc) { | ||
303 | pr_err("!ipc\n"); | ||
304 | return -EIO; | ||
305 | } | ||
306 | |||
307 | /* acquire rx buffer semaphores */ | ||
308 | retry: | ||
309 | if (down_interruptible(&ipc->buf_sem)) { | ||
310 | pr_err("baseband_ipc_file_read - " | ||
311 | "cannot acquire buffer semaphore\n"); | ||
312 | return -ERESTARTSYS; | ||
313 | } | ||
314 | |||
315 | /* get read data from rx linked list */ | ||
316 | read_count = 0; | ||
317 | list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx.buf, list) | ||
318 | { | ||
319 | pr_debug("baseband_ipc_file_read - " | ||
320 | "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n", | ||
321 | ipc_buf, ipc_buf->offset, ipc_buf->count); | ||
322 | pr_debug("baseband_ipc_file_read - " | ||
323 | "ipc_buf->data [0] %x [1] %x [2] %x [3] %x\n", | ||
324 | ipc_buf->data[0], | ||
325 | ipc_buf->data[1], | ||
326 | ipc_buf->data[2], | ||
327 | ipc_buf->data[3]); | ||
328 | if (ipc_buf->count > count - read_count) { | ||
329 | /* copy part of rx buffer */ | ||
330 | if (copy_to_user(buf + read_count, | ||
331 | ipc_buf->data + ipc_buf->offset, | ||
332 | count - read_count)) { | ||
333 | pr_err("copy_to_user failed\n"); | ||
334 | up(&ipc->buf_sem); | ||
335 | return -EFAULT; | ||
336 | } | ||
337 | ipc_buf->offset += count - read_count; | ||
338 | ipc_buf->count -= count - read_count; | ||
339 | read_count = count; | ||
340 | } else { | ||
341 | /* copy all data from rx buffer */ | ||
342 | if (copy_to_user(buf + read_count, | ||
343 | ipc_buf->data + ipc_buf->offset, | ||
344 | ipc_buf->count)) { | ||
345 | pr_err("copy_to_user failed\n"); | ||
346 | up(&ipc->buf_sem); | ||
347 | return -EFAULT; | ||
348 | } | ||
349 | read_count += ipc_buf->count; | ||
350 | ipc_buf->offset = 0; | ||
351 | ipc_buf->count = 0; | ||
352 | /* add rx buffer to rx free list */ | ||
353 | list_move_tail(&ipc_buf->list, &ipc->rx_free.buf); | ||
354 | wake_up(&ipc->rx_free.wait); | ||
355 | } | ||
356 | /* check if done */ | ||
357 | if (read_count == count) | ||
358 | break; | ||
359 | } | ||
360 | |||
361 | /* release rx buffer semaphores */ | ||
362 | up(&ipc->buf_sem); | ||
363 | |||
364 | /* wait for rx buffer available */ | ||
365 | if (!read_count) { | ||
366 | if (wait_event_interruptible(ipc->rx.wait, | ||
367 | !list_empty(&ipc->rx.buf))) { | ||
368 | pr_err("baseband_ipc_file_read - " | ||
369 | "interrupted wait\n"); | ||
370 | return -ERESTARTSYS; | ||
371 | } | ||
372 | goto retry; | ||
373 | } | ||
374 | |||
375 | return read_count; | ||
376 | } | ||
377 | |||
378 | static ssize_t baseband_ipc_file_write(struct baseband_ipc *ipc, | ||
379 | struct file *file, const char *buf, size_t count, loff_t *pos) | ||
380 | { | ||
381 | struct baseband_ipc_buf *ipc_buf, *ipc_buf_next; | ||
382 | size_t write_count; | ||
383 | |||
384 | pr_debug("baseband_ipc_file_write\n"); | ||
385 | |||
386 | /* check input */ | ||
387 | if (!ipc) { | ||
388 | pr_err("!ipc\n"); | ||
389 | return -EIO; | ||
390 | } | ||
391 | |||
392 | /* acquire tx buffer semaphores */ | ||
393 | retry: | ||
394 | if (down_interruptible(&ipc->buf_sem)) { | ||
395 | pr_err("baseband_ipc_file_write - " | ||
396 | "cannot acquire buffer semaphore\n"); | ||
397 | return -ERESTARTSYS; | ||
398 | } | ||
399 | |||
400 | /* put write data in tx linked list */ | ||
401 | write_count = 0; | ||
402 | list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx_free.buf, list) | ||
403 | { | ||
404 | pr_debug("baseband_ipc_file_write - " | ||
405 | "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n", | ||
406 | ipc_buf, ipc_buf->offset, ipc_buf->count); | ||
407 | if (sizeof(ipc_buf->data) > count - write_count) { | ||
408 | /* partially fill tx free buffer */ | ||
409 | if (copy_from_user(ipc_buf->data, | ||
410 | buf + write_count, | ||
411 | count - write_count)) { | ||
412 | pr_err("copy_from_user failed\n"); | ||
413 | up(&ipc->buf_sem); | ||
414 | return -EFAULT; | ||
415 | } | ||
416 | ipc_buf->offset = 0; | ||
417 | ipc_buf->count = count - write_count; | ||
418 | write_count = count; | ||
419 | } else { | ||
420 | /* fill entire tx free buffer */ | ||
421 | if (copy_from_user(ipc_buf->data, | ||
422 | buf + write_count, | ||
423 | sizeof(ipc_buf->data))) { | ||
424 | pr_err("copy_from_user failed\n"); | ||
425 | up(&ipc->buf_sem); | ||
426 | return -EFAULT; | ||
427 | } | ||
428 | ipc_buf->offset = 0; | ||
429 | ipc_buf->count = sizeof(ipc_buf->data); | ||
430 | write_count += sizeof(ipc_buf->data); | ||
431 | } | ||
432 | /* add filled tx free buffer to tx linked list */ | ||
433 | pr_debug("baseband_ipc_file_write - " | ||
434 | "ipc_buf->data [0] %x [1] %x [2] %x [3] %x\n", | ||
435 | ipc_buf->data[0], | ||
436 | ipc_buf->data[1], | ||
437 | ipc_buf->data[2], | ||
438 | ipc_buf->data[3]); | ||
439 | list_move_tail(&ipc_buf->list, &ipc->tx.buf); | ||
440 | wake_up(&ipc->tx.wait); | ||
441 | /* check if done */ | ||
442 | if (write_count == count) | ||
443 | break; | ||
444 | } | ||
445 | |||
446 | /* release tx buffer semaphores */ | ||
447 | up(&ipc->buf_sem); | ||
448 | |||
449 | /* wait for tx buffer available */ | ||
450 | if (!write_count) { | ||
451 | if (wait_event_interruptible(ipc->tx_free.wait, | ||
452 | !list_empty(&ipc->tx_free.buf))) { | ||
453 | pr_err("baseband_ipc_file_write - " | ||
454 | "interrupted wait\n"); | ||
455 | return -ERESTARTSYS; | ||
456 | } | ||
457 | goto retry; | ||
458 | } | ||
459 | |||
460 | /* queue ipc transaction work */ | ||
461 | queue_work(ipc->workqueue, &ipc->work); | ||
462 | |||
463 | return write_count; | ||
464 | } | ||
465 | |||
466 | static void baseband_ipc_close(struct baseband_ipc *ipc) | ||
467 | { | ||
468 | struct baseband_ipc_buf *ipc_buf, *ipc_buf_next; | ||
469 | |||
470 | pr_debug("baseband_ipc_close {\n"); | ||
471 | |||
472 | /* check input */ | ||
473 | if (!ipc) | ||
474 | return; | ||
475 | |||
476 | /* destroy work queue */ | ||
477 | if (ipc->workqueue) { | ||
478 | pr_debug("destroy workqueue {\n"); | ||
479 | cancel_work_sync(&ipc->work); | ||
480 | destroy_workqueue(ipc->workqueue); | ||
481 | ipc->workqueue = (struct workqueue_struct *) 0; | ||
482 | pr_debug("destroy workqueue }\n"); | ||
483 | } | ||
484 | memset(&ipc->work, 0, sizeof(ipc->work)); | ||
485 | |||
486 | /* destroy wait queues */ | ||
487 | memset(&ipc->tx_free.wait, 0, sizeof(ipc->tx_free.wait)); | ||
488 | memset(&ipc->rx_free.wait, 0, sizeof(ipc->rx_free.wait)); | ||
489 | memset(&ipc->tx.wait, 0, sizeof(ipc->tx.wait)); | ||
490 | memset(&ipc->rx.wait, 0, sizeof(ipc->rx.wait)); | ||
491 | |||
492 | /* destroy data buffers */ | ||
493 | kfree(ipc->ipc_tx); | ||
494 | ipc->ipc_tx = (unsigned char *) 0; | ||
495 | kfree(ipc->ipc_rx); | ||
496 | ipc->ipc_rx = (unsigned char *) 0; | ||
497 | list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx_free.buf, list) | ||
498 | { | ||
499 | kfree(ipc_buf); | ||
500 | } | ||
501 | list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx_free.buf, list) | ||
502 | { | ||
503 | kfree(ipc_buf); | ||
504 | } | ||
505 | list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx.buf, list) | ||
506 | { | ||
507 | kfree(ipc_buf); | ||
508 | } | ||
509 | list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx.buf, list) | ||
510 | { | ||
511 | kfree(ipc_buf); | ||
512 | } | ||
513 | |||
514 | /* destroy semaphores */ | ||
515 | memset(&ipc->buf_sem, 0, sizeof(ipc->buf_sem)); | ||
516 | |||
517 | /* free baseband ipc structure */ | ||
518 | kfree(ipc); | ||
519 | |||
520 | pr_debug("baseband_ipc_close }\n"); | ||
521 | } | ||
522 | |||
523 | static struct baseband_ipc *baseband_ipc_open(work_func_t work_func, | ||
524 | work_func_t rx_work_func, | ||
525 | work_func_t tx_work_func) | ||
526 | { | ||
527 | struct baseband_ipc *ipc; | ||
528 | struct baseband_ipc_buf *ipc_buf; | ||
529 | int i; | ||
530 | |||
531 | pr_debug("baseband_ipc_open {\n"); | ||
532 | |||
533 | /* allocate baseband ipc structure */ | ||
534 | ipc = kzalloc(sizeof(struct baseband_ipc), GFP_KERNEL); | ||
535 | if (!ipc) | ||
536 | return (struct baseband_ipc *) 0; | ||
537 | |||
538 | /* create semaphores */ | ||
539 | sema_init(&ipc->buf_sem, 1); | ||
540 | |||
541 | /* create data buffers */ | ||
542 | INIT_LIST_HEAD(&ipc->rx.buf); | ||
543 | INIT_LIST_HEAD(&ipc->tx.buf); | ||
544 | INIT_LIST_HEAD(&ipc->rx_free.buf); | ||
545 | INIT_LIST_HEAD(&ipc->tx_free.buf); | ||
546 | for (i = 0; i < BASEBAND_IPC_NUM_RX_BUF; i++) { | ||
547 | ipc_buf = (struct baseband_ipc_buf *) | ||
548 | kzalloc(sizeof(struct baseband_ipc_buf), GFP_KERNEL); | ||
549 | if (!ipc_buf) { | ||
550 | pr_err("cannot allocate baseband ipc rx buffer #%d\n", | ||
551 | i); | ||
552 | goto error_exit; | ||
553 | } | ||
554 | pr_debug("baseband_ipc_open - " | ||
555 | "rx_free: ipc_buf %p\n", | ||
556 | ipc_buf); | ||
557 | list_add_tail(&ipc_buf->list, &ipc->rx_free.buf); | ||
558 | } | ||
559 | for (i = 0; i < BASEBAND_IPC_NUM_TX_BUF; i++) { | ||
560 | ipc_buf = (struct baseband_ipc_buf *) | ||
561 | kzalloc(sizeof(struct baseband_ipc_buf), GFP_KERNEL); | ||
562 | if (!ipc_buf) { | ||
563 | pr_err("cannot allocate baseband ipc tx buffer #%d\n", | ||
564 | i); | ||
565 | goto error_exit; | ||
566 | } | ||
567 | pr_debug("baseband_ipc_open - " | ||
568 | "tx_free: ipc_buf %p\n", | ||
569 | ipc_buf); | ||
570 | list_add_tail(&ipc_buf->list, &ipc->tx_free.buf); | ||
571 | } | ||
572 | ipc->ipc_rx = (unsigned char *) 0; | ||
573 | ipc->ipc_tx = (unsigned char *) 0; | ||
574 | |||
575 | /* create wait queues */ | ||
576 | init_waitqueue_head(&ipc->rx.wait); | ||
577 | init_waitqueue_head(&ipc->tx.wait); | ||
578 | init_waitqueue_head(&ipc->rx_free.wait); | ||
579 | init_waitqueue_head(&ipc->tx_free.wait); | ||
580 | |||
581 | /* create work queue */ | ||
582 | ipc->workqueue = create_singlethread_workqueue | ||
583 | ("baseband_usb_chr_ipc_workqueue"); | ||
584 | if (!ipc->workqueue) { | ||
585 | pr_err("cannot create workqueue\n"); | ||
586 | goto error_exit; | ||
587 | } | ||
588 | if (work_func) | ||
589 | INIT_WORK(&ipc->work, work_func); | ||
590 | if (rx_work_func) | ||
591 | INIT_WORK(&ipc->rx_work, rx_work_func); | ||
592 | if (tx_work_func) | ||
593 | INIT_WORK(&ipc->tx_work, tx_work_func); | ||
594 | |||
595 | pr_debug("baseband_ipc_open }\n"); | ||
596 | return ipc; | ||
597 | |||
598 | error_exit: | ||
599 | baseband_ipc_close(ipc); | ||
600 | return (struct baseband_ipc *) 0; | ||
601 | } | ||
602 | |||
603 | /* usb rx */ | ||
604 | |||
605 | static void baseband_usb_chr_rx_urb_comp(struct urb *urb) | ||
606 | { | ||
607 | struct baseband_usb *usb = (struct baseband_usb *) urb->context; | ||
608 | |||
609 | pr_debug("baseband_usb_chr_rx_urb_comp { urb %p\n", urb); | ||
610 | |||
611 | /* queue rx urb completion work */ | ||
612 | queue_work(usb->ipc->workqueue, &usb->ipc->rx_work); | ||
613 | |||
614 | pr_debug("baseband_usb_chr_rx_urb_comp }\n"); | ||
615 | } | ||
616 | |||
617 | static int baseband_usb_chr_rx_urb_submit(struct baseband_usb *usb) | ||
618 | { | ||
619 | struct urb *urb; | ||
620 | void *buf; | ||
621 | int err; | ||
622 | |||
623 | pr_debug("baseband_usb_chr_rx_urb_submit { usb %p\n", usb); | ||
624 | |||
625 | if (!usb_device_connection) { | ||
626 | pr_err("!!no usb device conenction!!!!!\n"); | ||
627 | return -1; | ||
628 | } | ||
629 | |||
630 | /* check input */ | ||
631 | if (usb->usb.rx_urb) { | ||
632 | pr_err("previous urb still active\n"); | ||
633 | return -1; | ||
634 | } | ||
635 | |||
636 | /* allocate rx urb */ | ||
637 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
638 | if (!urb) { | ||
639 | pr_err("usb_alloc_urb() failed\n"); | ||
640 | return -ENOMEM; | ||
641 | } | ||
642 | buf = kzalloc(USB_CHR_RX_BUFSIZ, GFP_ATOMIC); | ||
643 | if (!buf) { | ||
644 | pr_err("usb buffer kzalloc() failed\n"); | ||
645 | usb_free_urb(urb); | ||
646 | return -ENOMEM; | ||
647 | } | ||
648 | usb_fill_bulk_urb(urb, usb->usb.device, usb->usb.pipe.bulk.in, | ||
649 | buf, USB_CHR_RX_BUFSIZ, | ||
650 | baseband_usb_chr_rx_urb_comp, | ||
651 | usb); | ||
652 | urb->transfer_flags = 0; | ||
653 | |||
654 | /* submit rx urb */ | ||
655 | usb->usb.rx_urb = urb; | ||
656 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
657 | if (err < 0) { | ||
658 | pr_err("usb_submit_urb() failed - err %d\n", err); | ||
659 | usb->usb.rx_urb = (struct urb *) 0; | ||
660 | kfree(urb->transfer_buffer); | ||
661 | usb_free_urb(urb); | ||
662 | return err; | ||
663 | } | ||
664 | |||
665 | pr_debug("baseband_usb_chr_rx_urb_submit }\n"); | ||
666 | return err; | ||
667 | } | ||
668 | |||
669 | static void baseband_usb_chr_rx_urb_comp_work(struct work_struct *work) | ||
670 | { | ||
671 | struct baseband_usb *usb = baseband_usb_chr; | ||
672 | struct urb *urb = usb->usb.rx_urb; | ||
673 | size_t len; | ||
674 | |||
675 | pr_debug("baseband_usb_chr_rx_urb_comp_work { work %p\n", work); | ||
676 | |||
677 | /* put rx urb data in rx buffer */ | ||
678 | if (urb->actual_length) { | ||
679 | pr_debug("baseband_usb_chr_rx_urb_comp_work - " | ||
680 | "urb->actual_length %d\n", urb->actual_length); | ||
681 | len = put_ipc_rx_buf(usb->ipc, | ||
682 | urb->transfer_buffer, urb->actual_length); | ||
683 | baseband_ipc_dump("baseband_usb_chr_rx_urb_comp_work" | ||
684 | " - rx buf ", 0, | ||
685 | urb->transfer_buffer, len > 16 ? 16 : len); | ||
686 | if (len != urb->actual_length) { | ||
687 | pr_err("baseband_usb_chr_rx_urb_comp_work - " | ||
688 | "put_ipx_rx_buf() only put %d/%d bytes\n", | ||
689 | len, urb->actual_length); | ||
690 | } | ||
691 | /* increment count of available rx bytes */ | ||
692 | atomic_add(len, &g_rx_count); | ||
693 | } | ||
694 | |||
695 | /* free rx urb */ | ||
696 | kfree(urb->transfer_buffer); | ||
697 | urb->transfer_buffer = (void *) 0; | ||
698 | usb_free_urb(urb); | ||
699 | usb->usb.rx_urb = (struct urb *) 0; | ||
700 | |||
701 | /* submit next rx urb */ | ||
702 | baseband_usb_chr_rx_urb_submit(usb); | ||
703 | |||
704 | pr_debug("baseband_usb_chr_rx_urb_comp_work }\n"); | ||
705 | } | ||
706 | |||
707 | /* usb functions */ | ||
708 | |||
709 | static void find_usb_pipe(struct baseband_usb *usb) | ||
710 | { | ||
711 | struct usb_device *usbdev = usb->usb.device; | ||
712 | struct usb_interface *intf = usb->usb.interface; | ||
713 | unsigned char numendpoint = intf->cur_altsetting->desc.bNumEndpoints; | ||
714 | struct usb_host_endpoint *endpoint = intf->cur_altsetting->endpoint; | ||
715 | unsigned char n; | ||
716 | |||
717 | for (n = 0; n < numendpoint; n++) { | ||
718 | if (usb_endpoint_is_isoc_in(&endpoint[n].desc)) { | ||
719 | pr_debug("endpoint[%d] isochronous in\n", n); | ||
720 | usb->usb.pipe.isoch.in = usb_rcvisocpipe(usbdev, | ||
721 | endpoint[n].desc.bEndpointAddress); | ||
722 | } else if (usb_endpoint_is_isoc_out(&endpoint[n].desc)) { | ||
723 | pr_debug("endpoint[%d] isochronous out\n", n); | ||
724 | usb->usb.pipe.isoch.out = usb_sndisocpipe(usbdev, | ||
725 | endpoint[n].desc.bEndpointAddress); | ||
726 | } else if (usb_endpoint_is_bulk_in(&endpoint[n].desc)) { | ||
727 | pr_debug("endpoint[%d] bulk in\n", n); | ||
728 | usb->usb.pipe.bulk.in = usb_rcvbulkpipe(usbdev, | ||
729 | endpoint[n].desc.bEndpointAddress); | ||
730 | } else if (usb_endpoint_is_bulk_out(&endpoint[n].desc)) { | ||
731 | pr_debug("endpoint[%d] bulk out\n", n); | ||
732 | usb->usb.pipe.bulk.out = usb_sndbulkpipe(usbdev, | ||
733 | endpoint[n].desc.bEndpointAddress); | ||
734 | } else if (usb_endpoint_is_int_in(&endpoint[n].desc)) { | ||
735 | pr_debug("endpoint[%d] interrupt in\n", n); | ||
736 | usb->usb.pipe.interrupt.in = usb_rcvintpipe(usbdev, | ||
737 | endpoint[n].desc.bEndpointAddress); | ||
738 | } else if (usb_endpoint_is_int_out(&endpoint[n].desc)) { | ||
739 | pr_debug("endpoint[%d] interrupt out\n", n); | ||
740 | usb->usb.pipe.interrupt.out = usb_sndintpipe(usbdev, | ||
741 | endpoint[n].desc.bEndpointAddress); | ||
742 | } else { | ||
743 | pr_debug("endpoint[%d] skipped\n", n); | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | |||
748 | static int baseband_usb_driver_probe(struct usb_interface *intf, | ||
749 | const struct usb_device_id *id) | ||
750 | { | ||
751 | int err; | ||
752 | |||
753 | pr_debug("%s(%d) { intf %p id %p\n", __func__, __LINE__, intf, id); | ||
754 | |||
755 | pr_debug("intf->cur_altsetting->desc.bInterfaceNumber %02x\n", | ||
756 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
757 | pr_debug("intf->cur_altsetting->desc.bAlternateSetting %02x\n", | ||
758 | intf->cur_altsetting->desc.bAlternateSetting); | ||
759 | pr_debug("intf->cur_altsetting->desc.bNumEndpoints %02x\n", | ||
760 | intf->cur_altsetting->desc.bNumEndpoints); | ||
761 | pr_debug("intf->cur_altsetting->desc.bInterfaceClass %02x\n", | ||
762 | intf->cur_altsetting->desc.bInterfaceClass); | ||
763 | pr_debug("intf->cur_altsetting->desc.bInterfaceSubClass %02x\n", | ||
764 | intf->cur_altsetting->desc.bInterfaceSubClass); | ||
765 | pr_debug("intf->cur_altsetting->desc.bInterfaceProtocol %02x\n", | ||
766 | intf->cur_altsetting->desc.bInterfaceProtocol); | ||
767 | pr_debug("intf->cur_altsetting->desc.iInterface %02x\n", | ||
768 | intf->cur_altsetting->desc.iInterface); | ||
769 | |||
770 | /* usb interface mismatch */ | ||
771 | if (baseband_usb_chr_intf != | ||
772 | intf->cur_altsetting->desc.bInterfaceNumber) { | ||
773 | pr_debug("%s(%d) } -ENODEV\n", __func__, __LINE__); | ||
774 | return -ENODEV; | ||
775 | } | ||
776 | |||
777 | /* usb interface match */ | ||
778 | baseband_usb_chr->usb.device = interface_to_usbdev(intf); | ||
779 | baseband_usb_chr->usb.interface = intf; | ||
780 | find_usb_pipe(baseband_usb_chr); | ||
781 | baseband_usb_chr->usb.rx_urb = (struct urb *) 0; | ||
782 | baseband_usb_chr->usb.tx_urb = (struct urb *) 0; | ||
783 | pr_debug("baseband_usb_chr->usb.driver->name %s\n", | ||
784 | baseband_usb_chr->usb.driver->name); | ||
785 | pr_debug("baseband_usb_chr->usb.device %p\n", | ||
786 | baseband_usb_chr->usb.device); | ||
787 | pr_debug("baseband_usb_chr->usb.interface %p\n", | ||
788 | baseband_usb_chr->usb.interface); | ||
789 | pr_debug("baseband_usb_chr->usb.pipe.isoch.in %x\n", | ||
790 | baseband_usb_chr->usb.pipe.isoch.in); | ||
791 | pr_debug("baseband_usb_chr->usb.pipe.isoch.out %x\n", | ||
792 | baseband_usb_chr->usb.pipe.isoch.out); | ||
793 | pr_debug("baseband_usb_chr->usb.pipe.bulk.in %x\n", | ||
794 | baseband_usb_chr->usb.pipe.bulk.in); | ||
795 | pr_debug("baseband_usb_chr->usb.pipe.bulk.out %x\n", | ||
796 | baseband_usb_chr->usb.pipe.bulk.out); | ||
797 | pr_debug("baseband_usb_chr->usb.pipe.interrupt.in %x\n", | ||
798 | baseband_usb_chr->usb.pipe.interrupt.in); | ||
799 | pr_debug("baseband_usb_chr->usb.pipe.interrupt.out %x\n", | ||
800 | baseband_usb_chr->usb.pipe.interrupt.out); | ||
801 | usb_device_connection = true; | ||
802 | |||
803 | /* start usb rx */ | ||
804 | err = baseband_usb_chr_rx_urb_submit(baseband_usb_chr); | ||
805 | if (err < 0) { | ||
806 | pr_err("submit rx failed - err %d\n", err); | ||
807 | return -ENODEV; | ||
808 | } | ||
809 | |||
810 | pr_debug("%s(%d) }\n", __func__, __LINE__); | ||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | static void baseband_usb_driver_disconnect(struct usb_interface *intf) | ||
815 | { | ||
816 | struct usb_device *usb_dev = interface_to_usbdev(intf); | ||
817 | pr_debug("%s(%d) { intf %p\n", __func__, __LINE__, intf); | ||
818 | pr_debug("%s(%d) }\n", __func__, __LINE__); | ||
819 | if (baseband_usb_chr->usb.interface != intf) { | ||
820 | pr_info("%s(%d) -ENODEV\n", __func__, __LINE__); | ||
821 | return; | ||
822 | } | ||
823 | if (baseband_usb_chr->usb.device == usb_dev) { | ||
824 | pr_info("%s: Matching usb device: Flush workqueue\n", __func__); | ||
825 | flush_workqueue(baseband_usb_chr->ipc->workqueue); | ||
826 | usb_device_connection = false; | ||
827 | } | ||
828 | |||
829 | } | ||
830 | |||
831 | static char baseband_usb_driver_name[32]; | ||
832 | |||
833 | static struct usb_device_id baseband_usb_driver_id_table[2]; | ||
834 | |||
835 | static struct usb_driver baseband_usb_driver = { | ||
836 | .name = baseband_usb_driver_name, | ||
837 | .probe = baseband_usb_driver_probe, | ||
838 | .disconnect = baseband_usb_driver_disconnect, | ||
839 | .id_table = baseband_usb_driver_id_table, | ||
840 | }; | ||
841 | |||
842 | static void baseband_usb_chr_work(struct work_struct *work) | ||
843 | { | ||
844 | struct baseband_usb *usb = baseband_usb_chr; | ||
845 | struct { | ||
846 | unsigned char *buf; | ||
847 | unsigned int bufsiz_byte; | ||
848 | } rx, tx; | ||
849 | int ipc_tx_byte; | ||
850 | int err; | ||
851 | |||
852 | pr_debug("baseband_usb_chr_work {\n"); | ||
853 | |||
854 | /* check input */ | ||
855 | if (!usb || !usb->ipc) { | ||
856 | pr_err("baseband_usb_chr_work - " | ||
857 | "usb not open\n"); | ||
858 | return; | ||
859 | } | ||
860 | if (!usb->usb.device) { | ||
861 | pr_err("baseband_usb_chr_work - " | ||
862 | "usb device not probed yet\n"); | ||
863 | mdelay(10); | ||
864 | queue_work(usb->ipc->workqueue, &usb->ipc->work); | ||
865 | return; | ||
866 | } | ||
867 | |||
868 | /* allocate buffers on first transaction (will be freed on close) */ | ||
869 | if (!usb->ipc->ipc_rx) { | ||
870 | usb->ipc->ipc_rx = kzalloc(USB_CHR_RX_BUFSIZ, GFP_KERNEL); | ||
871 | if (!usb->ipc->ipc_rx) { | ||
872 | pr_err("baseband_usb_chr_work - " | ||
873 | "cannot allocate usb->ipc->ipc_rx\n"); | ||
874 | return; | ||
875 | } | ||
876 | } | ||
877 | if (!usb->ipc->ipc_tx) { | ||
878 | usb->ipc->ipc_tx = kzalloc(USB_CHR_TX_BUFSIZ, GFP_KERNEL); | ||
879 | if (!usb->ipc->ipc_tx) { | ||
880 | pr_err("baseband_usb_chr_work - " | ||
881 | "cannot allocate usb->ipc->ipc_tx\n"); | ||
882 | return; | ||
883 | } | ||
884 | } | ||
885 | |||
886 | /* usb transaction loop */ | ||
887 | rx.buf = usb->ipc->ipc_rx; | ||
888 | tx.buf = usb->ipc->ipc_tx; | ||
889 | while ((tx.bufsiz_byte = peek_ipc_tx_bufsiz(usb->ipc, | ||
890 | USB_CHR_TX_BUFSIZ)) != 0) { | ||
891 | get_ipc_tx_buf(usb->ipc, tx.buf, tx.bufsiz_byte); | ||
892 | err = usb_bulk_msg(usb->usb.device, usb->usb.pipe.bulk.out, | ||
893 | tx.buf, tx.bufsiz_byte, &ipc_tx_byte, USB_CHR_TIMEOUT); | ||
894 | if (err < 0) { | ||
895 | pr_err("baseband_usb_chr_work - " | ||
896 | "usb_bulk_msg err %d\n", err); | ||
897 | continue; | ||
898 | } | ||
899 | if (tx.bufsiz_byte != ipc_tx_byte) { | ||
900 | pr_err("tx.bufsiz_byte %d != ipc_tx_byte %d\n", | ||
901 | tx.bufsiz_byte, ipc_tx_byte); | ||
902 | continue; | ||
903 | } | ||
904 | } | ||
905 | |||
906 | pr_debug("baseband_usb_chr_work }\n"); | ||
907 | } | ||
908 | |||
909 | /* usb character file operations */ | ||
910 | |||
911 | static int baseband_usb_chr_open(struct inode *inode, struct file *file) | ||
912 | { | ||
913 | pr_debug("baseband_usb_chr_open\n"); | ||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | static int baseband_usb_chr_release(struct inode *inode, struct file *file) | ||
918 | { | ||
919 | pr_debug("baseband_usb_chr_release\n"); | ||
920 | return 0; | ||
921 | } | ||
922 | |||
923 | static ssize_t baseband_usb_chr_read(struct file *file, char *buf, | ||
924 | size_t count, loff_t *pos) | ||
925 | { | ||
926 | ssize_t ret; | ||
927 | |||
928 | pr_debug("baseband_usb_chr_read\n"); | ||
929 | |||
930 | ret = baseband_ipc_file_read(baseband_usb_chr->ipc, | ||
931 | file, buf, count, pos); | ||
932 | if (ret > 0) { | ||
933 | /* decrement count of available rx bytes */ | ||
934 | int val = atomic_read(&g_rx_count); | ||
935 | pr_debug("baseband_usb_chr_read - read %d unread %d\n", | ||
936 | ret, val - ret); | ||
937 | atomic_sub(ret, &g_rx_count); | ||
938 | } | ||
939 | return ret; | ||
940 | } | ||
941 | |||
942 | static ssize_t baseband_usb_chr_write(struct file *file, const char *buf, | ||
943 | size_t count, loff_t *pos) | ||
944 | { | ||
945 | pr_debug("baseband_usb_chr_write\n"); | ||
946 | return baseband_ipc_file_write(baseband_usb_chr->ipc, | ||
947 | file, buf, count, pos); | ||
948 | } | ||
949 | |||
950 | static long baseband_usb_chr_ioctl(struct file *file, unsigned int cmd, | ||
951 | unsigned long arg) | ||
952 | { | ||
953 | pr_debug("baseband_usb_chr_ioctl\n"); | ||
954 | switch (cmd) { | ||
955 | case TCFLSH: | ||
956 | pr_debug("TCFLSH\n"); | ||
957 | /* flush queued ipc transaction work */ | ||
958 | flush_workqueue(baseband_usb_chr->ipc->workqueue); | ||
959 | return 0; | ||
960 | case FIONREAD: | ||
961 | pr_debug("FIONREAD\n"); | ||
962 | /* return count of available rx bytes */ | ||
963 | { | ||
964 | int __user *p = (int __user *) arg; | ||
965 | int val = atomic_read(&g_rx_count); | ||
966 | if (put_user(val, p)) | ||
967 | break; | ||
968 | } | ||
969 | return 0; | ||
970 | default: | ||
971 | pr_err("unsupported ioctl cmd %x\n", cmd); | ||
972 | } | ||
973 | return -ENODEV; | ||
974 | } | ||
975 | |||
976 | static const struct file_operations baseband_usb_chr_fops = { | ||
977 | .open = baseband_usb_chr_open, | ||
978 | .release = baseband_usb_chr_release, | ||
979 | .read = baseband_usb_chr_read, | ||
980 | .write = baseband_usb_chr_write, | ||
981 | .unlocked_ioctl = baseband_usb_chr_ioctl, | ||
982 | }; | ||
983 | |||
984 | /* usb device driver functions */ | ||
985 | |||
986 | static void baseband_usb_close(struct baseband_usb *usb) | ||
987 | { | ||
988 | pr_debug("baseband_usb_close {\n"); | ||
989 | |||
990 | /* check input */ | ||
991 | if (!usb) | ||
992 | return; | ||
993 | |||
994 | /* close usb driver */ | ||
995 | if (usb->usb.driver) { | ||
996 | pr_debug("close usb driver {\n"); | ||
997 | usb_deregister(usb->usb.driver); | ||
998 | usb->usb.driver = (struct usb_driver *) 0; | ||
999 | pr_debug("close usb driver }\n"); | ||
1000 | } | ||
1001 | |||
1002 | /* close baseband ipc */ | ||
1003 | if (usb->ipc) { | ||
1004 | baseband_ipc_close(usb->ipc); | ||
1005 | usb->ipc = (struct baseband_ipc *) 0; | ||
1006 | } | ||
1007 | |||
1008 | /* free baseband usb structure */ | ||
1009 | kfree(usb); | ||
1010 | |||
1011 | pr_debug("baseband_usb_close }\n"); | ||
1012 | } | ||
1013 | |||
1014 | static struct baseband_usb *baseband_usb_open(unsigned int vid, | ||
1015 | unsigned int pid, | ||
1016 | unsigned int intf, | ||
1017 | work_func_t work_func, | ||
1018 | work_func_t rx_work_func, | ||
1019 | work_func_t tx_work_func) | ||
1020 | { | ||
1021 | struct baseband_usb *usb; | ||
1022 | int err; | ||
1023 | |||
1024 | pr_debug("baseband_usb_open {\n"); | ||
1025 | |||
1026 | /* allocate baseband usb structure */ | ||
1027 | usb = kzalloc(sizeof(struct baseband_usb), GFP_KERNEL); | ||
1028 | if (!usb) | ||
1029 | return (struct baseband_usb *) 0; | ||
1030 | baseband_usb_chr = usb; | ||
1031 | |||
1032 | /* open baseband ipc */ | ||
1033 | usb->ipc = baseband_ipc_open(work_func, | ||
1034 | rx_work_func, | ||
1035 | tx_work_func); | ||
1036 | if (!usb->ipc) { | ||
1037 | pr_err("open baseband ipc failed\n"); | ||
1038 | goto error_exit; | ||
1039 | } | ||
1040 | |||
1041 | /* open usb driver */ | ||
1042 | sprintf(baseband_usb_driver_name, | ||
1043 | "baseband_usb_%x_%x_%x", | ||
1044 | vid, pid, intf); | ||
1045 | baseband_usb_driver_id_table[0].match_flags | ||
1046 | = USB_DEVICE_ID_MATCH_DEVICE; | ||
1047 | baseband_usb_driver_id_table[0].idVendor = vid; | ||
1048 | baseband_usb_driver_id_table[0].idProduct = pid; | ||
1049 | usb->usb.driver = &baseband_usb_driver; | ||
1050 | err = usb_register(&baseband_usb_driver); | ||
1051 | if (err < 0) { | ||
1052 | pr_err("cannot open usb driver - err %d\n", err); | ||
1053 | goto error_exit; | ||
1054 | } | ||
1055 | |||
1056 | pr_debug("baseband_usb_open }\n"); | ||
1057 | return usb; | ||
1058 | |||
1059 | error_exit: | ||
1060 | baseband_usb_close(usb); | ||
1061 | baseband_usb_chr = (struct baseband_usb *) 0; | ||
1062 | return (struct baseband_usb *) 0; | ||
1063 | } | ||
1064 | |||
1065 | /* module init / exit functions */ | ||
1066 | |||
1067 | static int baseband_usb_chr_init(void) | ||
1068 | { | ||
1069 | int err; | ||
1070 | |||
1071 | pr_debug("baseband_usb_chr_init {\n"); | ||
1072 | |||
1073 | /* open baseband usb */ | ||
1074 | baseband_usb_chr = baseband_usb_open | ||
1075 | (baseband_usb_chr_vid, | ||
1076 | baseband_usb_chr_pid, | ||
1077 | baseband_usb_chr_intf, | ||
1078 | baseband_usb_chr_work, | ||
1079 | baseband_usb_chr_rx_urb_comp_work, | ||
1080 | (work_func_t) 0); | ||
1081 | if (!baseband_usb_chr) { | ||
1082 | pr_err("cannot open baseband usb chr\n"); | ||
1083 | err = -1; | ||
1084 | goto err1; | ||
1085 | } | ||
1086 | |||
1087 | /* register character device */ | ||
1088 | err = register_chrdev(BASEBAND_USB_CHR_DEV_MAJOR, | ||
1089 | BASEBAND_USB_CHR_DEV_NAME, | ||
1090 | &baseband_usb_chr_fops); | ||
1091 | if (err < 0) { | ||
1092 | pr_err("cannot register character device - %d\n", err); | ||
1093 | goto err2; | ||
1094 | } | ||
1095 | pr_debug("registered baseband usb character device - major %d\n", | ||
1096 | BASEBAND_USB_CHR_DEV_MAJOR); | ||
1097 | |||
1098 | pr_debug("baseband_usb_chr_init }\n"); | ||
1099 | return 0; | ||
1100 | err2: baseband_usb_close(baseband_usb_chr); | ||
1101 | baseband_usb_chr = (struct baseband_usb *) 0; | ||
1102 | err1: return err; | ||
1103 | } | ||
1104 | |||
1105 | static void baseband_usb_chr_exit(void) | ||
1106 | { | ||
1107 | pr_debug("baseband_usb_chr_exit {\n"); | ||
1108 | |||
1109 | /* unregister character device */ | ||
1110 | unregister_chrdev(BASEBAND_USB_CHR_DEV_MAJOR, | ||
1111 | BASEBAND_USB_CHR_DEV_NAME); | ||
1112 | |||
1113 | /* close baseband usb */ | ||
1114 | if (baseband_usb_chr) { | ||
1115 | baseband_usb_close(baseband_usb_chr); | ||
1116 | baseband_usb_chr = (struct baseband_usb *) 0; | ||
1117 | } | ||
1118 | |||
1119 | pr_debug("baseband_usb_chr_exit }\n"); | ||
1120 | } | ||
1121 | |||
1122 | module_init(baseband_usb_chr_init) | ||
1123 | module_exit(baseband_usb_chr_exit) | ||
1124 | |||
diff --git a/drivers/usb/serial/baseband_usb_chr.h b/drivers/usb/serial/baseband_usb_chr.h new file mode 100644 index 00000000000..7935e795a54 --- /dev/null +++ b/drivers/usb/serial/baseband_usb_chr.h | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * baseband_usb_chr.h | ||
3 | * | ||
4 | * USB character driver to communicate with baseband modems. | ||
5 | * | ||
6 | * Copyright (c) 2011, NVIDIA Corporation. | ||
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 as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | #ifndef __BASEBAND_USB_CHR_H__ | ||
24 | #define __BASEBAND_USB_CHR_H__ | ||
25 | |||
26 | #define BASEBAND_USB_CHR_DEV_NAME "baseband_usb_chr" | ||
27 | #define BASEBAND_USB_CHR_DEV_MAJOR 66 | ||
28 | |||
29 | #ifndef USB_CHR_RX_BUFSIZ | ||
30 | #define USB_CHR_RX_BUFSIZ (128*1024) | ||
31 | #endif /* USB_CHR_RX_BUFSIZ */ | ||
32 | |||
33 | #ifndef USB_CHR_TX_BUFSIZ | ||
34 | #define USB_CHR_TX_BUFSIZ (128*1024) | ||
35 | #endif /* USB_CHR_TX_BUFSIZ */ | ||
36 | |||
37 | #ifndef USB_CHR_TIMEOUT | ||
38 | #define USB_CHR_TIMEOUT 5000 /* ms */ | ||
39 | #endif /* USB_CHR_TIMEOUT */ | ||
40 | |||
41 | #ifndef BASEBAND_IPC_NUM_RX_BUF | ||
42 | #define BASEBAND_IPC_NUM_RX_BUF 32 | ||
43 | #endif /* BASEBAND_IPC_NUM_RX_BUF */ | ||
44 | |||
45 | #ifndef BASEBAND_IPC_NUM_TX_BUF | ||
46 | #define BASEBAND_IPC_NUM_TX_BUF 16 | ||
47 | #endif /* BASEBAND_IPC_NUM_TX_BUF */ | ||
48 | |||
49 | #ifndef BASEBAND_IPC_BUFSIZ | ||
50 | #define BASEBAND_IPC_BUFSIZ 65536 | ||
51 | #endif /* BASEBAND_IPC_BUFSIZ */ | ||
52 | |||
53 | struct baseband_ipc { | ||
54 | /* rx / tx data */ | ||
55 | struct semaphore buf_sem; | ||
56 | struct { | ||
57 | /* linked list of data buffers */ | ||
58 | struct list_head buf; | ||
59 | /* wait queue of processes trying to access data buffers */ | ||
60 | wait_queue_head_t wait; | ||
61 | } rx, tx, rx_free, tx_free; | ||
62 | unsigned char *ipc_rx; | ||
63 | unsigned char *ipc_tx; | ||
64 | /* work queue | ||
65 | * - queued per ipc transaction | ||
66 | * - initiated by either: | ||
67 | * = interrupt on gpio line (rx data available) | ||
68 | * = tx data packet being added to tx linked list | ||
69 | */ | ||
70 | struct workqueue_struct *workqueue; | ||
71 | struct work_struct work; | ||
72 | struct work_struct rx_work; | ||
73 | struct work_struct tx_work; | ||
74 | }; | ||
75 | |||
76 | struct baseband_ipc_buf { | ||
77 | struct list_head list; | ||
78 | /* data buffer */ | ||
79 | unsigned char data[BASEBAND_IPC_BUFSIZ]; | ||
80 | /* offset of first data byte */ | ||
81 | size_t offset; | ||
82 | /* number of valid data bytes */ | ||
83 | size_t count; | ||
84 | }; | ||
85 | |||
86 | struct baseband_usb { | ||
87 | struct baseband_ipc *ipc; | ||
88 | struct { | ||
89 | struct usb_driver *driver; | ||
90 | struct usb_device *device; | ||
91 | struct usb_interface *interface; | ||
92 | struct { | ||
93 | struct { | ||
94 | unsigned int in; | ||
95 | unsigned int out; | ||
96 | } isoch, bulk, interrupt; | ||
97 | } pipe; | ||
98 | /* currently active rx urb */ | ||
99 | struct urb *rx_urb; | ||
100 | /* currently active tx urb */ | ||
101 | struct urb *tx_urb; | ||
102 | } usb; | ||
103 | }; | ||
104 | |||
105 | #endif /* __BASEBAND_USB_CHR_H__ */ | ||
106 | |||
diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c new file mode 100644 index 00000000000..3cfc762f505 --- /dev/null +++ b/drivers/usb/serial/ezusb.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * EZ-USB specific functions used by some of the USB to Serial drivers. | ||
3 | * | ||
4 | * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/tty.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/usb.h> | ||
18 | #include <linux/usb/serial.h> | ||
19 | |||
20 | /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ | ||
21 | #define CPUCS_REG 0x7F92 | ||
22 | |||
23 | int ezusb_writememory(struct usb_serial *serial, int address, | ||
24 | unsigned char *data, int length, __u8 request) | ||
25 | { | ||
26 | int result; | ||
27 | unsigned char *transfer_buffer; | ||
28 | |||
29 | /* dbg("ezusb_writememory %x, %d", address, length); */ | ||
30 | if (!serial->dev) { | ||
31 | printk(KERN_ERR "ezusb: %s - no physical device present, " | ||
32 | "failing.\n", __func__); | ||
33 | return -ENODEV; | ||
34 | } | ||
35 | |||
36 | transfer_buffer = kmemdup(data, length, GFP_KERNEL); | ||
37 | if (!transfer_buffer) { | ||
38 | dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", | ||
39 | __func__, length); | ||
40 | return -ENOMEM; | ||
41 | } | ||
42 | result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | ||
43 | request, 0x40, address, 0, transfer_buffer, length, 3000); | ||
44 | kfree(transfer_buffer); | ||
45 | return result; | ||
46 | } | ||
47 | EXPORT_SYMBOL_GPL(ezusb_writememory); | ||
48 | |||
49 | int ezusb_set_reset(struct usb_serial *serial, unsigned char reset_bit) | ||
50 | { | ||
51 | int response; | ||
52 | |||
53 | /* dbg("%s - %d", __func__, reset_bit); */ | ||
54 | response = ezusb_writememory(serial, CPUCS_REG, &reset_bit, 1, 0xa0); | ||
55 | if (response < 0) | ||
56 | dev_err(&serial->dev->dev, "%s- %d failed\n", | ||
57 | __func__, reset_bit); | ||
58 | return response; | ||
59 | } | ||
60 | EXPORT_SYMBOL_GPL(ezusb_set_reset); | ||
61 | |||
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c new file mode 100644 index 00000000000..fe3ffe1459b --- /dev/null +++ b/drivers/usb/storage/libusual.c | |||
@@ -0,0 +1,243 @@ | |||
1 | /* | ||
2 | * libusual | ||
3 | * | ||
4 | * The libusual contains the table of devices common for ub and usb-storage. | ||
5 | */ | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/usb.h> | ||
9 | #include <linux/usb_usual.h> | ||
10 | #include <linux/vmalloc.h> | ||
11 | #include <linux/kthread.h> | ||
12 | #include <linux/mutex.h> | ||
13 | |||
14 | /* | ||
15 | */ | ||
16 | #define USU_MOD_FL_THREAD 1 /* Thread is running */ | ||
17 | #define USU_MOD_FL_PRESENT 2 /* The module is loaded */ | ||
18 | |||
19 | struct mod_status { | ||
20 | unsigned long fls; | ||
21 | }; | ||
22 | |||
23 | static struct mod_status stat[3]; | ||
24 | static DEFINE_SPINLOCK(usu_lock); | ||
25 | |||
26 | /* | ||
27 | */ | ||
28 | #define USB_US_DEFAULT_BIAS USB_US_TYPE_STOR | ||
29 | static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS); | ||
30 | |||
31 | #define BIAS_NAME_SIZE (sizeof("usb-storage")) | ||
32 | static const char *bias_names[3] = { "none", "usb-storage", "ub" }; | ||
33 | |||
34 | static DEFINE_MUTEX(usu_probe_mutex); | ||
35 | static DECLARE_COMPLETION(usu_end_notify); | ||
36 | static atomic_t total_threads = ATOMIC_INIT(0); | ||
37 | |||
38 | static int usu_probe_thread(void *arg); | ||
39 | |||
40 | /* | ||
41 | * @type: the module type as an integer | ||
42 | */ | ||
43 | void usb_usual_set_present(int type) | ||
44 | { | ||
45 | struct mod_status *st; | ||
46 | unsigned long flags; | ||
47 | |||
48 | if (type <= 0 || type >= 3) | ||
49 | return; | ||
50 | st = &stat[type]; | ||
51 | spin_lock_irqsave(&usu_lock, flags); | ||
52 | st->fls |= USU_MOD_FL_PRESENT; | ||
53 | spin_unlock_irqrestore(&usu_lock, flags); | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(usb_usual_set_present); | ||
56 | |||
57 | void usb_usual_clear_present(int type) | ||
58 | { | ||
59 | struct mod_status *st; | ||
60 | unsigned long flags; | ||
61 | |||
62 | if (type <= 0 || type >= 3) | ||
63 | return; | ||
64 | st = &stat[type]; | ||
65 | spin_lock_irqsave(&usu_lock, flags); | ||
66 | st->fls &= ~USU_MOD_FL_PRESENT; | ||
67 | spin_unlock_irqrestore(&usu_lock, flags); | ||
68 | } | ||
69 | EXPORT_SYMBOL_GPL(usb_usual_clear_present); | ||
70 | |||
71 | /* | ||
72 | * Match the calling driver type against the table. | ||
73 | * Returns: 0 if the device matches. | ||
74 | */ | ||
75 | int usb_usual_check_type(const struct usb_device_id *id, int caller_type) | ||
76 | { | ||
77 | int id_type = USB_US_TYPE(id->driver_info); | ||
78 | |||
79 | if (caller_type <= 0 || caller_type >= 3) | ||
80 | return -EINVAL; | ||
81 | |||
82 | /* Drivers grab fixed assignment devices */ | ||
83 | if (id_type == caller_type) | ||
84 | return 0; | ||
85 | /* Drivers grab devices biased to them */ | ||
86 | if (id_type == USB_US_TYPE_NONE && caller_type == atomic_read(&usu_bias)) | ||
87 | return 0; | ||
88 | return -ENODEV; | ||
89 | } | ||
90 | EXPORT_SYMBOL_GPL(usb_usual_check_type); | ||
91 | |||
92 | /* | ||
93 | */ | ||
94 | static int usu_probe(struct usb_interface *intf, | ||
95 | const struct usb_device_id *id) | ||
96 | { | ||
97 | int rc; | ||
98 | unsigned long type; | ||
99 | struct task_struct* task; | ||
100 | unsigned long flags; | ||
101 | |||
102 | type = USB_US_TYPE(id->driver_info); | ||
103 | if (type == 0) | ||
104 | type = atomic_read(&usu_bias); | ||
105 | |||
106 | spin_lock_irqsave(&usu_lock, flags); | ||
107 | if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) { | ||
108 | spin_unlock_irqrestore(&usu_lock, flags); | ||
109 | return -ENXIO; | ||
110 | } | ||
111 | stat[type].fls |= USU_MOD_FL_THREAD; | ||
112 | spin_unlock_irqrestore(&usu_lock, flags); | ||
113 | |||
114 | task = kthread_run(usu_probe_thread, (void*)type, "libusual_%ld", type); | ||
115 | if (IS_ERR(task)) { | ||
116 | rc = PTR_ERR(task); | ||
117 | printk(KERN_WARNING "libusual: " | ||
118 | "Unable to start the thread for %s: %d\n", | ||
119 | bias_names[type], rc); | ||
120 | spin_lock_irqsave(&usu_lock, flags); | ||
121 | stat[type].fls &= ~USU_MOD_FL_THREAD; | ||
122 | spin_unlock_irqrestore(&usu_lock, flags); | ||
123 | return rc; /* Not being -ENXIO causes a message printed */ | ||
124 | } | ||
125 | atomic_inc(&total_threads); | ||
126 | |||
127 | return -ENXIO; | ||
128 | } | ||
129 | |||
130 | static void usu_disconnect(struct usb_interface *intf) | ||
131 | { | ||
132 | ; /* We should not be here. */ | ||
133 | } | ||
134 | |||
135 | static struct usb_driver usu_driver = { | ||
136 | .name = "libusual", | ||
137 | .probe = usu_probe, | ||
138 | .disconnect = usu_disconnect, | ||
139 | .id_table = usb_storage_usb_ids, | ||
140 | }; | ||
141 | |||
142 | /* | ||
143 | * A whole new thread for a purpose of request_module seems quite stupid. | ||
144 | * The request_module forks once inside again. However, if we attempt | ||
145 | * to load a storage module from our own modprobe thread, that module | ||
146 | * references our symbols, which cannot be resolved until our module is | ||
147 | * initialized. I wish there was a way to wait for the end of initialization. | ||
148 | * The module notifier reports MODULE_STATE_COMING only. | ||
149 | * So, we wait until module->init ends as the next best thing. | ||
150 | */ | ||
151 | static int usu_probe_thread(void *arg) | ||
152 | { | ||
153 | int type = (unsigned long) arg; | ||
154 | struct mod_status *st = &stat[type]; | ||
155 | int rc; | ||
156 | unsigned long flags; | ||
157 | |||
158 | mutex_lock(&usu_probe_mutex); | ||
159 | rc = request_module(bias_names[type]); | ||
160 | spin_lock_irqsave(&usu_lock, flags); | ||
161 | if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) { | ||
162 | /* | ||
163 | * This should not happen, but let us keep tabs on it. | ||
164 | */ | ||
165 | printk(KERN_NOTICE "libusual: " | ||
166 | "modprobe for %s succeeded, but module is not present\n", | ||
167 | bias_names[type]); | ||
168 | } | ||
169 | st->fls &= ~USU_MOD_FL_THREAD; | ||
170 | spin_unlock_irqrestore(&usu_lock, flags); | ||
171 | mutex_unlock(&usu_probe_mutex); | ||
172 | |||
173 | complete_and_exit(&usu_end_notify, 0); | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | */ | ||
178 | static int __init usb_usual_init(void) | ||
179 | { | ||
180 | int rc; | ||
181 | |||
182 | mutex_lock(&usu_probe_mutex); | ||
183 | rc = usb_register(&usu_driver); | ||
184 | mutex_unlock(&usu_probe_mutex); | ||
185 | return rc; | ||
186 | } | ||
187 | |||
188 | static void __exit usb_usual_exit(void) | ||
189 | { | ||
190 | /* | ||
191 | * We do not check for any drivers present, because | ||
192 | * they keep us pinned with symbol references. | ||
193 | */ | ||
194 | |||
195 | usb_deregister(&usu_driver); | ||
196 | |||
197 | while (atomic_read(&total_threads) > 0) { | ||
198 | wait_for_completion(&usu_end_notify); | ||
199 | atomic_dec(&total_threads); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * Validate and accept the bias parameter. | ||
205 | */ | ||
206 | static int usu_set_bias(const char *bias_s, struct kernel_param *kp) | ||
207 | { | ||
208 | int i; | ||
209 | int len; | ||
210 | int bias_n = 0; | ||
211 | |||
212 | len = strlen(bias_s); | ||
213 | if (len == 0) | ||
214 | return -EDOM; | ||
215 | if (bias_s[len-1] == '\n') | ||
216 | --len; | ||
217 | |||
218 | for (i = 1; i < 3; i++) { | ||
219 | if (strncmp(bias_s, bias_names[i], len) == 0) { | ||
220 | bias_n = i; | ||
221 | break; | ||
222 | } | ||
223 | } | ||
224 | if (bias_n == 0) | ||
225 | return -EINVAL; | ||
226 | |||
227 | atomic_set(&usu_bias, bias_n); | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static int usu_get_bias(char *buffer, struct kernel_param *kp) | ||
232 | { | ||
233 | return strlen(strcpy(buffer, bias_names[atomic_read(&usu_bias)])); | ||
234 | } | ||
235 | |||
236 | module_init(usb_usual_init); | ||
237 | module_exit(usb_usual_exit); | ||
238 | |||
239 | module_param_call(bias, usu_set_bias, usu_get_bias, NULL, S_IRUGO|S_IWUSR); | ||
240 | __MODULE_PARM_TYPE(bias, "string"); | ||
241 | MODULE_PARM_DESC(bias, "Bias to usb-storage or ub"); | ||
242 | |||
243 | MODULE_LICENSE("GPL"); | ||