diff options
Diffstat (limited to 'drivers')
216 files changed, 10361 insertions, 6190 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index feab124d8e05..cbfc81579c9a 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -194,7 +194,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) | |||
194 | 194 | ||
195 | if (!device->flags.power_manageable) { | 195 | if (!device->flags.power_manageable) { |
196 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", | 196 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", |
197 | device->dev.kobj.name)); | 197 | kobject_name(&device->dev.kobj))); |
198 | return -ENODEV; | 198 | return -ENODEV; |
199 | } | 199 | } |
200 | /* | 200 | /* |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 1e8287b4f40c..1f6fb38de017 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -276,21 +276,12 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr, | |||
276 | 276 | ||
277 | static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) | 277 | static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) |
278 | { | 278 | { |
279 | #ifdef CONFIG_GENERIC_CLOCKEVENTS | ||
280 | unsigned long reason; | 279 | unsigned long reason; |
281 | 280 | ||
282 | reason = pr->power.timer_broadcast_on_state < INT_MAX ? | 281 | reason = pr->power.timer_broadcast_on_state < INT_MAX ? |
283 | CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF; | 282 | CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF; |
284 | 283 | ||
285 | clockevents_notify(reason, &pr->id); | 284 | clockevents_notify(reason, &pr->id); |
286 | #else | ||
287 | cpumask_t mask = cpumask_of_cpu(pr->id); | ||
288 | |||
289 | if (pr->power.timer_broadcast_on_state < INT_MAX) | ||
290 | on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1); | ||
291 | else | ||
292 | on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1); | ||
293 | #endif | ||
294 | } | 285 | } |
295 | 286 | ||
296 | /* Power(C) State timer broadcast control */ | 287 | /* Power(C) State timer broadcast control */ |
@@ -298,8 +289,6 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, | |||
298 | struct acpi_processor_cx *cx, | 289 | struct acpi_processor_cx *cx, |
299 | int broadcast) | 290 | int broadcast) |
300 | { | 291 | { |
301 | #ifdef CONFIG_GENERIC_CLOCKEVENTS | ||
302 | |||
303 | int state = cx - pr->power.states; | 292 | int state = cx - pr->power.states; |
304 | 293 | ||
305 | if (state >= pr->power.timer_broadcast_on_state) { | 294 | if (state >= pr->power.timer_broadcast_on_state) { |
@@ -309,7 +298,6 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, | |||
309 | CLOCK_EVT_NOTIFY_BROADCAST_EXIT; | 298 | CLOCK_EVT_NOTIFY_BROADCAST_EXIT; |
310 | clockevents_notify(reason, &pr->id); | 299 | clockevents_notify(reason, &pr->id); |
311 | } | 300 | } |
312 | #endif | ||
313 | } | 301 | } |
314 | 302 | ||
315 | #else | 303 | #else |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 64620d668742..5b4d462117cf 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -319,16 +319,18 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv) | |||
319 | return !acpi_match_device_ids(acpi_dev, acpi_drv->ids); | 319 | return !acpi_match_device_ids(acpi_dev, acpi_drv->ids); |
320 | } | 320 | } |
321 | 321 | ||
322 | static int acpi_device_uevent(struct device *dev, char **envp, int num_envp, | 322 | static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
323 | char *buffer, int buffer_size) | ||
324 | { | 323 | { |
325 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 324 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
325 | int len; | ||
326 | 326 | ||
327 | strcpy(buffer, "MODALIAS="); | 327 | if (add_uevent_var(env, "MODALIAS=")) |
328 | if (create_modalias(acpi_dev, buffer + 9, buffer_size - 9) > 0) { | 328 | return -ENOMEM; |
329 | envp[0] = buffer; | 329 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], |
330 | envp[1] = NULL; | 330 | sizeof(env->buf) - env->buflen); |
331 | } | 331 | if (len >= (sizeof(env->buf) - env->buflen)) |
332 | return -ENOMEM; | ||
333 | env->buflen += len; | ||
332 | return 0; | 334 | return 0; |
333 | } | 335 | } |
334 | 336 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d05891f16282..b8a2095cb5ee 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -316,7 +316,7 @@ static int acpi_video_output_get(struct output_device *od) | |||
316 | { | 316 | { |
317 | unsigned long state; | 317 | unsigned long state; |
318 | struct acpi_video_device *vd = | 318 | struct acpi_video_device *vd = |
319 | (struct acpi_video_device *)class_get_devdata(&od->class_dev); | 319 | (struct acpi_video_device *)dev_get_drvdata(&od->dev); |
320 | acpi_video_device_get_state(vd, &state); | 320 | acpi_video_device_get_state(vd, &state); |
321 | return (int)state; | 321 | return (int)state; |
322 | } | 322 | } |
@@ -325,7 +325,7 @@ static int acpi_video_output_set(struct output_device *od) | |||
325 | { | 325 | { |
326 | unsigned long state = od->request_state; | 326 | unsigned long state = od->request_state; |
327 | struct acpi_video_device *vd= | 327 | struct acpi_video_device *vd= |
328 | (struct acpi_video_device *)class_get_devdata(&od->class_dev); | 328 | (struct acpi_video_device *)dev_get_drvdata(&od->dev); |
329 | return acpi_video_device_set_state(vd, state); | 329 | return acpi_video_device_set_state(vd, state); |
330 | } | 330 | } |
331 | 331 | ||
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 268e301775fc..6b94fb7be5f2 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c | |||
@@ -44,15 +44,12 @@ static int amba_match(struct device *dev, struct device_driver *drv) | |||
44 | } | 44 | } |
45 | 45 | ||
46 | #ifdef CONFIG_HOTPLUG | 46 | #ifdef CONFIG_HOTPLUG |
47 | static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz) | 47 | static int amba_uevent(struct device *dev, struct kobj_uevent_env *env) |
48 | { | 48 | { |
49 | struct amba_device *pcdev = to_amba_device(dev); | 49 | struct amba_device *pcdev = to_amba_device(dev); |
50 | int retval = 0, i = 0, len = 0; | 50 | int retval = 0; |
51 | 51 | ||
52 | retval = add_uevent_var(envp, nr_env, &i, | 52 | retval = add_uevent_var(env, "AMBA_ID=%08x", pcdev->periphid); |
53 | buf, bufsz, &len, | ||
54 | "AMBA_ID=%08x", pcdev->periphid); | ||
55 | envp[i] = NULL; | ||
56 | return retval; | 53 | return retval; |
57 | } | 54 | } |
58 | #else | 55 | #else |
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 5d6312e33490..d7da109c24fd 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -1,5 +1,13 @@ | |||
1 | menu "Generic Driver Options" | 1 | menu "Generic Driver Options" |
2 | 2 | ||
3 | config UEVENT_HELPER_PATH | ||
4 | string "path to uevent helper" | ||
5 | depends on HOTPLUG | ||
6 | default "/sbin/hotplug" | ||
7 | help | ||
8 | Path to uevent helper program forked by the kernel for | ||
9 | every uevent. | ||
10 | |||
3 | config STANDALONE | 11 | config STANDALONE |
4 | bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL | 12 | bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL |
5 | default y | 13 | default y |
diff --git a/drivers/base/base.h b/drivers/base/base.h index 47eb02d9f1af..10b2fb6c9ce6 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -18,8 +18,6 @@ extern int attribute_container_init(void); | |||
18 | extern int bus_add_device(struct device * dev); | 18 | extern int bus_add_device(struct device * dev); |
19 | extern void bus_attach_device(struct device * dev); | 19 | extern void bus_attach_device(struct device * dev); |
20 | extern void bus_remove_device(struct device * dev); | 20 | extern void bus_remove_device(struct device * dev); |
21 | extern struct bus_type *get_bus(struct bus_type * bus); | ||
22 | extern void put_bus(struct bus_type * bus); | ||
23 | 21 | ||
24 | extern int bus_add_driver(struct device_driver *); | 22 | extern int bus_add_driver(struct device_driver *); |
25 | extern void bus_remove_driver(struct device_driver *); | 23 | extern void bus_remove_driver(struct device_driver *); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 61c67526a656..9a19b071c573 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -30,6 +30,17 @@ | |||
30 | static int __must_check bus_rescan_devices_helper(struct device *dev, | 30 | static int __must_check bus_rescan_devices_helper(struct device *dev, |
31 | void *data); | 31 | void *data); |
32 | 32 | ||
33 | static struct bus_type *bus_get(struct bus_type *bus) | ||
34 | { | ||
35 | return bus ? container_of(kset_get(&bus->subsys), | ||
36 | struct bus_type, subsys) : NULL; | ||
37 | } | ||
38 | |||
39 | static void bus_put(struct bus_type *bus) | ||
40 | { | ||
41 | kset_put(&bus->subsys); | ||
42 | } | ||
43 | |||
33 | static ssize_t | 44 | static ssize_t |
34 | drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 45 | drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) |
35 | { | 46 | { |
@@ -78,7 +89,7 @@ static void driver_release(struct kobject * kobj) | |||
78 | */ | 89 | */ |
79 | } | 90 | } |
80 | 91 | ||
81 | static struct kobj_type ktype_driver = { | 92 | static struct kobj_type driver_ktype = { |
82 | .sysfs_ops = &driver_sysfs_ops, | 93 | .sysfs_ops = &driver_sysfs_ops, |
83 | .release = driver_release, | 94 | .release = driver_release, |
84 | }; | 95 | }; |
@@ -122,9 +133,9 @@ static struct sysfs_ops bus_sysfs_ops = { | |||
122 | int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) | 133 | int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) |
123 | { | 134 | { |
124 | int error; | 135 | int error; |
125 | if (get_bus(bus)) { | 136 | if (bus_get(bus)) { |
126 | error = sysfs_create_file(&bus->subsys.kobj, &attr->attr); | 137 | error = sysfs_create_file(&bus->subsys.kobj, &attr->attr); |
127 | put_bus(bus); | 138 | bus_put(bus); |
128 | } else | 139 | } else |
129 | error = -EINVAL; | 140 | error = -EINVAL; |
130 | return error; | 141 | return error; |
@@ -132,9 +143,9 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) | |||
132 | 143 | ||
133 | void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) | 144 | void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) |
134 | { | 145 | { |
135 | if (get_bus(bus)) { | 146 | if (bus_get(bus)) { |
136 | sysfs_remove_file(&bus->subsys.kobj, &attr->attr); | 147 | sysfs_remove_file(&bus->subsys.kobj, &attr->attr); |
137 | put_bus(bus); | 148 | bus_put(bus); |
138 | } | 149 | } |
139 | } | 150 | } |
140 | 151 | ||
@@ -172,7 +183,7 @@ static int driver_helper(struct device *dev, void *data) | |||
172 | static ssize_t driver_unbind(struct device_driver *drv, | 183 | static ssize_t driver_unbind(struct device_driver *drv, |
173 | const char *buf, size_t count) | 184 | const char *buf, size_t count) |
174 | { | 185 | { |
175 | struct bus_type *bus = get_bus(drv->bus); | 186 | struct bus_type *bus = bus_get(drv->bus); |
176 | struct device *dev; | 187 | struct device *dev; |
177 | int err = -ENODEV; | 188 | int err = -ENODEV; |
178 | 189 | ||
@@ -186,7 +197,7 @@ static ssize_t driver_unbind(struct device_driver *drv, | |||
186 | err = count; | 197 | err = count; |
187 | } | 198 | } |
188 | put_device(dev); | 199 | put_device(dev); |
189 | put_bus(bus); | 200 | bus_put(bus); |
190 | return err; | 201 | return err; |
191 | } | 202 | } |
192 | static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); | 203 | static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); |
@@ -199,7 +210,7 @@ static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); | |||
199 | static ssize_t driver_bind(struct device_driver *drv, | 210 | static ssize_t driver_bind(struct device_driver *drv, |
200 | const char *buf, size_t count) | 211 | const char *buf, size_t count) |
201 | { | 212 | { |
202 | struct bus_type *bus = get_bus(drv->bus); | 213 | struct bus_type *bus = bus_get(drv->bus); |
203 | struct device *dev; | 214 | struct device *dev; |
204 | int err = -ENODEV; | 215 | int err = -ENODEV; |
205 | 216 | ||
@@ -219,7 +230,7 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
219 | err = -ENODEV; | 230 | err = -ENODEV; |
220 | } | 231 | } |
221 | put_device(dev); | 232 | put_device(dev); |
222 | put_bus(bus); | 233 | bus_put(bus); |
223 | return err; | 234 | return err; |
224 | } | 235 | } |
225 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | 236 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); |
@@ -430,7 +441,7 @@ static inline void remove_deprecated_bus_links(struct device *dev) { } | |||
430 | */ | 441 | */ |
431 | int bus_add_device(struct device * dev) | 442 | int bus_add_device(struct device * dev) |
432 | { | 443 | { |
433 | struct bus_type * bus = get_bus(dev->bus); | 444 | struct bus_type * bus = bus_get(dev->bus); |
434 | int error = 0; | 445 | int error = 0; |
435 | 446 | ||
436 | if (bus) { | 447 | if (bus) { |
@@ -459,7 +470,7 @@ out_subsys: | |||
459 | out_id: | 470 | out_id: |
460 | device_remove_attrs(bus, dev); | 471 | device_remove_attrs(bus, dev); |
461 | out_put: | 472 | out_put: |
462 | put_bus(dev->bus); | 473 | bus_put(dev->bus); |
463 | return error; | 474 | return error; |
464 | } | 475 | } |
465 | 476 | ||
@@ -509,7 +520,7 @@ void bus_remove_device(struct device * dev) | |||
509 | } | 520 | } |
510 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); | 521 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); |
511 | device_release_driver(dev); | 522 | device_release_driver(dev); |
512 | put_bus(dev->bus); | 523 | bus_put(dev->bus); |
513 | } | 524 | } |
514 | } | 525 | } |
515 | 526 | ||
@@ -568,32 +579,29 @@ static void remove_bind_files(struct device_driver *drv) | |||
568 | driver_remove_file(drv, &driver_attr_unbind); | 579 | driver_remove_file(drv, &driver_attr_unbind); |
569 | } | 580 | } |
570 | 581 | ||
582 | static BUS_ATTR(drivers_probe, S_IWUSR, NULL, store_drivers_probe); | ||
583 | static BUS_ATTR(drivers_autoprobe, S_IWUSR | S_IRUGO, | ||
584 | show_drivers_autoprobe, store_drivers_autoprobe); | ||
585 | |||
571 | static int add_probe_files(struct bus_type *bus) | 586 | static int add_probe_files(struct bus_type *bus) |
572 | { | 587 | { |
573 | int retval; | 588 | int retval; |
574 | 589 | ||
575 | bus->drivers_probe_attr.attr.name = "drivers_probe"; | 590 | retval = bus_create_file(bus, &bus_attr_drivers_probe); |
576 | bus->drivers_probe_attr.attr.mode = S_IWUSR; | ||
577 | bus->drivers_probe_attr.store = store_drivers_probe; | ||
578 | retval = bus_create_file(bus, &bus->drivers_probe_attr); | ||
579 | if (retval) | 591 | if (retval) |
580 | goto out; | 592 | goto out; |
581 | 593 | ||
582 | bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe"; | 594 | retval = bus_create_file(bus, &bus_attr_drivers_autoprobe); |
583 | bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO; | ||
584 | bus->drivers_autoprobe_attr.show = show_drivers_autoprobe; | ||
585 | bus->drivers_autoprobe_attr.store = store_drivers_autoprobe; | ||
586 | retval = bus_create_file(bus, &bus->drivers_autoprobe_attr); | ||
587 | if (retval) | 595 | if (retval) |
588 | bus_remove_file(bus, &bus->drivers_probe_attr); | 596 | bus_remove_file(bus, &bus_attr_drivers_probe); |
589 | out: | 597 | out: |
590 | return retval; | 598 | return retval; |
591 | } | 599 | } |
592 | 600 | ||
593 | static void remove_probe_files(struct bus_type *bus) | 601 | static void remove_probe_files(struct bus_type *bus) |
594 | { | 602 | { |
595 | bus_remove_file(bus, &bus->drivers_autoprobe_attr); | 603 | bus_remove_file(bus, &bus_attr_drivers_autoprobe); |
596 | bus_remove_file(bus, &bus->drivers_probe_attr); | 604 | bus_remove_file(bus, &bus_attr_drivers_probe); |
597 | } | 605 | } |
598 | #else | 606 | #else |
599 | static inline int add_bind_files(struct device_driver *drv) { return 0; } | 607 | static inline int add_bind_files(struct device_driver *drv) { return 0; } |
@@ -602,6 +610,17 @@ static inline int add_probe_files(struct bus_type *bus) { return 0; } | |||
602 | static inline void remove_probe_files(struct bus_type *bus) {} | 610 | static inline void remove_probe_files(struct bus_type *bus) {} |
603 | #endif | 611 | #endif |
604 | 612 | ||
613 | static ssize_t driver_uevent_store(struct device_driver *drv, | ||
614 | const char *buf, size_t count) | ||
615 | { | ||
616 | enum kobject_action action; | ||
617 | |||
618 | if (kobject_action_type(buf, count, &action) == 0) | ||
619 | kobject_uevent(&drv->kobj, action); | ||
620 | return count; | ||
621 | } | ||
622 | static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); | ||
623 | |||
605 | /** | 624 | /** |
606 | * bus_add_driver - Add a driver to the bus. | 625 | * bus_add_driver - Add a driver to the bus. |
607 | * @drv: driver. | 626 | * @drv: driver. |
@@ -609,7 +628,7 @@ static inline void remove_probe_files(struct bus_type *bus) {} | |||
609 | */ | 628 | */ |
610 | int bus_add_driver(struct device_driver *drv) | 629 | int bus_add_driver(struct device_driver *drv) |
611 | { | 630 | { |
612 | struct bus_type * bus = get_bus(drv->bus); | 631 | struct bus_type * bus = bus_get(drv->bus); |
613 | int error = 0; | 632 | int error = 0; |
614 | 633 | ||
615 | if (!bus) | 634 | if (!bus) |
@@ -632,6 +651,11 @@ int bus_add_driver(struct device_driver *drv) | |||
632 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); | 651 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); |
633 | module_add_driver(drv->owner, drv); | 652 | module_add_driver(drv->owner, drv); |
634 | 653 | ||
654 | error = driver_create_file(drv, &driver_attr_uevent); | ||
655 | if (error) { | ||
656 | printk(KERN_ERR "%s: uevent attr (%s) failed\n", | ||
657 | __FUNCTION__, drv->name); | ||
658 | } | ||
635 | error = driver_add_attrs(bus, drv); | 659 | error = driver_add_attrs(bus, drv); |
636 | if (error) { | 660 | if (error) { |
637 | /* How the hell do we get out of this pickle? Give up */ | 661 | /* How the hell do we get out of this pickle? Give up */ |
@@ -649,7 +673,7 @@ int bus_add_driver(struct device_driver *drv) | |||
649 | out_unregister: | 673 | out_unregister: |
650 | kobject_unregister(&drv->kobj); | 674 | kobject_unregister(&drv->kobj); |
651 | out_put_bus: | 675 | out_put_bus: |
652 | put_bus(bus); | 676 | bus_put(bus); |
653 | return error; | 677 | return error; |
654 | } | 678 | } |
655 | 679 | ||
@@ -669,12 +693,13 @@ void bus_remove_driver(struct device_driver * drv) | |||
669 | 693 | ||
670 | remove_bind_files(drv); | 694 | remove_bind_files(drv); |
671 | driver_remove_attrs(drv->bus, drv); | 695 | driver_remove_attrs(drv->bus, drv); |
696 | driver_remove_file(drv, &driver_attr_uevent); | ||
672 | klist_remove(&drv->knode_bus); | 697 | klist_remove(&drv->knode_bus); |
673 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); | 698 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); |
674 | driver_detach(drv); | 699 | driver_detach(drv); |
675 | module_remove_driver(drv); | 700 | module_remove_driver(drv); |
676 | kobject_unregister(&drv->kobj); | 701 | kobject_unregister(&drv->kobj); |
677 | put_bus(drv->bus); | 702 | bus_put(drv->bus); |
678 | } | 703 | } |
679 | 704 | ||
680 | 705 | ||
@@ -729,18 +754,6 @@ int device_reprobe(struct device *dev) | |||
729 | } | 754 | } |
730 | EXPORT_SYMBOL_GPL(device_reprobe); | 755 | EXPORT_SYMBOL_GPL(device_reprobe); |
731 | 756 | ||
732 | struct bus_type *get_bus(struct bus_type *bus) | ||
733 | { | ||
734 | return bus ? container_of(subsys_get(&bus->subsys), | ||
735 | struct bus_type, subsys) : NULL; | ||
736 | } | ||
737 | |||
738 | void put_bus(struct bus_type * bus) | ||
739 | { | ||
740 | subsys_put(&bus->subsys); | ||
741 | } | ||
742 | |||
743 | |||
744 | /** | 757 | /** |
745 | * find_bus - locate bus by name. | 758 | * find_bus - locate bus by name. |
746 | * @name: name of bus. | 759 | * @name: name of bus. |
@@ -808,6 +821,17 @@ static void klist_devices_put(struct klist_node *n) | |||
808 | put_device(dev); | 821 | put_device(dev); |
809 | } | 822 | } |
810 | 823 | ||
824 | static ssize_t bus_uevent_store(struct bus_type *bus, | ||
825 | const char *buf, size_t count) | ||
826 | { | ||
827 | enum kobject_action action; | ||
828 | |||
829 | if (kobject_action_type(buf, count, &action) == 0) | ||
830 | kobject_uevent(&bus->subsys.kobj, action); | ||
831 | return count; | ||
832 | } | ||
833 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); | ||
834 | |||
811 | /** | 835 | /** |
812 | * bus_register - register a bus with the system. | 836 | * bus_register - register a bus with the system. |
813 | * @bus: bus. | 837 | * @bus: bus. |
@@ -826,11 +850,16 @@ int bus_register(struct bus_type * bus) | |||
826 | if (retval) | 850 | if (retval) |
827 | goto out; | 851 | goto out; |
828 | 852 | ||
829 | subsys_set_kset(bus, bus_subsys); | 853 | bus->subsys.kobj.kset = &bus_subsys; |
854 | |||
830 | retval = subsystem_register(&bus->subsys); | 855 | retval = subsystem_register(&bus->subsys); |
831 | if (retval) | 856 | if (retval) |
832 | goto out; | 857 | goto out; |
833 | 858 | ||
859 | retval = bus_create_file(bus, &bus_attr_uevent); | ||
860 | if (retval) | ||
861 | goto bus_uevent_fail; | ||
862 | |||
834 | kobject_set_name(&bus->devices.kobj, "devices"); | 863 | kobject_set_name(&bus->devices.kobj, "devices"); |
835 | bus->devices.kobj.parent = &bus->subsys.kobj; | 864 | bus->devices.kobj.parent = &bus->subsys.kobj; |
836 | retval = kset_register(&bus->devices); | 865 | retval = kset_register(&bus->devices); |
@@ -839,7 +868,7 @@ int bus_register(struct bus_type * bus) | |||
839 | 868 | ||
840 | kobject_set_name(&bus->drivers.kobj, "drivers"); | 869 | kobject_set_name(&bus->drivers.kobj, "drivers"); |
841 | bus->drivers.kobj.parent = &bus->subsys.kobj; | 870 | bus->drivers.kobj.parent = &bus->subsys.kobj; |
842 | bus->drivers.ktype = &ktype_driver; | 871 | bus->drivers.ktype = &driver_ktype; |
843 | retval = kset_register(&bus->drivers); | 872 | retval = kset_register(&bus->drivers); |
844 | if (retval) | 873 | if (retval) |
845 | goto bus_drivers_fail; | 874 | goto bus_drivers_fail; |
@@ -866,6 +895,8 @@ bus_probe_files_fail: | |||
866 | bus_drivers_fail: | 895 | bus_drivers_fail: |
867 | kset_unregister(&bus->devices); | 896 | kset_unregister(&bus->devices); |
868 | bus_devices_fail: | 897 | bus_devices_fail: |
898 | bus_remove_file(bus, &bus_attr_uevent); | ||
899 | bus_uevent_fail: | ||
869 | subsystem_unregister(&bus->subsys); | 900 | subsystem_unregister(&bus->subsys); |
870 | out: | 901 | out: |
871 | return retval; | 902 | return retval; |
@@ -876,7 +907,7 @@ out: | |||
876 | * @bus: bus. | 907 | * @bus: bus. |
877 | * | 908 | * |
878 | * Unregister the child subsystems and the bus itself. | 909 | * Unregister the child subsystems and the bus itself. |
879 | * Finally, we call put_bus() to release the refcount | 910 | * Finally, we call bus_put() to release the refcount |
880 | */ | 911 | */ |
881 | void bus_unregister(struct bus_type * bus) | 912 | void bus_unregister(struct bus_type * bus) |
882 | { | 913 | { |
@@ -885,6 +916,7 @@ void bus_unregister(struct bus_type * bus) | |||
885 | remove_probe_files(bus); | 916 | remove_probe_files(bus); |
886 | kset_unregister(&bus->drivers); | 917 | kset_unregister(&bus->drivers); |
887 | kset_unregister(&bus->devices); | 918 | kset_unregister(&bus->devices); |
919 | bus_remove_file(bus, &bus_attr_uevent); | ||
888 | subsystem_unregister(&bus->subsys); | 920 | subsystem_unregister(&bus->subsys); |
889 | } | 921 | } |
890 | 922 | ||
diff --git a/drivers/base/class.c b/drivers/base/class.c index 4d2222618b78..a863bb091e11 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -65,13 +65,13 @@ static struct sysfs_ops class_sysfs_ops = { | |||
65 | .store = class_attr_store, | 65 | .store = class_attr_store, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static struct kobj_type ktype_class = { | 68 | static struct kobj_type class_ktype = { |
69 | .sysfs_ops = &class_sysfs_ops, | 69 | .sysfs_ops = &class_sysfs_ops, |
70 | .release = class_release, | 70 | .release = class_release, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* Hotplug events for classes go to the class_obj subsys */ | 73 | /* Hotplug events for classes go to the class_obj subsys */ |
74 | static decl_subsys(class, &ktype_class, NULL); | 74 | static decl_subsys(class, &class_ktype, NULL); |
75 | 75 | ||
76 | 76 | ||
77 | int class_create_file(struct class * cls, const struct class_attribute * attr) | 77 | int class_create_file(struct class * cls, const struct class_attribute * attr) |
@@ -93,14 +93,14 @@ void class_remove_file(struct class * cls, const struct class_attribute * attr) | |||
93 | static struct class *class_get(struct class *cls) | 93 | static struct class *class_get(struct class *cls) |
94 | { | 94 | { |
95 | if (cls) | 95 | if (cls) |
96 | return container_of(subsys_get(&cls->subsys), struct class, subsys); | 96 | return container_of(kset_get(&cls->subsys), struct class, subsys); |
97 | return NULL; | 97 | return NULL; |
98 | } | 98 | } |
99 | 99 | ||
100 | static void class_put(struct class * cls) | 100 | static void class_put(struct class * cls) |
101 | { | 101 | { |
102 | if (cls) | 102 | if (cls) |
103 | subsys_put(&cls->subsys); | 103 | kset_put(&cls->subsys); |
104 | } | 104 | } |
105 | 105 | ||
106 | 106 | ||
@@ -149,7 +149,7 @@ int class_register(struct class * cls) | |||
149 | if (error) | 149 | if (error) |
150 | return error; | 150 | return error; |
151 | 151 | ||
152 | subsys_set_kset(cls, class_subsys); | 152 | cls->subsys.kobj.kset = &class_subsys; |
153 | 153 | ||
154 | error = subsystem_register(&cls->subsys); | 154 | error = subsystem_register(&cls->subsys); |
155 | if (!error) { | 155 | if (!error) { |
@@ -180,8 +180,7 @@ static void class_device_create_release(struct class_device *class_dev) | |||
180 | 180 | ||
181 | /* needed to allow these devices to have parent class devices */ | 181 | /* needed to allow these devices to have parent class devices */ |
182 | static int class_device_create_uevent(struct class_device *class_dev, | 182 | static int class_device_create_uevent(struct class_device *class_dev, |
183 | char **envp, int num_envp, | 183 | struct kobj_uevent_env *env) |
184 | char *buffer, int buffer_size) | ||
185 | { | 184 | { |
186 | pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id); | 185 | pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id); |
187 | return 0; | 186 | return 0; |
@@ -324,7 +323,7 @@ static void class_dev_release(struct kobject * kobj) | |||
324 | } | 323 | } |
325 | } | 324 | } |
326 | 325 | ||
327 | static struct kobj_type ktype_class_device = { | 326 | static struct kobj_type class_device_ktype = { |
328 | .sysfs_ops = &class_dev_sysfs_ops, | 327 | .sysfs_ops = &class_dev_sysfs_ops, |
329 | .release = class_dev_release, | 328 | .release = class_dev_release, |
330 | }; | 329 | }; |
@@ -333,7 +332,7 @@ static int class_uevent_filter(struct kset *kset, struct kobject *kobj) | |||
333 | { | 332 | { |
334 | struct kobj_type *ktype = get_ktype(kobj); | 333 | struct kobj_type *ktype = get_ktype(kobj); |
335 | 334 | ||
336 | if (ktype == &ktype_class_device) { | 335 | if (ktype == &class_device_ktype) { |
337 | struct class_device *class_dev = to_class_dev(kobj); | 336 | struct class_device *class_dev = to_class_dev(kobj); |
338 | if (class_dev->class) | 337 | if (class_dev->class) |
339 | return 1; | 338 | return 1; |
@@ -403,64 +402,43 @@ static void remove_deprecated_class_device_links(struct class_device *cd) | |||
403 | { } | 402 | { } |
404 | #endif | 403 | #endif |
405 | 404 | ||
406 | static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, | 405 | static int class_uevent(struct kset *kset, struct kobject *kobj, |
407 | int num_envp, char *buffer, int buffer_size) | 406 | struct kobj_uevent_env *env) |
408 | { | 407 | { |
409 | struct class_device *class_dev = to_class_dev(kobj); | 408 | struct class_device *class_dev = to_class_dev(kobj); |
410 | struct device *dev = class_dev->dev; | 409 | struct device *dev = class_dev->dev; |
411 | int i = 0; | ||
412 | int length = 0; | ||
413 | int retval = 0; | 410 | int retval = 0; |
414 | 411 | ||
415 | pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); | 412 | pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); |
416 | 413 | ||
417 | if (MAJOR(class_dev->devt)) { | 414 | if (MAJOR(class_dev->devt)) { |
418 | add_uevent_var(envp, num_envp, &i, | 415 | add_uevent_var(env, "MAJOR=%u", MAJOR(class_dev->devt)); |
419 | buffer, buffer_size, &length, | ||
420 | "MAJOR=%u", MAJOR(class_dev->devt)); | ||
421 | 416 | ||
422 | add_uevent_var(envp, num_envp, &i, | 417 | add_uevent_var(env, "MINOR=%u", MINOR(class_dev->devt)); |
423 | buffer, buffer_size, &length, | ||
424 | "MINOR=%u", MINOR(class_dev->devt)); | ||
425 | } | 418 | } |
426 | 419 | ||
427 | if (dev) { | 420 | if (dev) { |
428 | const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); | 421 | const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); |
429 | if (path) { | 422 | if (path) { |
430 | add_uevent_var(envp, num_envp, &i, | 423 | add_uevent_var(env, "PHYSDEVPATH=%s", path); |
431 | buffer, buffer_size, &length, | ||
432 | "PHYSDEVPATH=%s", path); | ||
433 | kfree(path); | 424 | kfree(path); |
434 | } | 425 | } |
435 | 426 | ||
436 | if (dev->bus) | 427 | if (dev->bus) |
437 | add_uevent_var(envp, num_envp, &i, | 428 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); |
438 | buffer, buffer_size, &length, | ||
439 | "PHYSDEVBUS=%s", dev->bus->name); | ||
440 | 429 | ||
441 | if (dev->driver) | 430 | if (dev->driver) |
442 | add_uevent_var(envp, num_envp, &i, | 431 | add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name); |
443 | buffer, buffer_size, &length, | ||
444 | "PHYSDEVDRIVER=%s", dev->driver->name); | ||
445 | } | 432 | } |
446 | 433 | ||
447 | /* terminate, set to next free slot, shrink available space */ | ||
448 | envp[i] = NULL; | ||
449 | envp = &envp[i]; | ||
450 | num_envp -= i; | ||
451 | buffer = &buffer[length]; | ||
452 | buffer_size -= length; | ||
453 | |||
454 | if (class_dev->uevent) { | 434 | if (class_dev->uevent) { |
455 | /* have the class device specific function add its stuff */ | 435 | /* have the class device specific function add its stuff */ |
456 | retval = class_dev->uevent(class_dev, envp, num_envp, | 436 | retval = class_dev->uevent(class_dev, env); |
457 | buffer, buffer_size); | ||
458 | if (retval) | 437 | if (retval) |
459 | pr_debug("class_dev->uevent() returned %d\n", retval); | 438 | pr_debug("class_dev->uevent() returned %d\n", retval); |
460 | } else if (class_dev->class->uevent) { | 439 | } else if (class_dev->class->uevent) { |
461 | /* have the class specific function add its stuff */ | 440 | /* have the class specific function add its stuff */ |
462 | retval = class_dev->class->uevent(class_dev, envp, num_envp, | 441 | retval = class_dev->class->uevent(class_dev, env); |
463 | buffer, buffer_size); | ||
464 | if (retval) | 442 | if (retval) |
465 | pr_debug("class->uevent() returned %d\n", retval); | 443 | pr_debug("class->uevent() returned %d\n", retval); |
466 | } | 444 | } |
@@ -474,7 +452,7 @@ static struct kset_uevent_ops class_uevent_ops = { | |||
474 | .uevent = class_uevent, | 452 | .uevent = class_uevent, |
475 | }; | 453 | }; |
476 | 454 | ||
477 | static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops); | 455 | static decl_subsys(class_obj, &class_device_ktype, &class_uevent_ops); |
478 | 456 | ||
479 | 457 | ||
480 | static int class_device_add_attrs(struct class_device * cd) | 458 | static int class_device_add_attrs(struct class_device * cd) |
@@ -883,7 +861,7 @@ int __init classes_init(void) | |||
883 | 861 | ||
884 | /* ick, this is ugly, the things we go through to keep from showing up | 862 | /* ick, this is ugly, the things we go through to keep from showing up |
885 | * in sysfs... */ | 863 | * in sysfs... */ |
886 | subsystem_init(&class_obj_subsys); | 864 | kset_init(&class_obj_subsys); |
887 | if (!class_obj_subsys.kobj.parent) | 865 | if (!class_obj_subsys.kobj.parent) |
888 | class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; | 866 | class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; |
889 | return 0; | 867 | return 0; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index ec86d6fc2360..c1343414d285 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -108,7 +108,7 @@ static void device_release(struct kobject * kobj) | |||
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | static struct kobj_type ktype_device = { | 111 | static struct kobj_type device_ktype = { |
112 | .release = device_release, | 112 | .release = device_release, |
113 | .sysfs_ops = &dev_sysfs_ops, | 113 | .sysfs_ops = &dev_sysfs_ops, |
114 | }; | 114 | }; |
@@ -118,7 +118,7 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) | |||
118 | { | 118 | { |
119 | struct kobj_type *ktype = get_ktype(kobj); | 119 | struct kobj_type *ktype = get_ktype(kobj); |
120 | 120 | ||
121 | if (ktype == &ktype_device) { | 121 | if (ktype == &device_ktype) { |
122 | struct device *dev = to_dev(kobj); | 122 | struct device *dev = to_dev(kobj); |
123 | if (dev->uevent_suppress) | 123 | if (dev->uevent_suppress) |
124 | return 0; | 124 | return 0; |
@@ -141,33 +141,23 @@ static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) | |||
141 | return NULL; | 141 | return NULL; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, | 144 | static int dev_uevent(struct kset *kset, struct kobject *kobj, |
145 | int num_envp, char *buffer, int buffer_size) | 145 | struct kobj_uevent_env *env) |
146 | { | 146 | { |
147 | struct device *dev = to_dev(kobj); | 147 | struct device *dev = to_dev(kobj); |
148 | int i = 0; | ||
149 | int length = 0; | ||
150 | int retval = 0; | 148 | int retval = 0; |
151 | 149 | ||
152 | /* add the major/minor if present */ | 150 | /* add the major/minor if present */ |
153 | if (MAJOR(dev->devt)) { | 151 | if (MAJOR(dev->devt)) { |
154 | add_uevent_var(envp, num_envp, &i, | 152 | add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); |
155 | buffer, buffer_size, &length, | 153 | add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); |
156 | "MAJOR=%u", MAJOR(dev->devt)); | ||
157 | add_uevent_var(envp, num_envp, &i, | ||
158 | buffer, buffer_size, &length, | ||
159 | "MINOR=%u", MINOR(dev->devt)); | ||
160 | } | 154 | } |
161 | 155 | ||
162 | if (dev->type && dev->type->name) | 156 | if (dev->type && dev->type->name) |
163 | add_uevent_var(envp, num_envp, &i, | 157 | add_uevent_var(env, "DEVTYPE=%s", dev->type->name); |
164 | buffer, buffer_size, &length, | ||
165 | "DEVTYPE=%s", dev->type->name); | ||
166 | 158 | ||
167 | if (dev->driver) | 159 | if (dev->driver) |
168 | add_uevent_var(envp, num_envp, &i, | 160 | add_uevent_var(env, "DRIVER=%s", dev->driver->name); |
169 | buffer, buffer_size, &length, | ||
170 | "DRIVER=%s", dev->driver->name); | ||
171 | 161 | ||
172 | #ifdef CONFIG_SYSFS_DEPRECATED | 162 | #ifdef CONFIG_SYSFS_DEPRECATED |
173 | if (dev->class) { | 163 | if (dev->class) { |
@@ -181,59 +171,43 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, | |||
181 | 171 | ||
182 | path = kobject_get_path(&parent->kobj, GFP_KERNEL); | 172 | path = kobject_get_path(&parent->kobj, GFP_KERNEL); |
183 | if (path) { | 173 | if (path) { |
184 | add_uevent_var(envp, num_envp, &i, | 174 | add_uevent_var(env, "PHYSDEVPATH=%s", path); |
185 | buffer, buffer_size, &length, | ||
186 | "PHYSDEVPATH=%s", path); | ||
187 | kfree(path); | 175 | kfree(path); |
188 | } | 176 | } |
189 | 177 | ||
190 | add_uevent_var(envp, num_envp, &i, | 178 | add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name); |
191 | buffer, buffer_size, &length, | ||
192 | "PHYSDEVBUS=%s", parent->bus->name); | ||
193 | 179 | ||
194 | if (parent->driver) | 180 | if (parent->driver) |
195 | add_uevent_var(envp, num_envp, &i, | 181 | add_uevent_var(env, "PHYSDEVDRIVER=%s", |
196 | buffer, buffer_size, &length, | 182 | parent->driver->name); |
197 | "PHYSDEVDRIVER=%s", parent->driver->name); | ||
198 | } | 183 | } |
199 | } else if (dev->bus) { | 184 | } else if (dev->bus) { |
200 | add_uevent_var(envp, num_envp, &i, | 185 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); |
201 | buffer, buffer_size, &length, | ||
202 | "PHYSDEVBUS=%s", dev->bus->name); | ||
203 | 186 | ||
204 | if (dev->driver) | 187 | if (dev->driver) |
205 | add_uevent_var(envp, num_envp, &i, | 188 | add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name); |
206 | buffer, buffer_size, &length, | ||
207 | "PHYSDEVDRIVER=%s", dev->driver->name); | ||
208 | } | 189 | } |
209 | #endif | 190 | #endif |
210 | 191 | ||
211 | /* terminate, set to next free slot, shrink available space */ | 192 | /* have the bus specific function add its stuff */ |
212 | envp[i] = NULL; | ||
213 | envp = &envp[i]; | ||
214 | num_envp -= i; | ||
215 | buffer = &buffer[length]; | ||
216 | buffer_size -= length; | ||
217 | |||
218 | if (dev->bus && dev->bus->uevent) { | 193 | if (dev->bus && dev->bus->uevent) { |
219 | /* have the bus specific function add its stuff */ | 194 | retval = dev->bus->uevent(dev, env); |
220 | retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size); | ||
221 | if (retval) | 195 | if (retval) |
222 | pr_debug ("%s: bus uevent() returned %d\n", | 196 | pr_debug ("%s: bus uevent() returned %d\n", |
223 | __FUNCTION__, retval); | 197 | __FUNCTION__, retval); |
224 | } | 198 | } |
225 | 199 | ||
200 | /* have the class specific function add its stuff */ | ||
226 | if (dev->class && dev->class->dev_uevent) { | 201 | if (dev->class && dev->class->dev_uevent) { |
227 | /* have the class specific function add its stuff */ | 202 | retval = dev->class->dev_uevent(dev, env); |
228 | retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); | ||
229 | if (retval) | 203 | if (retval) |
230 | pr_debug("%s: class uevent() returned %d\n", | 204 | pr_debug("%s: class uevent() returned %d\n", |
231 | __FUNCTION__, retval); | 205 | __FUNCTION__, retval); |
232 | } | 206 | } |
233 | 207 | ||
208 | /* have the device type specific fuction add its stuff */ | ||
234 | if (dev->type && dev->type->uevent) { | 209 | if (dev->type && dev->type->uevent) { |
235 | /* have the device type specific fuction add its stuff */ | 210 | retval = dev->type->uevent(dev, env); |
236 | retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size); | ||
237 | if (retval) | 211 | if (retval) |
238 | pr_debug("%s: dev_type uevent() returned %d\n", | 212 | pr_debug("%s: dev_type uevent() returned %d\n", |
239 | __FUNCTION__, retval); | 213 | __FUNCTION__, retval); |
@@ -253,22 +227,18 @@ static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, | |||
253 | { | 227 | { |
254 | struct kobject *top_kobj; | 228 | struct kobject *top_kobj; |
255 | struct kset *kset; | 229 | struct kset *kset; |
256 | char *envp[32]; | 230 | struct kobj_uevent_env *env = NULL; |
257 | char *data = NULL; | ||
258 | char *pos; | ||
259 | int i; | 231 | int i; |
260 | size_t count = 0; | 232 | size_t count = 0; |
261 | int retval; | 233 | int retval; |
262 | 234 | ||
263 | /* search the kset, the device belongs to */ | 235 | /* search the kset, the device belongs to */ |
264 | top_kobj = &dev->kobj; | 236 | top_kobj = &dev->kobj; |
265 | if (!top_kobj->kset && top_kobj->parent) { | 237 | while (!top_kobj->kset && top_kobj->parent) |
266 | do { | 238 | top_kobj = top_kobj->parent; |
267 | top_kobj = top_kobj->parent; | ||
268 | } while (!top_kobj->kset && top_kobj->parent); | ||
269 | } | ||
270 | if (!top_kobj->kset) | 239 | if (!top_kobj->kset) |
271 | goto out; | 240 | goto out; |
241 | |||
272 | kset = top_kobj->kset; | 242 | kset = top_kobj->kset; |
273 | if (!kset->uevent_ops || !kset->uevent_ops->uevent) | 243 | if (!kset->uevent_ops || !kset->uevent_ops->uevent) |
274 | goto out; | 244 | goto out; |
@@ -278,43 +248,29 @@ static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, | |||
278 | if (!kset->uevent_ops->filter(kset, &dev->kobj)) | 248 | if (!kset->uevent_ops->filter(kset, &dev->kobj)) |
279 | goto out; | 249 | goto out; |
280 | 250 | ||
281 | data = (char *)get_zeroed_page(GFP_KERNEL); | 251 | env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); |
282 | if (!data) | 252 | if (!env) |
283 | return -ENOMEM; | 253 | return -ENOMEM; |
284 | 254 | ||
285 | /* let the kset specific function add its keys */ | 255 | /* let the kset specific function add its keys */ |
286 | pos = data; | 256 | retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); |
287 | memset(envp, 0, sizeof(envp)); | ||
288 | retval = kset->uevent_ops->uevent(kset, &dev->kobj, | ||
289 | envp, ARRAY_SIZE(envp), | ||
290 | pos, PAGE_SIZE); | ||
291 | if (retval) | 257 | if (retval) |
292 | goto out; | 258 | goto out; |
293 | 259 | ||
294 | /* copy keys to file */ | 260 | /* copy keys to file */ |
295 | for (i = 0; envp[i]; i++) { | 261 | for (i = 0; i < env->envp_idx; i++) |
296 | pos = &buf[count]; | 262 | count += sprintf(&buf[count], "%s\n", env->envp[i]); |
297 | count += sprintf(pos, "%s\n", envp[i]); | ||
298 | } | ||
299 | out: | 263 | out: |
300 | free_page((unsigned long)data); | 264 | kfree(env); |
301 | return count; | 265 | return count; |
302 | } | 266 | } |
303 | 267 | ||
304 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | 268 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, |
305 | const char *buf, size_t count) | 269 | const char *buf, size_t count) |
306 | { | 270 | { |
307 | size_t len = count; | ||
308 | enum kobject_action action; | 271 | enum kobject_action action; |
309 | 272 | ||
310 | if (len && buf[len-1] == '\n') | 273 | if (kobject_action_type(buf, count, &action) == 0) { |
311 | len--; | ||
312 | |||
313 | for (action = 0; action < KOBJ_MAX; action++) { | ||
314 | if (strncmp(kobject_actions[action], buf, len) != 0) | ||
315 | continue; | ||
316 | if (kobject_actions[action][len] != '\0') | ||
317 | continue; | ||
318 | kobject_uevent(&dev->kobj, action); | 274 | kobject_uevent(&dev->kobj, action); |
319 | goto out; | 275 | goto out; |
320 | } | 276 | } |
@@ -449,7 +405,7 @@ static struct device_attribute devt_attr = | |||
449 | * devices_subsys - structure to be registered with kobject core. | 405 | * devices_subsys - structure to be registered with kobject core. |
450 | */ | 406 | */ |
451 | 407 | ||
452 | decl_subsys(devices, &ktype_device, &device_uevent_ops); | 408 | decl_subsys(devices, &device_ktype, &device_uevent_ops); |
453 | 409 | ||
454 | 410 | ||
455 | /** | 411 | /** |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index b24efd4e3e3d..0295855a3eef 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -88,19 +88,14 @@ static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); | |||
88 | 88 | ||
89 | static void fw_dev_release(struct device *dev); | 89 | static void fw_dev_release(struct device *dev); |
90 | 90 | ||
91 | static int firmware_uevent(struct device *dev, char **envp, int num_envp, | 91 | static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) |
92 | char *buffer, int buffer_size) | ||
93 | { | 92 | { |
94 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); | 93 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
95 | int i = 0, len = 0; | ||
96 | 94 | ||
97 | if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, | 95 | if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id)) |
98 | "FIRMWARE=%s", fw_priv->fw_id)) | ||
99 | return -ENOMEM; | 96 | return -ENOMEM; |
100 | if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, | 97 | if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout)) |
101 | "TIMEOUT=%i", loading_timeout)) | ||
102 | return -ENOMEM; | 98 | return -ENOMEM; |
103 | envp[i] = NULL; | ||
104 | 99 | ||
105 | return 0; | 100 | return 0; |
106 | } | 101 | } |
@@ -297,8 +292,7 @@ firmware_class_timeout(u_long data) | |||
297 | 292 | ||
298 | static inline void fw_setup_device_id(struct device *f_dev, struct device *dev) | 293 | static inline void fw_setup_device_id(struct device *f_dev, struct device *dev) |
299 | { | 294 | { |
300 | /* XXX warning we should watch out for name collisions */ | 295 | snprintf(f_dev->bus_id, BUS_ID_SIZE, "firmware-%s", dev->bus_id); |
301 | strlcpy(f_dev->bus_id, dev->bus_id, BUS_ID_SIZE); | ||
302 | } | 296 | } |
303 | 297 | ||
304 | static int fw_register_device(struct device **dev_p, const char *fw_name, | 298 | static int fw_register_device(struct device **dev_p, const char *fw_name, |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 74b96795d2f5..cb99daeae936 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -34,8 +34,7 @@ static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj) | |||
34 | return MEMORY_CLASS_NAME; | 34 | return MEMORY_CLASS_NAME; |
35 | } | 35 | } |
36 | 36 | ||
37 | static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp, | 37 | static int memory_uevent(struct kset *kset, struct kobj_uevent_env *env) |
38 | int num_envp, char *buffer, int buffer_size) | ||
39 | { | 38 | { |
40 | int retval = 0; | 39 | int retval = 0; |
41 | 40 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 869ff8c00146..fb5609241482 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -160,13 +160,8 @@ static void platform_device_release(struct device *dev) | |||
160 | * | 160 | * |
161 | * Create a platform device object which can have other objects attached | 161 | * Create a platform device object which can have other objects attached |
162 | * to it, and which will have attached objects freed when it is released. | 162 | * to it, and which will have attached objects freed when it is released. |
163 | * | ||
164 | * This device will be marked as not supporting hotpluggable drivers; no | ||
165 | * device add/remove uevents will be generated. In the unusual case that | ||
166 | * the device isn't being dynamically allocated as a legacy "probe the | ||
167 | * hardware" driver, infrastructure code should reverse this marking. | ||
168 | */ | 163 | */ |
169 | struct platform_device *platform_device_alloc(const char *name, unsigned int id) | 164 | struct platform_device *platform_device_alloc(const char *name, int id) |
170 | { | 165 | { |
171 | struct platform_object *pa; | 166 | struct platform_object *pa; |
172 | 167 | ||
@@ -177,12 +172,6 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id) | |||
177 | pa->pdev.id = id; | 172 | pa->pdev.id = id; |
178 | device_initialize(&pa->pdev.dev); | 173 | device_initialize(&pa->pdev.dev); |
179 | pa->pdev.dev.release = platform_device_release; | 174 | pa->pdev.dev.release = platform_device_release; |
180 | |||
181 | /* prevent hotplug "modprobe $(MODALIAS)" from causing trouble in | ||
182 | * legacy probe-the-hardware drivers, which don't properly split | ||
183 | * out device enumeration logic from drivers. | ||
184 | */ | ||
185 | pa->pdev.dev.uevent_suppress = 1; | ||
186 | } | 175 | } |
187 | 176 | ||
188 | return pa ? &pa->pdev : NULL; | 177 | return pa ? &pa->pdev : NULL; |
@@ -256,7 +245,8 @@ int platform_device_add(struct platform_device *pdev) | |||
256 | pdev->dev.bus = &platform_bus_type; | 245 | pdev->dev.bus = &platform_bus_type; |
257 | 246 | ||
258 | if (pdev->id != -1) | 247 | if (pdev->id != -1) |
259 | snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%u", pdev->name, pdev->id); | 248 | snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%d", pdev->name, |
249 | pdev->id); | ||
260 | else | 250 | else |
261 | strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE); | 251 | strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE); |
262 | 252 | ||
@@ -370,7 +360,7 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); | |||
370 | * the Linux driver model. In particular, when such drivers are built | 360 | * the Linux driver model. In particular, when such drivers are built |
371 | * as modules, they can't be "hotplugged". | 361 | * as modules, they can't be "hotplugged". |
372 | */ | 362 | */ |
373 | struct platform_device *platform_device_register_simple(char *name, unsigned int id, | 363 | struct platform_device *platform_device_register_simple(char *name, int id, |
374 | struct resource *res, unsigned int num) | 364 | struct resource *res, unsigned int num) |
375 | { | 365 | { |
376 | struct platform_device *pdev; | 366 | struct platform_device *pdev; |
@@ -530,7 +520,7 @@ static ssize_t | |||
530 | modalias_show(struct device *dev, struct device_attribute *a, char *buf) | 520 | modalias_show(struct device *dev, struct device_attribute *a, char *buf) |
531 | { | 521 | { |
532 | struct platform_device *pdev = to_platform_device(dev); | 522 | struct platform_device *pdev = to_platform_device(dev); |
533 | int len = snprintf(buf, PAGE_SIZE, "%s\n", pdev->name); | 523 | int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); |
534 | 524 | ||
535 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | 525 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
536 | } | 526 | } |
@@ -540,13 +530,11 @@ static struct device_attribute platform_dev_attrs[] = { | |||
540 | __ATTR_NULL, | 530 | __ATTR_NULL, |
541 | }; | 531 | }; |
542 | 532 | ||
543 | static int platform_uevent(struct device *dev, char **envp, int num_envp, | 533 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) |
544 | char *buffer, int buffer_size) | ||
545 | { | 534 | { |
546 | struct platform_device *pdev = to_platform_device(dev); | 535 | struct platform_device *pdev = to_platform_device(dev); |
547 | 536 | ||
548 | envp[0] = buffer; | 537 | add_uevent_var(env, "MODALIAS=platform:%s", pdev->name); |
549 | snprintf(buffer, buffer_size, "MODALIAS=%s", pdev->name); | ||
550 | return 0; | 538 | return 0; |
551 | } | 539 | } |
552 | 540 | ||
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index 9caeaea753a3..a803733c839e 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | obj-y := shutdown.o | 1 | obj-y := shutdown.o |
2 | obj-$(CONFIG_PM_SLEEP) += main.o suspend.o resume.o sysfs.o | 2 | obj-$(CONFIG_PM_SLEEP) += main.o sysfs.o |
3 | obj-$(CONFIG_PM_TRACE) += trace.o | 3 | obj-$(CONFIG_PM_TRACE) += trace.o |
4 | 4 | ||
5 | ifeq ($(CONFIG_DEBUG_DRIVER),y) | 5 | ifeq ($(CONFIG_DEBUG_DRIVER),y) |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index eb9f38d0aa58..0ab4ab21f564 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -20,19 +20,24 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/kallsyms.h> | ||
23 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/pm.h> | ||
26 | #include <linux/resume-trace.h> | ||
24 | 27 | ||
28 | #include "../base.h" | ||
25 | #include "power.h" | 29 | #include "power.h" |
26 | 30 | ||
27 | LIST_HEAD(dpm_active); | 31 | LIST_HEAD(dpm_active); |
28 | LIST_HEAD(dpm_off); | 32 | static LIST_HEAD(dpm_off); |
29 | LIST_HEAD(dpm_off_irq); | 33 | static LIST_HEAD(dpm_off_irq); |
30 | 34 | ||
31 | DEFINE_MUTEX(dpm_mtx); | 35 | static DEFINE_MUTEX(dpm_mtx); |
32 | DEFINE_MUTEX(dpm_list_mtx); | 36 | static DEFINE_MUTEX(dpm_list_mtx); |
33 | 37 | ||
34 | int (*platform_enable_wakeup)(struct device *dev, int is_on); | 38 | int (*platform_enable_wakeup)(struct device *dev, int is_on); |
35 | 39 | ||
40 | |||
36 | int device_pm_add(struct device *dev) | 41 | int device_pm_add(struct device *dev) |
37 | { | 42 | { |
38 | int error; | 43 | int error; |
@@ -61,3 +66,334 @@ void device_pm_remove(struct device *dev) | |||
61 | } | 66 | } |
62 | 67 | ||
63 | 68 | ||
69 | /*------------------------- Resume routines -------------------------*/ | ||
70 | |||
71 | /** | ||
72 | * resume_device - Restore state for one device. | ||
73 | * @dev: Device. | ||
74 | * | ||
75 | */ | ||
76 | |||
77 | static int resume_device(struct device * dev) | ||
78 | { | ||
79 | int error = 0; | ||
80 | |||
81 | TRACE_DEVICE(dev); | ||
82 | TRACE_RESUME(0); | ||
83 | |||
84 | down(&dev->sem); | ||
85 | |||
86 | if (dev->bus && dev->bus->resume) { | ||
87 | dev_dbg(dev,"resuming\n"); | ||
88 | error = dev->bus->resume(dev); | ||
89 | } | ||
90 | |||
91 | if (!error && dev->type && dev->type->resume) { | ||
92 | dev_dbg(dev,"resuming\n"); | ||
93 | error = dev->type->resume(dev); | ||
94 | } | ||
95 | |||
96 | if (!error && dev->class && dev->class->resume) { | ||
97 | dev_dbg(dev,"class resume\n"); | ||
98 | error = dev->class->resume(dev); | ||
99 | } | ||
100 | |||
101 | up(&dev->sem); | ||
102 | |||
103 | TRACE_RESUME(error); | ||
104 | return error; | ||
105 | } | ||
106 | |||
107 | |||
108 | static int resume_device_early(struct device * dev) | ||
109 | { | ||
110 | int error = 0; | ||
111 | |||
112 | TRACE_DEVICE(dev); | ||
113 | TRACE_RESUME(0); | ||
114 | if (dev->bus && dev->bus->resume_early) { | ||
115 | dev_dbg(dev,"EARLY resume\n"); | ||
116 | error = dev->bus->resume_early(dev); | ||
117 | } | ||
118 | TRACE_RESUME(error); | ||
119 | return error; | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * Resume the devices that have either not gone through | ||
124 | * the late suspend, or that did go through it but also | ||
125 | * went through the early resume | ||
126 | */ | ||
127 | static void dpm_resume(void) | ||
128 | { | ||
129 | mutex_lock(&dpm_list_mtx); | ||
130 | while(!list_empty(&dpm_off)) { | ||
131 | struct list_head * entry = dpm_off.next; | ||
132 | struct device * dev = to_device(entry); | ||
133 | |||
134 | get_device(dev); | ||
135 | list_move_tail(entry, &dpm_active); | ||
136 | |||
137 | mutex_unlock(&dpm_list_mtx); | ||
138 | resume_device(dev); | ||
139 | mutex_lock(&dpm_list_mtx); | ||
140 | put_device(dev); | ||
141 | } | ||
142 | mutex_unlock(&dpm_list_mtx); | ||
143 | } | ||
144 | |||
145 | |||
146 | /** | ||
147 | * device_resume - Restore state of each device in system. | ||
148 | * | ||
149 | * Walk the dpm_off list, remove each entry, resume the device, | ||
150 | * then add it to the dpm_active list. | ||
151 | */ | ||
152 | |||
153 | void device_resume(void) | ||
154 | { | ||
155 | might_sleep(); | ||
156 | mutex_lock(&dpm_mtx); | ||
157 | dpm_resume(); | ||
158 | mutex_unlock(&dpm_mtx); | ||
159 | } | ||
160 | |||
161 | EXPORT_SYMBOL_GPL(device_resume); | ||
162 | |||
163 | |||
164 | /** | ||
165 | * dpm_power_up - Power on some devices. | ||
166 | * | ||
167 | * Walk the dpm_off_irq list and power each device up. This | ||
168 | * is used for devices that required they be powered down with | ||
169 | * interrupts disabled. As devices are powered on, they are moved | ||
170 | * to the dpm_active list. | ||
171 | * | ||
172 | * Interrupts must be disabled when calling this. | ||
173 | */ | ||
174 | |||
175 | static void dpm_power_up(void) | ||
176 | { | ||
177 | while(!list_empty(&dpm_off_irq)) { | ||
178 | struct list_head * entry = dpm_off_irq.next; | ||
179 | struct device * dev = to_device(entry); | ||
180 | |||
181 | list_move_tail(entry, &dpm_off); | ||
182 | resume_device_early(dev); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | |||
187 | /** | ||
188 | * device_power_up - Turn on all devices that need special attention. | ||
189 | * | ||
190 | * Power on system devices then devices that required we shut them down | ||
191 | * with interrupts disabled. | ||
192 | * Called with interrupts disabled. | ||
193 | */ | ||
194 | |||
195 | void device_power_up(void) | ||
196 | { | ||
197 | sysdev_resume(); | ||
198 | dpm_power_up(); | ||
199 | } | ||
200 | |||
201 | EXPORT_SYMBOL_GPL(device_power_up); | ||
202 | |||
203 | |||
204 | /*------------------------- Suspend routines -------------------------*/ | ||
205 | |||
206 | /* | ||
207 | * The entries in the dpm_active list are in a depth first order, simply | ||
208 | * because children are guaranteed to be discovered after parents, and | ||
209 | * are inserted at the back of the list on discovery. | ||
210 | * | ||
211 | * All list on the suspend path are done in reverse order, so we operate | ||
212 | * on the leaves of the device tree (or forests, depending on how you want | ||
213 | * to look at it ;) first. As nodes are removed from the back of the list, | ||
214 | * they are inserted into the front of their destintation lists. | ||
215 | * | ||
216 | * Things are the reverse on the resume path - iterations are done in | ||
217 | * forward order, and nodes are inserted at the back of their destination | ||
218 | * lists. This way, the ancestors will be accessed before their descendents. | ||
219 | */ | ||
220 | |||
221 | static inline char *suspend_verb(u32 event) | ||
222 | { | ||
223 | switch (event) { | ||
224 | case PM_EVENT_SUSPEND: return "suspend"; | ||
225 | case PM_EVENT_FREEZE: return "freeze"; | ||
226 | case PM_EVENT_PRETHAW: return "prethaw"; | ||
227 | default: return "(unknown suspend event)"; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | |||
232 | static void | ||
233 | suspend_device_dbg(struct device *dev, pm_message_t state, char *info) | ||
234 | { | ||
235 | dev_dbg(dev, "%s%s%s\n", info, suspend_verb(state.event), | ||
236 | ((state.event == PM_EVENT_SUSPEND) && device_may_wakeup(dev)) ? | ||
237 | ", may wakeup" : ""); | ||
238 | } | ||
239 | |||
240 | /** | ||
241 | * suspend_device - Save state of one device. | ||
242 | * @dev: Device. | ||
243 | * @state: Power state device is entering. | ||
244 | */ | ||
245 | |||
246 | static int suspend_device(struct device * dev, pm_message_t state) | ||
247 | { | ||
248 | int error = 0; | ||
249 | |||
250 | down(&dev->sem); | ||
251 | if (dev->power.power_state.event) { | ||
252 | dev_dbg(dev, "PM: suspend %d-->%d\n", | ||
253 | dev->power.power_state.event, state.event); | ||
254 | } | ||
255 | |||
256 | if (dev->class && dev->class->suspend) { | ||
257 | suspend_device_dbg(dev, state, "class "); | ||
258 | error = dev->class->suspend(dev, state); | ||
259 | suspend_report_result(dev->class->suspend, error); | ||
260 | } | ||
261 | |||
262 | if (!error && dev->type && dev->type->suspend) { | ||
263 | suspend_device_dbg(dev, state, "type "); | ||
264 | error = dev->type->suspend(dev, state); | ||
265 | suspend_report_result(dev->type->suspend, error); | ||
266 | } | ||
267 | |||
268 | if (!error && dev->bus && dev->bus->suspend) { | ||
269 | suspend_device_dbg(dev, state, ""); | ||
270 | error = dev->bus->suspend(dev, state); | ||
271 | suspend_report_result(dev->bus->suspend, error); | ||
272 | } | ||
273 | up(&dev->sem); | ||
274 | return error; | ||
275 | } | ||
276 | |||
277 | |||
278 | /* | ||
279 | * This is called with interrupts off, only a single CPU | ||
280 | * running. We can't acquire a mutex or semaphore (and we don't | ||
281 | * need the protection) | ||
282 | */ | ||
283 | static int suspend_device_late(struct device *dev, pm_message_t state) | ||
284 | { | ||
285 | int error = 0; | ||
286 | |||
287 | if (dev->bus && dev->bus->suspend_late) { | ||
288 | suspend_device_dbg(dev, state, "LATE "); | ||
289 | error = dev->bus->suspend_late(dev, state); | ||
290 | suspend_report_result(dev->bus->suspend_late, error); | ||
291 | } | ||
292 | return error; | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * device_suspend - Save state and stop all devices in system. | ||
297 | * @state: Power state to put each device in. | ||
298 | * | ||
299 | * Walk the dpm_active list, call ->suspend() for each device, and move | ||
300 | * it to the dpm_off list. | ||
301 | * | ||
302 | * (For historical reasons, if it returns -EAGAIN, that used to mean | ||
303 | * that the device would be called again with interrupts disabled. | ||
304 | * These days, we use the "suspend_late()" callback for that, so we | ||
305 | * print a warning and consider it an error). | ||
306 | * | ||
307 | * If we get a different error, try and back out. | ||
308 | * | ||
309 | * If we hit a failure with any of the devices, call device_resume() | ||
310 | * above to bring the suspended devices back to life. | ||
311 | * | ||
312 | */ | ||
313 | |||
314 | int device_suspend(pm_message_t state) | ||
315 | { | ||
316 | int error = 0; | ||
317 | |||
318 | might_sleep(); | ||
319 | mutex_lock(&dpm_mtx); | ||
320 | mutex_lock(&dpm_list_mtx); | ||
321 | while (!list_empty(&dpm_active) && error == 0) { | ||
322 | struct list_head * entry = dpm_active.prev; | ||
323 | struct device * dev = to_device(entry); | ||
324 | |||
325 | get_device(dev); | ||
326 | mutex_unlock(&dpm_list_mtx); | ||
327 | |||
328 | error = suspend_device(dev, state); | ||
329 | |||
330 | mutex_lock(&dpm_list_mtx); | ||
331 | |||
332 | /* Check if the device got removed */ | ||
333 | if (!list_empty(&dev->power.entry)) { | ||
334 | /* Move it to the dpm_off list */ | ||
335 | if (!error) | ||
336 | list_move(&dev->power.entry, &dpm_off); | ||
337 | } | ||
338 | if (error) | ||
339 | printk(KERN_ERR "Could not suspend device %s: " | ||
340 | "error %d%s\n", | ||
341 | kobject_name(&dev->kobj), error, | ||
342 | error == -EAGAIN ? " (please convert to suspend_late)" : ""); | ||
343 | put_device(dev); | ||
344 | } | ||
345 | mutex_unlock(&dpm_list_mtx); | ||
346 | if (error) | ||
347 | dpm_resume(); | ||
348 | |||
349 | mutex_unlock(&dpm_mtx); | ||
350 | return error; | ||
351 | } | ||
352 | |||
353 | EXPORT_SYMBOL_GPL(device_suspend); | ||
354 | |||
355 | /** | ||
356 | * device_power_down - Shut down special devices. | ||
357 | * @state: Power state to enter. | ||
358 | * | ||
359 | * Walk the dpm_off_irq list, calling ->power_down() for each device that | ||
360 | * couldn't power down the device with interrupts enabled. When we're | ||
361 | * done, power down system devices. | ||
362 | */ | ||
363 | |||
364 | int device_power_down(pm_message_t state) | ||
365 | { | ||
366 | int error = 0; | ||
367 | struct device * dev; | ||
368 | |||
369 | while (!list_empty(&dpm_off)) { | ||
370 | struct list_head * entry = dpm_off.prev; | ||
371 | |||
372 | dev = to_device(entry); | ||
373 | error = suspend_device_late(dev, state); | ||
374 | if (error) | ||
375 | goto Error; | ||
376 | list_move(&dev->power.entry, &dpm_off_irq); | ||
377 | } | ||
378 | |||
379 | error = sysdev_suspend(state); | ||
380 | Done: | ||
381 | return error; | ||
382 | Error: | ||
383 | printk(KERN_ERR "Could not power down device %s: " | ||
384 | "error %d\n", kobject_name(&dev->kobj), error); | ||
385 | dpm_power_up(); | ||
386 | goto Done; | ||
387 | } | ||
388 | |||
389 | EXPORT_SYMBOL_GPL(device_power_down); | ||
390 | |||
391 | void __suspend_report_result(const char *function, void *fn, int ret) | ||
392 | { | ||
393 | if (ret) { | ||
394 | printk(KERN_ERR "%s(): ", function); | ||
395 | print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn); | ||
396 | printk("%d\n", ret); | ||
397 | } | ||
398 | } | ||
399 | EXPORT_SYMBOL_GPL(__suspend_report_result); | ||
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 8ba0830cbc03..5c4efd493fa5 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -11,32 +11,11 @@ extern void device_shutdown(void); | |||
11 | * main.c | 11 | * main.c |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | extern struct list_head dpm_active; /* The active device list */ |
15 | * Used to synchronize global power management operations. | ||
16 | */ | ||
17 | extern struct mutex dpm_mtx; | ||
18 | |||
19 | /* | ||
20 | * Used to serialize changes to the dpm_* lists. | ||
21 | */ | ||
22 | extern struct mutex dpm_list_mtx; | ||
23 | |||
24 | /* | ||
25 | * The PM lists. | ||
26 | */ | ||
27 | extern struct list_head dpm_active; | ||
28 | extern struct list_head dpm_off; | ||
29 | extern struct list_head dpm_off_irq; | ||
30 | |||
31 | |||
32 | static inline struct dev_pm_info * to_pm_info(struct list_head * entry) | ||
33 | { | ||
34 | return container_of(entry, struct dev_pm_info, entry); | ||
35 | } | ||
36 | 15 | ||
37 | static inline struct device * to_device(struct list_head * entry) | 16 | static inline struct device * to_device(struct list_head * entry) |
38 | { | 17 | { |
39 | return container_of(to_pm_info(entry), struct device, power); | 18 | return container_of(entry, struct device, power.entry); |
40 | } | 19 | } |
41 | 20 | ||
42 | extern int device_pm_add(struct device *); | 21 | extern int device_pm_add(struct device *); |
@@ -49,19 +28,6 @@ extern void device_pm_remove(struct device *); | |||
49 | extern int dpm_sysfs_add(struct device *); | 28 | extern int dpm_sysfs_add(struct device *); |
50 | extern void dpm_sysfs_remove(struct device *); | 29 | extern void dpm_sysfs_remove(struct device *); |
51 | 30 | ||
52 | /* | ||
53 | * resume.c | ||
54 | */ | ||
55 | |||
56 | extern void dpm_resume(void); | ||
57 | extern void dpm_power_up(void); | ||
58 | extern int resume_device(struct device *); | ||
59 | |||
60 | /* | ||
61 | * suspend.c | ||
62 | */ | ||
63 | extern int suspend_device(struct device *, pm_message_t); | ||
64 | |||
65 | #else /* CONFIG_PM_SLEEP */ | 31 | #else /* CONFIG_PM_SLEEP */ |
66 | 32 | ||
67 | 33 | ||
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c deleted file mode 100644 index 00fd84ae6e66..000000000000 --- a/drivers/base/power/resume.c +++ /dev/null | |||
@@ -1,149 +0,0 @@ | |||
1 | /* | ||
2 | * resume.c - Functions for waking devices up. | ||
3 | * | ||
4 | * Copyright (c) 2003 Patrick Mochel | ||
5 | * Copyright (c) 2003 Open Source Development Labs | ||
6 | * | ||
7 | * This file is released under the GPLv2 | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/device.h> | ||
12 | #include <linux/resume-trace.h> | ||
13 | #include "../base.h" | ||
14 | #include "power.h" | ||
15 | |||
16 | |||
17 | /** | ||
18 | * resume_device - Restore state for one device. | ||
19 | * @dev: Device. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | int resume_device(struct device * dev) | ||
24 | { | ||
25 | int error = 0; | ||
26 | |||
27 | TRACE_DEVICE(dev); | ||
28 | TRACE_RESUME(0); | ||
29 | |||
30 | down(&dev->sem); | ||
31 | |||
32 | if (dev->bus && dev->bus->resume) { | ||
33 | dev_dbg(dev,"resuming\n"); | ||
34 | error = dev->bus->resume(dev); | ||
35 | } | ||
36 | |||
37 | if (!error && dev->type && dev->type->resume) { | ||
38 | dev_dbg(dev,"resuming\n"); | ||
39 | error = dev->type->resume(dev); | ||
40 | } | ||
41 | |||
42 | if (!error && dev->class && dev->class->resume) { | ||
43 | dev_dbg(dev,"class resume\n"); | ||
44 | error = dev->class->resume(dev); | ||
45 | } | ||
46 | |||
47 | up(&dev->sem); | ||
48 | |||
49 | TRACE_RESUME(error); | ||
50 | return error; | ||
51 | } | ||
52 | |||
53 | |||
54 | static int resume_device_early(struct device * dev) | ||
55 | { | ||
56 | int error = 0; | ||
57 | |||
58 | TRACE_DEVICE(dev); | ||
59 | TRACE_RESUME(0); | ||
60 | if (dev->bus && dev->bus->resume_early) { | ||
61 | dev_dbg(dev,"EARLY resume\n"); | ||
62 | error = dev->bus->resume_early(dev); | ||
63 | } | ||
64 | TRACE_RESUME(error); | ||
65 | return error; | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * Resume the devices that have either not gone through | ||
70 | * the late suspend, or that did go through it but also | ||
71 | * went through the early resume | ||
72 | */ | ||
73 | void dpm_resume(void) | ||
74 | { | ||
75 | mutex_lock(&dpm_list_mtx); | ||
76 | while(!list_empty(&dpm_off)) { | ||
77 | struct list_head * entry = dpm_off.next; | ||
78 | struct device * dev = to_device(entry); | ||
79 | |||
80 | get_device(dev); | ||
81 | list_move_tail(entry, &dpm_active); | ||
82 | |||
83 | mutex_unlock(&dpm_list_mtx); | ||
84 | resume_device(dev); | ||
85 | mutex_lock(&dpm_list_mtx); | ||
86 | put_device(dev); | ||
87 | } | ||
88 | mutex_unlock(&dpm_list_mtx); | ||
89 | } | ||
90 | |||
91 | |||
92 | /** | ||
93 | * device_resume - Restore state of each device in system. | ||
94 | * | ||
95 | * Walk the dpm_off list, remove each entry, resume the device, | ||
96 | * then add it to the dpm_active list. | ||
97 | */ | ||
98 | |||
99 | void device_resume(void) | ||
100 | { | ||
101 | might_sleep(); | ||
102 | mutex_lock(&dpm_mtx); | ||
103 | dpm_resume(); | ||
104 | mutex_unlock(&dpm_mtx); | ||
105 | } | ||
106 | |||
107 | EXPORT_SYMBOL_GPL(device_resume); | ||
108 | |||
109 | |||
110 | /** | ||
111 | * dpm_power_up - Power on some devices. | ||
112 | * | ||
113 | * Walk the dpm_off_irq list and power each device up. This | ||
114 | * is used for devices that required they be powered down with | ||
115 | * interrupts disabled. As devices are powered on, they are moved | ||
116 | * to the dpm_active list. | ||
117 | * | ||
118 | * Interrupts must be disabled when calling this. | ||
119 | */ | ||
120 | |||
121 | void dpm_power_up(void) | ||
122 | { | ||
123 | while(!list_empty(&dpm_off_irq)) { | ||
124 | struct list_head * entry = dpm_off_irq.next; | ||
125 | struct device * dev = to_device(entry); | ||
126 | |||
127 | list_move_tail(entry, &dpm_off); | ||
128 | resume_device_early(dev); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | |||
133 | /** | ||
134 | * device_power_up - Turn on all devices that need special attention. | ||
135 | * | ||
136 | * Power on system devices then devices that required we shut them down | ||
137 | * with interrupts disabled. | ||
138 | * Called with interrupts disabled. | ||
139 | */ | ||
140 | |||
141 | void device_power_up(void) | ||
142 | { | ||
143 | sysdev_resume(); | ||
144 | dpm_power_up(); | ||
145 | } | ||
146 | |||
147 | EXPORT_SYMBOL_GPL(device_power_up); | ||
148 | |||
149 | |||
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c deleted file mode 100644 index 26df9b231737..000000000000 --- a/drivers/base/power/suspend.c +++ /dev/null | |||
@@ -1,210 +0,0 @@ | |||
1 | /* | ||
2 | * suspend.c - Functions for putting devices to sleep. | ||
3 | * | ||
4 | * Copyright (c) 2003 Patrick Mochel | ||
5 | * Copyright (c) 2003 Open Source Development Labs | ||
6 | * | ||
7 | * This file is released under the GPLv2 | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/device.h> | ||
12 | #include <linux/kallsyms.h> | ||
13 | #include <linux/pm.h> | ||
14 | #include "../base.h" | ||
15 | #include "power.h" | ||
16 | |||
17 | /* | ||
18 | * The entries in the dpm_active list are in a depth first order, simply | ||
19 | * because children are guaranteed to be discovered after parents, and | ||
20 | * are inserted at the back of the list on discovery. | ||
21 | * | ||
22 | * All list on the suspend path are done in reverse order, so we operate | ||
23 | * on the leaves of the device tree (or forests, depending on how you want | ||
24 | * to look at it ;) first. As nodes are removed from the back of the list, | ||
25 | * they are inserted into the front of their destintation lists. | ||
26 | * | ||
27 | * Things are the reverse on the resume path - iterations are done in | ||
28 | * forward order, and nodes are inserted at the back of their destination | ||
29 | * lists. This way, the ancestors will be accessed before their descendents. | ||
30 | */ | ||
31 | |||
32 | static inline char *suspend_verb(u32 event) | ||
33 | { | ||
34 | switch (event) { | ||
35 | case PM_EVENT_SUSPEND: return "suspend"; | ||
36 | case PM_EVENT_FREEZE: return "freeze"; | ||
37 | case PM_EVENT_PRETHAW: return "prethaw"; | ||
38 | default: return "(unknown suspend event)"; | ||
39 | } | ||
40 | } | ||
41 | |||
42 | |||
43 | static void | ||
44 | suspend_device_dbg(struct device *dev, pm_message_t state, char *info) | ||
45 | { | ||
46 | dev_dbg(dev, "%s%s%s\n", info, suspend_verb(state.event), | ||
47 | ((state.event == PM_EVENT_SUSPEND) && device_may_wakeup(dev)) ? | ||
48 | ", may wakeup" : ""); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * suspend_device - Save state of one device. | ||
53 | * @dev: Device. | ||
54 | * @state: Power state device is entering. | ||
55 | */ | ||
56 | |||
57 | int suspend_device(struct device * dev, pm_message_t state) | ||
58 | { | ||
59 | int error = 0; | ||
60 | |||
61 | down(&dev->sem); | ||
62 | if (dev->power.power_state.event) { | ||
63 | dev_dbg(dev, "PM: suspend %d-->%d\n", | ||
64 | dev->power.power_state.event, state.event); | ||
65 | } | ||
66 | |||
67 | if (dev->class && dev->class->suspend) { | ||
68 | suspend_device_dbg(dev, state, "class "); | ||
69 | error = dev->class->suspend(dev, state); | ||
70 | suspend_report_result(dev->class->suspend, error); | ||
71 | } | ||
72 | |||
73 | if (!error && dev->type && dev->type->suspend) { | ||
74 | suspend_device_dbg(dev, state, "type "); | ||
75 | error = dev->type->suspend(dev, state); | ||
76 | suspend_report_result(dev->type->suspend, error); | ||
77 | } | ||
78 | |||
79 | if (!error && dev->bus && dev->bus->suspend) { | ||
80 | suspend_device_dbg(dev, state, ""); | ||
81 | error = dev->bus->suspend(dev, state); | ||
82 | suspend_report_result(dev->bus->suspend, error); | ||
83 | } | ||
84 | up(&dev->sem); | ||
85 | return error; | ||
86 | } | ||
87 | |||
88 | |||
89 | /* | ||
90 | * This is called with interrupts off, only a single CPU | ||
91 | * running. We can't acquire a mutex or semaphore (and we don't | ||
92 | * need the protection) | ||
93 | */ | ||
94 | static int suspend_device_late(struct device *dev, pm_message_t state) | ||
95 | { | ||
96 | int error = 0; | ||
97 | |||
98 | if (dev->bus && dev->bus->suspend_late) { | ||
99 | suspend_device_dbg(dev, state, "LATE "); | ||
100 | error = dev->bus->suspend_late(dev, state); | ||
101 | suspend_report_result(dev->bus->suspend_late, error); | ||
102 | } | ||
103 | return error; | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * device_suspend - Save state and stop all devices in system. | ||
108 | * @state: Power state to put each device in. | ||
109 | * | ||
110 | * Walk the dpm_active list, call ->suspend() for each device, and move | ||
111 | * it to the dpm_off list. | ||
112 | * | ||
113 | * (For historical reasons, if it returns -EAGAIN, that used to mean | ||
114 | * that the device would be called again with interrupts disabled. | ||
115 | * These days, we use the "suspend_late()" callback for that, so we | ||
116 | * print a warning and consider it an error). | ||
117 | * | ||
118 | * If we get a different error, try and back out. | ||
119 | * | ||
120 | * If we hit a failure with any of the devices, call device_resume() | ||
121 | * above to bring the suspended devices back to life. | ||
122 | * | ||
123 | */ | ||
124 | |||
125 | int device_suspend(pm_message_t state) | ||
126 | { | ||
127 | int error = 0; | ||
128 | |||
129 | might_sleep(); | ||
130 | mutex_lock(&dpm_mtx); | ||
131 | mutex_lock(&dpm_list_mtx); | ||
132 | while (!list_empty(&dpm_active) && error == 0) { | ||
133 | struct list_head * entry = dpm_active.prev; | ||
134 | struct device * dev = to_device(entry); | ||
135 | |||
136 | get_device(dev); | ||
137 | mutex_unlock(&dpm_list_mtx); | ||
138 | |||
139 | error = suspend_device(dev, state); | ||
140 | |||
141 | mutex_lock(&dpm_list_mtx); | ||
142 | |||
143 | /* Check if the device got removed */ | ||
144 | if (!list_empty(&dev->power.entry)) { | ||
145 | /* Move it to the dpm_off list */ | ||
146 | if (!error) | ||
147 | list_move(&dev->power.entry, &dpm_off); | ||
148 | } | ||
149 | if (error) | ||
150 | printk(KERN_ERR "Could not suspend device %s: " | ||
151 | "error %d%s\n", | ||
152 | kobject_name(&dev->kobj), error, | ||
153 | error == -EAGAIN ? " (please convert to suspend_late)" : ""); | ||
154 | put_device(dev); | ||
155 | } | ||
156 | mutex_unlock(&dpm_list_mtx); | ||
157 | if (error) | ||
158 | dpm_resume(); | ||
159 | |||
160 | mutex_unlock(&dpm_mtx); | ||
161 | return error; | ||
162 | } | ||
163 | |||
164 | EXPORT_SYMBOL_GPL(device_suspend); | ||
165 | |||
166 | /** | ||
167 | * device_power_down - Shut down special devices. | ||
168 | * @state: Power state to enter. | ||
169 | * | ||
170 | * Walk the dpm_off_irq list, calling ->power_down() for each device that | ||
171 | * couldn't power down the device with interrupts enabled. When we're | ||
172 | * done, power down system devices. | ||
173 | */ | ||
174 | |||
175 | int device_power_down(pm_message_t state) | ||
176 | { | ||
177 | int error = 0; | ||
178 | struct device * dev; | ||
179 | |||
180 | while (!list_empty(&dpm_off)) { | ||
181 | struct list_head * entry = dpm_off.prev; | ||
182 | |||
183 | dev = to_device(entry); | ||
184 | error = suspend_device_late(dev, state); | ||
185 | if (error) | ||
186 | goto Error; | ||
187 | list_move(&dev->power.entry, &dpm_off_irq); | ||
188 | } | ||
189 | |||
190 | error = sysdev_suspend(state); | ||
191 | Done: | ||
192 | return error; | ||
193 | Error: | ||
194 | printk(KERN_ERR "Could not power down device %s: " | ||
195 | "error %d\n", kobject_name(&dev->kobj), error); | ||
196 | dpm_power_up(); | ||
197 | goto Done; | ||
198 | } | ||
199 | |||
200 | EXPORT_SYMBOL_GPL(device_power_down); | ||
201 | |||
202 | void __suspend_report_result(const char *function, void *fn, int ret) | ||
203 | { | ||
204 | if (ret) { | ||
205 | printk(KERN_ERR "%s(): ", function); | ||
206 | print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn); | ||
207 | printk("%d\n", ret); | ||
208 | } | ||
209 | } | ||
210 | EXPORT_SYMBOL_GPL(__suspend_report_result); | ||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 18febe26caa1..ac7ff6d0c6e5 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -139,7 +139,7 @@ int sysdev_class_register(struct sysdev_class * cls) | |||
139 | kobject_name(&cls->kset.kobj)); | 139 | kobject_name(&cls->kset.kobj)); |
140 | INIT_LIST_HEAD(&cls->drivers); | 140 | INIT_LIST_HEAD(&cls->drivers); |
141 | cls->kset.kobj.parent = &system_subsys.kobj; | 141 | cls->kset.kobj.parent = &system_subsys.kobj; |
142 | kset_set_kset_s(cls, system_subsys); | 142 | cls->kset.kobj.kset = &system_subsys; |
143 | return kset_register(&cls->kset); | 143 | return kset_register(&cls->kset); |
144 | } | 144 | } |
145 | 145 | ||
@@ -153,25 +153,22 @@ void sysdev_class_unregister(struct sysdev_class * cls) | |||
153 | EXPORT_SYMBOL_GPL(sysdev_class_register); | 153 | EXPORT_SYMBOL_GPL(sysdev_class_register); |
154 | EXPORT_SYMBOL_GPL(sysdev_class_unregister); | 154 | EXPORT_SYMBOL_GPL(sysdev_class_unregister); |
155 | 155 | ||
156 | |||
157 | static LIST_HEAD(sysdev_drivers); | ||
158 | static DEFINE_MUTEX(sysdev_drivers_lock); | 156 | static DEFINE_MUTEX(sysdev_drivers_lock); |
159 | 157 | ||
160 | /** | 158 | /** |
161 | * sysdev_driver_register - Register auxillary driver | 159 | * sysdev_driver_register - Register auxillary driver |
162 | * @cls: Device class driver belongs to. | 160 | * @cls: Device class driver belongs to. |
163 | * @drv: Driver. | 161 | * @drv: Driver. |
164 | * | 162 | * |
165 | * If @cls is valid, then @drv is inserted into @cls->drivers to be | 163 | * @drv is inserted into @cls->drivers to be |
166 | * called on each operation on devices of that class. The refcount | 164 | * called on each operation on devices of that class. The refcount |
167 | * of @cls is incremented. | 165 | * of @cls is incremented. |
168 | * Otherwise, @drv is inserted into sysdev_drivers, and called for | ||
169 | * each device. | ||
170 | */ | 166 | */ |
171 | 167 | ||
172 | int sysdev_driver_register(struct sysdev_class * cls, | 168 | int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) |
173 | struct sysdev_driver * drv) | ||
174 | { | 169 | { |
170 | int err = 0; | ||
171 | |||
175 | mutex_lock(&sysdev_drivers_lock); | 172 | mutex_lock(&sysdev_drivers_lock); |
176 | if (cls && kset_get(&cls->kset)) { | 173 | if (cls && kset_get(&cls->kset)) { |
177 | list_add_tail(&drv->entry, &cls->drivers); | 174 | list_add_tail(&drv->entry, &cls->drivers); |
@@ -182,10 +179,13 @@ int sysdev_driver_register(struct sysdev_class * cls, | |||
182 | list_for_each_entry(dev, &cls->kset.list, kobj.entry) | 179 | list_for_each_entry(dev, &cls->kset.list, kobj.entry) |
183 | drv->add(dev); | 180 | drv->add(dev); |
184 | } | 181 | } |
185 | } else | 182 | } else { |
186 | list_add_tail(&drv->entry, &sysdev_drivers); | 183 | err = -EINVAL; |
184 | printk(KERN_ERR "%s: invalid device class\n", __FUNCTION__); | ||
185 | WARN_ON(1); | ||
186 | } | ||
187 | mutex_unlock(&sysdev_drivers_lock); | 187 | mutex_unlock(&sysdev_drivers_lock); |
188 | return 0; | 188 | return err; |
189 | } | 189 | } |
190 | 190 | ||
191 | 191 | ||
@@ -251,12 +251,6 @@ int sysdev_register(struct sys_device * sysdev) | |||
251 | * code that should have called us. | 251 | * code that should have called us. |
252 | */ | 252 | */ |
253 | 253 | ||
254 | /* Notify global drivers */ | ||
255 | list_for_each_entry(drv, &sysdev_drivers, entry) { | ||
256 | if (drv->add) | ||
257 | drv->add(sysdev); | ||
258 | } | ||
259 | |||
260 | /* Notify class auxillary drivers */ | 254 | /* Notify class auxillary drivers */ |
261 | list_for_each_entry(drv, &cls->drivers, entry) { | 255 | list_for_each_entry(drv, &cls->drivers, entry) { |
262 | if (drv->add) | 256 | if (drv->add) |
@@ -272,11 +266,6 @@ void sysdev_unregister(struct sys_device * sysdev) | |||
272 | struct sysdev_driver * drv; | 266 | struct sysdev_driver * drv; |
273 | 267 | ||
274 | mutex_lock(&sysdev_drivers_lock); | 268 | mutex_lock(&sysdev_drivers_lock); |
275 | list_for_each_entry(drv, &sysdev_drivers, entry) { | ||
276 | if (drv->remove) | ||
277 | drv->remove(sysdev); | ||
278 | } | ||
279 | |||
280 | list_for_each_entry(drv, &sysdev->cls->drivers, entry) { | 269 | list_for_each_entry(drv, &sysdev->cls->drivers, entry) { |
281 | if (drv->remove) | 270 | if (drv->remove) |
282 | drv->remove(sysdev); | 271 | drv->remove(sysdev); |
@@ -293,7 +282,7 @@ void sysdev_unregister(struct sys_device * sysdev) | |||
293 | * | 282 | * |
294 | * Loop over each class of system devices, and the devices in each | 283 | * Loop over each class of system devices, and the devices in each |
295 | * of those classes. For each device, we call the shutdown method for | 284 | * of those classes. For each device, we call the shutdown method for |
296 | * each driver registered for the device - the globals, the auxillaries, | 285 | * each driver registered for the device - the auxillaries, |
297 | * and the class driver. | 286 | * and the class driver. |
298 | * | 287 | * |
299 | * Note: The list is iterated in reverse order, so that we shut down | 288 | * Note: The list is iterated in reverse order, so that we shut down |
@@ -320,13 +309,7 @@ void sysdev_shutdown(void) | |||
320 | struct sysdev_driver * drv; | 309 | struct sysdev_driver * drv; |
321 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); | 310 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); |
322 | 311 | ||
323 | /* Call global drivers first. */ | 312 | /* Call auxillary drivers first */ |
324 | list_for_each_entry(drv, &sysdev_drivers, entry) { | ||
325 | if (drv->shutdown) | ||
326 | drv->shutdown(sysdev); | ||
327 | } | ||
328 | |||
329 | /* Call auxillary drivers next. */ | ||
330 | list_for_each_entry(drv, &cls->drivers, entry) { | 313 | list_for_each_entry(drv, &cls->drivers, entry) { |
331 | if (drv->shutdown) | 314 | if (drv->shutdown) |
332 | drv->shutdown(sysdev); | 315 | drv->shutdown(sysdev); |
@@ -354,12 +337,6 @@ static void __sysdev_resume(struct sys_device *dev) | |||
354 | if (drv->resume) | 337 | if (drv->resume) |
355 | drv->resume(dev); | 338 | drv->resume(dev); |
356 | } | 339 | } |
357 | |||
358 | /* Call global drivers. */ | ||
359 | list_for_each_entry(drv, &sysdev_drivers, entry) { | ||
360 | if (drv->resume) | ||
361 | drv->resume(dev); | ||
362 | } | ||
363 | } | 340 | } |
364 | 341 | ||
365 | /** | 342 | /** |
@@ -393,16 +370,7 @@ int sysdev_suspend(pm_message_t state) | |||
393 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { | 370 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { |
394 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); | 371 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); |
395 | 372 | ||
396 | /* Call global drivers first. */ | 373 | /* Call auxillary drivers first */ |
397 | list_for_each_entry(drv, &sysdev_drivers, entry) { | ||
398 | if (drv->suspend) { | ||
399 | ret = drv->suspend(sysdev, state); | ||
400 | if (ret) | ||
401 | goto gbl_driver; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | /* Call auxillary drivers next. */ | ||
406 | list_for_each_entry(drv, &cls->drivers, entry) { | 374 | list_for_each_entry(drv, &cls->drivers, entry) { |
407 | if (drv->suspend) { | 375 | if (drv->suspend) { |
408 | ret = drv->suspend(sysdev, state); | 376 | ret = drv->suspend(sysdev, state); |
@@ -436,18 +404,7 @@ aux_driver: | |||
436 | if (err_drv->resume) | 404 | if (err_drv->resume) |
437 | err_drv->resume(sysdev); | 405 | err_drv->resume(sysdev); |
438 | } | 406 | } |
439 | drv = NULL; | ||
440 | 407 | ||
441 | gbl_driver: | ||
442 | if (drv) | ||
443 | printk(KERN_ERR "sysdev driver suspend failed for %s\n", | ||
444 | kobject_name(&sysdev->kobj)); | ||
445 | list_for_each_entry(err_drv, &sysdev_drivers, entry) { | ||
446 | if (err_drv == drv) | ||
447 | break; | ||
448 | if (err_drv->resume) | ||
449 | err_drv->resume(sysdev); | ||
450 | } | ||
451 | /* resume other sysdevs in current class */ | 408 | /* resume other sysdevs in current class */ |
452 | list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { | 409 | list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { |
453 | if (err_dev == sysdev) | 410 | if (err_dev == sysdev) |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 4245b7f80a49..ca4d7f0d09b7 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -361,8 +361,7 @@ config BLK_DEV_RAM_SIZE | |||
361 | default "4096" | 361 | default "4096" |
362 | help | 362 | help |
363 | The default value is 4096 kilobytes. Only change this if you know | 363 | The default value is 4096 kilobytes. Only change this if you know |
364 | what are you doing. If you are using IBM S/390, then set this to | 364 | what are you doing. |
365 | 8192. | ||
366 | 365 | ||
367 | config BLK_DEV_RAM_BLOCKSIZE | 366 | config BLK_DEV_RAM_BLOCKSIZE |
368 | int "Default RAM disk block size (bytes)" | 367 | int "Default RAM disk block size (bytes)" |
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 9b8278e1f4f8..acbfe1c49b4d 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c | |||
@@ -513,7 +513,7 @@ static int __init dsp56k_init_driver(void) | |||
513 | err = PTR_ERR(dsp56k_class); | 513 | err = PTR_ERR(dsp56k_class); |
514 | goto out_chrdev; | 514 | goto out_chrdev; |
515 | } | 515 | } |
516 | class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); | 516 | device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), "dsp56k"); |
517 | 517 | ||
518 | printk(banner); | 518 | printk(banner); |
519 | goto out; | 519 | goto out; |
@@ -527,7 +527,7 @@ module_init(dsp56k_init_driver); | |||
527 | 527 | ||
528 | static void __exit dsp56k_cleanup_driver(void) | 528 | static void __exit dsp56k_cleanup_driver(void) |
529 | { | 529 | { |
530 | class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0)); | 530 | device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0)); |
531 | class_destroy(dsp56k_class); | 531 | class_destroy(dsp56k_class); |
532 | unregister_chrdev(DSP56K_MAJOR, "dsp56k"); | 532 | unregister_chrdev(DSP56K_MAJOR, "dsp56k"); |
533 | } | 533 | } |
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 8d74b8745e60..bd94d5f9e62b 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -411,8 +411,8 @@ cleanup_module(void) | |||
411 | iiResetDelay( i2BoardPtrTable[i] ); | 411 | iiResetDelay( i2BoardPtrTable[i] ); |
412 | /* free io addresses and Tibet */ | 412 | /* free io addresses and Tibet */ |
413 | release_region( ip2config.addr[i], 8 ); | 413 | release_region( ip2config.addr[i], 8 ); |
414 | class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); | 414 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); |
415 | class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); | 415 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); |
416 | } | 416 | } |
417 | /* Disable and remove interrupt handler. */ | 417 | /* Disable and remove interrupt handler. */ |
418 | if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { | 418 | if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { |
@@ -718,12 +718,12 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
718 | } | 718 | } |
719 | 719 | ||
720 | if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { | 720 | if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { |
721 | class_device_create(ip2_class, NULL, | 721 | device_create(ip2_class, NULL, |
722 | MKDEV(IP2_IPL_MAJOR, 4 * i), | 722 | MKDEV(IP2_IPL_MAJOR, 4 * i), |
723 | NULL, "ipl%d", i); | 723 | "ipl%d", i); |
724 | class_device_create(ip2_class, NULL, | 724 | device_create(ip2_class, NULL, |
725 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), | 725 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), |
726 | NULL, "stat%d", i); | 726 | "stat%d", i); |
727 | 727 | ||
728 | for ( box = 0; box < ABS_MAX_BOXES; ++box ) | 728 | for ( box = 0; box < ABS_MAX_BOXES; ++box ) |
729 | { | 729 | { |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index c2aa44ee6eb6..0246a2b8ce48 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -865,7 +865,7 @@ static void ipmi_new_smi(int if_num, struct device *device) | |||
865 | entry->dev = dev; | 865 | entry->dev = dev; |
866 | 866 | ||
867 | mutex_lock(®_list_mutex); | 867 | mutex_lock(®_list_mutex); |
868 | class_device_create(ipmi_class, NULL, dev, device, "ipmi%d", if_num); | 868 | device_create(ipmi_class, device, dev, "ipmi%d", if_num); |
869 | list_add(&entry->link, ®_list); | 869 | list_add(&entry->link, ®_list); |
870 | mutex_unlock(®_list_mutex); | 870 | mutex_unlock(®_list_mutex); |
871 | } | 871 | } |
@@ -883,7 +883,7 @@ static void ipmi_smi_gone(int if_num) | |||
883 | break; | 883 | break; |
884 | } | 884 | } |
885 | } | 885 | } |
886 | class_device_destroy(ipmi_class, dev); | 886 | device_destroy(ipmi_class, dev); |
887 | mutex_unlock(®_list_mutex); | 887 | mutex_unlock(®_list_mutex); |
888 | } | 888 | } |
889 | 889 | ||
@@ -938,7 +938,7 @@ static __exit void cleanup_ipmi(void) | |||
938 | mutex_lock(®_list_mutex); | 938 | mutex_lock(®_list_mutex); |
939 | list_for_each_entry_safe(entry, entry2, ®_list, link) { | 939 | list_for_each_entry_safe(entry, entry2, ®_list, link) { |
940 | list_del(&entry->link); | 940 | list_del(&entry->link); |
941 | class_device_destroy(ipmi_class, entry->dev); | 941 | device_destroy(ipmi_class, entry->dev); |
942 | kfree(entry); | 942 | kfree(entry); |
943 | } | 943 | } |
944 | mutex_unlock(®_list_mutex); | 944 | mutex_unlock(®_list_mutex); |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 3c66f402f9d7..1f27be1ec3d4 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -4624,9 +4624,8 @@ static int __init istallion_module_init(void) | |||
4624 | 4624 | ||
4625 | istallion_class = class_create(THIS_MODULE, "staliomem"); | 4625 | istallion_class = class_create(THIS_MODULE, "staliomem"); |
4626 | for (i = 0; i < 4; i++) | 4626 | for (i = 0; i < 4; i++) |
4627 | class_device_create(istallion_class, NULL, | 4627 | device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), |
4628 | MKDEV(STL_SIOMEMMAJOR, i), | 4628 | "staliomem%d", i); |
4629 | NULL, "staliomem%d", i); | ||
4630 | 4629 | ||
4631 | return 0; | 4630 | return 0; |
4632 | err_deinit: | 4631 | err_deinit: |
@@ -4659,8 +4658,7 @@ static void __exit istallion_module_exit(void) | |||
4659 | unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); | 4658 | unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); |
4660 | 4659 | ||
4661 | for (j = 0; j < 4; j++) | 4660 | for (j = 0; j < 4; j++) |
4662 | class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, | 4661 | device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j)); |
4663 | j)); | ||
4664 | class_destroy(istallion_class); | 4662 | class_destroy(istallion_class); |
4665 | 4663 | ||
4666 | pci_unregister_driver(&stli_pcidriver); | 4664 | pci_unregister_driver(&stli_pcidriver); |
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 62051f8b0910..c59e2a0996cc 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -799,8 +799,7 @@ static int lp_register(int nr, struct parport *port) | |||
799 | if (reset) | 799 | if (reset) |
800 | lp_reset(nr); | 800 | lp_reset(nr); |
801 | 801 | ||
802 | class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev, | 802 | device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), "lp%d", nr); |
803 | "lp%d", nr); | ||
804 | 803 | ||
805 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, | 804 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, |
806 | (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); | 805 | (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); |
@@ -971,7 +970,7 @@ static void lp_cleanup_module (void) | |||
971 | if (lp_table[offset].dev == NULL) | 970 | if (lp_table[offset].dev == NULL) |
972 | continue; | 971 | continue; |
973 | parport_unregister_device(lp_table[offset].dev); | 972 | parport_unregister_device(lp_table[offset].dev); |
974 | class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset)); | 973 | device_destroy(lp_class, MKDEV(LP_MAJOR, offset)); |
975 | } | 974 | } |
976 | class_destroy(lp_class); | 975 | class_destroy(lp_class); |
977 | } | 976 | } |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 4177f6db83e9..cc5d77797def 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -1863,8 +1863,7 @@ static int cm4000_probe(struct pcmcia_device *link) | |||
1863 | return ret; | 1863 | return ret; |
1864 | } | 1864 | } |
1865 | 1865 | ||
1866 | class_device_create(cmm_class, NULL, MKDEV(major, i), NULL, | 1866 | device_create(cmm_class, NULL, MKDEV(major, i), "cmm%d", i); |
1867 | "cmm%d", i); | ||
1868 | 1867 | ||
1869 | return 0; | 1868 | return 0; |
1870 | } | 1869 | } |
@@ -1888,7 +1887,7 @@ static void cm4000_detach(struct pcmcia_device *link) | |||
1888 | dev_table[devno] = NULL; | 1887 | dev_table[devno] = NULL; |
1889 | kfree(dev); | 1888 | kfree(dev); |
1890 | 1889 | ||
1891 | class_device_destroy(cmm_class, MKDEV(major, devno)); | 1890 | device_destroy(cmm_class, MKDEV(major, devno)); |
1892 | 1891 | ||
1893 | return; | 1892 | return; |
1894 | } | 1893 | } |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index b24a3e7bbb9f..a0b9c8728d56 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -642,8 +642,7 @@ static int reader_probe(struct pcmcia_device *link) | |||
642 | return ret; | 642 | return ret; |
643 | } | 643 | } |
644 | 644 | ||
645 | class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, | 645 | device_create(cmx_class, NULL, MKDEV(major, i), "cmx%d", i); |
646 | "cmx%d", i); | ||
647 | 646 | ||
648 | return 0; | 647 | return 0; |
649 | } | 648 | } |
@@ -666,7 +665,7 @@ static void reader_detach(struct pcmcia_device *link) | |||
666 | dev_table[devno] = NULL; | 665 | dev_table[devno] = NULL; |
667 | kfree(dev); | 666 | kfree(dev); |
668 | 667 | ||
669 | class_device_destroy(cmx_class, MKDEV(major, devno)); | 668 | device_destroy(cmx_class, MKDEV(major, devno)); |
670 | 669 | ||
671 | return; | 670 | return; |
672 | } | 671 | } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index de14aea34e11..73de77105fea 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -248,14 +248,19 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file, | |||
248 | return -ENOIOCTLCMD; | 248 | return -ENOIOCTLCMD; |
249 | } | 249 | } |
250 | 250 | ||
251 | static int legacy_count = CONFIG_LEGACY_PTY_COUNT; | ||
252 | module_param(legacy_count, int, 0); | ||
253 | |||
251 | static void __init legacy_pty_init(void) | 254 | static void __init legacy_pty_init(void) |
252 | { | 255 | { |
256 | if (legacy_count <= 0) | ||
257 | return; | ||
253 | 258 | ||
254 | pty_driver = alloc_tty_driver(NR_PTYS); | 259 | pty_driver = alloc_tty_driver(legacy_count); |
255 | if (!pty_driver) | 260 | if (!pty_driver) |
256 | panic("Couldn't allocate pty driver"); | 261 | panic("Couldn't allocate pty driver"); |
257 | 262 | ||
258 | pty_slave_driver = alloc_tty_driver(NR_PTYS); | 263 | pty_slave_driver = alloc_tty_driver(legacy_count); |
259 | if (!pty_slave_driver) | 264 | if (!pty_slave_driver) |
260 | panic("Couldn't allocate pty slave driver"); | 265 | panic("Couldn't allocate pty slave driver"); |
261 | 266 | ||
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 1f0d7c60c944..bbfa0e241cba 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -255,10 +255,7 @@ static const struct file_operations raw_ctl_fops = { | |||
255 | .owner = THIS_MODULE, | 255 | .owner = THIS_MODULE, |
256 | }; | 256 | }; |
257 | 257 | ||
258 | static struct cdev raw_cdev = { | 258 | static struct cdev raw_cdev; |
259 | .kobj = {.name = "raw", }, | ||
260 | .owner = THIS_MODULE, | ||
261 | }; | ||
262 | 259 | ||
263 | static int __init raw_init(void) | 260 | static int __init raw_init(void) |
264 | { | 261 | { |
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 52753e723eaa..b9c1dba6bd01 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c | |||
@@ -441,8 +441,7 @@ scdrv_init(void) | |||
441 | continue; | 441 | continue; |
442 | } | 442 | } |
443 | 443 | ||
444 | class_device_create(snsc_class, NULL, dev, NULL, | 444 | device_create(snsc_class, NULL, dev, "%s", devname); |
445 | "%s", devname); | ||
446 | 445 | ||
447 | ia64_sn_irtr_intr_enable(scd->scd_nasid, | 446 | ia64_sn_irtr_intr_enable(scd->scd_nasid, |
448 | 0 /*ignored */ , | 447 | 0 /*ignored */ , |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 4a80b2f864e0..45758d5b56ef 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -4778,9 +4778,8 @@ static int __init stallion_module_init(void) | |||
4778 | if (IS_ERR(stallion_class)) | 4778 | if (IS_ERR(stallion_class)) |
4779 | printk("STALLION: failed to create class\n"); | 4779 | printk("STALLION: failed to create class\n"); |
4780 | for (i = 0; i < 4; i++) | 4780 | for (i = 0; i < 4; i++) |
4781 | class_device_create(stallion_class, NULL, | 4781 | device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), |
4782 | MKDEV(STL_SIOMEMMAJOR, i), NULL, | 4782 | "staliomem%d", i); |
4783 | "staliomem%d", i); | ||
4784 | 4783 | ||
4785 | return 0; | 4784 | return 0; |
4786 | err_unrtty: | 4785 | err_unrtty: |
@@ -4816,7 +4815,7 @@ static void __exit stallion_module_exit(void) | |||
4816 | } | 4815 | } |
4817 | 4816 | ||
4818 | for (i = 0; i < 4; i++) | 4817 | for (i = 0; i < 4; i++) |
4819 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | 4818 | device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); |
4820 | unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); | 4819 | unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); |
4821 | class_destroy(stallion_class); | 4820 | class_destroy(stallion_class); |
4822 | 4821 | ||
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 35b40b996534..cef55c40654f 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -441,8 +441,8 @@ tipar_register(int nr, struct parport *port) | |||
441 | goto out; | 441 | goto out; |
442 | } | 442 | } |
443 | 443 | ||
444 | class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, | 444 | device_create(tipar_class, port->dev, MKDEV(TIPAR_MAJOR, |
445 | TIPAR_MINOR + nr), port->dev, "par%d", nr); | 445 | TIPAR_MINOR + nr), "par%d", nr); |
446 | 446 | ||
447 | /* Display informations */ | 447 | /* Display informations */ |
448 | pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == | 448 | pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == |
@@ -534,7 +534,7 @@ tipar_cleanup_module(void) | |||
534 | if (table[i].dev == NULL) | 534 | if (table[i].dev == NULL) |
535 | continue; | 535 | continue; |
536 | parport_unregister_device(table[i].dev); | 536 | parport_unregister_device(table[i].dev); |
537 | class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i)); | 537 | device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i)); |
538 | } | 538 | } |
539 | class_destroy(tipar_class); | 539 | class_destroy(tipar_class); |
540 | 540 | ||
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index f1d60f0cef8f..db7a731e2362 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -871,10 +871,10 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
871 | state[i].cur_part = 0; | 871 | state[i].cur_part = 0; |
872 | for (j = 0; j < MAX_PARTITIONS; ++j) | 872 | for (j = 0; j < MAX_PARTITIONS; ++j) |
873 | state[i].part_stat_rwi[j] = VIOT_IDLE; | 873 | state[i].part_stat_rwi[j] = VIOT_IDLE; |
874 | class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL, | 874 | device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), |
875 | "iseries!vt%d", i); | 875 | "iseries!vt%d", i); |
876 | class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), | 876 | device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), |
877 | NULL, "iseries!nvt%d", i); | 877 | "iseries!nvt%d", i); |
878 | printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries " | 878 | printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries " |
879 | "resource %10.10s type %4.4s, model %3.3s\n", | 879 | "resource %10.10s type %4.4s, model %3.3s\n", |
880 | i, viotape_unitinfo[i].rsrcname, | 880 | i, viotape_unitinfo[i].rsrcname, |
@@ -886,8 +886,8 @@ static int viotape_remove(struct vio_dev *vdev) | |||
886 | { | 886 | { |
887 | int i = vdev->unit_address; | 887 | int i = vdev->unit_address; |
888 | 888 | ||
889 | class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80)); | 889 | device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80)); |
890 | class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i)); | 890 | device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i)); |
891 | return 0; | 891 | return 0; |
892 | } | 892 | } |
893 | 893 | ||
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 993fa7b89253..721f86f4f008 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
@@ -56,10 +56,6 @@ config CPU_FREQ_STAT_DETAILS | |||
56 | 56 | ||
57 | If in doubt, say N. | 57 | If in doubt, say N. |
58 | 58 | ||
59 | # Note that it is not currently possible to set the other governors (such as ondemand) | ||
60 | # as the default, since if they fail to initialise, cpufreq will be | ||
61 | # left in an undefined state. | ||
62 | |||
63 | choice | 59 | choice |
64 | prompt "Default CPUFreq governor" | 60 | prompt "Default CPUFreq governor" |
65 | default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 | 61 | default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 |
@@ -85,6 +81,29 @@ config CPU_FREQ_DEFAULT_GOV_USERSPACE | |||
85 | program shall be able to set the CPU dynamically without having | 81 | program shall be able to set the CPU dynamically without having |
86 | to enable the userspace governor manually. | 82 | to enable the userspace governor manually. |
87 | 83 | ||
84 | config CPU_FREQ_DEFAULT_GOV_ONDEMAND | ||
85 | bool "ondemand" | ||
86 | select CPU_FREQ_GOV_ONDEMAND | ||
87 | select CPU_FREQ_GOV_PERFORMANCE | ||
88 | help | ||
89 | Use the CPUFreq governor 'ondemand' as default. This allows | ||
90 | you to get a full dynamic frequency capable system by simply | ||
91 | loading your cpufreq low-level hardware driver. | ||
92 | Be aware that not all cpufreq drivers support the ondemand | ||
93 | governor. If unsure have a look at the help section of the | ||
94 | driver. Fallback governor will be the performance governor. | ||
95 | |||
96 | config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE | ||
97 | bool "conservative" | ||
98 | select CPU_FREQ_GOV_CONSERVATIVE | ||
99 | select CPU_FREQ_GOV_PERFORMANCE | ||
100 | help | ||
101 | Use the CPUFreq governor 'conservative' as default. This allows | ||
102 | you to get a full dynamic frequency capable system by simply | ||
103 | loading your cpufreq low-level hardware driver. | ||
104 | Be aware that not all cpufreq drivers support the conservative | ||
105 | governor. If unsure have a look at the help section of the | ||
106 | driver. Fallback governor will be the performance governor. | ||
88 | endchoice | 107 | endchoice |
89 | 108 | ||
90 | config CPU_FREQ_GOV_PERFORMANCE | 109 | config CPU_FREQ_GOV_PERFORMANCE |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2f6a73c01b71..5e626b12b97e 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -763,6 +763,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
763 | init_completion(&policy->kobj_unregister); | 763 | init_completion(&policy->kobj_unregister); |
764 | INIT_WORK(&policy->update, handle_update); | 764 | INIT_WORK(&policy->update, handle_update); |
765 | 765 | ||
766 | /* Set governor before ->init, so that driver could check it */ | ||
767 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
766 | /* call driver. From then on the cpufreq must be able | 768 | /* call driver. From then on the cpufreq must be able |
767 | * to accept all calls to ->verify and ->setpolicy for this CPU | 769 | * to accept all calls to ->verify and ->setpolicy for this CPU |
768 | */ | 770 | */ |
@@ -828,7 +830,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
828 | /* prepare interface data */ | 830 | /* prepare interface data */ |
829 | policy->kobj.parent = &sys_dev->kobj; | 831 | policy->kobj.parent = &sys_dev->kobj; |
830 | policy->kobj.ktype = &ktype_cpufreq; | 832 | policy->kobj.ktype = &ktype_cpufreq; |
831 | strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN); | 833 | kobject_set_name(&policy->kobj, "cpufreq"); |
832 | 834 | ||
833 | ret = kobject_register(&policy->kobj); | 835 | ret = kobject_register(&policy->kobj); |
834 | if (ret) { | 836 | if (ret) { |
@@ -1109,12 +1111,7 @@ unsigned int cpufreq_quick_get(unsigned int cpu) | |||
1109 | unsigned int ret_freq = 0; | 1111 | unsigned int ret_freq = 0; |
1110 | 1112 | ||
1111 | if (policy) { | 1113 | if (policy) { |
1112 | if (unlikely(lock_policy_rwsem_read(cpu))) | ||
1113 | return ret_freq; | ||
1114 | |||
1115 | ret_freq = policy->cur; | 1114 | ret_freq = policy->cur; |
1116 | |||
1117 | unlock_policy_rwsem_read(cpu); | ||
1118 | cpufreq_cpu_put(policy); | 1115 | cpufreq_cpu_put(policy); |
1119 | } | 1116 | } |
1120 | 1117 | ||
@@ -1483,6 +1480,31 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, | |||
1483 | { | 1480 | { |
1484 | int ret; | 1481 | int ret; |
1485 | 1482 | ||
1483 | /* Only must be defined when default governor is known to have latency | ||
1484 | restrictions, like e.g. conservative or ondemand. | ||
1485 | That this is the case is already ensured in Kconfig | ||
1486 | */ | ||
1487 | #ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE | ||
1488 | struct cpufreq_governor *gov = &cpufreq_gov_performance; | ||
1489 | #else | ||
1490 | struct cpufreq_governor *gov = NULL; | ||
1491 | #endif | ||
1492 | |||
1493 | if (policy->governor->max_transition_latency && | ||
1494 | policy->cpuinfo.transition_latency > | ||
1495 | policy->governor->max_transition_latency) { | ||
1496 | if (!gov) | ||
1497 | return -EINVAL; | ||
1498 | else { | ||
1499 | printk(KERN_WARNING "%s governor failed, too long" | ||
1500 | " transition latency of HW, fallback" | ||
1501 | " to %s governor\n", | ||
1502 | policy->governor->name, | ||
1503 | gov->name); | ||
1504 | policy->governor = gov; | ||
1505 | } | ||
1506 | } | ||
1507 | |||
1486 | if (!try_module_get(policy->governor->owner)) | 1508 | if (!try_module_get(policy->governor->owner)) |
1487 | return -EINVAL; | 1509 | return -EINVAL; |
1488 | 1510 | ||
@@ -1703,7 +1725,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
1703 | } | 1725 | } |
1704 | EXPORT_SYMBOL(cpufreq_update_policy); | 1726 | EXPORT_SYMBOL(cpufreq_update_policy); |
1705 | 1727 | ||
1706 | static int cpufreq_cpu_callback(struct notifier_block *nfb, | 1728 | static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, |
1707 | unsigned long action, void *hcpu) | 1729 | unsigned long action, void *hcpu) |
1708 | { | 1730 | { |
1709 | unsigned int cpu = (unsigned long)hcpu; | 1731 | unsigned int cpu = (unsigned long)hcpu; |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 26f440ccc3fb..4bd33ce8a6f3 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -58,7 +58,7 @@ static unsigned int def_sampling_rate; | |||
58 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) | 58 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) |
59 | #define DEF_SAMPLING_DOWN_FACTOR (1) | 59 | #define DEF_SAMPLING_DOWN_FACTOR (1) |
60 | #define MAX_SAMPLING_DOWN_FACTOR (10) | 60 | #define MAX_SAMPLING_DOWN_FACTOR (10) |
61 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | 61 | #define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) |
62 | 62 | ||
63 | static void do_dbs_timer(struct work_struct *work); | 63 | static void do_dbs_timer(struct work_struct *work); |
64 | 64 | ||
@@ -466,9 +466,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
466 | (!policy->cur)) | 466 | (!policy->cur)) |
467 | return -EINVAL; | 467 | return -EINVAL; |
468 | 468 | ||
469 | if (policy->cpuinfo.transition_latency > | ||
470 | (TRANSITION_LATENCY_LIMIT * 1000)) | ||
471 | return -EINVAL; | ||
472 | if (this_dbs_info->enable) /* Already enabled */ | 469 | if (this_dbs_info->enable) /* Already enabled */ |
473 | break; | 470 | break; |
474 | 471 | ||
@@ -551,15 +548,17 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
551 | return 0; | 548 | return 0; |
552 | } | 549 | } |
553 | 550 | ||
554 | static struct cpufreq_governor cpufreq_gov_dbs = { | 551 | struct cpufreq_governor cpufreq_gov_conservative = { |
555 | .name = "conservative", | 552 | .name = "conservative", |
556 | .governor = cpufreq_governor_dbs, | 553 | .governor = cpufreq_governor_dbs, |
557 | .owner = THIS_MODULE, | 554 | .max_transition_latency = TRANSITION_LATENCY_LIMIT, |
555 | .owner = THIS_MODULE, | ||
558 | }; | 556 | }; |
557 | EXPORT_SYMBOL(cpufreq_gov_conservative); | ||
559 | 558 | ||
560 | static int __init cpufreq_gov_dbs_init(void) | 559 | static int __init cpufreq_gov_dbs_init(void) |
561 | { | 560 | { |
562 | return cpufreq_register_governor(&cpufreq_gov_dbs); | 561 | return cpufreq_register_governor(&cpufreq_gov_conservative); |
563 | } | 562 | } |
564 | 563 | ||
565 | static void __exit cpufreq_gov_dbs_exit(void) | 564 | static void __exit cpufreq_gov_dbs_exit(void) |
@@ -567,7 +566,7 @@ static void __exit cpufreq_gov_dbs_exit(void) | |||
567 | /* Make sure that the scheduled work is indeed not running */ | 566 | /* Make sure that the scheduled work is indeed not running */ |
568 | flush_scheduled_work(); | 567 | flush_scheduled_work(); |
569 | 568 | ||
570 | cpufreq_unregister_governor(&cpufreq_gov_dbs); | 569 | cpufreq_unregister_governor(&cpufreq_gov_conservative); |
571 | } | 570 | } |
572 | 571 | ||
573 | 572 | ||
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index e794527e4925..369f44595150 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -47,7 +47,7 @@ static unsigned int def_sampling_rate; | |||
47 | (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) | 47 | (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) |
48 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | 48 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) |
49 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) | 49 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) |
50 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | 50 | #define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) |
51 | 51 | ||
52 | static void do_dbs_timer(struct work_struct *work); | 52 | static void do_dbs_timer(struct work_struct *work); |
53 | 53 | ||
@@ -508,12 +508,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
508 | if ((!cpu_online(cpu)) || (!policy->cur)) | 508 | if ((!cpu_online(cpu)) || (!policy->cur)) |
509 | return -EINVAL; | 509 | return -EINVAL; |
510 | 510 | ||
511 | if (policy->cpuinfo.transition_latency > | ||
512 | (TRANSITION_LATENCY_LIMIT * 1000)) { | ||
513 | printk(KERN_WARNING "ondemand governor failed to load " | ||
514 | "due to too long transition latency\n"); | ||
515 | return -EINVAL; | ||
516 | } | ||
517 | if (this_dbs_info->enable) /* Already enabled */ | 511 | if (this_dbs_info->enable) /* Already enabled */ |
518 | break; | 512 | break; |
519 | 513 | ||
@@ -585,11 +579,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
585 | return 0; | 579 | return 0; |
586 | } | 580 | } |
587 | 581 | ||
588 | static struct cpufreq_governor cpufreq_gov_dbs = { | 582 | struct cpufreq_governor cpufreq_gov_ondemand = { |
589 | .name = "ondemand", | 583 | .name = "ondemand", |
590 | .governor = cpufreq_governor_dbs, | 584 | .governor = cpufreq_governor_dbs, |
591 | .owner = THIS_MODULE, | 585 | .max_transition_latency = TRANSITION_LATENCY_LIMIT, |
586 | .owner = THIS_MODULE, | ||
592 | }; | 587 | }; |
588 | EXPORT_SYMBOL(cpufreq_gov_ondemand); | ||
593 | 589 | ||
594 | static int __init cpufreq_gov_dbs_init(void) | 590 | static int __init cpufreq_gov_dbs_init(void) |
595 | { | 591 | { |
@@ -598,12 +594,12 @@ static int __init cpufreq_gov_dbs_init(void) | |||
598 | printk(KERN_ERR "Creation of kondemand failed\n"); | 594 | printk(KERN_ERR "Creation of kondemand failed\n"); |
599 | return -EFAULT; | 595 | return -EFAULT; |
600 | } | 596 | } |
601 | return cpufreq_register_governor(&cpufreq_gov_dbs); | 597 | return cpufreq_register_governor(&cpufreq_gov_ondemand); |
602 | } | 598 | } |
603 | 599 | ||
604 | static void __exit cpufreq_gov_dbs_exit(void) | 600 | static void __exit cpufreq_gov_dbs_exit(void) |
605 | { | 601 | { |
606 | cpufreq_unregister_governor(&cpufreq_gov_dbs); | 602 | cpufreq_unregister_governor(&cpufreq_gov_ondemand); |
607 | destroy_workqueue(kondemand_wq); | 603 | destroy_workqueue(kondemand_wq); |
608 | } | 604 | } |
609 | 605 | ||
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 917b9bab9ccb..8a45d0f93e26 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -164,8 +164,7 @@ freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) | |||
164 | return -1; | 164 | return -1; |
165 | } | 165 | } |
166 | 166 | ||
167 | static void | 167 | static void __cpuexit cpufreq_stats_free_table(unsigned int cpu) |
168 | cpufreq_stats_free_table (unsigned int cpu) | ||
169 | { | 168 | { |
170 | struct cpufreq_stats *stat = cpufreq_stats_table[cpu]; | 169 | struct cpufreq_stats *stat = cpufreq_stats_table[cpu]; |
171 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); | 170 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); |
@@ -305,8 +304,9 @@ cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val, | |||
305 | return 0; | 304 | return 0; |
306 | } | 305 | } |
307 | 306 | ||
308 | static int cpufreq_stat_cpu_callback(struct notifier_block *nfb, | 307 | static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, |
309 | unsigned long action, void *hcpu) | 308 | unsigned long action, |
309 | void *hcpu) | ||
310 | { | 310 | { |
311 | unsigned int cpu = (unsigned long)hcpu; | 311 | unsigned int cpu = (unsigned long)hcpu; |
312 | 312 | ||
@@ -323,7 +323,7 @@ static int cpufreq_stat_cpu_callback(struct notifier_block *nfb, | |||
323 | return NOTIFY_OK; | 323 | return NOTIFY_OK; |
324 | } | 324 | } |
325 | 325 | ||
326 | static struct notifier_block cpufreq_stat_cpu_notifier = | 326 | static struct notifier_block cpufreq_stat_cpu_notifier __cpuinitdata = |
327 | { | 327 | { |
328 | .notifier_call = cpufreq_stat_cpu_callback, | 328 | .notifier_call = cpufreq_stat_cpu_callback, |
329 | }; | 329 | }; |
@@ -356,8 +356,7 @@ __init cpufreq_stats_init(void) | |||
356 | 356 | ||
357 | register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); | 357 | register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); |
358 | for_each_online_cpu(cpu) { | 358 | for_each_online_cpu(cpu) { |
359 | cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, | 359 | cpufreq_update_policy(cpu); |
360 | CPU_ONLINE, (void *)(long)cpu); | ||
361 | } | 360 | } |
362 | return 0; | 361 | return 0; |
363 | } | 362 | } |
@@ -372,13 +371,12 @@ __exit cpufreq_stats_exit(void) | |||
372 | CPUFREQ_TRANSITION_NOTIFIER); | 371 | CPUFREQ_TRANSITION_NOTIFIER); |
373 | unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); | 372 | unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); |
374 | for_each_online_cpu(cpu) { | 373 | for_each_online_cpu(cpu) { |
375 | cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, | 374 | cpufreq_stats_free_table(cpu); |
376 | CPU_DEAD, (void *)(long)cpu); | ||
377 | } | 375 | } |
378 | } | 376 | } |
379 | 377 | ||
380 | MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>"); | 378 | MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>"); |
381 | MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats" | 379 | MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats " |
382 | "through sysfs filesystem"); | 380 | "through sysfs filesystem"); |
383 | MODULE_LICENSE ("GPL"); | 381 | MODULE_LICENSE ("GPL"); |
384 | 382 | ||
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 4a0576bd06fc..3706b2bc0987 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -743,7 +743,7 @@ static struct kobj_type ktype_mc_set_attribs = { | |||
743 | * /sys/devices/system/edac/mc | 743 | * /sys/devices/system/edac/mc |
744 | */ | 744 | */ |
745 | static struct kset mc_kset = { | 745 | static struct kset mc_kset = { |
746 | .kobj = {.name = "mc", .ktype = &ktype_mc_set_attribs }, | 746 | .kobj = {.ktype = &ktype_mc_set_attribs }, |
747 | .ktype = &ktype_mci, | 747 | .ktype = &ktype_mci, |
748 | }; | 748 | }; |
749 | 749 | ||
@@ -1010,6 +1010,7 @@ int edac_sysfs_setup_mc_kset(void) | |||
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | /* Init the MC's kobject */ | 1012 | /* Init the MC's kobject */ |
1013 | kobject_set_name(&mc_kset.kobj, "mc"); | ||
1013 | mc_kset.kobj.parent = &edac_class->kset.kobj; | 1014 | mc_kset.kobj.parent = &edac_class->kset.kobj; |
1014 | 1015 | ||
1015 | /* register the mc_kset */ | 1016 | /* register the mc_kset */ |
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c index d944647c82c2..4d4a47393909 100644 --- a/drivers/eisa/eisa-bus.c +++ b/drivers/eisa/eisa-bus.c | |||
@@ -128,16 +128,11 @@ static int eisa_bus_match (struct device *dev, struct device_driver *drv) | |||
128 | return 0; | 128 | return 0; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int eisa_bus_uevent(struct device *dev, char **envp, int num_envp, | 131 | static int eisa_bus_uevent(struct device *dev, struct kobj_uevent_env *env) |
132 | char *buffer, int buffer_size) | ||
133 | { | 132 | { |
134 | struct eisa_device *edev = to_eisa_device(dev); | 133 | struct eisa_device *edev = to_eisa_device(dev); |
135 | int i = 0; | ||
136 | int length = 0; | ||
137 | 134 | ||
138 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | 135 | add_uevent_var(env, "MODALIAS=" EISA_DEVICE_MODALIAS_FMT, edev->id.sig); |
139 | "MODALIAS=" EISA_DEVICE_MODALIAS_FMT, edev->id.sig); | ||
140 | envp[i] = NULL; | ||
141 | return 0; | 136 | return 0; |
142 | } | 137 | } |
143 | 138 | ||
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index 2b6586341635..56681b3b297b 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
@@ -130,23 +130,16 @@ static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) | |||
130 | } | 130 | } |
131 | 131 | ||
132 | static int | 132 | static int |
133 | fw_unit_uevent(struct device *dev, char **envp, int num_envp, | 133 | fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env) |
134 | char *buffer, int buffer_size) | ||
135 | { | 134 | { |
136 | struct fw_unit *unit = fw_unit(dev); | 135 | struct fw_unit *unit = fw_unit(dev); |
137 | char modalias[64]; | 136 | char modalias[64]; |
138 | int length = 0; | ||
139 | int i = 0; | ||
140 | 137 | ||
141 | get_modalias(unit, modalias, sizeof(modalias)); | 138 | get_modalias(unit, modalias, sizeof(modalias)); |
142 | 139 | ||
143 | if (add_uevent_var(envp, num_envp, &i, | 140 | if (add_uevent_var(env, "MODALIAS=%s", modalias)) |
144 | buffer, buffer_size, &length, | ||
145 | "MODALIAS=%s", modalias)) | ||
146 | return -ENOMEM; | 141 | return -ENOMEM; |
147 | 142 | ||
148 | envp[i] = NULL; | ||
149 | |||
150 | return 0; | 143 | return 0; |
151 | } | 144 | } |
152 | 145 | ||
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index 59c3b5aa89f4..b6e1eb77d148 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c | |||
@@ -13,21 +13,31 @@ | |||
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/autoconf.h> | 14 | #include <linux/autoconf.h> |
15 | 15 | ||
16 | #define DEFINE_DMI_ATTR(_name, _mode, _show) \ | 16 | struct dmi_device_attribute{ |
17 | static struct device_attribute sys_dmi_##_name##_attr = \ | 17 | struct device_attribute dev_attr; |
18 | __ATTR(_name, _mode, _show, NULL); | 18 | int field; |
19 | 19 | }; | |
20 | #define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field) \ | 20 | #define to_dmi_dev_attr(_dev_attr) \ |
21 | static ssize_t sys_dmi_##_name##_show(struct device *dev, \ | 21 | container_of(_dev_attr, struct dmi_device_attribute, dev_attr) |
22 | struct device_attribute *attr, \ | 22 | |
23 | char *page) \ | 23 | static ssize_t sys_dmi_field_show(struct device *dev, |
24 | { \ | 24 | struct device_attribute *attr, |
25 | ssize_t len; \ | 25 | char *page) |
26 | len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(_field)); \ | 26 | { |
27 | page[len-1] = '\n'; \ | 27 | int field = to_dmi_dev_attr(attr)->field; |
28 | return len; \ | 28 | ssize_t len; |
29 | } \ | 29 | len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(field)); |
30 | DEFINE_DMI_ATTR(_name, _mode, sys_dmi_##_name##_show); | 30 | page[len-1] = '\n'; |
31 | return len; | ||
32 | } | ||
33 | |||
34 | #define DMI_ATTR(_name, _mode, _show, _field) \ | ||
35 | { .dev_attr = __ATTR(_name, _mode, _show, NULL), \ | ||
36 | .field = _field } | ||
37 | |||
38 | #define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field) \ | ||
39 | static struct dmi_device_attribute sys_dmi_##_name##_attr = \ | ||
40 | DMI_ATTR(_name, _mode, sys_dmi_field_show, _field); | ||
31 | 41 | ||
32 | DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor, 0444, DMI_BIOS_VENDOR); | 42 | DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor, 0444, DMI_BIOS_VENDOR); |
33 | DEFINE_DMI_ATTR_WITH_SHOW(bios_version, 0444, DMI_BIOS_VERSION); | 43 | DEFINE_DMI_ATTR_WITH_SHOW(bios_version, 0444, DMI_BIOS_VERSION); |
@@ -121,7 +131,8 @@ static ssize_t sys_dmi_modalias_show(struct device *dev, | |||
121 | return r+1; | 131 | return r+1; |
122 | } | 132 | } |
123 | 133 | ||
124 | DEFINE_DMI_ATTR(modalias, 0444, sys_dmi_modalias_show); | 134 | static struct device_attribute sys_dmi_modalias_attr = |
135 | __ATTR(modalias, 0444, sys_dmi_modalias_show, NULL); | ||
125 | 136 | ||
126 | static struct attribute *sys_dmi_attributes[DMI_STRING_MAX+2]; | 137 | static struct attribute *sys_dmi_attributes[DMI_STRING_MAX+2]; |
127 | 138 | ||
@@ -134,14 +145,17 @@ static struct attribute_group* sys_dmi_attribute_groups[] = { | |||
134 | NULL | 145 | NULL |
135 | }; | 146 | }; |
136 | 147 | ||
137 | static int dmi_dev_uevent(struct device *dev, char **envp, | 148 | static int dmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) |
138 | int num_envp, char *buffer, int buffer_size) | ||
139 | { | 149 | { |
140 | strcpy(buffer, "MODALIAS="); | 150 | ssize_t len; |
141 | get_modalias(buffer+9, buffer_size-9); | 151 | |
142 | envp[0] = buffer; | 152 | if (add_uevent_var(env, "MODALIAS=")) |
143 | envp[1] = NULL; | 153 | return -ENOMEM; |
144 | 154 | len = get_modalias(&env->buf[env->buflen - 1], | |
155 | sizeof(env->buf) - env->buflen); | ||
156 | if (len >= (sizeof(env->buf) - env->buflen)) | ||
157 | return -ENOMEM; | ||
158 | env->buflen += len; | ||
145 | return 0; | 159 | return 0; |
146 | } | 160 | } |
147 | 161 | ||
@@ -157,7 +171,7 @@ static struct device *dmi_dev; | |||
157 | 171 | ||
158 | #define ADD_DMI_ATTR(_name, _field) \ | 172 | #define ADD_DMI_ATTR(_name, _field) \ |
159 | if (dmi_get_system_info(_field)) \ | 173 | if (dmi_get_system_info(_field)) \ |
160 | sys_dmi_attributes[i++] = & sys_dmi_##_name##_attr.attr; | 174 | sys_dmi_attributes[i++] = &sys_dmi_##_name##_attr.dev_attr.attr; |
161 | 175 | ||
162 | extern int dmi_available; | 176 | extern int dmi_available; |
163 | 177 | ||
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 0fb730ee1da8..6942e065e609 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c | |||
@@ -625,13 +625,13 @@ static void edd_release(struct kobject * kobj) | |||
625 | kfree(dev); | 625 | kfree(dev); |
626 | } | 626 | } |
627 | 627 | ||
628 | static struct kobj_type ktype_edd = { | 628 | static struct kobj_type edd_ktype = { |
629 | .release = edd_release, | 629 | .release = edd_release, |
630 | .sysfs_ops = &edd_attr_ops, | 630 | .sysfs_ops = &edd_attr_ops, |
631 | .default_attrs = def_attrs, | 631 | .default_attrs = def_attrs, |
632 | }; | 632 | }; |
633 | 633 | ||
634 | static decl_subsys(edd,&ktype_edd,NULL); | 634 | static decl_subsys(edd, &edd_ktype, NULL); |
635 | 635 | ||
636 | 636 | ||
637 | /** | 637 | /** |
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index bfd2d67df689..858a7b95933b 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -402,7 +402,7 @@ static struct attribute *def_attrs[] = { | |||
402 | NULL, | 402 | NULL, |
403 | }; | 403 | }; |
404 | 404 | ||
405 | static struct kobj_type ktype_efivar = { | 405 | static struct kobj_type efivar_ktype = { |
406 | .release = efivar_release, | 406 | .release = efivar_release, |
407 | .sysfs_ops = &efivar_attr_ops, | 407 | .sysfs_ops = &efivar_attr_ops, |
408 | .default_attrs = def_attrs, | 408 | .default_attrs = def_attrs, |
@@ -583,7 +583,7 @@ static struct subsys_attribute *efi_subsys_attrs[] = { | |||
583 | NULL, /* maybe more in the future? */ | 583 | NULL, /* maybe more in the future? */ |
584 | }; | 584 | }; |
585 | 585 | ||
586 | static decl_subsys(vars, &ktype_efivar, NULL); | 586 | static decl_subsys(vars, &efivar_ktype, NULL); |
587 | static decl_subsys(efi, NULL, NULL); | 587 | static decl_subsys(efi, NULL, NULL); |
588 | 588 | ||
589 | /* | 589 | /* |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d663e6960d93..910a62de190d 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -67,20 +67,16 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv) | |||
67 | #ifdef CONFIG_HOTPLUG | 67 | #ifdef CONFIG_HOTPLUG |
68 | 68 | ||
69 | /* uevent helps with hotplug: modprobe -q $(MODALIAS) */ | 69 | /* uevent helps with hotplug: modprobe -q $(MODALIAS) */ |
70 | static int i2c_device_uevent(struct device *dev, char **envp, int num_envp, | 70 | static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
71 | char *buffer, int buffer_size) | ||
72 | { | 71 | { |
73 | struct i2c_client *client = to_i2c_client(dev); | 72 | struct i2c_client *client = to_i2c_client(dev); |
74 | int i = 0, length = 0; | ||
75 | 73 | ||
76 | /* by definition, legacy drivers can't hotplug */ | 74 | /* by definition, legacy drivers can't hotplug */ |
77 | if (dev->driver || !client->driver_name) | 75 | if (dev->driver || !client->driver_name) |
78 | return 0; | 76 | return 0; |
79 | 77 | ||
80 | if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | 78 | if (add_uevent_var(env, "MODALIAS=%s", client->driver_name)) |
81 | "MODALIAS=%s", client->driver_name)) | ||
82 | return -ENOMEM; | 79 | return -ENOMEM; |
83 | envp[i] = NULL; | ||
84 | dev_dbg(dev, "uevent\n"); | 80 | dev_dbg(dev, "uevent\n"); |
85 | return 0; | 81 | return 0; |
86 | } | 82 | } |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index e96212ce5729..a96a8b1b3539 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -1663,20 +1663,13 @@ static struct device_attribute ide_dev_attrs[] = { | |||
1663 | __ATTR_NULL | 1663 | __ATTR_NULL |
1664 | }; | 1664 | }; |
1665 | 1665 | ||
1666 | static int ide_uevent(struct device *dev, char **envp, int num_envp, | 1666 | static int ide_uevent(struct device *dev, struct kobj_uevent_env *env) |
1667 | char *buffer, int buffer_size) | ||
1668 | { | 1667 | { |
1669 | ide_drive_t *drive = to_ide_device(dev); | 1668 | ide_drive_t *drive = to_ide_device(dev); |
1670 | int i = 0; | 1669 | |
1671 | int length = 0; | 1670 | add_uevent_var(env, "MEDIA=%s", media_string(drive)); |
1672 | 1671 | add_uevent_var(env, "DRIVENAME=%s", drive->name); | |
1673 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | 1672 | add_uevent_var(env, "MODALIAS=ide:m-%s", media_string(drive)); |
1674 | "MEDIA=%s", media_string(drive)); | ||
1675 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | ||
1676 | "DRIVENAME=%s", drive->name); | ||
1677 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | ||
1678 | "MODALIAS=ide:m-%s", media_string(drive)); | ||
1679 | envp[i] = NULL; | ||
1680 | return 0; | 1673 | return 0; |
1681 | } | 1674 | } |
1682 | 1675 | ||
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 2ffd53461db6..1939fee616ec 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -153,8 +153,7 @@ struct host_info { | |||
153 | }; | 153 | }; |
154 | 154 | ||
155 | static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); | 155 | static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); |
156 | static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, | 156 | static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env); |
157 | char *buffer, int buffer_size); | ||
158 | static void nodemgr_resume_ne(struct node_entry *ne); | 157 | static void nodemgr_resume_ne(struct node_entry *ne); |
159 | static void nodemgr_remove_ne(struct node_entry *ne); | 158 | static void nodemgr_remove_ne(struct node_entry *ne); |
160 | static struct node_entry *find_entry_by_guid(u64 guid); | 159 | static struct node_entry *find_entry_by_guid(u64 guid); |
@@ -1160,12 +1159,9 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent | |||
1160 | 1159 | ||
1161 | #ifdef CONFIG_HOTPLUG | 1160 | #ifdef CONFIG_HOTPLUG |
1162 | 1161 | ||
1163 | static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, | 1162 | static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env) |
1164 | char *buffer, int buffer_size) | ||
1165 | { | 1163 | { |
1166 | struct unit_directory *ud; | 1164 | struct unit_directory *ud; |
1167 | int i = 0; | ||
1168 | int length = 0; | ||
1169 | int retval = 0; | 1165 | int retval = 0; |
1170 | /* ieee1394:venNmoNspNverN */ | 1166 | /* ieee1394:venNmoNspNverN */ |
1171 | char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; | 1167 | char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; |
@@ -1180,9 +1176,7 @@ static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, | |||
1180 | 1176 | ||
1181 | #define PUT_ENVP(fmt,val) \ | 1177 | #define PUT_ENVP(fmt,val) \ |
1182 | do { \ | 1178 | do { \ |
1183 | retval = add_uevent_var(envp, num_envp, &i, \ | 1179 | retval = add_uevent_var(env, fmt, val); \ |
1184 | buffer, buffer_size, &length, \ | ||
1185 | fmt, val); \ | ||
1186 | if (retval) \ | 1180 | if (retval) \ |
1187 | return retval; \ | 1181 | return retval; \ |
1188 | } while (0) | 1182 | } while (0) |
@@ -1201,15 +1195,12 @@ do { \ | |||
1201 | 1195 | ||
1202 | #undef PUT_ENVP | 1196 | #undef PUT_ENVP |
1203 | 1197 | ||
1204 | envp[i] = NULL; | ||
1205 | |||
1206 | return 0; | 1198 | return 0; |
1207 | } | 1199 | } |
1208 | 1200 | ||
1209 | #else | 1201 | #else |
1210 | 1202 | ||
1211 | static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, | 1203 | static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env) |
1212 | char *buffer, int buffer_size) | ||
1213 | { | 1204 | { |
1214 | return -ENODEV; | 1205 | return -ENODEV; |
1215 | } | 1206 | } |
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 70b77ae67422..3d4050681325 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -434,21 +434,18 @@ static void ib_device_release(struct class_device *cdev) | |||
434 | kfree(dev); | 434 | kfree(dev); |
435 | } | 435 | } |
436 | 436 | ||
437 | static int ib_device_uevent(struct class_device *cdev, char **envp, | 437 | static int ib_device_uevent(struct class_device *cdev, |
438 | int num_envp, char *buf, int size) | 438 | struct kobj_uevent_env *env) |
439 | { | 439 | { |
440 | struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); | 440 | struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); |
441 | int i = 0, len = 0; | ||
442 | 441 | ||
443 | if (add_uevent_var(envp, num_envp, &i, buf, size, &len, | 442 | if (add_uevent_var(env, "NAME=%s", dev->name)) |
444 | "NAME=%s", dev->name)) | ||
445 | return -ENOMEM; | 443 | return -ENOMEM; |
446 | 444 | ||
447 | /* | 445 | /* |
448 | * It would be nice to pass the node GUID with the event... | 446 | * It would be nice to pass the node GUID with the event... |
449 | */ | 447 | */ |
450 | 448 | ||
451 | envp[i] = NULL; | ||
452 | return 0; | 449 | return 0; |
453 | } | 450 | } |
454 | 451 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index 5fe755586623..5dc361c954e2 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -859,87 +859,66 @@ static void input_dev_release(struct device *device) | |||
859 | * Input uevent interface - loading event handlers based on | 859 | * Input uevent interface - loading event handlers based on |
860 | * device bitfields. | 860 | * device bitfields. |
861 | */ | 861 | */ |
862 | static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, | 862 | static int input_add_uevent_bm_var(struct kobj_uevent_env *env, |
863 | char *buffer, int buffer_size, int *cur_len, | ||
864 | const char *name, unsigned long *bitmap, int max) | 863 | const char *name, unsigned long *bitmap, int max) |
865 | { | 864 | { |
866 | if (*cur_index >= num_envp - 1) | 865 | int len; |
867 | return -ENOMEM; | ||
868 | |||
869 | envp[*cur_index] = buffer + *cur_len; | ||
870 | 866 | ||
871 | *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name); | 867 | if (add_uevent_var(env, "%s=", name)) |
872 | if (*cur_len >= buffer_size) | ||
873 | return -ENOMEM; | 868 | return -ENOMEM; |
874 | 869 | ||
875 | *cur_len += input_print_bitmap(buffer + *cur_len, | 870 | len = input_print_bitmap(&env->buf[env->buflen - 1], |
876 | max(buffer_size - *cur_len, 0), | 871 | sizeof(env->buf) - env->buflen, |
877 | bitmap, max, 0) + 1; | 872 | bitmap, max, 0); |
878 | if (*cur_len > buffer_size) | 873 | if (len >= (sizeof(env->buf) - env->buflen)) |
879 | return -ENOMEM; | 874 | return -ENOMEM; |
880 | 875 | ||
881 | (*cur_index)++; | 876 | env->buflen += len; |
882 | return 0; | 877 | return 0; |
883 | } | 878 | } |
884 | 879 | ||
885 | static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_index, | 880 | static int input_add_uevent_modalias_var(struct kobj_uevent_env *env, |
886 | char *buffer, int buffer_size, int *cur_len, | ||
887 | struct input_dev *dev) | 881 | struct input_dev *dev) |
888 | { | 882 | { |
889 | if (*cur_index >= num_envp - 1) | 883 | int len; |
890 | return -ENOMEM; | ||
891 | |||
892 | envp[*cur_index] = buffer + *cur_len; | ||
893 | 884 | ||
894 | *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), | 885 | if (add_uevent_var(env, "MODALIAS=")) |
895 | "MODALIAS="); | ||
896 | if (*cur_len >= buffer_size) | ||
897 | return -ENOMEM; | 886 | return -ENOMEM; |
898 | 887 | ||
899 | *cur_len += input_print_modalias(buffer + *cur_len, | 888 | len = input_print_modalias(&env->buf[env->buflen - 1], |
900 | max(buffer_size - *cur_len, 0), | 889 | sizeof(env->buf) - env->buflen, |
901 | dev, 0) + 1; | 890 | dev, 0); |
902 | if (*cur_len > buffer_size) | 891 | if (len >= (sizeof(env->buf) - env->buflen)) |
903 | return -ENOMEM; | 892 | return -ENOMEM; |
904 | 893 | ||
905 | (*cur_index)++; | 894 | env->buflen += len; |
906 | return 0; | 895 | return 0; |
907 | } | 896 | } |
908 | 897 | ||
909 | #define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ | 898 | #define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ |
910 | do { \ | 899 | do { \ |
911 | int err = add_uevent_var(envp, num_envp, &i, \ | 900 | int err = add_uevent_var(env, fmt, val); \ |
912 | buffer, buffer_size, &len, \ | ||
913 | fmt, val); \ | ||
914 | if (err) \ | 901 | if (err) \ |
915 | return err; \ | 902 | return err; \ |
916 | } while (0) | 903 | } while (0) |
917 | 904 | ||
918 | #define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \ | 905 | #define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \ |
919 | do { \ | 906 | do { \ |
920 | int err = input_add_uevent_bm_var(envp, num_envp, &i, \ | 907 | int err = input_add_uevent_bm_var(env, name, bm, max); \ |
921 | buffer, buffer_size, &len, \ | ||
922 | name, bm, max); \ | ||
923 | if (err) \ | 908 | if (err) \ |
924 | return err; \ | 909 | return err; \ |
925 | } while (0) | 910 | } while (0) |
926 | 911 | ||
927 | #define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \ | 912 | #define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \ |
928 | do { \ | 913 | do { \ |
929 | int err = input_add_uevent_modalias_var(envp, \ | 914 | int err = input_add_uevent_modalias_var(env, dev); \ |
930 | num_envp, &i, \ | ||
931 | buffer, buffer_size, &len, \ | ||
932 | dev); \ | ||
933 | if (err) \ | 915 | if (err) \ |
934 | return err; \ | 916 | return err; \ |
935 | } while (0) | 917 | } while (0) |
936 | 918 | ||
937 | static int input_dev_uevent(struct device *device, char **envp, | 919 | static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) |
938 | int num_envp, char *buffer, int buffer_size) | ||
939 | { | 920 | { |
940 | struct input_dev *dev = to_input_dev(device); | 921 | struct input_dev *dev = to_input_dev(device); |
941 | int i = 0; | ||
942 | int len = 0; | ||
943 | 922 | ||
944 | INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x", | 923 | INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x", |
945 | dev->id.bustype, dev->id.vendor, | 924 | dev->id.bustype, dev->id.vendor, |
@@ -971,7 +950,6 @@ static int input_dev_uevent(struct device *device, char **envp, | |||
971 | 950 | ||
972 | INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev); | 951 | INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev); |
973 | 952 | ||
974 | envp[i] = NULL; | ||
975 | return 0; | 953 | return 0; |
976 | } | 954 | } |
977 | 955 | ||
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 906bf5e8de89..c19f77fbaf2a 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c | |||
@@ -17,17 +17,18 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <asm/8253pit.h> | ||
21 | #include <asm/io.h> | 20 | #include <asm/io.h> |
22 | 21 | ||
23 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 22 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
24 | MODULE_DESCRIPTION("PC Speaker beeper driver"); | 23 | MODULE_DESCRIPTION("PC Speaker beeper driver"); |
25 | MODULE_LICENSE("GPL"); | 24 | MODULE_LICENSE("GPL"); |
25 | MODULE_ALIAS("platform:pcspkr"); | ||
26 | 26 | ||
27 | #ifdef CONFIG_X86 | 27 | #ifdef CONFIG_X86 |
28 | /* Use the global PIT lock ! */ | 28 | /* Use the global PIT lock ! */ |
29 | #include <asm/i8253.h> | 29 | #include <asm/i8253.h> |
30 | #else | 30 | #else |
31 | #include <asm/8253pit.h> | ||
31 | static DEFINE_SPINLOCK(i8253_lock); | 32 | static DEFINE_SPINLOCK(i8253_lock); |
32 | #endif | 33 | #endif |
33 | 34 | ||
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 372ca4931194..b3bc15acd3f5 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -876,18 +876,14 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv) | |||
876 | 876 | ||
877 | #define SERIO_ADD_UEVENT_VAR(fmt, val...) \ | 877 | #define SERIO_ADD_UEVENT_VAR(fmt, val...) \ |
878 | do { \ | 878 | do { \ |
879 | int err = add_uevent_var(envp, num_envp, &i, \ | 879 | int err = add_uevent_var(env, fmt, val); \ |
880 | buffer, buffer_size, &len, \ | ||
881 | fmt, val); \ | ||
882 | if (err) \ | 880 | if (err) \ |
883 | return err; \ | 881 | return err; \ |
884 | } while (0) | 882 | } while (0) |
885 | 883 | ||
886 | static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) | 884 | static int serio_uevent(struct device *dev, struct kobj_uevent_env *env) |
887 | { | 885 | { |
888 | struct serio *serio; | 886 | struct serio *serio; |
889 | int i = 0; | ||
890 | int len = 0; | ||
891 | 887 | ||
892 | if (!dev) | 888 | if (!dev) |
893 | return -ENODEV; | 889 | return -ENODEV; |
@@ -900,7 +896,6 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf | |||
900 | SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); | 896 | SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); |
901 | SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", | 897 | SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", |
902 | serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); | 898 | serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); |
903 | envp[i] = NULL; | ||
904 | 899 | ||
905 | return 0; | 900 | return 0; |
906 | } | 901 | } |
@@ -908,7 +903,7 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf | |||
908 | 903 | ||
909 | #else | 904 | #else |
910 | 905 | ||
911 | static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) | 906 | static int serio_uevent(struct device *dev, struct kobj_uevent_env *env) |
912 | { | 907 | { |
913 | return -ENODEV; | 908 | return -ENODEV; |
914 | } | 909 | } |
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index b04a178e5021..f8b79783c8b3 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/isapnp.h> | 20 | #include <linux/isapnp.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | 22 | ||
23 | extern const char *CardType[]; | ||
24 | static const char *avm_pci_rev = "$Revision: 1.29.2.4 $"; | 23 | static const char *avm_pci_rev = "$Revision: 1.29.2.4 $"; |
25 | 24 | ||
26 | #define AVM_FRITZ_PCI 1 | 25 | #define AVM_FRITZ_PCI 1 |
@@ -726,100 +725,15 @@ AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) | |||
726 | return(0); | 725 | return(0); |
727 | } | 726 | } |
728 | 727 | ||
729 | #ifdef CONFIG_PCI | 728 | static int __devinit avm_setup_rest(struct IsdnCardState *cs) |
730 | static struct pci_dev *dev_avm __devinitdata = NULL; | ||
731 | #endif | ||
732 | #ifdef __ISAPNP__ | ||
733 | static struct pnp_card *pnp_avm_c __devinitdata = NULL; | ||
734 | #endif | ||
735 | |||
736 | int __devinit | ||
737 | setup_avm_pcipnp(struct IsdnCard *card) | ||
738 | { | 729 | { |
739 | u_int val, ver; | 730 | u_int val, ver; |
740 | struct IsdnCardState *cs = card->cs; | ||
741 | char tmp[64]; | ||
742 | 731 | ||
743 | strcpy(tmp, avm_pci_rev); | ||
744 | printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); | ||
745 | if (cs->typ != ISDN_CTYPE_FRITZPCI) | ||
746 | return (0); | ||
747 | if (card->para[1]) { | ||
748 | /* old manual method */ | ||
749 | cs->hw.avm.cfg_reg = card->para[1]; | ||
750 | cs->irq = card->para[0]; | ||
751 | cs->subtyp = AVM_FRITZ_PNP; | ||
752 | goto ready; | ||
753 | } | ||
754 | #ifdef __ISAPNP__ | ||
755 | if (isapnp_present()) { | ||
756 | struct pnp_dev *pnp_avm_d = NULL; | ||
757 | if ((pnp_avm_c = pnp_find_card( | ||
758 | ISAPNP_VENDOR('A', 'V', 'M'), | ||
759 | ISAPNP_FUNCTION(0x0900), pnp_avm_c))) { | ||
760 | if ((pnp_avm_d = pnp_find_dev(pnp_avm_c, | ||
761 | ISAPNP_VENDOR('A', 'V', 'M'), | ||
762 | ISAPNP_FUNCTION(0x0900), pnp_avm_d))) { | ||
763 | int err; | ||
764 | |||
765 | pnp_disable_dev(pnp_avm_d); | ||
766 | err = pnp_activate_dev(pnp_avm_d); | ||
767 | if (err<0) { | ||
768 | printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", | ||
769 | __FUNCTION__, err); | ||
770 | return(0); | ||
771 | } | ||
772 | cs->hw.avm.cfg_reg = | ||
773 | pnp_port_start(pnp_avm_d, 0); | ||
774 | cs->irq = pnp_irq(pnp_avm_d, 0); | ||
775 | if (!cs->irq) { | ||
776 | printk(KERN_ERR "FritzPnP:No IRQ\n"); | ||
777 | return(0); | ||
778 | } | ||
779 | if (!cs->hw.avm.cfg_reg) { | ||
780 | printk(KERN_ERR "FritzPnP:No IO address\n"); | ||
781 | return(0); | ||
782 | } | ||
783 | cs->subtyp = AVM_FRITZ_PNP; | ||
784 | goto ready; | ||
785 | } | ||
786 | } | ||
787 | } else { | ||
788 | printk(KERN_INFO "FritzPnP: no ISA PnP present\n"); | ||
789 | } | ||
790 | #endif | ||
791 | #ifdef CONFIG_PCI | ||
792 | if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, | ||
793 | PCI_DEVICE_ID_AVM_A1, dev_avm))) { | ||
794 | if (pci_enable_device(dev_avm)) | ||
795 | return(0); | ||
796 | cs->irq = dev_avm->irq; | ||
797 | if (!cs->irq) { | ||
798 | printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); | ||
799 | return(0); | ||
800 | } | ||
801 | cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); | ||
802 | if (!cs->hw.avm.cfg_reg) { | ||
803 | printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); | ||
804 | return(0); | ||
805 | } | ||
806 | cs->subtyp = AVM_FRITZ_PCI; | ||
807 | } else { | ||
808 | printk(KERN_WARNING "FritzPCI: No PCI card found\n"); | ||
809 | return(0); | ||
810 | } | ||
811 | cs->irq_flags |= IRQF_SHARED; | ||
812 | #else | ||
813 | printk(KERN_WARNING "FritzPCI: NO_PCI_BIOS\n"); | ||
814 | return (0); | ||
815 | #endif /* CONFIG_PCI */ | ||
816 | ready: | ||
817 | cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; | 732 | cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; |
818 | if (!request_region(cs->hw.avm.cfg_reg, 32, | 733 | if (!request_region(cs->hw.avm.cfg_reg, 32, |
819 | (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) { | 734 | (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) { |
820 | printk(KERN_WARNING | 735 | printk(KERN_WARNING |
821 | "HiSax: %s config port %x-%x already in use\n", | 736 | "HiSax: Fritz!PCI/PNP config port %x-%x already in use\n", |
822 | CardType[card->typ], | ||
823 | cs->hw.avm.cfg_reg, | 737 | cs->hw.avm.cfg_reg, |
824 | cs->hw.avm.cfg_reg + 31); | 738 | cs->hw.avm.cfg_reg + 31); |
825 | return (0); | 739 | return (0); |
@@ -860,3 +774,137 @@ ready: | |||
860 | ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); | 774 | ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); |
861 | return (1); | 775 | return (1); |
862 | } | 776 | } |
777 | |||
778 | #ifndef __ISAPNP__ | ||
779 | |||
780 | static int __devinit avm_pnp_setup(struct IsdnCardState *cs) | ||
781 | { | ||
782 | return(1); /* no-op: success */ | ||
783 | } | ||
784 | |||
785 | #else | ||
786 | |||
787 | static struct pnp_card *pnp_avm_c __devinitdata = NULL; | ||
788 | |||
789 | static int __devinit avm_pnp_setup(struct IsdnCardState *cs) | ||
790 | { | ||
791 | struct pnp_dev *pnp_avm_d = NULL; | ||
792 | |||
793 | if (!isapnp_present()) | ||
794 | return(1); /* no-op: success */ | ||
795 | |||
796 | if ((pnp_avm_c = pnp_find_card( | ||
797 | ISAPNP_VENDOR('A', 'V', 'M'), | ||
798 | ISAPNP_FUNCTION(0x0900), pnp_avm_c))) { | ||
799 | if ((pnp_avm_d = pnp_find_dev(pnp_avm_c, | ||
800 | ISAPNP_VENDOR('A', 'V', 'M'), | ||
801 | ISAPNP_FUNCTION(0x0900), pnp_avm_d))) { | ||
802 | int err; | ||
803 | |||
804 | pnp_disable_dev(pnp_avm_d); | ||
805 | err = pnp_activate_dev(pnp_avm_d); | ||
806 | if (err<0) { | ||
807 | printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", | ||
808 | __FUNCTION__, err); | ||
809 | return(0); | ||
810 | } | ||
811 | cs->hw.avm.cfg_reg = | ||
812 | pnp_port_start(pnp_avm_d, 0); | ||
813 | cs->irq = pnp_irq(pnp_avm_d, 0); | ||
814 | if (!cs->irq) { | ||
815 | printk(KERN_ERR "FritzPnP:No IRQ\n"); | ||
816 | return(0); | ||
817 | } | ||
818 | if (!cs->hw.avm.cfg_reg) { | ||
819 | printk(KERN_ERR "FritzPnP:No IO address\n"); | ||
820 | return(0); | ||
821 | } | ||
822 | cs->subtyp = AVM_FRITZ_PNP; | ||
823 | |||
824 | return (2); /* goto 'ready' label */ | ||
825 | } | ||
826 | } | ||
827 | |||
828 | return (1); | ||
829 | } | ||
830 | |||
831 | #endif /* __ISAPNP__ */ | ||
832 | |||
833 | #ifndef CONFIG_PCI | ||
834 | |||
835 | static int __devinit avm_pci_setup(struct IsdnCardState *cs) | ||
836 | { | ||
837 | return(1); /* no-op: success */ | ||
838 | } | ||
839 | |||
840 | #else | ||
841 | |||
842 | static struct pci_dev *dev_avm __devinitdata = NULL; | ||
843 | |||
844 | static int __devinit avm_pci_setup(struct IsdnCardState *cs) | ||
845 | { | ||
846 | if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, | ||
847 | PCI_DEVICE_ID_AVM_A1, dev_avm))) { | ||
848 | |||
849 | if (pci_enable_device(dev_avm)) | ||
850 | return(0); | ||
851 | |||
852 | cs->irq = dev_avm->irq; | ||
853 | if (!cs->irq) { | ||
854 | printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); | ||
855 | return(0); | ||
856 | } | ||
857 | |||
858 | cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); | ||
859 | if (!cs->hw.avm.cfg_reg) { | ||
860 | printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); | ||
861 | return(0); | ||
862 | } | ||
863 | |||
864 | cs->subtyp = AVM_FRITZ_PCI; | ||
865 | } else { | ||
866 | printk(KERN_WARNING "FritzPCI: No PCI card found\n"); | ||
867 | return(0); | ||
868 | } | ||
869 | |||
870 | cs->irq_flags |= IRQF_SHARED; | ||
871 | |||
872 | return (1); | ||
873 | } | ||
874 | |||
875 | #endif /* CONFIG_PCI */ | ||
876 | |||
877 | int __devinit | ||
878 | setup_avm_pcipnp(struct IsdnCard *card) | ||
879 | { | ||
880 | struct IsdnCardState *cs = card->cs; | ||
881 | char tmp[64]; | ||
882 | int rc; | ||
883 | |||
884 | strcpy(tmp, avm_pci_rev); | ||
885 | printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); | ||
886 | |||
887 | if (cs->typ != ISDN_CTYPE_FRITZPCI) | ||
888 | return (0); | ||
889 | |||
890 | if (card->para[1]) { | ||
891 | /* old manual method */ | ||
892 | cs->hw.avm.cfg_reg = card->para[1]; | ||
893 | cs->irq = card->para[0]; | ||
894 | cs->subtyp = AVM_FRITZ_PNP; | ||
895 | goto ready; | ||
896 | } | ||
897 | |||
898 | rc = avm_pnp_setup(cs); | ||
899 | if (rc < 1) | ||
900 | return (0); | ||
901 | if (rc == 2) | ||
902 | goto ready; | ||
903 | |||
904 | rc = avm_pci_setup(cs); | ||
905 | if (rc < 1) | ||
906 | return (0); | ||
907 | |||
908 | ready: | ||
909 | return avm_setup_rest(cs); | ||
910 | } | ||
diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c index 6339bb443f62..99ef3b43fcd7 100644 --- a/drivers/isdn/hisax/bkm_a8.c +++ b/drivers/isdn/hisax/bkm_a8.c | |||
@@ -20,8 +20,6 @@ | |||
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include "bkm_ax.h" | 21 | #include "bkm_ax.h" |
22 | 22 | ||
23 | #ifdef CONFIG_PCI | ||
24 | |||
25 | #define ATTEMPT_PCI_REMAPPING /* Required for PLX rev 1 */ | 23 | #define ATTEMPT_PCI_REMAPPING /* Required for PLX rev 1 */ |
26 | 24 | ||
27 | extern const char *CardType[]; | 25 | extern const char *CardType[]; |
@@ -279,12 +277,9 @@ static u_char pci_bus __devinitdata = 0; | |||
279 | static u_char pci_device_fn __devinitdata = 0; | 277 | static u_char pci_device_fn __devinitdata = 0; |
280 | static u_char pci_irq __devinitdata = 0; | 278 | static u_char pci_irq __devinitdata = 0; |
281 | 279 | ||
282 | #endif /* CONFIG_PCI */ | ||
283 | |||
284 | int __devinit | 280 | int __devinit |
285 | setup_sct_quadro(struct IsdnCard *card) | 281 | setup_sct_quadro(struct IsdnCard *card) |
286 | { | 282 | { |
287 | #ifdef CONFIG_PCI | ||
288 | struct IsdnCardState *cs = card->cs; | 283 | struct IsdnCardState *cs = card->cs; |
289 | char tmp[64]; | 284 | char tmp[64]; |
290 | u_int found = 0; | 285 | u_int found = 0; |
@@ -442,7 +437,4 @@ setup_sct_quadro(struct IsdnCard *card) | |||
442 | sct_quadro_subtypes[cs->subtyp], | 437 | sct_quadro_subtypes[cs->subtyp], |
443 | readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ID)); | 438 | readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ID)); |
444 | return (1); | 439 | return (1); |
445 | #else | ||
446 | printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n"); | ||
447 | #endif /* CONFIG_PCI */ | ||
448 | } | 440 | } |
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 6eebeb441bfd..826745078746 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/isapnp.h> | 26 | #include <linux/isapnp.h> |
27 | 27 | ||
28 | extern const char *CardType[]; | ||
29 | |||
30 | static const char *Diva_revision = "$Revision: 1.33.2.6 $"; | 28 | static const char *Diva_revision = "$Revision: 1.33.2.6 $"; |
31 | 29 | ||
32 | #define byteout(addr,val) outb(val,addr) | 30 | #define byteout(addr,val) outb(val,addr) |
@@ -906,225 +904,15 @@ Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg) | |||
906 | return(0); | 904 | return(0); |
907 | } | 905 | } |
908 | 906 | ||
909 | static struct pci_dev *dev_diva __devinitdata = NULL; | 907 | static int __devinit setup_diva_common(struct IsdnCardState *cs) |
910 | static struct pci_dev *dev_diva_u __devinitdata = NULL; | ||
911 | static struct pci_dev *dev_diva201 __devinitdata = NULL; | ||
912 | static struct pci_dev *dev_diva202 __devinitdata = NULL; | ||
913 | |||
914 | #ifdef __ISAPNP__ | ||
915 | static struct isapnp_device_id diva_ids[] __devinitdata = { | ||
916 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), | ||
917 | ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), | ||
918 | (unsigned long) "Diva picola" }, | ||
919 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), | ||
920 | ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), | ||
921 | (unsigned long) "Diva picola" }, | ||
922 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), | ||
923 | ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), | ||
924 | (unsigned long) "Diva 2.0" }, | ||
925 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), | ||
926 | ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), | ||
927 | (unsigned long) "Diva 2.0" }, | ||
928 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), | ||
929 | ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), | ||
930 | (unsigned long) "Diva 2.01" }, | ||
931 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), | ||
932 | ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), | ||
933 | (unsigned long) "Diva 2.01" }, | ||
934 | { 0, } | ||
935 | }; | ||
936 | |||
937 | static struct isapnp_device_id *ipid __devinitdata = &diva_ids[0]; | ||
938 | static struct pnp_card *pnp_c __devinitdata = NULL; | ||
939 | #endif | ||
940 | |||
941 | |||
942 | int __devinit | ||
943 | setup_diva(struct IsdnCard *card) | ||
944 | { | 908 | { |
945 | int bytecnt = 8; | 909 | int bytecnt; |
946 | u_char val; | 910 | u_char val; |
947 | struct IsdnCardState *cs = card->cs; | ||
948 | char tmp[64]; | ||
949 | |||
950 | strcpy(tmp, Diva_revision); | ||
951 | printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); | ||
952 | if (cs->typ != ISDN_CTYPE_DIEHLDIVA) | ||
953 | return(0); | ||
954 | cs->hw.diva.status = 0; | ||
955 | if (card->para[1]) { | ||
956 | cs->hw.diva.ctrl_reg = 0; | ||
957 | cs->hw.diva.cfg_reg = card->para[1]; | ||
958 | val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, | ||
959 | cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); | ||
960 | printk(KERN_INFO "Diva: IPAC version %x\n", val); | ||
961 | if ((val == 1) || (val==2)) { | ||
962 | cs->subtyp = DIVA_IPAC_ISA; | ||
963 | cs->hw.diva.ctrl = 0; | ||
964 | cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; | ||
965 | cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; | ||
966 | cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; | ||
967 | cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; | ||
968 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | ||
969 | } else { | ||
970 | cs->subtyp = DIVA_ISA; | ||
971 | cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; | ||
972 | cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; | ||
973 | cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; | ||
974 | cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; | ||
975 | cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; | ||
976 | } | ||
977 | cs->irq = card->para[0]; | ||
978 | } else { | ||
979 | #ifdef __ISAPNP__ | ||
980 | if (isapnp_present()) { | ||
981 | struct pnp_dev *pnp_d; | ||
982 | while(ipid->card_vendor) { | ||
983 | if ((pnp_c = pnp_find_card(ipid->card_vendor, | ||
984 | ipid->card_device, pnp_c))) { | ||
985 | pnp_d = NULL; | ||
986 | if ((pnp_d = pnp_find_dev(pnp_c, | ||
987 | ipid->vendor, ipid->function, pnp_d))) { | ||
988 | int err; | ||
989 | |||
990 | printk(KERN_INFO "HiSax: %s detected\n", | ||
991 | (char *)ipid->driver_data); | ||
992 | pnp_disable_dev(pnp_d); | ||
993 | err = pnp_activate_dev(pnp_d); | ||
994 | if (err<0) { | ||
995 | printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", | ||
996 | __FUNCTION__, err); | ||
997 | return(0); | ||
998 | } | ||
999 | card->para[1] = pnp_port_start(pnp_d, 0); | ||
1000 | card->para[0] = pnp_irq(pnp_d, 0); | ||
1001 | if (!card->para[0] || !card->para[1]) { | ||
1002 | printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", | ||
1003 | card->para[0], card->para[1]); | ||
1004 | pnp_disable_dev(pnp_d); | ||
1005 | return(0); | ||
1006 | } | ||
1007 | cs->hw.diva.cfg_reg = card->para[1]; | ||
1008 | cs->irq = card->para[0]; | ||
1009 | if (ipid->function == ISAPNP_FUNCTION(0xA1)) { | ||
1010 | cs->subtyp = DIVA_IPAC_ISA; | ||
1011 | cs->hw.diva.ctrl = 0; | ||
1012 | cs->hw.diva.isac = | ||
1013 | card->para[1] + DIVA_IPAC_DATA; | ||
1014 | cs->hw.diva.hscx = | ||
1015 | card->para[1] + DIVA_IPAC_DATA; | ||
1016 | cs->hw.diva.isac_adr = | ||
1017 | card->para[1] + DIVA_IPAC_ADR; | ||
1018 | cs->hw.diva.hscx_adr = | ||
1019 | card->para[1] + DIVA_IPAC_ADR; | ||
1020 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | ||
1021 | } else { | ||
1022 | cs->subtyp = DIVA_ISA; | ||
1023 | cs->hw.diva.ctrl = | ||
1024 | card->para[1] + DIVA_ISA_CTRL; | ||
1025 | cs->hw.diva.isac = | ||
1026 | card->para[1] + DIVA_ISA_ISAC_DATA; | ||
1027 | cs->hw.diva.hscx = | ||
1028 | card->para[1] + DIVA_HSCX_DATA; | ||
1029 | cs->hw.diva.isac_adr = | ||
1030 | card->para[1] + DIVA_ISA_ISAC_ADR; | ||
1031 | cs->hw.diva.hscx_adr = | ||
1032 | card->para[1] + DIVA_HSCX_ADR; | ||
1033 | } | ||
1034 | goto ready; | ||
1035 | } else { | ||
1036 | printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); | ||
1037 | return(0); | ||
1038 | } | ||
1039 | } | ||
1040 | ipid++; | ||
1041 | pnp_c=NULL; | ||
1042 | } | ||
1043 | if (!ipid->card_vendor) { | ||
1044 | printk(KERN_INFO "Diva PnP: no ISAPnP card found\n"); | ||
1045 | } | ||
1046 | } | ||
1047 | #endif | ||
1048 | #ifdef CONFIG_PCI | ||
1049 | cs->subtyp = 0; | ||
1050 | if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, | ||
1051 | PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { | ||
1052 | if (pci_enable_device(dev_diva)) | ||
1053 | return(0); | ||
1054 | cs->subtyp = DIVA_PCI; | ||
1055 | cs->irq = dev_diva->irq; | ||
1056 | cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); | ||
1057 | } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, | ||
1058 | PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { | ||
1059 | if (pci_enable_device(dev_diva_u)) | ||
1060 | return(0); | ||
1061 | cs->subtyp = DIVA_PCI; | ||
1062 | cs->irq = dev_diva_u->irq; | ||
1063 | cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); | ||
1064 | } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, | ||
1065 | PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { | ||
1066 | if (pci_enable_device(dev_diva201)) | ||
1067 | return(0); | ||
1068 | cs->subtyp = DIVA_IPAC_PCI; | ||
1069 | cs->irq = dev_diva201->irq; | ||
1070 | cs->hw.diva.pci_cfg = | ||
1071 | (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); | ||
1072 | cs->hw.diva.cfg_reg = | ||
1073 | (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); | ||
1074 | } else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON, | ||
1075 | PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { | ||
1076 | if (pci_enable_device(dev_diva202)) | ||
1077 | return(0); | ||
1078 | cs->subtyp = DIVA_IPACX_PCI; | ||
1079 | cs->irq = dev_diva202->irq; | ||
1080 | cs->hw.diva.pci_cfg = | ||
1081 | (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); | ||
1082 | cs->hw.diva.cfg_reg = | ||
1083 | (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); | ||
1084 | } else { | ||
1085 | printk(KERN_WARNING "Diva: No PCI card found\n"); | ||
1086 | return(0); | ||
1087 | } | ||
1088 | |||
1089 | if (!cs->irq) { | ||
1090 | printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); | ||
1091 | iounmap_diva(cs); | ||
1092 | return(0); | ||
1093 | } | ||
1094 | |||
1095 | if (!cs->hw.diva.cfg_reg) { | ||
1096 | printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); | ||
1097 | iounmap_diva(cs); | ||
1098 | return(0); | ||
1099 | } | ||
1100 | cs->irq_flags |= IRQF_SHARED; | ||
1101 | #else | ||
1102 | printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n"); | ||
1103 | printk(KERN_WARNING "Diva: unable to config DIVA PCI\n"); | ||
1104 | return (0); | ||
1105 | #endif /* CONFIG_PCI */ | ||
1106 | if ((cs->subtyp == DIVA_IPAC_PCI) || | ||
1107 | (cs->subtyp == DIVA_IPACX_PCI) ) { | ||
1108 | cs->hw.diva.ctrl = 0; | ||
1109 | cs->hw.diva.isac = 0; | ||
1110 | cs->hw.diva.hscx = 0; | ||
1111 | cs->hw.diva.isac_adr = 0; | ||
1112 | cs->hw.diva.hscx_adr = 0; | ||
1113 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | ||
1114 | bytecnt = 0; | ||
1115 | } else { | ||
1116 | cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; | ||
1117 | cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; | ||
1118 | cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; | ||
1119 | cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; | ||
1120 | cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; | ||
1121 | bytecnt = 32; | ||
1122 | } | ||
1123 | } | ||
1124 | 911 | ||
1125 | #ifdef __ISAPNP__ | 912 | if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) |
1126 | ready: | 913 | bytecnt = 8; |
1127 | #endif | 914 | else |
915 | bytecnt = 32; | ||
1128 | 916 | ||
1129 | printk(KERN_INFO | 917 | printk(KERN_INFO |
1130 | "Diva: %s card configured at %#lx IRQ %d\n", | 918 | "Diva: %s card configured at %#lx IRQ %d\n", |
@@ -1145,7 +933,7 @@ ready: | |||
1145 | if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) { | 933 | if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) { |
1146 | printk(KERN_WARNING | 934 | printk(KERN_WARNING |
1147 | "HiSax: %s config port %lx-%lx already in use\n", | 935 | "HiSax: %s config port %lx-%lx already in use\n", |
1148 | CardType[card->typ], | 936 | "diva", |
1149 | cs->hw.diva.cfg_reg, | 937 | cs->hw.diva.cfg_reg, |
1150 | cs->hw.diva.cfg_reg + bytecnt); | 938 | cs->hw.diva.cfg_reg + bytecnt); |
1151 | iounmap_diva(cs); | 939 | iounmap_diva(cs); |
@@ -1206,3 +994,290 @@ ready: | |||
1206 | } | 994 | } |
1207 | return (1); | 995 | return (1); |
1208 | } | 996 | } |
997 | |||
998 | #ifdef CONFIG_ISA | ||
999 | |||
1000 | static int __devinit setup_diva_isa(struct IsdnCard *card) | ||
1001 | { | ||
1002 | struct IsdnCardState *cs = card->cs; | ||
1003 | u_char val; | ||
1004 | |||
1005 | if (!card->para[1]) | ||
1006 | return (-1); /* card not found; continue search */ | ||
1007 | |||
1008 | cs->hw.diva.ctrl_reg = 0; | ||
1009 | cs->hw.diva.cfg_reg = card->para[1]; | ||
1010 | val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, | ||
1011 | cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); | ||
1012 | printk(KERN_INFO "Diva: IPAC version %x\n", val); | ||
1013 | if ((val == 1) || (val==2)) { | ||
1014 | cs->subtyp = DIVA_IPAC_ISA; | ||
1015 | cs->hw.diva.ctrl = 0; | ||
1016 | cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; | ||
1017 | cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; | ||
1018 | cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; | ||
1019 | cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; | ||
1020 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | ||
1021 | } else { | ||
1022 | cs->subtyp = DIVA_ISA; | ||
1023 | cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; | ||
1024 | cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; | ||
1025 | cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; | ||
1026 | cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; | ||
1027 | cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; | ||
1028 | } | ||
1029 | cs->irq = card->para[0]; | ||
1030 | |||
1031 | return (1); /* card found */ | ||
1032 | } | ||
1033 | |||
1034 | #else /* if !CONFIG_ISA */ | ||
1035 | |||
1036 | static int __devinit setup_diva_isa(struct IsdnCard *card) | ||
1037 | { | ||
1038 | return (-1); /* card not found; continue search */ | ||
1039 | } | ||
1040 | |||
1041 | #endif /* CONFIG_ISA */ | ||
1042 | |||
1043 | #ifdef __ISAPNP__ | ||
1044 | static struct isapnp_device_id diva_ids[] __devinitdata = { | ||
1045 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), | ||
1046 | ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), | ||
1047 | (unsigned long) "Diva picola" }, | ||
1048 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), | ||
1049 | ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), | ||
1050 | (unsigned long) "Diva picola" }, | ||
1051 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), | ||
1052 | ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), | ||
1053 | (unsigned long) "Diva 2.0" }, | ||
1054 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), | ||
1055 | ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), | ||
1056 | (unsigned long) "Diva 2.0" }, | ||
1057 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), | ||
1058 | ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), | ||
1059 | (unsigned long) "Diva 2.01" }, | ||
1060 | { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), | ||
1061 | ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), | ||
1062 | (unsigned long) "Diva 2.01" }, | ||
1063 | { 0, } | ||
1064 | }; | ||
1065 | |||
1066 | static struct isapnp_device_id *ipid __devinitdata = &diva_ids[0]; | ||
1067 | static struct pnp_card *pnp_c __devinitdata = NULL; | ||
1068 | |||
1069 | static int __devinit setup_diva_isapnp(struct IsdnCard *card) | ||
1070 | { | ||
1071 | struct IsdnCardState *cs = card->cs; | ||
1072 | struct pnp_dev *pnp_d; | ||
1073 | |||
1074 | if (!isapnp_present()) | ||
1075 | return (-1); /* card not found; continue search */ | ||
1076 | |||
1077 | while(ipid->card_vendor) { | ||
1078 | if ((pnp_c = pnp_find_card(ipid->card_vendor, | ||
1079 | ipid->card_device, pnp_c))) { | ||
1080 | pnp_d = NULL; | ||
1081 | if ((pnp_d = pnp_find_dev(pnp_c, | ||
1082 | ipid->vendor, ipid->function, pnp_d))) { | ||
1083 | int err; | ||
1084 | |||
1085 | printk(KERN_INFO "HiSax: %s detected\n", | ||
1086 | (char *)ipid->driver_data); | ||
1087 | pnp_disable_dev(pnp_d); | ||
1088 | err = pnp_activate_dev(pnp_d); | ||
1089 | if (err<0) { | ||
1090 | printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", | ||
1091 | __FUNCTION__, err); | ||
1092 | return(0); | ||
1093 | } | ||
1094 | card->para[1] = pnp_port_start(pnp_d, 0); | ||
1095 | card->para[0] = pnp_irq(pnp_d, 0); | ||
1096 | if (!card->para[0] || !card->para[1]) { | ||
1097 | printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", | ||
1098 | card->para[0], card->para[1]); | ||
1099 | pnp_disable_dev(pnp_d); | ||
1100 | return(0); | ||
1101 | } | ||
1102 | cs->hw.diva.cfg_reg = card->para[1]; | ||
1103 | cs->irq = card->para[0]; | ||
1104 | if (ipid->function == ISAPNP_FUNCTION(0xA1)) { | ||
1105 | cs->subtyp = DIVA_IPAC_ISA; | ||
1106 | cs->hw.diva.ctrl = 0; | ||
1107 | cs->hw.diva.isac = | ||
1108 | card->para[1] + DIVA_IPAC_DATA; | ||
1109 | cs->hw.diva.hscx = | ||
1110 | card->para[1] + DIVA_IPAC_DATA; | ||
1111 | cs->hw.diva.isac_adr = | ||
1112 | card->para[1] + DIVA_IPAC_ADR; | ||
1113 | cs->hw.diva.hscx_adr = | ||
1114 | card->para[1] + DIVA_IPAC_ADR; | ||
1115 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | ||
1116 | } else { | ||
1117 | cs->subtyp = DIVA_ISA; | ||
1118 | cs->hw.diva.ctrl = | ||
1119 | card->para[1] + DIVA_ISA_CTRL; | ||
1120 | cs->hw.diva.isac = | ||
1121 | card->para[1] + DIVA_ISA_ISAC_DATA; | ||
1122 | cs->hw.diva.hscx = | ||
1123 | card->para[1] + DIVA_HSCX_DATA; | ||
1124 | cs->hw.diva.isac_adr = | ||
1125 | card->para[1] + DIVA_ISA_ISAC_ADR; | ||
1126 | cs->hw.diva.hscx_adr = | ||
1127 | card->para[1] + DIVA_HSCX_ADR; | ||
1128 | } | ||
1129 | return (1); /* card found */ | ||
1130 | } else { | ||
1131 | printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); | ||
1132 | return(0); | ||
1133 | } | ||
1134 | } | ||
1135 | ipid++; | ||
1136 | pnp_c=NULL; | ||
1137 | } | ||
1138 | |||
1139 | return (-1); /* card not found; continue search */ | ||
1140 | } | ||
1141 | |||
1142 | #else /* if !ISAPNP */ | ||
1143 | |||
1144 | static int __devinit setup_diva_isapnp(struct IsdnCard *card) | ||
1145 | { | ||
1146 | return (-1); /* card not found; continue search */ | ||
1147 | } | ||
1148 | |||
1149 | #endif /* ISAPNP */ | ||
1150 | |||
1151 | #ifdef CONFIG_PCI | ||
1152 | static struct pci_dev *dev_diva __devinitdata = NULL; | ||
1153 | static struct pci_dev *dev_diva_u __devinitdata = NULL; | ||
1154 | static struct pci_dev *dev_diva201 __devinitdata = NULL; | ||
1155 | static struct pci_dev *dev_diva202 __devinitdata = NULL; | ||
1156 | |||
1157 | static int __devinit setup_diva_pci(struct IsdnCard *card) | ||
1158 | { | ||
1159 | struct IsdnCardState *cs = card->cs; | ||
1160 | |||
1161 | cs->subtyp = 0; | ||
1162 | if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, | ||
1163 | PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { | ||
1164 | if (pci_enable_device(dev_diva)) | ||
1165 | return(0); | ||
1166 | cs->subtyp = DIVA_PCI; | ||
1167 | cs->irq = dev_diva->irq; | ||
1168 | cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); | ||
1169 | } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, | ||
1170 | PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { | ||
1171 | if (pci_enable_device(dev_diva_u)) | ||
1172 | return(0); | ||
1173 | cs->subtyp = DIVA_PCI; | ||
1174 | cs->irq = dev_diva_u->irq; | ||
1175 | cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); | ||
1176 | } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, | ||
1177 | PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { | ||
1178 | if (pci_enable_device(dev_diva201)) | ||
1179 | return(0); | ||
1180 | cs->subtyp = DIVA_IPAC_PCI; | ||
1181 | cs->irq = dev_diva201->irq; | ||
1182 | cs->hw.diva.pci_cfg = | ||
1183 | (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); | ||
1184 | cs->hw.diva.cfg_reg = | ||
1185 | (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); | ||
1186 | } else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON, | ||
1187 | PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { | ||
1188 | if (pci_enable_device(dev_diva202)) | ||
1189 | return(0); | ||
1190 | cs->subtyp = DIVA_IPACX_PCI; | ||
1191 | cs->irq = dev_diva202->irq; | ||
1192 | cs->hw.diva.pci_cfg = | ||
1193 | (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); | ||
1194 | cs->hw.diva.cfg_reg = | ||
1195 | (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); | ||
1196 | } else { | ||
1197 | return (-1); /* card not found; continue search */ | ||
1198 | } | ||
1199 | |||
1200 | if (!cs->irq) { | ||
1201 | printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); | ||
1202 | iounmap_diva(cs); | ||
1203 | return(0); | ||
1204 | } | ||
1205 | |||
1206 | if (!cs->hw.diva.cfg_reg) { | ||
1207 | printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); | ||
1208 | iounmap_diva(cs); | ||
1209 | return(0); | ||
1210 | } | ||
1211 | cs->irq_flags |= IRQF_SHARED; | ||
1212 | |||
1213 | if ((cs->subtyp == DIVA_IPAC_PCI) || | ||
1214 | (cs->subtyp == DIVA_IPACX_PCI) ) { | ||
1215 | cs->hw.diva.ctrl = 0; | ||
1216 | cs->hw.diva.isac = 0; | ||
1217 | cs->hw.diva.hscx = 0; | ||
1218 | cs->hw.diva.isac_adr = 0; | ||
1219 | cs->hw.diva.hscx_adr = 0; | ||
1220 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | ||
1221 | } else { | ||
1222 | cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; | ||
1223 | cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; | ||
1224 | cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; | ||
1225 | cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; | ||
1226 | cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; | ||
1227 | } | ||
1228 | |||
1229 | return (1); /* card found */ | ||
1230 | } | ||
1231 | |||
1232 | #else /* if !CONFIG_PCI */ | ||
1233 | |||
1234 | static int __devinit setup_diva_pci(struct IsdnCard *card) | ||
1235 | { | ||
1236 | return (-1); /* card not found; continue search */ | ||
1237 | } | ||
1238 | |||
1239 | #endif /* CONFIG_PCI */ | ||
1240 | |||
1241 | int __devinit | ||
1242 | setup_diva(struct IsdnCard *card) | ||
1243 | { | ||
1244 | int rc, have_card = 0; | ||
1245 | struct IsdnCardState *cs = card->cs; | ||
1246 | char tmp[64]; | ||
1247 | |||
1248 | strcpy(tmp, Diva_revision); | ||
1249 | printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); | ||
1250 | if (cs->typ != ISDN_CTYPE_DIEHLDIVA) | ||
1251 | return(0); | ||
1252 | cs->hw.diva.status = 0; | ||
1253 | |||
1254 | rc = setup_diva_isa(card); | ||
1255 | if (!rc) | ||
1256 | return rc; | ||
1257 | if (rc > 0) { | ||
1258 | have_card = 1; | ||
1259 | goto ready; | ||
1260 | } | ||
1261 | |||
1262 | rc = setup_diva_isapnp(card); | ||
1263 | if (!rc) | ||
1264 | return rc; | ||
1265 | if (rc > 0) { | ||
1266 | have_card = 1; | ||
1267 | goto ready; | ||
1268 | } | ||
1269 | |||
1270 | rc = setup_diva_pci(card); | ||
1271 | if (!rc) | ||
1272 | return rc; | ||
1273 | if (rc > 0) | ||
1274 | have_card = 1; | ||
1275 | |||
1276 | ready: | ||
1277 | if (!have_card) { | ||
1278 | printk(KERN_WARNING "Diva: No ISA, ISAPNP or PCI card found\n"); | ||
1279 | return(0); | ||
1280 | } | ||
1281 | |||
1282 | return setup_diva_common(card->cs); | ||
1283 | } | ||
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index fab3e4ea0595..0c1351b23840 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c | |||
@@ -30,8 +30,6 @@ | |||
30 | #include <linux/serial.h> | 30 | #include <linux/serial.h> |
31 | #include <linux/serial_reg.h> | 31 | #include <linux/serial_reg.h> |
32 | 32 | ||
33 | extern const char *CardType[]; | ||
34 | |||
35 | static const char *Elsa_revision = "$Revision: 2.32.2.4 $"; | 33 | static const char *Elsa_revision = "$Revision: 2.32.2.4 $"; |
36 | static const char *Elsa_Types[] = | 34 | static const char *Elsa_Types[] = |
37 | {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro", | 35 | {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro", |
@@ -832,8 +830,75 @@ probe_elsa(struct IsdnCardState *cs) | |||
832 | return (CARD_portlist[i]); | 830 | return (CARD_portlist[i]); |
833 | } | 831 | } |
834 | 832 | ||
835 | static struct pci_dev *dev_qs1000 __devinitdata = NULL; | 833 | static int __devinit |
836 | static struct pci_dev *dev_qs3000 __devinitdata = NULL; | 834 | setup_elsa_isa(struct IsdnCard *card) |
835 | { | ||
836 | struct IsdnCardState *cs = card->cs; | ||
837 | u_char val; | ||
838 | |||
839 | cs->hw.elsa.base = card->para[0]; | ||
840 | printk(KERN_INFO "Elsa: Microlink IO probing\n"); | ||
841 | if (cs->hw.elsa.base) { | ||
842 | if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, | ||
843 | cs->typ))) { | ||
844 | printk(KERN_WARNING | ||
845 | "Elsa: no Elsa Microlink at %#lx\n", | ||
846 | cs->hw.elsa.base); | ||
847 | return (0); | ||
848 | } | ||
849 | } else | ||
850 | cs->hw.elsa.base = probe_elsa(cs); | ||
851 | |||
852 | if (!cs->hw.elsa.base) { | ||
853 | printk(KERN_WARNING | ||
854 | "No Elsa Microlink found\n"); | ||
855 | return (0); | ||
856 | } | ||
857 | |||
858 | cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; | ||
859 | cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; | ||
860 | cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; | ||
861 | cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; | ||
862 | cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC; | ||
863 | cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; | ||
864 | cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; | ||
865 | cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; | ||
866 | val = bytein(cs->hw.elsa.cfg); | ||
867 | if (cs->subtyp == ELSA_PC) { | ||
868 | const u_char CARD_IrqTab[8] = | ||
869 | {7, 3, 5, 9, 0, 0, 0, 0}; | ||
870 | cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2]; | ||
871 | } else if (cs->subtyp == ELSA_PCC8) { | ||
872 | const u_char CARD_IrqTab[8] = | ||
873 | {7, 3, 5, 9, 0, 0, 0, 0}; | ||
874 | cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4]; | ||
875 | } else { | ||
876 | const u_char CARD_IrqTab[8] = | ||
877 | {15, 10, 15, 3, 11, 5, 11, 9}; | ||
878 | cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3]; | ||
879 | } | ||
880 | val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE; | ||
881 | if (val < 3) | ||
882 | val |= 8; | ||
883 | val += 'A' - 3; | ||
884 | if (val == 'B' || val == 'C') | ||
885 | val ^= 1; | ||
886 | if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G')) | ||
887 | val = 'C'; | ||
888 | printk(KERN_INFO | ||
889 | "Elsa: %s found at %#lx Rev.:%c IRQ %d\n", | ||
890 | Elsa_Types[cs->subtyp], | ||
891 | cs->hw.elsa.base, | ||
892 | val, cs->irq); | ||
893 | val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD; | ||
894 | if (val) { | ||
895 | printk(KERN_WARNING | ||
896 | "Elsa: Microlink S0 bus power bad\n"); | ||
897 | cs->hw.elsa.status |= ELSA_BAD_PWR; | ||
898 | } | ||
899 | |||
900 | return (1); | ||
901 | } | ||
837 | 902 | ||
838 | #ifdef __ISAPNP__ | 903 | #ifdef __ISAPNP__ |
839 | static struct isapnp_device_id elsa_ids[] __devinitdata = { | 904 | static struct isapnp_device_id elsa_ids[] __devinitdata = { |
@@ -848,233 +913,194 @@ static struct isapnp_device_id elsa_ids[] __devinitdata = { | |||
848 | 913 | ||
849 | static struct isapnp_device_id *ipid __devinitdata = &elsa_ids[0]; | 914 | static struct isapnp_device_id *ipid __devinitdata = &elsa_ids[0]; |
850 | static struct pnp_card *pnp_c __devinitdata = NULL; | 915 | static struct pnp_card *pnp_c __devinitdata = NULL; |
851 | #endif | 916 | #endif /* __ISAPNP__ */ |
852 | 917 | ||
853 | int __devinit | 918 | static int __devinit |
854 | setup_elsa(struct IsdnCard *card) | 919 | setup_elsa_isapnp(struct IsdnCard *card) |
855 | { | 920 | { |
856 | int bytecnt; | ||
857 | u_char val; | ||
858 | struct IsdnCardState *cs = card->cs; | 921 | struct IsdnCardState *cs = card->cs; |
859 | char tmp[64]; | ||
860 | 922 | ||
861 | strcpy(tmp, Elsa_revision); | ||
862 | printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp)); | ||
863 | cs->hw.elsa.ctrl_reg = 0; | ||
864 | cs->hw.elsa.status = 0; | ||
865 | cs->hw.elsa.MFlag = 0; | ||
866 | cs->subtyp = 0; | ||
867 | if (cs->typ == ISDN_CTYPE_ELSA) { | ||
868 | cs->hw.elsa.base = card->para[0]; | ||
869 | printk(KERN_INFO "Elsa: Microlink IO probing\n"); | ||
870 | if (cs->hw.elsa.base) { | ||
871 | if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, | ||
872 | cs->typ))) { | ||
873 | printk(KERN_WARNING | ||
874 | "Elsa: no Elsa Microlink at %#lx\n", | ||
875 | cs->hw.elsa.base); | ||
876 | return (0); | ||
877 | } | ||
878 | } else | ||
879 | cs->hw.elsa.base = probe_elsa(cs); | ||
880 | if (cs->hw.elsa.base) { | ||
881 | cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; | ||
882 | cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; | ||
883 | cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; | ||
884 | cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; | ||
885 | cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC; | ||
886 | cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; | ||
887 | cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; | ||
888 | cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; | ||
889 | val = bytein(cs->hw.elsa.cfg); | ||
890 | if (cs->subtyp == ELSA_PC) { | ||
891 | const u_char CARD_IrqTab[8] = | ||
892 | {7, 3, 5, 9, 0, 0, 0, 0}; | ||
893 | cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2]; | ||
894 | } else if (cs->subtyp == ELSA_PCC8) { | ||
895 | const u_char CARD_IrqTab[8] = | ||
896 | {7, 3, 5, 9, 0, 0, 0, 0}; | ||
897 | cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4]; | ||
898 | } else { | ||
899 | const u_char CARD_IrqTab[8] = | ||
900 | {15, 10, 15, 3, 11, 5, 11, 9}; | ||
901 | cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3]; | ||
902 | } | ||
903 | val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE; | ||
904 | if (val < 3) | ||
905 | val |= 8; | ||
906 | val += 'A' - 3; | ||
907 | if (val == 'B' || val == 'C') | ||
908 | val ^= 1; | ||
909 | if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G')) | ||
910 | val = 'C'; | ||
911 | printk(KERN_INFO | ||
912 | "Elsa: %s found at %#lx Rev.:%c IRQ %d\n", | ||
913 | Elsa_Types[cs->subtyp], | ||
914 | cs->hw.elsa.base, | ||
915 | val, cs->irq); | ||
916 | val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD; | ||
917 | if (val) { | ||
918 | printk(KERN_WARNING | ||
919 | "Elsa: Microlink S0 bus power bad\n"); | ||
920 | cs->hw.elsa.status |= ELSA_BAD_PWR; | ||
921 | } | ||
922 | } else { | ||
923 | printk(KERN_WARNING | ||
924 | "No Elsa Microlink found\n"); | ||
925 | return (0); | ||
926 | } | ||
927 | } else if (cs->typ == ISDN_CTYPE_ELSA_PNP) { | ||
928 | #ifdef __ISAPNP__ | 923 | #ifdef __ISAPNP__ |
929 | if (!card->para[1] && isapnp_present()) { | 924 | if (!card->para[1] && isapnp_present()) { |
930 | struct pnp_dev *pnp_d; | 925 | struct pnp_dev *pnp_d; |
931 | while(ipid->card_vendor) { | 926 | while(ipid->card_vendor) { |
932 | if ((pnp_c = pnp_find_card(ipid->card_vendor, | 927 | if ((pnp_c = pnp_find_card(ipid->card_vendor, |
933 | ipid->card_device, pnp_c))) { | 928 | ipid->card_device, pnp_c))) { |
934 | pnp_d = NULL; | 929 | pnp_d = NULL; |
935 | if ((pnp_d = pnp_find_dev(pnp_c, | 930 | if ((pnp_d = pnp_find_dev(pnp_c, |
936 | ipid->vendor, ipid->function, pnp_d))) { | 931 | ipid->vendor, ipid->function, pnp_d))) { |
937 | int err; | 932 | int err; |
938 | 933 | ||
939 | printk(KERN_INFO "HiSax: %s detected\n", | 934 | printk(KERN_INFO "HiSax: %s detected\n", |
940 | (char *)ipid->driver_data); | 935 | (char *)ipid->driver_data); |
936 | pnp_disable_dev(pnp_d); | ||
937 | err = pnp_activate_dev(pnp_d); | ||
938 | if (err<0) { | ||
939 | printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", | ||
940 | __FUNCTION__, err); | ||
941 | return(0); | ||
942 | } | ||
943 | card->para[1] = pnp_port_start(pnp_d, 0); | ||
944 | card->para[0] = pnp_irq(pnp_d, 0); | ||
945 | |||
946 | if (!card->para[0] || !card->para[1]) { | ||
947 | printk(KERN_ERR "Elsa PnP:some resources are missing %ld/%lx\n", | ||
948 | card->para[0], card->para[1]); | ||
941 | pnp_disable_dev(pnp_d); | 949 | pnp_disable_dev(pnp_d); |
942 | err = pnp_activate_dev(pnp_d); | ||
943 | if (err<0) { | ||
944 | printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", | ||
945 | __FUNCTION__, err); | ||
946 | return(0); | ||
947 | } | ||
948 | card->para[1] = pnp_port_start(pnp_d, 0); | ||
949 | card->para[0] = pnp_irq(pnp_d, 0); | ||
950 | |||
951 | if (!card->para[0] || !card->para[1]) { | ||
952 | printk(KERN_ERR "Elsa PnP:some resources are missing %ld/%lx\n", | ||
953 | card->para[0], card->para[1]); | ||
954 | pnp_disable_dev(pnp_d); | ||
955 | return(0); | ||
956 | } | ||
957 | if (ipid->function == ISAPNP_FUNCTION(0x133)) | ||
958 | cs->subtyp = ELSA_QS1000; | ||
959 | else | ||
960 | cs->subtyp = ELSA_QS3000; | ||
961 | break; | ||
962 | } else { | ||
963 | printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n"); | ||
964 | return(0); | 950 | return(0); |
965 | } | 951 | } |
952 | if (ipid->function == ISAPNP_FUNCTION(0x133)) | ||
953 | cs->subtyp = ELSA_QS1000; | ||
954 | else | ||
955 | cs->subtyp = ELSA_QS3000; | ||
956 | break; | ||
957 | } else { | ||
958 | printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n"); | ||
959 | return(0); | ||
966 | } | 960 | } |
967 | ipid++; | ||
968 | pnp_c=NULL; | ||
969 | } | ||
970 | if (!ipid->card_vendor) { | ||
971 | printk(KERN_INFO "Elsa PnP: no ISAPnP card found\n"); | ||
972 | return(0); | ||
973 | } | 961 | } |
962 | ipid++; | ||
963 | pnp_c=NULL; | ||
964 | } | ||
965 | if (!ipid->card_vendor) { | ||
966 | printk(KERN_INFO "Elsa PnP: no ISAPnP card found\n"); | ||
967 | return(0); | ||
974 | } | 968 | } |
975 | #endif | 969 | } |
976 | if (card->para[1] && card->para[0]) { | 970 | #endif /* __ISAPNP__ */ |
977 | cs->hw.elsa.base = card->para[1]; | 971 | |
978 | cs->irq = card->para[0]; | 972 | if (card->para[1] && card->para[0]) { |
979 | if (!cs->subtyp) | ||
980 | cs->subtyp = ELSA_QS1000; | ||
981 | } else { | ||
982 | printk(KERN_ERR "Elsa PnP: no parameter\n"); | ||
983 | } | ||
984 | cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; | ||
985 | cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; | ||
986 | cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; | ||
987 | cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; | ||
988 | cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; | ||
989 | cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; | ||
990 | cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; | ||
991 | printk(KERN_INFO | ||
992 | "Elsa: %s defined at %#lx IRQ %d\n", | ||
993 | Elsa_Types[cs->subtyp], | ||
994 | cs->hw.elsa.base, | ||
995 | cs->irq); | ||
996 | } else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA) { | ||
997 | cs->hw.elsa.base = card->para[1]; | 973 | cs->hw.elsa.base = card->para[1]; |
998 | cs->irq = card->para[0]; | 974 | cs->irq = card->para[0]; |
999 | val = readreg(cs->hw.elsa.base + 0, cs->hw.elsa.base + 2, IPAC_ID); | 975 | if (!cs->subtyp) |
1000 | if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */ | 976 | cs->subtyp = ELSA_QS1000; |
1001 | cs->subtyp = ELSA_PCMCIA_IPAC; | 977 | } else { |
1002 | cs->hw.elsa.ale = cs->hw.elsa.base + 0; | 978 | printk(KERN_ERR "Elsa PnP: no parameter\n"); |
1003 | cs->hw.elsa.isac = cs->hw.elsa.base + 2; | 979 | } |
1004 | cs->hw.elsa.hscx = cs->hw.elsa.base + 2; | 980 | cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; |
1005 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | 981 | cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; |
1006 | } else { | 982 | cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; |
1007 | cs->subtyp = ELSA_PCMCIA; | 983 | cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; |
1008 | cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM; | 984 | cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; |
1009 | cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM; | 985 | cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; |
1010 | cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; | 986 | cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; |
1011 | } | 987 | printk(KERN_INFO |
1012 | cs->hw.elsa.timer = 0; | 988 | "Elsa: %s defined at %#lx IRQ %d\n", |
1013 | cs->hw.elsa.trig = 0; | 989 | Elsa_Types[cs->subtyp], |
1014 | cs->hw.elsa.ctrl = 0; | 990 | cs->hw.elsa.base, |
1015 | cs->irq_flags |= IRQF_SHARED; | 991 | cs->irq); |
1016 | printk(KERN_INFO | 992 | |
1017 | "Elsa: %s defined at %#lx IRQ %d\n", | 993 | return (1); |
1018 | Elsa_Types[cs->subtyp], | 994 | } |
1019 | cs->hw.elsa.base, | 995 | |
1020 | cs->irq); | 996 | static void __devinit |
1021 | } else if (cs->typ == ISDN_CTYPE_ELSA_PCI) { | 997 | setup_elsa_pcmcia(struct IsdnCard *card) |
998 | { | ||
999 | struct IsdnCardState *cs = card->cs; | ||
1000 | u_char val; | ||
1001 | |||
1002 | cs->hw.elsa.base = card->para[1]; | ||
1003 | cs->irq = card->para[0]; | ||
1004 | val = readreg(cs->hw.elsa.base + 0, cs->hw.elsa.base + 2, IPAC_ID); | ||
1005 | if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */ | ||
1006 | cs->subtyp = ELSA_PCMCIA_IPAC; | ||
1007 | cs->hw.elsa.ale = cs->hw.elsa.base + 0; | ||
1008 | cs->hw.elsa.isac = cs->hw.elsa.base + 2; | ||
1009 | cs->hw.elsa.hscx = cs->hw.elsa.base + 2; | ||
1010 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | ||
1011 | } else { | ||
1012 | cs->subtyp = ELSA_PCMCIA; | ||
1013 | cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM; | ||
1014 | cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM; | ||
1015 | cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; | ||
1016 | } | ||
1017 | cs->hw.elsa.timer = 0; | ||
1018 | cs->hw.elsa.trig = 0; | ||
1019 | cs->hw.elsa.ctrl = 0; | ||
1020 | cs->irq_flags |= IRQF_SHARED; | ||
1021 | printk(KERN_INFO | ||
1022 | "Elsa: %s defined at %#lx IRQ %d\n", | ||
1023 | Elsa_Types[cs->subtyp], | ||
1024 | cs->hw.elsa.base, | ||
1025 | cs->irq); | ||
1026 | } | ||
1027 | |||
1022 | #ifdef CONFIG_PCI | 1028 | #ifdef CONFIG_PCI |
1023 | cs->subtyp = 0; | 1029 | static struct pci_dev *dev_qs1000 __devinitdata = NULL; |
1024 | if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA, | 1030 | static struct pci_dev *dev_qs3000 __devinitdata = NULL; |
1025 | PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) { | 1031 | |
1026 | if (pci_enable_device(dev_qs1000)) | 1032 | static int __devinit |
1027 | return(0); | 1033 | setup_elsa_pci(struct IsdnCard *card) |
1028 | cs->subtyp = ELSA_QS1000PCI; | 1034 | { |
1029 | cs->irq = dev_qs1000->irq; | 1035 | struct IsdnCardState *cs = card->cs; |
1030 | cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1); | 1036 | |
1031 | cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3); | 1037 | cs->subtyp = 0; |
1032 | } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA, | 1038 | if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA, |
1033 | PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) { | 1039 | PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) { |
1034 | if (pci_enable_device(dev_qs3000)) | 1040 | if (pci_enable_device(dev_qs1000)) |
1035 | return(0); | ||
1036 | cs->subtyp = ELSA_QS3000PCI; | ||
1037 | cs->irq = dev_qs3000->irq; | ||
1038 | cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1); | ||
1039 | cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3); | ||
1040 | } else { | ||
1041 | printk(KERN_WARNING "Elsa: No PCI card found\n"); | ||
1042 | return(0); | 1041 | return(0); |
1043 | } | 1042 | cs->subtyp = ELSA_QS1000PCI; |
1044 | if (!cs->irq) { | 1043 | cs->irq = dev_qs1000->irq; |
1045 | printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n"); | 1044 | cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1); |
1045 | cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3); | ||
1046 | } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA, | ||
1047 | PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) { | ||
1048 | if (pci_enable_device(dev_qs3000)) | ||
1046 | return(0); | 1049 | return(0); |
1047 | } | 1050 | cs->subtyp = ELSA_QS3000PCI; |
1051 | cs->irq = dev_qs3000->irq; | ||
1052 | cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1); | ||
1053 | cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3); | ||
1054 | } else { | ||
1055 | printk(KERN_WARNING "Elsa: No PCI card found\n"); | ||
1056 | return(0); | ||
1057 | } | ||
1058 | if (!cs->irq) { | ||
1059 | printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n"); | ||
1060 | return(0); | ||
1061 | } | ||
1062 | |||
1063 | if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) { | ||
1064 | printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n"); | ||
1065 | return(0); | ||
1066 | } | ||
1067 | if ((cs->hw.elsa.cfg & 0xff) || (cs->hw.elsa.base & 0xf)) { | ||
1068 | printk(KERN_WARNING "Elsa: You may have a wrong PCI bios\n"); | ||
1069 | printk(KERN_WARNING "Elsa: If your system hangs now, read\n"); | ||
1070 | printk(KERN_WARNING "Elsa: Documentation/isdn/README.HiSax\n"); | ||
1071 | } | ||
1072 | cs->hw.elsa.ale = cs->hw.elsa.base; | ||
1073 | cs->hw.elsa.isac = cs->hw.elsa.base +1; | ||
1074 | cs->hw.elsa.hscx = cs->hw.elsa.base +1; | ||
1075 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | ||
1076 | cs->hw.elsa.timer = 0; | ||
1077 | cs->hw.elsa.trig = 0; | ||
1078 | cs->irq_flags |= IRQF_SHARED; | ||
1079 | printk(KERN_INFO | ||
1080 | "Elsa: %s defined at %#lx/0x%x IRQ %d\n", | ||
1081 | Elsa_Types[cs->subtyp], | ||
1082 | cs->hw.elsa.base, | ||
1083 | cs->hw.elsa.cfg, | ||
1084 | cs->irq); | ||
1085 | |||
1086 | return (1); | ||
1087 | } | ||
1048 | 1088 | ||
1049 | if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) { | ||
1050 | printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n"); | ||
1051 | return(0); | ||
1052 | } | ||
1053 | if ((cs->hw.elsa.cfg & 0xff) || (cs->hw.elsa.base & 0xf)) { | ||
1054 | printk(KERN_WARNING "Elsa: You may have a wrong PCI bios\n"); | ||
1055 | printk(KERN_WARNING "Elsa: If your system hangs now, read\n"); | ||
1056 | printk(KERN_WARNING "Elsa: Documentation/isdn/README.HiSax\n"); | ||
1057 | } | ||
1058 | cs->hw.elsa.ale = cs->hw.elsa.base; | ||
1059 | cs->hw.elsa.isac = cs->hw.elsa.base +1; | ||
1060 | cs->hw.elsa.hscx = cs->hw.elsa.base +1; | ||
1061 | test_and_set_bit(HW_IPAC, &cs->HW_Flags); | ||
1062 | cs->hw.elsa.timer = 0; | ||
1063 | cs->hw.elsa.trig = 0; | ||
1064 | cs->irq_flags |= IRQF_SHARED; | ||
1065 | printk(KERN_INFO | ||
1066 | "Elsa: %s defined at %#lx/0x%x IRQ %d\n", | ||
1067 | Elsa_Types[cs->subtyp], | ||
1068 | cs->hw.elsa.base, | ||
1069 | cs->hw.elsa.cfg, | ||
1070 | cs->irq); | ||
1071 | #else | 1089 | #else |
1072 | printk(KERN_WARNING "Elsa: Elsa PCI and NO_PCI_BIOS\n"); | 1090 | |
1073 | printk(KERN_WARNING "Elsa: unable to config Elsa PCI\n"); | 1091 | static void __devinit |
1074 | return (0); | 1092 | setup_elsa_pci(struct IsdnCard *card) |
1093 | { | ||
1094 | return (1); | ||
1095 | } | ||
1075 | #endif /* CONFIG_PCI */ | 1096 | #endif /* CONFIG_PCI */ |
1076 | } else | 1097 | |
1077 | return (0); | 1098 | static int __devinit |
1099 | setup_elsa_common(struct IsdnCard *card) | ||
1100 | { | ||
1101 | struct IsdnCardState *cs = card->cs; | ||
1102 | u_char val; | ||
1103 | int bytecnt; | ||
1078 | 1104 | ||
1079 | switch (cs->subtyp) { | 1105 | switch (cs->subtyp) { |
1080 | case ELSA_PC: | 1106 | case ELSA_PC: |
@@ -1104,8 +1130,7 @@ setup_elsa(struct IsdnCard *card) | |||
1104 | here, it would fail. */ | 1130 | here, it would fail. */ |
1105 | if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA && !request_region(cs->hw.elsa.base, bytecnt, "elsa isdn")) { | 1131 | if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA && !request_region(cs->hw.elsa.base, bytecnt, "elsa isdn")) { |
1106 | printk(KERN_WARNING | 1132 | printk(KERN_WARNING |
1107 | "HiSax: %s config port %#lx-%#lx already in use\n", | 1133 | "HiSax: ELSA config port %#lx-%#lx already in use\n", |
1108 | CardType[card->typ], | ||
1109 | cs->hw.elsa.base, | 1134 | cs->hw.elsa.base, |
1110 | cs->hw.elsa.base + bytecnt); | 1135 | cs->hw.elsa.base + bytecnt); |
1111 | return (0); | 1136 | return (0); |
@@ -1113,8 +1138,7 @@ setup_elsa(struct IsdnCard *card) | |||
1113 | if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) { | 1138 | if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) { |
1114 | if (!request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) { | 1139 | if (!request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) { |
1115 | printk(KERN_WARNING | 1140 | printk(KERN_WARNING |
1116 | "HiSax: %s pci port %x-%x already in use\n", | 1141 | "HiSax: ELSA pci port %x-%x already in use\n", |
1117 | CardType[card->typ], | ||
1118 | cs->hw.elsa.cfg, | 1142 | cs->hw.elsa.cfg, |
1119 | cs->hw.elsa.cfg + 0x80); | 1143 | cs->hw.elsa.cfg + 0x80); |
1120 | release_region(cs->hw.elsa.base, bytecnt); | 1144 | release_region(cs->hw.elsa.base, bytecnt); |
@@ -1186,3 +1210,41 @@ setup_elsa(struct IsdnCard *card) | |||
1186 | } | 1210 | } |
1187 | return (1); | 1211 | return (1); |
1188 | } | 1212 | } |
1213 | |||
1214 | int __devinit | ||
1215 | setup_elsa(struct IsdnCard *card) | ||
1216 | { | ||
1217 | int rc; | ||
1218 | struct IsdnCardState *cs = card->cs; | ||
1219 | char tmp[64]; | ||
1220 | |||
1221 | strcpy(tmp, Elsa_revision); | ||
1222 | printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp)); | ||
1223 | cs->hw.elsa.ctrl_reg = 0; | ||
1224 | cs->hw.elsa.status = 0; | ||
1225 | cs->hw.elsa.MFlag = 0; | ||
1226 | cs->subtyp = 0; | ||
1227 | |||
1228 | if (cs->typ == ISDN_CTYPE_ELSA) { | ||
1229 | rc = setup_elsa_isa(card); | ||
1230 | if (!rc) | ||
1231 | return (0); | ||
1232 | |||
1233 | } else if (cs->typ == ISDN_CTYPE_ELSA_PNP) { | ||
1234 | rc = setup_elsa_isapnp(card); | ||
1235 | if (!rc) | ||
1236 | return (0); | ||
1237 | |||
1238 | } else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA) | ||
1239 | setup_elsa_pcmcia(card); | ||
1240 | |||
1241 | else if (cs->typ == ISDN_CTYPE_ELSA_PCI) { | ||
1242 | rc = setup_elsa_pci(card); | ||
1243 | if (!rc) | ||
1244 | return (0); | ||
1245 | |||
1246 | } else | ||
1247 | return (0); | ||
1248 | |||
1249 | return setup_elsa_common(card); | ||
1250 | } | ||
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c index ad06f3cc60fb..03dfc32166a0 100644 --- a/drivers/isdn/hisax/sedlbauer.c +++ b/drivers/isdn/hisax/sedlbauer.c | |||
@@ -518,8 +518,6 @@ Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg) | |||
518 | return(0); | 518 | return(0); |
519 | } | 519 | } |
520 | 520 | ||
521 | static struct pci_dev *dev_sedl __devinitdata = NULL; | ||
522 | |||
523 | #ifdef __ISAPNP__ | 521 | #ifdef __ISAPNP__ |
524 | static struct isapnp_device_id sedl_ids[] __devinitdata = { | 522 | static struct isapnp_device_id sedl_ids[] __devinitdata = { |
525 | { ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01), | 523 | { ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01), |
@@ -533,15 +531,158 @@ static struct isapnp_device_id sedl_ids[] __devinitdata = { | |||
533 | 531 | ||
534 | static struct isapnp_device_id *ipid __devinitdata = &sedl_ids[0]; | 532 | static struct isapnp_device_id *ipid __devinitdata = &sedl_ids[0]; |
535 | static struct pnp_card *pnp_c __devinitdata = NULL; | 533 | static struct pnp_card *pnp_c __devinitdata = NULL; |
536 | #endif | 534 | |
535 | static int __devinit | ||
536 | setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt) | ||
537 | { | ||
538 | struct IsdnCardState *cs = card->cs; | ||
539 | struct pnp_dev *pnp_d; | ||
540 | |||
541 | if (!isapnp_present()) | ||
542 | return -1; | ||
543 | |||
544 | while(ipid->card_vendor) { | ||
545 | if ((pnp_c = pnp_find_card(ipid->card_vendor, | ||
546 | ipid->card_device, pnp_c))) { | ||
547 | pnp_d = NULL; | ||
548 | if ((pnp_d = pnp_find_dev(pnp_c, | ||
549 | ipid->vendor, ipid->function, pnp_d))) { | ||
550 | int err; | ||
551 | |||
552 | printk(KERN_INFO "HiSax: %s detected\n", | ||
553 | (char *)ipid->driver_data); | ||
554 | pnp_disable_dev(pnp_d); | ||
555 | err = pnp_activate_dev(pnp_d); | ||
556 | if (err<0) { | ||
557 | printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", | ||
558 | __FUNCTION__, err); | ||
559 | return(0); | ||
560 | } | ||
561 | card->para[1] = pnp_port_start(pnp_d, 0); | ||
562 | card->para[0] = pnp_irq(pnp_d, 0); | ||
563 | |||
564 | if (!card->para[0] || !card->para[1]) { | ||
565 | printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n", | ||
566 | card->para[0], card->para[1]); | ||
567 | pnp_disable_dev(pnp_d); | ||
568 | return(0); | ||
569 | } | ||
570 | cs->hw.sedl.cfg_reg = card->para[1]; | ||
571 | cs->irq = card->para[0]; | ||
572 | if (ipid->function == ISAPNP_FUNCTION(0x2)) { | ||
573 | cs->subtyp = SEDL_SPEED_FAX; | ||
574 | cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; | ||
575 | *bytecnt = 16; | ||
576 | } else { | ||
577 | cs->subtyp = SEDL_SPEED_CARD_WIN; | ||
578 | cs->hw.sedl.chip = SEDL_CHIP_TEST; | ||
579 | } | ||
580 | |||
581 | return (1); | ||
582 | } else { | ||
583 | printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); | ||
584 | return(0); | ||
585 | } | ||
586 | } | ||
587 | ipid++; | ||
588 | pnp_c = NULL; | ||
589 | } | ||
590 | |||
591 | printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n"); | ||
592 | return -1; | ||
593 | } | ||
594 | #else | ||
595 | |||
596 | static int __devinit | ||
597 | setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt) | ||
598 | { | ||
599 | return -1; | ||
600 | } | ||
601 | #endif /* __ISAPNP__ */ | ||
602 | |||
603 | #ifdef CONFIG_PCI | ||
604 | static struct pci_dev *dev_sedl __devinitdata = NULL; | ||
605 | |||
606 | static int __devinit | ||
607 | setup_sedlbauer_pci(struct IsdnCard *card) | ||
608 | { | ||
609 | struct IsdnCardState *cs = card->cs; | ||
610 | u16 sub_vendor_id, sub_id; | ||
611 | |||
612 | if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, | ||
613 | PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) { | ||
614 | if (pci_enable_device(dev_sedl)) | ||
615 | return(0); | ||
616 | cs->irq = dev_sedl->irq; | ||
617 | if (!cs->irq) { | ||
618 | printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n"); | ||
619 | return(0); | ||
620 | } | ||
621 | cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0); | ||
622 | } else { | ||
623 | printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); | ||
624 | return(0); | ||
625 | } | ||
626 | cs->irq_flags |= IRQF_SHARED; | ||
627 | cs->hw.sedl.bus = SEDL_BUS_PCI; | ||
628 | sub_vendor_id = dev_sedl->subsystem_vendor; | ||
629 | sub_id = dev_sedl->subsystem_device; | ||
630 | printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n", | ||
631 | sub_vendor_id, sub_id); | ||
632 | printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n", | ||
633 | cs->hw.sedl.cfg_reg); | ||
634 | if (sub_id != PCI_SUB_ID_SEDLBAUER) { | ||
635 | printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id); | ||
636 | return(0); | ||
637 | } | ||
638 | if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) { | ||
639 | cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; | ||
640 | cs->subtyp = SEDL_SPEEDFAX_PYRAMID; | ||
641 | } else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) { | ||
642 | cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; | ||
643 | cs->subtyp = SEDL_SPEEDFAX_PCI; | ||
644 | } else if (sub_vendor_id == PCI_SUBVENDOR_HST_SAPHIR3) { | ||
645 | cs->hw.sedl.chip = SEDL_CHIP_IPAC; | ||
646 | cs->subtyp = HST_SAPHIR3; | ||
647 | } else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) { | ||
648 | cs->hw.sedl.chip = SEDL_CHIP_IPAC; | ||
649 | cs->subtyp = SEDL_SPEED_PCI; | ||
650 | } else { | ||
651 | printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n", | ||
652 | sub_vendor_id); | ||
653 | return(0); | ||
654 | } | ||
655 | |||
656 | cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON; | ||
657 | cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF; | ||
658 | byteout(cs->hw.sedl.cfg_reg, 0xff); | ||
659 | byteout(cs->hw.sedl.cfg_reg, 0x00); | ||
660 | byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd); | ||
661 | byteout(cs->hw.sedl.cfg_reg+ 5, 0); /* disable all IRQ */ | ||
662 | byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on); | ||
663 | mdelay(2); | ||
664 | byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); | ||
665 | mdelay(10); | ||
666 | |||
667 | return (1); | ||
668 | } | ||
669 | |||
670 | #else | ||
671 | |||
672 | static int __devinit | ||
673 | setup_sedlbauer_pci(struct IsdnCard *card) | ||
674 | { | ||
675 | return (1); | ||
676 | } | ||
677 | |||
678 | #endif /* CONFIG_PCI */ | ||
537 | 679 | ||
538 | int __devinit | 680 | int __devinit |
539 | setup_sedlbauer(struct IsdnCard *card) | 681 | setup_sedlbauer(struct IsdnCard *card) |
540 | { | 682 | { |
541 | int bytecnt, ver, val; | 683 | int bytecnt = 8, ver, val, rc; |
542 | struct IsdnCardState *cs = card->cs; | 684 | struct IsdnCardState *cs = card->cs; |
543 | char tmp[64]; | 685 | char tmp[64]; |
544 | u16 sub_vendor_id, sub_id; | ||
545 | 686 | ||
546 | strcpy(tmp, Sedlbauer_revision); | 687 | strcpy(tmp, Sedlbauer_revision); |
547 | printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp)); | 688 | printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp)); |
@@ -569,124 +710,21 @@ setup_sedlbauer(struct IsdnCard *card) | |||
569 | bytecnt = 16; | 710 | bytecnt = 16; |
570 | } | 711 | } |
571 | } else { | 712 | } else { |
572 | #ifdef __ISAPNP__ | 713 | rc = setup_sedlbauer_isapnp(card, &bytecnt); |
573 | if (isapnp_present()) { | 714 | if (!rc) |
574 | struct pnp_dev *pnp_d; | 715 | return (0); |
575 | while(ipid->card_vendor) { | 716 | if (rc > 0) |
576 | if ((pnp_c = pnp_find_card(ipid->card_vendor, | 717 | goto ready; |
577 | ipid->card_device, pnp_c))) { | 718 | |
578 | pnp_d = NULL; | 719 | /* Probe for Sedlbauer speed pci */ |
579 | if ((pnp_d = pnp_find_dev(pnp_c, | 720 | rc = setup_sedlbauer_pci(card); |
580 | ipid->vendor, ipid->function, pnp_d))) { | 721 | if (!rc) |
581 | int err; | 722 | return (0); |
582 | 723 | ||
583 | printk(KERN_INFO "HiSax: %s detected\n", | ||
584 | (char *)ipid->driver_data); | ||
585 | pnp_disable_dev(pnp_d); | ||
586 | err = pnp_activate_dev(pnp_d); | ||
587 | if (err<0) { | ||
588 | printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", | ||
589 | __FUNCTION__, err); | ||
590 | return(0); | ||
591 | } | ||
592 | card->para[1] = pnp_port_start(pnp_d, 0); | ||
593 | card->para[0] = pnp_irq(pnp_d, 0); | ||
594 | |||
595 | if (!card->para[0] || !card->para[1]) { | ||
596 | printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n", | ||
597 | card->para[0], card->para[1]); | ||
598 | pnp_disable_dev(pnp_d); | ||
599 | return(0); | ||
600 | } | ||
601 | cs->hw.sedl.cfg_reg = card->para[1]; | ||
602 | cs->irq = card->para[0]; | ||
603 | if (ipid->function == ISAPNP_FUNCTION(0x2)) { | ||
604 | cs->subtyp = SEDL_SPEED_FAX; | ||
605 | cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; | ||
606 | bytecnt = 16; | ||
607 | } else { | ||
608 | cs->subtyp = SEDL_SPEED_CARD_WIN; | ||
609 | cs->hw.sedl.chip = SEDL_CHIP_TEST; | ||
610 | } | ||
611 | goto ready; | ||
612 | } else { | ||
613 | printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); | ||
614 | return(0); | ||
615 | } | ||
616 | } | ||
617 | ipid++; | ||
618 | pnp_c = NULL; | ||
619 | } | ||
620 | if (!ipid->card_vendor) { | ||
621 | printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n"); | ||
622 | } | ||
623 | } | ||
624 | #endif | ||
625 | /* Probe for Sedlbauer speed pci */ | ||
626 | #ifdef CONFIG_PCI | ||
627 | if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, | ||
628 | PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) { | ||
629 | if (pci_enable_device(dev_sedl)) | ||
630 | return(0); | ||
631 | cs->irq = dev_sedl->irq; | ||
632 | if (!cs->irq) { | ||
633 | printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n"); | ||
634 | return(0); | ||
635 | } | ||
636 | cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0); | ||
637 | } else { | ||
638 | printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); | ||
639 | return(0); | ||
640 | } | ||
641 | cs->irq_flags |= IRQF_SHARED; | ||
642 | cs->hw.sedl.bus = SEDL_BUS_PCI; | ||
643 | sub_vendor_id = dev_sedl->subsystem_vendor; | ||
644 | sub_id = dev_sedl->subsystem_device; | ||
645 | printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n", | ||
646 | sub_vendor_id, sub_id); | ||
647 | printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n", | ||
648 | cs->hw.sedl.cfg_reg); | ||
649 | if (sub_id != PCI_SUB_ID_SEDLBAUER) { | ||
650 | printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id); | ||
651 | return(0); | ||
652 | } | ||
653 | if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) { | ||
654 | cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; | ||
655 | cs->subtyp = SEDL_SPEEDFAX_PYRAMID; | ||
656 | } else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) { | ||
657 | cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; | ||
658 | cs->subtyp = SEDL_SPEEDFAX_PCI; | ||
659 | } else if (sub_vendor_id == PCI_SUBVENDOR_HST_SAPHIR3) { | ||
660 | cs->hw.sedl.chip = SEDL_CHIP_IPAC; | ||
661 | cs->subtyp = HST_SAPHIR3; | ||
662 | } else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) { | ||
663 | cs->hw.sedl.chip = SEDL_CHIP_IPAC; | ||
664 | cs->subtyp = SEDL_SPEED_PCI; | ||
665 | } else { | ||
666 | printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n", | ||
667 | sub_vendor_id); | ||
668 | return(0); | ||
669 | } | ||
670 | bytecnt = 256; | 724 | bytecnt = 256; |
671 | cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON; | ||
672 | cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF; | ||
673 | byteout(cs->hw.sedl.cfg_reg, 0xff); | ||
674 | byteout(cs->hw.sedl.cfg_reg, 0x00); | ||
675 | byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd); | ||
676 | byteout(cs->hw.sedl.cfg_reg+ 5, 0); /* disable all IRQ */ | ||
677 | byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on); | ||
678 | mdelay(2); | ||
679 | byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); | ||
680 | mdelay(10); | ||
681 | #else | ||
682 | printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n"); | ||
683 | return (0); | ||
684 | #endif /* CONFIG_PCI */ | ||
685 | } | 725 | } |
686 | 726 | ||
687 | #ifdef __ISAPNP__ | ||
688 | ready: | 727 | ready: |
689 | #endif | ||
690 | 728 | ||
691 | /* In case of the sedlbauer pcmcia card, this region is in use, | 729 | /* In case of the sedlbauer pcmcia card, this region is in use, |
692 | * reserved for us by the card manager. So we do not check it | 730 | * reserved for us by the card manager. So we do not check it |
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index d09f6d033f15..4393003ae162 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c | |||
@@ -295,11 +295,12 @@ setup_telespci(struct IsdnCard *card) | |||
295 | #ifdef __BIG_ENDIAN | 295 | #ifdef __BIG_ENDIAN |
296 | #error "not running on big endian machines now" | 296 | #error "not running on big endian machines now" |
297 | #endif | 297 | #endif |
298 | |||
298 | strcpy(tmp, telespci_revision); | 299 | strcpy(tmp, telespci_revision); |
299 | printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); | 300 | printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); |
300 | if (cs->typ != ISDN_CTYPE_TELESPCI) | 301 | if (cs->typ != ISDN_CTYPE_TELESPCI) |
301 | return (0); | 302 | return (0); |
302 | #ifdef CONFIG_PCI | 303 | |
303 | if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) { | 304 | if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) { |
304 | if (pci_enable_device(dev_tel)) | 305 | if (pci_enable_device(dev_tel)) |
305 | return(0); | 306 | return(0); |
@@ -317,11 +318,6 @@ setup_telespci(struct IsdnCard *card) | |||
317 | printk(KERN_WARNING "TelesPCI: No PCI card found\n"); | 318 | printk(KERN_WARNING "TelesPCI: No PCI card found\n"); |
318 | return(0); | 319 | return(0); |
319 | } | 320 | } |
320 | #else | ||
321 | printk(KERN_WARNING "HiSax: Teles/PCI and NO_PCI_BIOS\n"); | ||
322 | printk(KERN_WARNING "HiSax: Teles/PCI unable to config\n"); | ||
323 | return (0); | ||
324 | #endif /* CONFIG_PCI */ | ||
325 | 321 | ||
326 | /* Initialize Zoran PCI controller */ | 322 | /* Initialize Zoran PCI controller */ |
327 | writel(0x00000000, cs->hw.teles0.membase + 0x28); | 323 | writel(0x00000000, cs->hw.teles0.membase + 0x28); |
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c index 3aeceaf9769e..39129b94f8be 100644 --- a/drivers/isdn/hisax/w6692.c +++ b/drivers/isdn/hisax/w6692.c | |||
@@ -1009,7 +1009,7 @@ setup_w6692(struct IsdnCard *card) | |||
1009 | printk(KERN_INFO "HiSax: W6692 driver Rev. %s\n", HiSax_getrev(tmp)); | 1009 | printk(KERN_INFO "HiSax: W6692 driver Rev. %s\n", HiSax_getrev(tmp)); |
1010 | if (cs->typ != ISDN_CTYPE_W6692) | 1010 | if (cs->typ != ISDN_CTYPE_W6692) |
1011 | return (0); | 1011 | return (0); |
1012 | #ifdef CONFIG_PCI | 1012 | |
1013 | while (id_list[id_idx].vendor_id) { | 1013 | while (id_list[id_idx].vendor_id) { |
1014 | dev_w6692 = pci_find_device(id_list[id_idx].vendor_id, | 1014 | dev_w6692 = pci_find_device(id_list[id_idx].vendor_id, |
1015 | id_list[id_idx].device_id, | 1015 | id_list[id_idx].device_id, |
@@ -1061,11 +1061,6 @@ setup_w6692(struct IsdnCard *card) | |||
1061 | cs->hw.w6692.iobase + 255); | 1061 | cs->hw.w6692.iobase + 255); |
1062 | return (0); | 1062 | return (0); |
1063 | } | 1063 | } |
1064 | #else | ||
1065 | printk(KERN_WARNING "HiSax: W6692 and NO_PCI_BIOS\n"); | ||
1066 | printk(KERN_WARNING "HiSax: W6692 unable to config\n"); | ||
1067 | return (0); | ||
1068 | #endif /* CONFIG_PCI */ | ||
1069 | 1064 | ||
1070 | printk(KERN_INFO | 1065 | printk(KERN_INFO |
1071 | "HiSax: %s config irq:%d I/O:%x\n", | 1066 | "HiSax: %s config irq:%d I/O:%x\n", |
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c index 9e01748a176e..b7cc5c2f08c6 100644 --- a/drivers/isdn/hysdn/hysdn_init.c +++ b/drivers/isdn/hysdn/hysdn_init.c | |||
@@ -20,10 +20,15 @@ | |||
20 | #include "hysdn_defs.h" | 20 | #include "hysdn_defs.h" |
21 | 21 | ||
22 | static struct pci_device_id hysdn_pci_tbl[] = { | 22 | static struct pci_device_id hysdn_pci_tbl[] = { |
23 | {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO}, | 23 | { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, |
24 | {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2}, | 24 | PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO, 0, 0, BD_METRO }, |
25 | {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO}, | 25 | { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, |
26 | {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO}, | 26 | PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2, 0, 0, BD_CHAMP2 }, |
27 | { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, | ||
28 | PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO, 0, 0, BD_ERGO }, | ||
29 | { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, | ||
30 | PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO, 0, 0, BD_ERGO }, | ||
31 | |||
27 | { } /* Terminating entry */ | 32 | { } /* Terminating entry */ |
28 | }; | 33 | }; |
29 | MODULE_DEVICE_TABLE(pci, hysdn_pci_tbl); | 34 | MODULE_DEVICE_TABLE(pci, hysdn_pci_tbl); |
@@ -34,128 +39,7 @@ MODULE_LICENSE("GPL"); | |||
34 | static char *hysdn_init_revision = "$Revision: 1.6.6.6 $"; | 39 | static char *hysdn_init_revision = "$Revision: 1.6.6.6 $"; |
35 | static int cardmax; /* number of found cards */ | 40 | static int cardmax; /* number of found cards */ |
36 | hysdn_card *card_root = NULL; /* pointer to first card */ | 41 | hysdn_card *card_root = NULL; /* pointer to first card */ |
37 | 42 | static hysdn_card *card_last = NULL; /* pointer to first card */ | |
38 | /**********************************************/ | ||
39 | /* table assigning PCI-sub ids to board types */ | ||
40 | /* the last entry contains all 0 */ | ||
41 | /**********************************************/ | ||
42 | static struct { | ||
43 | unsigned short subid; /* PCI sub id */ | ||
44 | unsigned char cardtyp; /* card type assigned */ | ||
45 | } pci_subid_map[] = { | ||
46 | |||
47 | { | ||
48 | PCI_SUBDEVICE_ID_HYPERCOPE_METRO, BD_METRO | ||
49 | }, | ||
50 | { | ||
51 | PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2, BD_CHAMP2 | ||
52 | }, | ||
53 | { | ||
54 | PCI_SUBDEVICE_ID_HYPERCOPE_ERGO, BD_ERGO | ||
55 | }, | ||
56 | { | ||
57 | PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO, BD_ERGO | ||
58 | }, | ||
59 | { | ||
60 | 0, 0 | ||
61 | } /* terminating entry */ | ||
62 | }; | ||
63 | |||
64 | |||
65 | /*********************************************************************/ | ||
66 | /* search_cards searches for available cards in the pci config data. */ | ||
67 | /* If a card is found, the card structure is allocated and the cards */ | ||
68 | /* ressources are reserved. cardmax is incremented. */ | ||
69 | /*********************************************************************/ | ||
70 | static void | ||
71 | search_cards(void) | ||
72 | { | ||
73 | struct pci_dev *akt_pcidev = NULL; | ||
74 | hysdn_card *card, *card_last; | ||
75 | int i; | ||
76 | |||
77 | card_root = NULL; | ||
78 | card_last = NULL; | ||
79 | while ((akt_pcidev = pci_find_device(PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, | ||
80 | akt_pcidev)) != NULL) { | ||
81 | if (pci_enable_device(akt_pcidev)) | ||
82 | continue; | ||
83 | |||
84 | if (!(card = kzalloc(sizeof(hysdn_card), GFP_KERNEL))) { | ||
85 | printk(KERN_ERR "HYSDN: unable to alloc device mem \n"); | ||
86 | return; | ||
87 | } | ||
88 | card->myid = cardmax; /* set own id */ | ||
89 | card->bus = akt_pcidev->bus->number; | ||
90 | card->devfn = akt_pcidev->devfn; /* slot + function */ | ||
91 | card->subsysid = akt_pcidev->subsystem_device; | ||
92 | card->irq = akt_pcidev->irq; | ||
93 | card->iobase = pci_resource_start(akt_pcidev, PCI_REG_PLX_IO_BASE); | ||
94 | card->plxbase = pci_resource_start(akt_pcidev, PCI_REG_PLX_MEM_BASE); | ||
95 | card->membase = pci_resource_start(akt_pcidev, PCI_REG_MEMORY_BASE); | ||
96 | card->brdtype = BD_NONE; /* unknown */ | ||
97 | card->debug_flags = DEF_DEB_FLAGS; /* set default debug */ | ||
98 | card->faxchans = 0; /* default no fax channels */ | ||
99 | card->bchans = 2; /* and 2 b-channels */ | ||
100 | for (i = 0; pci_subid_map[i].subid; i++) | ||
101 | if (pci_subid_map[i].subid == card->subsysid) { | ||
102 | card->brdtype = pci_subid_map[i].cardtyp; | ||
103 | break; | ||
104 | } | ||
105 | if (card->brdtype != BD_NONE) { | ||
106 | if (ergo_inithardware(card)) { | ||
107 | printk(KERN_WARNING "HYSDN: card at io 0x%04x already in use\n", card->iobase); | ||
108 | kfree(card); | ||
109 | continue; | ||
110 | } | ||
111 | } else { | ||
112 | printk(KERN_WARNING "HYSDN: unknown card id 0x%04x\n", card->subsysid); | ||
113 | kfree(card); /* release mem */ | ||
114 | continue; | ||
115 | } | ||
116 | cardmax++; | ||
117 | card->next = NULL; /*end of chain */ | ||
118 | if (card_last) | ||
119 | card_last->next = card; /* pointer to next card */ | ||
120 | else | ||
121 | card_root = card; | ||
122 | card_last = card; /* new chain end */ | ||
123 | } /* device found */ | ||
124 | } /* search_cards */ | ||
125 | |||
126 | /************************************************************************************/ | ||
127 | /* free_resources frees the acquired PCI resources and returns the allocated memory */ | ||
128 | /************************************************************************************/ | ||
129 | static void | ||
130 | free_resources(void) | ||
131 | { | ||
132 | hysdn_card *card; | ||
133 | |||
134 | while (card_root) { | ||
135 | card = card_root; | ||
136 | if (card->releasehardware) | ||
137 | card->releasehardware(card); /* free all hardware resources */ | ||
138 | card_root = card_root->next; /* remove card from chain */ | ||
139 | kfree(card); /* return mem */ | ||
140 | |||
141 | } /* while card_root */ | ||
142 | } /* free_resources */ | ||
143 | |||
144 | /**************************************************************************/ | ||
145 | /* stop_cards disables (hardware resets) all cards and disables interrupt */ | ||
146 | /**************************************************************************/ | ||
147 | static void | ||
148 | stop_cards(void) | ||
149 | { | ||
150 | hysdn_card *card; | ||
151 | |||
152 | card = card_root; /* first in chain */ | ||
153 | while (card) { | ||
154 | if (card->stopcard) | ||
155 | card->stopcard(card); | ||
156 | card = card->next; /* remove card from chain */ | ||
157 | } /* while card */ | ||
158 | } /* stop_cards */ | ||
159 | 43 | ||
160 | 44 | ||
161 | /****************************************************************************/ | 45 | /****************************************************************************/ |
@@ -191,31 +75,138 @@ hysdn_getrev(const char *revision) | |||
191 | /* and the module is added to the list in /proc/modules, otherwise an error */ | 75 | /* and the module is added to the list in /proc/modules, otherwise an error */ |
192 | /* is assumed and the module will not be kept in memory. */ | 76 | /* is assumed and the module will not be kept in memory. */ |
193 | /****************************************************************************/ | 77 | /****************************************************************************/ |
78 | |||
79 | static int __devinit hysdn_pci_init_one(struct pci_dev *akt_pcidev, | ||
80 | const struct pci_device_id *ent) | ||
81 | { | ||
82 | hysdn_card *card; | ||
83 | int rc; | ||
84 | |||
85 | rc = pci_enable_device(akt_pcidev); | ||
86 | if (rc) | ||
87 | return rc; | ||
88 | |||
89 | if (!(card = kzalloc(sizeof(hysdn_card), GFP_KERNEL))) { | ||
90 | printk(KERN_ERR "HYSDN: unable to alloc device mem \n"); | ||
91 | rc = -ENOMEM; | ||
92 | goto err_out; | ||
93 | } | ||
94 | card->myid = cardmax; /* set own id */ | ||
95 | card->bus = akt_pcidev->bus->number; | ||
96 | card->devfn = akt_pcidev->devfn; /* slot + function */ | ||
97 | card->subsysid = akt_pcidev->subsystem_device; | ||
98 | card->irq = akt_pcidev->irq; | ||
99 | card->iobase = pci_resource_start(akt_pcidev, PCI_REG_PLX_IO_BASE); | ||
100 | card->plxbase = pci_resource_start(akt_pcidev, PCI_REG_PLX_MEM_BASE); | ||
101 | card->membase = pci_resource_start(akt_pcidev, PCI_REG_MEMORY_BASE); | ||
102 | card->brdtype = BD_NONE; /* unknown */ | ||
103 | card->debug_flags = DEF_DEB_FLAGS; /* set default debug */ | ||
104 | card->faxchans = 0; /* default no fax channels */ | ||
105 | card->bchans = 2; /* and 2 b-channels */ | ||
106 | card->brdtype = ent->driver_data; | ||
107 | |||
108 | if (ergo_inithardware(card)) { | ||
109 | printk(KERN_WARNING "HYSDN: card at io 0x%04x already in use\n", card->iobase); | ||
110 | rc = -EBUSY; | ||
111 | goto err_out_card; | ||
112 | } | ||
113 | |||
114 | cardmax++; | ||
115 | card->next = NULL; /*end of chain */ | ||
116 | if (card_last) | ||
117 | card_last->next = card; /* pointer to next card */ | ||
118 | else | ||
119 | card_root = card; | ||
120 | card_last = card; /* new chain end */ | ||
121 | |||
122 | pci_set_drvdata(akt_pcidev, card); | ||
123 | return 0; | ||
124 | |||
125 | err_out_card: | ||
126 | kfree(card); | ||
127 | err_out: | ||
128 | pci_disable_device(akt_pcidev); | ||
129 | return rc; | ||
130 | } | ||
131 | |||
132 | static void __devexit hysdn_pci_remove_one(struct pci_dev *akt_pcidev) | ||
133 | { | ||
134 | hysdn_card *card = pci_get_drvdata(akt_pcidev); | ||
135 | |||
136 | pci_set_drvdata(akt_pcidev, NULL); | ||
137 | |||
138 | if (card->stopcard) | ||
139 | card->stopcard(card); | ||
140 | |||
141 | #ifdef CONFIG_HYSDN_CAPI | ||
142 | hycapi_capi_release(card); | ||
143 | #endif | ||
144 | |||
145 | if (card->releasehardware) | ||
146 | card->releasehardware(card); /* free all hardware resources */ | ||
147 | |||
148 | if (card == card_root) { | ||
149 | card_root = card_root->next; | ||
150 | if (!card_root) | ||
151 | card_last = NULL; | ||
152 | } else { | ||
153 | hysdn_card *tmp = card_root; | ||
154 | while (tmp) { | ||
155 | if (tmp->next == card) | ||
156 | tmp->next = card->next; | ||
157 | card_last = tmp; | ||
158 | tmp = tmp->next; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | kfree(card); | ||
163 | pci_disable_device(akt_pcidev); | ||
164 | } | ||
165 | |||
166 | static struct pci_driver hysdn_pci_driver = { | ||
167 | .name = "hysdn", | ||
168 | .id_table = hysdn_pci_tbl, | ||
169 | .probe = hysdn_pci_init_one, | ||
170 | .remove = __devexit_p(hysdn_pci_remove_one), | ||
171 | }; | ||
172 | |||
173 | static int hysdn_have_procfs; | ||
174 | |||
194 | static int __init | 175 | static int __init |
195 | hysdn_init(void) | 176 | hysdn_init(void) |
196 | { | 177 | { |
197 | char tmp[50]; | 178 | char tmp[50]; |
179 | int rc; | ||
198 | 180 | ||
199 | strcpy(tmp, hysdn_init_revision); | 181 | strcpy(tmp, hysdn_init_revision); |
200 | printk(KERN_NOTICE "HYSDN: module Rev: %s loaded\n", hysdn_getrev(tmp)); | 182 | printk(KERN_NOTICE "HYSDN: module Rev: %s loaded\n", hysdn_getrev(tmp)); |
201 | strcpy(tmp, hysdn_net_revision); | 183 | strcpy(tmp, hysdn_net_revision); |
202 | printk(KERN_NOTICE "HYSDN: network interface Rev: %s \n", hysdn_getrev(tmp)); | 184 | printk(KERN_NOTICE "HYSDN: network interface Rev: %s \n", hysdn_getrev(tmp)); |
203 | search_cards(); | 185 | |
186 | rc = pci_register_driver(&hysdn_pci_driver); | ||
187 | if (rc) | ||
188 | return rc; | ||
189 | |||
204 | printk(KERN_INFO "HYSDN: %d card(s) found.\n", cardmax); | 190 | printk(KERN_INFO "HYSDN: %d card(s) found.\n", cardmax); |
205 | 191 | ||
206 | if (hysdn_procconf_init()) { | 192 | if (!hysdn_procconf_init()) |
207 | free_resources(); /* proc file_sys not created */ | 193 | hysdn_have_procfs = 1; |
208 | return (-1); | 194 | |
209 | } | ||
210 | #ifdef CONFIG_HYSDN_CAPI | 195 | #ifdef CONFIG_HYSDN_CAPI |
211 | if(cardmax > 0) { | 196 | if(cardmax > 0) { |
212 | if(hycapi_init()) { | 197 | if(hycapi_init()) { |
213 | printk(KERN_ERR "HYCAPI: init failed\n"); | 198 | printk(KERN_ERR "HYCAPI: init failed\n"); |
214 | return(-1); | 199 | |
200 | if (hysdn_have_procfs) | ||
201 | hysdn_procconf_release(); | ||
202 | |||
203 | pci_unregister_driver(&hysdn_pci_driver); | ||
204 | return -ESPIPE; | ||
215 | } | 205 | } |
216 | } | 206 | } |
217 | #endif /* CONFIG_HYSDN_CAPI */ | 207 | #endif /* CONFIG_HYSDN_CAPI */ |
218 | return (0); /* no error */ | 208 | |
209 | return 0; /* no error */ | ||
219 | } /* init_module */ | 210 | } /* init_module */ |
220 | 211 | ||
221 | 212 | ||
@@ -230,20 +221,15 @@ hysdn_init(void) | |||
230 | static void __exit | 221 | static void __exit |
231 | hysdn_exit(void) | 222 | hysdn_exit(void) |
232 | { | 223 | { |
224 | if (hysdn_have_procfs) | ||
225 | hysdn_procconf_release(); | ||
226 | |||
227 | pci_unregister_driver(&hysdn_pci_driver); | ||
228 | |||
233 | #ifdef CONFIG_HYSDN_CAPI | 229 | #ifdef CONFIG_HYSDN_CAPI |
234 | hysdn_card *card; | ||
235 | #endif /* CONFIG_HYSDN_CAPI */ | ||
236 | stop_cards(); | ||
237 | #ifdef CONFIG_HYSDN_CAPI | ||
238 | card = card_root; /* first in chain */ | ||
239 | while (card) { | ||
240 | hycapi_capi_release(card); | ||
241 | card = card->next; /* remove card from chain */ | ||
242 | } /* while card */ | ||
243 | hycapi_cleanup(); | 230 | hycapi_cleanup(); |
244 | #endif /* CONFIG_HYSDN_CAPI */ | 231 | #endif /* CONFIG_HYSDN_CAPI */ |
245 | hysdn_procconf_release(); | 232 | |
246 | free_resources(); | ||
247 | printk(KERN_NOTICE "HYSDN: module unloaded\n"); | 233 | printk(KERN_NOTICE "HYSDN: module unloaded\n"); |
248 | } /* cleanup_module */ | 234 | } /* cleanup_module */ |
249 | 235 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index e8f102ea9b03..acf1b81b47cb 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -3076,8 +3076,7 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) | |||
3076 | mddev->gendisk = disk; | 3076 | mddev->gendisk = disk; |
3077 | mutex_unlock(&disks_mutex); | 3077 | mutex_unlock(&disks_mutex); |
3078 | mddev->kobj.parent = &disk->kobj; | 3078 | mddev->kobj.parent = &disk->kobj; |
3079 | mddev->kobj.k_name = NULL; | 3079 | kobject_set_name(&mddev->kobj, "%s", "md"); |
3080 | snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md"); | ||
3081 | mddev->kobj.ktype = &md_ktype; | 3080 | mddev->kobj.ktype = &md_ktype; |
3082 | if (kobject_register(&mddev->kobj)) | 3081 | if (kobject_register(&mddev->kobj)) |
3083 | printk(KERN_WARNING "md: cannot register %s/md - name in use\n", | 3082 | printk(KERN_WARNING "md: cannot register %s/md - name in use\n", |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 56231d8edc07..18738faecbbc 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -103,10 +103,7 @@ static struct file_operations dvb_device_fops = | |||
103 | .open = dvb_device_open, | 103 | .open = dvb_device_open, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static struct cdev dvb_device_cdev = { | 106 | static struct cdev dvb_device_cdev; |
107 | .kobj = {.name = "dvb", }, | ||
108 | .owner = THIS_MODULE, | ||
109 | }; | ||
110 | 107 | ||
111 | int dvb_generic_open(struct inode *inode, struct file *file) | 108 | int dvb_generic_open(struct inode *inode, struct file *file) |
112 | { | 109 | { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 7a78d6b34738..2ee3c3049e8f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | |||
@@ -905,8 +905,8 @@ struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp, | |||
905 | } | 905 | } |
906 | 906 | ||
907 | 907 | ||
908 | static int pvr2_sysfs_hotplug(struct device *cd,char **envp, | 908 | static int pvr2_sysfs_hotplug(struct device *d, |
909 | int numenvp,char *buf,int size) | 909 | struct kobj_uevent_env *env) |
910 | { | 910 | { |
911 | /* Even though we don't do anything here, we still need this function | 911 | /* Even though we don't do anything here, we still need this function |
912 | because sysfs will still try to call it. */ | 912 | because sysfs will still try to call it. */ |
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index d195fb088f4a..8f77949f93dd 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c | |||
@@ -57,16 +57,11 @@ static int tifm_bus_match(struct device *dev, struct device_driver *drv) | |||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
59 | 59 | ||
60 | static int tifm_uevent(struct device *dev, char **envp, int num_envp, | 60 | static int tifm_uevent(struct device *dev, struct kobj_uevent_env *env) |
61 | char *buffer, int buffer_size) | ||
62 | { | 61 | { |
63 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); | 62 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); |
64 | int i = 0; | ||
65 | int length = 0; | ||
66 | 63 | ||
67 | if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | 64 | if (add_uevent_var(env, "TIFM_CARD_TYPE=%s", tifm_media_type_name(sock->type, 1))) |
68 | "TIFM_CARD_TYPE=%s", | ||
69 | tifm_media_type_name(sock->type, 1))) | ||
70 | return -ENOMEM; | 65 | return -ENOMEM; |
71 | 66 | ||
72 | return 0; | 67 | return 0; |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 8d6f6014870f..b0c22cad9423 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -58,12 +58,11 @@ static int mmc_bus_match(struct device *dev, struct device_driver *drv) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | static int | 60 | static int |
61 | mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, | 61 | mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) |
62 | int buf_size) | ||
63 | { | 62 | { |
64 | struct mmc_card *card = dev_to_mmc_card(dev); | 63 | struct mmc_card *card = dev_to_mmc_card(dev); |
65 | const char *type; | 64 | const char *type; |
66 | int i = 0, length = 0; | 65 | int retval = 0; |
67 | 66 | ||
68 | switch (card->type) { | 67 | switch (card->type) { |
69 | case MMC_TYPE_MMC: | 68 | case MMC_TYPE_MMC: |
@@ -80,20 +79,14 @@ mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, | |||
80 | } | 79 | } |
81 | 80 | ||
82 | if (type) { | 81 | if (type) { |
83 | if (add_uevent_var(envp, num_envp, &i, | 82 | retval = add_uevent_var(env, "MMC_TYPE=%s", type); |
84 | buf, buf_size, &length, | 83 | if (retval) |
85 | "MMC_TYPE=%s", type)) | 84 | return retval; |
86 | return -ENOMEM; | ||
87 | } | 85 | } |
88 | 86 | ||
89 | if (add_uevent_var(envp, num_envp, &i, | 87 | retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card)); |
90 | buf, buf_size, &length, | ||
91 | "MMC_NAME=%s", mmc_card_name(card))) | ||
92 | return -ENOMEM; | ||
93 | 88 | ||
94 | envp[i] = NULL; | 89 | return retval; |
95 | |||
96 | return 0; | ||
97 | } | 90 | } |
98 | 91 | ||
99 | static int mmc_bus_probe(struct device *dev) | 92 | static int mmc_bus_probe(struct device *dev) |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 64fbc9759a30..c65d203a846d 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -143,7 +143,7 @@ void mmc_remove_host(struct mmc_host *host) | |||
143 | 143 | ||
144 | device_del(&host->class_dev); | 144 | device_del(&host->class_dev); |
145 | 145 | ||
146 | led_trigger_unregister(host->led); | 146 | led_trigger_unregister_simple(host->led); |
147 | 147 | ||
148 | spin_lock(&mmc_host_lock); | 148 | spin_lock(&mmc_host_lock); |
149 | idr_remove(&mmc_host_idr, host->index); | 149 | idr_remove(&mmc_host_idr, host->index); |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d68accea380b..78ed633ceb82 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -2652,10 +2652,10 @@ static int bnx2_poll_work(struct bnx2 *bp, int work_done, int budget) | |||
2652 | REG_RD(bp, BNX2_HC_COMMAND); | 2652 | REG_RD(bp, BNX2_HC_COMMAND); |
2653 | } | 2653 | } |
2654 | 2654 | ||
2655 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons) | 2655 | if (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons) |
2656 | bnx2_tx_int(bp); | 2656 | bnx2_tx_int(bp); |
2657 | 2657 | ||
2658 | if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) | 2658 | if (sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) |
2659 | work_done += bnx2_rx_int(bp, budget - work_done); | 2659 | work_done += bnx2_rx_int(bp, budget - work_done); |
2660 | 2660 | ||
2661 | return work_done; | 2661 | return work_done; |
@@ -2665,6 +2665,7 @@ static int bnx2_poll(struct napi_struct *napi, int budget) | |||
2665 | { | 2665 | { |
2666 | struct bnx2 *bp = container_of(napi, struct bnx2, napi); | 2666 | struct bnx2 *bp = container_of(napi, struct bnx2, napi); |
2667 | int work_done = 0; | 2667 | int work_done = 0; |
2668 | struct status_block *sblk = bp->status_blk; | ||
2668 | 2669 | ||
2669 | while (1) { | 2670 | while (1) { |
2670 | work_done = bnx2_poll_work(bp, work_done, budget); | 2671 | work_done = bnx2_poll_work(bp, work_done, budget); |
@@ -2672,16 +2673,19 @@ static int bnx2_poll(struct napi_struct *napi, int budget) | |||
2672 | if (unlikely(work_done >= budget)) | 2673 | if (unlikely(work_done >= budget)) |
2673 | break; | 2674 | break; |
2674 | 2675 | ||
2676 | /* bp->last_status_idx is used below to tell the hw how | ||
2677 | * much work has been processed, so we must read it before | ||
2678 | * checking for more work. | ||
2679 | */ | ||
2680 | bp->last_status_idx = sblk->status_idx; | ||
2681 | rmb(); | ||
2675 | if (likely(!bnx2_has_work(bp))) { | 2682 | if (likely(!bnx2_has_work(bp))) { |
2676 | bp->last_status_idx = bp->status_blk->status_idx; | ||
2677 | rmb(); | ||
2678 | |||
2679 | netif_rx_complete(bp->dev, napi); | 2683 | netif_rx_complete(bp->dev, napi); |
2680 | if (likely(bp->flags & USING_MSI_FLAG)) { | 2684 | if (likely(bp->flags & USING_MSI_FLAG)) { |
2681 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 2685 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
2682 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | 2686 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | |
2683 | bp->last_status_idx); | 2687 | bp->last_status_idx); |
2684 | return 0; | 2688 | break; |
2685 | } | 2689 | } |
2686 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 2690 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
2687 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | 2691 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 4ac161e1ca12..7d7758f3ad8c 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -1183,7 +1183,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ | |||
1183 | pool_count[i], pool_size[i], | 1183 | pool_count[i], pool_size[i], |
1184 | pool_active[i]); | 1184 | pool_active[i]); |
1185 | kobj->parent = &dev->dev.kobj; | 1185 | kobj->parent = &dev->dev.kobj; |
1186 | sprintf(kobj->name, "pool%d", i); | 1186 | kobject_set_name(kobj, "pool%d", i); |
1187 | kobj->ktype = &ktype_veth_pool; | 1187 | kobj->ktype = &ktype_veth_pool; |
1188 | kobject_register(kobj); | 1188 | kobject_register(kobj); |
1189 | } | 1189 | } |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e795c33b982d..30b1cca8144c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -3576,7 +3576,7 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, int budget) | |||
3576 | if (sblk->idx[0].tx_consumer != tp->tx_cons) { | 3576 | if (sblk->idx[0].tx_consumer != tp->tx_cons) { |
3577 | tg3_tx(tp); | 3577 | tg3_tx(tp); |
3578 | if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING)) | 3578 | if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING)) |
3579 | return 0; | 3579 | return work_done; |
3580 | } | 3580 | } |
3581 | 3581 | ||
3582 | /* run RX thread, within the bounds set by NAPI. | 3582 | /* run RX thread, within the bounds set by NAPI. |
@@ -3593,6 +3593,7 @@ static int tg3_poll(struct napi_struct *napi, int budget) | |||
3593 | { | 3593 | { |
3594 | struct tg3 *tp = container_of(napi, struct tg3, napi); | 3594 | struct tg3 *tp = container_of(napi, struct tg3, napi); |
3595 | int work_done = 0; | 3595 | int work_done = 0; |
3596 | struct tg3_hw_status *sblk = tp->hw_status; | ||
3596 | 3597 | ||
3597 | while (1) { | 3598 | while (1) { |
3598 | work_done = tg3_poll_work(tp, work_done, budget); | 3599 | work_done = tg3_poll_work(tp, work_done, budget); |
@@ -3603,15 +3604,17 @@ static int tg3_poll(struct napi_struct *napi, int budget) | |||
3603 | if (unlikely(work_done >= budget)) | 3604 | if (unlikely(work_done >= budget)) |
3604 | break; | 3605 | break; |
3605 | 3606 | ||
3606 | if (likely(!tg3_has_work(tp))) { | 3607 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) { |
3607 | struct tg3_hw_status *sblk = tp->hw_status; | 3608 | /* tp->last_tag is used in tg3_restart_ints() below |
3608 | 3609 | * to tell the hw how much work has been processed, | |
3609 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) { | 3610 | * so we must read it before checking for more work. |
3610 | tp->last_tag = sblk->status_tag; | 3611 | */ |
3611 | rmb(); | 3612 | tp->last_tag = sblk->status_tag; |
3612 | } else | 3613 | rmb(); |
3613 | sblk->status &= ~SD_STATUS_UPDATED; | 3614 | } else |
3615 | sblk->status &= ~SD_STATUS_UPDATED; | ||
3614 | 3616 | ||
3617 | if (likely(!tg3_has_work(tp))) { | ||
3615 | netif_rx_complete(tp->dev, napi); | 3618 | netif_rx_complete(tp->dev, napi); |
3616 | tg3_restart_ints(tp); | 3619 | tg3_restart_ints(tp); |
3617 | break; | 3620 | break; |
@@ -3621,9 +3624,10 @@ static int tg3_poll(struct napi_struct *napi, int budget) | |||
3621 | return work_done; | 3624 | return work_done; |
3622 | 3625 | ||
3623 | tx_recovery: | 3626 | tx_recovery: |
3627 | /* work_done is guaranteed to be less than budget. */ | ||
3624 | netif_rx_complete(tp->dev, napi); | 3628 | netif_rx_complete(tp->dev, napi); |
3625 | schedule_work(&tp->reset_task); | 3629 | schedule_work(&tp->reset_task); |
3626 | return 0; | 3630 | return work_done; |
3627 | } | 3631 | } |
3628 | 3632 | ||
3629 | static void tg3_irq_quiesce(struct tg3 *tp) | 3633 | static void tg3_irq_quiesce(struct tg3 *tp) |
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c index 1c97e7dd130b..2b5352a7dffc 100644 --- a/drivers/pci/hotplug.c +++ b/drivers/pci/hotplug.c | |||
@@ -3,12 +3,9 @@ | |||
3 | #include <linux/module.h> | 3 | #include <linux/module.h> |
4 | #include "pci.h" | 4 | #include "pci.h" |
5 | 5 | ||
6 | int pci_uevent(struct device *dev, char **envp, int num_envp, | 6 | int pci_uevent(struct device *dev, struct kobj_uevent_env *env) |
7 | char *buffer, int buffer_size) | ||
8 | { | 7 | { |
9 | struct pci_dev *pdev; | 8 | struct pci_dev *pdev; |
10 | int i = 0; | ||
11 | int length = 0; | ||
12 | 9 | ||
13 | if (!dev) | 10 | if (!dev) |
14 | return -ENODEV; | 11 | return -ENODEV; |
@@ -17,37 +14,24 @@ int pci_uevent(struct device *dev, char **envp, int num_envp, | |||
17 | if (!pdev) | 14 | if (!pdev) |
18 | return -ENODEV; | 15 | return -ENODEV; |
19 | 16 | ||
20 | if (add_uevent_var(envp, num_envp, &i, | 17 | if (add_uevent_var(env, "PCI_CLASS=%04X", pdev->class)) |
21 | buffer, buffer_size, &length, | ||
22 | "PCI_CLASS=%04X", pdev->class)) | ||
23 | return -ENOMEM; | 18 | return -ENOMEM; |
24 | 19 | ||
25 | if (add_uevent_var(envp, num_envp, &i, | 20 | if (add_uevent_var(env, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device)) |
26 | buffer, buffer_size, &length, | ||
27 | "PCI_ID=%04X:%04X", pdev->vendor, pdev->device)) | ||
28 | return -ENOMEM; | 21 | return -ENOMEM; |
29 | 22 | ||
30 | if (add_uevent_var(envp, num_envp, &i, | 23 | if (add_uevent_var(env, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, |
31 | buffer, buffer_size, &length, | ||
32 | "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, | ||
33 | pdev->subsystem_device)) | 24 | pdev->subsystem_device)) |
34 | return -ENOMEM; | 25 | return -ENOMEM; |
35 | 26 | ||
36 | if (add_uevent_var(envp, num_envp, &i, | 27 | if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev))) |
37 | buffer, buffer_size, &length, | ||
38 | "PCI_SLOT_NAME=%s", pci_name(pdev))) | ||
39 | return -ENOMEM; | 28 | return -ENOMEM; |
40 | 29 | ||
41 | if (add_uevent_var(envp, num_envp, &i, | 30 | if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x", |
42 | buffer, buffer_size, &length, | ||
43 | "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x", | ||
44 | pdev->vendor, pdev->device, | 31 | pdev->vendor, pdev->device, |
45 | pdev->subsystem_vendor, pdev->subsystem_device, | 32 | pdev->subsystem_vendor, pdev->subsystem_device, |
46 | (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), | 33 | (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), |
47 | (u8)(pdev->class))) | 34 | (u8)(pdev->class))) |
48 | return -ENOMEM; | 35 | return -ENOMEM; |
49 | |||
50 | envp[i] = NULL; | ||
51 | |||
52 | return 0; | 36 | return 0; |
53 | } | 37 | } |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index bd433ef6bfc6..f0eba534f805 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -694,66 +694,6 @@ int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot, | |||
694 | if ((slot == NULL) || (info == NULL)) | 694 | if ((slot == NULL) || (info == NULL)) |
695 | return -ENODEV; | 695 | return -ENODEV; |
696 | 696 | ||
697 | /* | ||
698 | * check all fields in the info structure, and update timestamps | ||
699 | * for the files referring to the fields that have now changed. | ||
700 | */ | ||
701 | if ((has_power_file(slot) == 0) && | ||
702 | (slot->info->power_status != info->power_status)) { | ||
703 | retval = sysfs_update_file(&slot->kobj, | ||
704 | &hotplug_slot_attr_power.attr); | ||
705 | if (retval) | ||
706 | return retval; | ||
707 | } | ||
708 | |||
709 | if ((has_attention_file(slot) == 0) && | ||
710 | (slot->info->attention_status != info->attention_status)) { | ||
711 | retval = sysfs_update_file(&slot->kobj, | ||
712 | &hotplug_slot_attr_attention.attr); | ||
713 | if (retval) | ||
714 | return retval; | ||
715 | } | ||
716 | |||
717 | if ((has_latch_file(slot) == 0) && | ||
718 | (slot->info->latch_status != info->latch_status)) { | ||
719 | retval = sysfs_update_file(&slot->kobj, | ||
720 | &hotplug_slot_attr_latch.attr); | ||
721 | if (retval) | ||
722 | return retval; | ||
723 | } | ||
724 | |||
725 | if ((has_adapter_file(slot) == 0) && | ||
726 | (slot->info->adapter_status != info->adapter_status)) { | ||
727 | retval = sysfs_update_file(&slot->kobj, | ||
728 | &hotplug_slot_attr_presence.attr); | ||
729 | if (retval) | ||
730 | return retval; | ||
731 | } | ||
732 | |||
733 | if ((has_address_file(slot) == 0) && | ||
734 | (slot->info->address != info->address)) { | ||
735 | retval = sysfs_update_file(&slot->kobj, | ||
736 | &hotplug_slot_attr_address.attr); | ||
737 | if (retval) | ||
738 | return retval; | ||
739 | } | ||
740 | |||
741 | if ((has_max_bus_speed_file(slot) == 0) && | ||
742 | (slot->info->max_bus_speed != info->max_bus_speed)) { | ||
743 | retval = sysfs_update_file(&slot->kobj, | ||
744 | &hotplug_slot_attr_max_bus_speed.attr); | ||
745 | if (retval) | ||
746 | return retval; | ||
747 | } | ||
748 | |||
749 | if ((has_cur_bus_speed_file(slot) == 0) && | ||
750 | (slot->info->cur_bus_speed != info->cur_bus_speed)) { | ||
751 | retval = sysfs_update_file(&slot->kobj, | ||
752 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
753 | if (retval) | ||
754 | return retval; | ||
755 | } | ||
756 | |||
757 | memcpy (slot->info, info, sizeof (struct hotplug_slot_info)); | 697 | memcpy (slot->info, info, sizeof (struct hotplug_slot_info)); |
758 | 698 | ||
759 | return 0; | 699 | return 0; |
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c index df076064a3e0..a080fedf0332 100644 --- a/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/drivers/pci/hotplug/rpadlpar_sysfs.c | |||
@@ -129,17 +129,17 @@ struct kobj_type ktype_dlpar_io = { | |||
129 | }; | 129 | }; |
130 | 130 | ||
131 | struct kset dlpar_io_kset = { | 131 | struct kset dlpar_io_kset = { |
132 | .kobj = {.name = DLPAR_KOBJ_NAME, | 132 | .kobj = {.ktype = &ktype_dlpar_io, |
133 | .ktype = &ktype_dlpar_io, | ||
134 | .parent = &pci_hotplug_slots_subsys.kobj}, | 133 | .parent = &pci_hotplug_slots_subsys.kobj}, |
135 | .ktype = &ktype_dlpar_io, | 134 | .ktype = &ktype_dlpar_io, |
136 | }; | 135 | }; |
137 | 136 | ||
138 | int dlpar_sysfs_init(void) | 137 | int dlpar_sysfs_init(void) |
139 | { | 138 | { |
139 | kobject_set_name(&dlpar_io_kset.kobj, DLPAR_KOBJ_NAME); | ||
140 | if (kset_register(&dlpar_io_kset)) { | 140 | if (kset_register(&dlpar_io_kset)) { |
141 | printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n", | 141 | printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n", |
142 | dlpar_io_kset.kobj.name); | 142 | kobject_name(&dlpar_io_kset.kobj)); |
143 | return -EINVAL; | 143 | return -EINVAL; |
144 | } | 144 | } |
145 | 145 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index c43ecedce673..6e2760b6c20a 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -531,8 +531,7 @@ void pci_dev_put(struct pci_dev *dev) | |||
531 | } | 531 | } |
532 | 532 | ||
533 | #ifndef CONFIG_HOTPLUG | 533 | #ifndef CONFIG_HOTPLUG |
534 | int pci_uevent(struct device *dev, char **envp, int num_envp, | 534 | int pci_uevent(struct device *dev, struct kobj_uevent_env *env) |
535 | char *buffer, int buffer_size) | ||
536 | { | 535 | { |
537 | return -ENODEV; | 536 | return -ENODEV; |
538 | } | 537 | } |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 5360d73d4941..6fda33de84e8 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -1,7 +1,6 @@ | |||
1 | /* Functions internal to the PCI core code */ | 1 | /* Functions internal to the PCI core code */ |
2 | 2 | ||
3 | extern int pci_uevent(struct device *dev, char **envp, int num_envp, | 3 | extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env); |
4 | char *buffer, int buffer_size); | ||
5 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); | 4 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); |
6 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); | 5 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); |
7 | extern void pci_cleanup_rom(struct pci_dev *dev); | 6 | extern void pci_cleanup_rom(struct pci_dev *dev); |
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c index 568f1877315c..05ca2ed9eb51 100644 --- a/drivers/pci/setup-irq.c +++ b/drivers/pci/setup-irq.c | |||
@@ -48,7 +48,7 @@ pdev_fixup_irq(struct pci_dev *dev, | |||
48 | dev->irq = irq; | 48 | dev->irq = irq; |
49 | 49 | ||
50 | pr_debug("PCI: fixup irq: (%s) got %d\n", | 50 | pr_debug("PCI: fixup irq: (%s) got %d\n", |
51 | dev->dev.kobj.name, dev->irq); | 51 | kobject_name(&dev->dev.kobj), dev->irq); |
52 | 52 | ||
53 | /* Always tell the device, so the driver knows what is | 53 | /* Always tell the device, so the driver knows what is |
54 | the real IRQ to use; the device does not use it. */ | 54 | the real IRQ to use; the device does not use it. */ |
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index f8b13f0270d7..a0aca46ce877 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
@@ -907,18 +907,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) | |||
907 | EXPORT_SYMBOL(pcmcia_insert_card); | 907 | EXPORT_SYMBOL(pcmcia_insert_card); |
908 | 908 | ||
909 | 909 | ||
910 | static int pcmcia_socket_uevent(struct device *dev, char **envp, | 910 | static int pcmcia_socket_uevent(struct device *dev, |
911 | int num_envp, char *buffer, int buffer_size) | 911 | struct kobj_uevent_env *env) |
912 | { | 912 | { |
913 | struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); | 913 | struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); |
914 | int i = 0, length = 0; | ||
915 | 914 | ||
916 | if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, | 915 | if (add_uevent_var(env, "SOCKET_NO=%u", s->sock)) |
917 | &length, "SOCKET_NO=%u", s->sock)) | ||
918 | return -ENOMEM; | 916 | return -ENOMEM; |
919 | 917 | ||
920 | envp[i] = NULL; | ||
921 | |||
922 | return 0; | 918 | return 0; |
923 | } | 919 | } |
924 | 920 | ||
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index a99607142fc8..55baa1f0fcbb 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -1064,11 +1064,10 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { | |||
1064 | 1064 | ||
1065 | #ifdef CONFIG_HOTPLUG | 1065 | #ifdef CONFIG_HOTPLUG |
1066 | 1066 | ||
1067 | static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, | 1067 | static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) |
1068 | char *buffer, int buffer_size) | ||
1069 | { | 1068 | { |
1070 | struct pcmcia_device *p_dev; | 1069 | struct pcmcia_device *p_dev; |
1071 | int i, length = 0; | 1070 | int i; |
1072 | u32 hash[4] = { 0, 0, 0, 0}; | 1071 | u32 hash[4] = { 0, 0, 0, 0}; |
1073 | 1072 | ||
1074 | if (!dev) | 1073 | if (!dev) |
@@ -1083,23 +1082,13 @@ static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, | |||
1083 | hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i])); | 1082 | hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i])); |
1084 | } | 1083 | } |
1085 | 1084 | ||
1086 | i = 0; | 1085 | if (add_uevent_var(env, "SOCKET_NO=%u", p_dev->socket->sock)) |
1087 | |||
1088 | if (add_uevent_var(envp, num_envp, &i, | ||
1089 | buffer, buffer_size, &length, | ||
1090 | "SOCKET_NO=%u", | ||
1091 | p_dev->socket->sock)) | ||
1092 | return -ENOMEM; | 1086 | return -ENOMEM; |
1093 | 1087 | ||
1094 | if (add_uevent_var(envp, num_envp, &i, | 1088 | if (add_uevent_var(env, "DEVICE_NO=%02X", p_dev->device_no)) |
1095 | buffer, buffer_size, &length, | ||
1096 | "DEVICE_NO=%02X", | ||
1097 | p_dev->device_no)) | ||
1098 | return -ENOMEM; | 1089 | return -ENOMEM; |
1099 | 1090 | ||
1100 | if (add_uevent_var(envp, num_envp, &i, | 1091 | if (add_uevent_var(env, "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X" |
1101 | buffer, buffer_size, &length, | ||
1102 | "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X" | ||
1103 | "pa%08Xpb%08Xpc%08Xpd%08X", | 1092 | "pa%08Xpb%08Xpc%08Xpd%08X", |
1104 | p_dev->has_manf_id ? p_dev->manf_id : 0, | 1093 | p_dev->has_manf_id ? p_dev->manf_id : 0, |
1105 | p_dev->has_card_id ? p_dev->card_id : 0, | 1094 | p_dev->has_card_id ? p_dev->card_id : 0, |
@@ -1112,15 +1101,12 @@ static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, | |||
1112 | hash[3])) | 1101 | hash[3])) |
1113 | return -ENOMEM; | 1102 | return -ENOMEM; |
1114 | 1103 | ||
1115 | envp[i] = NULL; | ||
1116 | |||
1117 | return 0; | 1104 | return 0; |
1118 | } | 1105 | } |
1119 | 1106 | ||
1120 | #else | 1107 | #else |
1121 | 1108 | ||
1122 | static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, | 1109 | static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) |
1123 | char *buffer, int buffer_size) | ||
1124 | { | 1110 | { |
1125 | return -ENODEV; | 1111 | return -ENODEV; |
1126 | } | 1112 | } |
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index 383107ba4bd3..f6722ba0dd1e 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c | |||
@@ -175,7 +175,6 @@ static int __init mst_pcmcia_init(void) | |||
175 | if (!mst_pcmcia_device) | 175 | if (!mst_pcmcia_device) |
176 | return -ENOMEM; | 176 | return -ENOMEM; |
177 | 177 | ||
178 | mst_pcmcia_device->dev.uevent_suppress = 0; | ||
179 | mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; | 178 | mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; |
180 | 179 | ||
181 | ret = platform_device_add(mst_pcmcia_device); | 180 | ret = platform_device_add(mst_pcmcia_device); |
@@ -195,3 +194,4 @@ fs_initcall(mst_pcmcia_init); | |||
195 | module_exit(mst_pcmcia_exit); | 194 | module_exit(mst_pcmcia_exit); |
196 | 195 | ||
197 | MODULE_LICENSE("GPL"); | 196 | MODULE_LICENSE("GPL"); |
197 | MODULE_ALIAS("platform:pxa2xx-pcmcia"); | ||
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index a2daa3f531b2..d5c33bd78d68 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c | |||
@@ -261,7 +261,6 @@ static int __init sharpsl_pcmcia_init(void) | |||
261 | if (!sharpsl_pcmcia_device) | 261 | if (!sharpsl_pcmcia_device) |
262 | return -ENOMEM; | 262 | return -ENOMEM; |
263 | 263 | ||
264 | sharpsl_pcmcia_device->dev.uevent_suppress = 0; | ||
265 | sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; | 264 | sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; |
266 | sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; | 265 | sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; |
267 | 266 | ||
@@ -284,3 +283,4 @@ module_exit(sharpsl_pcmcia_exit); | |||
284 | 283 | ||
285 | MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support"); | 284 | MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support"); |
286 | MODULE_LICENSE("GPL"); | 285 | MODULE_LICENSE("GPL"); |
286 | MODULE_ALIAS("platform:pxa2xx-pcmcia"); | ||
diff --git a/drivers/power/power_supply.h b/drivers/power/power_supply.h index a9880d468ee4..f38ba482be75 100644 --- a/drivers/power/power_supply.h +++ b/drivers/power/power_supply.h | |||
@@ -14,8 +14,7 @@ | |||
14 | 14 | ||
15 | extern int power_supply_create_attrs(struct power_supply *psy); | 15 | extern int power_supply_create_attrs(struct power_supply *psy); |
16 | extern void power_supply_remove_attrs(struct power_supply *psy); | 16 | extern void power_supply_remove_attrs(struct power_supply *psy); |
17 | extern int power_supply_uevent(struct device *dev, char **envp, int num_envp, | 17 | extern int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env); |
18 | char *buffer, int buffer_size); | ||
19 | 18 | ||
20 | #else | 19 | #else |
21 | 20 | ||
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index de3155b21285..249f61bae639 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c | |||
@@ -195,11 +195,10 @@ static char *kstruprdup(const char *str, gfp_t gfp) | |||
195 | return ret; | 195 | return ret; |
196 | } | 196 | } |
197 | 197 | ||
198 | int power_supply_uevent(struct device *dev, char **envp, int num_envp, | 198 | int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env) |
199 | char *buffer, int buffer_size) | ||
200 | { | 199 | { |
201 | struct power_supply *psy = dev_get_drvdata(dev); | 200 | struct power_supply *psy = dev_get_drvdata(dev); |
202 | int i = 0, length = 0, ret = 0, j; | 201 | int ret = 0, j; |
203 | char *prop_buf; | 202 | char *prop_buf; |
204 | char *attrname; | 203 | char *attrname; |
205 | 204 | ||
@@ -212,8 +211,7 @@ int power_supply_uevent(struct device *dev, char **envp, int num_envp, | |||
212 | 211 | ||
213 | dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name); | 212 | dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name); |
214 | 213 | ||
215 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, | 214 | ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->name); |
216 | &length, "POWER_SUPPLY_NAME=%s", psy->name); | ||
217 | if (ret) | 215 | if (ret) |
218 | return ret; | 216 | return ret; |
219 | 217 | ||
@@ -243,9 +241,7 @@ int power_supply_uevent(struct device *dev, char **envp, int num_envp, | |||
243 | 241 | ||
244 | dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf); | 242 | dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf); |
245 | 243 | ||
246 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, | 244 | ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf); |
247 | &length, "POWER_SUPPLY_%s=%s", | ||
248 | attrname, prop_buf); | ||
249 | kfree(attrname); | 245 | kfree(attrname); |
250 | if (ret) | 246 | if (ret) |
251 | goto out; | 247 | goto out; |
@@ -282,14 +278,11 @@ int power_supply_uevent(struct device *dev, char **envp, int num_envp, | |||
282 | 278 | ||
283 | dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf); | 279 | dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf); |
284 | 280 | ||
285 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, | 281 | ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf); |
286 | &length, "POWER_SUPPLY_%s=%s", | ||
287 | attrname, prop_buf); | ||
288 | kfree(attrname); | 282 | kfree(attrname); |
289 | if (ret) | 283 | if (ret) |
290 | goto out; | 284 | goto out; |
291 | } | 285 | } |
292 | envp[i] = NULL; | ||
293 | 286 | ||
294 | out: | 287 | out: |
295 | free_page((unsigned long)prop_buf); | 288 | free_page((unsigned long)prop_buf); |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index aeda52682446..d427daeef511 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/genhd.h> | 53 | #include <linux/genhd.h> |
54 | #include <linux/hdreg.h> | 54 | #include <linux/hdreg.h> |
55 | #include <linux/interrupt.h> | 55 | #include <linux/interrupt.h> |
56 | #include <linux/log2.h> | ||
56 | #include <asm/ccwdev.h> | 57 | #include <asm/ccwdev.h> |
57 | #include <linux/workqueue.h> | 58 | #include <linux/workqueue.h> |
58 | #include <asm/debug.h> | 59 | #include <asm/debug.h> |
@@ -456,7 +457,7 @@ dasd_free_chunk(struct list_head *chunk_list, void *mem) | |||
456 | static inline int | 457 | static inline int |
457 | dasd_check_blocksize(int bsize) | 458 | dasd_check_blocksize(int bsize) |
458 | { | 459 | { |
459 | if (bsize < 512 || bsize > 4096 || (bsize & (bsize - 1)) != 0) | 460 | if (bsize < 512 || bsize > 4096 || !is_power_of_2(bsize)) |
460 | return -EMEDIUMTYPE; | 461 | return -EMEDIUMTYPE; |
461 | return 0; | 462 | return 0; |
462 | } | 463 | } |
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 0fbacc8b1063..f231bc21b1ca 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c | |||
@@ -230,7 +230,7 @@ static int xpram_make_request(struct request_queue *q, struct bio *bio) | |||
230 | } | 230 | } |
231 | } | 231 | } |
232 | set_bit(BIO_UPTODATE, &bio->bi_flags); | 232 | set_bit(BIO_UPTODATE, &bio->bi_flags); |
233 | bio_end_io(bio, 0); | 233 | bio_endio(bio, 0); |
234 | return 0; | 234 | return 0; |
235 | fail: | 235 | fail: |
236 | bio_io_error(bio); | 236 | bio_io_error(bio); |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 6000bdee4082..0e1f35c9ed9d 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -667,6 +667,9 @@ raw3215_probe (struct ccw_device *cdev) | |||
667 | struct raw3215_info *raw; | 667 | struct raw3215_info *raw; |
668 | int line; | 668 | int line; |
669 | 669 | ||
670 | /* Console is special. */ | ||
671 | if (raw3215[0] && (cdev->dev.driver_data == raw3215[0])) | ||
672 | return 0; | ||
670 | raw = kmalloc(sizeof(struct raw3215_info) + | 673 | raw = kmalloc(sizeof(struct raw3215_info) + |
671 | RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA); | 674 | RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA); |
672 | if (raw == NULL) | 675 | if (raw == NULL) |
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index fd3479119eb4..0b040557db02 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/ebcdic.h> | 22 | #include <asm/ebcdic.h> |
23 | 23 | ||
24 | #include "raw3270.h" | 24 | #include "raw3270.h" |
25 | #include "tty3270.h" | ||
25 | #include "ctrlchar.h" | 26 | #include "ctrlchar.h" |
26 | 27 | ||
27 | #define CON3270_OUTPUT_BUFFER_SIZE 1024 | 28 | #define CON3270_OUTPUT_BUFFER_SIZE 1024 |
@@ -507,8 +508,6 @@ con3270_write(struct console *co, const char *str, unsigned int count) | |||
507 | spin_unlock_irqrestore(&cp->view.lock,flags); | 508 | spin_unlock_irqrestore(&cp->view.lock,flags); |
508 | } | 509 | } |
509 | 510 | ||
510 | extern struct tty_driver *tty3270_driver; | ||
511 | |||
512 | static struct tty_driver * | 511 | static struct tty_driver * |
513 | con3270_device(struct console *c, int *index) | 512 | con3270_device(struct console *c, int *index) |
514 | { | 513 | { |
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index fa62e6944057..25629b92dec3 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c | |||
@@ -93,6 +93,7 @@ static volatile enum sclp_mask_state_t { | |||
93 | #define SCLP_RETRY_INTERVAL 30 | 93 | #define SCLP_RETRY_INTERVAL 30 |
94 | 94 | ||
95 | static void sclp_process_queue(void); | 95 | static void sclp_process_queue(void); |
96 | static void __sclp_make_read_req(void); | ||
96 | static int sclp_init_mask(int calculate); | 97 | static int sclp_init_mask(int calculate); |
97 | static int sclp_init(void); | 98 | static int sclp_init(void); |
98 | 99 | ||
@@ -115,7 +116,6 @@ sclp_service_call(sclp_cmdw_t command, void *sccb) | |||
115 | return 0; | 116 | return 0; |
116 | } | 117 | } |
117 | 118 | ||
118 | static inline void __sclp_make_read_req(void); | ||
119 | 119 | ||
120 | static void | 120 | static void |
121 | __sclp_queue_read_req(void) | 121 | __sclp_queue_read_req(void) |
@@ -318,8 +318,7 @@ sclp_read_cb(struct sclp_req *req, void *data) | |||
318 | } | 318 | } |
319 | 319 | ||
320 | /* Prepare read event data request. Called while sclp_lock is locked. */ | 320 | /* Prepare read event data request. Called while sclp_lock is locked. */ |
321 | static inline void | 321 | static void __sclp_make_read_req(void) |
322 | __sclp_make_read_req(void) | ||
323 | { | 322 | { |
324 | struct sccb_header *sccb; | 323 | struct sccb_header *sccb; |
325 | 324 | ||
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 9f244c591eeb..da25f8e24152 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -708,16 +708,22 @@ static void tape_3590_med_state_set(struct tape_device *device, | |||
708 | 708 | ||
709 | c_info = &TAPE_3590_CRYPT_INFO(device); | 709 | c_info = &TAPE_3590_CRYPT_INFO(device); |
710 | 710 | ||
711 | if (sense->masst == MSENSE_UNASSOCIATED) { | 711 | DBF_EVENT(6, "medium state: %x:%x\n", sense->macst, sense->masst); |
712 | switch (sense->macst) { | ||
713 | case 0x04: | ||
714 | case 0x05: | ||
715 | case 0x06: | ||
712 | tape_med_state_set(device, MS_UNLOADED); | 716 | tape_med_state_set(device, MS_UNLOADED); |
713 | TAPE_3590_CRYPT_INFO(device).medium_status = 0; | 717 | TAPE_3590_CRYPT_INFO(device).medium_status = 0; |
714 | return; | 718 | return; |
715 | } | 719 | case 0x08: |
716 | if (sense->masst != MSENSE_ASSOCIATED_MOUNT) { | 720 | case 0x09: |
717 | PRINT_ERR("Unknown medium state: %x\n", sense->masst); | 721 | tape_med_state_set(device, MS_LOADED); |
722 | break; | ||
723 | default: | ||
724 | tape_med_state_set(device, MS_UNKNOWN); | ||
718 | return; | 725 | return; |
719 | } | 726 | } |
720 | tape_med_state_set(device, MS_LOADED); | ||
721 | c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK; | 727 | c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK; |
722 | if (sense->flags & MSENSE_CRYPT_MASK) { | 728 | if (sense->flags & MSENSE_CRYPT_MASK) { |
723 | PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags); | 729 | PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags); |
@@ -835,15 +841,17 @@ tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb) | |||
835 | /* Probably result of halt ssch */ | 841 | /* Probably result of halt ssch */ |
836 | return TAPE_IO_PENDING; | 842 | return TAPE_IO_PENDING; |
837 | else if (irb->scsw.dstat == 0x85) | 843 | else if (irb->scsw.dstat == 0x85) |
838 | /* Device Ready -> check medium state */ | 844 | /* Device Ready */ |
839 | tape_3590_schedule_work(device, TO_MSEN); | 845 | DBF_EVENT(3, "unsol.irq! tape ready: %08x\n", device->cdev_id); |
840 | else if (irb->scsw.dstat & DEV_STAT_ATTENTION) | 846 | else if (irb->scsw.dstat & DEV_STAT_ATTENTION) { |
841 | tape_3590_schedule_work(device, TO_READ_ATTMSG); | 847 | tape_3590_schedule_work(device, TO_READ_ATTMSG); |
842 | else { | 848 | } else { |
843 | DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id); | 849 | DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id); |
844 | PRINT_WARN("Unsolicited IRQ (Device End) caught.\n"); | 850 | PRINT_WARN("Unsolicited IRQ (Device End) caught.\n"); |
845 | tape_dump_sense(device, NULL, irb); | 851 | tape_dump_sense(device, NULL, irb); |
846 | } | 852 | } |
853 | /* check medium state */ | ||
854 | tape_3590_schedule_work(device, TO_MSEN); | ||
847 | return TAPE_IO_SUCCESS; | 855 | return TAPE_IO_SUCCESS; |
848 | } | 856 | } |
849 | 857 | ||
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index bc33068b9ce2..70b1980a08b6 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
@@ -25,8 +25,8 @@ | |||
25 | #include <asm/ebcdic.h> | 25 | #include <asm/ebcdic.h> |
26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
27 | 27 | ||
28 | |||
29 | #include "raw3270.h" | 28 | #include "raw3270.h" |
29 | #include "tty3270.h" | ||
30 | #include "keyboard.h" | 30 | #include "keyboard.h" |
31 | 31 | ||
32 | #define TTY3270_CHAR_BUF_SIZE 256 | 32 | #define TTY3270_CHAR_BUF_SIZE 256 |
@@ -1338,8 +1338,11 @@ tty3270_getpar(struct tty3270 *tp, int ix) | |||
1338 | static void | 1338 | static void |
1339 | tty3270_goto_xy(struct tty3270 *tp, int cx, int cy) | 1339 | tty3270_goto_xy(struct tty3270 *tp, int cx, int cy) |
1340 | { | 1340 | { |
1341 | tp->cx = min_t(int, tp->view.cols - 1, max_t(int, 0, cx)); | 1341 | int max_cx = max(0, cx); |
1342 | cy = min_t(int, tp->view.rows - 3, max_t(int, 0, cy)); | 1342 | int max_cy = max(0, cy); |
1343 | |||
1344 | tp->cx = min_t(int, tp->view.cols - 1, max_cx); | ||
1345 | cy = min_t(int, tp->view.rows - 3, max_cy); | ||
1343 | if (cy != tp->cy) { | 1346 | if (cy != tp->cy) { |
1344 | tty3270_convert_line(tp, tp->cy); | 1347 | tty3270_convert_line(tp, tp->cy); |
1345 | tp->cy = cy; | 1348 | tp->cy = cy; |
diff --git a/drivers/s390/char/tty3270.h b/drivers/s390/char/tty3270.h new file mode 100644 index 000000000000..799da57f0390 --- /dev/null +++ b/drivers/s390/char/tty3270.h | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * drivers/s390/char/tty3270.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef __DRIVERS_S390_CHAR_TTY3270_H | ||
9 | #define __DRIVERS_S390_CHAR_TTY3270_H | ||
10 | |||
11 | #include <linux/tty.h> | ||
12 | #include <linux/tty_driver.h> | ||
13 | |||
14 | extern struct tty_driver *tty3270_driver; | ||
15 | |||
16 | #endif /* __DRIVERS_S390_CHAR_TTY3270_H */ | ||
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index 680b9b58b80e..6f40facb1c4d 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c | |||
@@ -66,8 +66,8 @@ static int __diag288(enum vmwdt_func func, unsigned int timeout, | |||
66 | "0: la %0,0\n" | 66 | "0: la %0,0\n" |
67 | "1:\n" | 67 | "1:\n" |
68 | EX_TABLE(0b,1b) | 68 | EX_TABLE(0b,1b) |
69 | : "=d" (err) : "d"(__func), "d"(__timeout), | 69 | : "+d" (err) : "d"(__func), "d"(__timeout), |
70 | "d"(__cmdp), "d"(__cmdl), "0" (-EINVAL) : "1", "cc"); | 70 | "d"(__cmdp), "d"(__cmdl) : "1", "cc"); |
71 | return err; | 71 | return err; |
72 | } | 72 | } |
73 | 73 | ||
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 3712ede16723..7073daf77981 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c | |||
@@ -141,15 +141,16 @@ static int memcpy_real(void *dest, unsigned long src, size_t count) | |||
141 | 141 | ||
142 | if (count == 0) | 142 | if (count == 0) |
143 | return 0; | 143 | return 0; |
144 | flags = __raw_local_irq_stnsm(0xf8); /* switch to real mode */ | 144 | flags = __raw_local_irq_stnsm(0xf8UL); /* switch to real mode */ |
145 | asm volatile ( | 145 | asm volatile ( |
146 | "0: mvcle %1,%2,0x0\n" | 146 | "0: mvcle %1,%2,0x0\n" |
147 | "1: jo 0b\n" | 147 | "1: jo 0b\n" |
148 | " lhi %0,0x0\n" | 148 | " lhi %0,0x0\n" |
149 | "2:\n" | 149 | "2:\n" |
150 | EX_TABLE(1b,2b) | 150 | EX_TABLE(1b,2b) |
151 | : "+d" (rc) | 151 | : "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1), |
152 | : "d" (_dest), "d" (_src), "d" (_len1), "d" (_len2) | 152 | "+d" (_len2), "=m" (*((long*)dest)) |
153 | : "m" (*((long*)src)) | ||
153 | : "cc", "memory"); | 154 | : "cc", "memory"); |
154 | __raw_local_irq_ssm(flags); | 155 | __raw_local_irq_ssm(flags); |
155 | 156 | ||
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index b0a18f5176aa..5baa517c3b66 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -44,8 +44,7 @@ ccwgroup_bus_match (struct device * dev, struct device_driver * drv) | |||
44 | return 0; | 44 | return 0; |
45 | } | 45 | } |
46 | static int | 46 | static int |
47 | ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer, | 47 | ccwgroup_uevent (struct device *dev, struct kobj_uevent_env *env) |
48 | int buffer_size) | ||
49 | { | 48 | { |
50 | /* TODO */ | 49 | /* TODO */ |
51 | return 0; | 50 | return 0; |
@@ -152,16 +151,24 @@ __ccwgroup_create_symlinks(struct ccwgroup_device *gdev) | |||
152 | return 0; | 151 | return 0; |
153 | } | 152 | } |
154 | 153 | ||
155 | /* | 154 | /** |
156 | * try to add a new ccwgroup device for one driver | 155 | * ccwgroup_create() - create and register a ccw group device |
157 | * argc and argv[] are a list of bus_id's of devices | 156 | * @root: parent device for the new device |
158 | * belonging to the driver. | 157 | * @creator_id: identifier of creating driver |
158 | * @cdrv: ccw driver of slave devices | ||
159 | * @argc: number of slave devices | ||
160 | * @argv: bus ids of slave devices | ||
161 | * | ||
162 | * Create and register a new ccw group device as a child of @root. Slave | ||
163 | * devices are obtained from the list of bus ids given in @argv[] and must all | ||
164 | * belong to @cdrv. | ||
165 | * Returns: | ||
166 | * %0 on success and an error code on failure. | ||
167 | * Context: | ||
168 | * non-atomic | ||
159 | */ | 169 | */ |
160 | int | 170 | int ccwgroup_create(struct device *root, unsigned int creator_id, |
161 | ccwgroup_create(struct device *root, | 171 | struct ccw_driver *cdrv, int argc, char *argv[]) |
162 | unsigned int creator_id, | ||
163 | struct ccw_driver *cdrv, | ||
164 | int argc, char *argv[]) | ||
165 | { | 172 | { |
166 | struct ccwgroup_device *gdev; | 173 | struct ccwgroup_device *gdev; |
167 | int i; | 174 | int i; |
@@ -390,8 +397,13 @@ static struct bus_type ccwgroup_bus_type = { | |||
390 | .remove = ccwgroup_remove, | 397 | .remove = ccwgroup_remove, |
391 | }; | 398 | }; |
392 | 399 | ||
393 | int | 400 | /** |
394 | ccwgroup_driver_register (struct ccwgroup_driver *cdriver) | 401 | * ccwgroup_driver_register() - register a ccw group driver |
402 | * @cdriver: driver to be registered | ||
403 | * | ||
404 | * This function is mainly a wrapper around driver_register(). | ||
405 | */ | ||
406 | int ccwgroup_driver_register(struct ccwgroup_driver *cdriver) | ||
395 | { | 407 | { |
396 | /* register our new driver with the core */ | 408 | /* register our new driver with the core */ |
397 | cdriver->driver.bus = &ccwgroup_bus_type; | 409 | cdriver->driver.bus = &ccwgroup_bus_type; |
@@ -406,8 +418,13 @@ __ccwgroup_match_all(struct device *dev, void *data) | |||
406 | return 1; | 418 | return 1; |
407 | } | 419 | } |
408 | 420 | ||
409 | void | 421 | /** |
410 | ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) | 422 | * ccwgroup_driver_unregister() - deregister a ccw group driver |
423 | * @cdriver: driver to be deregistered | ||
424 | * | ||
425 | * This function is mainly a wrapper around driver_unregister(). | ||
426 | */ | ||
427 | void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) | ||
411 | { | 428 | { |
412 | struct device *dev; | 429 | struct device *dev; |
413 | 430 | ||
@@ -427,8 +444,16 @@ ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) | |||
427 | driver_unregister(&cdriver->driver); | 444 | driver_unregister(&cdriver->driver); |
428 | } | 445 | } |
429 | 446 | ||
430 | int | 447 | /** |
431 | ccwgroup_probe_ccwdev(struct ccw_device *cdev) | 448 | * ccwgroup_probe_ccwdev() - probe function for slave devices |
449 | * @cdev: ccw device to be probed | ||
450 | * | ||
451 | * This is a dummy probe function for ccw devices that are slave devices in | ||
452 | * a ccw group device. | ||
453 | * Returns: | ||
454 | * always %0 | ||
455 | */ | ||
456 | int ccwgroup_probe_ccwdev(struct ccw_device *cdev) | ||
432 | { | 457 | { |
433 | return 0; | 458 | return 0; |
434 | } | 459 | } |
@@ -452,8 +477,15 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev) | |||
452 | return NULL; | 477 | return NULL; |
453 | } | 478 | } |
454 | 479 | ||
455 | void | 480 | /** |
456 | ccwgroup_remove_ccwdev(struct ccw_device *cdev) | 481 | * ccwgroup_remove_ccwdev() - remove function for slave devices |
482 | * @cdev: ccw device to be removed | ||
483 | * | ||
484 | * This is a remove function for ccw devices that are slave devices in a ccw | ||
485 | * group device. It sets the ccw device offline and also deregisters the | ||
486 | * embedding ccw group device. | ||
487 | */ | ||
488 | void ccwgroup_remove_ccwdev(struct ccw_device *cdev) | ||
457 | { | 489 | { |
458 | struct ccwgroup_device *gdev; | 490 | struct ccwgroup_device *gdev; |
459 | 491 | ||
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 920dd71e6434..42c1f4659adb 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/jiffies.h> | 14 | #include <linux/jiffies.h> |
15 | #include <linux/wait.h> | 15 | #include <linux/wait.h> |
16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
17 | #include <asm/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <asm/chpid.h> | 18 | #include <asm/chpid.h> |
19 | #include <asm/sclp.h> | 19 | #include <asm/sclp.h> |
20 | 20 | ||
@@ -55,7 +55,7 @@ static wait_queue_head_t cfg_wait_queue; | |||
55 | /* Return channel_path struct for given chpid. */ | 55 | /* Return channel_path struct for given chpid. */ |
56 | static inline struct channel_path *chpid_to_chp(struct chp_id chpid) | 56 | static inline struct channel_path *chpid_to_chp(struct chp_id chpid) |
57 | { | 57 | { |
58 | return css[chpid.cssid]->chps[chpid.id]; | 58 | return channel_subsystems[chpid.cssid]->chps[chpid.id]; |
59 | } | 59 | } |
60 | 60 | ||
61 | /* Set vary state for given chpid. */ | 61 | /* Set vary state for given chpid. */ |
@@ -86,7 +86,7 @@ u8 chp_get_sch_opm(struct subchannel *sch) | |||
86 | 86 | ||
87 | opm = 0; | 87 | opm = 0; |
88 | chp_id_init(&chpid); | 88 | chp_id_init(&chpid); |
89 | for (i=0; i < 8; i++) { | 89 | for (i = 0; i < 8; i++) { |
90 | opm <<= 1; | 90 | opm <<= 1; |
91 | chpid.id = sch->schib.pmcw.chpid[i]; | 91 | chpid.id = sch->schib.pmcw.chpid[i]; |
92 | if (chp_get_status(chpid) != 0) | 92 | if (chp_get_status(chpid) != 0) |
@@ -118,7 +118,7 @@ static int s390_vary_chpid(struct chp_id chpid, int on) | |||
118 | 118 | ||
119 | sprintf(dbf_text, on?"varyon%x.%02x":"varyoff%x.%02x", chpid.cssid, | 119 | sprintf(dbf_text, on?"varyon%x.%02x":"varyoff%x.%02x", chpid.cssid, |
120 | chpid.id); | 120 | chpid.id); |
121 | CIO_TRACE_EVENT( 2, dbf_text); | 121 | CIO_TRACE_EVENT(2, dbf_text); |
122 | 122 | ||
123 | status = chp_get_status(chpid); | 123 | status = chp_get_status(chpid); |
124 | if (!on && !status) { | 124 | if (!on && !status) { |
@@ -140,9 +140,11 @@ static ssize_t chp_measurement_chars_read(struct kobject *kobj, | |||
140 | char *buf, loff_t off, size_t count) | 140 | char *buf, loff_t off, size_t count) |
141 | { | 141 | { |
142 | struct channel_path *chp; | 142 | struct channel_path *chp; |
143 | struct device *device; | ||
143 | unsigned int size; | 144 | unsigned int size; |
144 | 145 | ||
145 | chp = to_channelpath(container_of(kobj, struct device, kobj)); | 146 | device = container_of(kobj, struct device, kobj); |
147 | chp = to_channelpath(device); | ||
146 | if (!chp->cmg_chars) | 148 | if (!chp->cmg_chars) |
147 | return 0; | 149 | return 0; |
148 | 150 | ||
@@ -193,9 +195,11 @@ static ssize_t chp_measurement_read(struct kobject *kobj, | |||
193 | { | 195 | { |
194 | struct channel_path *chp; | 196 | struct channel_path *chp; |
195 | struct channel_subsystem *css; | 197 | struct channel_subsystem *css; |
198 | struct device *device; | ||
196 | unsigned int size; | 199 | unsigned int size; |
197 | 200 | ||
198 | chp = to_channelpath(container_of(kobj, struct device, kobj)); | 201 | device = container_of(kobj, struct device, kobj); |
202 | chp = to_channelpath(device); | ||
199 | css = to_css(chp->dev.parent); | 203 | css = to_css(chp->dev.parent); |
200 | 204 | ||
201 | size = sizeof(struct cmg_entry); | 205 | size = sizeof(struct cmg_entry); |
@@ -353,7 +357,7 @@ static ssize_t chp_shared_show(struct device *dev, | |||
353 | 357 | ||
354 | static DEVICE_ATTR(shared, 0444, chp_shared_show, NULL); | 358 | static DEVICE_ATTR(shared, 0444, chp_shared_show, NULL); |
355 | 359 | ||
356 | static struct attribute * chp_attrs[] = { | 360 | static struct attribute *chp_attrs[] = { |
357 | &dev_attr_status.attr, | 361 | &dev_attr_status.attr, |
358 | &dev_attr_configure.attr, | 362 | &dev_attr_configure.attr, |
359 | &dev_attr_type.attr, | 363 | &dev_attr_type.attr, |
@@ -395,7 +399,7 @@ int chp_new(struct chp_id chpid) | |||
395 | /* fill in status, etc. */ | 399 | /* fill in status, etc. */ |
396 | chp->chpid = chpid; | 400 | chp->chpid = chpid; |
397 | chp->state = 1; | 401 | chp->state = 1; |
398 | chp->dev.parent = &css[chpid.cssid]->device; | 402 | chp->dev.parent = &channel_subsystems[chpid.cssid]->device; |
399 | chp->dev.release = chp_release; | 403 | chp->dev.release = chp_release; |
400 | snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp%x.%02x", chpid.cssid, | 404 | snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp%x.%02x", chpid.cssid, |
401 | chpid.id); | 405 | chpid.id); |
@@ -430,18 +434,18 @@ int chp_new(struct chp_id chpid) | |||
430 | device_unregister(&chp->dev); | 434 | device_unregister(&chp->dev); |
431 | goto out_free; | 435 | goto out_free; |
432 | } | 436 | } |
433 | mutex_lock(&css[chpid.cssid]->mutex); | 437 | mutex_lock(&channel_subsystems[chpid.cssid]->mutex); |
434 | if (css[chpid.cssid]->cm_enabled) { | 438 | if (channel_subsystems[chpid.cssid]->cm_enabled) { |
435 | ret = chp_add_cmg_attr(chp); | 439 | ret = chp_add_cmg_attr(chp); |
436 | if (ret) { | 440 | if (ret) { |
437 | sysfs_remove_group(&chp->dev.kobj, &chp_attr_group); | 441 | sysfs_remove_group(&chp->dev.kobj, &chp_attr_group); |
438 | device_unregister(&chp->dev); | 442 | device_unregister(&chp->dev); |
439 | mutex_unlock(&css[chpid.cssid]->mutex); | 443 | mutex_unlock(&channel_subsystems[chpid.cssid]->mutex); |
440 | goto out_free; | 444 | goto out_free; |
441 | } | 445 | } |
442 | } | 446 | } |
443 | css[chpid.cssid]->chps[chpid.id] = chp; | 447 | channel_subsystems[chpid.cssid]->chps[chpid.id] = chp; |
444 | mutex_unlock(&css[chpid.cssid]->mutex); | 448 | mutex_unlock(&channel_subsystems[chpid.cssid]->mutex); |
445 | return ret; | 449 | return ret; |
446 | out_free: | 450 | out_free: |
447 | kfree(chp); | 451 | kfree(chp); |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index f2708d65be5a..46905345159e 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -619,6 +619,11 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | |||
619 | sch->schib.pmcw.ena = 0; | 619 | sch->schib.pmcw.ena = 0; |
620 | if ((sch->lpm & (sch->lpm - 1)) != 0) | 620 | if ((sch->lpm & (sch->lpm - 1)) != 0) |
621 | sch->schib.pmcw.mp = 1; /* multipath mode */ | 621 | sch->schib.pmcw.mp = 1; /* multipath mode */ |
622 | /* clean up possible residual cmf stuff */ | ||
623 | sch->schib.pmcw.mme = 0; | ||
624 | sch->schib.pmcw.mbfc = 0; | ||
625 | sch->schib.pmcw.mbi = 0; | ||
626 | sch->schib.mba = 0; | ||
622 | return 0; | 627 | return 0; |
623 | out: | 628 | out: |
624 | if (!cio_is_console(schid)) | 629 | if (!cio_is_console(schid)) |
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 34a796913b06..b960f66843e4 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c | |||
@@ -45,7 +45,8 @@ | |||
45 | #include "ioasm.h" | 45 | #include "ioasm.h" |
46 | #include "chsc.h" | 46 | #include "chsc.h" |
47 | 47 | ||
48 | /* parameter to enable cmf during boot, possible uses are: | 48 | /* |
49 | * parameter to enable cmf during boot, possible uses are: | ||
49 | * "s390cmf" -- enable cmf and allocate 2 MB of ram so measuring can be | 50 | * "s390cmf" -- enable cmf and allocate 2 MB of ram so measuring can be |
50 | * used on any subchannel | 51 | * used on any subchannel |
51 | * "s390cmf=<num>" -- enable cmf and allocate enough memory to measure | 52 | * "s390cmf=<num>" -- enable cmf and allocate enough memory to measure |
@@ -73,18 +74,20 @@ enum cmb_index { | |||
73 | * enum cmb_format - types of supported measurement block formats | 74 | * enum cmb_format - types of supported measurement block formats |
74 | * | 75 | * |
75 | * @CMF_BASIC: traditional channel measurement blocks supported | 76 | * @CMF_BASIC: traditional channel measurement blocks supported |
76 | * by all machines that we run on | 77 | * by all machines that we run on |
77 | * @CMF_EXTENDED: improved format that was introduced with the z990 | 78 | * @CMF_EXTENDED: improved format that was introduced with the z990 |
78 | * machine | 79 | * machine |
79 | * @CMF_AUTODETECT: default: use extended format when running on a z990 | 80 | * @CMF_AUTODETECT: default: use extended format when running on a machine |
80 | * or later machine, otherwise fall back to basic format | 81 | * supporting extended format, otherwise fall back to |
81 | **/ | 82 | * basic format |
83 | */ | ||
82 | enum cmb_format { | 84 | enum cmb_format { |
83 | CMF_BASIC, | 85 | CMF_BASIC, |
84 | CMF_EXTENDED, | 86 | CMF_EXTENDED, |
85 | CMF_AUTODETECT = -1, | 87 | CMF_AUTODETECT = -1, |
86 | }; | 88 | }; |
87 | /** | 89 | |
90 | /* | ||
88 | * format - actual format for all measurement blocks | 91 | * format - actual format for all measurement blocks |
89 | * | 92 | * |
90 | * The format module parameter can be set to a value of 0 (zero) | 93 | * The format module parameter can be set to a value of 0 (zero) |
@@ -105,20 +108,21 @@ module_param(format, bool, 0444); | |||
105 | * either with the help of a special pool or with kmalloc | 108 | * either with the help of a special pool or with kmalloc |
106 | * @free: free memory allocated with @alloc | 109 | * @free: free memory allocated with @alloc |
107 | * @set: enable or disable measurement | 110 | * @set: enable or disable measurement |
111 | * @read: read a measurement entry at an index | ||
108 | * @readall: read a measurement block in a common format | 112 | * @readall: read a measurement block in a common format |
109 | * @reset: clear the data in the associated measurement block and | 113 | * @reset: clear the data in the associated measurement block and |
110 | * reset its time stamp | 114 | * reset its time stamp |
111 | * @align: align an allocated block so that the hardware can use it | 115 | * @align: align an allocated block so that the hardware can use it |
112 | */ | 116 | */ |
113 | struct cmb_operations { | 117 | struct cmb_operations { |
114 | int (*alloc) (struct ccw_device*); | 118 | int (*alloc) (struct ccw_device *); |
115 | void(*free) (struct ccw_device*); | 119 | void (*free) (struct ccw_device *); |
116 | int (*set) (struct ccw_device*, u32); | 120 | int (*set) (struct ccw_device *, u32); |
117 | u64 (*read) (struct ccw_device*, int); | 121 | u64 (*read) (struct ccw_device *, int); |
118 | int (*readall)(struct ccw_device*, struct cmbdata *); | 122 | int (*readall)(struct ccw_device *, struct cmbdata *); |
119 | void (*reset) (struct ccw_device*); | 123 | void (*reset) (struct ccw_device *); |
120 | void * (*align) (void *); | 124 | void *(*align) (void *); |
121 | 125 | /* private: */ | |
122 | struct attribute_group *attr_group; | 126 | struct attribute_group *attr_group; |
123 | }; | 127 | }; |
124 | static struct cmb_operations *cmbops; | 128 | static struct cmb_operations *cmbops; |
@@ -130,9 +134,11 @@ struct cmb_data { | |||
130 | unsigned long long last_update; /* when last_block was updated */ | 134 | unsigned long long last_update; /* when last_block was updated */ |
131 | }; | 135 | }; |
132 | 136 | ||
133 | /* our user interface is designed in terms of nanoseconds, | 137 | /* |
138 | * Our user interface is designed in terms of nanoseconds, | ||
134 | * while the hardware measures total times in its own | 139 | * while the hardware measures total times in its own |
135 | * unit.*/ | 140 | * unit. |
141 | */ | ||
136 | static inline u64 time_to_nsec(u32 value) | 142 | static inline u64 time_to_nsec(u32 value) |
137 | { | 143 | { |
138 | return ((u64)value) * 128000ull; | 144 | return ((u64)value) * 128000ull; |
@@ -159,12 +165,13 @@ static inline u64 time_to_avg_nsec(u32 value, u32 count) | |||
159 | return ret; | 165 | return ret; |
160 | } | 166 | } |
161 | 167 | ||
162 | /* activate or deactivate the channel monitor. When area is NULL, | 168 | /* |
169 | * Activate or deactivate the channel monitor. When area is NULL, | ||
163 | * the monitor is deactivated. The channel monitor needs to | 170 | * the monitor is deactivated. The channel monitor needs to |
164 | * be active in order to measure subchannels, which also need | 171 | * be active in order to measure subchannels, which also need |
165 | * to be enabled. */ | 172 | * to be enabled. |
166 | static inline void | 173 | */ |
167 | cmf_activate(void *area, unsigned int onoff) | 174 | static inline void cmf_activate(void *area, unsigned int onoff) |
168 | { | 175 | { |
169 | register void * __gpr2 asm("2"); | 176 | register void * __gpr2 asm("2"); |
170 | register long __gpr1 asm("1"); | 177 | register long __gpr1 asm("1"); |
@@ -175,8 +182,8 @@ cmf_activate(void *area, unsigned int onoff) | |||
175 | asm("schm" : : "d" (__gpr2), "d" (__gpr1) ); | 182 | asm("schm" : : "d" (__gpr2), "d" (__gpr1) ); |
176 | } | 183 | } |
177 | 184 | ||
178 | static int | 185 | static int set_schib(struct ccw_device *cdev, u32 mme, int mbfc, |
179 | set_schib(struct ccw_device *cdev, u32 mme, int mbfc, unsigned long address) | 186 | unsigned long address) |
180 | { | 187 | { |
181 | int ret; | 188 | int ret; |
182 | int retry; | 189 | int retry; |
@@ -466,6 +473,7 @@ static void cmf_generic_reset(struct ccw_device *cdev) | |||
466 | * | 473 | * |
467 | * @mem: pointer to CMBs (only in basic measurement mode) | 474 | * @mem: pointer to CMBs (only in basic measurement mode) |
468 | * @list: contains a linked list of all subchannels | 475 | * @list: contains a linked list of all subchannels |
476 | * @num_channels: number of channels to be measured | ||
469 | * @lock: protect concurrent access to @mem and @list | 477 | * @lock: protect concurrent access to @mem and @list |
470 | */ | 478 | */ |
471 | struct cmb_area { | 479 | struct cmb_area { |
@@ -481,28 +489,36 @@ static struct cmb_area cmb_area = { | |||
481 | .num_channels = 1024, | 489 | .num_channels = 1024, |
482 | }; | 490 | }; |
483 | 491 | ||
484 | |||
485 | /* ****** old style CMB handling ********/ | 492 | /* ****** old style CMB handling ********/ |
486 | 493 | ||
487 | /** int maxchannels | 494 | /* |
488 | * | ||
489 | * Basic channel measurement blocks are allocated in one contiguous | 495 | * Basic channel measurement blocks are allocated in one contiguous |
490 | * block of memory, which can not be moved as long as any channel | 496 | * block of memory, which can not be moved as long as any channel |
491 | * is active. Therefore, a maximum number of subchannels needs to | 497 | * is active. Therefore, a maximum number of subchannels needs to |
492 | * be defined somewhere. This is a module parameter, defaulting to | 498 | * be defined somewhere. This is a module parameter, defaulting to |
493 | * a resonable value of 1024, or 32 kb of memory. | 499 | * a resonable value of 1024, or 32 kb of memory. |
494 | * Current kernels don't allow kmalloc with more than 128kb, so the | 500 | * Current kernels don't allow kmalloc with more than 128kb, so the |
495 | * maximum is 4096 | 501 | * maximum is 4096. |
496 | */ | 502 | */ |
497 | 503 | ||
498 | module_param_named(maxchannels, cmb_area.num_channels, uint, 0444); | 504 | module_param_named(maxchannels, cmb_area.num_channels, uint, 0444); |
499 | 505 | ||
500 | /** | 506 | /** |
501 | * struct cmb - basic channel measurement block | 507 | * struct cmb - basic channel measurement block |
508 | * @ssch_rsch_count: number of ssch and rsch | ||
509 | * @sample_count: number of samples | ||
510 | * @device_connect_time: time of device connect | ||
511 | * @function_pending_time: time of function pending | ||
512 | * @device_disconnect_time: time of device disconnect | ||
513 | * @control_unit_queuing_time: time of control unit queuing | ||
514 | * @device_active_only_time: time of device active only | ||
515 | * @reserved: unused in basic measurement mode | ||
516 | * | ||
517 | * The measurement block as used by the hardware. The fields are described | ||
518 | * further in z/Architecture Principles of Operation, chapter 17. | ||
502 | * | 519 | * |
503 | * cmb as used by the hardware the fields are described in z/Architecture | 520 | * The cmb area made up from these blocks must be a contiguous array and may |
504 | * Principles of Operation, chapter 17. | 521 | * not be reallocated or freed. |
505 | * The area to be a contiguous array and may not be reallocated or freed. | ||
506 | * Only one cmb area can be present in the system. | 522 | * Only one cmb area can be present in the system. |
507 | */ | 523 | */ |
508 | struct cmb { | 524 | struct cmb { |
@@ -516,8 +532,9 @@ struct cmb { | |||
516 | u32 reserved[2]; | 532 | u32 reserved[2]; |
517 | }; | 533 | }; |
518 | 534 | ||
519 | /* insert a single device into the cmb_area list | 535 | /* |
520 | * called with cmb_area.lock held from alloc_cmb | 536 | * Insert a single device into the cmb_area list. |
537 | * Called with cmb_area.lock held from alloc_cmb. | ||
521 | */ | 538 | */ |
522 | static int alloc_cmb_single(struct ccw_device *cdev, | 539 | static int alloc_cmb_single(struct ccw_device *cdev, |
523 | struct cmb_data *cmb_data) | 540 | struct cmb_data *cmb_data) |
@@ -532,9 +549,11 @@ static int alloc_cmb_single(struct ccw_device *cdev, | |||
532 | goto out; | 549 | goto out; |
533 | } | 550 | } |
534 | 551 | ||
535 | /* find first unused cmb in cmb_area.mem. | 552 | /* |
536 | * this is a little tricky: cmb_area.list | 553 | * Find first unused cmb in cmb_area.mem. |
537 | * remains sorted by ->cmb->hw_data pointers */ | 554 | * This is a little tricky: cmb_area.list |
555 | * remains sorted by ->cmb->hw_data pointers. | ||
556 | */ | ||
538 | cmb = cmb_area.mem; | 557 | cmb = cmb_area.mem; |
539 | list_for_each_entry(node, &cmb_area.list, cmb_list) { | 558 | list_for_each_entry(node, &cmb_area.list, cmb_list) { |
540 | struct cmb_data *data; | 559 | struct cmb_data *data; |
@@ -558,8 +577,7 @@ out: | |||
558 | return ret; | 577 | return ret; |
559 | } | 578 | } |
560 | 579 | ||
561 | static int | 580 | static int alloc_cmb(struct ccw_device *cdev) |
562 | alloc_cmb (struct ccw_device *cdev) | ||
563 | { | 581 | { |
564 | int ret; | 582 | int ret; |
565 | struct cmb *mem; | 583 | struct cmb *mem; |
@@ -670,7 +688,7 @@ static int set_cmb(struct ccw_device *cdev, u32 mme) | |||
670 | return set_schib_wait(cdev, mme, 0, offset); | 688 | return set_schib_wait(cdev, mme, 0, offset); |
671 | } | 689 | } |
672 | 690 | ||
673 | static u64 read_cmb (struct ccw_device *cdev, int index) | 691 | static u64 read_cmb(struct ccw_device *cdev, int index) |
674 | { | 692 | { |
675 | struct cmb *cmb; | 693 | struct cmb *cmb; |
676 | u32 val; | 694 | u32 val; |
@@ -720,7 +738,7 @@ out: | |||
720 | return ret; | 738 | return ret; |
721 | } | 739 | } |
722 | 740 | ||
723 | static int readall_cmb (struct ccw_device *cdev, struct cmbdata *data) | 741 | static int readall_cmb(struct ccw_device *cdev, struct cmbdata *data) |
724 | { | 742 | { |
725 | struct cmb *cmb; | 743 | struct cmb *cmb; |
726 | struct cmb_data *cmb_data; | 744 | struct cmb_data *cmb_data; |
@@ -793,14 +811,25 @@ static struct cmb_operations cmbops_basic = { | |||
793 | .align = align_cmb, | 811 | .align = align_cmb, |
794 | .attr_group = &cmf_attr_group, | 812 | .attr_group = &cmf_attr_group, |
795 | }; | 813 | }; |
796 | 814 | ||
797 | /* ******** extended cmb handling ********/ | 815 | /* ******** extended cmb handling ********/ |
798 | 816 | ||
799 | /** | 817 | /** |
800 | * struct cmbe - extended channel measurement block | 818 | * struct cmbe - extended channel measurement block |
819 | * @ssch_rsch_count: number of ssch and rsch | ||
820 | * @sample_count: number of samples | ||
821 | * @device_connect_time: time of device connect | ||
822 | * @function_pending_time: time of function pending | ||
823 | * @device_disconnect_time: time of device disconnect | ||
824 | * @control_unit_queuing_time: time of control unit queuing | ||
825 | * @device_active_only_time: time of device active only | ||
826 | * @device_busy_time: time of device busy | ||
827 | * @initial_command_response_time: initial command response time | ||
828 | * @reserved: unused | ||
801 | * | 829 | * |
802 | * cmb as used by the hardware, may be in any 64 bit physical location, | 830 | * The measurement block as used by the hardware. May be in any 64 bit physical |
803 | * the fields are described in z/Architecture Principles of Operation, | 831 | * location. |
832 | * The fields are described further in z/Architecture Principles of Operation, | ||
804 | * third edition, chapter 17. | 833 | * third edition, chapter 17. |
805 | */ | 834 | */ |
806 | struct cmbe { | 835 | struct cmbe { |
@@ -816,10 +845,12 @@ struct cmbe { | |||
816 | u32 reserved[7]; | 845 | u32 reserved[7]; |
817 | }; | 846 | }; |
818 | 847 | ||
819 | /* kmalloc only guarantees 8 byte alignment, but we need cmbe | 848 | /* |
849 | * kmalloc only guarantees 8 byte alignment, but we need cmbe | ||
820 | * pointers to be naturally aligned. Make sure to allocate | 850 | * pointers to be naturally aligned. Make sure to allocate |
821 | * enough space for two cmbes */ | 851 | * enough space for two cmbes. |
822 | static inline struct cmbe* cmbe_align(struct cmbe *c) | 852 | */ |
853 | static inline struct cmbe *cmbe_align(struct cmbe *c) | ||
823 | { | 854 | { |
824 | unsigned long addr; | 855 | unsigned long addr; |
825 | addr = ((unsigned long)c + sizeof (struct cmbe) - sizeof(long)) & | 856 | addr = ((unsigned long)c + sizeof (struct cmbe) - sizeof(long)) & |
@@ -827,7 +858,7 @@ static inline struct cmbe* cmbe_align(struct cmbe *c) | |||
827 | return (struct cmbe*)addr; | 858 | return (struct cmbe*)addr; |
828 | } | 859 | } |
829 | 860 | ||
830 | static int alloc_cmbe (struct ccw_device *cdev) | 861 | static int alloc_cmbe(struct ccw_device *cdev) |
831 | { | 862 | { |
832 | struct cmbe *cmbe; | 863 | struct cmbe *cmbe; |
833 | struct cmb_data *cmb_data; | 864 | struct cmb_data *cmb_data; |
@@ -873,7 +904,7 @@ out_free: | |||
873 | return ret; | 904 | return ret; |
874 | } | 905 | } |
875 | 906 | ||
876 | static void free_cmbe (struct ccw_device *cdev) | 907 | static void free_cmbe(struct ccw_device *cdev) |
877 | { | 908 | { |
878 | struct cmb_data *cmb_data; | 909 | struct cmb_data *cmb_data; |
879 | 910 | ||
@@ -912,7 +943,7 @@ static int set_cmbe(struct ccw_device *cdev, u32 mme) | |||
912 | } | 943 | } |
913 | 944 | ||
914 | 945 | ||
915 | static u64 read_cmbe (struct ccw_device *cdev, int index) | 946 | static u64 read_cmbe(struct ccw_device *cdev, int index) |
916 | { | 947 | { |
917 | struct cmbe *cmb; | 948 | struct cmbe *cmb; |
918 | struct cmb_data *cmb_data; | 949 | struct cmb_data *cmb_data; |
@@ -970,7 +1001,7 @@ out: | |||
970 | return ret; | 1001 | return ret; |
971 | } | 1002 | } |
972 | 1003 | ||
973 | static int readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) | 1004 | static int readall_cmbe(struct ccw_device *cdev, struct cmbdata *data) |
974 | { | 1005 | { |
975 | struct cmbe *cmb; | 1006 | struct cmbe *cmb; |
976 | struct cmb_data *cmb_data; | 1007 | struct cmb_data *cmb_data; |
@@ -1047,17 +1078,16 @@ static struct cmb_operations cmbops_extended = { | |||
1047 | .align = align_cmbe, | 1078 | .align = align_cmbe, |
1048 | .attr_group = &cmf_attr_group_ext, | 1079 | .attr_group = &cmf_attr_group_ext, |
1049 | }; | 1080 | }; |
1050 | |||
1051 | 1081 | ||
1052 | static ssize_t | 1082 | static ssize_t cmb_show_attr(struct device *dev, char *buf, enum cmb_index idx) |
1053 | cmb_show_attr(struct device *dev, char *buf, enum cmb_index idx) | ||
1054 | { | 1083 | { |
1055 | return sprintf(buf, "%lld\n", | 1084 | return sprintf(buf, "%lld\n", |
1056 | (unsigned long long) cmf_read(to_ccwdev(dev), idx)); | 1085 | (unsigned long long) cmf_read(to_ccwdev(dev), idx)); |
1057 | } | 1086 | } |
1058 | 1087 | ||
1059 | static ssize_t | 1088 | static ssize_t cmb_show_avg_sample_interval(struct device *dev, |
1060 | cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, char *buf) | 1089 | struct device_attribute *attr, |
1090 | char *buf) | ||
1061 | { | 1091 | { |
1062 | struct ccw_device *cdev; | 1092 | struct ccw_device *cdev; |
1063 | long interval; | 1093 | long interval; |
@@ -1079,8 +1109,9 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, | |||
1079 | return sprintf(buf, "%ld\n", interval); | 1109 | return sprintf(buf, "%ld\n", interval); |
1080 | } | 1110 | } |
1081 | 1111 | ||
1082 | static ssize_t | 1112 | static ssize_t cmb_show_avg_utilization(struct device *dev, |
1083 | cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char *buf) | 1113 | struct device_attribute *attr, |
1114 | char *buf) | ||
1084 | { | 1115 | { |
1085 | struct cmbdata data; | 1116 | struct cmbdata data; |
1086 | u64 utilization; | 1117 | u64 utilization; |
@@ -1112,14 +1143,16 @@ cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char | |||
1112 | } | 1143 | } |
1113 | 1144 | ||
1114 | #define cmf_attr(name) \ | 1145 | #define cmf_attr(name) \ |
1115 | static ssize_t show_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \ | 1146 | static ssize_t show_##name(struct device *dev, \ |
1116 | { return cmb_show_attr((dev), buf, cmb_ ## name); } \ | 1147 | struct device_attribute *attr, char *buf) \ |
1117 | static DEVICE_ATTR(name, 0444, show_ ## name, NULL); | 1148 | { return cmb_show_attr((dev), buf, cmb_##name); } \ |
1149 | static DEVICE_ATTR(name, 0444, show_##name, NULL); | ||
1118 | 1150 | ||
1119 | #define cmf_attr_avg(name) \ | 1151 | #define cmf_attr_avg(name) \ |
1120 | static ssize_t show_avg_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \ | 1152 | static ssize_t show_avg_##name(struct device *dev, \ |
1121 | { return cmb_show_attr((dev), buf, cmb_ ## name); } \ | 1153 | struct device_attribute *attr, char *buf) \ |
1122 | static DEVICE_ATTR(avg_ ## name, 0444, show_avg_ ## name, NULL); | 1154 | { return cmb_show_attr((dev), buf, cmb_##name); } \ |
1155 | static DEVICE_ATTR(avg_##name, 0444, show_avg_##name, NULL); | ||
1123 | 1156 | ||
1124 | cmf_attr(ssch_rsch_count); | 1157 | cmf_attr(ssch_rsch_count); |
1125 | cmf_attr(sample_count); | 1158 | cmf_attr(sample_count); |
@@ -1131,7 +1164,8 @@ cmf_attr_avg(device_active_only_time); | |||
1131 | cmf_attr_avg(device_busy_time); | 1164 | cmf_attr_avg(device_busy_time); |
1132 | cmf_attr_avg(initial_command_response_time); | 1165 | cmf_attr_avg(initial_command_response_time); |
1133 | 1166 | ||
1134 | static DEVICE_ATTR(avg_sample_interval, 0444, cmb_show_avg_sample_interval, NULL); | 1167 | static DEVICE_ATTR(avg_sample_interval, 0444, cmb_show_avg_sample_interval, |
1168 | NULL); | ||
1135 | static DEVICE_ATTR(avg_utilization, 0444, cmb_show_avg_utilization, NULL); | 1169 | static DEVICE_ATTR(avg_utilization, 0444, cmb_show_avg_utilization, NULL); |
1136 | 1170 | ||
1137 | static struct attribute *cmf_attributes[] = { | 1171 | static struct attribute *cmf_attributes[] = { |
@@ -1172,12 +1206,16 @@ static struct attribute_group cmf_attr_group_ext = { | |||
1172 | .attrs = cmf_attributes_ext, | 1206 | .attrs = cmf_attributes_ext, |
1173 | }; | 1207 | }; |
1174 | 1208 | ||
1175 | static ssize_t cmb_enable_show(struct device *dev, struct device_attribute *attr, char *buf) | 1209 | static ssize_t cmb_enable_show(struct device *dev, |
1210 | struct device_attribute *attr, | ||
1211 | char *buf) | ||
1176 | { | 1212 | { |
1177 | return sprintf(buf, "%d\n", to_ccwdev(dev)->private->cmb ? 1 : 0); | 1213 | return sprintf(buf, "%d\n", to_ccwdev(dev)->private->cmb ? 1 : 0); |
1178 | } | 1214 | } |
1179 | 1215 | ||
1180 | static ssize_t cmb_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t c) | 1216 | static ssize_t cmb_enable_store(struct device *dev, |
1217 | struct device_attribute *attr, const char *buf, | ||
1218 | size_t c) | ||
1181 | { | 1219 | { |
1182 | struct ccw_device *cdev; | 1220 | struct ccw_device *cdev; |
1183 | int ret; | 1221 | int ret; |
@@ -1202,9 +1240,16 @@ static ssize_t cmb_enable_store(struct device *dev, struct device_attribute *att | |||
1202 | 1240 | ||
1203 | DEVICE_ATTR(cmb_enable, 0644, cmb_enable_show, cmb_enable_store); | 1241 | DEVICE_ATTR(cmb_enable, 0644, cmb_enable_show, cmb_enable_store); |
1204 | 1242 | ||
1205 | /* enable_cmf/disable_cmf: module interface for cmf (de)activation */ | 1243 | /** |
1206 | int | 1244 | * enable_cmf() - switch on the channel measurement for a specific device |
1207 | enable_cmf(struct ccw_device *cdev) | 1245 | * @cdev: The ccw device to be enabled |
1246 | * | ||
1247 | * Returns %0 for success or a negative error value. | ||
1248 | * | ||
1249 | * Context: | ||
1250 | * non-atomic | ||
1251 | */ | ||
1252 | int enable_cmf(struct ccw_device *cdev) | ||
1208 | { | 1253 | { |
1209 | int ret; | 1254 | int ret; |
1210 | 1255 | ||
@@ -1225,8 +1270,16 @@ enable_cmf(struct ccw_device *cdev) | |||
1225 | return ret; | 1270 | return ret; |
1226 | } | 1271 | } |
1227 | 1272 | ||
1228 | int | 1273 | /** |
1229 | disable_cmf(struct ccw_device *cdev) | 1274 | * disable_cmf() - switch off the channel measurement for a specific device |
1275 | * @cdev: The ccw device to be disabled | ||
1276 | * | ||
1277 | * Returns %0 for success or a negative error value. | ||
1278 | * | ||
1279 | * Context: | ||
1280 | * non-atomic | ||
1281 | */ | ||
1282 | int disable_cmf(struct ccw_device *cdev) | ||
1230 | { | 1283 | { |
1231 | int ret; | 1284 | int ret; |
1232 | 1285 | ||
@@ -1238,14 +1291,32 @@ disable_cmf(struct ccw_device *cdev) | |||
1238 | return ret; | 1291 | return ret; |
1239 | } | 1292 | } |
1240 | 1293 | ||
1241 | u64 | 1294 | /** |
1242 | cmf_read(struct ccw_device *cdev, int index) | 1295 | * cmf_read() - read one value from the current channel measurement block |
1296 | * @cdev: the channel to be read | ||
1297 | * @index: the index of the value to be read | ||
1298 | * | ||
1299 | * Returns the value read or %0 if the value cannot be read. | ||
1300 | * | ||
1301 | * Context: | ||
1302 | * any | ||
1303 | */ | ||
1304 | u64 cmf_read(struct ccw_device *cdev, int index) | ||
1243 | { | 1305 | { |
1244 | return cmbops->read(cdev, index); | 1306 | return cmbops->read(cdev, index); |
1245 | } | 1307 | } |
1246 | 1308 | ||
1247 | int | 1309 | /** |
1248 | cmf_readall(struct ccw_device *cdev, struct cmbdata *data) | 1310 | * cmf_readall() - read the current channel measurement block |
1311 | * @cdev: the channel to be read | ||
1312 | * @data: a pointer to a data block that will be filled | ||
1313 | * | ||
1314 | * Returns %0 on success, a negative error value otherwise. | ||
1315 | * | ||
1316 | * Context: | ||
1317 | * any | ||
1318 | */ | ||
1319 | int cmf_readall(struct ccw_device *cdev, struct cmbdata *data) | ||
1249 | { | 1320 | { |
1250 | return cmbops->readall(cdev, data); | 1321 | return cmbops->readall(cdev, data); |
1251 | } | 1322 | } |
@@ -1257,15 +1328,16 @@ int cmf_reenable(struct ccw_device *cdev) | |||
1257 | return cmbops->set(cdev, 2); | 1328 | return cmbops->set(cdev, 2); |
1258 | } | 1329 | } |
1259 | 1330 | ||
1260 | static int __init | 1331 | static int __init init_cmf(void) |
1261 | init_cmf(void) | ||
1262 | { | 1332 | { |
1263 | char *format_string; | 1333 | char *format_string; |
1264 | char *detect_string = "parameter"; | 1334 | char *detect_string = "parameter"; |
1265 | 1335 | ||
1266 | /* We cannot really autoprobe this. If the user did not give a parameter, | 1336 | /* |
1267 | see if we are running on z990 or up, otherwise fall back to basic mode. */ | 1337 | * If the user did not give a parameter, see if we are running on a |
1268 | 1338 | * machine supporting extended measurement blocks, otherwise fall back | |
1339 | * to basic mode. | ||
1340 | */ | ||
1269 | if (format == CMF_AUTODETECT) { | 1341 | if (format == CMF_AUTODETECT) { |
1270 | if (!css_characteristics_avail || | 1342 | if (!css_characteristics_avail || |
1271 | !css_general_characteristics.ext_mb) { | 1343 | !css_general_characteristics.ext_mb) { |
@@ -1284,7 +1356,7 @@ init_cmf(void) | |||
1284 | cmbops = &cmbops_basic; | 1356 | cmbops = &cmbops_basic; |
1285 | break; | 1357 | break; |
1286 | case CMF_EXTENDED: | 1358 | case CMF_EXTENDED: |
1287 | format_string = "extended"; | 1359 | format_string = "extended"; |
1288 | cmbops = &cmbops_extended; | 1360 | cmbops = &cmbops_extended; |
1289 | break; | 1361 | break; |
1290 | default: | 1362 | default: |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 5635e656c1a3..5d83dd471461 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
16 | #include <linux/reboot.h> | ||
16 | 17 | ||
17 | #include "css.h" | 18 | #include "css.h" |
18 | #include "cio.h" | 19 | #include "cio.h" |
@@ -27,7 +28,7 @@ int css_init_done = 0; | |||
27 | static int need_reprobe = 0; | 28 | static int need_reprobe = 0; |
28 | static int max_ssid = 0; | 29 | static int max_ssid = 0; |
29 | 30 | ||
30 | struct channel_subsystem *css[__MAX_CSSID + 1]; | 31 | struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1]; |
31 | 32 | ||
32 | int css_characteristics_avail = 0; | 33 | int css_characteristics_avail = 0; |
33 | 34 | ||
@@ -177,7 +178,7 @@ static int css_register_subchannel(struct subchannel *sch) | |||
177 | int ret; | 178 | int ret; |
178 | 179 | ||
179 | /* Initialize the subchannel structure */ | 180 | /* Initialize the subchannel structure */ |
180 | sch->dev.parent = &css[0]->device; | 181 | sch->dev.parent = &channel_subsystems[0]->device; |
181 | sch->dev.bus = &css_bus_type; | 182 | sch->dev.bus = &css_bus_type; |
182 | sch->dev.release = &css_subchannel_release; | 183 | sch->dev.release = &css_subchannel_release; |
183 | sch->dev.groups = subch_attr_groups; | 184 | sch->dev.groups = subch_attr_groups; |
@@ -606,30 +607,55 @@ static int __init setup_css(int nr) | |||
606 | { | 607 | { |
607 | u32 tod_high; | 608 | u32 tod_high; |
608 | int ret; | 609 | int ret; |
610 | struct channel_subsystem *css; | ||
609 | 611 | ||
610 | memset(css[nr], 0, sizeof(struct channel_subsystem)); | 612 | css = channel_subsystems[nr]; |
611 | css[nr]->pseudo_subchannel = | 613 | memset(css, 0, sizeof(struct channel_subsystem)); |
612 | kzalloc(sizeof(*css[nr]->pseudo_subchannel), GFP_KERNEL); | 614 | css->pseudo_subchannel = |
613 | if (!css[nr]->pseudo_subchannel) | 615 | kzalloc(sizeof(*css->pseudo_subchannel), GFP_KERNEL); |
616 | if (!css->pseudo_subchannel) | ||
614 | return -ENOMEM; | 617 | return -ENOMEM; |
615 | css[nr]->pseudo_subchannel->dev.parent = &css[nr]->device; | 618 | css->pseudo_subchannel->dev.parent = &css->device; |
616 | css[nr]->pseudo_subchannel->dev.release = css_subchannel_release; | 619 | css->pseudo_subchannel->dev.release = css_subchannel_release; |
617 | sprintf(css[nr]->pseudo_subchannel->dev.bus_id, "defunct"); | 620 | sprintf(css->pseudo_subchannel->dev.bus_id, "defunct"); |
618 | ret = cio_create_sch_lock(css[nr]->pseudo_subchannel); | 621 | ret = cio_create_sch_lock(css->pseudo_subchannel); |
619 | if (ret) { | 622 | if (ret) { |
620 | kfree(css[nr]->pseudo_subchannel); | 623 | kfree(css->pseudo_subchannel); |
621 | return ret; | 624 | return ret; |
622 | } | 625 | } |
623 | mutex_init(&css[nr]->mutex); | 626 | mutex_init(&css->mutex); |
624 | css[nr]->valid = 1; | 627 | css->valid = 1; |
625 | css[nr]->cssid = nr; | 628 | css->cssid = nr; |
626 | sprintf(css[nr]->device.bus_id, "css%x", nr); | 629 | sprintf(css->device.bus_id, "css%x", nr); |
627 | css[nr]->device.release = channel_subsystem_release; | 630 | css->device.release = channel_subsystem_release; |
628 | tod_high = (u32) (get_clock() >> 32); | 631 | tod_high = (u32) (get_clock() >> 32); |
629 | css_generate_pgid(css[nr], tod_high); | 632 | css_generate_pgid(css, tod_high); |
630 | return 0; | 633 | return 0; |
631 | } | 634 | } |
632 | 635 | ||
636 | static int css_reboot_event(struct notifier_block *this, | ||
637 | unsigned long event, | ||
638 | void *ptr) | ||
639 | { | ||
640 | int ret, i; | ||
641 | |||
642 | ret = NOTIFY_DONE; | ||
643 | for (i = 0; i <= __MAX_CSSID; i++) { | ||
644 | struct channel_subsystem *css; | ||
645 | |||
646 | css = channel_subsystems[i]; | ||
647 | if (css->cm_enabled) | ||
648 | if (chsc_secm(css, 0)) | ||
649 | ret = NOTIFY_BAD; | ||
650 | } | ||
651 | |||
652 | return ret; | ||
653 | } | ||
654 | |||
655 | static struct notifier_block css_reboot_notifier = { | ||
656 | .notifier_call = css_reboot_event, | ||
657 | }; | ||
658 | |||
633 | /* | 659 | /* |
634 | * Now that the driver core is running, we can setup our channel subsystem. | 660 | * Now that the driver core is running, we can setup our channel subsystem. |
635 | * The struct subchannel's are created during probing (except for the | 661 | * The struct subchannel's are created during probing (except for the |
@@ -670,51 +696,63 @@ init_channel_subsystem (void) | |||
670 | } | 696 | } |
671 | /* Setup css structure. */ | 697 | /* Setup css structure. */ |
672 | for (i = 0; i <= __MAX_CSSID; i++) { | 698 | for (i = 0; i <= __MAX_CSSID; i++) { |
673 | css[i] = kmalloc(sizeof(struct channel_subsystem), GFP_KERNEL); | 699 | struct channel_subsystem *css; |
674 | if (!css[i]) { | 700 | |
701 | css = kmalloc(sizeof(struct channel_subsystem), GFP_KERNEL); | ||
702 | if (!css) { | ||
675 | ret = -ENOMEM; | 703 | ret = -ENOMEM; |
676 | goto out_unregister; | 704 | goto out_unregister; |
677 | } | 705 | } |
706 | channel_subsystems[i] = css; | ||
678 | ret = setup_css(i); | 707 | ret = setup_css(i); |
679 | if (ret) | 708 | if (ret) |
680 | goto out_free; | 709 | goto out_free; |
681 | ret = device_register(&css[i]->device); | 710 | ret = device_register(&css->device); |
682 | if (ret) | 711 | if (ret) |
683 | goto out_free_all; | 712 | goto out_free_all; |
684 | if (css_characteristics_avail && | 713 | if (css_characteristics_avail && |
685 | css_chsc_characteristics.secm) { | 714 | css_chsc_characteristics.secm) { |
686 | ret = device_create_file(&css[i]->device, | 715 | ret = device_create_file(&css->device, |
687 | &dev_attr_cm_enable); | 716 | &dev_attr_cm_enable); |
688 | if (ret) | 717 | if (ret) |
689 | goto out_device; | 718 | goto out_device; |
690 | } | 719 | } |
691 | ret = device_register(&css[i]->pseudo_subchannel->dev); | 720 | ret = device_register(&css->pseudo_subchannel->dev); |
692 | if (ret) | 721 | if (ret) |
693 | goto out_file; | 722 | goto out_file; |
694 | } | 723 | } |
724 | ret = register_reboot_notifier(&css_reboot_notifier); | ||
725 | if (ret) | ||
726 | goto out_pseudo; | ||
695 | css_init_done = 1; | 727 | css_init_done = 1; |
696 | 728 | ||
697 | ctl_set_bit(6, 28); | 729 | ctl_set_bit(6, 28); |
698 | 730 | ||
699 | for_each_subchannel(__init_channel_subsystem, NULL); | 731 | for_each_subchannel(__init_channel_subsystem, NULL); |
700 | return 0; | 732 | return 0; |
733 | out_pseudo: | ||
734 | device_unregister(&channel_subsystems[i]->pseudo_subchannel->dev); | ||
701 | out_file: | 735 | out_file: |
702 | device_remove_file(&css[i]->device, &dev_attr_cm_enable); | 736 | device_remove_file(&channel_subsystems[i]->device, |
737 | &dev_attr_cm_enable); | ||
703 | out_device: | 738 | out_device: |
704 | device_unregister(&css[i]->device); | 739 | device_unregister(&channel_subsystems[i]->device); |
705 | out_free_all: | 740 | out_free_all: |
706 | kfree(css[i]->pseudo_subchannel->lock); | 741 | kfree(channel_subsystems[i]->pseudo_subchannel->lock); |
707 | kfree(css[i]->pseudo_subchannel); | 742 | kfree(channel_subsystems[i]->pseudo_subchannel); |
708 | out_free: | 743 | out_free: |
709 | kfree(css[i]); | 744 | kfree(channel_subsystems[i]); |
710 | out_unregister: | 745 | out_unregister: |
711 | while (i > 0) { | 746 | while (i > 0) { |
747 | struct channel_subsystem *css; | ||
748 | |||
712 | i--; | 749 | i--; |
713 | device_unregister(&css[i]->pseudo_subchannel->dev); | 750 | css = channel_subsystems[i]; |
751 | device_unregister(&css->pseudo_subchannel->dev); | ||
714 | if (css_characteristics_avail && css_chsc_characteristics.secm) | 752 | if (css_characteristics_avail && css_chsc_characteristics.secm) |
715 | device_remove_file(&css[i]->device, | 753 | device_remove_file(&css->device, |
716 | &dev_attr_cm_enable); | 754 | &dev_attr_cm_enable); |
717 | device_unregister(&css[i]->device); | 755 | device_unregister(&css->device); |
718 | } | 756 | } |
719 | out_bus: | 757 | out_bus: |
720 | bus_unregister(&css_bus_type); | 758 | bus_unregister(&css_bus_type); |
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 5d65e83ca66e..81215ef32435 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h | |||
@@ -167,7 +167,7 @@ struct channel_subsystem { | |||
167 | #define to_css(dev) container_of(dev, struct channel_subsystem, device) | 167 | #define to_css(dev) container_of(dev, struct channel_subsystem, device) |
168 | 168 | ||
169 | extern struct bus_type css_bus_type; | 169 | extern struct bus_type css_bus_type; |
170 | extern struct channel_subsystem *css[]; | 170 | extern struct channel_subsystem *channel_subsystems[]; |
171 | 171 | ||
172 | /* Some helper functions for disconnected state. */ | 172 | /* Some helper functions for disconnected state. */ |
173 | int device_is_disconnected(struct subchannel *); | 173 | int device_is_disconnected(struct subchannel *); |
@@ -191,6 +191,5 @@ int sch_is_pseudo_sch(struct subchannel *); | |||
191 | 191 | ||
192 | extern struct workqueue_struct *slow_path_wq; | 192 | extern struct workqueue_struct *slow_path_wq; |
193 | 193 | ||
194 | int subchannel_add_files (struct device *); | ||
195 | extern struct attribute_group *subch_attr_groups[]; | 194 | extern struct attribute_group *subch_attr_groups[]; |
196 | #endif | 195 | #endif |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index e44d92eac8e9..7ee57f084a89 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/ccwdev.h> | 21 | #include <asm/ccwdev.h> |
22 | #include <asm/cio.h> | 22 | #include <asm/cio.h> |
23 | #include <asm/param.h> /* HZ */ | 23 | #include <asm/param.h> /* HZ */ |
24 | #include <asm/cmb.h> | ||
24 | 25 | ||
25 | #include "cio.h" | 26 | #include "cio.h" |
26 | #include "cio_debug.h" | 27 | #include "cio_debug.h" |
@@ -78,49 +79,38 @@ static int snprint_alias(char *buf, size_t size, | |||
78 | 79 | ||
79 | /* Set up environment variables for ccw device uevent. Return 0 on success, | 80 | /* Set up environment variables for ccw device uevent. Return 0 on success, |
80 | * non-zero otherwise. */ | 81 | * non-zero otherwise. */ |
81 | static int ccw_uevent(struct device *dev, char **envp, int num_envp, | 82 | static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env) |
82 | char *buffer, int buffer_size) | ||
83 | { | 83 | { |
84 | struct ccw_device *cdev = to_ccwdev(dev); | 84 | struct ccw_device *cdev = to_ccwdev(dev); |
85 | struct ccw_device_id *id = &(cdev->id); | 85 | struct ccw_device_id *id = &(cdev->id); |
86 | int i = 0; | ||
87 | int len = 0; | ||
88 | int ret; | 86 | int ret; |
89 | char modalias_buf[30]; | 87 | char modalias_buf[30]; |
90 | 88 | ||
91 | /* CU_TYPE= */ | 89 | /* CU_TYPE= */ |
92 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, | 90 | ret = add_uevent_var(env, "CU_TYPE=%04X", id->cu_type); |
93 | "CU_TYPE=%04X", id->cu_type); | ||
94 | if (ret) | 91 | if (ret) |
95 | return ret; | 92 | return ret; |
96 | 93 | ||
97 | /* CU_MODEL= */ | 94 | /* CU_MODEL= */ |
98 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, | 95 | ret = add_uevent_var(env, "CU_MODEL=%02X", id->cu_model); |
99 | "CU_MODEL=%02X", id->cu_model); | ||
100 | if (ret) | 96 | if (ret) |
101 | return ret; | 97 | return ret; |
102 | 98 | ||
103 | /* The next two can be zero, that's ok for us */ | 99 | /* The next two can be zero, that's ok for us */ |
104 | /* DEV_TYPE= */ | 100 | /* DEV_TYPE= */ |
105 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, | 101 | ret = add_uevent_var(env, "DEV_TYPE=%04X", id->dev_type); |
106 | "DEV_TYPE=%04X", id->dev_type); | ||
107 | if (ret) | 102 | if (ret) |
108 | return ret; | 103 | return ret; |
109 | 104 | ||
110 | /* DEV_MODEL= */ | 105 | /* DEV_MODEL= */ |
111 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, | 106 | ret = add_uevent_var(env, "DEV_MODEL=%02X", id->dev_model); |
112 | "DEV_MODEL=%02X", id->dev_model); | ||
113 | if (ret) | 107 | if (ret) |
114 | return ret; | 108 | return ret; |
115 | 109 | ||
116 | /* MODALIAS= */ | 110 | /* MODALIAS= */ |
117 | snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); | 111 | snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); |
118 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, | 112 | ret = add_uevent_var(env, "MODALIAS=%s", modalias_buf); |
119 | "MODALIAS=%s", modalias_buf); | 113 | return ret; |
120 | if (ret) | ||
121 | return ret; | ||
122 | envp[i] = NULL; | ||
123 | return 0; | ||
124 | } | 114 | } |
125 | 115 | ||
126 | struct bus_type ccw_bus_type; | 116 | struct bus_type ccw_bus_type; |
@@ -357,8 +347,18 @@ ccw_device_remove_disconnected(struct ccw_device *cdev) | |||
357 | cdev->private->dev_id.devno); | 347 | cdev->private->dev_id.devno); |
358 | } | 348 | } |
359 | 349 | ||
360 | int | 350 | /** |
361 | ccw_device_set_offline(struct ccw_device *cdev) | 351 | * ccw_device_set_offline() - disable a ccw device for I/O |
352 | * @cdev: target ccw device | ||
353 | * | ||
354 | * This function calls the driver's set_offline() function for @cdev, if | ||
355 | * given, and then disables @cdev. | ||
356 | * Returns: | ||
357 | * %0 on success and a negative error value on failure. | ||
358 | * Context: | ||
359 | * enabled, ccw device lock not held | ||
360 | */ | ||
361 | int ccw_device_set_offline(struct ccw_device *cdev) | ||
362 | { | 362 | { |
363 | int ret; | 363 | int ret; |
364 | 364 | ||
@@ -396,8 +396,19 @@ ccw_device_set_offline(struct ccw_device *cdev) | |||
396 | return ret; | 396 | return ret; |
397 | } | 397 | } |
398 | 398 | ||
399 | int | 399 | /** |
400 | ccw_device_set_online(struct ccw_device *cdev) | 400 | * ccw_device_set_online() - enable a ccw device for I/O |
401 | * @cdev: target ccw device | ||
402 | * | ||
403 | * This function first enables @cdev and then calls the driver's set_online() | ||
404 | * function for @cdev, if given. If set_online() returns an error, @cdev is | ||
405 | * disabled again. | ||
406 | * Returns: | ||
407 | * %0 on success and a negative error value on failure. | ||
408 | * Context: | ||
409 | * enabled, ccw device lock not held | ||
410 | */ | ||
411 | int ccw_device_set_online(struct ccw_device *cdev) | ||
401 | { | 412 | { |
402 | int ret; | 413 | int ret; |
403 | 414 | ||
@@ -947,8 +958,7 @@ out: | |||
947 | wake_up(&ccw_device_init_wq); | 958 | wake_up(&ccw_device_init_wq); |
948 | } | 959 | } |
949 | 960 | ||
950 | void | 961 | static void ccw_device_call_sch_unregister(struct work_struct *work) |
951 | ccw_device_call_sch_unregister(struct work_struct *work) | ||
952 | { | 962 | { |
953 | struct ccw_device_private *priv; | 963 | struct ccw_device_private *priv; |
954 | struct ccw_device *cdev; | 964 | struct ccw_device *cdev; |
@@ -1101,6 +1111,7 @@ io_subchannel_probe (struct subchannel *sch) | |||
1101 | * device, e.g. the console. | 1111 | * device, e.g. the console. |
1102 | */ | 1112 | */ |
1103 | cdev = sch->dev.driver_data; | 1113 | cdev = sch->dev.driver_data; |
1114 | cdev->dev.groups = ccwdev_attr_groups; | ||
1104 | device_initialize(&cdev->dev); | 1115 | device_initialize(&cdev->dev); |
1105 | ccw_device_register(cdev); | 1116 | ccw_device_register(cdev); |
1106 | /* | 1117 | /* |
@@ -1326,8 +1337,19 @@ __ccwdev_check_busid(struct device *dev, void *id) | |||
1326 | } | 1337 | } |
1327 | 1338 | ||
1328 | 1339 | ||
1329 | struct ccw_device * | 1340 | /** |
1330 | get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id) | 1341 | * get_ccwdev_by_busid() - obtain device from a bus id |
1342 | * @cdrv: driver the device is owned by | ||
1343 | * @bus_id: bus id of the device to be searched | ||
1344 | * | ||
1345 | * This function searches all devices owned by @cdrv for a device with a bus | ||
1346 | * id matching @bus_id. | ||
1347 | * Returns: | ||
1348 | * If a match is found, its reference count of the found device is increased | ||
1349 | * and it is returned; else %NULL is returned. | ||
1350 | */ | ||
1351 | struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, | ||
1352 | const char *bus_id) | ||
1331 | { | 1353 | { |
1332 | struct device *dev; | 1354 | struct device *dev; |
1333 | struct device_driver *drv; | 1355 | struct device_driver *drv; |
@@ -1401,16 +1423,34 @@ ccw_device_remove (struct device *dev) | |||
1401 | return 0; | 1423 | return 0; |
1402 | } | 1424 | } |
1403 | 1425 | ||
1426 | static void ccw_device_shutdown(struct device *dev) | ||
1427 | { | ||
1428 | struct ccw_device *cdev; | ||
1429 | |||
1430 | cdev = to_ccwdev(dev); | ||
1431 | if (cdev->drv && cdev->drv->shutdown) | ||
1432 | cdev->drv->shutdown(cdev); | ||
1433 | disable_cmf(cdev); | ||
1434 | } | ||
1435 | |||
1404 | struct bus_type ccw_bus_type = { | 1436 | struct bus_type ccw_bus_type = { |
1405 | .name = "ccw", | 1437 | .name = "ccw", |
1406 | .match = ccw_bus_match, | 1438 | .match = ccw_bus_match, |
1407 | .uevent = ccw_uevent, | 1439 | .uevent = ccw_uevent, |
1408 | .probe = ccw_device_probe, | 1440 | .probe = ccw_device_probe, |
1409 | .remove = ccw_device_remove, | 1441 | .remove = ccw_device_remove, |
1442 | .shutdown = ccw_device_shutdown, | ||
1410 | }; | 1443 | }; |
1411 | 1444 | ||
1412 | int | 1445 | /** |
1413 | ccw_driver_register (struct ccw_driver *cdriver) | 1446 | * ccw_driver_register() - register a ccw driver |
1447 | * @cdriver: driver to be registered | ||
1448 | * | ||
1449 | * This function is mainly a wrapper around driver_register(). | ||
1450 | * Returns: | ||
1451 | * %0 on success and a negative error value on failure. | ||
1452 | */ | ||
1453 | int ccw_driver_register(struct ccw_driver *cdriver) | ||
1414 | { | 1454 | { |
1415 | struct device_driver *drv = &cdriver->driver; | 1455 | struct device_driver *drv = &cdriver->driver; |
1416 | 1456 | ||
@@ -1420,8 +1460,13 @@ ccw_driver_register (struct ccw_driver *cdriver) | |||
1420 | return driver_register(drv); | 1460 | return driver_register(drv); |
1421 | } | 1461 | } |
1422 | 1462 | ||
1423 | void | 1463 | /** |
1424 | ccw_driver_unregister (struct ccw_driver *cdriver) | 1464 | * ccw_driver_unregister() - deregister a ccw driver |
1465 | * @cdriver: driver to be deregistered | ||
1466 | * | ||
1467 | * This function is mainly a wrapper around driver_unregister(). | ||
1468 | */ | ||
1469 | void ccw_driver_unregister(struct ccw_driver *cdriver) | ||
1425 | { | 1470 | { |
1426 | driver_unregister(&cdriver->driver); | 1471 | driver_unregister(&cdriver->driver); |
1427 | } | 1472 | } |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index b66338b76579..0d4089600439 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
@@ -80,7 +80,6 @@ void io_subchannel_recog_done(struct ccw_device *cdev); | |||
80 | int ccw_device_cancel_halt_clear(struct ccw_device *); | 80 | int ccw_device_cancel_halt_clear(struct ccw_device *); |
81 | 81 | ||
82 | void ccw_device_do_unreg_rereg(struct work_struct *); | 82 | void ccw_device_do_unreg_rereg(struct work_struct *); |
83 | void ccw_device_call_sch_unregister(struct work_struct *); | ||
84 | void ccw_device_move_to_orphanage(struct work_struct *); | 83 | void ccw_device_move_to_orphanage(struct work_struct *); |
85 | int ccw_device_is_orphan(struct ccw_device *); | 84 | int ccw_device_is_orphan(struct ccw_device *); |
86 | 85 | ||
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 8633dc537695..8867443b8060 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -446,7 +446,8 @@ static void __ccw_device_get_common_pgid(struct ccw_device *cdev) | |||
446 | if (cdev->private->pgid[last].inf.ps.state1 == | 446 | if (cdev->private->pgid[last].inf.ps.state1 == |
447 | SNID_STATE1_RESET) | 447 | SNID_STATE1_RESET) |
448 | /* No previous pgid found */ | 448 | /* No previous pgid found */ |
449 | memcpy(&cdev->private->pgid[0], &css[0]->global_pgid, | 449 | memcpy(&cdev->private->pgid[0], |
450 | &channel_subsystems[0]->global_pgid, | ||
450 | sizeof(struct pgid)); | 451 | sizeof(struct pgid)); |
451 | else | 452 | else |
452 | /* Use existing pgid */ | 453 | /* Use existing pgid */ |
@@ -543,51 +544,6 @@ ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event) | |||
543 | } | 544 | } |
544 | 545 | ||
545 | 546 | ||
546 | static void | ||
547 | ccw_device_nopath_notify(struct work_struct *work) | ||
548 | { | ||
549 | struct ccw_device_private *priv; | ||
550 | struct ccw_device *cdev; | ||
551 | struct subchannel *sch; | ||
552 | int ret; | ||
553 | unsigned long flags; | ||
554 | |||
555 | priv = container_of(work, struct ccw_device_private, kick_work); | ||
556 | cdev = priv->cdev; | ||
557 | spin_lock_irqsave(cdev->ccwlock, flags); | ||
558 | sch = to_subchannel(cdev->dev.parent); | ||
559 | /* Extra sanity. */ | ||
560 | if (sch->lpm) | ||
561 | goto out_unlock; | ||
562 | if (sch->driver && sch->driver->notify) { | ||
563 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
564 | ret = sch->driver->notify(&sch->dev, CIO_NO_PATH); | ||
565 | spin_lock_irqsave(cdev->ccwlock, flags); | ||
566 | } else | ||
567 | ret = 0; | ||
568 | if (!ret) { | ||
569 | if (get_device(&sch->dev)) { | ||
570 | /* Driver doesn't want to keep device. */ | ||
571 | cio_disable_subchannel(sch); | ||
572 | if (get_device(&cdev->dev)) { | ||
573 | PREPARE_WORK(&cdev->private->kick_work, | ||
574 | ccw_device_call_sch_unregister); | ||
575 | queue_work(ccw_device_work, | ||
576 | &cdev->private->kick_work); | ||
577 | } else | ||
578 | put_device(&sch->dev); | ||
579 | } | ||
580 | } else { | ||
581 | cio_disable_subchannel(sch); | ||
582 | ccw_device_set_timeout(cdev, 0); | ||
583 | cdev->private->flags.fake_irb = 0; | ||
584 | cdev->private->state = DEV_STATE_DISCONNECTED; | ||
585 | wake_up(&cdev->private->wait_q); | ||
586 | } | ||
587 | out_unlock: | ||
588 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
589 | } | ||
590 | |||
591 | void | 547 | void |
592 | ccw_device_verify_done(struct ccw_device *cdev, int err) | 548 | ccw_device_verify_done(struct ccw_device *cdev, int err) |
593 | { | 549 | { |
@@ -631,12 +587,9 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) | |||
631 | default: | 587 | default: |
632 | /* Reset oper notify indication after verify error. */ | 588 | /* Reset oper notify indication after verify error. */ |
633 | cdev->private->flags.donotify = 0; | 589 | cdev->private->flags.donotify = 0; |
634 | if (cdev->online) { | 590 | if (cdev->online) |
635 | PREPARE_WORK(&cdev->private->kick_work, | 591 | dev_fsm_event(cdev, DEV_EVENT_NOTOPER); |
636 | ccw_device_nopath_notify); | 592 | else |
637 | queue_work(ccw_device_notify_work, | ||
638 | &cdev->private->kick_work); | ||
639 | } else | ||
640 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | 593 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
641 | break; | 594 | break; |
642 | } | 595 | } |
@@ -690,11 +643,7 @@ ccw_device_disband_done(struct ccw_device *cdev, int err) | |||
690 | break; | 643 | break; |
691 | default: | 644 | default: |
692 | cdev->private->flags.donotify = 0; | 645 | cdev->private->flags.donotify = 0; |
693 | if (get_device(&cdev->dev)) { | 646 | dev_fsm_event(cdev, DEV_EVENT_NOTOPER); |
694 | PREPARE_WORK(&cdev->private->kick_work, | ||
695 | ccw_device_call_sch_unregister); | ||
696 | queue_work(ccw_device_work, &cdev->private->kick_work); | ||
697 | } | ||
698 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | 647 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
699 | break; | 648 | break; |
700 | } | 649 | } |
@@ -765,59 +714,16 @@ ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event) | |||
765 | } | 714 | } |
766 | 715 | ||
767 | /* | 716 | /* |
768 | * Handle not operational event while offline. | 717 | * Handle not operational event in non-special state. |
769 | */ | 718 | */ |
770 | static void | 719 | static void ccw_device_generic_notoper(struct ccw_device *cdev, |
771 | ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event) | 720 | enum dev_event dev_event) |
772 | { | 721 | { |
773 | struct subchannel *sch; | 722 | struct subchannel *sch; |
774 | 723 | ||
775 | cdev->private->state = DEV_STATE_NOT_OPER; | 724 | cdev->private->state = DEV_STATE_NOT_OPER; |
776 | sch = to_subchannel(cdev->dev.parent); | 725 | sch = to_subchannel(cdev->dev.parent); |
777 | if (get_device(&cdev->dev)) { | 726 | css_schedule_eval(sch->schid); |
778 | PREPARE_WORK(&cdev->private->kick_work, | ||
779 | ccw_device_call_sch_unregister); | ||
780 | queue_work(ccw_device_work, &cdev->private->kick_work); | ||
781 | } | ||
782 | wake_up(&cdev->private->wait_q); | ||
783 | } | ||
784 | |||
785 | /* | ||
786 | * Handle not operational event while online. | ||
787 | */ | ||
788 | static void | ||
789 | ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event) | ||
790 | { | ||
791 | struct subchannel *sch; | ||
792 | int ret; | ||
793 | |||
794 | sch = to_subchannel(cdev->dev.parent); | ||
795 | if (sch->driver->notify) { | ||
796 | spin_unlock_irq(cdev->ccwlock); | ||
797 | ret = sch->driver->notify(&sch->dev, | ||
798 | sch->lpm ? CIO_GONE : CIO_NO_PATH); | ||
799 | spin_lock_irq(cdev->ccwlock); | ||
800 | } else | ||
801 | ret = 0; | ||
802 | if (ret) { | ||
803 | ccw_device_set_timeout(cdev, 0); | ||
804 | cdev->private->flags.fake_irb = 0; | ||
805 | cdev->private->state = DEV_STATE_DISCONNECTED; | ||
806 | wake_up(&cdev->private->wait_q); | ||
807 | return; | ||
808 | } | ||
809 | cdev->private->state = DEV_STATE_NOT_OPER; | ||
810 | cio_disable_subchannel(sch); | ||
811 | if (sch->schib.scsw.actl != 0) { | ||
812 | // FIXME: not-oper indication to device driver ? | ||
813 | ccw_device_call_handler(cdev); | ||
814 | } | ||
815 | if (get_device(&cdev->dev)) { | ||
816 | PREPARE_WORK(&cdev->private->kick_work, | ||
817 | ccw_device_call_sch_unregister); | ||
818 | queue_work(ccw_device_work, &cdev->private->kick_work); | ||
819 | } | ||
820 | wake_up(&cdev->private->wait_q); | ||
821 | } | 727 | } |
822 | 728 | ||
823 | /* | 729 | /* |
@@ -915,18 +821,9 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event) | |||
915 | cdev->private->state = DEV_STATE_TIMEOUT_KILL; | 821 | cdev->private->state = DEV_STATE_TIMEOUT_KILL; |
916 | return; | 822 | return; |
917 | } | 823 | } |
918 | if (ret == -ENODEV) { | 824 | if (ret == -ENODEV) |
919 | struct subchannel *sch; | 825 | dev_fsm_event(cdev, DEV_EVENT_NOTOPER); |
920 | 826 | else if (cdev->handler) | |
921 | sch = to_subchannel(cdev->dev.parent); | ||
922 | if (!sch->lpm) { | ||
923 | PREPARE_WORK(&cdev->private->kick_work, | ||
924 | ccw_device_nopath_notify); | ||
925 | queue_work(ccw_device_notify_work, | ||
926 | &cdev->private->kick_work); | ||
927 | } else | ||
928 | dev_fsm_event(cdev, DEV_EVENT_NOTOPER); | ||
929 | } else if (cdev->handler) | ||
930 | cdev->handler(cdev, cdev->private->intparm, | 827 | cdev->handler(cdev, cdev->private->intparm, |
931 | ERR_PTR(-ETIMEDOUT)); | 828 | ERR_PTR(-ETIMEDOUT)); |
932 | } | 829 | } |
@@ -1233,7 +1130,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1233 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1130 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
1234 | }, | 1131 | }, |
1235 | [DEV_STATE_SENSE_PGID] = { | 1132 | [DEV_STATE_SENSE_PGID] = { |
1236 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1133 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, |
1237 | [DEV_EVENT_INTERRUPT] = ccw_device_sense_pgid_irq, | 1134 | [DEV_EVENT_INTERRUPT] = ccw_device_sense_pgid_irq, |
1238 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, | 1135 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, |
1239 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1136 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
@@ -1245,50 +1142,50 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1245 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1142 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
1246 | }, | 1143 | }, |
1247 | [DEV_STATE_OFFLINE] = { | 1144 | [DEV_STATE_OFFLINE] = { |
1248 | [DEV_EVENT_NOTOPER] = ccw_device_offline_notoper, | 1145 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, |
1249 | [DEV_EVENT_INTERRUPT] = ccw_device_offline_irq, | 1146 | [DEV_EVENT_INTERRUPT] = ccw_device_offline_irq, |
1250 | [DEV_EVENT_TIMEOUT] = ccw_device_nop, | 1147 | [DEV_EVENT_TIMEOUT] = ccw_device_nop, |
1251 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1148 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
1252 | }, | 1149 | }, |
1253 | [DEV_STATE_VERIFY] = { | 1150 | [DEV_STATE_VERIFY] = { |
1254 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1151 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, |
1255 | [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, | 1152 | [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, |
1256 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, | 1153 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, |
1257 | [DEV_EVENT_VERIFY] = ccw_device_delay_verify, | 1154 | [DEV_EVENT_VERIFY] = ccw_device_delay_verify, |
1258 | }, | 1155 | }, |
1259 | [DEV_STATE_ONLINE] = { | 1156 | [DEV_STATE_ONLINE] = { |
1260 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1157 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, |
1261 | [DEV_EVENT_INTERRUPT] = ccw_device_irq, | 1158 | [DEV_EVENT_INTERRUPT] = ccw_device_irq, |
1262 | [DEV_EVENT_TIMEOUT] = ccw_device_online_timeout, | 1159 | [DEV_EVENT_TIMEOUT] = ccw_device_online_timeout, |
1263 | [DEV_EVENT_VERIFY] = ccw_device_online_verify, | 1160 | [DEV_EVENT_VERIFY] = ccw_device_online_verify, |
1264 | }, | 1161 | }, |
1265 | [DEV_STATE_W4SENSE] = { | 1162 | [DEV_STATE_W4SENSE] = { |
1266 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1163 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, |
1267 | [DEV_EVENT_INTERRUPT] = ccw_device_w4sense, | 1164 | [DEV_EVENT_INTERRUPT] = ccw_device_w4sense, |
1268 | [DEV_EVENT_TIMEOUT] = ccw_device_nop, | 1165 | [DEV_EVENT_TIMEOUT] = ccw_device_nop, |
1269 | [DEV_EVENT_VERIFY] = ccw_device_online_verify, | 1166 | [DEV_EVENT_VERIFY] = ccw_device_online_verify, |
1270 | }, | 1167 | }, |
1271 | [DEV_STATE_DISBAND_PGID] = { | 1168 | [DEV_STATE_DISBAND_PGID] = { |
1272 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1169 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, |
1273 | [DEV_EVENT_INTERRUPT] = ccw_device_disband_irq, | 1170 | [DEV_EVENT_INTERRUPT] = ccw_device_disband_irq, |
1274 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, | 1171 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, |
1275 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1172 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
1276 | }, | 1173 | }, |
1277 | [DEV_STATE_BOXED] = { | 1174 | [DEV_STATE_BOXED] = { |
1278 | [DEV_EVENT_NOTOPER] = ccw_device_offline_notoper, | 1175 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, |
1279 | [DEV_EVENT_INTERRUPT] = ccw_device_stlck_done, | 1176 | [DEV_EVENT_INTERRUPT] = ccw_device_stlck_done, |
1280 | [DEV_EVENT_TIMEOUT] = ccw_device_stlck_done, | 1177 | [DEV_EVENT_TIMEOUT] = ccw_device_stlck_done, |
1281 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1178 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
1282 | }, | 1179 | }, |
1283 | /* states to wait for i/o completion before doing something */ | 1180 | /* states to wait for i/o completion before doing something */ |
1284 | [DEV_STATE_CLEAR_VERIFY] = { | 1181 | [DEV_STATE_CLEAR_VERIFY] = { |
1285 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1182 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, |
1286 | [DEV_EVENT_INTERRUPT] = ccw_device_clear_verify, | 1183 | [DEV_EVENT_INTERRUPT] = ccw_device_clear_verify, |
1287 | [DEV_EVENT_TIMEOUT] = ccw_device_nop, | 1184 | [DEV_EVENT_TIMEOUT] = ccw_device_nop, |
1288 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1185 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
1289 | }, | 1186 | }, |
1290 | [DEV_STATE_TIMEOUT_KILL] = { | 1187 | [DEV_STATE_TIMEOUT_KILL] = { |
1291 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1188 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, |
1292 | [DEV_EVENT_INTERRUPT] = ccw_device_killing_irq, | 1189 | [DEV_EVENT_INTERRUPT] = ccw_device_killing_irq, |
1293 | [DEV_EVENT_TIMEOUT] = ccw_device_killing_timeout, | 1190 | [DEV_EVENT_TIMEOUT] = ccw_device_killing_timeout, |
1294 | [DEV_EVENT_VERIFY] = ccw_device_nop, //FIXME | 1191 | [DEV_EVENT_VERIFY] = ccw_device_nop, //FIXME |
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 14eba854b155..7fd2dadc3297 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c | |||
@@ -25,6 +25,16 @@ | |||
25 | #include "device.h" | 25 | #include "device.h" |
26 | #include "chp.h" | 26 | #include "chp.h" |
27 | 27 | ||
28 | /** | ||
29 | * ccw_device_set_options_mask() - set some options and unset the rest | ||
30 | * @cdev: device for which the options are to be set | ||
31 | * @flags: options to be set | ||
32 | * | ||
33 | * All flags specified in @flags are set, all flags not specified in @flags | ||
34 | * are cleared. | ||
35 | * Returns: | ||
36 | * %0 on success, -%EINVAL on an invalid flag combination. | ||
37 | */ | ||
28 | int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags) | 38 | int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags) |
29 | { | 39 | { |
30 | /* | 40 | /* |
@@ -40,6 +50,15 @@ int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags) | |||
40 | return 0; | 50 | return 0; |
41 | } | 51 | } |
42 | 52 | ||
53 | /** | ||
54 | * ccw_device_set_options() - set some options | ||
55 | * @cdev: device for which the options are to be set | ||
56 | * @flags: options to be set | ||
57 | * | ||
58 | * All flags specified in @flags are set, the remainder is left untouched. | ||
59 | * Returns: | ||
60 | * %0 on success, -%EINVAL if an invalid flag combination would ensue. | ||
61 | */ | ||
43 | int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags) | 62 | int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags) |
44 | { | 63 | { |
45 | /* | 64 | /* |
@@ -59,6 +78,13 @@ int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags) | |||
59 | return 0; | 78 | return 0; |
60 | } | 79 | } |
61 | 80 | ||
81 | /** | ||
82 | * ccw_device_clear_options() - clear some options | ||
83 | * @cdev: device for which the options are to be cleared | ||
84 | * @flags: options to be cleared | ||
85 | * | ||
86 | * All flags specified in @flags are cleared, the remainder is left untouched. | ||
87 | */ | ||
62 | void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags) | 88 | void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags) |
63 | { | 89 | { |
64 | cdev->private->options.fast &= (flags & CCWDEV_EARLY_NOTIFICATION) == 0; | 90 | cdev->private->options.fast &= (flags & CCWDEV_EARLY_NOTIFICATION) == 0; |
@@ -67,8 +93,22 @@ void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags) | |||
67 | cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0; | 93 | cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0; |
68 | } | 94 | } |
69 | 95 | ||
70 | int | 96 | /** |
71 | ccw_device_clear(struct ccw_device *cdev, unsigned long intparm) | 97 | * ccw_device_clear() - terminate I/O request processing |
98 | * @cdev: target ccw device | ||
99 | * @intparm: interruption parameter; value is only used if no I/O is | ||
100 | * outstanding, otherwise the intparm associated with the I/O request | ||
101 | * is returned | ||
102 | * | ||
103 | * ccw_device_clear() calls csch on @cdev's subchannel. | ||
104 | * Returns: | ||
105 | * %0 on success, | ||
106 | * -%ENODEV on device not operational, | ||
107 | * -%EINVAL on invalid device state. | ||
108 | * Context: | ||
109 | * Interrupts disabled, ccw device lock held | ||
110 | */ | ||
111 | int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm) | ||
72 | { | 112 | { |
73 | struct subchannel *sch; | 113 | struct subchannel *sch; |
74 | int ret; | 114 | int ret; |
@@ -89,10 +129,33 @@ ccw_device_clear(struct ccw_device *cdev, unsigned long intparm) | |||
89 | return ret; | 129 | return ret; |
90 | } | 130 | } |
91 | 131 | ||
92 | int | 132 | /** |
93 | ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, | 133 | * ccw_device_start_key() - start a s390 channel program with key |
94 | unsigned long intparm, __u8 lpm, __u8 key, | 134 | * @cdev: target ccw device |
95 | unsigned long flags) | 135 | * @cpa: logical start address of channel program |
136 | * @intparm: user specific interruption parameter; will be presented back to | ||
137 | * @cdev's interrupt handler. Allows a device driver to associate | ||
138 | * the interrupt with a particular I/O request. | ||
139 | * @lpm: defines the channel path to be used for a specific I/O request. A | ||
140 | * value of 0 will make cio use the opm. | ||
141 | * @key: storage key to be used for the I/O | ||
142 | * @flags: additional flags; defines the action to be performed for I/O | ||
143 | * processing. | ||
144 | * | ||
145 | * Start a S/390 channel program. When the interrupt arrives, the | ||
146 | * IRQ handler is called, either immediately, delayed (dev-end missing, | ||
147 | * or sense required) or never (no IRQ handler registered). | ||
148 | * Returns: | ||
149 | * %0, if the operation was successful; | ||
150 | * -%EBUSY, if the device is busy, or status pending; | ||
151 | * -%EACCES, if no path specified in @lpm is operational; | ||
152 | * -%ENODEV, if the device is not operational. | ||
153 | * Context: | ||
154 | * Interrupts disabled, ccw device lock held | ||
155 | */ | ||
156 | int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, | ||
157 | unsigned long intparm, __u8 lpm, __u8 key, | ||
158 | unsigned long flags) | ||
96 | { | 159 | { |
97 | struct subchannel *sch; | 160 | struct subchannel *sch; |
98 | int ret; | 161 | int ret; |
@@ -135,11 +198,38 @@ ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, | |||
135 | return ret; | 198 | return ret; |
136 | } | 199 | } |
137 | 200 | ||
138 | 201 | /** | |
139 | int | 202 | * ccw_device_start_timeout_key() - start a s390 channel program with timeout and key |
140 | ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa, | 203 | * @cdev: target ccw device |
141 | unsigned long intparm, __u8 lpm, __u8 key, | 204 | * @cpa: logical start address of channel program |
142 | unsigned long flags, int expires) | 205 | * @intparm: user specific interruption parameter; will be presented back to |
206 | * @cdev's interrupt handler. Allows a device driver to associate | ||
207 | * the interrupt with a particular I/O request. | ||
208 | * @lpm: defines the channel path to be used for a specific I/O request. A | ||
209 | * value of 0 will make cio use the opm. | ||
210 | * @key: storage key to be used for the I/O | ||
211 | * @flags: additional flags; defines the action to be performed for I/O | ||
212 | * processing. | ||
213 | * @expires: timeout value in jiffies | ||
214 | * | ||
215 | * Start a S/390 channel program. When the interrupt arrives, the | ||
216 | * IRQ handler is called, either immediately, delayed (dev-end missing, | ||
217 | * or sense required) or never (no IRQ handler registered). | ||
218 | * This function notifies the device driver if the channel program has not | ||
219 | * completed during the time specified by @expires. If a timeout occurs, the | ||
220 | * channel program is terminated via xsch, hsch or csch, and the device's | ||
221 | * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT). | ||
222 | * Returns: | ||
223 | * %0, if the operation was successful; | ||
224 | * -%EBUSY, if the device is busy, or status pending; | ||
225 | * -%EACCES, if no path specified in @lpm is operational; | ||
226 | * -%ENODEV, if the device is not operational. | ||
227 | * Context: | ||
228 | * Interrupts disabled, ccw device lock held | ||
229 | */ | ||
230 | int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa, | ||
231 | unsigned long intparm, __u8 lpm, __u8 key, | ||
232 | unsigned long flags, int expires) | ||
143 | { | 233 | { |
144 | int ret; | 234 | int ret; |
145 | 235 | ||
@@ -152,18 +242,67 @@ ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa, | |||
152 | return ret; | 242 | return ret; |
153 | } | 243 | } |
154 | 244 | ||
155 | int | 245 | /** |
156 | ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa, | 246 | * ccw_device_start() - start a s390 channel program |
157 | unsigned long intparm, __u8 lpm, unsigned long flags) | 247 | * @cdev: target ccw device |
248 | * @cpa: logical start address of channel program | ||
249 | * @intparm: user specific interruption parameter; will be presented back to | ||
250 | * @cdev's interrupt handler. Allows a device driver to associate | ||
251 | * the interrupt with a particular I/O request. | ||
252 | * @lpm: defines the channel path to be used for a specific I/O request. A | ||
253 | * value of 0 will make cio use the opm. | ||
254 | * @flags: additional flags; defines the action to be performed for I/O | ||
255 | * processing. | ||
256 | * | ||
257 | * Start a S/390 channel program. When the interrupt arrives, the | ||
258 | * IRQ handler is called, either immediately, delayed (dev-end missing, | ||
259 | * or sense required) or never (no IRQ handler registered). | ||
260 | * Returns: | ||
261 | * %0, if the operation was successful; | ||
262 | * -%EBUSY, if the device is busy, or status pending; | ||
263 | * -%EACCES, if no path specified in @lpm is operational; | ||
264 | * -%ENODEV, if the device is not operational. | ||
265 | * Context: | ||
266 | * Interrupts disabled, ccw device lock held | ||
267 | */ | ||
268 | int ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa, | ||
269 | unsigned long intparm, __u8 lpm, unsigned long flags) | ||
158 | { | 270 | { |
159 | return ccw_device_start_key(cdev, cpa, intparm, lpm, | 271 | return ccw_device_start_key(cdev, cpa, intparm, lpm, |
160 | PAGE_DEFAULT_KEY, flags); | 272 | PAGE_DEFAULT_KEY, flags); |
161 | } | 273 | } |
162 | 274 | ||
163 | int | 275 | /** |
164 | ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa, | 276 | * ccw_device_start_timeout() - start a s390 channel program with timeout |
165 | unsigned long intparm, __u8 lpm, unsigned long flags, | 277 | * @cdev: target ccw device |
166 | int expires) | 278 | * @cpa: logical start address of channel program |
279 | * @intparm: user specific interruption parameter; will be presented back to | ||
280 | * @cdev's interrupt handler. Allows a device driver to associate | ||
281 | * the interrupt with a particular I/O request. | ||
282 | * @lpm: defines the channel path to be used for a specific I/O request. A | ||
283 | * value of 0 will make cio use the opm. | ||
284 | * @flags: additional flags; defines the action to be performed for I/O | ||
285 | * processing. | ||
286 | * @expires: timeout value in jiffies | ||
287 | * | ||
288 | * Start a S/390 channel program. When the interrupt arrives, the | ||
289 | * IRQ handler is called, either immediately, delayed (dev-end missing, | ||
290 | * or sense required) or never (no IRQ handler registered). | ||
291 | * This function notifies the device driver if the channel program has not | ||
292 | * completed during the time specified by @expires. If a timeout occurs, the | ||
293 | * channel program is terminated via xsch, hsch or csch, and the device's | ||
294 | * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT). | ||
295 | * Returns: | ||
296 | * %0, if the operation was successful; | ||
297 | * -%EBUSY, if the device is busy, or status pending; | ||
298 | * -%EACCES, if no path specified in @lpm is operational; | ||
299 | * -%ENODEV, if the device is not operational. | ||
300 | * Context: | ||
301 | * Interrupts disabled, ccw device lock held | ||
302 | */ | ||
303 | int ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa, | ||
304 | unsigned long intparm, __u8 lpm, | ||
305 | unsigned long flags, int expires) | ||
167 | { | 306 | { |
168 | return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, | 307 | return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, |
169 | PAGE_DEFAULT_KEY, flags, | 308 | PAGE_DEFAULT_KEY, flags, |
@@ -171,8 +310,23 @@ ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa, | |||
171 | } | 310 | } |
172 | 311 | ||
173 | 312 | ||
174 | int | 313 | /** |
175 | ccw_device_halt(struct ccw_device *cdev, unsigned long intparm) | 314 | * ccw_device_halt() - halt I/O request processing |
315 | * @cdev: target ccw device | ||
316 | * @intparm: interruption parameter; value is only used if no I/O is | ||
317 | * outstanding, otherwise the intparm associated with the I/O request | ||
318 | * is returned | ||
319 | * | ||
320 | * ccw_device_halt() calls hsch on @cdev's subchannel. | ||
321 | * Returns: | ||
322 | * %0 on success, | ||
323 | * -%ENODEV on device not operational, | ||
324 | * -%EINVAL on invalid device state, | ||
325 | * -%EBUSY on device busy or interrupt pending. | ||
326 | * Context: | ||
327 | * Interrupts disabled, ccw device lock held | ||
328 | */ | ||
329 | int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm) | ||
176 | { | 330 | { |
177 | struct subchannel *sch; | 331 | struct subchannel *sch; |
178 | int ret; | 332 | int ret; |
@@ -193,8 +347,20 @@ ccw_device_halt(struct ccw_device *cdev, unsigned long intparm) | |||
193 | return ret; | 347 | return ret; |
194 | } | 348 | } |
195 | 349 | ||
196 | int | 350 | /** |
197 | ccw_device_resume(struct ccw_device *cdev) | 351 | * ccw_device_resume() - resume channel program execution |
352 | * @cdev: target ccw device | ||
353 | * | ||
354 | * ccw_device_resume() calls rsch on @cdev's subchannel. | ||
355 | * Returns: | ||
356 | * %0 on success, | ||
357 | * -%ENODEV on device not operational, | ||
358 | * -%EINVAL on invalid device state, | ||
359 | * -%EBUSY on device busy or interrupt pending. | ||
360 | * Context: | ||
361 | * Interrupts disabled, ccw device lock held | ||
362 | */ | ||
363 | int ccw_device_resume(struct ccw_device *cdev) | ||
198 | { | 364 | { |
199 | struct subchannel *sch; | 365 | struct subchannel *sch; |
200 | 366 | ||
@@ -260,11 +426,21 @@ ccw_device_call_handler(struct ccw_device *cdev) | |||
260 | return 1; | 426 | return 1; |
261 | } | 427 | } |
262 | 428 | ||
263 | /* | 429 | /** |
264 | * Search for CIW command in extended sense data. | 430 | * ccw_device_get_ciw() - Search for CIW command in extended sense data. |
431 | * @cdev: ccw device to inspect | ||
432 | * @ct: command type to look for | ||
433 | * | ||
434 | * During SenseID, command information words (CIWs) describing special | ||
435 | * commands available to the device may have been stored in the extended | ||
436 | * sense data. This function searches for CIWs of a specified command | ||
437 | * type in the extended sense data. | ||
438 | * Returns: | ||
439 | * %NULL if no extended sense data has been stored or if no CIW of the | ||
440 | * specified command type could be found, | ||
441 | * else a pointer to the CIW of the specified command type. | ||
265 | */ | 442 | */ |
266 | struct ciw * | 443 | struct ciw *ccw_device_get_ciw(struct ccw_device *cdev, __u32 ct) |
267 | ccw_device_get_ciw(struct ccw_device *cdev, __u32 ct) | ||
268 | { | 444 | { |
269 | int ciw_cnt; | 445 | int ciw_cnt; |
270 | 446 | ||
@@ -276,8 +452,14 @@ ccw_device_get_ciw(struct ccw_device *cdev, __u32 ct) | |||
276 | return NULL; | 452 | return NULL; |
277 | } | 453 | } |
278 | 454 | ||
279 | __u8 | 455 | /** |
280 | ccw_device_get_path_mask(struct ccw_device *cdev) | 456 | * ccw_device_get_path_mask() - get currently available paths |
457 | * @cdev: ccw device to be queried | ||
458 | * Returns: | ||
459 | * %0 if no subchannel for the device is available, | ||
460 | * else the mask of currently available paths for the ccw device's subchannel. | ||
461 | */ | ||
462 | __u8 ccw_device_get_path_mask(struct ccw_device *cdev) | ||
281 | { | 463 | { |
282 | struct subchannel *sch; | 464 | struct subchannel *sch; |
283 | 465 | ||
@@ -357,8 +539,7 @@ out_unlock: | |||
357 | return ret; | 539 | return ret; |
358 | } | 540 | } |
359 | 541 | ||
360 | void * | 542 | void *ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no) |
361 | ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no) | ||
362 | { | 543 | { |
363 | struct subchannel *sch; | 544 | struct subchannel *sch; |
364 | struct chp_id chpid; | 545 | struct chp_id chpid; |
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index d8d479876ec7..40a3208c7cf3 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
@@ -1024,9 +1024,9 @@ __qdio_outbound_processing(struct qdio_q *q) | |||
1024 | } | 1024 | } |
1025 | 1025 | ||
1026 | static void | 1026 | static void |
1027 | qdio_outbound_processing(struct qdio_q *q) | 1027 | qdio_outbound_processing(unsigned long q) |
1028 | { | 1028 | { |
1029 | __qdio_outbound_processing(q); | 1029 | __qdio_outbound_processing((struct qdio_q *) q); |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | /************************* INBOUND ROUTINES *******************************/ | 1032 | /************************* INBOUND ROUTINES *******************************/ |
@@ -1449,9 +1449,10 @@ out: | |||
1449 | } | 1449 | } |
1450 | 1450 | ||
1451 | static void | 1451 | static void |
1452 | tiqdio_inbound_processing(struct qdio_q *q) | 1452 | tiqdio_inbound_processing(unsigned long q) |
1453 | { | 1453 | { |
1454 | __tiqdio_inbound_processing(q, atomic_read(&spare_indicator_usecount)); | 1454 | __tiqdio_inbound_processing((struct qdio_q *) q, |
1455 | atomic_read(&spare_indicator_usecount)); | ||
1455 | } | 1456 | } |
1456 | 1457 | ||
1457 | static void | 1458 | static void |
@@ -1494,9 +1495,9 @@ again: | |||
1494 | } | 1495 | } |
1495 | 1496 | ||
1496 | static void | 1497 | static void |
1497 | qdio_inbound_processing(struct qdio_q *q) | 1498 | qdio_inbound_processing(unsigned long q) |
1498 | { | 1499 | { |
1499 | __qdio_inbound_processing(q); | 1500 | __qdio_inbound_processing((struct qdio_q *) q); |
1500 | } | 1501 | } |
1501 | 1502 | ||
1502 | /************************* MAIN ROUTINES *******************************/ | 1503 | /************************* MAIN ROUTINES *******************************/ |
@@ -1760,12 +1761,15 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, | |||
1760 | q->handler=input_handler; | 1761 | q->handler=input_handler; |
1761 | q->dev_st_chg_ind=irq_ptr->dev_st_chg_ind; | 1762 | q->dev_st_chg_ind=irq_ptr->dev_st_chg_ind; |
1762 | 1763 | ||
1763 | q->tasklet.data=(unsigned long)q; | ||
1764 | /* q->is_thinint_q isn't valid at this time, but | 1764 | /* q->is_thinint_q isn't valid at this time, but |
1765 | * irq_ptr->is_thinint_irq is */ | 1765 | * irq_ptr->is_thinint_irq is |
1766 | q->tasklet.func=(void(*)(unsigned long)) | 1766 | */ |
1767 | ((irq_ptr->is_thinint_irq)?&tiqdio_inbound_processing: | 1767 | if (irq_ptr->is_thinint_irq) |
1768 | &qdio_inbound_processing); | 1768 | tasklet_init(&q->tasklet, tiqdio_inbound_processing, |
1769 | (unsigned long) q); | ||
1770 | else | ||
1771 | tasklet_init(&q->tasklet, qdio_inbound_processing, | ||
1772 | (unsigned long) q); | ||
1769 | 1773 | ||
1770 | /* actually this is not used for inbound queues. yet. */ | 1774 | /* actually this is not used for inbound queues. yet. */ |
1771 | atomic_set(&q->busy_siga_counter,0); | 1775 | atomic_set(&q->busy_siga_counter,0); |
@@ -1836,13 +1840,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, | |||
1836 | q->last_move_ftc=0; | 1840 | q->last_move_ftc=0; |
1837 | q->handler=output_handler; | 1841 | q->handler=output_handler; |
1838 | 1842 | ||
1839 | q->tasklet.data=(unsigned long)q; | 1843 | tasklet_init(&q->tasklet, qdio_outbound_processing, |
1840 | q->tasklet.func=(void(*)(unsigned long)) | 1844 | (unsigned long) q); |
1841 | &qdio_outbound_processing; | 1845 | setup_timer(&q->timer, qdio_outbound_processing, |
1842 | q->timer.function=(void(*)(unsigned long)) | 1846 | (unsigned long) q); |
1843 | &qdio_outbound_processing; | ||
1844 | q->timer.data = (long)q; | ||
1845 | init_timer(&q->timer); | ||
1846 | 1847 | ||
1847 | atomic_set(&q->busy_siga_counter,0); | 1848 | atomic_set(&q->busy_siga_counter,0); |
1848 | q->timing.busy_start=0; | 1849 | q->timing.busy_start=0; |
@@ -3726,7 +3727,7 @@ qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count | |||
3726 | #endif /* CONFIG_64BIT */ | 3727 | #endif /* CONFIG_64BIT */ |
3727 | } | 3728 | } |
3728 | } else { | 3729 | } else { |
3729 | QDIO_PRINT_WARN("QDIO performance_stats: write 0 or 1 to this file!\n"); | 3730 | QDIO_PRINT_ERR("QDIO performance_stats: write 0 or 1 to this file!\n"); |
3730 | return -EINVAL; | 3731 | return -EINVAL; |
3731 | } | 3732 | } |
3732 | return count; | 3733 | return count; |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 90bd22014513..67aaff3e668d 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -458,28 +458,22 @@ static int ap_bus_match(struct device *dev, struct device_driver *drv) | |||
458 | * uevent function for AP devices. It sets up a single environment | 458 | * uevent function for AP devices. It sets up a single environment |
459 | * variable DEV_TYPE which contains the hardware device type. | 459 | * variable DEV_TYPE which contains the hardware device type. |
460 | */ | 460 | */ |
461 | static int ap_uevent (struct device *dev, char **envp, int num_envp, | 461 | static int ap_uevent (struct device *dev, struct kobj_uevent_env *env) |
462 | char *buffer, int buffer_size) | ||
463 | { | 462 | { |
464 | struct ap_device *ap_dev = to_ap_dev(dev); | 463 | struct ap_device *ap_dev = to_ap_dev(dev); |
465 | int retval = 0, length = 0, i = 0; | 464 | int retval = 0; |
466 | 465 | ||
467 | if (!ap_dev) | 466 | if (!ap_dev) |
468 | return -ENODEV; | 467 | return -ENODEV; |
469 | 468 | ||
470 | /* Set up DEV_TYPE environment variable. */ | 469 | /* Set up DEV_TYPE environment variable. */ |
471 | retval = add_uevent_var(envp, num_envp, &i, | 470 | retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type); |
472 | buffer, buffer_size, &length, | ||
473 | "DEV_TYPE=%04X", ap_dev->device_type); | ||
474 | if (retval) | 471 | if (retval) |
475 | return retval; | 472 | return retval; |
476 | 473 | ||
477 | /* Add MODALIAS= */ | 474 | /* Add MODALIAS= */ |
478 | retval = add_uevent_var(envp, num_envp, &i, | 475 | retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type); |
479 | buffer, buffer_size, &length, | ||
480 | "MODALIAS=ap:t%02X", ap_dev->device_type); | ||
481 | 476 | ||
482 | envp[i] = NULL; | ||
483 | return retval; | 477 | return retval; |
484 | } | 478 | } |
485 | 479 | ||
@@ -1231,8 +1225,9 @@ static void ap_reset_domain(void) | |||
1231 | { | 1225 | { |
1232 | int i; | 1226 | int i; |
1233 | 1227 | ||
1234 | for (i = 0; i < AP_DEVICES; i++) | 1228 | if (ap_domain_index != -1) |
1235 | ap_reset_queue(AP_MKQID(i, ap_domain_index)); | 1229 | for (i = 0; i < AP_DEVICES; i++) |
1230 | ap_reset_queue(AP_MKQID(i, ap_domain_index)); | ||
1236 | } | 1231 | } |
1237 | 1232 | ||
1238 | static void ap_reset_all(void) | 1233 | static void ap_reset_all(void) |
diff --git a/drivers/s390/crypto/zcrypt_mono.c b/drivers/s390/crypto/zcrypt_mono.c index 2a9349ad68b7..44253fdd4136 100644 --- a/drivers/s390/crypto/zcrypt_mono.c +++ b/drivers/s390/crypto/zcrypt_mono.c | |||
@@ -45,7 +45,7 @@ | |||
45 | /** | 45 | /** |
46 | * The module initialization code. | 46 | * The module initialization code. |
47 | */ | 47 | */ |
48 | int __init zcrypt_init(void) | 48 | static int __init zcrypt_init(void) |
49 | { | 49 | { |
50 | int rc; | 50 | int rc; |
51 | 51 | ||
@@ -86,7 +86,7 @@ out: | |||
86 | /** | 86 | /** |
87 | * The module termination code. | 87 | * The module termination code. |
88 | */ | 88 | */ |
89 | void __exit zcrypt_exit(void) | 89 | static void __exit zcrypt_exit(void) |
90 | { | 90 | { |
91 | zcrypt_cex2a_exit(); | 91 | zcrypt_cex2a_exit(); |
92 | zcrypt_pcixcc_exit(); | 92 | zcrypt_pcixcc_exit(); |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 64948788d301..70b9ddc8cf9d 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
@@ -277,7 +277,7 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
277 | }; | 277 | }; |
278 | struct { | 278 | struct { |
279 | struct type6_hdr hdr; | 279 | struct type6_hdr hdr; |
280 | struct ica_CPRBX cprbx; | 280 | struct CPRBX cprbx; |
281 | } __attribute__((packed)) *msg = ap_msg->message; | 281 | } __attribute__((packed)) *msg = ap_msg->message; |
282 | 282 | ||
283 | int rcblen = CEIL4(xcRB->request_control_blk_length); | 283 | int rcblen = CEIL4(xcRB->request_control_blk_length); |
@@ -432,14 +432,17 @@ static int convert_type86_ica(struct zcrypt_device *zdev, | |||
432 | } | 432 | } |
433 | if (service_rc == 8 && service_rs == 770) { | 433 | if (service_rc == 8 && service_rs == 770) { |
434 | PDEBUG("Invalid key length on PCIXCC/CEX2C\n"); | 434 | PDEBUG("Invalid key length on PCIXCC/CEX2C\n"); |
435 | zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD; | 435 | return -EINVAL; |
436 | return -EAGAIN; | ||
437 | } | 436 | } |
438 | if (service_rc == 8 && service_rs == 783) { | 437 | if (service_rc == 8 && service_rs == 783) { |
439 | PDEBUG("Extended bitlengths not enabled on PCIXCC/CEX2C\n"); | 438 | PDEBUG("Extended bitlengths not enabled on PCIXCC/CEX2C\n"); |
440 | zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD; | 439 | zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD; |
441 | return -EAGAIN; | 440 | return -EAGAIN; |
442 | } | 441 | } |
442 | if (service_rc == 12 && service_rs == 769) { | ||
443 | PDEBUG("Invalid key on PCIXCC/CEX2C\n"); | ||
444 | return -EINVAL; | ||
445 | } | ||
443 | PRINTK("Unknown service rc/rs (PCIXCC/CEX2C): %d/%d\n", | 446 | PRINTK("Unknown service rc/rs (PCIXCC/CEX2C): %d/%d\n", |
444 | service_rc, service_rs); | 447 | service_rc, service_rs); |
445 | zdev->online = 0; | 448 | zdev->online = 0; |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.h b/drivers/s390/crypto/zcrypt_pcixcc.h index a78ff307fd19..8cb7d7a6973b 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.h +++ b/drivers/s390/crypto/zcrypt_pcixcc.h | |||
@@ -28,51 +28,6 @@ | |||
28 | #ifndef _ZCRYPT_PCIXCC_H_ | 28 | #ifndef _ZCRYPT_PCIXCC_H_ |
29 | #define _ZCRYPT_PCIXCC_H_ | 29 | #define _ZCRYPT_PCIXCC_H_ |
30 | 30 | ||
31 | /** | ||
32 | * CPRBX | ||
33 | * Note that all shorts and ints are big-endian. | ||
34 | * All pointer fields are 16 bytes long, and mean nothing. | ||
35 | * | ||
36 | * A request CPRB is followed by a request_parameter_block. | ||
37 | * | ||
38 | * The request (or reply) parameter block is organized thus: | ||
39 | * function code | ||
40 | * VUD block | ||
41 | * key block | ||
42 | */ | ||
43 | struct CPRBX { | ||
44 | unsigned short cprb_len; /* CPRB length 220 */ | ||
45 | unsigned char cprb_ver_id; /* CPRB version id. 0x02 */ | ||
46 | unsigned char pad_000[3]; /* Alignment pad bytes */ | ||
47 | unsigned char func_id[2]; /* function id 0x5432 */ | ||
48 | unsigned char cprb_flags[4]; /* Flags */ | ||
49 | unsigned int req_parml; /* request parameter buffer len */ | ||
50 | unsigned int req_datal; /* request data buffer */ | ||
51 | unsigned int rpl_msgbl; /* reply message block length */ | ||
52 | unsigned int rpld_parml; /* replied parameter block len */ | ||
53 | unsigned int rpl_datal; /* reply data block len */ | ||
54 | unsigned int rpld_datal; /* replied data block len */ | ||
55 | unsigned int req_extbl; /* request extension block len */ | ||
56 | unsigned char pad_001[4]; /* reserved */ | ||
57 | unsigned int rpld_extbl; /* replied extension block len */ | ||
58 | unsigned char req_parmb[16]; /* request parm block 'address' */ | ||
59 | unsigned char req_datab[16]; /* request data block 'address' */ | ||
60 | unsigned char rpl_parmb[16]; /* reply parm block 'address' */ | ||
61 | unsigned char rpl_datab[16]; /* reply data block 'address' */ | ||
62 | unsigned char req_extb[16]; /* request extension block 'addr'*/ | ||
63 | unsigned char rpl_extb[16]; /* reply extension block 'addres'*/ | ||
64 | unsigned short ccp_rtcode; /* server return code */ | ||
65 | unsigned short ccp_rscode; /* server reason code */ | ||
66 | unsigned int mac_data_len; /* Mac Data Length */ | ||
67 | unsigned char logon_id[8]; /* Logon Identifier */ | ||
68 | unsigned char mac_value[8]; /* Mac Value */ | ||
69 | unsigned char mac_content_flgs;/* Mac content flag byte */ | ||
70 | unsigned char pad_002; /* Alignment */ | ||
71 | unsigned short domain; /* Domain */ | ||
72 | unsigned char pad_003[12]; /* Domain masks */ | ||
73 | unsigned char pad_004[36]; /* reserved */ | ||
74 | } __attribute__((packed)); | ||
75 | |||
76 | int zcrypt_pcixcc_init(void); | 31 | int zcrypt_pcixcc_init(void); |
77 | void zcrypt_pcixcc_exit(void); | 32 | void zcrypt_pcixcc_exit(void); |
78 | 33 | ||
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 1c8f71a59855..c0d1c0eb3209 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
@@ -28,7 +28,7 @@ static void zfcp_ccw_remove(struct ccw_device *); | |||
28 | static int zfcp_ccw_set_online(struct ccw_device *); | 28 | static int zfcp_ccw_set_online(struct ccw_device *); |
29 | static int zfcp_ccw_set_offline(struct ccw_device *); | 29 | static int zfcp_ccw_set_offline(struct ccw_device *); |
30 | static int zfcp_ccw_notify(struct ccw_device *, int); | 30 | static int zfcp_ccw_notify(struct ccw_device *, int); |
31 | static void zfcp_ccw_shutdown(struct device *); | 31 | static void zfcp_ccw_shutdown(struct ccw_device *); |
32 | 32 | ||
33 | static struct ccw_device_id zfcp_ccw_device_id[] = { | 33 | static struct ccw_device_id zfcp_ccw_device_id[] = { |
34 | {CCW_DEVICE_DEVTYPE(ZFCP_CONTROL_UNIT_TYPE, | 34 | {CCW_DEVICE_DEVTYPE(ZFCP_CONTROL_UNIT_TYPE, |
@@ -51,9 +51,7 @@ static struct ccw_driver zfcp_ccw_driver = { | |||
51 | .set_online = zfcp_ccw_set_online, | 51 | .set_online = zfcp_ccw_set_online, |
52 | .set_offline = zfcp_ccw_set_offline, | 52 | .set_offline = zfcp_ccw_set_offline, |
53 | .notify = zfcp_ccw_notify, | 53 | .notify = zfcp_ccw_notify, |
54 | .driver = { | 54 | .shutdown = zfcp_ccw_shutdown, |
55 | .shutdown = zfcp_ccw_shutdown, | ||
56 | }, | ||
57 | }; | 55 | }; |
58 | 56 | ||
59 | MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); | 57 | MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); |
@@ -277,12 +275,12 @@ zfcp_ccw_register(void) | |||
277 | * Makes sure that QDIO queues are down when the system gets stopped. | 275 | * Makes sure that QDIO queues are down when the system gets stopped. |
278 | */ | 276 | */ |
279 | static void | 277 | static void |
280 | zfcp_ccw_shutdown(struct device *dev) | 278 | zfcp_ccw_shutdown(struct ccw_device *cdev) |
281 | { | 279 | { |
282 | struct zfcp_adapter *adapter; | 280 | struct zfcp_adapter *adapter; |
283 | 281 | ||
284 | down(&zfcp_data.config_sema); | 282 | down(&zfcp_data.config_sema); |
285 | adapter = dev_get_drvdata(dev); | 283 | adapter = dev_get_drvdata(&cdev->dev); |
286 | zfcp_erp_adapter_shutdown(adapter, 0); | 284 | zfcp_erp_adapter_shutdown(adapter, 0); |
287 | zfcp_erp_wait(adapter); | 285 | zfcp_erp_wait(adapter); |
288 | up(&zfcp_data.config_sema); | 286 | up(&zfcp_data.config_sema); |
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 5f3212440f68..ffa3bf756943 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -19,8 +19,8 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <asm/debug.h> | ||
23 | #include <linux/ctype.h> | 22 | #include <linux/ctype.h> |
23 | #include <asm/debug.h> | ||
24 | #include "zfcp_ext.h" | 24 | #include "zfcp_ext.h" |
25 | 25 | ||
26 | static u32 dbfsize = 4; | 26 | static u32 dbfsize = 4; |
@@ -35,17 +35,17 @@ static int | |||
35 | zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck) | 35 | zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck) |
36 | { | 36 | { |
37 | unsigned long long sec; | 37 | unsigned long long sec; |
38 | struct timespec xtime; | 38 | struct timespec dbftime; |
39 | int len = 0; | 39 | int len = 0; |
40 | 40 | ||
41 | stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); | 41 | stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); |
42 | sec = stck >> 12; | 42 | sec = stck >> 12; |
43 | do_div(sec, 1000000); | 43 | do_div(sec, 1000000); |
44 | xtime.tv_sec = sec; | 44 | dbftime.tv_sec = sec; |
45 | stck -= (sec * 1000000) << 12; | 45 | stck -= (sec * 1000000) << 12; |
46 | xtime.tv_nsec = ((stck * 1000) >> 12); | 46 | dbftime.tv_nsec = ((stck * 1000) >> 12); |
47 | len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n", | 47 | len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n", |
48 | label, xtime.tv_sec, xtime.tv_nsec); | 48 | label, dbftime.tv_sec, dbftime.tv_nsec); |
49 | 49 | ||
50 | return len; | 50 | return len; |
51 | } | 51 | } |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index d8cd75ce2d9a..16b4418ab257 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -54,7 +54,7 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *, int); | |||
54 | static int zfcp_erp_strategy_statechange(int, u32, struct zfcp_adapter *, | 54 | static int zfcp_erp_strategy_statechange(int, u32, struct zfcp_adapter *, |
55 | struct zfcp_port *, | 55 | struct zfcp_port *, |
56 | struct zfcp_unit *, int); | 56 | struct zfcp_unit *, int); |
57 | static inline int zfcp_erp_strategy_statechange_detected(atomic_t *, u32); | 57 | static int zfcp_erp_strategy_statechange_detected(atomic_t *, u32); |
58 | static int zfcp_erp_strategy_followup_actions(int, struct zfcp_adapter *, | 58 | static int zfcp_erp_strategy_followup_actions(int, struct zfcp_adapter *, |
59 | struct zfcp_port *, | 59 | struct zfcp_port *, |
60 | struct zfcp_unit *, int); | 60 | struct zfcp_unit *, int); |
@@ -106,8 +106,8 @@ static void zfcp_erp_action_cleanup(int, struct zfcp_adapter *, | |||
106 | static void zfcp_erp_action_ready(struct zfcp_erp_action *); | 106 | static void zfcp_erp_action_ready(struct zfcp_erp_action *); |
107 | static int zfcp_erp_action_exists(struct zfcp_erp_action *); | 107 | static int zfcp_erp_action_exists(struct zfcp_erp_action *); |
108 | 108 | ||
109 | static inline void zfcp_erp_action_to_ready(struct zfcp_erp_action *); | 109 | static void zfcp_erp_action_to_ready(struct zfcp_erp_action *); |
110 | static inline void zfcp_erp_action_to_running(struct zfcp_erp_action *); | 110 | static void zfcp_erp_action_to_running(struct zfcp_erp_action *); |
111 | 111 | ||
112 | static void zfcp_erp_memwait_handler(unsigned long); | 112 | static void zfcp_erp_memwait_handler(unsigned long); |
113 | 113 | ||
@@ -952,7 +952,7 @@ zfcp_erp_memwait_handler(unsigned long data) | |||
952 | * action gets an appropriate flag and will be processed | 952 | * action gets an appropriate flag and will be processed |
953 | * accordingly | 953 | * accordingly |
954 | */ | 954 | */ |
955 | void zfcp_erp_timeout_handler(unsigned long data) | 955 | static void zfcp_erp_timeout_handler(unsigned long data) |
956 | { | 956 | { |
957 | struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data; | 957 | struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data; |
958 | struct zfcp_adapter *adapter = erp_action->adapter; | 958 | struct zfcp_adapter *adapter = erp_action->adapter; |
@@ -1491,7 +1491,7 @@ zfcp_erp_strategy_statechange(int action, | |||
1491 | return retval; | 1491 | return retval; |
1492 | } | 1492 | } |
1493 | 1493 | ||
1494 | static inline int | 1494 | static int |
1495 | zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status) | 1495 | zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status) |
1496 | { | 1496 | { |
1497 | return | 1497 | return |
@@ -2001,7 +2001,7 @@ zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close) | |||
2001 | * returns: 0 - successful setup | 2001 | * returns: 0 - successful setup |
2002 | * !0 - failed setup | 2002 | * !0 - failed setup |
2003 | */ | 2003 | */ |
2004 | int | 2004 | static int |
2005 | zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) | 2005 | zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) |
2006 | { | 2006 | { |
2007 | int retval; | 2007 | int retval; |
@@ -3248,8 +3248,7 @@ static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) | |||
3248 | zfcp_erp_action_dismiss(&unit->erp_action); | 3248 | zfcp_erp_action_dismiss(&unit->erp_action); |
3249 | } | 3249 | } |
3250 | 3250 | ||
3251 | static inline void | 3251 | static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) |
3252 | zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) | ||
3253 | { | 3252 | { |
3254 | struct zfcp_adapter *adapter = erp_action->adapter; | 3253 | struct zfcp_adapter *adapter = erp_action->adapter; |
3255 | 3254 | ||
@@ -3258,8 +3257,7 @@ zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) | |||
3258 | list_move(&erp_action->list, &erp_action->adapter->erp_running_head); | 3257 | list_move(&erp_action->list, &erp_action->adapter->erp_running_head); |
3259 | } | 3258 | } |
3260 | 3259 | ||
3261 | static inline void | 3260 | static void zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action) |
3262 | zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action) | ||
3263 | { | 3261 | { |
3264 | struct zfcp_adapter *adapter = erp_action->adapter; | 3262 | struct zfcp_adapter *adapter = erp_action->adapter; |
3265 | 3263 | ||
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 34cdce6738a6..ede9986d349a 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -277,16 +277,11 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) | |||
277 | return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0; | 277 | return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0; |
278 | } | 278 | } |
279 | 279 | ||
280 | static int scsi_bus_uevent(struct device *dev, char **envp, int num_envp, | 280 | static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) |
281 | char *buffer, int buffer_size) | ||
282 | { | 281 | { |
283 | struct scsi_device *sdev = to_scsi_device(dev); | 282 | struct scsi_device *sdev = to_scsi_device(dev); |
284 | int i = 0; | ||
285 | int length = 0; | ||
286 | 283 | ||
287 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | 284 | add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type); |
288 | "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type); | ||
289 | envp[i] = NULL; | ||
290 | return 0; | 285 | return 0; |
291 | } | 286 | } |
292 | 287 | ||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index e84d21597943..bcb8dd5fb0b4 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -67,14 +67,11 @@ static int spi_match_device(struct device *dev, struct device_driver *drv) | |||
67 | return strncmp(spi->modalias, drv->name, BUS_ID_SIZE) == 0; | 67 | return strncmp(spi->modalias, drv->name, BUS_ID_SIZE) == 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | static int spi_uevent(struct device *dev, char **envp, int num_envp, | 70 | static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) |
71 | char *buffer, int buffer_size) | ||
72 | { | 71 | { |
73 | const struct spi_device *spi = to_spi_device(dev); | 72 | const struct spi_device *spi = to_spi_device(dev); |
74 | 73 | ||
75 | envp[0] = buffer; | 74 | add_uevent_var(env, "MODALIAS=%s", spi->modalias); |
76 | snprintf(buffer, buffer_size, "MODALIAS=%s", spi->modalias); | ||
77 | envp[1] = NULL; | ||
78 | return 0; | 75 | return 0; |
79 | } | 76 | } |
80 | 77 | ||
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index ac49b15fa768..516a6400db43 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -28,27 +28,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/ | |||
28 | 28 | ||
29 | obj-$(CONFIG_USB_SERIAL) += serial/ | 29 | obj-$(CONFIG_USB_SERIAL) += serial/ |
30 | 30 | ||
31 | obj-$(CONFIG_USB_ADUTUX) += misc/ | 31 | obj-$(CONFIG_USB) += misc/ |
32 | obj-$(CONFIG_USB_APPLEDISPLAY) += misc/ | ||
33 | obj-$(CONFIG_USB_AUERSWALD) += misc/ | ||
34 | obj-$(CONFIG_USB_BERRY_CHARGE) += misc/ | ||
35 | obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/ | ||
36 | obj-$(CONFIG_USB_CYTHERM) += misc/ | ||
37 | obj-$(CONFIG_USB_EMI26) += misc/ | ||
38 | obj-$(CONFIG_USB_EMI62) += misc/ | ||
39 | obj-$(CONFIG_USB_FTDI_ELAN) += misc/ | ||
40 | obj-$(CONFIG_USB_IDMOUSE) += misc/ | ||
41 | obj-$(CONFIG_USB_LCD) += misc/ | ||
42 | obj-$(CONFIG_USB_LD) += misc/ | ||
43 | obj-$(CONFIG_USB_LED) += misc/ | ||
44 | obj-$(CONFIG_USB_LEGOTOWER) += misc/ | ||
45 | obj-$(CONFIG_USB_PHIDGETSERVO) += misc/ | ||
46 | obj-$(CONFIG_USB_RIO500) += misc/ | ||
47 | obj-$(CONFIG_USB_SISUSBVGA) += misc/ | ||
48 | obj-$(CONFIG_USB_TEST) += misc/ | ||
49 | obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/ | ||
50 | obj-$(CONFIG_USB_USS720) += misc/ | ||
51 | obj-$(CONFIG_USB_IOWARRIOR) += misc/ | ||
52 | 32 | ||
53 | obj-$(CONFIG_USB_ATM) += atm/ | 33 | obj-$(CONFIG_USB_ATM) += atm/ |
54 | obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ | 34 | obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index a73e714288e5..a51eeedc18d4 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -482,7 +482,9 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
482 | int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE; | 482 | int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE; |
483 | 483 | ||
484 | if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) { | 484 | if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) { |
485 | dbg("too big transfer requested"); | 485 | if (printk_ratelimit()) |
486 | usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n", | ||
487 | wbuflen, rbuflen); | ||
486 | ret = -ENOMEM; | 488 | ret = -ENOMEM; |
487 | goto fail; | 489 | goto fail; |
488 | } | 490 | } |
@@ -493,8 +495,9 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
493 | init_completion(&instance->rcv_done); | 495 | init_completion(&instance->rcv_done); |
494 | ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL); | 496 | ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL); |
495 | if (ret < 0) { | 497 | if (ret < 0) { |
496 | dbg("submitting read urb for cm %#x failed", cm); | 498 | if (printk_ratelimit()) |
497 | ret = ret; | 499 | usb_err(instance->usbatm, "submit of read urb for cm %#x failed (%d)\n", |
500 | cm, ret); | ||
498 | goto fail; | 501 | goto fail; |
499 | } | 502 | } |
500 | 503 | ||
@@ -510,27 +513,29 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
510 | init_completion(&instance->snd_done); | 513 | init_completion(&instance->snd_done); |
511 | ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL); | 514 | ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL); |
512 | if (ret < 0) { | 515 | if (ret < 0) { |
513 | dbg("submitting write urb for cm %#x failed", cm); | 516 | if (printk_ratelimit()) |
514 | ret = ret; | 517 | usb_err(instance->usbatm, "submit of write urb for cm %#x failed (%d)\n", |
518 | cm, ret); | ||
515 | goto fail; | 519 | goto fail; |
516 | } | 520 | } |
517 | 521 | ||
518 | ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL); | 522 | ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL); |
519 | if (ret < 0) { | 523 | if (ret < 0) { |
520 | dbg("sending cm %#x failed", cm); | 524 | if (printk_ratelimit()) |
521 | ret = ret; | 525 | usb_err(instance->usbatm, "send of cm %#x failed (%d)\n", cm, ret); |
522 | goto fail; | 526 | goto fail; |
523 | } | 527 | } |
524 | 528 | ||
525 | ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen); | 529 | ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen); |
526 | if (ret < 0) { | 530 | if (ret < 0) { |
527 | dbg("receiving cm %#x failed", cm); | 531 | if (printk_ratelimit()) |
528 | ret = ret; | 532 | usb_err(instance->usbatm, "receive of cm %#x failed (%d)\n", cm, ret); |
529 | goto fail; | 533 | goto fail; |
530 | } | 534 | } |
531 | if (actlen % CMD_PACKET_SIZE || !actlen) { | 535 | if (actlen % CMD_PACKET_SIZE || !actlen) { |
532 | dbg("response is not a positive multiple of %d: %#x", | 536 | if (printk_ratelimit()) |
533 | CMD_PACKET_SIZE, actlen); | 537 | usb_err(instance->usbatm, "invalid response length to cm %#x: %d\n", |
538 | cm, actlen); | ||
534 | ret = -EIO; | 539 | ret = -EIO; |
535 | goto fail; | 540 | goto fail; |
536 | } | 541 | } |
@@ -538,12 +543,16 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
538 | /* check the return status and copy the data to the output buffer, if needed */ | 543 | /* check the return status and copy the data to the output buffer, if needed */ |
539 | for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) { | 544 | for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) { |
540 | if (rbuf[offb] != cm) { | 545 | if (rbuf[offb] != cm) { |
541 | dbg("wrong cm %#x in response", rbuf[offb]); | 546 | if (printk_ratelimit()) |
547 | usb_err(instance->usbatm, "wrong cm %#x in response to cm %#x\n", | ||
548 | rbuf[offb], cm); | ||
542 | ret = -EIO; | 549 | ret = -EIO; |
543 | goto fail; | 550 | goto fail; |
544 | } | 551 | } |
545 | if (rbuf[offb + 1] != CM_STATUS_SUCCESS) { | 552 | if (rbuf[offb + 1] != CM_STATUS_SUCCESS) { |
546 | dbg("response failed: %#x", rbuf[offb + 1]); | 553 | if (printk_ratelimit()) |
554 | usb_err(instance->usbatm, "response to cm %#x failed: %#x\n", | ||
555 | cm, rbuf[offb + 1]); | ||
547 | ret = -EIO; | 556 | ret = -EIO; |
548 | goto fail; | 557 | goto fail; |
549 | } | 558 | } |
@@ -582,14 +591,18 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ | |||
582 | for (offb = 0; offb < len; ) { | 591 | for (offb = 0; offb < len; ) { |
583 | int l = le32_to_cpu(buf[offb++]); | 592 | int l = le32_to_cpu(buf[offb++]); |
584 | if (l > stride || l > (len - offb) / 2) { | 593 | if (l > stride || l > (len - offb) / 2) { |
585 | dbg("wrong data length %#x in response", l); | 594 | if (printk_ratelimit()) |
595 | usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n", | ||
596 | cm, l); | ||
586 | ret = -EIO; | 597 | ret = -EIO; |
587 | goto cleanup; | 598 | goto cleanup; |
588 | } | 599 | } |
589 | while (l--) { | 600 | while (l--) { |
590 | offd = le32_to_cpu(buf[offb++]); | 601 | offd = le32_to_cpu(buf[offb++]); |
591 | if (offd >= size) { | 602 | if (offd >= size) { |
592 | dbg("wrong index %#x in response", offd); | 603 | if (printk_ratelimit()) |
604 | usb_err(instance->usbatm, "wrong index #%x in response to cm #%x\n", | ||
605 | offd, cm); | ||
593 | ret = -EIO; | 606 | ret = -EIO; |
594 | goto cleanup; | 607 | goto cleanup; |
595 | } | 608 | } |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index eb0615abff68..8b132c4a503b 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -251,7 +251,6 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
251 | { | 251 | { |
252 | unsigned char *buffer; | 252 | unsigned char *buffer; |
253 | struct usbatm_data *usbatm = instance->usbatm; | 253 | struct usbatm_data *usbatm = instance->usbatm; |
254 | struct usb_interface *intf; | ||
255 | struct usb_device *usb_dev = usbatm->usb_dev; | 254 | struct usb_device *usb_dev = usbatm->usb_dev; |
256 | int actual_length; | 255 | int actual_length; |
257 | int ret = 0; | 256 | int ret = 0; |
@@ -265,7 +264,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
265 | goto out; | 264 | goto out; |
266 | } | 265 | } |
267 | 266 | ||
268 | if (!(intf = usb_ifnum_to_if(usb_dev, 2))) { | 267 | if (!usb_ifnum_to_if(usb_dev, 2)) { |
269 | ret = -ENODEV; | 268 | ret = -ENODEV; |
270 | usb_dbg(usbatm, "%s: interface not found!\n", __func__); | 269 | usb_dbg(usbatm, "%s: interface not found!\n", __func__); |
271 | goto out_free; | 270 | goto out_free; |
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 29807d048b04..389c5b164eb2 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -2,7 +2,8 @@ | |||
2 | * Copyright (c) 2003, 2004 | 2 | * Copyright (c) 2003, 2004 |
3 | * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. | 3 | * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. |
4 | * | 4 | * |
5 | * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr> | 5 | * Copyright (c) 2005-2007 Matthieu Castet <castet.matthieu@free.fr> |
6 | * Copyright (c) 2005-2007 Stanislaw Gruszka <stf_xl@wp.pl> | ||
6 | * | 7 | * |
7 | * This software is available to you under a choice of one of two | 8 | * This software is available to you under a choice of one of two |
8 | * licenses. You may choose to be licensed under the terms of the GNU | 9 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -107,18 +108,51 @@ | |||
107 | #define uea_info(usb_dev, format,args...) \ | 108 | #define uea_info(usb_dev, format,args...) \ |
108 | dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args) | 109 | dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args) |
109 | 110 | ||
110 | struct uea_cmvs { | 111 | struct intr_pkt; |
112 | |||
113 | /* cmv's from firmware */ | ||
114 | struct uea_cmvs_v1 { | ||
111 | u32 address; | 115 | u32 address; |
112 | u16 offset; | 116 | u16 offset; |
113 | u32 data; | 117 | u32 data; |
114 | } __attribute__ ((packed)); | 118 | } __attribute__ ((packed)); |
115 | 119 | ||
120 | struct uea_cmvs_v2 { | ||
121 | u32 group; | ||
122 | u32 address; | ||
123 | u32 offset; | ||
124 | u32 data; | ||
125 | } __attribute__ ((packed)); | ||
126 | |||
127 | /* information about currently processed cmv */ | ||
128 | struct cmv_dsc_e1 { | ||
129 | u8 function; | ||
130 | u16 idx; | ||
131 | u32 address; | ||
132 | u16 offset; | ||
133 | }; | ||
134 | |||
135 | struct cmv_dsc_e4 { | ||
136 | u16 function; | ||
137 | u16 offset; | ||
138 | u16 address; | ||
139 | u16 group; | ||
140 | }; | ||
141 | |||
142 | union cmv_dsc { | ||
143 | struct cmv_dsc_e1 e1; | ||
144 | struct cmv_dsc_e4 e4; | ||
145 | }; | ||
146 | |||
116 | struct uea_softc { | 147 | struct uea_softc { |
117 | struct usb_device *usb_dev; | 148 | struct usb_device *usb_dev; |
118 | struct usbatm_data *usbatm; | 149 | struct usbatm_data *usbatm; |
119 | 150 | ||
120 | int modem_index; | 151 | int modem_index; |
121 | unsigned int driver_info; | 152 | unsigned int driver_info; |
153 | int annex; | ||
154 | #define ANNEXA 0 | ||
155 | #define ANNEXB 1 | ||
122 | 156 | ||
123 | int booting; | 157 | int booting; |
124 | int reset; | 158 | int reset; |
@@ -127,20 +161,23 @@ struct uea_softc { | |||
127 | 161 | ||
128 | struct task_struct *kthread; | 162 | struct task_struct *kthread; |
129 | u32 data; | 163 | u32 data; |
130 | wait_queue_head_t cmv_ack_wait; | 164 | u32 data1; |
165 | |||
131 | int cmv_ack; | 166 | int cmv_ack; |
167 | union cmv_dsc cmv_dsc; | ||
132 | 168 | ||
133 | struct work_struct task; | 169 | struct work_struct task; |
170 | struct workqueue_struct *work_q; | ||
134 | u16 pageno; | 171 | u16 pageno; |
135 | u16 ovl; | 172 | u16 ovl; |
136 | 173 | ||
137 | const struct firmware *dsp_firm; | 174 | const struct firmware *dsp_firm; |
138 | struct urb *urb_int; | 175 | struct urb *urb_int; |
139 | 176 | ||
140 | u8 cmv_function; | 177 | void (*dispatch_cmv) (struct uea_softc *, struct intr_pkt *); |
141 | u16 cmv_idx; | 178 | void (*schedule_load_page) (struct uea_softc *, struct intr_pkt *); |
142 | u32 cmv_address; | 179 | int (*stat) (struct uea_softc *); |
143 | u16 cmv_offset; | 180 | int (*send_cmvs) (struct uea_softc *); |
144 | 181 | ||
145 | /* keep in sync with eaglectl */ | 182 | /* keep in sync with eaglectl */ |
146 | struct uea_stats { | 183 | struct uea_stats { |
@@ -174,10 +211,34 @@ struct uea_softc { | |||
174 | #define ELSA_PID_PSTFIRM 0x3350 | 211 | #define ELSA_PID_PSTFIRM 0x3350 |
175 | #define ELSA_PID_PREFIRM 0x3351 | 212 | #define ELSA_PID_PREFIRM 0x3351 |
176 | 213 | ||
214 | #define ELSA_PID_A_PREFIRM 0x3352 | ||
215 | #define ELSA_PID_A_PSTFIRM 0x3353 | ||
216 | #define ELSA_PID_B_PREFIRM 0x3362 | ||
217 | #define ELSA_PID_B_PSTFIRM 0x3363 | ||
218 | |||
177 | /* | 219 | /* |
178 | * Sagem USB IDs | 220 | * Devolo IDs : pots if (pid & 0x10) |
179 | */ | 221 | */ |
180 | #define EAGLE_VID 0x1110 | 222 | #define DEVOLO_VID 0x1039 |
223 | #define DEVOLO_EAGLE_I_A_PID_PSTFIRM 0x2110 | ||
224 | #define DEVOLO_EAGLE_I_A_PID_PREFIRM 0x2111 | ||
225 | |||
226 | #define DEVOLO_EAGLE_I_B_PID_PSTFIRM 0x2100 | ||
227 | #define DEVOLO_EAGLE_I_B_PID_PREFIRM 0x2101 | ||
228 | |||
229 | #define DEVOLO_EAGLE_II_A_PID_PSTFIRM 0x2130 | ||
230 | #define DEVOLO_EAGLE_II_A_PID_PREFIRM 0x2131 | ||
231 | |||
232 | #define DEVOLO_EAGLE_II_B_PID_PSTFIRM 0x2120 | ||
233 | #define DEVOLO_EAGLE_II_B_PID_PREFIRM 0x2121 | ||
234 | |||
235 | /* | ||
236 | * Reference design USB IDs | ||
237 | */ | ||
238 | #define ANALOG_VID 0x1110 | ||
239 | #define ADI930_PID_PREFIRM 0x9001 | ||
240 | #define ADI930_PID_PSTFIRM 0x9000 | ||
241 | |||
181 | #define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */ | 242 | #define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */ |
182 | #define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */ | 243 | #define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */ |
183 | 244 | ||
@@ -187,12 +248,12 @@ struct uea_softc { | |||
187 | #define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */ | 248 | #define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */ |
188 | #define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */ | 249 | #define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */ |
189 | 250 | ||
190 | /* | ||
191 | * Eagle III Pid | ||
192 | */ | ||
193 | #define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */ | 251 | #define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */ |
194 | #define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */ | 252 | #define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */ |
195 | 253 | ||
254 | #define EAGLE_IV_PID_PREFIRM 0x9042 /* Eagle IV */ | ||
255 | #define EAGLE_IV_PID_PSTFIRM 0x9041 /* Eagle IV */ | ||
256 | |||
196 | /* | 257 | /* |
197 | * USR USB IDs | 258 | * USR USB IDs |
198 | */ | 259 | */ |
@@ -208,11 +269,15 @@ struct uea_softc { | |||
208 | 269 | ||
209 | #define PREFIRM 0 | 270 | #define PREFIRM 0 |
210 | #define PSTFIRM (1<<7) | 271 | #define PSTFIRM (1<<7) |
272 | #define AUTO_ANNEX_A (1<<8) | ||
273 | #define AUTO_ANNEX_B (1<<9) | ||
274 | |||
211 | enum { | 275 | enum { |
212 | ADI930 = 0, | 276 | ADI930 = 0, |
213 | EAGLE_I, | 277 | EAGLE_I, |
214 | EAGLE_II, | 278 | EAGLE_II, |
215 | EAGLE_III | 279 | EAGLE_III, |
280 | EAGLE_IV | ||
216 | }; | 281 | }; |
217 | 282 | ||
218 | /* macros for both struct usb_device_id and struct uea_softc */ | 283 | /* macros for both struct usb_device_id and struct uea_softc */ |
@@ -221,15 +286,18 @@ enum { | |||
221 | #define UEA_CHIP_VERSION(x) \ | 286 | #define UEA_CHIP_VERSION(x) \ |
222 | ((x)->driver_info & 0xf) | 287 | ((x)->driver_info & 0xf) |
223 | 288 | ||
224 | #define IS_ISDN(usb_dev) \ | 289 | #define IS_ISDN(x) \ |
225 | (le16_to_cpu((usb_dev)->descriptor.bcdDevice) & 0x80) | 290 | ((x)->annex & ANNEXB) |
226 | 291 | ||
227 | #define INS_TO_USBDEV(ins) ins->usb_dev | 292 | #define INS_TO_USBDEV(ins) ins->usb_dev |
228 | 293 | ||
229 | #define GET_STATUS(data) \ | 294 | #define GET_STATUS(data) \ |
230 | ((data >> 8) & 0xf) | 295 | ((data >> 8) & 0xf) |
296 | |||
231 | #define IS_OPERATIONAL(sc) \ | 297 | #define IS_OPERATIONAL(sc) \ |
232 | (GET_STATUS(sc->stats.phy.state) == 2) | 298 | ((UEA_CHIP_VERSION(sc) != EAGLE_IV) ? \ |
299 | (GET_STATUS(sc->stats.phy.state) == 2) : \ | ||
300 | (sc->stats.phy.state == 7)) | ||
233 | 301 | ||
234 | /* | 302 | /* |
235 | * Set of macros to handle unaligned data in the firmware blob. | 303 | * Set of macros to handle unaligned data in the firmware blob. |
@@ -259,7 +327,8 @@ enum { | |||
259 | #define UEA_INTR_PIPE 0x04 | 327 | #define UEA_INTR_PIPE 0x04 |
260 | #define UEA_ISO_DATA_PIPE 0x08 | 328 | #define UEA_ISO_DATA_PIPE 0x08 |
261 | 329 | ||
262 | #define UEA_SET_BLOCK 0x0001 | 330 | #define UEA_E1_SET_BLOCK 0x0001 |
331 | #define UEA_E4_SET_BLOCK 0x002c | ||
263 | #define UEA_SET_MODE 0x0003 | 332 | #define UEA_SET_MODE 0x0003 |
264 | #define UEA_SET_2183_DATA 0x0004 | 333 | #define UEA_SET_2183_DATA 0x0004 |
265 | #define UEA_SET_TIMEOUT 0x0011 | 334 | #define UEA_SET_TIMEOUT 0x0011 |
@@ -275,71 +344,179 @@ enum { | |||
275 | #define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000) | 344 | #define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000) |
276 | #define UEA_MPRX_MAILBOX (0x3fdf | 0x4000) | 345 | #define UEA_MPRX_MAILBOX (0x3fdf | 0x4000) |
277 | 346 | ||
278 | /* structure describing a block within a DSP page */ | 347 | /* block information in eagle4 dsp firmware */ |
279 | struct block_info { | 348 | struct block_index { |
349 | __le32 PageOffset; | ||
350 | __le32 NotLastBlock; | ||
351 | __le32 dummy; | ||
352 | __le32 PageSize; | ||
353 | __le32 PageAddress; | ||
354 | __le16 dummy1; | ||
355 | __le16 PageNumber; | ||
356 | } __attribute__ ((packed)); | ||
357 | |||
358 | #define E4_IS_BOOT_PAGE(PageSize) ((le32_to_cpu(PageSize)) & 0x80000000) | ||
359 | #define E4_PAGE_BYTES(PageSize) ((le32_to_cpu(PageSize) & 0x7fffffff) * 4) | ||
360 | |||
361 | #define E4_L1_STRING_HEADER 0x10 | ||
362 | #define E4_MAX_PAGE_NUMBER 0x58 | ||
363 | #define E4_NO_SWAPPAGE_HEADERS 0x31 | ||
364 | |||
365 | /* l1_code is eagle4 dsp firmware format */ | ||
366 | struct l1_code { | ||
367 | u8 string_header[E4_L1_STRING_HEADER]; | ||
368 | u8 page_number_to_block_index[E4_MAX_PAGE_NUMBER]; | ||
369 | struct block_index page_header[E4_NO_SWAPPAGE_HEADERS]; | ||
370 | u8 code [0]; | ||
371 | } __attribute__ ((packed)); | ||
372 | |||
373 | /* structures describing a block within a DSP page */ | ||
374 | struct block_info_e1 { | ||
280 | __le16 wHdr; | 375 | __le16 wHdr; |
281 | #define UEA_BIHDR 0xabcd | ||
282 | __le16 wAddress; | 376 | __le16 wAddress; |
283 | __le16 wSize; | 377 | __le16 wSize; |
284 | __le16 wOvlOffset; | 378 | __le16 wOvlOffset; |
285 | __le16 wOvl; /* overlay */ | 379 | __le16 wOvl; /* overlay */ |
286 | __le16 wLast; | 380 | __le16 wLast; |
287 | } __attribute__ ((packed)); | 381 | } __attribute__ ((packed)); |
288 | #define BLOCK_INFO_SIZE 12 | 382 | #define E1_BLOCK_INFO_SIZE 12 |
383 | |||
384 | struct block_info_e4 { | ||
385 | __be16 wHdr; | ||
386 | __u8 bBootPage; | ||
387 | __u8 bPageNumber; | ||
388 | __be32 dwSize; | ||
389 | __be32 dwAddress; | ||
390 | __be16 wReserved; | ||
391 | } __attribute__ ((packed)); | ||
392 | #define E4_BLOCK_INFO_SIZE 14 | ||
289 | 393 | ||
290 | /* structure representing a CMV (Configuration and Management Variable) */ | 394 | #define UEA_BIHDR 0xabcd |
291 | struct cmv { | 395 | #define UEA_RESERVED 0xffff |
292 | __le16 wPreamble; | 396 | |
293 | #define PREAMBLE 0x535c | 397 | /* constants describing cmv type */ |
294 | __u8 bDirection; | 398 | #define E1_PREAMBLE 0x535c |
295 | #define MODEMTOHOST 0x01 | 399 | #define E1_MODEMTOHOST 0x01 |
296 | #define HOSTTOMODEM 0x10 | 400 | #define E1_HOSTTOMODEM 0x10 |
297 | __u8 bFunction; | 401 | |
298 | #define FUNCTION_TYPE(f) ((f) >> 4) | 402 | #define E1_MEMACCESS 0x1 |
299 | #define MEMACCESS 0x1 | 403 | #define E1_ADSLDIRECTIVE 0x7 |
300 | #define ADSLDIRECTIVE 0x7 | 404 | #define E1_FUNCTION_TYPE(f) ((f) >> 4) |
405 | #define E1_FUNCTION_SUBTYPE(f) ((f) & 0x0f) | ||
406 | |||
407 | #define E4_MEMACCESS 0 | ||
408 | #define E4_ADSLDIRECTIVE 0xf | ||
409 | #define E4_FUNCTION_TYPE(f) ((f) >> 8) | ||
410 | #define E4_FUNCTION_SIZE(f) ((f) & 0x0f) | ||
411 | #define E4_FUNCTION_SUBTYPE(f) (((f) >> 4) & 0x0f) | ||
301 | 412 | ||
302 | #define FUNCTION_SUBTYPE(f) ((f) & 0x0f) | ||
303 | /* for MEMACCESS */ | 413 | /* for MEMACCESS */ |
304 | #define REQUESTREAD 0x0 | 414 | #define E1_REQUESTREAD 0x0 |
305 | #define REQUESTWRITE 0x1 | 415 | #define E1_REQUESTWRITE 0x1 |
306 | #define REPLYREAD 0x2 | 416 | #define E1_REPLYREAD 0x2 |
307 | #define REPLYWRITE 0x3 | 417 | #define E1_REPLYWRITE 0x3 |
418 | |||
419 | #define E4_REQUESTREAD 0x0 | ||
420 | #define E4_REQUESTWRITE 0x4 | ||
421 | #define E4_REPLYREAD (E4_REQUESTREAD | 1) | ||
422 | #define E4_REPLYWRITE (E4_REQUESTWRITE | 1) | ||
423 | |||
308 | /* for ADSLDIRECTIVE */ | 424 | /* for ADSLDIRECTIVE */ |
309 | #define KERNELREADY 0x0 | 425 | #define E1_KERNELREADY 0x0 |
310 | #define MODEMREADY 0x1 | 426 | #define E1_MODEMREADY 0x1 |
311 | 427 | ||
312 | #define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf)) | 428 | #define E4_KERNELREADY 0x0 |
313 | __le16 wIndex; | 429 | #define E4_MODEMREADY 0x1 |
314 | __le32 dwSymbolicAddress; | 430 | |
315 | #define MAKESA(a, b, c, d) \ | 431 | #define E1_MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf)) |
432 | #define E4_MAKEFUNCTION(t, st, s) (((t) & 0xf) << 8 | ((st) & 0xf) << 4 | ((s) & 0xf)) | ||
433 | |||
434 | #define E1_MAKESA(a, b, c, d) \ | ||
316 | (((c) & 0xff) << 24 | \ | 435 | (((c) & 0xff) << 24 | \ |
317 | ((d) & 0xff) << 16 | \ | 436 | ((d) & 0xff) << 16 | \ |
318 | ((a) & 0xff) << 8 | \ | 437 | ((a) & 0xff) << 8 | \ |
319 | ((b) & 0xff)) | 438 | ((b) & 0xff)) |
320 | #define GETSA1(a) ((a >> 8) & 0xff) | 439 | |
321 | #define GETSA2(a) (a & 0xff) | 440 | #define E1_GETSA1(a) ((a >> 8) & 0xff) |
322 | #define GETSA3(a) ((a >> 24) & 0xff) | 441 | #define E1_GETSA2(a) (a & 0xff) |
323 | #define GETSA4(a) ((a >> 16) & 0xff) | 442 | #define E1_GETSA3(a) ((a >> 24) & 0xff) |
324 | 443 | #define E1_GETSA4(a) ((a >> 16) & 0xff) | |
325 | #define SA_CNTL MAKESA('C', 'N', 'T', 'L') | 444 | |
326 | #define SA_DIAG MAKESA('D', 'I', 'A', 'G') | 445 | #define E1_SA_CNTL E1_MAKESA('C', 'N', 'T', 'L') |
327 | #define SA_INFO MAKESA('I', 'N', 'F', 'O') | 446 | #define E1_SA_DIAG E1_MAKESA('D', 'I', 'A', 'G') |
328 | #define SA_OPTN MAKESA('O', 'P', 'T', 'N') | 447 | #define E1_SA_INFO E1_MAKESA('I', 'N', 'F', 'O') |
329 | #define SA_RATE MAKESA('R', 'A', 'T', 'E') | 448 | #define E1_SA_OPTN E1_MAKESA('O', 'P', 'T', 'N') |
330 | #define SA_STAT MAKESA('S', 'T', 'A', 'T') | 449 | #define E1_SA_RATE E1_MAKESA('R', 'A', 'T', 'E') |
450 | #define E1_SA_STAT E1_MAKESA('S', 'T', 'A', 'T') | ||
451 | |||
452 | #define E4_SA_CNTL 1 | ||
453 | #define E4_SA_STAT 2 | ||
454 | #define E4_SA_INFO 3 | ||
455 | #define E4_SA_TEST 4 | ||
456 | #define E4_SA_OPTN 5 | ||
457 | #define E4_SA_RATE 6 | ||
458 | #define E4_SA_DIAG 7 | ||
459 | #define E4_SA_CNFG 8 | ||
460 | |||
461 | /* structures representing a CMV (Configuration and Management Variable) */ | ||
462 | struct cmv_e1 { | ||
463 | __le16 wPreamble; | ||
464 | __u8 bDirection; | ||
465 | __u8 bFunction; | ||
466 | __le16 wIndex; | ||
467 | __le32 dwSymbolicAddress; | ||
331 | __le16 wOffsetAddress; | 468 | __le16 wOffsetAddress; |
332 | __le32 dwData; | 469 | __le32 dwData; |
333 | } __attribute__ ((packed)); | 470 | } __attribute__ ((packed)); |
334 | #define CMV_SIZE 16 | ||
335 | 471 | ||
336 | /* structure representing swap information */ | 472 | struct cmv_e4 { |
337 | struct swap_info { | 473 | __be16 wGroup; |
474 | __be16 wFunction; | ||
475 | __be16 wOffset; | ||
476 | __be16 wAddress; | ||
477 | __be32 dwData [6]; | ||
478 | } __attribute__ ((packed)); | ||
479 | |||
480 | /* structures representing swap information */ | ||
481 | struct swap_info_e1 { | ||
338 | __u8 bSwapPageNo; | 482 | __u8 bSwapPageNo; |
339 | __u8 bOvl; /* overlay */ | 483 | __u8 bOvl; /* overlay */ |
340 | } __attribute__ ((packed)); | 484 | } __attribute__ ((packed)); |
341 | 485 | ||
342 | /* structure representing interrupt data */ | 486 | struct swap_info_e4 { |
487 | __u8 bSwapPageNo; | ||
488 | } __attribute__ ((packed)); | ||
489 | |||
490 | /* structures representing interrupt data */ | ||
491 | #define e1_bSwapPageNo u.e1.s1.swapinfo.bSwapPageNo | ||
492 | #define e1_bOvl u.e1.s1.swapinfo.bOvl | ||
493 | #define e4_bSwapPageNo u.e4.s1.swapinfo.bSwapPageNo | ||
494 | |||
495 | #define INT_LOADSWAPPAGE 0x0001 | ||
496 | #define INT_INCOMINGCMV 0x0002 | ||
497 | |||
498 | union intr_data_e1 { | ||
499 | struct { | ||
500 | struct swap_info_e1 swapinfo; | ||
501 | __le16 wDataSize; | ||
502 | } __attribute__ ((packed)) s1; | ||
503 | struct { | ||
504 | struct cmv_e1 cmv; | ||
505 | __le16 wDataSize; | ||
506 | } __attribute__ ((packed)) s2; | ||
507 | } __attribute__ ((packed)); | ||
508 | |||
509 | union intr_data_e4 { | ||
510 | struct { | ||
511 | struct swap_info_e4 swapinfo; | ||
512 | __le16 wDataSize; | ||
513 | } __attribute__ ((packed)) s1; | ||
514 | struct { | ||
515 | struct cmv_e4 cmv; | ||
516 | __le16 wDataSize; | ||
517 | } __attribute__ ((packed)) s2; | ||
518 | } __attribute__ ((packed)); | ||
519 | |||
343 | struct intr_pkt { | 520 | struct intr_pkt { |
344 | __u8 bType; | 521 | __u8 bType; |
345 | __u8 bNotification; | 522 | __u8 bNotification; |
@@ -347,43 +524,48 @@ struct intr_pkt { | |||
347 | __le16 wIndex; | 524 | __le16 wIndex; |
348 | __le16 wLength; | 525 | __le16 wLength; |
349 | __le16 wInterrupt; | 526 | __le16 wInterrupt; |
350 | #define INT_LOADSWAPPAGE 0x0001 | ||
351 | #define INT_INCOMINGCMV 0x0002 | ||
352 | union { | 527 | union { |
353 | struct { | 528 | union intr_data_e1 e1; |
354 | struct swap_info swapinfo; | 529 | union intr_data_e4 e4; |
355 | __le16 wDataSize; | 530 | } u; |
356 | } __attribute__ ((packed)) s1; | ||
357 | |||
358 | struct { | ||
359 | struct cmv cmv; | ||
360 | __le16 wDataSize; | ||
361 | } __attribute__ ((packed)) s2; | ||
362 | } __attribute__ ((packed)) u; | ||
363 | #define bSwapPageNo u.s1.swapinfo.bSwapPageNo | ||
364 | #define bOvl u.s1.swapinfo.bOvl | ||
365 | } __attribute__ ((packed)); | 531 | } __attribute__ ((packed)); |
366 | #define INTR_PKT_SIZE 28 | 532 | |
533 | #define E1_INTR_PKT_SIZE 28 | ||
534 | #define E4_INTR_PKT_SIZE 64 | ||
367 | 535 | ||
368 | static struct usb_driver uea_driver; | 536 | static struct usb_driver uea_driver; |
369 | static DEFINE_MUTEX(uea_mutex); | 537 | static DEFINE_MUTEX(uea_mutex); |
370 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; | 538 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III", "Eagle IV"}; |
371 | 539 | ||
372 | static int modem_index; | 540 | static int modem_index; |
373 | static unsigned int debug; | 541 | static unsigned int debug; |
374 | static int use_iso[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = 1}; | 542 | static unsigned int altsetting[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = FASTEST_ISO_INTF}; |
375 | static int sync_wait[NB_MODEM]; | 543 | static int sync_wait[NB_MODEM]; |
376 | static char *cmv_file[NB_MODEM]; | 544 | static char *cmv_file[NB_MODEM]; |
545 | static int annex[NB_MODEM]; | ||
377 | 546 | ||
378 | module_param(debug, uint, 0644); | 547 | module_param(debug, uint, 0644); |
379 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); | 548 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); |
380 | module_param_array(use_iso, bool, NULL, 0644); | 549 | module_param_array(altsetting, uint, NULL, 0644); |
381 | MODULE_PARM_DESC(use_iso, "use isochronous usb pipe for incoming traffic"); | 550 | MODULE_PARM_DESC(altsetting, "alternate setting for incoming traffic: 0=bulk, " |
551 | "1=isoc slowest, ... , 8=isoc fastest (default)"); | ||
382 | module_param_array(sync_wait, bool, NULL, 0644); | 552 | module_param_array(sync_wait, bool, NULL, 0644); |
383 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); | 553 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); |
384 | module_param_array(cmv_file, charp, NULL, 0644); | 554 | module_param_array(cmv_file, charp, NULL, 0644); |
385 | MODULE_PARM_DESC(cmv_file, | 555 | MODULE_PARM_DESC(cmv_file, |
386 | "file name with configuration and management variables"); | 556 | "file name with configuration and management variables"); |
557 | module_param_array(annex, uint, NULL, 0644); | ||
558 | MODULE_PARM_DESC(annex, | ||
559 | "manually set annex a/b (0=auto, 1=annex a, 2=annex b)"); | ||
560 | |||
561 | #define uea_wait(sc, cond, timeo) \ | ||
562 | ({ \ | ||
563 | int _r = wait_event_interruptible_timeout(sc->sync_q, \ | ||
564 | (cond) || kthread_should_stop(), timeo); \ | ||
565 | if (kthread_should_stop()) \ | ||
566 | _r = -ENODEV; \ | ||
567 | _r; \ | ||
568 | }) | ||
387 | 569 | ||
388 | #define UPDATE_ATM_STAT(type, val) \ | 570 | #define UPDATE_ATM_STAT(type, val) \ |
389 | do { \ | 571 | do { \ |
@@ -519,6 +701,9 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | |||
519 | case EAGLE_III: | 701 | case EAGLE_III: |
520 | fw_name = FW_DIR "eagleIII.fw"; | 702 | fw_name = FW_DIR "eagleIII.fw"; |
521 | break; | 703 | break; |
704 | case EAGLE_IV: | ||
705 | fw_name = FW_DIR "eagleIV.fw"; | ||
706 | break; | ||
522 | } | 707 | } |
523 | 708 | ||
524 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); | 709 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); |
@@ -537,7 +722,7 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | |||
537 | /* | 722 | /* |
538 | * Make sure that the DSP code provided is safe to use. | 723 | * Make sure that the DSP code provided is safe to use. |
539 | */ | 724 | */ |
540 | static int check_dsp(u8 *dsp, unsigned int len) | 725 | static int check_dsp_e1(u8 *dsp, unsigned int len) |
541 | { | 726 | { |
542 | u8 pagecount, blockcount; | 727 | u8 pagecount, blockcount; |
543 | u16 blocksize; | 728 | u16 blocksize; |
@@ -588,6 +773,51 @@ static int check_dsp(u8 *dsp, unsigned int len) | |||
588 | return 0; | 773 | return 0; |
589 | } | 774 | } |
590 | 775 | ||
776 | static int check_dsp_e4(u8 *dsp, int len) | ||
777 | { | ||
778 | int i; | ||
779 | struct l1_code *p = (struct l1_code *) dsp; | ||
780 | unsigned int sum = p->code - dsp; | ||
781 | |||
782 | if (len < sum) | ||
783 | return 1; | ||
784 | |||
785 | if (strcmp("STRATIPHY ANEXA", p->string_header) != 0 && | ||
786 | strcmp("STRATIPHY ANEXB", p->string_header) != 0) | ||
787 | return 1; | ||
788 | |||
789 | for (i = 0; i < E4_MAX_PAGE_NUMBER; i++) { | ||
790 | struct block_index *blockidx; | ||
791 | u8 blockno = p->page_number_to_block_index[i]; | ||
792 | if (blockno >= E4_NO_SWAPPAGE_HEADERS) | ||
793 | continue; | ||
794 | |||
795 | do { | ||
796 | u64 l; | ||
797 | |||
798 | if (blockno >= E4_NO_SWAPPAGE_HEADERS) | ||
799 | return 1; | ||
800 | |||
801 | blockidx = &p->page_header[blockno++]; | ||
802 | if ((u8 *)(blockidx + 1) - dsp >= len) | ||
803 | return 1; | ||
804 | |||
805 | if (le16_to_cpu(blockidx->PageNumber) != i) | ||
806 | return 1; | ||
807 | |||
808 | l = E4_PAGE_BYTES(blockidx->PageSize); | ||
809 | sum += l; | ||
810 | l += le32_to_cpu(blockidx->PageOffset); | ||
811 | if (l > len) | ||
812 | return 1; | ||
813 | |||
814 | /* zero is zero regardless endianes */ | ||
815 | } while (blockidx->NotLastBlock); | ||
816 | } | ||
817 | |||
818 | return (sum == len) ? 0 : 1; | ||
819 | } | ||
820 | |||
591 | /* | 821 | /* |
592 | * send data to the idma pipe | 822 | * send data to the idma pipe |
593 | * */ | 823 | * */ |
@@ -624,13 +854,18 @@ static int request_dsp(struct uea_softc *sc) | |||
624 | int ret; | 854 | int ret; |
625 | char *dsp_name; | 855 | char *dsp_name; |
626 | 856 | ||
627 | if (UEA_CHIP_VERSION(sc) == ADI930) { | 857 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
628 | if (IS_ISDN(sc->usb_dev)) | 858 | if (IS_ISDN(sc)) |
859 | dsp_name = FW_DIR "DSP4i.bin"; | ||
860 | else | ||
861 | dsp_name = FW_DIR "DSP4p.bin"; | ||
862 | } else if (UEA_CHIP_VERSION(sc) == ADI930) { | ||
863 | if (IS_ISDN(sc)) | ||
629 | dsp_name = FW_DIR "DSP9i.bin"; | 864 | dsp_name = FW_DIR "DSP9i.bin"; |
630 | else | 865 | else |
631 | dsp_name = FW_DIR "DSP9p.bin"; | 866 | dsp_name = FW_DIR "DSP9p.bin"; |
632 | } else { | 867 | } else { |
633 | if (IS_ISDN(sc->usb_dev)) | 868 | if (IS_ISDN(sc)) |
634 | dsp_name = FW_DIR "DSPei.bin"; | 869 | dsp_name = FW_DIR "DSPei.bin"; |
635 | else | 870 | else |
636 | dsp_name = FW_DIR "DSPep.bin"; | 871 | dsp_name = FW_DIR "DSPep.bin"; |
@@ -640,11 +875,16 @@ static int request_dsp(struct uea_softc *sc) | |||
640 | if (ret < 0) { | 875 | if (ret < 0) { |
641 | uea_err(INS_TO_USBDEV(sc), | 876 | uea_err(INS_TO_USBDEV(sc), |
642 | "requesting firmware %s failed with error %d\n", | 877 | "requesting firmware %s failed with error %d\n", |
643 | dsp_name, ret); | 878 | dsp_name, ret); |
644 | return ret; | 879 | return ret; |
645 | } | 880 | } |
646 | 881 | ||
647 | if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) { | 882 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) |
883 | ret = check_dsp_e4(sc->dsp_firm->data, sc->dsp_firm->size); | ||
884 | else | ||
885 | ret = check_dsp_e1(sc->dsp_firm->data, sc->dsp_firm->size); | ||
886 | |||
887 | if (ret) { | ||
648 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | 888 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", |
649 | dsp_name); | 889 | dsp_name); |
650 | release_firmware(sc->dsp_firm); | 890 | release_firmware(sc->dsp_firm); |
@@ -658,12 +898,12 @@ static int request_dsp(struct uea_softc *sc) | |||
658 | /* | 898 | /* |
659 | * The uea_load_page() function must be called within a process context | 899 | * The uea_load_page() function must be called within a process context |
660 | */ | 900 | */ |
661 | static void uea_load_page(struct work_struct *work) | 901 | static void uea_load_page_e1(struct work_struct *work) |
662 | { | 902 | { |
663 | struct uea_softc *sc = container_of(work, struct uea_softc, task); | 903 | struct uea_softc *sc = container_of(work, struct uea_softc, task); |
664 | u16 pageno = sc->pageno; | 904 | u16 pageno = sc->pageno; |
665 | u16 ovl = sc->ovl; | 905 | u16 ovl = sc->ovl; |
666 | struct block_info bi; | 906 | struct block_info_e1 bi; |
667 | 907 | ||
668 | u8 *p; | 908 | u8 *p; |
669 | u8 pagecount, blockcount; | 909 | u8 pagecount, blockcount; |
@@ -716,7 +956,7 @@ static void uea_load_page(struct work_struct *work) | |||
716 | bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0); | 956 | bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0); |
717 | 957 | ||
718 | /* send block info through the IDMA pipe */ | 958 | /* send block info through the IDMA pipe */ |
719 | if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE)) | 959 | if (uea_idma_write(sc, &bi, E1_BLOCK_INFO_SIZE)) |
720 | goto bad2; | 960 | goto bad2; |
721 | 961 | ||
722 | /* send block data through the IDMA pipe */ | 962 | /* send block data through the IDMA pipe */ |
@@ -735,17 +975,114 @@ bad1: | |||
735 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); | 975 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); |
736 | } | 976 | } |
737 | 977 | ||
978 | static void __uea_load_page_e4(struct uea_softc *sc, u8 pageno, int boot) | ||
979 | { | ||
980 | struct block_info_e4 bi; | ||
981 | struct block_index *blockidx; | ||
982 | struct l1_code *p = (struct l1_code *) sc->dsp_firm->data; | ||
983 | u8 blockno = p->page_number_to_block_index[pageno]; | ||
984 | |||
985 | bi.wHdr = cpu_to_be16(UEA_BIHDR); | ||
986 | bi.bBootPage = boot; | ||
987 | bi.bPageNumber = pageno; | ||
988 | bi.wReserved = cpu_to_be16(UEA_RESERVED); | ||
989 | |||
990 | do { | ||
991 | u8 *blockoffset; | ||
992 | unsigned int blocksize; | ||
993 | |||
994 | blockidx = &p->page_header[blockno]; | ||
995 | blocksize = E4_PAGE_BYTES(blockidx->PageSize); | ||
996 | blockoffset = sc->dsp_firm->data + le32_to_cpu(blockidx->PageOffset); | ||
997 | |||
998 | bi.dwSize = cpu_to_be32(blocksize); | ||
999 | bi.dwAddress = swab32(blockidx->PageAddress); | ||
1000 | |||
1001 | uea_dbg(INS_TO_USBDEV(sc), | ||
1002 | "sending block %u for DSP page %u size %u adress %x\n", | ||
1003 | blockno, pageno, blocksize, le32_to_cpu(blockidx->PageAddress)); | ||
1004 | |||
1005 | /* send block info through the IDMA pipe */ | ||
1006 | if (uea_idma_write(sc, &bi, E4_BLOCK_INFO_SIZE)) | ||
1007 | goto bad; | ||
1008 | |||
1009 | /* send block data through the IDMA pipe */ | ||
1010 | if (uea_idma_write(sc, blockoffset, blocksize)) | ||
1011 | goto bad; | ||
1012 | |||
1013 | blockno++; | ||
1014 | } while (blockidx->NotLastBlock); | ||
1015 | |||
1016 | return; | ||
1017 | |||
1018 | bad: | ||
1019 | uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", blockno); | ||
1020 | return; | ||
1021 | } | ||
1022 | |||
1023 | static void uea_load_page_e4(struct work_struct *work) | ||
1024 | { | ||
1025 | struct uea_softc *sc = container_of(work, struct uea_softc, task); | ||
1026 | u8 pageno = sc->pageno; | ||
1027 | int i; | ||
1028 | struct block_info_e4 bi; | ||
1029 | struct l1_code *p; | ||
1030 | |||
1031 | uea_dbg(INS_TO_USBDEV(sc), "sending DSP page %u\n", pageno); | ||
1032 | |||
1033 | /* reload firmware when reboot start and it's loaded already */ | ||
1034 | if (pageno == 0 && sc->dsp_firm) { | ||
1035 | release_firmware(sc->dsp_firm); | ||
1036 | sc->dsp_firm = NULL; | ||
1037 | } | ||
1038 | |||
1039 | if (sc->dsp_firm == NULL && request_dsp(sc) < 0) | ||
1040 | return; | ||
1041 | |||
1042 | p = (struct l1_code *) sc->dsp_firm->data; | ||
1043 | if (pageno >= p->page_header[0].PageNumber) { | ||
1044 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); | ||
1045 | return; | ||
1046 | } | ||
1047 | |||
1048 | if (pageno != 0) { | ||
1049 | __uea_load_page_e4(sc, pageno, 0); | ||
1050 | return; | ||
1051 | } | ||
1052 | |||
1053 | uea_dbg(INS_TO_USBDEV(sc), | ||
1054 | "sending Main DSP page %u\n", p->page_header[0].PageNumber); | ||
1055 | |||
1056 | for (i = 0; i < le16_to_cpu(p->page_header[0].PageNumber); i++) { | ||
1057 | if (E4_IS_BOOT_PAGE(p->page_header[i].PageSize)) | ||
1058 | __uea_load_page_e4(sc, i, 1); | ||
1059 | } | ||
1060 | |||
1061 | uea_dbg(INS_TO_USBDEV(sc),"sending start bi\n"); | ||
1062 | |||
1063 | bi.wHdr = cpu_to_be16(UEA_BIHDR); | ||
1064 | bi.bBootPage = 0; | ||
1065 | bi.bPageNumber = 0xff; | ||
1066 | bi.wReserved = cpu_to_be16(UEA_RESERVED); | ||
1067 | bi.dwSize = cpu_to_be32(E4_PAGE_BYTES(p->page_header[0].PageSize)); | ||
1068 | bi.dwAddress = swab32(p->page_header[0].PageAddress); | ||
1069 | |||
1070 | /* send block info through the IDMA pipe */ | ||
1071 | if (uea_idma_write(sc, &bi, E4_BLOCK_INFO_SIZE)) | ||
1072 | uea_err(INS_TO_USBDEV(sc), "sending DSP start bi failed\n"); | ||
1073 | } | ||
1074 | |||
738 | static inline void wake_up_cmv_ack(struct uea_softc *sc) | 1075 | static inline void wake_up_cmv_ack(struct uea_softc *sc) |
739 | { | 1076 | { |
740 | BUG_ON(sc->cmv_ack); | 1077 | BUG_ON(sc->cmv_ack); |
741 | sc->cmv_ack = 1; | 1078 | sc->cmv_ack = 1; |
742 | wake_up(&sc->cmv_ack_wait); | 1079 | wake_up(&sc->sync_q); |
743 | } | 1080 | } |
744 | 1081 | ||
745 | static inline int wait_cmv_ack(struct uea_softc *sc) | 1082 | static inline int wait_cmv_ack(struct uea_softc *sc) |
746 | { | 1083 | { |
747 | int ret = wait_event_interruptible_timeout(sc->cmv_ack_wait, | 1084 | int ret = uea_wait(sc, sc->cmv_ack , ACK_TIMEOUT); |
748 | sc->cmv_ack, ACK_TIMEOUT); | 1085 | |
749 | sc->cmv_ack = 0; | 1086 | sc->cmv_ack = 0; |
750 | 1087 | ||
751 | uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n", | 1088 | uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n", |
@@ -792,33 +1129,68 @@ static int uea_request(struct uea_softc *sc, | |||
792 | return 0; | 1129 | return 0; |
793 | } | 1130 | } |
794 | 1131 | ||
795 | static int uea_cmv(struct uea_softc *sc, | 1132 | static int uea_cmv_e1(struct uea_softc *sc, |
796 | u8 function, u32 address, u16 offset, u32 data) | 1133 | u8 function, u32 address, u16 offset, u32 data) |
797 | { | 1134 | { |
798 | struct cmv cmv; | 1135 | struct cmv_e1 cmv; |
799 | int ret; | 1136 | int ret; |
800 | 1137 | ||
801 | uea_enters(INS_TO_USBDEV(sc)); | 1138 | uea_enters(INS_TO_USBDEV(sc)); |
802 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, " | 1139 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, " |
803 | "offset : 0x%04x, data : 0x%08x\n", | 1140 | "offset : 0x%04x, data : 0x%08x\n", |
804 | FUNCTION_TYPE(function), FUNCTION_SUBTYPE(function), | 1141 | E1_FUNCTION_TYPE(function), E1_FUNCTION_SUBTYPE(function), |
805 | GETSA1(address), GETSA2(address), GETSA3(address), | 1142 | E1_GETSA1(address), E1_GETSA2(address), E1_GETSA3(address), |
806 | GETSA4(address), offset, data); | 1143 | E1_GETSA4(address), offset, data); |
1144 | |||
807 | /* we send a request, but we expect a reply */ | 1145 | /* we send a request, but we expect a reply */ |
808 | sc->cmv_function = function | 0x2; | 1146 | sc->cmv_dsc.e1.function = function | 0x2; |
809 | sc->cmv_idx++; | 1147 | sc->cmv_dsc.e1.idx++; |
810 | sc->cmv_address = address; | 1148 | sc->cmv_dsc.e1.address = address; |
811 | sc->cmv_offset = offset; | 1149 | sc->cmv_dsc.e1.offset = offset; |
812 | 1150 | ||
813 | cmv.wPreamble = cpu_to_le16(PREAMBLE); | 1151 | cmv.wPreamble = cpu_to_le16(E1_PREAMBLE); |
814 | cmv.bDirection = HOSTTOMODEM; | 1152 | cmv.bDirection = E1_HOSTTOMODEM; |
815 | cmv.bFunction = function; | 1153 | cmv.bFunction = function; |
816 | cmv.wIndex = cpu_to_le16(sc->cmv_idx); | 1154 | cmv.wIndex = cpu_to_le16(sc->cmv_dsc.e1.idx); |
817 | put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress); | 1155 | put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress); |
818 | cmv.wOffsetAddress = cpu_to_le16(offset); | 1156 | cmv.wOffsetAddress = cpu_to_le16(offset); |
819 | put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData); | 1157 | put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData); |
820 | 1158 | ||
821 | ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); | 1159 | ret = uea_request(sc, UEA_E1_SET_BLOCK, UEA_MPTX_START, sizeof(cmv), &cmv); |
1160 | if (ret < 0) | ||
1161 | return ret; | ||
1162 | ret = wait_cmv_ack(sc); | ||
1163 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1164 | return ret; | ||
1165 | } | ||
1166 | |||
1167 | static int uea_cmv_e4(struct uea_softc *sc, | ||
1168 | u16 function, u16 group, u16 address, u16 offset, u32 data) | ||
1169 | { | ||
1170 | struct cmv_e4 cmv; | ||
1171 | int ret; | ||
1172 | |||
1173 | uea_enters(INS_TO_USBDEV(sc)); | ||
1174 | memset(&cmv, 0, sizeof(cmv)); | ||
1175 | |||
1176 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Group : 0x%04x, " | ||
1177 | "Address : 0x%04x, offset : 0x%04x, data : 0x%08x\n", | ||
1178 | E4_FUNCTION_TYPE(function), E4_FUNCTION_SUBTYPE(function), | ||
1179 | group, address, offset, data); | ||
1180 | |||
1181 | /* we send a request, but we expect a reply */ | ||
1182 | sc->cmv_dsc.e4.function = function | (0x1 << 4); | ||
1183 | sc->cmv_dsc.e4.offset = offset; | ||
1184 | sc->cmv_dsc.e4.address = address; | ||
1185 | sc->cmv_dsc.e4.group = group; | ||
1186 | |||
1187 | cmv.wFunction = cpu_to_be16(function); | ||
1188 | cmv.wGroup = cpu_to_be16(group); | ||
1189 | cmv.wAddress = cpu_to_be16(address); | ||
1190 | cmv.wOffset = cpu_to_be16(offset); | ||
1191 | cmv.dwData[0] = cpu_to_be32(data); | ||
1192 | |||
1193 | ret = uea_request(sc, UEA_E4_SET_BLOCK, UEA_MPTX_START, sizeof(cmv), &cmv); | ||
822 | if (ret < 0) | 1194 | if (ret < 0) |
823 | return ret; | 1195 | return ret; |
824 | ret = wait_cmv_ack(sc); | 1196 | ret = wait_cmv_ack(sc); |
@@ -826,10 +1198,10 @@ static int uea_cmv(struct uea_softc *sc, | |||
826 | return ret; | 1198 | return ret; |
827 | } | 1199 | } |
828 | 1200 | ||
829 | static inline int uea_read_cmv(struct uea_softc *sc, | 1201 | static inline int uea_read_cmv_e1(struct uea_softc *sc, |
830 | u32 address, u16 offset, u32 *data) | 1202 | u32 address, u16 offset, u32 *data) |
831 | { | 1203 | { |
832 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD), | 1204 | int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTREAD), |
833 | address, offset, 0); | 1205 | address, offset, 0); |
834 | if (ret < 0) | 1206 | if (ret < 0) |
835 | uea_err(INS_TO_USBDEV(sc), | 1207 | uea_err(INS_TO_USBDEV(sc), |
@@ -840,10 +1212,27 @@ static inline int uea_read_cmv(struct uea_softc *sc, | |||
840 | return ret; | 1212 | return ret; |
841 | } | 1213 | } |
842 | 1214 | ||
843 | static inline int uea_write_cmv(struct uea_softc *sc, | 1215 | static inline int uea_read_cmv_e4(struct uea_softc *sc, |
1216 | u8 size, u16 group, u16 address, u16 offset, u32 *data) | ||
1217 | { | ||
1218 | int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS, E4_REQUESTREAD, size), | ||
1219 | group, address, offset, 0); | ||
1220 | if (ret < 0) | ||
1221 | uea_err(INS_TO_USBDEV(sc), | ||
1222 | "reading cmv failed with error %d\n", ret); | ||
1223 | else { | ||
1224 | *data = sc->data; | ||
1225 | /* size is in 16-bit word quantities */ | ||
1226 | if (size > 2) | ||
1227 | *(data + 1) = sc->data1; | ||
1228 | } | ||
1229 | return ret; | ||
1230 | } | ||
1231 | |||
1232 | static inline int uea_write_cmv_e1(struct uea_softc *sc, | ||
844 | u32 address, u16 offset, u32 data) | 1233 | u32 address, u16 offset, u32 data) |
845 | { | 1234 | { |
846 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE), | 1235 | int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTWRITE), |
847 | address, offset, data); | 1236 | address, offset, data); |
848 | if (ret < 0) | 1237 | if (ret < 0) |
849 | uea_err(INS_TO_USBDEV(sc), | 1238 | uea_err(INS_TO_USBDEV(sc), |
@@ -852,12 +1241,48 @@ static inline int uea_write_cmv(struct uea_softc *sc, | |||
852 | return ret; | 1241 | return ret; |
853 | } | 1242 | } |
854 | 1243 | ||
1244 | static inline int uea_write_cmv_e4(struct uea_softc *sc, | ||
1245 | u8 size, u16 group, u16 address, u16 offset, u32 data) | ||
1246 | { | ||
1247 | int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS, E4_REQUESTWRITE, size), | ||
1248 | group, address, offset, data); | ||
1249 | if (ret < 0) | ||
1250 | uea_err(INS_TO_USBDEV(sc), | ||
1251 | "writing cmv failed with error %d\n", ret); | ||
1252 | |||
1253 | return ret; | ||
1254 | } | ||
1255 | |||
1256 | static void uea_set_bulk_timeout(struct uea_softc *sc, u32 dsrate) | ||
1257 | { | ||
1258 | int ret; | ||
1259 | u16 timeout; | ||
1260 | |||
1261 | /* in bulk mode the modem have problem with high rate | ||
1262 | * changing internal timing could improve things, but the | ||
1263 | * value is misterious. | ||
1264 | * ADI930 don't support it (-EPIPE error). | ||
1265 | */ | ||
1266 | |||
1267 | if (UEA_CHIP_VERSION(sc) == ADI930 || | ||
1268 | altsetting[sc->modem_index] > 0 || | ||
1269 | sc->stats.phy.dsrate == dsrate) | ||
1270 | return; | ||
1271 | |||
1272 | /* Original timming (1Mbit/s) from ADI (used in windows driver) */ | ||
1273 | timeout = (dsrate <= 1024*1024) ? 0 : 1; | ||
1274 | ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); | ||
1275 | uea_info(INS_TO_USBDEV(sc), "setting new timeout %d%s\n", | ||
1276 | timeout, ret < 0 ? " failed" : ""); | ||
1277 | |||
1278 | } | ||
1279 | |||
855 | /* | 1280 | /* |
856 | * Monitor the modem and update the stat | 1281 | * Monitor the modem and update the stat |
857 | * return 0 if everything is ok | 1282 | * return 0 if everything is ok |
858 | * return < 0 if an error occurs (-EAGAIN reboot needed) | 1283 | * return < 0 if an error occurs (-EAGAIN reboot needed) |
859 | */ | 1284 | */ |
860 | static int uea_stat(struct uea_softc *sc) | 1285 | static int uea_stat_e1(struct uea_softc *sc) |
861 | { | 1286 | { |
862 | u32 data; | 1287 | u32 data; |
863 | int ret; | 1288 | int ret; |
@@ -865,7 +1290,7 @@ static int uea_stat(struct uea_softc *sc) | |||
865 | uea_enters(INS_TO_USBDEV(sc)); | 1290 | uea_enters(INS_TO_USBDEV(sc)); |
866 | data = sc->stats.phy.state; | 1291 | data = sc->stats.phy.state; |
867 | 1292 | ||
868 | ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state); | 1293 | ret = uea_read_cmv_e1(sc, E1_SA_STAT, 0, &sc->stats.phy.state); |
869 | if (ret < 0) | 1294 | if (ret < 0) |
870 | return ret; | 1295 | return ret; |
871 | 1296 | ||
@@ -885,7 +1310,7 @@ static int uea_stat(struct uea_softc *sc) | |||
885 | 1310 | ||
886 | case 3: /* fail ... */ | 1311 | case 3: /* fail ... */ |
887 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" | 1312 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" |
888 | " (may be try other cmv/dsp)\n"); | 1313 | " (may be try other cmv/dsp)\n"); |
889 | return -EAGAIN; | 1314 | return -EAGAIN; |
890 | 1315 | ||
891 | case 4 ... 6: /* test state */ | 1316 | case 4 ... 6: /* test state */ |
@@ -923,7 +1348,7 @@ static int uea_stat(struct uea_softc *sc) | |||
923 | /* wake up processes waiting for synchronization */ | 1348 | /* wake up processes waiting for synchronization */ |
924 | wake_up(&sc->sync_q); | 1349 | wake_up(&sc->sync_q); |
925 | 1350 | ||
926 | ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags); | 1351 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 2, &sc->stats.phy.flags); |
927 | if (ret < 0) | 1352 | if (ret < 0) |
928 | return ret; | 1353 | return ret; |
929 | sc->stats.phy.mflags |= sc->stats.phy.flags; | 1354 | sc->stats.phy.mflags |= sc->stats.phy.flags; |
@@ -937,105 +1362,223 @@ static int uea_stat(struct uea_softc *sc) | |||
937 | return 0; | 1362 | return 0; |
938 | } | 1363 | } |
939 | 1364 | ||
940 | ret = uea_read_cmv(sc, SA_RATE, 0, &data); | 1365 | ret = uea_read_cmv_e1(sc, E1_SA_RATE, 0, &data); |
941 | if (ret < 0) | 1366 | if (ret < 0) |
942 | return ret; | 1367 | return ret; |
943 | 1368 | ||
944 | /* in bulk mode the modem have problem with high rate | 1369 | uea_set_bulk_timeout(sc, (data >> 16) * 32); |
945 | * changing internal timing could improve things, but the | ||
946 | * value is misterious. | ||
947 | * ADI930 don't support it (-EPIPE error). | ||
948 | */ | ||
949 | if (UEA_CHIP_VERSION(sc) != ADI930 | ||
950 | && !use_iso[sc->modem_index] | ||
951 | && sc->stats.phy.dsrate != (data >> 16) * 32) { | ||
952 | /* Original timming from ADI(used in windows driver) | ||
953 | * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits | ||
954 | */ | ||
955 | u16 timeout = (data <= 0x20ffff) ? 0 : 1; | ||
956 | ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); | ||
957 | uea_info(INS_TO_USBDEV(sc), | ||
958 | "setting new timeout %d%s\n", timeout, | ||
959 | ret < 0?" failed":""); | ||
960 | } | ||
961 | sc->stats.phy.dsrate = (data >> 16) * 32; | 1370 | sc->stats.phy.dsrate = (data >> 16) * 32; |
962 | sc->stats.phy.usrate = (data & 0xffff) * 32; | 1371 | sc->stats.phy.usrate = (data & 0xffff) * 32; |
963 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); | 1372 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); |
964 | 1373 | ||
965 | ret = uea_read_cmv(sc, SA_DIAG, 23, &data); | 1374 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 23, &data); |
966 | if (ret < 0) | 1375 | if (ret < 0) |
967 | return ret; | 1376 | return ret; |
968 | sc->stats.phy.dsattenuation = (data & 0xff) / 2; | 1377 | sc->stats.phy.dsattenuation = (data & 0xff) / 2; |
969 | 1378 | ||
970 | ret = uea_read_cmv(sc, SA_DIAG, 47, &data); | 1379 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 47, &data); |
971 | if (ret < 0) | 1380 | if (ret < 0) |
972 | return ret; | 1381 | return ret; |
973 | sc->stats.phy.usattenuation = (data & 0xff) / 2; | 1382 | sc->stats.phy.usattenuation = (data & 0xff) / 2; |
974 | 1383 | ||
975 | ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin); | 1384 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 25, &sc->stats.phy.dsmargin); |
976 | if (ret < 0) | 1385 | if (ret < 0) |
977 | return ret; | 1386 | return ret; |
978 | 1387 | ||
979 | ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin); | 1388 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 49, &sc->stats.phy.usmargin); |
980 | if (ret < 0) | 1389 | if (ret < 0) |
981 | return ret; | 1390 | return ret; |
982 | 1391 | ||
983 | ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow); | 1392 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 51, &sc->stats.phy.rxflow); |
984 | if (ret < 0) | 1393 | if (ret < 0) |
985 | return ret; | 1394 | return ret; |
986 | 1395 | ||
987 | ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow); | 1396 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 52, &sc->stats.phy.txflow); |
988 | if (ret < 0) | 1397 | if (ret < 0) |
989 | return ret; | 1398 | return ret; |
990 | 1399 | ||
991 | ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc); | 1400 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 54, &sc->stats.phy.dsunc); |
992 | if (ret < 0) | 1401 | if (ret < 0) |
993 | return ret; | 1402 | return ret; |
994 | 1403 | ||
995 | /* only for atu-c */ | 1404 | /* only for atu-c */ |
996 | ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc); | 1405 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 58, &sc->stats.phy.usunc); |
997 | if (ret < 0) | 1406 | if (ret < 0) |
998 | return ret; | 1407 | return ret; |
999 | 1408 | ||
1000 | ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr); | 1409 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 53, &sc->stats.phy.dscorr); |
1001 | if (ret < 0) | 1410 | if (ret < 0) |
1002 | return ret; | 1411 | return ret; |
1003 | 1412 | ||
1004 | /* only for atu-c */ | 1413 | /* only for atu-c */ |
1005 | ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr); | 1414 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 57, &sc->stats.phy.uscorr); |
1006 | if (ret < 0) | 1415 | if (ret < 0) |
1007 | return ret; | 1416 | return ret; |
1008 | 1417 | ||
1009 | ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco); | 1418 | ret = uea_read_cmv_e1(sc, E1_SA_INFO, 8, &sc->stats.phy.vidco); |
1010 | if (ret < 0) | 1419 | if (ret < 0) |
1011 | return ret; | 1420 | return ret; |
1012 | 1421 | ||
1013 | ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe); | 1422 | ret = uea_read_cmv_e1(sc, E1_SA_INFO, 13, &sc->stats.phy.vidcpe); |
1014 | if (ret < 0) | 1423 | if (ret < 0) |
1015 | return ret; | 1424 | return ret; |
1016 | 1425 | ||
1017 | return 0; | 1426 | return 0; |
1018 | } | 1427 | } |
1019 | 1428 | ||
1020 | static int request_cmvs(struct uea_softc *sc, | 1429 | static int uea_stat_e4(struct uea_softc *sc) |
1021 | struct uea_cmvs **cmvs, const struct firmware **fw) | ||
1022 | { | 1430 | { |
1023 | int ret, size; | 1431 | u32 data; |
1024 | u8 *data; | 1432 | u32 tmp_arr[2]; |
1433 | int ret; | ||
1434 | |||
1435 | uea_enters(INS_TO_USBDEV(sc)); | ||
1436 | data = sc->stats.phy.state; | ||
1437 | |||
1438 | /* XXX only need to be done before operationnal... */ | ||
1439 | ret = uea_read_cmv_e4(sc, 1, E4_SA_STAT, 0, 0, &sc->stats.phy.state); | ||
1440 | if (ret < 0) | ||
1441 | return ret; | ||
1442 | |||
1443 | switch (sc->stats.phy.state) { | ||
1444 | case 0x0: /* not yet synchronized */ | ||
1445 | case 0x1: | ||
1446 | case 0x3: | ||
1447 | case 0x4: | ||
1448 | uea_dbg(INS_TO_USBDEV(sc), "modem not yet synchronized\n"); | ||
1449 | return 0; | ||
1450 | case 0x5: /* initialization */ | ||
1451 | case 0x6: | ||
1452 | case 0x9: | ||
1453 | case 0xa: | ||
1454 | uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n"); | ||
1455 | return 0; | ||
1456 | case 0x2: /* fail ... */ | ||
1457 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" | ||
1458 | " (may be try other cmv/dsp)\n"); | ||
1459 | return -EAGAIN; | ||
1460 | case 0x7: /* operational */ | ||
1461 | break; | ||
1462 | default: | ||
1463 | uea_warn(INS_TO_USBDEV(sc), "unknown state: %x\n", sc->stats.phy.state); | ||
1464 | return 0; | ||
1465 | } | ||
1466 | |||
1467 | if (data != 7) { | ||
1468 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL); | ||
1469 | uea_info(INS_TO_USBDEV(sc), "modem operational\n"); | ||
1470 | |||
1471 | /* release the dsp firmware as it is not needed until | ||
1472 | * the next failure | ||
1473 | */ | ||
1474 | if (sc->dsp_firm) { | ||
1475 | release_firmware(sc->dsp_firm); | ||
1476 | sc->dsp_firm = NULL; | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1480 | /* always update it as atm layer could not be init when we switch to | ||
1481 | * operational state | ||
1482 | */ | ||
1483 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND); | ||
1484 | |||
1485 | /* wake up processes waiting for synchronization */ | ||
1486 | wake_up(&sc->sync_q); | ||
1487 | |||
1488 | /* TODO improve this state machine : | ||
1489 | * we need some CMV info : what they do and their unit | ||
1490 | * we should find the equivalent of eagle3- CMV | ||
1491 | */ | ||
1492 | /* check flags */ | ||
1493 | ret = uea_read_cmv_e4(sc, 1, E4_SA_DIAG, 0, 0, &sc->stats.phy.flags); | ||
1494 | if (ret < 0) | ||
1495 | return ret; | ||
1496 | sc->stats.phy.mflags |= sc->stats.phy.flags; | ||
1497 | |||
1498 | /* in case of a flags ( for example delineation LOSS (& 0x10)), | ||
1499 | * we check the status again in order to detect the failure earlier | ||
1500 | */ | ||
1501 | if (sc->stats.phy.flags) { | ||
1502 | uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n", | ||
1503 | sc->stats.phy.flags); | ||
1504 | if (sc->stats.phy.flags & 1) //delineation LOSS | ||
1505 | return -EAGAIN; | ||
1506 | if (sc->stats.phy.flags & 0x4000) //Reset Flag | ||
1507 | return -EAGAIN; | ||
1508 | return 0; | ||
1509 | } | ||
1510 | |||
1511 | /* rate data may be in upper or lower half of 64 bit word, strange */ | ||
1512 | ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 0, 0, tmp_arr); | ||
1513 | if (ret < 0) | ||
1514 | return ret; | ||
1515 | data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1]; | ||
1516 | sc->stats.phy.usrate = data / 1000; | ||
1517 | |||
1518 | ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 1, 0, tmp_arr); | ||
1519 | if (ret < 0) | ||
1520 | return ret; | ||
1521 | data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1]; | ||
1522 | uea_set_bulk_timeout(sc, data / 1000); | ||
1523 | sc->stats.phy.dsrate = data / 1000; | ||
1524 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); | ||
1525 | |||
1526 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 1, &data); | ||
1527 | if (ret < 0) | ||
1528 | return ret; | ||
1529 | sc->stats.phy.dsattenuation = data / 10; | ||
1530 | |||
1531 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 1, &data); | ||
1532 | if (ret < 0) | ||
1533 | return ret; | ||
1534 | sc->stats.phy.usattenuation = data / 10; | ||
1535 | |||
1536 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 3, &data); | ||
1537 | if (ret < 0) | ||
1538 | return ret; | ||
1539 | sc->stats.phy.dsmargin = data / 2; | ||
1540 | |||
1541 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 3, &data); | ||
1542 | if (ret < 0) | ||
1543 | return ret; | ||
1544 | sc->stats.phy.usmargin = data / 10; | ||
1545 | |||
1546 | return 0; | ||
1547 | } | ||
1548 | |||
1549 | static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver) | ||
1550 | { | ||
1551 | char file_arr[] = "CMVxy.bin"; | ||
1025 | char *file; | 1552 | char *file; |
1026 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ | ||
1027 | 1553 | ||
1554 | /* set proper name corresponding modem version and line type */ | ||
1028 | if (cmv_file[sc->modem_index] == NULL) { | 1555 | if (cmv_file[sc->modem_index] == NULL) { |
1029 | if (UEA_CHIP_VERSION(sc) == ADI930) | 1556 | if (UEA_CHIP_VERSION(sc) == ADI930) |
1030 | file = (IS_ISDN(sc->usb_dev)) ? "CMV9i.bin" : "CMV9p.bin"; | 1557 | file_arr[3] = '9'; |
1558 | else if (UEA_CHIP_VERSION(sc) == EAGLE_IV) | ||
1559 | file_arr[3] = '4'; | ||
1031 | else | 1560 | else |
1032 | file = (IS_ISDN(sc->usb_dev)) ? "CMVei.bin" : "CMVep.bin"; | 1561 | file_arr[3] = 'e'; |
1562 | |||
1563 | file_arr[4] = IS_ISDN(sc) ? 'i' : 'p'; | ||
1564 | file = file_arr; | ||
1033 | } else | 1565 | } else |
1034 | file = cmv_file[sc->modem_index]; | 1566 | file = cmv_file[sc->modem_index]; |
1035 | 1567 | ||
1036 | strcpy(cmv_name, FW_DIR); | 1568 | strcpy(cmv_name, FW_DIR); |
1037 | strlcat(cmv_name, file, sizeof(cmv_name)); | 1569 | strlcat(cmv_name, file, FIRMWARE_NAME_MAX); |
1570 | if (ver == 2) | ||
1571 | strlcat(cmv_name, ".v2", FIRMWARE_NAME_MAX); | ||
1572 | } | ||
1573 | |||
1574 | static int request_cmvs_old(struct uea_softc *sc, | ||
1575 | void **cmvs, const struct firmware **fw) | ||
1576 | { | ||
1577 | int ret, size; | ||
1578 | u8 *data; | ||
1579 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ | ||
1038 | 1580 | ||
1581 | cmvs_file_name(sc, cmv_name, 1); | ||
1039 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); | 1582 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); |
1040 | if (ret < 0) { | 1583 | if (ret < 0) { |
1041 | uea_err(INS_TO_USBDEV(sc), | 1584 | uea_err(INS_TO_USBDEV(sc), |
@@ -1045,16 +1588,197 @@ static int request_cmvs(struct uea_softc *sc, | |||
1045 | } | 1588 | } |
1046 | 1589 | ||
1047 | data = (u8 *) (*fw)->data; | 1590 | data = (u8 *) (*fw)->data; |
1048 | size = *data * sizeof(struct uea_cmvs) + 1; | 1591 | size = (*fw)->size; |
1049 | if (size != (*fw)->size) { | 1592 | if (size < 1) |
1050 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | 1593 | goto err_fw_corrupted; |
1051 | cmv_name); | 1594 | |
1052 | release_firmware(*fw); | 1595 | if (size != *data * sizeof(struct uea_cmvs_v1) + 1) |
1053 | return -EILSEQ; | 1596 | goto err_fw_corrupted; |
1597 | |||
1598 | *cmvs = (void *)(data + 1); | ||
1599 | return *data; | ||
1600 | |||
1601 | err_fw_corrupted: | ||
1602 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", cmv_name); | ||
1603 | release_firmware(*fw); | ||
1604 | return -EILSEQ; | ||
1605 | } | ||
1606 | |||
1607 | static int request_cmvs(struct uea_softc *sc, | ||
1608 | void **cmvs, const struct firmware **fw, int *ver) | ||
1609 | { | ||
1610 | int ret, size; | ||
1611 | u32 crc; | ||
1612 | u8 *data; | ||
1613 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ | ||
1614 | |||
1615 | cmvs_file_name(sc, cmv_name, 2); | ||
1616 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); | ||
1617 | if (ret < 0) { | ||
1618 | /* if caller can handle old version, try to provide it */ | ||
1619 | if (*ver == 1) { | ||
1620 | uea_warn(INS_TO_USBDEV(sc), "requesting firmware %s failed, " | ||
1621 | "try to get older cmvs\n", cmv_name); | ||
1622 | return request_cmvs_old(sc, cmvs, fw); | ||
1623 | } | ||
1624 | uea_err(INS_TO_USBDEV(sc), | ||
1625 | "requesting firmware %s failed with error %d\n", | ||
1626 | cmv_name, ret); | ||
1627 | return ret; | ||
1628 | } | ||
1629 | |||
1630 | size = (*fw)->size; | ||
1631 | data = (u8 *) (*fw)->data; | ||
1632 | if (size < 4 || strncmp(data, "cmv2", 4) != 0) { | ||
1633 | if (*ver == 1) { | ||
1634 | uea_warn(INS_TO_USBDEV(sc), "firmware %s is corrupted, " | ||
1635 | "try to get older cmvs\n", cmv_name); | ||
1636 | release_firmware(*fw); | ||
1637 | return request_cmvs_old(sc, cmvs, fw); | ||
1638 | } | ||
1639 | goto err_fw_corrupted; | ||
1054 | } | 1640 | } |
1055 | 1641 | ||
1056 | *cmvs = (struct uea_cmvs *)(data + 1); | 1642 | *ver = 2; |
1643 | |||
1644 | data += 4; | ||
1645 | size -= 4; | ||
1646 | if (size < 5) | ||
1647 | goto err_fw_corrupted; | ||
1648 | |||
1649 | crc = FW_GET_LONG(data); | ||
1650 | data += 4; | ||
1651 | size -= 4; | ||
1652 | if (crc32_be(0, data, size) != crc) | ||
1653 | goto err_fw_corrupted; | ||
1654 | |||
1655 | if (size != *data * sizeof(struct uea_cmvs_v2) + 1) | ||
1656 | goto err_fw_corrupted; | ||
1657 | |||
1658 | *cmvs = (void *) (data + 1); | ||
1057 | return *data; | 1659 | return *data; |
1660 | |||
1661 | err_fw_corrupted: | ||
1662 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", cmv_name); | ||
1663 | release_firmware(*fw); | ||
1664 | return -EILSEQ; | ||
1665 | } | ||
1666 | |||
1667 | static int uea_send_cmvs_e1(struct uea_softc *sc) | ||
1668 | { | ||
1669 | int i, ret, len; | ||
1670 | void *cmvs_ptr; | ||
1671 | const struct firmware *cmvs_fw; | ||
1672 | int ver = 1; // we can handle v1 cmv firmware version; | ||
1673 | |||
1674 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | ||
1675 | ret = uea_write_cmv_e1(sc, E1_SA_CNTL, 0, 1); | ||
1676 | if (ret < 0) | ||
1677 | return ret; | ||
1678 | |||
1679 | /* Dump firmware version */ | ||
1680 | ret = uea_read_cmv_e1(sc, E1_SA_INFO, 10, &sc->stats.phy.firmid); | ||
1681 | if (ret < 0) | ||
1682 | return ret; | ||
1683 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1684 | sc->stats.phy.firmid); | ||
1685 | |||
1686 | /* get options */ | ||
1687 | ret = len = request_cmvs(sc, &cmvs_ptr, &cmvs_fw, &ver); | ||
1688 | if (ret < 0) | ||
1689 | return ret; | ||
1690 | |||
1691 | /* send options */ | ||
1692 | if (ver == 1) { | ||
1693 | struct uea_cmvs_v1 *cmvs_v1 = cmvs_ptr; | ||
1694 | |||
1695 | uea_warn(INS_TO_USBDEV(sc), "use deprecated cmvs version, " | ||
1696 | "please update your firmware\n"); | ||
1697 | |||
1698 | for (i = 0; i < len; i++) { | ||
1699 | ret = uea_write_cmv_e1(sc, FW_GET_LONG(&cmvs_v1[i].address), | ||
1700 | FW_GET_WORD(&cmvs_v1[i].offset), | ||
1701 | FW_GET_LONG(&cmvs_v1[i].data)); | ||
1702 | if (ret < 0) | ||
1703 | goto out; | ||
1704 | } | ||
1705 | } else if (ver == 2) { | ||
1706 | struct uea_cmvs_v2 *cmvs_v2 = cmvs_ptr; | ||
1707 | |||
1708 | for (i = 0; i < len; i++) { | ||
1709 | ret = uea_write_cmv_e1(sc, FW_GET_LONG(&cmvs_v2[i].address), | ||
1710 | (u16) FW_GET_LONG(&cmvs_v2[i].offset), | ||
1711 | FW_GET_LONG(&cmvs_v2[i].data)); | ||
1712 | if (ret < 0) | ||
1713 | goto out; | ||
1714 | } | ||
1715 | } else { | ||
1716 | /* This realy should not happen */ | ||
1717 | uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver); | ||
1718 | goto out; | ||
1719 | } | ||
1720 | |||
1721 | /* Enter in R-ACT-REQ */ | ||
1722 | ret = uea_write_cmv_e1(sc, E1_SA_CNTL, 0, 2); | ||
1723 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1724 | uea_info(INS_TO_USBDEV(sc), "modem started, waiting synchronization...\n"); | ||
1725 | out: | ||
1726 | release_firmware(cmvs_fw); | ||
1727 | return ret; | ||
1728 | } | ||
1729 | |||
1730 | static int uea_send_cmvs_e4(struct uea_softc *sc) | ||
1731 | { | ||
1732 | int i, ret, len; | ||
1733 | void *cmvs_ptr; | ||
1734 | const struct firmware *cmvs_fw; | ||
1735 | int ver = 2; // we can only handle v2 cmv firmware version; | ||
1736 | |||
1737 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | ||
1738 | ret = uea_write_cmv_e4(sc, 1, E4_SA_CNTL, 0, 0, 1); | ||
1739 | if (ret < 0) | ||
1740 | return ret; | ||
1741 | |||
1742 | /* Dump firmware version */ | ||
1743 | /* XXX don't read the 3th byte as it is always 6 */ | ||
1744 | ret = uea_read_cmv_e4(sc, 2, E4_SA_INFO, 55, 0, &sc->stats.phy.firmid); | ||
1745 | if (ret < 0) | ||
1746 | return ret; | ||
1747 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1748 | sc->stats.phy.firmid); | ||
1749 | |||
1750 | |||
1751 | /* get options */ | ||
1752 | ret = len = request_cmvs(sc, &cmvs_ptr, &cmvs_fw, &ver); | ||
1753 | if (ret < 0) | ||
1754 | return ret; | ||
1755 | |||
1756 | /* send options */ | ||
1757 | if (ver == 2) { | ||
1758 | struct uea_cmvs_v2 *cmvs_v2 = cmvs_ptr; | ||
1759 | |||
1760 | for (i = 0; i < len; i++) { | ||
1761 | ret = uea_write_cmv_e4(sc, 1, | ||
1762 | FW_GET_LONG(&cmvs_v2[i].group), | ||
1763 | FW_GET_LONG(&cmvs_v2[i].address), | ||
1764 | FW_GET_LONG(&cmvs_v2[i].offset), | ||
1765 | FW_GET_LONG(&cmvs_v2[i].data)); | ||
1766 | if (ret < 0) | ||
1767 | goto out; | ||
1768 | } | ||
1769 | } else { | ||
1770 | /* This realy should not happen */ | ||
1771 | uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver); | ||
1772 | goto out; | ||
1773 | } | ||
1774 | |||
1775 | /* Enter in R-ACT-REQ */ | ||
1776 | ret = uea_write_cmv_e4(sc, 1, E4_SA_CNTL, 0, 0, 2); | ||
1777 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1778 | uea_info(INS_TO_USBDEV(sc), "modem started, waiting synchronization...\n"); | ||
1779 | out: | ||
1780 | release_firmware(cmvs_fw); | ||
1781 | return ret; | ||
1058 | } | 1782 | } |
1059 | 1783 | ||
1060 | /* Start boot post firmware modem: | 1784 | /* Start boot post firmware modem: |
@@ -1066,9 +1790,7 @@ static int request_cmvs(struct uea_softc *sc, | |||
1066 | static int uea_start_reset(struct uea_softc *sc) | 1790 | static int uea_start_reset(struct uea_softc *sc) |
1067 | { | 1791 | { |
1068 | u16 zero = 0; /* ;-) */ | 1792 | u16 zero = 0; /* ;-) */ |
1069 | int i, len, ret; | 1793 | int ret; |
1070 | struct uea_cmvs *cmvs; | ||
1071 | const struct firmware *cmvs_fw; | ||
1072 | 1794 | ||
1073 | uea_enters(INS_TO_USBDEV(sc)); | 1795 | uea_enters(INS_TO_USBDEV(sc)); |
1074 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); | 1796 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); |
@@ -1093,25 +1815,36 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1093 | uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL); | 1815 | uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL); |
1094 | 1816 | ||
1095 | /* original driver use 200ms, but windows driver use 100ms */ | 1817 | /* original driver use 200ms, but windows driver use 100ms */ |
1096 | msleep(100); | 1818 | ret = uea_wait(sc, 0, msecs_to_jiffies(100)); |
1819 | if (ret < 0) | ||
1820 | return ret; | ||
1097 | 1821 | ||
1098 | /* leave reset mode */ | 1822 | /* leave reset mode */ |
1099 | uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL); | 1823 | uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL); |
1100 | 1824 | ||
1101 | /* clear tx and rx mailboxes */ | 1825 | if (UEA_CHIP_VERSION(sc) != EAGLE_IV) { |
1102 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero); | 1826 | /* clear tx and rx mailboxes */ |
1103 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero); | 1827 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero); |
1104 | uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero); | 1828 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero); |
1829 | uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero); | ||
1830 | } | ||
1831 | |||
1832 | ret = uea_wait(sc, 0, msecs_to_jiffies(1000)); | ||
1833 | if (ret < 0) | ||
1834 | return ret; | ||
1835 | |||
1836 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) | ||
1837 | sc->cmv_dsc.e4.function = E4_MAKEFUNCTION(E4_ADSLDIRECTIVE, E4_MODEMREADY, 1); | ||
1838 | else | ||
1839 | sc->cmv_dsc.e1.function = E1_MAKEFUNCTION(E1_ADSLDIRECTIVE, E1_MODEMREADY); | ||
1105 | 1840 | ||
1106 | msleep(1000); | ||
1107 | sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); | ||
1108 | /* demask interrupt */ | 1841 | /* demask interrupt */ |
1109 | sc->booting = 0; | 1842 | sc->booting = 0; |
1110 | 1843 | ||
1111 | /* start loading DSP */ | 1844 | /* start loading DSP */ |
1112 | sc->pageno = 0; | 1845 | sc->pageno = 0; |
1113 | sc->ovl = 0; | 1846 | sc->ovl = 0; |
1114 | schedule_work(&sc->task); | 1847 | queue_work(sc->work_q, &sc->task); |
1115 | 1848 | ||
1116 | /* wait for modem ready CMV */ | 1849 | /* wait for modem ready CMV */ |
1117 | ret = wait_cmv_ack(sc); | 1850 | ret = wait_cmv_ack(sc); |
@@ -1120,38 +1853,10 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1120 | 1853 | ||
1121 | uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n"); | 1854 | uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n"); |
1122 | 1855 | ||
1123 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | 1856 | ret = sc->send_cmvs(sc); |
1124 | ret = uea_write_cmv(sc, SA_CNTL, 0, 1); | ||
1125 | if (ret < 0) | ||
1126 | return ret; | ||
1127 | |||
1128 | /* Dump firmware version */ | ||
1129 | ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); | ||
1130 | if (ret < 0) | 1857 | if (ret < 0) |
1131 | return ret; | 1858 | return ret; |
1132 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1133 | sc->stats.phy.firmid); | ||
1134 | 1859 | ||
1135 | /* get options */ | ||
1136 | ret = len = request_cmvs(sc, &cmvs, &cmvs_fw); | ||
1137 | if (ret < 0) | ||
1138 | return ret; | ||
1139 | |||
1140 | /* send options */ | ||
1141 | for (i = 0; i < len; i++) { | ||
1142 | ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address), | ||
1143 | FW_GET_WORD(&cmvs[i].offset), | ||
1144 | FW_GET_LONG(&cmvs[i].data)); | ||
1145 | if (ret < 0) | ||
1146 | goto out; | ||
1147 | } | ||
1148 | /* Enter in R-ACT-REQ */ | ||
1149 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); | ||
1150 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1151 | uea_info(INS_TO_USBDEV(sc), "Modem started, " | ||
1152 | "waiting synchronization\n"); | ||
1153 | out: | ||
1154 | release_firmware(cmvs_fw); | ||
1155 | sc->reset = 0; | 1860 | sc->reset = 0; |
1156 | uea_leaves(INS_TO_USBDEV(sc)); | 1861 | uea_leaves(INS_TO_USBDEV(sc)); |
1157 | return ret; | 1862 | return ret; |
@@ -1174,12 +1879,10 @@ static int uea_kthread(void *data) | |||
1174 | if (ret < 0 || sc->reset) | 1879 | if (ret < 0 || sc->reset) |
1175 | ret = uea_start_reset(sc); | 1880 | ret = uea_start_reset(sc); |
1176 | if (!ret) | 1881 | if (!ret) |
1177 | ret = uea_stat(sc); | 1882 | ret = sc->stat(sc); |
1178 | if (ret != -EAGAIN) | 1883 | if (ret != -EAGAIN) |
1179 | msleep_interruptible(1000); | 1884 | uea_wait(sc, 0, msecs_to_jiffies(1000)); |
1180 | if (try_to_freeze()) | 1885 | try_to_freeze(); |
1181 | uea_err(INS_TO_USBDEV(sc), "suspend/resume not supported, " | ||
1182 | "please unplug/replug your modem\n"); | ||
1183 | } | 1886 | } |
1184 | uea_leaves(INS_TO_USBDEV(sc)); | 1887 | uea_leaves(INS_TO_USBDEV(sc)); |
1185 | return ret; | 1888 | return ret; |
@@ -1234,7 +1937,6 @@ static int load_XILINX_firmware(struct uea_softc *sc) | |||
1234 | if (ret < 0) | 1937 | if (ret < 0) |
1235 | uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret); | 1938 | uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret); |
1236 | 1939 | ||
1237 | |||
1238 | err1: | 1940 | err1: |
1239 | release_firmware(fw_entry); | 1941 | release_firmware(fw_entry); |
1240 | err0: | 1942 | err0: |
@@ -1243,40 +1945,41 @@ err0: | |||
1243 | } | 1945 | } |
1244 | 1946 | ||
1245 | /* The modem send us an ack. First with check if it right */ | 1947 | /* The modem send us an ack. First with check if it right */ |
1246 | static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | 1948 | static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr) |
1247 | { | 1949 | { |
1950 | struct cmv_dsc_e1 *dsc = &sc->cmv_dsc.e1; | ||
1951 | struct cmv_e1 *cmv = &intr->u.e1.s2.cmv; | ||
1952 | |||
1248 | uea_enters(INS_TO_USBDEV(sc)); | 1953 | uea_enters(INS_TO_USBDEV(sc)); |
1249 | if (le16_to_cpu(cmv->wPreamble) != PREAMBLE) | 1954 | if (le16_to_cpu(cmv->wPreamble) != E1_PREAMBLE) |
1250 | goto bad1; | 1955 | goto bad1; |
1251 | 1956 | ||
1252 | if (cmv->bDirection != MODEMTOHOST) | 1957 | if (cmv->bDirection != E1_MODEMTOHOST) |
1253 | goto bad1; | 1958 | goto bad1; |
1254 | 1959 | ||
1255 | /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to | 1960 | /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to |
1256 | * the first MEMACESS cmv. Ignore it... | 1961 | * the first MEMACESS cmv. Ignore it... |
1257 | */ | 1962 | */ |
1258 | if (cmv->bFunction != sc->cmv_function) { | 1963 | if (cmv->bFunction != dsc->function) { |
1259 | if (UEA_CHIP_VERSION(sc) == ADI930 | 1964 | if (UEA_CHIP_VERSION(sc) == ADI930 |
1260 | && cmv->bFunction == MAKEFUNCTION(2, 2)) { | 1965 | && cmv->bFunction == E1_MAKEFUNCTION(2, 2)) { |
1261 | cmv->wIndex = cpu_to_le16(sc->cmv_idx); | 1966 | cmv->wIndex = cpu_to_le16(dsc->idx); |
1262 | put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress); | 1967 | put_unaligned(cpu_to_le32(dsc->address), &cmv->dwSymbolicAddress); |
1263 | cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset); | 1968 | cmv->wOffsetAddress = cpu_to_le16(dsc->offset); |
1264 | } | 1969 | } else |
1265 | else | ||
1266 | goto bad2; | 1970 | goto bad2; |
1267 | } | 1971 | } |
1268 | 1972 | ||
1269 | if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { | 1973 | if (cmv->bFunction == E1_MAKEFUNCTION(E1_ADSLDIRECTIVE, E1_MODEMREADY)) { |
1270 | wake_up_cmv_ack(sc); | 1974 | wake_up_cmv_ack(sc); |
1271 | uea_leaves(INS_TO_USBDEV(sc)); | 1975 | uea_leaves(INS_TO_USBDEV(sc)); |
1272 | return; | 1976 | return; |
1273 | } | 1977 | } |
1274 | 1978 | ||
1275 | /* in case of MEMACCESS */ | 1979 | /* in case of MEMACCESS */ |
1276 | if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx || | 1980 | if (le16_to_cpu(cmv->wIndex) != dsc->idx || |
1277 | le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) != | 1981 | le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) != dsc->address || |
1278 | sc->cmv_address | 1982 | le16_to_cpu(cmv->wOffsetAddress) != dsc->offset) |
1279 | || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset) | ||
1280 | goto bad2; | 1983 | goto bad2; |
1281 | 1984 | ||
1282 | sc->data = le32_to_cpu(get_unaligned(&cmv->dwData)); | 1985 | sc->data = le32_to_cpu(get_unaligned(&cmv->dwData)); |
@@ -1289,8 +1992,8 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | |||
1289 | bad2: | 1992 | bad2: |
1290 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | 1993 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," |
1291 | "Function : %d, Subfunction : %d\n", | 1994 | "Function : %d, Subfunction : %d\n", |
1292 | FUNCTION_TYPE(cmv->bFunction), | 1995 | E1_FUNCTION_TYPE(cmv->bFunction), |
1293 | FUNCTION_SUBTYPE(cmv->bFunction)); | 1996 | E1_FUNCTION_SUBTYPE(cmv->bFunction)); |
1294 | uea_leaves(INS_TO_USBDEV(sc)); | 1997 | uea_leaves(INS_TO_USBDEV(sc)); |
1295 | return; | 1998 | return; |
1296 | 1999 | ||
@@ -1301,6 +2004,61 @@ bad1: | |||
1301 | uea_leaves(INS_TO_USBDEV(sc)); | 2004 | uea_leaves(INS_TO_USBDEV(sc)); |
1302 | } | 2005 | } |
1303 | 2006 | ||
2007 | /* The modem send us an ack. First with check if it right */ | ||
2008 | static void uea_dispatch_cmv_e4(struct uea_softc *sc, struct intr_pkt *intr) | ||
2009 | { | ||
2010 | struct cmv_dsc_e4 *dsc = &sc->cmv_dsc.e4; | ||
2011 | struct cmv_e4 *cmv = &intr->u.e4.s2.cmv; | ||
2012 | |||
2013 | uea_enters(INS_TO_USBDEV(sc)); | ||
2014 | uea_dbg(INS_TO_USBDEV(sc), "cmv %x %x %x %x %x %x\n", | ||
2015 | be16_to_cpu(cmv->wGroup), be16_to_cpu(cmv->wFunction), | ||
2016 | be16_to_cpu(cmv->wOffset), be16_to_cpu(cmv->wAddress), | ||
2017 | be32_to_cpu(cmv->dwData[0]), be32_to_cpu(cmv->dwData[1])); | ||
2018 | |||
2019 | if (be16_to_cpu(cmv->wFunction) != dsc->function) | ||
2020 | goto bad2; | ||
2021 | |||
2022 | if (be16_to_cpu(cmv->wFunction) == E4_MAKEFUNCTION(E4_ADSLDIRECTIVE, E4_MODEMREADY, 1)) { | ||
2023 | wake_up_cmv_ack(sc); | ||
2024 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2025 | return; | ||
2026 | } | ||
2027 | |||
2028 | /* in case of MEMACCESS */ | ||
2029 | if (be16_to_cpu(cmv->wOffset) != dsc->offset || | ||
2030 | be16_to_cpu(cmv->wGroup) != dsc->group || | ||
2031 | be16_to_cpu(cmv->wAddress) != dsc->address) | ||
2032 | goto bad2; | ||
2033 | |||
2034 | sc->data = be32_to_cpu(cmv->dwData[0]); | ||
2035 | sc->data1 = be32_to_cpu(cmv->dwData[1]); | ||
2036 | wake_up_cmv_ack(sc); | ||
2037 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2038 | return; | ||
2039 | |||
2040 | bad2: | ||
2041 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | ||
2042 | "Function : %d, Subfunction : %d\n", | ||
2043 | E4_FUNCTION_TYPE(cmv->wFunction), | ||
2044 | E4_FUNCTION_SUBTYPE(cmv->wFunction)); | ||
2045 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2046 | return; | ||
2047 | } | ||
2048 | |||
2049 | static void uea_schedule_load_page_e1(struct uea_softc *sc, struct intr_pkt *intr) | ||
2050 | { | ||
2051 | sc->pageno = intr->e1_bSwapPageNo; | ||
2052 | sc->ovl = intr->e1_bOvl >> 4 | intr->e1_bOvl << 4; | ||
2053 | queue_work(sc->work_q, &sc->task); | ||
2054 | } | ||
2055 | |||
2056 | static void uea_schedule_load_page_e4(struct uea_softc *sc, struct intr_pkt *intr) | ||
2057 | { | ||
2058 | sc->pageno = intr->e4_bSwapPageNo; | ||
2059 | queue_work(sc->work_q, &sc->task); | ||
2060 | } | ||
2061 | |||
1304 | /* | 2062 | /* |
1305 | * interrupt handler | 2063 | * interrupt handler |
1306 | */ | 2064 | */ |
@@ -1326,13 +2084,11 @@ static void uea_intr(struct urb *urb) | |||
1326 | 2084 | ||
1327 | switch (le16_to_cpu(intr->wInterrupt)) { | 2085 | switch (le16_to_cpu(intr->wInterrupt)) { |
1328 | case INT_LOADSWAPPAGE: | 2086 | case INT_LOADSWAPPAGE: |
1329 | sc->pageno = intr->bSwapPageNo; | 2087 | sc->schedule_load_page(sc, intr); |
1330 | sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4; | ||
1331 | schedule_work(&sc->task); | ||
1332 | break; | 2088 | break; |
1333 | 2089 | ||
1334 | case INT_INCOMINGCMV: | 2090 | case INT_INCOMINGCMV: |
1335 | uea_dispatch_cmv(sc, &intr->u.s2.cmv); | 2091 | sc->dispatch_cmv(sc, intr); |
1336 | break; | 2092 | break; |
1337 | 2093 | ||
1338 | default: | 2094 | default: |
@@ -1349,35 +2105,55 @@ resubmit: | |||
1349 | */ | 2105 | */ |
1350 | static int uea_boot(struct uea_softc *sc) | 2106 | static int uea_boot(struct uea_softc *sc) |
1351 | { | 2107 | { |
1352 | int ret; | 2108 | int ret, size; |
1353 | struct intr_pkt *intr; | 2109 | struct intr_pkt *intr; |
1354 | 2110 | ||
1355 | uea_enters(INS_TO_USBDEV(sc)); | 2111 | uea_enters(INS_TO_USBDEV(sc)); |
1356 | 2112 | ||
1357 | INIT_WORK(&sc->task, uea_load_page); | 2113 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
2114 | size = E4_INTR_PKT_SIZE; | ||
2115 | sc->dispatch_cmv = uea_dispatch_cmv_e4; | ||
2116 | sc->schedule_load_page = uea_schedule_load_page_e4; | ||
2117 | sc->stat = uea_stat_e4; | ||
2118 | sc->send_cmvs = uea_send_cmvs_e4; | ||
2119 | INIT_WORK(&sc->task, uea_load_page_e4); | ||
2120 | } else { | ||
2121 | size = E1_INTR_PKT_SIZE; | ||
2122 | sc->dispatch_cmv = uea_dispatch_cmv_e1; | ||
2123 | sc->schedule_load_page = uea_schedule_load_page_e1; | ||
2124 | sc->stat = uea_stat_e1; | ||
2125 | sc->send_cmvs = uea_send_cmvs_e1; | ||
2126 | INIT_WORK(&sc->task, uea_load_page_e1); | ||
2127 | } | ||
2128 | |||
1358 | init_waitqueue_head(&sc->sync_q); | 2129 | init_waitqueue_head(&sc->sync_q); |
1359 | init_waitqueue_head(&sc->cmv_ack_wait); | 2130 | |
2131 | sc->work_q = create_workqueue("ueagle-dsp"); | ||
2132 | if (!sc->work_q) { | ||
2133 | uea_err(INS_TO_USBDEV(sc), "cannot allocate workqueue\n"); | ||
2134 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2135 | return -ENOMEM; | ||
2136 | } | ||
1360 | 2137 | ||
1361 | if (UEA_CHIP_VERSION(sc) == ADI930) | 2138 | if (UEA_CHIP_VERSION(sc) == ADI930) |
1362 | load_XILINX_firmware(sc); | 2139 | load_XILINX_firmware(sc); |
1363 | 2140 | ||
1364 | intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL); | 2141 | intr = kmalloc(size, GFP_KERNEL); |
1365 | if (!intr) { | 2142 | if (!intr) { |
1366 | uea_err(INS_TO_USBDEV(sc), | 2143 | uea_err(INS_TO_USBDEV(sc), |
1367 | "cannot allocate interrupt package\n"); | 2144 | "cannot allocate interrupt package\n"); |
1368 | uea_leaves(INS_TO_USBDEV(sc)); | 2145 | goto err0; |
1369 | return -ENOMEM; | ||
1370 | } | 2146 | } |
1371 | 2147 | ||
1372 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); | 2148 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); |
1373 | if (!sc->urb_int) { | 2149 | if (!sc->urb_int) { |
1374 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); | 2150 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); |
1375 | goto err; | 2151 | goto err1; |
1376 | } | 2152 | } |
1377 | 2153 | ||
1378 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, | 2154 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, |
1379 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), | 2155 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), |
1380 | intr, INTR_PKT_SIZE, uea_intr, sc, | 2156 | intr, size, uea_intr, sc, |
1381 | sc->usb_dev->actconfig->interface[0]->altsetting[0]. | 2157 | sc->usb_dev->actconfig->interface[0]->altsetting[0]. |
1382 | endpoint[0].desc.bInterval); | 2158 | endpoint[0].desc.bInterval); |
1383 | 2159 | ||
@@ -1385,7 +2161,7 @@ static int uea_boot(struct uea_softc *sc) | |||
1385 | if (ret < 0) { | 2161 | if (ret < 0) { |
1386 | uea_err(INS_TO_USBDEV(sc), | 2162 | uea_err(INS_TO_USBDEV(sc), |
1387 | "urb submition failed with error %d\n", ret); | 2163 | "urb submition failed with error %d\n", ret); |
1388 | goto err; | 2164 | goto err1; |
1389 | } | 2165 | } |
1390 | 2166 | ||
1391 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); | 2167 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); |
@@ -1399,10 +2175,12 @@ static int uea_boot(struct uea_softc *sc) | |||
1399 | 2175 | ||
1400 | err2: | 2176 | err2: |
1401 | usb_kill_urb(sc->urb_int); | 2177 | usb_kill_urb(sc->urb_int); |
1402 | err: | 2178 | err1: |
1403 | usb_free_urb(sc->urb_int); | 2179 | usb_free_urb(sc->urb_int); |
1404 | sc->urb_int = NULL; | 2180 | sc->urb_int = NULL; |
1405 | kfree(intr); | 2181 | kfree(intr); |
2182 | err0: | ||
2183 | destroy_workqueue(sc->work_q); | ||
1406 | uea_leaves(INS_TO_USBDEV(sc)); | 2184 | uea_leaves(INS_TO_USBDEV(sc)); |
1407 | return -ENOMEM; | 2185 | return -ENOMEM; |
1408 | } | 2186 | } |
@@ -1417,15 +2195,15 @@ static void uea_stop(struct uea_softc *sc) | |||
1417 | ret = kthread_stop(sc->kthread); | 2195 | ret = kthread_stop(sc->kthread); |
1418 | uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); | 2196 | uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); |
1419 | 2197 | ||
1420 | /* stop any pending boot process */ | ||
1421 | flush_scheduled_work(); | ||
1422 | |||
1423 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); | 2198 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); |
1424 | 2199 | ||
1425 | usb_kill_urb(sc->urb_int); | 2200 | usb_kill_urb(sc->urb_int); |
1426 | kfree(sc->urb_int->transfer_buffer); | 2201 | kfree(sc->urb_int->transfer_buffer); |
1427 | usb_free_urb(sc->urb_int); | 2202 | usb_free_urb(sc->urb_int); |
1428 | 2203 | ||
2204 | /* stop any pending boot process, when no one can schedule work */ | ||
2205 | destroy_workqueue(sc->work_q); | ||
2206 | |||
1429 | if (sc->dsp_firm) | 2207 | if (sc->dsp_firm) |
1430 | release_firmware(sc->dsp_firm); | 2208 | release_firmware(sc->dsp_firm); |
1431 | uea_leaves(INS_TO_USBDEV(sc)); | 2209 | uea_leaves(INS_TO_USBDEV(sc)); |
@@ -1487,6 +2265,7 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1487 | char *buf) | 2265 | char *buf) |
1488 | { | 2266 | { |
1489 | int ret = -ENODEV; | 2267 | int ret = -ENODEV; |
2268 | int modem_state; | ||
1490 | struct uea_softc *sc; | 2269 | struct uea_softc *sc; |
1491 | 2270 | ||
1492 | mutex_lock(&uea_mutex); | 2271 | mutex_lock(&uea_mutex); |
@@ -1494,7 +2273,34 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1494 | if (!sc) | 2273 | if (!sc) |
1495 | goto out; | 2274 | goto out; |
1496 | 2275 | ||
1497 | switch (GET_STATUS(sc->stats.phy.state)) { | 2276 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
2277 | switch (sc->stats.phy.state) { | ||
2278 | case 0x0: /* not yet synchronized */ | ||
2279 | case 0x1: | ||
2280 | case 0x3: | ||
2281 | case 0x4: | ||
2282 | modem_state = 0; | ||
2283 | break; | ||
2284 | case 0x5: /* initialization */ | ||
2285 | case 0x6: | ||
2286 | case 0x9: | ||
2287 | case 0xa: | ||
2288 | modem_state = 1; | ||
2289 | break; | ||
2290 | case 0x7: /* operational */ | ||
2291 | modem_state = 2; | ||
2292 | break; | ||
2293 | case 0x2: /* fail ... */ | ||
2294 | modem_state = 3; | ||
2295 | break; | ||
2296 | default: /* unknown */ | ||
2297 | modem_state = 4; | ||
2298 | break; | ||
2299 | } | ||
2300 | } else | ||
2301 | modem_state = GET_STATUS(sc->stats.phy.state); | ||
2302 | |||
2303 | switch (modem_state) { | ||
1498 | case 0: | 2304 | case 0: |
1499 | ret = sprintf(buf, "Modem is booting\n"); | 2305 | ret = sprintf(buf, "Modem is booting\n"); |
1500 | break; | 2306 | break; |
@@ -1504,9 +2310,12 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1504 | case 2: | 2310 | case 2: |
1505 | ret = sprintf(buf, "Modem is operational\n"); | 2311 | ret = sprintf(buf, "Modem is operational\n"); |
1506 | break; | 2312 | break; |
1507 | default: | 2313 | case 3: |
1508 | ret = sprintf(buf, "Modem synchronization failed\n"); | 2314 | ret = sprintf(buf, "Modem synchronization failed\n"); |
1509 | break; | 2315 | break; |
2316 | default: | ||
2317 | ret = sprintf(buf, "Modem state is unknown\n"); | ||
2318 | break; | ||
1510 | } | 2319 | } |
1511 | out: | 2320 | out: |
1512 | mutex_unlock(&uea_mutex); | 2321 | mutex_unlock(&uea_mutex); |
@@ -1520,18 +2329,26 @@ static ssize_t read_delin(struct device *dev, struct device_attribute *attr, | |||
1520 | { | 2329 | { |
1521 | int ret = -ENODEV; | 2330 | int ret = -ENODEV; |
1522 | struct uea_softc *sc; | 2331 | struct uea_softc *sc; |
2332 | char *delin = "GOOD"; | ||
1523 | 2333 | ||
1524 | mutex_lock(&uea_mutex); | 2334 | mutex_lock(&uea_mutex); |
1525 | sc = dev_to_uea(dev); | 2335 | sc = dev_to_uea(dev); |
1526 | if (!sc) | 2336 | if (!sc) |
1527 | goto out; | 2337 | goto out; |
1528 | 2338 | ||
1529 | if (sc->stats.phy.flags & 0x0C00) | 2339 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
1530 | ret = sprintf(buf, "ERROR\n"); | 2340 | if (sc->stats.phy.flags & 0x4000) |
1531 | else if (sc->stats.phy.flags & 0x0030) | 2341 | delin = "RESET"; |
1532 | ret = sprintf(buf, "LOSS\n"); | 2342 | else if (sc->stats.phy.flags & 0x0001) |
1533 | else | 2343 | delin = "LOSS"; |
1534 | ret = sprintf(buf, "GOOD\n"); | 2344 | } else { |
2345 | if (sc->stats.phy.flags & 0x0C00) | ||
2346 | delin = "ERROR"; | ||
2347 | else if (sc->stats.phy.flags & 0x0030) | ||
2348 | delin = "LOSS"; | ||
2349 | } | ||
2350 | |||
2351 | ret = sprintf(buf, "%s\n", delin); | ||
1535 | out: | 2352 | out: |
1536 | mutex_unlock(&uea_mutex); | 2353 | mutex_unlock(&uea_mutex); |
1537 | return ret; | 2354 | return ret; |
@@ -1662,6 +2479,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1662 | struct usb_device *usb = interface_to_usbdev(intf); | 2479 | struct usb_device *usb = interface_to_usbdev(intf); |
1663 | struct uea_softc *sc; | 2480 | struct uea_softc *sc; |
1664 | int ret, ifnum = intf->altsetting->desc.bInterfaceNumber; | 2481 | int ret, ifnum = intf->altsetting->desc.bInterfaceNumber; |
2482 | unsigned int alt; | ||
1665 | 2483 | ||
1666 | uea_enters(usb); | 2484 | uea_enters(usb); |
1667 | 2485 | ||
@@ -1696,22 +2514,29 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1696 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; | 2514 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; |
1697 | sc->driver_info = id->driver_info; | 2515 | sc->driver_info = id->driver_info; |
1698 | 2516 | ||
1699 | /* ADI930 don't support iso */ | 2517 | /* first try to use module parameter */ |
1700 | if (UEA_CHIP_VERSION(id) != ADI930 && use_iso[sc->modem_index]) { | 2518 | if (annex[sc->modem_index] == 1) |
1701 | int i; | 2519 | sc->annex = ANNEXA; |
1702 | 2520 | else if (annex[sc->modem_index] == 2) | |
1703 | /* try set fastest alternate for inbound traffic interface */ | 2521 | sc->annex = ANNEXB; |
1704 | for (i = FASTEST_ISO_INTF; i > 0; i--) | 2522 | /* try to autodetect annex */ |
1705 | if (usb_set_interface(usb, UEA_DS_IFACE_NO, i) == 0) | 2523 | else if (sc->driver_info & AUTO_ANNEX_A) |
1706 | break; | 2524 | sc->annex = ANNEXA; |
2525 | else if (sc->driver_info & AUTO_ANNEX_B) | ||
2526 | sc->annex = ANNEXB; | ||
2527 | else | ||
2528 | sc->annex = (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)?ANNEXB:ANNEXA; | ||
1707 | 2529 | ||
1708 | if (i > 0) { | 2530 | alt = altsetting[sc->modem_index]; |
1709 | uea_dbg(usb, "set alternate %d for 2 interface\n", i); | 2531 | /* ADI930 don't support iso */ |
2532 | if (UEA_CHIP_VERSION(id) != ADI930 && alt > 0) { | ||
2533 | if (alt <= 8 && usb_set_interface(usb, UEA_DS_IFACE_NO, alt) == 0) { | ||
2534 | uea_dbg(usb, "set alternate %u for 2 interface\n", alt); | ||
1710 | uea_info(usb, "using iso mode\n"); | 2535 | uea_info(usb, "using iso mode\n"); |
1711 | usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ; | 2536 | usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ; |
1712 | } else { | 2537 | } else { |
1713 | uea_err(usb, "setting any alternate failed for " | 2538 | uea_err(usb, "setting alternate %u failed for " |
1714 | "2 interface, using bulk mode\n"); | 2539 | "2 interface, using bulk mode\n", alt); |
1715 | } | 2540 | } |
1716 | } | 2541 | } |
1717 | 2542 | ||
@@ -1757,10 +2582,11 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1757 | struct usb_device *usb = interface_to_usbdev(intf); | 2582 | struct usb_device *usb = interface_to_usbdev(intf); |
1758 | 2583 | ||
1759 | uea_enters(usb); | 2584 | uea_enters(usb); |
1760 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s %s\n", | 2585 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n", |
1761 | le16_to_cpu(usb->descriptor.idVendor), | 2586 | le16_to_cpu(usb->descriptor.idVendor), |
1762 | le16_to_cpu(usb->descriptor.idProduct), | 2587 | le16_to_cpu(usb->descriptor.idProduct), |
1763 | chip_name[UEA_CHIP_VERSION(id)], IS_ISDN(usb)?"isdn":"pots"); | 2588 | le16_to_cpu(usb->descriptor.bcdDevice), |
2589 | chip_name[UEA_CHIP_VERSION(id)]); | ||
1764 | 2590 | ||
1765 | usb_reset_device(usb); | 2591 | usb_reset_device(usb); |
1766 | 2592 | ||
@@ -1793,24 +2619,40 @@ static void uea_disconnect(struct usb_interface *intf) | |||
1793 | * List of supported VID/PID | 2619 | * List of supported VID/PID |
1794 | */ | 2620 | */ |
1795 | static const struct usb_device_id uea_ids[] = { | 2621 | static const struct usb_device_id uea_ids[] = { |
2622 | {USB_DEVICE(ANALOG_VID, ADI930_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, | ||
2623 | {USB_DEVICE(ANALOG_VID, ADI930_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, | ||
2624 | {USB_DEVICE(ANALOG_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
2625 | {USB_DEVICE(ANALOG_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
2626 | {USB_DEVICE(ANALOG_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2627 | {USB_DEVICE(ANALOG_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
2628 | {USB_DEVICE(ANALOG_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2629 | {USB_DEVICE(ANALOG_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
2630 | {USB_DEVICE(ANALOG_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM}, | ||
2631 | {USB_DEVICE(ANALOG_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM}, | ||
2632 | {USB_DEVICE(ANALOG_VID, EAGLE_IV_PID_PREFIRM), .driver_info = EAGLE_IV | PREFIRM}, | ||
2633 | {USB_DEVICE(ANALOG_VID, EAGLE_IV_PID_PSTFIRM), .driver_info = EAGLE_IV | PSTFIRM}, | ||
2634 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
2635 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A}, | ||
2636 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
2637 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B}, | ||
2638 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_A_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2639 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_A_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM | AUTO_ANNEX_A}, | ||
2640 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_B_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2641 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_B_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM | AUTO_ANNEX_B}, | ||
1796 | {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, | 2642 | {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, |
1797 | {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, | 2643 | {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, |
1798 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | 2644 | {USB_DEVICE(ELSA_VID, ELSA_PID_A_PREFIRM), .driver_info = ADI930 | PREFIRM}, |
1799 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | 2645 | {USB_DEVICE(ELSA_VID, ELSA_PID_A_PSTFIRM), .driver_info = ADI930 | PSTFIRM | AUTO_ANNEX_A}, |
1800 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | 2646 | {USB_DEVICE(ELSA_VID, ELSA_PID_B_PREFIRM), .driver_info = ADI930 | PREFIRM}, |
1801 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | 2647 | {USB_DEVICE(ELSA_VID, ELSA_PID_B_PSTFIRM), .driver_info = ADI930 | PSTFIRM | AUTO_ANNEX_B}, |
1802 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
1803 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
1804 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM}, | ||
1805 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM}, | ||
1806 | {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | 2648 | {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, |
1807 | {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | 2649 | {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A}, |
1808 | {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | 2650 | {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, |
1809 | {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | 2651 | {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B}, |
1810 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | 2652 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, |
1811 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | 2653 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A}, |
1812 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | 2654 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, |
1813 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | 2655 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B}, |
1814 | {} | 2656 | {} |
1815 | }; | 2657 | }; |
1816 | 2658 | ||
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 5192cd9356de..ad632f2d6f94 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -28,6 +28,7 @@ | |||
28 | * v0.12 - add hpoj.sourceforge.net ioctls (David Paschal) | 28 | * v0.12 - add hpoj.sourceforge.net ioctls (David Paschal) |
29 | * v0.13 - alloc space for statusbuf (<status> not on stack); | 29 | * v0.13 - alloc space for statusbuf (<status> not on stack); |
30 | * use usb_buffer_alloc() for read buf & write buf; | 30 | * use usb_buffer_alloc() for read buf & write buf; |
31 | * none - Maintained in Linux kernel after v0.13 | ||
31 | */ | 32 | */ |
32 | 33 | ||
33 | /* | 34 | /* |
@@ -69,7 +70,6 @@ | |||
69 | #define USBLP_DEVICE_ID_SIZE 1024 | 70 | #define USBLP_DEVICE_ID_SIZE 1024 |
70 | 71 | ||
71 | /* ioctls: */ | 72 | /* ioctls: */ |
72 | #define LPGETSTATUS 0x060b /* same as in drivers/char/lp.c */ | ||
73 | #define IOCNR_GET_DEVICE_ID 1 | 73 | #define IOCNR_GET_DEVICE_ID 1 |
74 | #define IOCNR_GET_PROTOCOLS 2 | 74 | #define IOCNR_GET_PROTOCOLS 2 |
75 | #define IOCNR_SET_PROTOCOL 3 | 75 | #define IOCNR_SET_PROTOCOL 3 |
@@ -115,7 +115,7 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H | |||
115 | #define USBLP_MINORS 16 | 115 | #define USBLP_MINORS 16 |
116 | #define USBLP_MINOR_BASE 0 | 116 | #define USBLP_MINOR_BASE 0 |
117 | 117 | ||
118 | #define USBLP_WRITE_TIMEOUT (5000) /* 5 seconds */ | 118 | #define USBLP_CTL_TIMEOUT 5000 /* 5 seconds */ |
119 | 119 | ||
120 | #define USBLP_FIRST_PROTOCOL 1 | 120 | #define USBLP_FIRST_PROTOCOL 1 |
121 | #define USBLP_LAST_PROTOCOL 3 | 121 | #define USBLP_LAST_PROTOCOL 3 |
@@ -159,10 +159,12 @@ struct usblp { | |||
159 | int wstatus; /* bytes written or error */ | 159 | int wstatus; /* bytes written or error */ |
160 | int rstatus; /* bytes ready or error */ | 160 | int rstatus; /* bytes ready or error */ |
161 | unsigned int quirks; /* quirks flags */ | 161 | unsigned int quirks; /* quirks flags */ |
162 | unsigned int flags; /* mode flags */ | ||
162 | unsigned char used; /* True if open */ | 163 | unsigned char used; /* True if open */ |
163 | unsigned char present; /* True if not disconnected */ | 164 | unsigned char present; /* True if not disconnected */ |
164 | unsigned char bidir; /* interface is bidirectional */ | 165 | unsigned char bidir; /* interface is bidirectional */ |
165 | unsigned char sleeping; /* interface is suspended */ | 166 | unsigned char sleeping; /* interface is suspended */ |
167 | unsigned char no_paper; /* Paper Out happened */ | ||
166 | unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ | 168 | unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ |
167 | /* first 2 bytes are (big-endian) length */ | 169 | /* first 2 bytes are (big-endian) length */ |
168 | }; | 170 | }; |
@@ -259,7 +261,7 @@ static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, i | |||
259 | 261 | ||
260 | retval = usb_control_msg(usblp->dev, | 262 | retval = usb_control_msg(usblp->dev, |
261 | dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0), | 263 | dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0), |
262 | request, type | dir | recip, value, index, buf, len, USBLP_WRITE_TIMEOUT); | 264 | request, type | dir | recip, value, index, buf, len, USBLP_CTL_TIMEOUT); |
263 | dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d", | 265 | dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d", |
264 | request, !!dir, recip, value, index, len, retval); | 266 | request, !!dir, recip, value, index, len, retval); |
265 | return retval < 0 ? retval : 0; | 267 | return retval < 0 ? retval : 0; |
@@ -325,13 +327,11 @@ static void usblp_bulk_write(struct urb *urb) | |||
325 | usblp->wstatus = status; | 327 | usblp->wstatus = status; |
326 | else | 328 | else |
327 | usblp->wstatus = urb->actual_length; | 329 | usblp->wstatus = urb->actual_length; |
330 | usblp->no_paper = 0; | ||
328 | usblp->wcomplete = 1; | 331 | usblp->wcomplete = 1; |
329 | wake_up(&usblp->wwait); | 332 | wake_up(&usblp->wwait); |
330 | spin_unlock(&usblp->lock); | 333 | spin_unlock(&usblp->lock); |
331 | 334 | ||
332 | /* XXX Use usb_setup_bulk_urb when available. Talk to Marcel. */ | ||
333 | kfree(urb->transfer_buffer); | ||
334 | urb->transfer_buffer = NULL; /* Not refcounted, so to be safe... */ | ||
335 | usb_free_urb(urb); | 335 | usb_free_urb(urb); |
336 | } | 336 | } |
337 | 337 | ||
@@ -346,16 +346,17 @@ static int usblp_check_status(struct usblp *usblp, int err) | |||
346 | unsigned char status, newerr = 0; | 346 | unsigned char status, newerr = 0; |
347 | int error; | 347 | int error; |
348 | 348 | ||
349 | error = usblp_read_status (usblp, usblp->statusbuf); | 349 | mutex_lock(&usblp->mut); |
350 | if (error < 0) { | 350 | if ((error = usblp_read_status(usblp, usblp->statusbuf)) < 0) { |
351 | mutex_unlock(&usblp->mut); | ||
351 | if (printk_ratelimit()) | 352 | if (printk_ratelimit()) |
352 | printk(KERN_ERR | 353 | printk(KERN_ERR |
353 | "usblp%d: error %d reading printer status\n", | 354 | "usblp%d: error %d reading printer status\n", |
354 | usblp->minor, error); | 355 | usblp->minor, error); |
355 | return 0; | 356 | return 0; |
356 | } | 357 | } |
357 | |||
358 | status = *usblp->statusbuf; | 358 | status = *usblp->statusbuf; |
359 | mutex_unlock(&usblp->mut); | ||
359 | 360 | ||
360 | if (~status & LP_PERRORP) | 361 | if (~status & LP_PERRORP) |
361 | newerr = 3; | 362 | newerr = 3; |
@@ -411,18 +412,10 @@ static int usblp_open(struct inode *inode, struct file *file) | |||
411 | goto out; | 412 | goto out; |
412 | 413 | ||
413 | /* | 414 | /* |
414 | * TODO: need to implement LP_ABORTOPEN + O_NONBLOCK as in drivers/char/lp.c ??? | 415 | * We do not implement LP_ABORTOPEN/LPABORTOPEN for two reasons: |
415 | * This is #if 0-ed because we *don't* want to fail an open | 416 | * - We do not want persistent state which close(2) does not clear |
416 | * just because the printer is off-line. | 417 | * - It is not used anyway, according to CUPS people |
417 | */ | 418 | */ |
418 | #if 0 | ||
419 | if ((retval = usblp_check_status(usblp, 0))) { | ||
420 | retval = retval > 1 ? -EIO : -ENOSPC; | ||
421 | goto out; | ||
422 | } | ||
423 | #else | ||
424 | retval = 0; | ||
425 | #endif | ||
426 | 419 | ||
427 | retval = usb_autopm_get_interface(intf); | 420 | retval = usb_autopm_get_interface(intf); |
428 | if (retval < 0) | 421 | if (retval < 0) |
@@ -463,6 +456,8 @@ static int usblp_release(struct inode *inode, struct file *file) | |||
463 | { | 456 | { |
464 | struct usblp *usblp = file->private_data; | 457 | struct usblp *usblp = file->private_data; |
465 | 458 | ||
459 | usblp->flags &= ~LP_ABORT; | ||
460 | |||
466 | mutex_lock (&usblp_mutex); | 461 | mutex_lock (&usblp_mutex); |
467 | usblp->used = 0; | 462 | usblp->used = 0; |
468 | if (usblp->present) { | 463 | if (usblp->present) { |
@@ -485,8 +480,8 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait | |||
485 | poll_wait(file, &usblp->rwait, wait); | 480 | poll_wait(file, &usblp->rwait, wait); |
486 | poll_wait(file, &usblp->wwait, wait); | 481 | poll_wait(file, &usblp->wwait, wait); |
487 | spin_lock_irqsave(&usblp->lock, flags); | 482 | spin_lock_irqsave(&usblp->lock, flags); |
488 | ret = ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN | POLLRDNORM) | 483 | ret = ((usblp->bidir && usblp->rcomplete) ? POLLIN | POLLRDNORM : 0) | |
489 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); | 484 | ((usblp->no_paper || usblp->wcomplete) ? POLLOUT | POLLWRNORM : 0); |
490 | spin_unlock_irqrestore(&usblp->lock, flags); | 485 | spin_unlock_irqrestore(&usblp->lock, flags); |
491 | return ret; | 486 | return ret; |
492 | } | 487 | } |
@@ -675,6 +670,13 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
675 | retval = -EFAULT; | 670 | retval = -EFAULT; |
676 | break; | 671 | break; |
677 | 672 | ||
673 | case LPABORT: | ||
674 | if (arg) | ||
675 | usblp->flags |= LP_ABORT; | ||
676 | else | ||
677 | usblp->flags &= ~LP_ABORT; | ||
678 | break; | ||
679 | |||
678 | default: | 680 | default: |
679 | retval = -ENOTTY; | 681 | retval = -ENOTTY; |
680 | } | 682 | } |
@@ -684,10 +686,30 @@ done: | |||
684 | return retval; | 686 | return retval; |
685 | } | 687 | } |
686 | 688 | ||
689 | static struct urb *usblp_new_writeurb(struct usblp *usblp, int transfer_length) | ||
690 | { | ||
691 | struct urb *urb; | ||
692 | char *writebuf; | ||
693 | |||
694 | if ((writebuf = kmalloc(transfer_length, GFP_KERNEL)) == NULL) | ||
695 | return NULL; | ||
696 | if ((urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) { | ||
697 | kfree(writebuf); | ||
698 | return NULL; | ||
699 | } | ||
700 | |||
701 | usb_fill_bulk_urb(urb, usblp->dev, | ||
702 | usb_sndbulkpipe(usblp->dev, | ||
703 | usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress), | ||
704 | writebuf, transfer_length, usblp_bulk_write, usblp); | ||
705 | urb->transfer_flags |= URB_FREE_BUFFER; | ||
706 | |||
707 | return urb; | ||
708 | } | ||
709 | |||
687 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 710 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
688 | { | 711 | { |
689 | struct usblp *usblp = file->private_data; | 712 | struct usblp *usblp = file->private_data; |
690 | char *writebuf; | ||
691 | struct urb *writeurb; | 713 | struct urb *writeurb; |
692 | int rv; | 714 | int rv; |
693 | int transfer_length; | 715 | int transfer_length; |
@@ -708,17 +730,11 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
708 | transfer_length = USBLP_BUF_SIZE; | 730 | transfer_length = USBLP_BUF_SIZE; |
709 | 731 | ||
710 | rv = -ENOMEM; | 732 | rv = -ENOMEM; |
711 | if ((writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL)) == NULL) | 733 | if ((writeurb = usblp_new_writeurb(usblp, transfer_length)) == NULL) |
712 | goto raise_buf; | ||
713 | if ((writeurb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) | ||
714 | goto raise_urb; | 734 | goto raise_urb; |
715 | usb_fill_bulk_urb(writeurb, usblp->dev, | ||
716 | usb_sndbulkpipe(usblp->dev, | ||
717 | usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress), | ||
718 | writebuf, transfer_length, usblp_bulk_write, usblp); | ||
719 | usb_anchor_urb(writeurb, &usblp->urbs); | 735 | usb_anchor_urb(writeurb, &usblp->urbs); |
720 | 736 | ||
721 | if (copy_from_user(writebuf, | 737 | if (copy_from_user(writeurb->transfer_buffer, |
722 | buffer + writecount, transfer_length)) { | 738 | buffer + writecount, transfer_length)) { |
723 | rv = -EFAULT; | 739 | rv = -EFAULT; |
724 | goto raise_badaddr; | 740 | goto raise_badaddr; |
@@ -730,6 +746,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
730 | if ((rv = usb_submit_urb(writeurb, GFP_KERNEL)) < 0) { | 746 | if ((rv = usb_submit_urb(writeurb, GFP_KERNEL)) < 0) { |
731 | usblp->wstatus = 0; | 747 | usblp->wstatus = 0; |
732 | spin_lock_irq(&usblp->lock); | 748 | spin_lock_irq(&usblp->lock); |
749 | usblp->no_paper = 0; | ||
733 | usblp->wcomplete = 1; | 750 | usblp->wcomplete = 1; |
734 | wake_up(&usblp->wwait); | 751 | wake_up(&usblp->wwait); |
735 | spin_unlock_irq(&usblp->lock); | 752 | spin_unlock_irq(&usblp->lock); |
@@ -747,12 +764,17 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
747 | /* Presume that it's going to complete well. */ | 764 | /* Presume that it's going to complete well. */ |
748 | writecount += transfer_length; | 765 | writecount += transfer_length; |
749 | } | 766 | } |
767 | if (rv == -ENOSPC) { | ||
768 | spin_lock_irq(&usblp->lock); | ||
769 | usblp->no_paper = 1; /* Mark for poll(2) */ | ||
770 | spin_unlock_irq(&usblp->lock); | ||
771 | writecount += transfer_length; | ||
772 | } | ||
750 | /* Leave URB dangling, to be cleaned on close. */ | 773 | /* Leave URB dangling, to be cleaned on close. */ |
751 | goto collect_error; | 774 | goto collect_error; |
752 | } | 775 | } |
753 | 776 | ||
754 | if (usblp->wstatus < 0) { | 777 | if (usblp->wstatus < 0) { |
755 | usblp_check_status(usblp, 0); | ||
756 | rv = -EIO; | 778 | rv = -EIO; |
757 | goto collect_error; | 779 | goto collect_error; |
758 | } | 780 | } |
@@ -771,8 +793,6 @@ raise_badaddr: | |||
771 | usb_unanchor_urb(writeurb); | 793 | usb_unanchor_urb(writeurb); |
772 | usb_free_urb(writeurb); | 794 | usb_free_urb(writeurb); |
773 | raise_urb: | 795 | raise_urb: |
774 | kfree(writebuf); | ||
775 | raise_buf: | ||
776 | raise_wait: | 796 | raise_wait: |
777 | collect_error: /* Out of raise sequence */ | 797 | collect_error: /* Out of raise sequence */ |
778 | mutex_unlock(&usblp->wmut); | 798 | mutex_unlock(&usblp->wmut); |
@@ -838,32 +858,36 @@ done: | |||
838 | * when O_NONBLOCK is set. So, applications setting O_NONBLOCK must use | 858 | * when O_NONBLOCK is set. So, applications setting O_NONBLOCK must use |
839 | * select(2) or poll(2) to wait for the buffer to drain before closing. | 859 | * select(2) or poll(2) to wait for the buffer to drain before closing. |
840 | * Alternatively, set blocking mode with fcntl and issue a zero-size write. | 860 | * Alternatively, set blocking mode with fcntl and issue a zero-size write. |
841 | * | ||
842 | * Old v0.13 code had a non-functional timeout for wait_event(). Someone forgot | ||
843 | * to check the return code for timeout expiration, so it had no effect. | ||
844 | * Apparently, it was intended to check for error conditons, such as out | ||
845 | * of paper. It is going to return when we settle things with CUPS. XXX | ||
846 | */ | 861 | */ |
847 | static int usblp_wwait(struct usblp *usblp, int nonblock) | 862 | static int usblp_wwait(struct usblp *usblp, int nonblock) |
848 | { | 863 | { |
849 | DECLARE_WAITQUEUE(waita, current); | 864 | DECLARE_WAITQUEUE(waita, current); |
850 | int rc; | 865 | int rc; |
866 | int err = 0; | ||
851 | 867 | ||
852 | add_wait_queue(&usblp->wwait, &waita); | 868 | add_wait_queue(&usblp->wwait, &waita); |
853 | for (;;) { | 869 | for (;;) { |
870 | set_current_state(TASK_INTERRUPTIBLE); | ||
854 | if (mutex_lock_interruptible(&usblp->mut)) { | 871 | if (mutex_lock_interruptible(&usblp->mut)) { |
855 | rc = -EINTR; | 872 | rc = -EINTR; |
856 | break; | 873 | break; |
857 | } | 874 | } |
858 | set_current_state(TASK_INTERRUPTIBLE); | 875 | rc = usblp_wtest(usblp, nonblock); |
859 | if ((rc = usblp_wtest(usblp, nonblock)) < 0) { | ||
860 | mutex_unlock(&usblp->mut); | ||
861 | break; | ||
862 | } | ||
863 | mutex_unlock(&usblp->mut); | 876 | mutex_unlock(&usblp->mut); |
864 | if (rc == 0) | 877 | if (rc <= 0) |
865 | break; | 878 | break; |
866 | schedule(); | 879 | |
880 | if (usblp->flags & LP_ABORT) { | ||
881 | if (schedule_timeout(msecs_to_jiffies(5000)) == 0) { | ||
882 | err = usblp_check_status(usblp, err); | ||
883 | if (err == 1) { /* Paper out */ | ||
884 | rc = -ENOSPC; | ||
885 | break; | ||
886 | } | ||
887 | } | ||
888 | } else { | ||
889 | schedule(); | ||
890 | } | ||
867 | } | 891 | } |
868 | set_current_state(TASK_RUNNING); | 892 | set_current_state(TASK_RUNNING); |
869 | remove_wait_queue(&usblp->wwait, &waita); | 893 | remove_wait_queue(&usblp->wwait, &waita); |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index cb69aa1e02e8..1a8edcee7f30 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -507,18 +507,30 @@ void usb_destroy_configuration(struct usb_device *dev) | |||
507 | } | 507 | } |
508 | 508 | ||
509 | 509 | ||
510 | // hub-only!! ... and only in reset path, or usb_new_device() | 510 | /* |
511 | // (used by real hubs and virtual root hubs) | 511 | * Get the USB config descriptors, cache and parse'em |
512 | * | ||
513 | * hub-only!! ... and only in reset path, or usb_new_device() | ||
514 | * (used by real hubs and virtual root hubs) | ||
515 | * | ||
516 | * NOTE: if this is a WUSB device and is not authorized, we skip the | ||
517 | * whole thing. A non-authorized USB device has no | ||
518 | * configurations. | ||
519 | */ | ||
512 | int usb_get_configuration(struct usb_device *dev) | 520 | int usb_get_configuration(struct usb_device *dev) |
513 | { | 521 | { |
514 | struct device *ddev = &dev->dev; | 522 | struct device *ddev = &dev->dev; |
515 | int ncfg = dev->descriptor.bNumConfigurations; | 523 | int ncfg = dev->descriptor.bNumConfigurations; |
516 | int result = -ENOMEM; | 524 | int result = 0; |
517 | unsigned int cfgno, length; | 525 | unsigned int cfgno, length; |
518 | unsigned char *buffer; | 526 | unsigned char *buffer; |
519 | unsigned char *bigbuffer; | 527 | unsigned char *bigbuffer; |
520 | struct usb_config_descriptor *desc; | 528 | struct usb_config_descriptor *desc; |
521 | 529 | ||
530 | cfgno = 0; | ||
531 | if (dev->authorized == 0) /* Not really an error */ | ||
532 | goto out_not_authorized; | ||
533 | result = -ENOMEM; | ||
522 | if (ncfg > USB_MAXCONFIG) { | 534 | if (ncfg > USB_MAXCONFIG) { |
523 | dev_warn(ddev, "too many configurations: %d, " | 535 | dev_warn(ddev, "too many configurations: %d, " |
524 | "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); | 536 | "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); |
@@ -545,14 +557,15 @@ int usb_get_configuration(struct usb_device *dev) | |||
545 | goto err2; | 557 | goto err2; |
546 | desc = (struct usb_config_descriptor *)buffer; | 558 | desc = (struct usb_config_descriptor *)buffer; |
547 | 559 | ||
548 | for (cfgno = 0; cfgno < ncfg; cfgno++) { | 560 | result = 0; |
561 | for (; cfgno < ncfg; cfgno++) { | ||
549 | /* We grab just the first descriptor so we know how long | 562 | /* We grab just the first descriptor so we know how long |
550 | * the whole configuration is */ | 563 | * the whole configuration is */ |
551 | result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, | 564 | result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, |
552 | buffer, USB_DT_CONFIG_SIZE); | 565 | buffer, USB_DT_CONFIG_SIZE); |
553 | if (result < 0) { | 566 | if (result < 0) { |
554 | dev_err(ddev, "unable to read config index %d " | 567 | dev_err(ddev, "unable to read config index %d " |
555 | "descriptor/%s\n", cfgno, "start"); | 568 | "descriptor/%s: %d\n", cfgno, "start", result); |
556 | dev_err(ddev, "chopping to %d config(s)\n", cfgno); | 569 | dev_err(ddev, "chopping to %d config(s)\n", cfgno); |
557 | dev->descriptor.bNumConfigurations = cfgno; | 570 | dev->descriptor.bNumConfigurations = cfgno; |
558 | break; | 571 | break; |
@@ -599,6 +612,7 @@ int usb_get_configuration(struct usb_device *dev) | |||
599 | 612 | ||
600 | err: | 613 | err: |
601 | kfree(buffer); | 614 | kfree(buffer); |
615 | out_not_authorized: | ||
602 | dev->descriptor.bNumConfigurations = cfgno; | 616 | dev->descriptor.bNumConfigurations = cfgno; |
603 | err2: | 617 | err2: |
604 | if (result == -ENOMEM) | 618 | if (result == -ENOMEM) |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 927a181120a9..f013b4012c9a 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -71,6 +71,7 @@ struct async { | |||
71 | void __user *userbuffer; | 71 | void __user *userbuffer; |
72 | void __user *userurb; | 72 | void __user *userurb; |
73 | struct urb *urb; | 73 | struct urb *urb; |
74 | int status; | ||
74 | u32 secid; | 75 | u32 secid; |
75 | }; | 76 | }; |
76 | 77 | ||
@@ -289,10 +290,8 @@ static void snoop_urb(struct urb *urb, void __user *userurb) | |||
289 | if (!usbfs_snoop) | 290 | if (!usbfs_snoop) |
290 | return; | 291 | return; |
291 | 292 | ||
292 | if (urb->pipe & USB_DIR_IN) | 293 | dev_info(&urb->dev->dev, "direction=%s\n", |
293 | dev_info(&urb->dev->dev, "direction=IN\n"); | 294 | usb_urb_dir_in(urb) ? "IN" : "OUT"); |
294 | else | ||
295 | dev_info(&urb->dev->dev, "direction=OUT\n"); | ||
296 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); | 295 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); |
297 | dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", | 296 | dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", |
298 | urb->transfer_buffer_length); | 297 | urb->transfer_buffer_length); |
@@ -312,9 +311,10 @@ static void async_completed(struct urb *urb) | |||
312 | spin_lock(&ps->lock); | 311 | spin_lock(&ps->lock); |
313 | list_move_tail(&as->asynclist, &ps->async_completed); | 312 | list_move_tail(&as->asynclist, &ps->async_completed); |
314 | spin_unlock(&ps->lock); | 313 | spin_unlock(&ps->lock); |
314 | as->status = urb->status; | ||
315 | if (as->signr) { | 315 | if (as->signr) { |
316 | sinfo.si_signo = as->signr; | 316 | sinfo.si_signo = as->signr; |
317 | sinfo.si_errno = as->urb->status; | 317 | sinfo.si_errno = as->status; |
318 | sinfo.si_code = SI_ASYNCIO; | 318 | sinfo.si_code = SI_ASYNCIO; |
319 | sinfo.si_addr = as->userurb; | 319 | sinfo.si_addr = as->userurb; |
320 | kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid, | 320 | kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid, |
@@ -910,6 +910,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
910 | struct usb_ctrlrequest *dr = NULL; | 910 | struct usb_ctrlrequest *dr = NULL; |
911 | unsigned int u, totlen, isofrmlen; | 911 | unsigned int u, totlen, isofrmlen; |
912 | int ret, ifnum = -1; | 912 | int ret, ifnum = -1; |
913 | int is_in; | ||
913 | 914 | ||
914 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK| | 915 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK| |
915 | URB_NO_FSBR|URB_ZERO_PACKET)) | 916 | URB_NO_FSBR|URB_ZERO_PACKET)) |
@@ -924,16 +925,18 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
924 | if ((ret = checkintf(ps, ifnum))) | 925 | if ((ret = checkintf(ps, ifnum))) |
925 | return ret; | 926 | return ret; |
926 | } | 927 | } |
927 | if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) | 928 | if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) { |
928 | ep = ps->dev->ep_in [uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; | 929 | is_in = 1; |
929 | else | 930 | ep = ps->dev->ep_in[uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; |
930 | ep = ps->dev->ep_out [uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; | 931 | } else { |
932 | is_in = 0; | ||
933 | ep = ps->dev->ep_out[uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; | ||
934 | } | ||
931 | if (!ep) | 935 | if (!ep) |
932 | return -ENOENT; | 936 | return -ENOENT; |
933 | switch(uurb->type) { | 937 | switch(uurb->type) { |
934 | case USBDEVFS_URB_TYPE_CONTROL: | 938 | case USBDEVFS_URB_TYPE_CONTROL: |
935 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 939 | if (!usb_endpoint_xfer_control(&ep->desc)) |
936 | != USB_ENDPOINT_XFER_CONTROL) | ||
937 | return -EINVAL; | 940 | return -EINVAL; |
938 | /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */ | 941 | /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */ |
939 | if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) | 942 | if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) |
@@ -952,23 +955,32 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
952 | kfree(dr); | 955 | kfree(dr); |
953 | return ret; | 956 | return ret; |
954 | } | 957 | } |
955 | uurb->endpoint = (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) | (dr->bRequestType & USB_ENDPOINT_DIR_MASK); | ||
956 | uurb->number_of_packets = 0; | 958 | uurb->number_of_packets = 0; |
957 | uurb->buffer_length = le16_to_cpup(&dr->wLength); | 959 | uurb->buffer_length = le16_to_cpup(&dr->wLength); |
958 | uurb->buffer += 8; | 960 | uurb->buffer += 8; |
959 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) { | 961 | if ((dr->bRequestType & USB_DIR_IN) && uurb->buffer_length) { |
962 | is_in = 1; | ||
963 | uurb->endpoint |= USB_DIR_IN; | ||
964 | } else { | ||
965 | is_in = 0; | ||
966 | uurb->endpoint &= ~USB_DIR_IN; | ||
967 | } | ||
968 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
969 | uurb->buffer, uurb->buffer_length)) { | ||
960 | kfree(dr); | 970 | kfree(dr); |
961 | return -EFAULT; | 971 | return -EFAULT; |
962 | } | 972 | } |
963 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " | 973 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " |
964 | "bRrequestType=%02x wValue=%04x " | 974 | "bRrequestType=%02x wValue=%04x " |
965 | "wIndex=%04x wLength=%04x\n", | 975 | "wIndex=%04x wLength=%04x\n", |
966 | dr->bRequest, dr->bRequestType, dr->wValue, | 976 | dr->bRequest, dr->bRequestType, |
967 | dr->wIndex, dr->wLength); | 977 | __le16_to_cpup(&dr->wValue), |
978 | __le16_to_cpup(&dr->wIndex), | ||
979 | __le16_to_cpup(&dr->wLength)); | ||
968 | break; | 980 | break; |
969 | 981 | ||
970 | case USBDEVFS_URB_TYPE_BULK: | 982 | case USBDEVFS_URB_TYPE_BULK: |
971 | switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 983 | switch (usb_endpoint_type(&ep->desc)) { |
972 | case USB_ENDPOINT_XFER_CONTROL: | 984 | case USB_ENDPOINT_XFER_CONTROL: |
973 | case USB_ENDPOINT_XFER_ISOC: | 985 | case USB_ENDPOINT_XFER_ISOC: |
974 | return -EINVAL; | 986 | return -EINVAL; |
@@ -977,7 +989,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
977 | uurb->number_of_packets = 0; | 989 | uurb->number_of_packets = 0; |
978 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 990 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
979 | return -EINVAL; | 991 | return -EINVAL; |
980 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) | 992 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, |
993 | uurb->buffer, uurb->buffer_length)) | ||
981 | return -EFAULT; | 994 | return -EFAULT; |
982 | snoop(&ps->dev->dev, "bulk urb\n"); | 995 | snoop(&ps->dev->dev, "bulk urb\n"); |
983 | break; | 996 | break; |
@@ -986,8 +999,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
986 | /* arbitrary limit */ | 999 | /* arbitrary limit */ |
987 | if (uurb->number_of_packets < 1 || uurb->number_of_packets > 128) | 1000 | if (uurb->number_of_packets < 1 || uurb->number_of_packets > 128) |
988 | return -EINVAL; | 1001 | return -EINVAL; |
989 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1002 | if (!usb_endpoint_xfer_isoc(&ep->desc)) |
990 | != USB_ENDPOINT_XFER_ISOC) | ||
991 | return -EINVAL; | 1003 | return -EINVAL; |
992 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets; | 1004 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets; |
993 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) | 1005 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) |
@@ -1014,12 +1026,12 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1014 | 1026 | ||
1015 | case USBDEVFS_URB_TYPE_INTERRUPT: | 1027 | case USBDEVFS_URB_TYPE_INTERRUPT: |
1016 | uurb->number_of_packets = 0; | 1028 | uurb->number_of_packets = 0; |
1017 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1029 | if (!usb_endpoint_xfer_int(&ep->desc)) |
1018 | != USB_ENDPOINT_XFER_INT) | ||
1019 | return -EINVAL; | 1030 | return -EINVAL; |
1020 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1031 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1021 | return -EINVAL; | 1032 | return -EINVAL; |
1022 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) | 1033 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, |
1034 | uurb->buffer, uurb->buffer_length)) | ||
1023 | return -EFAULT; | 1035 | return -EFAULT; |
1024 | snoop(&ps->dev->dev, "interrupt urb\n"); | 1036 | snoop(&ps->dev->dev, "interrupt urb\n"); |
1025 | break; | 1037 | break; |
@@ -1039,8 +1051,11 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1039 | return -ENOMEM; | 1051 | return -ENOMEM; |
1040 | } | 1052 | } |
1041 | as->urb->dev = ps->dev; | 1053 | as->urb->dev = ps->dev; |
1042 | as->urb->pipe = (uurb->type << 30) | __create_pipe(ps->dev, uurb->endpoint & 0xf) | (uurb->endpoint & USB_DIR_IN); | 1054 | as->urb->pipe = (uurb->type << 30) | |
1043 | as->urb->transfer_flags = uurb->flags; | 1055 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | |
1056 | (uurb->endpoint & USB_DIR_IN); | ||
1057 | as->urb->transfer_flags = uurb->flags | | ||
1058 | (is_in ? URB_DIR_IN : URB_DIR_OUT); | ||
1044 | as->urb->transfer_buffer_length = uurb->buffer_length; | 1059 | as->urb->transfer_buffer_length = uurb->buffer_length; |
1045 | as->urb->setup_packet = (unsigned char*)dr; | 1060 | as->urb->setup_packet = (unsigned char*)dr; |
1046 | as->urb->start_frame = uurb->start_frame; | 1061 | as->urb->start_frame = uurb->start_frame; |
@@ -1070,13 +1085,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1070 | as->uid = current->uid; | 1085 | as->uid = current->uid; |
1071 | as->euid = current->euid; | 1086 | as->euid = current->euid; |
1072 | security_task_getsecid(current, &as->secid); | 1087 | security_task_getsecid(current, &as->secid); |
1073 | if (!(uurb->endpoint & USB_DIR_IN)) { | 1088 | if (!is_in) { |
1074 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) { | 1089 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, |
1090 | as->urb->transfer_buffer_length)) { | ||
1075 | free_async(as); | 1091 | free_async(as); |
1076 | return -EFAULT; | 1092 | return -EFAULT; |
1077 | } | 1093 | } |
1078 | } | 1094 | } |
1079 | snoop(&as->urb->dev->dev, "submit urb\n"); | ||
1080 | snoop_urb(as->urb, as->userurb); | 1095 | snoop_urb(as->urb, as->userurb); |
1081 | async_newpending(as); | 1096 | async_newpending(as); |
1082 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { | 1097 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { |
@@ -1119,14 +1134,14 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1119 | if (as->userbuffer) | 1134 | if (as->userbuffer) |
1120 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) | 1135 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) |
1121 | return -EFAULT; | 1136 | return -EFAULT; |
1122 | if (put_user(urb->status, &userurb->status)) | 1137 | if (put_user(as->status, &userurb->status)) |
1123 | return -EFAULT; | 1138 | return -EFAULT; |
1124 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1139 | if (put_user(urb->actual_length, &userurb->actual_length)) |
1125 | return -EFAULT; | 1140 | return -EFAULT; |
1126 | if (put_user(urb->error_count, &userurb->error_count)) | 1141 | if (put_user(urb->error_count, &userurb->error_count)) |
1127 | return -EFAULT; | 1142 | return -EFAULT; |
1128 | 1143 | ||
1129 | if (usb_pipeisoc(urb->pipe)) { | 1144 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { |
1130 | for (i = 0; i < urb->number_of_packets; i++) { | 1145 | for (i = 0; i < urb->number_of_packets; i++) { |
1131 | if (put_user(urb->iso_frame_desc[i].actual_length, | 1146 | if (put_user(urb->iso_frame_desc[i].actual_length, |
1132 | &userurb->iso_frame_desc[i].actual_length)) | 1147 | &userurb->iso_frame_desc[i].actual_length)) |
@@ -1233,14 +1248,14 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
1233 | if (as->userbuffer) | 1248 | if (as->userbuffer) |
1234 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) | 1249 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) |
1235 | return -EFAULT; | 1250 | return -EFAULT; |
1236 | if (put_user(urb->status, &userurb->status)) | 1251 | if (put_user(as->status, &userurb->status)) |
1237 | return -EFAULT; | 1252 | return -EFAULT; |
1238 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1253 | if (put_user(urb->actual_length, &userurb->actual_length)) |
1239 | return -EFAULT; | 1254 | return -EFAULT; |
1240 | if (put_user(urb->error_count, &userurb->error_count)) | 1255 | if (put_user(urb->error_count, &userurb->error_count)) |
1241 | return -EFAULT; | 1256 | return -EFAULT; |
1242 | 1257 | ||
1243 | if (usb_pipeisoc(urb->pipe)) { | 1258 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { |
1244 | for (i = 0; i < urb->number_of_packets; i++) { | 1259 | for (i = 0; i < urb->number_of_packets; i++) { |
1245 | if (put_user(urb->iso_frame_desc[i].actual_length, | 1260 | if (put_user(urb->iso_frame_desc[i].actual_length, |
1246 | &userurb->iso_frame_desc[i].actual_length)) | 1261 | &userurb->iso_frame_desc[i].actual_length)) |
@@ -1576,6 +1591,7 @@ static unsigned int usbdev_poll(struct file *file, struct poll_table_struct *wai | |||
1576 | } | 1591 | } |
1577 | 1592 | ||
1578 | const struct file_operations usbdev_file_operations = { | 1593 | const struct file_operations usbdev_file_operations = { |
1594 | .owner = THIS_MODULE, | ||
1579 | .llseek = usbdev_lseek, | 1595 | .llseek = usbdev_lseek, |
1580 | .read = usbdev_read, | 1596 | .read = usbdev_read, |
1581 | .poll = usbdev_poll, | 1597 | .poll = usbdev_poll, |
@@ -1625,10 +1641,7 @@ static struct notifier_block usbdev_nb = { | |||
1625 | }; | 1641 | }; |
1626 | #endif | 1642 | #endif |
1627 | 1643 | ||
1628 | static struct cdev usb_device_cdev = { | 1644 | static struct cdev usb_device_cdev; |
1629 | .kobj = {.name = "usb_device", }, | ||
1630 | .owner = THIS_MODULE, | ||
1631 | }; | ||
1632 | 1645 | ||
1633 | int __init usb_devio_init(void) | 1646 | int __init usb_devio_init(void) |
1634 | { | 1647 | { |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 63b1243a9139..8586817698ad 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -202,6 +202,11 @@ static int usb_probe_interface(struct device *dev) | |||
202 | intf = to_usb_interface(dev); | 202 | intf = to_usb_interface(dev); |
203 | udev = interface_to_usbdev(intf); | 203 | udev = interface_to_usbdev(intf); |
204 | 204 | ||
205 | if (udev->authorized == 0) { | ||
206 | dev_err(&intf->dev, "Device is not authorized for usage\n"); | ||
207 | return -ENODEV; | ||
208 | } | ||
209 | |||
205 | id = usb_match_id(intf, driver->id_table); | 210 | id = usb_match_id(intf, driver->id_table); |
206 | if (!id) | 211 | if (!id) |
207 | id = usb_match_dynamic_id(intf, driver); | 212 | id = usb_match_dynamic_id(intf, driver); |
@@ -576,12 +581,9 @@ static int usb_device_match(struct device *dev, struct device_driver *drv) | |||
576 | } | 581 | } |
577 | 582 | ||
578 | #ifdef CONFIG_HOTPLUG | 583 | #ifdef CONFIG_HOTPLUG |
579 | static int usb_uevent(struct device *dev, char **envp, int num_envp, | 584 | static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) |
580 | char *buffer, int buffer_size) | ||
581 | { | 585 | { |
582 | struct usb_device *usb_dev; | 586 | struct usb_device *usb_dev; |
583 | int i = 0; | ||
584 | int length = 0; | ||
585 | 587 | ||
586 | if (!dev) | 588 | if (!dev) |
587 | return -ENODEV; | 589 | return -ENODEV; |
@@ -610,51 +612,39 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp, | |||
610 | * all the device descriptors we don't tell them about. Or | 612 | * all the device descriptors we don't tell them about. Or |
611 | * act as usermode drivers. | 613 | * act as usermode drivers. |
612 | */ | 614 | */ |
613 | if (add_uevent_var(envp, num_envp, &i, | 615 | if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d", |
614 | buffer, buffer_size, &length, | ||
615 | "DEVICE=/proc/bus/usb/%03d/%03d", | ||
616 | usb_dev->bus->busnum, usb_dev->devnum)) | 616 | usb_dev->bus->busnum, usb_dev->devnum)) |
617 | return -ENOMEM; | 617 | return -ENOMEM; |
618 | #endif | 618 | #endif |
619 | 619 | ||
620 | /* per-device configurations are common */ | 620 | /* per-device configurations are common */ |
621 | if (add_uevent_var(envp, num_envp, &i, | 621 | if (add_uevent_var(env, "PRODUCT=%x/%x/%x", |
622 | buffer, buffer_size, &length, | ||
623 | "PRODUCT=%x/%x/%x", | ||
624 | le16_to_cpu(usb_dev->descriptor.idVendor), | 622 | le16_to_cpu(usb_dev->descriptor.idVendor), |
625 | le16_to_cpu(usb_dev->descriptor.idProduct), | 623 | le16_to_cpu(usb_dev->descriptor.idProduct), |
626 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) | 624 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) |
627 | return -ENOMEM; | 625 | return -ENOMEM; |
628 | 626 | ||
629 | /* class-based driver binding models */ | 627 | /* class-based driver binding models */ |
630 | if (add_uevent_var(envp, num_envp, &i, | 628 | if (add_uevent_var(env, "TYPE=%d/%d/%d", |
631 | buffer, buffer_size, &length, | ||
632 | "TYPE=%d/%d/%d", | ||
633 | usb_dev->descriptor.bDeviceClass, | 629 | usb_dev->descriptor.bDeviceClass, |
634 | usb_dev->descriptor.bDeviceSubClass, | 630 | usb_dev->descriptor.bDeviceSubClass, |
635 | usb_dev->descriptor.bDeviceProtocol)) | 631 | usb_dev->descriptor.bDeviceProtocol)) |
636 | return -ENOMEM; | 632 | return -ENOMEM; |
637 | 633 | ||
638 | if (add_uevent_var(envp, num_envp, &i, | 634 | if (add_uevent_var(env, "BUSNUM=%03d", |
639 | buffer, buffer_size, &length, | ||
640 | "BUSNUM=%03d", | ||
641 | usb_dev->bus->busnum)) | 635 | usb_dev->bus->busnum)) |
642 | return -ENOMEM; | 636 | return -ENOMEM; |
643 | 637 | ||
644 | if (add_uevent_var(envp, num_envp, &i, | 638 | if (add_uevent_var(env, "DEVNUM=%03d", |
645 | buffer, buffer_size, &length, | ||
646 | "DEVNUM=%03d", | ||
647 | usb_dev->devnum)) | 639 | usb_dev->devnum)) |
648 | return -ENOMEM; | 640 | return -ENOMEM; |
649 | 641 | ||
650 | envp[i] = NULL; | ||
651 | return 0; | 642 | return 0; |
652 | } | 643 | } |
653 | 644 | ||
654 | #else | 645 | #else |
655 | 646 | ||
656 | static int usb_uevent(struct device *dev, char **envp, | 647 | static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) |
657 | int num_envp, char *buffer, int buffer_size) | ||
658 | { | 648 | { |
659 | return -ENODEV; | 649 | return -ENODEV; |
660 | } | 650 | } |
@@ -945,11 +935,11 @@ done: | |||
945 | #ifdef CONFIG_USB_SUSPEND | 935 | #ifdef CONFIG_USB_SUSPEND |
946 | 936 | ||
947 | /* Internal routine to check whether we may autosuspend a device. */ | 937 | /* Internal routine to check whether we may autosuspend a device. */ |
948 | static int autosuspend_check(struct usb_device *udev) | 938 | static int autosuspend_check(struct usb_device *udev, int reschedule) |
949 | { | 939 | { |
950 | int i; | 940 | int i; |
951 | struct usb_interface *intf; | 941 | struct usb_interface *intf; |
952 | unsigned long suspend_time; | 942 | unsigned long suspend_time, j; |
953 | 943 | ||
954 | /* For autosuspend, fail fast if anything is in use or autosuspend | 944 | /* For autosuspend, fail fast if anything is in use or autosuspend |
955 | * is disabled. Also fail if any interfaces require remote wakeup | 945 | * is disabled. Also fail if any interfaces require remote wakeup |
@@ -991,20 +981,20 @@ static int autosuspend_check(struct usb_device *udev) | |||
991 | } | 981 | } |
992 | 982 | ||
993 | /* If everything is okay but the device hasn't been idle for long | 983 | /* If everything is okay but the device hasn't been idle for long |
994 | * enough, queue a delayed autosuspend request. | 984 | * enough, queue a delayed autosuspend request. If the device |
985 | * _has_ been idle for long enough and the reschedule flag is set, | ||
986 | * likewise queue a delayed (1 second) autosuspend request. | ||
995 | */ | 987 | */ |
996 | if (time_after(suspend_time, jiffies)) { | 988 | j = jiffies; |
989 | if (time_before(j, suspend_time)) | ||
990 | reschedule = 1; | ||
991 | else | ||
992 | suspend_time = j + HZ; | ||
993 | if (reschedule) { | ||
997 | if (!timer_pending(&udev->autosuspend.timer)) { | 994 | if (!timer_pending(&udev->autosuspend.timer)) { |
998 | |||
999 | /* The value of jiffies may change between the | ||
1000 | * time_after() comparison above and the subtraction | ||
1001 | * below. That's okay; the system behaves sanely | ||
1002 | * when a timer is registered for the present moment | ||
1003 | * or for the past. | ||
1004 | */ | ||
1005 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, | 995 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, |
1006 | round_jiffies_relative(suspend_time - jiffies)); | 996 | round_jiffies_relative(suspend_time - j)); |
1007 | } | 997 | } |
1008 | return -EAGAIN; | 998 | return -EAGAIN; |
1009 | } | 999 | } |
1010 | return 0; | 1000 | return 0; |
@@ -1012,7 +1002,7 @@ static int autosuspend_check(struct usb_device *udev) | |||
1012 | 1002 | ||
1013 | #else | 1003 | #else |
1014 | 1004 | ||
1015 | static inline int autosuspend_check(struct usb_device *udev) | 1005 | static inline int autosuspend_check(struct usb_device *udev, int reschedule) |
1016 | { | 1006 | { |
1017 | return 0; | 1007 | return 0; |
1018 | } | 1008 | } |
@@ -1069,7 +1059,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1069 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); | 1059 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); |
1070 | 1060 | ||
1071 | if (udev->auto_pm) { | 1061 | if (udev->auto_pm) { |
1072 | status = autosuspend_check(udev); | 1062 | status = autosuspend_check(udev, 0); |
1073 | if (status < 0) | 1063 | if (status < 0) |
1074 | goto done; | 1064 | goto done; |
1075 | } | 1065 | } |
@@ -1083,15 +1073,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1083 | break; | 1073 | break; |
1084 | } | 1074 | } |
1085 | } | 1075 | } |
1086 | if (status == 0) { | 1076 | if (status == 0) |
1087 | |||
1088 | /* Non-root devices don't need to do anything for FREEZE | ||
1089 | * or PRETHAW. */ | ||
1090 | if (udev->parent && (msg.event == PM_EVENT_FREEZE || | ||
1091 | msg.event == PM_EVENT_PRETHAW)) | ||
1092 | goto done; | ||
1093 | status = usb_suspend_device(udev, msg); | 1077 | status = usb_suspend_device(udev, msg); |
1094 | } | ||
1095 | 1078 | ||
1096 | /* If the suspend failed, resume interfaces that did get suspended */ | 1079 | /* If the suspend failed, resume interfaces that did get suspended */ |
1097 | if (status != 0) { | 1080 | if (status != 0) { |
@@ -1102,12 +1085,24 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1102 | 1085 | ||
1103 | /* Try another autosuspend when the interfaces aren't busy */ | 1086 | /* Try another autosuspend when the interfaces aren't busy */ |
1104 | if (udev->auto_pm) | 1087 | if (udev->auto_pm) |
1105 | autosuspend_check(udev); | 1088 | autosuspend_check(udev, status == -EBUSY); |
1106 | 1089 | ||
1107 | /* If the suspend succeeded, propagate it up the tree */ | 1090 | /* If the suspend succeeded then prevent any more URB submissions, |
1091 | * flush any outstanding URBs, and propagate the suspend up the tree. | ||
1092 | */ | ||
1108 | } else { | 1093 | } else { |
1109 | cancel_delayed_work(&udev->autosuspend); | 1094 | cancel_delayed_work(&udev->autosuspend); |
1110 | if (parent) | 1095 | udev->can_submit = 0; |
1096 | for (i = 0; i < 16; ++i) { | ||
1097 | usb_hcd_flush_endpoint(udev, udev->ep_out[i]); | ||
1098 | usb_hcd_flush_endpoint(udev, udev->ep_in[i]); | ||
1099 | } | ||
1100 | |||
1101 | /* If this is just a FREEZE or a PRETHAW, udev might | ||
1102 | * not really be suspended. Only true suspends get | ||
1103 | * propagated up the device tree. | ||
1104 | */ | ||
1105 | if (parent && udev->state == USB_STATE_SUSPENDED) | ||
1111 | usb_autosuspend_device(parent); | 1106 | usb_autosuspend_device(parent); |
1112 | } | 1107 | } |
1113 | 1108 | ||
@@ -1156,6 +1151,7 @@ static int usb_resume_both(struct usb_device *udev) | |||
1156 | status = -ENODEV; | 1151 | status = -ENODEV; |
1157 | goto done; | 1152 | goto done; |
1158 | } | 1153 | } |
1154 | udev->can_submit = 1; | ||
1159 | 1155 | ||
1160 | /* Propagate the resume up the tree, if necessary */ | 1156 | /* Propagate the resume up the tree, if necessary */ |
1161 | if (udev->state == USB_STATE_SUSPENDED) { | 1157 | if (udev->state == USB_STATE_SUSPENDED) { |
@@ -1529,9 +1525,21 @@ int usb_external_resume_device(struct usb_device *udev) | |||
1529 | 1525 | ||
1530 | static int usb_suspend(struct device *dev, pm_message_t message) | 1526 | static int usb_suspend(struct device *dev, pm_message_t message) |
1531 | { | 1527 | { |
1528 | struct usb_device *udev; | ||
1529 | |||
1532 | if (!is_usb_device(dev)) /* Ignore PM for interfaces */ | 1530 | if (!is_usb_device(dev)) /* Ignore PM for interfaces */ |
1533 | return 0; | 1531 | return 0; |
1534 | return usb_external_suspend_device(to_usb_device(dev), message); | 1532 | udev = to_usb_device(dev); |
1533 | |||
1534 | /* If udev is already suspended, we can skip this suspend and | ||
1535 | * we should also skip the upcoming system resume. */ | ||
1536 | if (udev->state == USB_STATE_SUSPENDED) { | ||
1537 | udev->skip_sys_resume = 1; | ||
1538 | return 0; | ||
1539 | } | ||
1540 | |||
1541 | udev->skip_sys_resume = 0; | ||
1542 | return usb_external_suspend_device(udev, message); | ||
1535 | } | 1543 | } |
1536 | 1544 | ||
1537 | static int usb_resume(struct device *dev) | 1545 | static int usb_resume(struct device *dev) |
@@ -1542,13 +1550,14 @@ static int usb_resume(struct device *dev) | |||
1542 | return 0; | 1550 | return 0; |
1543 | udev = to_usb_device(dev); | 1551 | udev = to_usb_device(dev); |
1544 | 1552 | ||
1545 | /* If autoresume is disabled then we also want to prevent resume | 1553 | /* If udev->skip_sys_resume is set then udev was already suspended |
1546 | * during system wakeup. However, a "persistent-device" reset-resume | 1554 | * when the system suspend started, so we don't want to resume |
1547 | * after power loss counts as a wakeup event. So allow a | 1555 | * udev during this system wakeup. However a reset-resume counts |
1548 | * reset-resume to occur if remote wakeup is enabled. */ | 1556 | * as a wakeup event, so allow a reset-resume to occur if remote |
1549 | if (udev->autoresume_disabled) { | 1557 | * wakeup is enabled. */ |
1558 | if (udev->skip_sys_resume) { | ||
1550 | if (!(udev->reset_resume && udev->do_remote_wakeup)) | 1559 | if (!(udev->reset_resume && udev->do_remote_wakeup)) |
1551 | return -EPERM; | 1560 | return -EHOSTUNREACH; |
1552 | } | 1561 | } |
1553 | return usb_external_resume_device(udev); | 1562 | return usb_external_resume_device(udev); |
1554 | } | 1563 | } |
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index e0ec7045e865..7dc123d6b2d0 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c | |||
@@ -267,7 +267,6 @@ static void ep_device_release(struct device *dev) | |||
267 | { | 267 | { |
268 | struct ep_device *ep_dev = to_ep_device(dev); | 268 | struct ep_device *ep_dev = to_ep_device(dev); |
269 | 269 | ||
270 | dev_dbg(dev, "%s called for %s\n", __FUNCTION__, dev->bus_id); | ||
271 | endpoint_free_minor(ep_dev); | 270 | endpoint_free_minor(ep_dev); |
272 | kfree(ep_dev); | 271 | kfree(ep_dev); |
273 | } | 272 | } |
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index b2fc2b115256..c1cb94e9f242 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
@@ -40,7 +40,7 @@ static int is_activesync(struct usb_interface_descriptor *desc) | |||
40 | && desc->bInterfaceProtocol == 1; | 40 | && desc->bInterfaceProtocol == 1; |
41 | } | 41 | } |
42 | 42 | ||
43 | static int choose_configuration(struct usb_device *udev) | 43 | int usb_choose_configuration(struct usb_device *udev) |
44 | { | 44 | { |
45 | int i; | 45 | int i; |
46 | int num_configs; | 46 | int num_configs; |
@@ -161,17 +161,20 @@ static int generic_probe(struct usb_device *udev) | |||
161 | /* Choose and set the configuration. This registers the interfaces | 161 | /* Choose and set the configuration. This registers the interfaces |
162 | * with the driver core and lets interface drivers bind to them. | 162 | * with the driver core and lets interface drivers bind to them. |
163 | */ | 163 | */ |
164 | c = choose_configuration(udev); | 164 | if (udev->authorized == 0) |
165 | if (c >= 0) { | 165 | dev_err(&udev->dev, "Device is not authorized for usage\n"); |
166 | err = usb_set_configuration(udev, c); | 166 | else { |
167 | if (err) { | 167 | c = usb_choose_configuration(udev); |
168 | dev_err(&udev->dev, "can't set config #%d, error %d\n", | 168 | if (c >= 0) { |
169 | err = usb_set_configuration(udev, c); | ||
170 | if (err) { | ||
171 | dev_err(&udev->dev, "can't set config #%d, error %d\n", | ||
169 | c, err); | 172 | c, err); |
170 | /* This need not be fatal. The user can try to | 173 | /* This need not be fatal. The user can try to |
171 | * set other configurations. */ | 174 | * set other configurations. */ |
175 | } | ||
172 | } | 176 | } |
173 | } | 177 | } |
174 | |||
175 | /* USB device state == configured ... usable */ | 178 | /* USB device state == configured ... usable */ |
176 | usb_notify_add_device(udev); | 179 | usb_notify_add_device(udev); |
177 | 180 | ||
@@ -203,8 +206,13 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) | |||
203 | */ | 206 | */ |
204 | if (!udev->parent) | 207 | if (!udev->parent) |
205 | rc = hcd_bus_suspend(udev); | 208 | rc = hcd_bus_suspend(udev); |
209 | |||
210 | /* Non-root devices don't need to do anything for FREEZE or PRETHAW */ | ||
211 | else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) | ||
212 | rc = 0; | ||
206 | else | 213 | else |
207 | rc = usb_port_suspend(udev); | 214 | rc = usb_port_suspend(udev); |
215 | |||
208 | return rc; | 216 | return rc; |
209 | } | 217 | } |
210 | 218 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 42ef1d5f6c8a..3dd997df8505 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -356,10 +356,18 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
356 | const u8 *bufp = tbuf; | 356 | const u8 *bufp = tbuf; |
357 | int len = 0; | 357 | int len = 0; |
358 | int patch_wakeup = 0; | 358 | int patch_wakeup = 0; |
359 | unsigned long flags; | 359 | int status; |
360 | int status = 0; | ||
361 | int n; | 360 | int n; |
362 | 361 | ||
362 | might_sleep(); | ||
363 | |||
364 | spin_lock_irq(&hcd_root_hub_lock); | ||
365 | status = usb_hcd_link_urb_to_ep(hcd, urb); | ||
366 | spin_unlock_irq(&hcd_root_hub_lock); | ||
367 | if (status) | ||
368 | return status; | ||
369 | urb->hcpriv = hcd; /* Indicate it's queued */ | ||
370 | |||
363 | cmd = (struct usb_ctrlrequest *) urb->setup_packet; | 371 | cmd = (struct usb_ctrlrequest *) urb->setup_packet; |
364 | typeReq = (cmd->bRequestType << 8) | cmd->bRequest; | 372 | typeReq = (cmd->bRequestType << 8) | cmd->bRequest; |
365 | wValue = le16_to_cpu (cmd->wValue); | 373 | wValue = le16_to_cpu (cmd->wValue); |
@@ -523,13 +531,18 @@ error: | |||
523 | } | 531 | } |
524 | 532 | ||
525 | /* any errors get returned through the urb completion */ | 533 | /* any errors get returned through the urb completion */ |
526 | local_irq_save (flags); | 534 | spin_lock_irq(&hcd_root_hub_lock); |
527 | spin_lock (&urb->lock); | 535 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
528 | if (urb->status == -EINPROGRESS) | 536 | |
529 | urb->status = status; | 537 | /* This peculiar use of spinlocks echoes what real HC drivers do. |
530 | spin_unlock (&urb->lock); | 538 | * Avoiding calls to local_irq_disable/enable makes the code |
531 | usb_hcd_giveback_urb (hcd, urb); | 539 | * RT-friendly. |
532 | local_irq_restore (flags); | 540 | */ |
541 | spin_unlock(&hcd_root_hub_lock); | ||
542 | usb_hcd_giveback_urb(hcd, urb, status); | ||
543 | spin_lock(&hcd_root_hub_lock); | ||
544 | |||
545 | spin_unlock_irq(&hcd_root_hub_lock); | ||
533 | return 0; | 546 | return 0; |
534 | } | 547 | } |
535 | 548 | ||
@@ -559,31 +572,23 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) | |||
559 | if (length > 0) { | 572 | if (length > 0) { |
560 | 573 | ||
561 | /* try to complete the status urb */ | 574 | /* try to complete the status urb */ |
562 | local_irq_save (flags); | 575 | spin_lock_irqsave(&hcd_root_hub_lock, flags); |
563 | spin_lock(&hcd_root_hub_lock); | ||
564 | urb = hcd->status_urb; | 576 | urb = hcd->status_urb; |
565 | if (urb) { | 577 | if (urb) { |
566 | spin_lock(&urb->lock); | 578 | hcd->poll_pending = 0; |
567 | if (urb->status == -EINPROGRESS) { | 579 | hcd->status_urb = NULL; |
568 | hcd->poll_pending = 0; | 580 | urb->actual_length = length; |
569 | hcd->status_urb = NULL; | 581 | memcpy(urb->transfer_buffer, buffer, length); |
570 | urb->status = 0; | ||
571 | urb->hcpriv = NULL; | ||
572 | urb->actual_length = length; | ||
573 | memcpy(urb->transfer_buffer, buffer, length); | ||
574 | } else /* urb has been unlinked */ | ||
575 | length = 0; | ||
576 | spin_unlock(&urb->lock); | ||
577 | } else | ||
578 | length = 0; | ||
579 | spin_unlock(&hcd_root_hub_lock); | ||
580 | 582 | ||
581 | /* local irqs are always blocked in completions */ | 583 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
582 | if (length > 0) | 584 | spin_unlock(&hcd_root_hub_lock); |
583 | usb_hcd_giveback_urb (hcd, urb); | 585 | usb_hcd_giveback_urb(hcd, urb, 0); |
584 | else | 586 | spin_lock(&hcd_root_hub_lock); |
587 | } else { | ||
588 | length = 0; | ||
585 | hcd->poll_pending = 1; | 589 | hcd->poll_pending = 1; |
586 | local_irq_restore (flags); | 590 | } |
591 | spin_unlock_irqrestore(&hcd_root_hub_lock, flags); | ||
587 | } | 592 | } |
588 | 593 | ||
589 | /* The USB 2.0 spec says 256 ms. This is close enough and won't | 594 | /* The USB 2.0 spec says 256 ms. This is close enough and won't |
@@ -611,33 +616,35 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb) | |||
611 | int len = 1 + (urb->dev->maxchild / 8); | 616 | int len = 1 + (urb->dev->maxchild / 8); |
612 | 617 | ||
613 | spin_lock_irqsave (&hcd_root_hub_lock, flags); | 618 | spin_lock_irqsave (&hcd_root_hub_lock, flags); |
614 | if (urb->status != -EINPROGRESS) /* already unlinked */ | 619 | if (hcd->status_urb || urb->transfer_buffer_length < len) { |
615 | retval = urb->status; | ||
616 | else if (hcd->status_urb || urb->transfer_buffer_length < len) { | ||
617 | dev_dbg (hcd->self.controller, "not queuing rh status urb\n"); | 620 | dev_dbg (hcd->self.controller, "not queuing rh status urb\n"); |
618 | retval = -EINVAL; | 621 | retval = -EINVAL; |
619 | } else { | 622 | goto done; |
620 | hcd->status_urb = urb; | 623 | } |
621 | urb->hcpriv = hcd; /* indicate it's queued */ | ||
622 | 624 | ||
623 | if (!hcd->uses_new_polling) | 625 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
624 | mod_timer (&hcd->rh_timer, | 626 | if (retval) |
625 | (jiffies/(HZ/4) + 1) * (HZ/4)); | 627 | goto done; |
626 | 628 | ||
627 | /* If a status change has already occurred, report it ASAP */ | 629 | hcd->status_urb = urb; |
628 | else if (hcd->poll_pending) | 630 | urb->hcpriv = hcd; /* indicate it's queued */ |
629 | mod_timer (&hcd->rh_timer, jiffies); | 631 | if (!hcd->uses_new_polling) |
630 | retval = 0; | 632 | mod_timer(&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); |
631 | } | 633 | |
634 | /* If a status change has already occurred, report it ASAP */ | ||
635 | else if (hcd->poll_pending) | ||
636 | mod_timer(&hcd->rh_timer, jiffies); | ||
637 | retval = 0; | ||
638 | done: | ||
632 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); | 639 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); |
633 | return retval; | 640 | return retval; |
634 | } | 641 | } |
635 | 642 | ||
636 | static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) | 643 | static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) |
637 | { | 644 | { |
638 | if (usb_pipeint (urb->pipe)) | 645 | if (usb_endpoint_xfer_int(&urb->ep->desc)) |
639 | return rh_queue_status (hcd, urb); | 646 | return rh_queue_status (hcd, urb); |
640 | if (usb_pipecontrol (urb->pipe)) | 647 | if (usb_endpoint_xfer_control(&urb->ep->desc)) |
641 | return rh_call_control (hcd, urb); | 648 | return rh_call_control (hcd, urb); |
642 | return -EINVAL; | 649 | return -EINVAL; |
643 | } | 650 | } |
@@ -647,32 +654,96 @@ static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) | |||
647 | /* Unlinks of root-hub control URBs are legal, but they don't do anything | 654 | /* Unlinks of root-hub control URBs are legal, but they don't do anything |
648 | * since these URBs always execute synchronously. | 655 | * since these URBs always execute synchronously. |
649 | */ | 656 | */ |
650 | static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 657 | static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
651 | { | 658 | { |
652 | unsigned long flags; | 659 | unsigned long flags; |
660 | int rc; | ||
661 | |||
662 | spin_lock_irqsave(&hcd_root_hub_lock, flags); | ||
663 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
664 | if (rc) | ||
665 | goto done; | ||
653 | 666 | ||
654 | if (usb_pipeendpoint(urb->pipe) == 0) { /* Control URB */ | 667 | if (usb_endpoint_num(&urb->ep->desc) == 0) { /* Control URB */ |
655 | ; /* Do nothing */ | 668 | ; /* Do nothing */ |
656 | 669 | ||
657 | } else { /* Status URB */ | 670 | } else { /* Status URB */ |
658 | if (!hcd->uses_new_polling) | 671 | if (!hcd->uses_new_polling) |
659 | del_timer (&hcd->rh_timer); | 672 | del_timer (&hcd->rh_timer); |
660 | local_irq_save (flags); | ||
661 | spin_lock (&hcd_root_hub_lock); | ||
662 | if (urb == hcd->status_urb) { | 673 | if (urb == hcd->status_urb) { |
663 | hcd->status_urb = NULL; | 674 | hcd->status_urb = NULL; |
664 | urb->hcpriv = NULL; | 675 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
665 | } else | 676 | |
666 | urb = NULL; /* wasn't fully queued */ | 677 | spin_unlock(&hcd_root_hub_lock); |
667 | spin_unlock (&hcd_root_hub_lock); | 678 | usb_hcd_giveback_urb(hcd, urb, status); |
668 | if (urb) | 679 | spin_lock(&hcd_root_hub_lock); |
669 | usb_hcd_giveback_urb (hcd, urb); | 680 | } |
670 | local_irq_restore (flags); | ||
671 | } | 681 | } |
682 | done: | ||
683 | spin_unlock_irqrestore(&hcd_root_hub_lock, flags); | ||
684 | return rc; | ||
685 | } | ||
672 | 686 | ||
673 | return 0; | 687 | |
688 | |||
689 | /* | ||
690 | * Show & store the current value of authorized_default | ||
691 | */ | ||
692 | static ssize_t usb_host_authorized_default_show(struct device *dev, | ||
693 | struct device_attribute *attr, | ||
694 | char *buf) | ||
695 | { | ||
696 | struct usb_device *rh_usb_dev = to_usb_device(dev); | ||
697 | struct usb_bus *usb_bus = rh_usb_dev->bus; | ||
698 | struct usb_hcd *usb_hcd; | ||
699 | |||
700 | if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ | ||
701 | return -ENODEV; | ||
702 | usb_hcd = bus_to_hcd(usb_bus); | ||
703 | return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default); | ||
704 | } | ||
705 | |||
706 | static ssize_t usb_host_authorized_default_store(struct device *dev, | ||
707 | struct device_attribute *attr, | ||
708 | const char *buf, size_t size) | ||
709 | { | ||
710 | ssize_t result; | ||
711 | unsigned val; | ||
712 | struct usb_device *rh_usb_dev = to_usb_device(dev); | ||
713 | struct usb_bus *usb_bus = rh_usb_dev->bus; | ||
714 | struct usb_hcd *usb_hcd; | ||
715 | |||
716 | if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ | ||
717 | return -ENODEV; | ||
718 | usb_hcd = bus_to_hcd(usb_bus); | ||
719 | result = sscanf(buf, "%u\n", &val); | ||
720 | if (result == 1) { | ||
721 | usb_hcd->authorized_default = val? 1 : 0; | ||
722 | result = size; | ||
723 | } | ||
724 | else | ||
725 | result = -EINVAL; | ||
726 | return result; | ||
674 | } | 727 | } |
675 | 728 | ||
729 | static DEVICE_ATTR(authorized_default, 0644, | ||
730 | usb_host_authorized_default_show, | ||
731 | usb_host_authorized_default_store); | ||
732 | |||
733 | |||
734 | /* Group all the USB bus attributes */ | ||
735 | static struct attribute *usb_bus_attrs[] = { | ||
736 | &dev_attr_authorized_default.attr, | ||
737 | NULL, | ||
738 | }; | ||
739 | |||
740 | static struct attribute_group usb_bus_attr_group = { | ||
741 | .name = NULL, /* we want them in the same directory */ | ||
742 | .attrs = usb_bus_attrs, | ||
743 | }; | ||
744 | |||
745 | |||
746 | |||
676 | /*-------------------------------------------------------------------------*/ | 747 | /*-------------------------------------------------------------------------*/ |
677 | 748 | ||
678 | static struct class *usb_host_class; | 749 | static struct class *usb_host_class; |
@@ -726,27 +797,23 @@ static void usb_bus_init (struct usb_bus *bus) | |||
726 | */ | 797 | */ |
727 | static int usb_register_bus(struct usb_bus *bus) | 798 | static int usb_register_bus(struct usb_bus *bus) |
728 | { | 799 | { |
800 | int result = -E2BIG; | ||
729 | int busnum; | 801 | int busnum; |
730 | 802 | ||
731 | mutex_lock(&usb_bus_list_lock); | 803 | mutex_lock(&usb_bus_list_lock); |
732 | busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); | 804 | busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); |
733 | if (busnum < USB_MAXBUS) { | 805 | if (busnum >= USB_MAXBUS) { |
734 | set_bit (busnum, busmap.busmap); | ||
735 | bus->busnum = busnum; | ||
736 | } else { | ||
737 | printk (KERN_ERR "%s: too many buses\n", usbcore_name); | 806 | printk (KERN_ERR "%s: too many buses\n", usbcore_name); |
738 | mutex_unlock(&usb_bus_list_lock); | 807 | goto error_find_busnum; |
739 | return -E2BIG; | ||
740 | } | 808 | } |
741 | 809 | set_bit (busnum, busmap.busmap); | |
810 | bus->busnum = busnum; | ||
742 | bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0), | 811 | bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0), |
743 | bus->controller, "usb_host%d", busnum); | 812 | bus->controller, "usb_host%d", |
744 | if (IS_ERR(bus->class_dev)) { | 813 | busnum); |
745 | clear_bit(busnum, busmap.busmap); | 814 | result = PTR_ERR(bus->class_dev); |
746 | mutex_unlock(&usb_bus_list_lock); | 815 | if (IS_ERR(bus->class_dev)) |
747 | return PTR_ERR(bus->class_dev); | 816 | goto error_create_class_dev; |
748 | } | ||
749 | |||
750 | class_set_devdata(bus->class_dev, bus); | 817 | class_set_devdata(bus->class_dev, bus); |
751 | 818 | ||
752 | /* Add it to the local list of buses */ | 819 | /* Add it to the local list of buses */ |
@@ -755,8 +822,15 @@ static int usb_register_bus(struct usb_bus *bus) | |||
755 | 822 | ||
756 | usb_notify_add_bus(bus); | 823 | usb_notify_add_bus(bus); |
757 | 824 | ||
758 | dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum); | 825 | dev_info (bus->controller, "new USB bus registered, assigned bus " |
826 | "number %d\n", bus->busnum); | ||
759 | return 0; | 827 | return 0; |
828 | |||
829 | error_create_class_dev: | ||
830 | clear_bit(busnum, busmap.busmap); | ||
831 | error_find_busnum: | ||
832 | mutex_unlock(&usb_bus_list_lock); | ||
833 | return result; | ||
760 | } | 834 | } |
761 | 835 | ||
762 | /** | 836 | /** |
@@ -908,103 +982,145 @@ EXPORT_SYMBOL (usb_calc_bus_time); | |||
908 | 982 | ||
909 | /*-------------------------------------------------------------------------*/ | 983 | /*-------------------------------------------------------------------------*/ |
910 | 984 | ||
911 | static void urb_unlink(struct usb_hcd *hcd, struct urb *urb) | 985 | /** |
986 | * usb_hcd_link_urb_to_ep - add an URB to its endpoint queue | ||
987 | * @hcd: host controller to which @urb was submitted | ||
988 | * @urb: URB being submitted | ||
989 | * | ||
990 | * Host controller drivers should call this routine in their enqueue() | ||
991 | * method. The HCD's private spinlock must be held and interrupts must | ||
992 | * be disabled. The actions carried out here are required for URB | ||
993 | * submission, as well as for endpoint shutdown and for usb_kill_urb. | ||
994 | * | ||
995 | * Returns 0 for no error, otherwise a negative error code (in which case | ||
996 | * the enqueue() method must fail). If no error occurs but enqueue() fails | ||
997 | * anyway, it must call usb_hcd_unlink_urb_from_ep() before releasing | ||
998 | * the private spinlock and returning. | ||
999 | */ | ||
1000 | int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb) | ||
912 | { | 1001 | { |
913 | unsigned long flags; | 1002 | int rc = 0; |
914 | 1003 | ||
915 | /* clear all state linking urb to this dev (and hcd) */ | 1004 | spin_lock(&hcd_urb_list_lock); |
916 | spin_lock_irqsave(&hcd_urb_list_lock, flags); | ||
917 | list_del_init (&urb->urb_list); | ||
918 | spin_unlock_irqrestore(&hcd_urb_list_lock, flags); | ||
919 | 1005 | ||
920 | if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { | 1006 | /* Check that the URB isn't being killed */ |
921 | if (usb_pipecontrol (urb->pipe) | 1007 | if (unlikely(urb->reject)) { |
922 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) | 1008 | rc = -EPERM; |
923 | dma_unmap_single (hcd->self.controller, urb->setup_dma, | 1009 | goto done; |
924 | sizeof (struct usb_ctrlrequest), | ||
925 | DMA_TO_DEVICE); | ||
926 | if (urb->transfer_buffer_length != 0 | ||
927 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) | ||
928 | dma_unmap_single (hcd->self.controller, | ||
929 | urb->transfer_dma, | ||
930 | urb->transfer_buffer_length, | ||
931 | usb_pipein (urb->pipe) | ||
932 | ? DMA_FROM_DEVICE | ||
933 | : DMA_TO_DEVICE); | ||
934 | } | 1010 | } |
935 | } | ||
936 | |||
937 | /* may be called in any context with a valid urb->dev usecount | ||
938 | * caller surrenders "ownership" of urb | ||
939 | * expects usb_submit_urb() to have sanity checked and conditioned all | ||
940 | * inputs in the urb | ||
941 | */ | ||
942 | int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | ||
943 | { | ||
944 | int status; | ||
945 | struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); | ||
946 | struct usb_host_endpoint *ep; | ||
947 | unsigned long flags; | ||
948 | 1011 | ||
949 | if (!hcd) | 1012 | if (unlikely(!urb->ep->enabled)) { |
950 | return -ENODEV; | 1013 | rc = -ENOENT; |
1014 | goto done; | ||
1015 | } | ||
951 | 1016 | ||
952 | usbmon_urb_submit(&hcd->self, urb); | 1017 | if (unlikely(!urb->dev->can_submit)) { |
1018 | rc = -EHOSTUNREACH; | ||
1019 | goto done; | ||
1020 | } | ||
953 | 1021 | ||
954 | /* | 1022 | /* |
955 | * Atomically queue the urb, first to our records, then to the HCD. | 1023 | * Check the host controller's state and add the URB to the |
956 | * Access to urb->status is controlled by urb->lock ... changes on | 1024 | * endpoint's queue. |
957 | * i/o completion (normal or fault) or unlinking. | ||
958 | */ | 1025 | */ |
959 | 1026 | switch (hcd->state) { | |
960 | // FIXME: verify that quiescing hc works right (RH cleans up) | ||
961 | |||
962 | spin_lock_irqsave(&hcd_urb_list_lock, flags); | ||
963 | ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out) | ||
964 | [usb_pipeendpoint(urb->pipe)]; | ||
965 | if (unlikely (!ep)) | ||
966 | status = -ENOENT; | ||
967 | else if (unlikely (urb->reject)) | ||
968 | status = -EPERM; | ||
969 | else switch (hcd->state) { | ||
970 | case HC_STATE_RUNNING: | 1027 | case HC_STATE_RUNNING: |
971 | case HC_STATE_RESUMING: | 1028 | case HC_STATE_RESUMING: |
972 | list_add_tail (&urb->urb_list, &ep->urb_list); | 1029 | urb->unlinked = 0; |
973 | status = 0; | 1030 | list_add_tail(&urb->urb_list, &urb->ep->urb_list); |
974 | break; | 1031 | break; |
975 | default: | 1032 | default: |
976 | status = -ESHUTDOWN; | 1033 | rc = -ESHUTDOWN; |
977 | break; | 1034 | goto done; |
978 | } | 1035 | } |
979 | spin_unlock_irqrestore(&hcd_urb_list_lock, flags); | 1036 | done: |
980 | if (status) { | 1037 | spin_unlock(&hcd_urb_list_lock); |
981 | INIT_LIST_HEAD (&urb->urb_list); | 1038 | return rc; |
982 | usbmon_urb_submit_error(&hcd->self, urb, status); | 1039 | } |
983 | return status; | 1040 | EXPORT_SYMBOL_GPL(usb_hcd_link_urb_to_ep); |
1041 | |||
1042 | /** | ||
1043 | * usb_hcd_check_unlink_urb - check whether an URB may be unlinked | ||
1044 | * @hcd: host controller to which @urb was submitted | ||
1045 | * @urb: URB being checked for unlinkability | ||
1046 | * @status: error code to store in @urb if the unlink succeeds | ||
1047 | * | ||
1048 | * Host controller drivers should call this routine in their dequeue() | ||
1049 | * method. The HCD's private spinlock must be held and interrupts must | ||
1050 | * be disabled. The actions carried out here are required for making | ||
1051 | * sure than an unlink is valid. | ||
1052 | * | ||
1053 | * Returns 0 for no error, otherwise a negative error code (in which case | ||
1054 | * the dequeue() method must fail). The possible error codes are: | ||
1055 | * | ||
1056 | * -EIDRM: @urb was not submitted or has already completed. | ||
1057 | * The completion function may not have been called yet. | ||
1058 | * | ||
1059 | * -EBUSY: @urb has already been unlinked. | ||
1060 | */ | ||
1061 | int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, | ||
1062 | int status) | ||
1063 | { | ||
1064 | struct list_head *tmp; | ||
1065 | |||
1066 | /* insist the urb is still queued */ | ||
1067 | list_for_each(tmp, &urb->ep->urb_list) { | ||
1068 | if (tmp == &urb->urb_list) | ||
1069 | break; | ||
984 | } | 1070 | } |
1071 | if (tmp != &urb->urb_list) | ||
1072 | return -EIDRM; | ||
985 | 1073 | ||
986 | /* increment urb's reference count as part of giving it to the HCD | 1074 | /* Any status except -EINPROGRESS means something already started to |
987 | * (which now controls it). HCD guarantees that it either returns | 1075 | * unlink this URB from the hardware. So there's no more work to do. |
988 | * an error or calls giveback(), but not both. | ||
989 | */ | 1076 | */ |
990 | urb = usb_get_urb (urb); | 1077 | if (urb->unlinked) |
991 | atomic_inc (&urb->use_count); | 1078 | return -EBUSY; |
992 | 1079 | urb->unlinked = status; | |
993 | if (is_root_hub(urb->dev)) { | 1080 | |
994 | /* NOTE: requirement on hub callers (usbfs and the hub | 1081 | /* IRQ setup can easily be broken so that USB controllers |
995 | * driver, for now) that URBs' urb->transfer_buffer be | 1082 | * never get completion IRQs ... maybe even the ones we need to |
996 | * valid and usb_buffer_{sync,unmap}() not be needed, since | 1083 | * finish unlinking the initial failed usb_set_address() |
997 | * they could clobber root hub response data. | 1084 | * or device descriptor fetch. |
998 | */ | 1085 | */ |
999 | status = rh_urb_enqueue (hcd, urb); | 1086 | if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) && |
1000 | goto done; | 1087 | !is_root_hub(urb->dev)) { |
1088 | dev_warn(hcd->self.controller, "Unlink after no-IRQ? " | ||
1089 | "Controller is probably using the wrong IRQ.\n"); | ||
1090 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | ||
1001 | } | 1091 | } |
1002 | 1092 | ||
1003 | /* lower level hcd code should use *_dma exclusively, | 1093 | return 0; |
1094 | } | ||
1095 | EXPORT_SYMBOL_GPL(usb_hcd_check_unlink_urb); | ||
1096 | |||
1097 | /** | ||
1098 | * usb_hcd_unlink_urb_from_ep - remove an URB from its endpoint queue | ||
1099 | * @hcd: host controller to which @urb was submitted | ||
1100 | * @urb: URB being unlinked | ||
1101 | * | ||
1102 | * Host controller drivers should call this routine before calling | ||
1103 | * usb_hcd_giveback_urb(). The HCD's private spinlock must be held and | ||
1104 | * interrupts must be disabled. The actions carried out here are required | ||
1105 | * for URB completion. | ||
1106 | */ | ||
1107 | void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb) | ||
1108 | { | ||
1109 | /* clear all state linking urb to this dev (and hcd) */ | ||
1110 | spin_lock(&hcd_urb_list_lock); | ||
1111 | list_del_init(&urb->urb_list); | ||
1112 | spin_unlock(&hcd_urb_list_lock); | ||
1113 | } | ||
1114 | EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep); | ||
1115 | |||
1116 | static void map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) | ||
1117 | { | ||
1118 | /* Map the URB's buffers for DMA access. | ||
1119 | * Lower level HCD code should use *_dma exclusively, | ||
1004 | * unless it uses pio or talks to another transport. | 1120 | * unless it uses pio or talks to another transport. |
1005 | */ | 1121 | */ |
1006 | if (hcd->self.uses_dma) { | 1122 | if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { |
1007 | if (usb_pipecontrol (urb->pipe) | 1123 | if (usb_endpoint_xfer_control(&urb->ep->desc) |
1008 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) | 1124 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) |
1009 | urb->setup_dma = dma_map_single ( | 1125 | urb->setup_dma = dma_map_single ( |
1010 | hcd->self.controller, | 1126 | hcd->self.controller, |
@@ -1017,20 +1133,75 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
1017 | hcd->self.controller, | 1133 | hcd->self.controller, |
1018 | urb->transfer_buffer, | 1134 | urb->transfer_buffer, |
1019 | urb->transfer_buffer_length, | 1135 | urb->transfer_buffer_length, |
1020 | usb_pipein (urb->pipe) | 1136 | usb_urb_dir_in(urb) |
1021 | ? DMA_FROM_DEVICE | 1137 | ? DMA_FROM_DEVICE |
1022 | : DMA_TO_DEVICE); | 1138 | : DMA_TO_DEVICE); |
1023 | } | 1139 | } |
1140 | } | ||
1024 | 1141 | ||
1025 | status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags); | 1142 | static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) |
1026 | done: | 1143 | { |
1027 | if (unlikely (status)) { | 1144 | if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { |
1028 | urb_unlink(hcd, urb); | 1145 | if (usb_endpoint_xfer_control(&urb->ep->desc) |
1029 | atomic_dec (&urb->use_count); | 1146 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) |
1030 | if (urb->reject) | 1147 | dma_unmap_single(hcd->self.controller, urb->setup_dma, |
1031 | wake_up (&usb_kill_urb_queue); | 1148 | sizeof(struct usb_ctrlrequest), |
1149 | DMA_TO_DEVICE); | ||
1150 | if (urb->transfer_buffer_length != 0 | ||
1151 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) | ||
1152 | dma_unmap_single(hcd->self.controller, | ||
1153 | urb->transfer_dma, | ||
1154 | urb->transfer_buffer_length, | ||
1155 | usb_urb_dir_in(urb) | ||
1156 | ? DMA_FROM_DEVICE | ||
1157 | : DMA_TO_DEVICE); | ||
1158 | } | ||
1159 | } | ||
1160 | |||
1161 | /*-------------------------------------------------------------------------*/ | ||
1162 | |||
1163 | /* may be called in any context with a valid urb->dev usecount | ||
1164 | * caller surrenders "ownership" of urb | ||
1165 | * expects usb_submit_urb() to have sanity checked and conditioned all | ||
1166 | * inputs in the urb | ||
1167 | */ | ||
1168 | int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | ||
1169 | { | ||
1170 | int status; | ||
1171 | struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); | ||
1172 | |||
1173 | /* increment urb's reference count as part of giving it to the HCD | ||
1174 | * (which will control it). HCD guarantees that it either returns | ||
1175 | * an error or calls giveback(), but not both. | ||
1176 | */ | ||
1177 | usb_get_urb(urb); | ||
1178 | atomic_inc(&urb->use_count); | ||
1179 | atomic_inc(&urb->dev->urbnum); | ||
1180 | usbmon_urb_submit(&hcd->self, urb); | ||
1181 | |||
1182 | /* NOTE requirements on root-hub callers (usbfs and the hub | ||
1183 | * driver, for now): URBs' urb->transfer_buffer must be | ||
1184 | * valid and usb_buffer_{sync,unmap}() not be needed, since | ||
1185 | * they could clobber root hub response data. Also, control | ||
1186 | * URBs must be submitted in process context with interrupts | ||
1187 | * enabled. | ||
1188 | */ | ||
1189 | map_urb_for_dma(hcd, urb); | ||
1190 | if (is_root_hub(urb->dev)) | ||
1191 | status = rh_urb_enqueue(hcd, urb); | ||
1192 | else | ||
1193 | status = hcd->driver->urb_enqueue(hcd, urb, mem_flags); | ||
1194 | |||
1195 | if (unlikely(status)) { | ||
1032 | usbmon_urb_submit_error(&hcd->self, urb, status); | 1196 | usbmon_urb_submit_error(&hcd->self, urb, status); |
1033 | usb_put_urb (urb); | 1197 | unmap_urb_for_dma(hcd, urb); |
1198 | urb->hcpriv = NULL; | ||
1199 | INIT_LIST_HEAD(&urb->urb_list); | ||
1200 | atomic_dec(&urb->use_count); | ||
1201 | atomic_dec(&urb->dev->urbnum); | ||
1202 | if (urb->reject) | ||
1203 | wake_up(&usb_kill_urb_queue); | ||
1204 | usb_put_urb(urb); | ||
1034 | } | 1205 | } |
1035 | return status; | 1206 | return status; |
1036 | } | 1207 | } |
@@ -1042,24 +1213,19 @@ done: | |||
1042 | * soon as practical. we've already set up the urb's return status, | 1213 | * soon as practical. we've already set up the urb's return status, |
1043 | * but we can't know if the callback completed already. | 1214 | * but we can't know if the callback completed already. |
1044 | */ | 1215 | */ |
1045 | static int | 1216 | static int unlink1(struct usb_hcd *hcd, struct urb *urb, int status) |
1046 | unlink1 (struct usb_hcd *hcd, struct urb *urb) | ||
1047 | { | 1217 | { |
1048 | int value; | 1218 | int value; |
1049 | 1219 | ||
1050 | if (is_root_hub(urb->dev)) | 1220 | if (is_root_hub(urb->dev)) |
1051 | value = usb_rh_urb_dequeue (hcd, urb); | 1221 | value = usb_rh_urb_dequeue(hcd, urb, status); |
1052 | else { | 1222 | else { |
1053 | 1223 | ||
1054 | /* The only reason an HCD might fail this call is if | 1224 | /* The only reason an HCD might fail this call is if |
1055 | * it has not yet fully queued the urb to begin with. | 1225 | * it has not yet fully queued the urb to begin with. |
1056 | * Such failures should be harmless. */ | 1226 | * Such failures should be harmless. */ |
1057 | value = hcd->driver->urb_dequeue (hcd, urb); | 1227 | value = hcd->driver->urb_dequeue(hcd, urb, status); |
1058 | } | 1228 | } |
1059 | |||
1060 | if (value != 0) | ||
1061 | dev_dbg (hcd->self.controller, "dequeue %p --> %d\n", | ||
1062 | urb, value); | ||
1063 | return value; | 1229 | return value; |
1064 | } | 1230 | } |
1065 | 1231 | ||
@@ -1071,88 +1237,17 @@ unlink1 (struct usb_hcd *hcd, struct urb *urb) | |||
1071 | */ | 1237 | */ |
1072 | int usb_hcd_unlink_urb (struct urb *urb, int status) | 1238 | int usb_hcd_unlink_urb (struct urb *urb, int status) |
1073 | { | 1239 | { |
1074 | struct usb_host_endpoint *ep; | 1240 | struct usb_hcd *hcd; |
1075 | struct usb_hcd *hcd = NULL; | 1241 | int retval; |
1076 | struct device *sys = NULL; | ||
1077 | unsigned long flags; | ||
1078 | struct list_head *tmp; | ||
1079 | int retval; | ||
1080 | |||
1081 | if (!urb) | ||
1082 | return -EINVAL; | ||
1083 | if (!urb->dev || !urb->dev->bus) | ||
1084 | return -ENODEV; | ||
1085 | ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out) | ||
1086 | [usb_pipeendpoint(urb->pipe)]; | ||
1087 | if (!ep) | ||
1088 | return -ENODEV; | ||
1089 | |||
1090 | /* | ||
1091 | * we contend for urb->status with the hcd core, | ||
1092 | * which changes it while returning the urb. | ||
1093 | * | ||
1094 | * Caller guaranteed that the urb pointer hasn't been freed, and | ||
1095 | * that it was submitted. But as a rule it can't know whether or | ||
1096 | * not it's already been unlinked ... so we respect the reversed | ||
1097 | * lock sequence needed for the usb_hcd_giveback_urb() code paths | ||
1098 | * (urb lock, then hcd_urb_list_lock) in case some other CPU is now | ||
1099 | * unlinking it. | ||
1100 | */ | ||
1101 | spin_lock_irqsave (&urb->lock, flags); | ||
1102 | spin_lock(&hcd_urb_list_lock); | ||
1103 | 1242 | ||
1104 | sys = &urb->dev->dev; | ||
1105 | hcd = bus_to_hcd(urb->dev->bus); | 1243 | hcd = bus_to_hcd(urb->dev->bus); |
1106 | if (hcd == NULL) { | 1244 | retval = unlink1(hcd, urb, status); |
1107 | retval = -ENODEV; | ||
1108 | goto done; | ||
1109 | } | ||
1110 | 1245 | ||
1111 | /* insist the urb is still queued */ | ||
1112 | list_for_each(tmp, &ep->urb_list) { | ||
1113 | if (tmp == &urb->urb_list) | ||
1114 | break; | ||
1115 | } | ||
1116 | if (tmp != &urb->urb_list) { | ||
1117 | retval = -EIDRM; | ||
1118 | goto done; | ||
1119 | } | ||
1120 | |||
1121 | /* Any status except -EINPROGRESS means something already started to | ||
1122 | * unlink this URB from the hardware. So there's no more work to do. | ||
1123 | */ | ||
1124 | if (urb->status != -EINPROGRESS) { | ||
1125 | retval = -EBUSY; | ||
1126 | goto done; | ||
1127 | } | ||
1128 | |||
1129 | /* IRQ setup can easily be broken so that USB controllers | ||
1130 | * never get completion IRQs ... maybe even the ones we need to | ||
1131 | * finish unlinking the initial failed usb_set_address() | ||
1132 | * or device descriptor fetch. | ||
1133 | */ | ||
1134 | if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) && | ||
1135 | !is_root_hub(urb->dev)) { | ||
1136 | dev_warn (hcd->self.controller, "Unlink after no-IRQ? " | ||
1137 | "Controller is probably using the wrong IRQ.\n"); | ||
1138 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | ||
1139 | } | ||
1140 | |||
1141 | urb->status = status; | ||
1142 | |||
1143 | spin_unlock(&hcd_urb_list_lock); | ||
1144 | spin_unlock_irqrestore (&urb->lock, flags); | ||
1145 | |||
1146 | retval = unlink1 (hcd, urb); | ||
1147 | if (retval == 0) | 1246 | if (retval == 0) |
1148 | retval = -EINPROGRESS; | 1247 | retval = -EINPROGRESS; |
1149 | return retval; | 1248 | else if (retval != -EIDRM && retval != -EBUSY) |
1150 | 1249 | dev_dbg(&urb->dev->dev, "hcd_unlink_urb %p fail %d\n", | |
1151 | done: | 1250 | urb, retval); |
1152 | spin_unlock(&hcd_urb_list_lock); | ||
1153 | spin_unlock_irqrestore (&urb->lock, flags); | ||
1154 | if (retval != -EIDRM && sys && sys->driver) | ||
1155 | dev_dbg (sys, "hcd_unlink_urb %p fail %d\n", urb, retval); | ||
1156 | return retval; | 1251 | return retval; |
1157 | } | 1252 | } |
1158 | 1253 | ||
@@ -1162,6 +1257,7 @@ done: | |||
1162 | * usb_hcd_giveback_urb - return URB from HCD to device driver | 1257 | * usb_hcd_giveback_urb - return URB from HCD to device driver |
1163 | * @hcd: host controller returning the URB | 1258 | * @hcd: host controller returning the URB |
1164 | * @urb: urb being returned to the USB device driver. | 1259 | * @urb: urb being returned to the USB device driver. |
1260 | * @status: completion status code for the URB. | ||
1165 | * Context: in_interrupt() | 1261 | * Context: in_interrupt() |
1166 | * | 1262 | * |
1167 | * This hands the URB from HCD to its USB device driver, using its | 1263 | * This hands the URB from HCD to its USB device driver, using its |
@@ -1169,14 +1265,27 @@ done: | |||
1169 | * (and is done using urb->hcpriv). It also released all HCD locks; | 1265 | * (and is done using urb->hcpriv). It also released all HCD locks; |
1170 | * the device driver won't cause problems if it frees, modifies, | 1266 | * the device driver won't cause problems if it frees, modifies, |
1171 | * or resubmits this URB. | 1267 | * or resubmits this URB. |
1268 | * | ||
1269 | * If @urb was unlinked, the value of @status will be overridden by | ||
1270 | * @urb->unlinked. Erroneous short transfers are detected in case | ||
1271 | * the HCD hasn't checked for them. | ||
1172 | */ | 1272 | */ |
1173 | void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) | 1273 | void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) |
1174 | { | 1274 | { |
1175 | urb_unlink(hcd, urb); | 1275 | urb->hcpriv = NULL; |
1176 | usbmon_urb_complete (&hcd->self, urb); | 1276 | if (unlikely(urb->unlinked)) |
1277 | status = urb->unlinked; | ||
1278 | else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && | ||
1279 | urb->actual_length < urb->transfer_buffer_length && | ||
1280 | !status)) | ||
1281 | status = -EREMOTEIO; | ||
1282 | |||
1283 | unmap_urb_for_dma(hcd, urb); | ||
1284 | usbmon_urb_complete(&hcd->self, urb, status); | ||
1177 | usb_unanchor_urb(urb); | 1285 | usb_unanchor_urb(urb); |
1178 | 1286 | ||
1179 | /* pass ownership to the completion handler */ | 1287 | /* pass ownership to the completion handler */ |
1288 | urb->status = status; | ||
1180 | urb->complete (urb); | 1289 | urb->complete (urb); |
1181 | atomic_dec (&urb->use_count); | 1290 | atomic_dec (&urb->use_count); |
1182 | if (unlikely (urb->reject)) | 1291 | if (unlikely (urb->reject)) |
@@ -1187,78 +1296,61 @@ EXPORT_SYMBOL (usb_hcd_giveback_urb); | |||
1187 | 1296 | ||
1188 | /*-------------------------------------------------------------------------*/ | 1297 | /*-------------------------------------------------------------------------*/ |
1189 | 1298 | ||
1190 | /* disables the endpoint: cancels any pending urbs, then synchronizes with | 1299 | /* Cancel all URBs pending on this endpoint and wait for the endpoint's |
1191 | * the hcd to make sure all endpoint state is gone from hardware, and then | 1300 | * queue to drain completely. The caller must first insure that no more |
1192 | * waits until the endpoint's queue is completely drained. use for | 1301 | * URBs can be submitted for this endpoint. |
1193 | * set_configuration, set_interface, driver removal, physical disconnect. | ||
1194 | * | ||
1195 | * example: a qh stored in ep->hcpriv, holding state related to endpoint | ||
1196 | * type, maxpacket size, toggle, halt status, and scheduling. | ||
1197 | */ | 1302 | */ |
1198 | void usb_hcd_endpoint_disable (struct usb_device *udev, | 1303 | void usb_hcd_flush_endpoint(struct usb_device *udev, |
1199 | struct usb_host_endpoint *ep) | 1304 | struct usb_host_endpoint *ep) |
1200 | { | 1305 | { |
1201 | struct usb_hcd *hcd; | 1306 | struct usb_hcd *hcd; |
1202 | struct urb *urb; | 1307 | struct urb *urb; |
1203 | 1308 | ||
1309 | if (!ep) | ||
1310 | return; | ||
1311 | might_sleep(); | ||
1204 | hcd = bus_to_hcd(udev->bus); | 1312 | hcd = bus_to_hcd(udev->bus); |
1205 | local_irq_disable (); | ||
1206 | 1313 | ||
1207 | /* ep is already gone from udev->ep_{in,out}[]; no more submits */ | 1314 | /* No more submits can occur */ |
1208 | rescan: | 1315 | rescan: |
1209 | spin_lock(&hcd_urb_list_lock); | 1316 | spin_lock_irq(&hcd_urb_list_lock); |
1210 | list_for_each_entry (urb, &ep->urb_list, urb_list) { | 1317 | list_for_each_entry (urb, &ep->urb_list, urb_list) { |
1211 | int tmp; | 1318 | int is_in; |
1212 | 1319 | ||
1213 | /* the urb may already have been unlinked */ | 1320 | if (urb->unlinked) |
1214 | if (urb->status != -EINPROGRESS) | ||
1215 | continue; | 1321 | continue; |
1216 | usb_get_urb (urb); | 1322 | usb_get_urb (urb); |
1323 | is_in = usb_urb_dir_in(urb); | ||
1217 | spin_unlock(&hcd_urb_list_lock); | 1324 | spin_unlock(&hcd_urb_list_lock); |
1218 | 1325 | ||
1219 | spin_lock (&urb->lock); | 1326 | /* kick hcd */ |
1220 | tmp = urb->status; | 1327 | unlink1(hcd, urb, -ESHUTDOWN); |
1221 | if (tmp == -EINPROGRESS) | 1328 | dev_dbg (hcd->self.controller, |
1222 | urb->status = -ESHUTDOWN; | 1329 | "shutdown urb %p ep%d%s%s\n", |
1223 | spin_unlock (&urb->lock); | 1330 | urb, usb_endpoint_num(&ep->desc), |
1224 | 1331 | is_in ? "in" : "out", | |
1225 | /* kick hcd unless it's already returning this */ | 1332 | ({ char *s; |
1226 | if (tmp == -EINPROGRESS) { | 1333 | |
1227 | tmp = urb->pipe; | 1334 | switch (usb_endpoint_type(&ep->desc)) { |
1228 | unlink1 (hcd, urb); | 1335 | case USB_ENDPOINT_XFER_CONTROL: |
1229 | dev_dbg (hcd->self.controller, | 1336 | s = ""; break; |
1230 | "shutdown urb %p pipe %08x ep%d%s%s\n", | 1337 | case USB_ENDPOINT_XFER_BULK: |
1231 | urb, tmp, usb_pipeendpoint (tmp), | 1338 | s = "-bulk"; break; |
1232 | (tmp & USB_DIR_IN) ? "in" : "out", | 1339 | case USB_ENDPOINT_XFER_INT: |
1233 | ({ char *s; \ | 1340 | s = "-intr"; break; |
1234 | switch (usb_pipetype (tmp)) { \ | 1341 | default: |
1235 | case PIPE_CONTROL: s = ""; break; \ | 1342 | s = "-iso"; break; |
1236 | case PIPE_BULK: s = "-bulk"; break; \ | 1343 | }; |
1237 | case PIPE_INTERRUPT: s = "-intr"; break; \ | 1344 | s; |
1238 | default: s = "-iso"; break; \ | 1345 | })); |
1239 | }; s;})); | ||
1240 | } | ||
1241 | usb_put_urb (urb); | 1346 | usb_put_urb (urb); |
1242 | 1347 | ||
1243 | /* list contents may have changed */ | 1348 | /* list contents may have changed */ |
1244 | goto rescan; | 1349 | goto rescan; |
1245 | } | 1350 | } |
1246 | spin_unlock(&hcd_urb_list_lock); | 1351 | spin_unlock_irq(&hcd_urb_list_lock); |
1247 | local_irq_enable (); | ||
1248 | |||
1249 | /* synchronize with the hardware, so old configuration state | ||
1250 | * clears out immediately (and will be freed). | ||
1251 | */ | ||
1252 | might_sleep (); | ||
1253 | if (hcd->driver->endpoint_disable) | ||
1254 | hcd->driver->endpoint_disable (hcd, ep); | ||
1255 | 1352 | ||
1256 | /* Wait until the endpoint queue is completely empty. Most HCDs | 1353 | /* Wait until the endpoint queue is completely empty */ |
1257 | * will have done this already in their endpoint_disable method, | ||
1258 | * but some might not. And there could be root-hub control URBs | ||
1259 | * still pending since they aren't affected by the HCDs' | ||
1260 | * endpoint_disable methods. | ||
1261 | */ | ||
1262 | while (!list_empty (&ep->urb_list)) { | 1354 | while (!list_empty (&ep->urb_list)) { |
1263 | spin_lock_irq(&hcd_urb_list_lock); | 1355 | spin_lock_irq(&hcd_urb_list_lock); |
1264 | 1356 | ||
@@ -1278,6 +1370,25 @@ rescan: | |||
1278 | } | 1370 | } |
1279 | } | 1371 | } |
1280 | 1372 | ||
1373 | /* Disables the endpoint: synchronizes with the hcd to make sure all | ||
1374 | * endpoint state is gone from hardware. usb_hcd_flush_endpoint() must | ||
1375 | * have been called previously. Use for set_configuration, set_interface, | ||
1376 | * driver removal, physical disconnect. | ||
1377 | * | ||
1378 | * example: a qh stored in ep->hcpriv, holding state related to endpoint | ||
1379 | * type, maxpacket size, toggle, halt status, and scheduling. | ||
1380 | */ | ||
1381 | void usb_hcd_disable_endpoint(struct usb_device *udev, | ||
1382 | struct usb_host_endpoint *ep) | ||
1383 | { | ||
1384 | struct usb_hcd *hcd; | ||
1385 | |||
1386 | might_sleep(); | ||
1387 | hcd = bus_to_hcd(udev->bus); | ||
1388 | if (hcd->driver->endpoint_disable) | ||
1389 | hcd->driver->endpoint_disable(hcd, ep); | ||
1390 | } | ||
1391 | |||
1281 | /*-------------------------------------------------------------------------*/ | 1392 | /*-------------------------------------------------------------------------*/ |
1282 | 1393 | ||
1283 | /* called in any context */ | 1394 | /* called in any context */ |
@@ -1525,7 +1636,6 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, | |||
1525 | hcd->driver = driver; | 1636 | hcd->driver = driver; |
1526 | hcd->product_desc = (driver->product_desc) ? driver->product_desc : | 1637 | hcd->product_desc = (driver->product_desc) ? driver->product_desc : |
1527 | "USB Host Controller"; | 1638 | "USB Host Controller"; |
1528 | |||
1529 | return hcd; | 1639 | return hcd; |
1530 | } | 1640 | } |
1531 | EXPORT_SYMBOL (usb_create_hcd); | 1641 | EXPORT_SYMBOL (usb_create_hcd); |
@@ -1570,6 +1680,7 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1570 | 1680 | ||
1571 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); | 1681 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); |
1572 | 1682 | ||
1683 | hcd->authorized_default = hcd->wireless? 0 : 1; | ||
1573 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 1684 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
1574 | 1685 | ||
1575 | /* HC is in reset state, but accessible. Now do the one-time init, | 1686 | /* HC is in reset state, but accessible. Now do the one-time init, |
@@ -1646,10 +1757,20 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1646 | if ((retval = register_root_hub(hcd)) != 0) | 1757 | if ((retval = register_root_hub(hcd)) != 0) |
1647 | goto err_register_root_hub; | 1758 | goto err_register_root_hub; |
1648 | 1759 | ||
1760 | retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group); | ||
1761 | if (retval < 0) { | ||
1762 | printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n", | ||
1763 | retval); | ||
1764 | goto error_create_attr_group; | ||
1765 | } | ||
1649 | if (hcd->uses_new_polling && hcd->poll_rh) | 1766 | if (hcd->uses_new_polling && hcd->poll_rh) |
1650 | usb_hcd_poll_rh_status(hcd); | 1767 | usb_hcd_poll_rh_status(hcd); |
1651 | return retval; | 1768 | return retval; |
1652 | 1769 | ||
1770 | error_create_attr_group: | ||
1771 | mutex_lock(&usb_bus_list_lock); | ||
1772 | usb_disconnect(&hcd->self.root_hub); | ||
1773 | mutex_unlock(&usb_bus_list_lock); | ||
1653 | err_register_root_hub: | 1774 | err_register_root_hub: |
1654 | hcd->driver->stop(hcd); | 1775 | hcd->driver->stop(hcd); |
1655 | err_hcd_driver_start: | 1776 | err_hcd_driver_start: |
@@ -1691,6 +1812,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
1691 | cancel_work_sync(&hcd->wakeup_work); | 1812 | cancel_work_sync(&hcd->wakeup_work); |
1692 | #endif | 1813 | #endif |
1693 | 1814 | ||
1815 | sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group); | ||
1694 | mutex_lock(&usb_bus_list_lock); | 1816 | mutex_lock(&usb_bus_list_lock); |
1695 | usb_disconnect(&hcd->self.root_hub); | 1817 | usb_disconnect(&hcd->self.root_hub); |
1696 | mutex_unlock(&usb_bus_list_lock); | 1818 | mutex_unlock(&usb_bus_list_lock); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index b5ebb73c2332..98e24194a4ab 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -19,6 +19,8 @@ | |||
19 | 19 | ||
20 | #ifdef __KERNEL__ | 20 | #ifdef __KERNEL__ |
21 | 21 | ||
22 | #include <linux/rwsem.h> | ||
23 | |||
22 | /* This file contains declarations of usbcore internals that are mostly | 24 | /* This file contains declarations of usbcore internals that are mostly |
23 | * used or exposed by Host Controller Drivers. | 25 | * used or exposed by Host Controller Drivers. |
24 | */ | 26 | */ |
@@ -51,6 +53,12 @@ | |||
51 | * | 53 | * |
52 | * Since "struct usb_bus" is so thin, you can't share much code in it. | 54 | * Since "struct usb_bus" is so thin, you can't share much code in it. |
53 | * This framework is a layer over that, and should be more sharable. | 55 | * This framework is a layer over that, and should be more sharable. |
56 | * | ||
57 | * @authorized_default: Specifies if new devices are authorized to | ||
58 | * connect by default or they require explicit | ||
59 | * user space authorization; this bit is settable | ||
60 | * through /sys/class/usb_host/X/authorized_default. | ||
61 | * For the rest is RO, so we don't lock to r/w it. | ||
54 | */ | 62 | */ |
55 | 63 | ||
56 | /*-------------------------------------------------------------------------*/ | 64 | /*-------------------------------------------------------------------------*/ |
@@ -90,6 +98,7 @@ struct usb_hcd { | |||
90 | unsigned poll_rh:1; /* poll for rh status? */ | 98 | unsigned poll_rh:1; /* poll for rh status? */ |
91 | unsigned poll_pending:1; /* status has changed? */ | 99 | unsigned poll_pending:1; /* status has changed? */ |
92 | unsigned wireless:1; /* Wireless USB HCD */ | 100 | unsigned wireless:1; /* Wireless USB HCD */ |
101 | unsigned authorized_default:1; | ||
93 | 102 | ||
94 | int irq; /* irq allocated */ | 103 | int irq; /* irq allocated */ |
95 | void __iomem *regs; /* device memory/io */ | 104 | void __iomem *regs; /* device memory/io */ |
@@ -182,11 +191,10 @@ struct hc_driver { | |||
182 | int (*get_frame_number) (struct usb_hcd *hcd); | 191 | int (*get_frame_number) (struct usb_hcd *hcd); |
183 | 192 | ||
184 | /* manage i/o requests, device state */ | 193 | /* manage i/o requests, device state */ |
185 | int (*urb_enqueue) (struct usb_hcd *hcd, | 194 | int (*urb_enqueue)(struct usb_hcd *hcd, |
186 | struct usb_host_endpoint *ep, | 195 | struct urb *urb, gfp_t mem_flags); |
187 | struct urb *urb, | 196 | int (*urb_dequeue)(struct usb_hcd *hcd, |
188 | gfp_t mem_flags); | 197 | struct urb *urb, int status); |
189 | int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb); | ||
190 | 198 | ||
191 | /* hw synch, freeing endpoint resources that urb_dequeue can't */ | 199 | /* hw synch, freeing endpoint resources that urb_dequeue can't */ |
192 | void (*endpoint_disable)(struct usb_hcd *hcd, | 200 | void (*endpoint_disable)(struct usb_hcd *hcd, |
@@ -204,10 +212,18 @@ struct hc_driver { | |||
204 | /* Needed only if port-change IRQs are level-triggered */ | 212 | /* Needed only if port-change IRQs are level-triggered */ |
205 | }; | 213 | }; |
206 | 214 | ||
215 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); | ||
216 | extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, | ||
217 | int status); | ||
218 | extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb); | ||
219 | |||
207 | extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags); | 220 | extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags); |
208 | extern int usb_hcd_unlink_urb (struct urb *urb, int status); | 221 | extern int usb_hcd_unlink_urb (struct urb *urb, int status); |
209 | extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb); | 222 | extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, |
210 | extern void usb_hcd_endpoint_disable (struct usb_device *udev, | 223 | int status); |
224 | extern void usb_hcd_flush_endpoint(struct usb_device *udev, | ||
225 | struct usb_host_endpoint *ep); | ||
226 | extern void usb_hcd_disable_endpoint(struct usb_device *udev, | ||
211 | struct usb_host_endpoint *ep); | 227 | struct usb_host_endpoint *ep); |
212 | extern int usb_hcd_get_frame_number (struct usb_device *udev); | 228 | extern int usb_hcd_get_frame_number (struct usb_device *udev); |
213 | 229 | ||
@@ -402,7 +418,7 @@ static inline void usbfs_cleanup(void) { } | |||
402 | struct usb_mon_operations { | 418 | struct usb_mon_operations { |
403 | void (*urb_submit)(struct usb_bus *bus, struct urb *urb); | 419 | void (*urb_submit)(struct usb_bus *bus, struct urb *urb); |
404 | void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err); | 420 | void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err); |
405 | void (*urb_complete)(struct usb_bus *bus, struct urb *urb); | 421 | void (*urb_complete)(struct usb_bus *bus, struct urb *urb, int status); |
406 | /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ | 422 | /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ |
407 | }; | 423 | }; |
408 | 424 | ||
@@ -421,10 +437,11 @@ static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, | |||
421 | (*mon_ops->urb_submit_error)(bus, urb, error); | 437 | (*mon_ops->urb_submit_error)(bus, urb, error); |
422 | } | 438 | } |
423 | 439 | ||
424 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) | 440 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, |
441 | int status) | ||
425 | { | 442 | { |
426 | if (bus->monitored) | 443 | if (bus->monitored) |
427 | (*mon_ops->urb_complete)(bus, urb); | 444 | (*mon_ops->urb_complete)(bus, urb, status); |
428 | } | 445 | } |
429 | 446 | ||
430 | int usb_mon_register(struct usb_mon_operations *ops); | 447 | int usb_mon_register(struct usb_mon_operations *ops); |
@@ -435,7 +452,8 @@ void usb_mon_deregister(void); | |||
435 | static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {} | 452 | static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {} |
436 | static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, | 453 | static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, |
437 | int error) {} | 454 | int error) {} |
438 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {} | 455 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, |
456 | int status) {} | ||
439 | 457 | ||
440 | #endif /* CONFIG_USB_MON */ | 458 | #endif /* CONFIG_USB_MON */ |
441 | 459 | ||
@@ -454,5 +472,9 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {} | |||
454 | : (in_interrupt () ? "in_interrupt" : "can sleep")) | 472 | : (in_interrupt () ? "in_interrupt" : "can sleep")) |
455 | 473 | ||
456 | 474 | ||
457 | #endif /* __KERNEL__ */ | 475 | /* This rwsem is for use only by the hub driver and ehci-hcd. |
476 | * Nobody else should touch it. | ||
477 | */ | ||
478 | extern struct rw_semaphore ehci_cf_port_reset_rwsem; | ||
458 | 479 | ||
480 | #endif /* __KERNEL__ */ | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index f7b337feb3ea..d20cb545a6e4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -125,6 +125,12 @@ MODULE_PARM_DESC(use_both_schemes, | |||
125 | "try the other device initialization scheme if the " | 125 | "try the other device initialization scheme if the " |
126 | "first one fails"); | 126 | "first one fails"); |
127 | 127 | ||
128 | /* Mutual exclusion for EHCI CF initialization. This interferes with | ||
129 | * port reset on some companion controllers. | ||
130 | */ | ||
131 | DECLARE_RWSEM(ehci_cf_port_reset_rwsem); | ||
132 | EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); | ||
133 | |||
128 | 134 | ||
129 | static inline char *portspeed(int portstatus) | 135 | static inline char *portspeed(int portstatus) |
130 | { | 136 | { |
@@ -347,11 +353,11 @@ void usb_kick_khubd(struct usb_device *hdev) | |||
347 | static void hub_irq(struct urb *urb) | 353 | static void hub_irq(struct urb *urb) |
348 | { | 354 | { |
349 | struct usb_hub *hub = urb->context; | 355 | struct usb_hub *hub = urb->context; |
350 | int status; | 356 | int status = urb->status; |
351 | int i; | 357 | int i; |
352 | unsigned long bits; | 358 | unsigned long bits; |
353 | 359 | ||
354 | switch (urb->status) { | 360 | switch (status) { |
355 | case -ENOENT: /* synchronous unlink */ | 361 | case -ENOENT: /* synchronous unlink */ |
356 | case -ECONNRESET: /* async unlink */ | 362 | case -ECONNRESET: /* async unlink */ |
357 | case -ESHUTDOWN: /* hardware going away */ | 363 | case -ESHUTDOWN: /* hardware going away */ |
@@ -359,10 +365,10 @@ static void hub_irq(struct urb *urb) | |||
359 | 365 | ||
360 | default: /* presumably an error */ | 366 | default: /* presumably an error */ |
361 | /* Cause a hub reset after 10 consecutive errors */ | 367 | /* Cause a hub reset after 10 consecutive errors */ |
362 | dev_dbg (hub->intfdev, "transfer --> %d\n", urb->status); | 368 | dev_dbg (hub->intfdev, "transfer --> %d\n", status); |
363 | if ((++hub->nerrors < 10) || hub->error) | 369 | if ((++hub->nerrors < 10) || hub->error) |
364 | goto resubmit; | 370 | goto resubmit; |
365 | hub->error = urb->status; | 371 | hub->error = status; |
366 | /* FALL THROUGH */ | 372 | /* FALL THROUGH */ |
367 | 373 | ||
368 | /* let khubd handle things */ | 374 | /* let khubd handle things */ |
@@ -1220,54 +1226,14 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1220 | #endif | 1226 | #endif |
1221 | 1227 | ||
1222 | /** | 1228 | /** |
1223 | * usb_new_device - perform initial device setup (usbcore-internal) | 1229 | * usb_configure_device_otg - FIXME (usbcore-internal) |
1224 | * @udev: newly addressed device (in ADDRESS state) | 1230 | * @udev: newly addressed device (in ADDRESS state) |
1225 | * | 1231 | * |
1226 | * This is called with devices which have been enumerated, but not yet | 1232 | * Do configuration for On-The-Go devices |
1227 | * configured. The device descriptor is available, but not descriptors | ||
1228 | * for any device configuration. The caller must have locked either | ||
1229 | * the parent hub (if udev is a normal device) or else the | ||
1230 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | ||
1231 | * udev has already been installed, but udev is not yet visible through | ||
1232 | * sysfs or other filesystem code. | ||
1233 | * | ||
1234 | * It will return if the device is configured properly or not. Zero if | ||
1235 | * the interface was registered with the driver core; else a negative | ||
1236 | * errno value. | ||
1237 | * | ||
1238 | * This call is synchronous, and may not be used in an interrupt context. | ||
1239 | * | ||
1240 | * Only the hub driver or root-hub registrar should ever call this. | ||
1241 | */ | 1233 | */ |
1242 | int usb_new_device(struct usb_device *udev) | 1234 | static int usb_configure_device_otg(struct usb_device *udev) |
1243 | { | 1235 | { |
1244 | int err; | 1236 | int err = 0; |
1245 | |||
1246 | /* Determine quirks */ | ||
1247 | usb_detect_quirks(udev); | ||
1248 | |||
1249 | err = usb_get_configuration(udev); | ||
1250 | if (err < 0) { | ||
1251 | dev_err(&udev->dev, "can't read configurations, error %d\n", | ||
1252 | err); | ||
1253 | goto fail; | ||
1254 | } | ||
1255 | |||
1256 | /* read the standard strings and cache them if present */ | ||
1257 | udev->product = usb_cache_string(udev, udev->descriptor.iProduct); | ||
1258 | udev->manufacturer = usb_cache_string(udev, | ||
1259 | udev->descriptor.iManufacturer); | ||
1260 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); | ||
1261 | |||
1262 | /* Tell the world! */ | ||
1263 | dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " | ||
1264 | "SerialNumber=%d\n", | ||
1265 | udev->descriptor.iManufacturer, | ||
1266 | udev->descriptor.iProduct, | ||
1267 | udev->descriptor.iSerialNumber); | ||
1268 | show_string(udev, "Product", udev->product); | ||
1269 | show_string(udev, "Manufacturer", udev->manufacturer); | ||
1270 | show_string(udev, "SerialNumber", udev->serial); | ||
1271 | 1237 | ||
1272 | #ifdef CONFIG_USB_OTG | 1238 | #ifdef CONFIG_USB_OTG |
1273 | /* | 1239 | /* |
@@ -1329,8 +1295,82 @@ int usb_new_device(struct usb_device *udev) | |||
1329 | err = -ENOTSUPP; | 1295 | err = -ENOTSUPP; |
1330 | goto fail; | 1296 | goto fail; |
1331 | } | 1297 | } |
1298 | fail: | ||
1332 | #endif | 1299 | #endif |
1300 | return err; | ||
1301 | } | ||
1302 | |||
1303 | |||
1304 | /** | ||
1305 | * usb_configure_device - Detect and probe device intfs/otg (usbcore-internal) | ||
1306 | * @udev: newly addressed device (in ADDRESS state) | ||
1307 | * | ||
1308 | * This is only called by usb_new_device() and usb_authorize_device() | ||
1309 | * and FIXME -- all comments that apply to them apply here wrt to | ||
1310 | * environment. | ||
1311 | * | ||
1312 | * If the device is WUSB and not authorized, we don't attempt to read | ||
1313 | * the string descriptors, as they will be errored out by the device | ||
1314 | * until it has been authorized. | ||
1315 | */ | ||
1316 | static int usb_configure_device(struct usb_device *udev) | ||
1317 | { | ||
1318 | int err; | ||
1333 | 1319 | ||
1320 | if (udev->config == NULL) { | ||
1321 | err = usb_get_configuration(udev); | ||
1322 | if (err < 0) { | ||
1323 | dev_err(&udev->dev, "can't read configurations, error %d\n", | ||
1324 | err); | ||
1325 | goto fail; | ||
1326 | } | ||
1327 | } | ||
1328 | if (udev->wusb == 1 && udev->authorized == 0) { | ||
1329 | udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1330 | udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1331 | udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1332 | } | ||
1333 | else { | ||
1334 | /* read the standard strings and cache them if present */ | ||
1335 | udev->product = usb_cache_string(udev, udev->descriptor.iProduct); | ||
1336 | udev->manufacturer = usb_cache_string(udev, | ||
1337 | udev->descriptor.iManufacturer); | ||
1338 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); | ||
1339 | } | ||
1340 | err = usb_configure_device_otg(udev); | ||
1341 | fail: | ||
1342 | return err; | ||
1343 | } | ||
1344 | |||
1345 | |||
1346 | /** | ||
1347 | * usb_new_device - perform initial device setup (usbcore-internal) | ||
1348 | * @udev: newly addressed device (in ADDRESS state) | ||
1349 | * | ||
1350 | * This is called with devices which have been enumerated, but not yet | ||
1351 | * configured. The device descriptor is available, but not descriptors | ||
1352 | * for any device configuration. The caller must have locked either | ||
1353 | * the parent hub (if udev is a normal device) or else the | ||
1354 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | ||
1355 | * udev has already been installed, but udev is not yet visible through | ||
1356 | * sysfs or other filesystem code. | ||
1357 | * | ||
1358 | * It will return if the device is configured properly or not. Zero if | ||
1359 | * the interface was registered with the driver core; else a negative | ||
1360 | * errno value. | ||
1361 | * | ||
1362 | * This call is synchronous, and may not be used in an interrupt context. | ||
1363 | * | ||
1364 | * Only the hub driver or root-hub registrar should ever call this. | ||
1365 | */ | ||
1366 | int usb_new_device(struct usb_device *udev) | ||
1367 | { | ||
1368 | int err; | ||
1369 | |||
1370 | usb_detect_quirks(udev); /* Determine quirks */ | ||
1371 | err = usb_configure_device(udev); /* detect & probe dev/intfs */ | ||
1372 | if (err < 0) | ||
1373 | goto fail; | ||
1334 | /* export the usbdev device-node for libusb */ | 1374 | /* export the usbdev device-node for libusb */ |
1335 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, | 1375 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, |
1336 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); | 1376 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); |
@@ -1346,19 +1386,106 @@ int usb_new_device(struct usb_device *udev) | |||
1346 | err = device_add(&udev->dev); | 1386 | err = device_add(&udev->dev); |
1347 | if (err) { | 1387 | if (err) { |
1348 | dev_err(&udev->dev, "can't device_add, error %d\n", err); | 1388 | dev_err(&udev->dev, "can't device_add, error %d\n", err); |
1349 | if (udev->parent) | ||
1350 | usb_autosuspend_device(udev->parent); | ||
1351 | goto fail; | 1389 | goto fail; |
1352 | } | 1390 | } |
1353 | 1391 | ||
1354 | exit: | 1392 | /* Tell the world! */ |
1393 | dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " | ||
1394 | "SerialNumber=%d\n", | ||
1395 | udev->descriptor.iManufacturer, | ||
1396 | udev->descriptor.iProduct, | ||
1397 | udev->descriptor.iSerialNumber); | ||
1398 | show_string(udev, "Product", udev->product); | ||
1399 | show_string(udev, "Manufacturer", udev->manufacturer); | ||
1400 | show_string(udev, "SerialNumber", udev->serial); | ||
1355 | return err; | 1401 | return err; |
1356 | 1402 | ||
1357 | fail: | 1403 | fail: |
1358 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); | 1404 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); |
1359 | goto exit; | 1405 | return err; |
1360 | } | 1406 | } |
1361 | 1407 | ||
1408 | |||
1409 | /** | ||
1410 | * Similar to usb_disconnect() | ||
1411 | * | ||
1412 | * We share a lock (that we have) with device_del(), so we need to | ||
1413 | * defer its call. | ||
1414 | */ | ||
1415 | int usb_deauthorize_device(struct usb_device *usb_dev) | ||
1416 | { | ||
1417 | unsigned cnt; | ||
1418 | usb_lock_device(usb_dev); | ||
1419 | if (usb_dev->authorized == 0) | ||
1420 | goto out_unauthorized; | ||
1421 | usb_dev->authorized = 0; | ||
1422 | usb_set_configuration(usb_dev, -1); | ||
1423 | usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1424 | usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1425 | usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1426 | kfree(usb_dev->config); | ||
1427 | usb_dev->config = NULL; | ||
1428 | for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++) | ||
1429 | kfree(usb_dev->rawdescriptors[cnt]); | ||
1430 | usb_dev->descriptor.bNumConfigurations = 0; | ||
1431 | kfree(usb_dev->rawdescriptors); | ||
1432 | out_unauthorized: | ||
1433 | usb_unlock_device(usb_dev); | ||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | |||
1438 | int usb_authorize_device(struct usb_device *usb_dev) | ||
1439 | { | ||
1440 | int result = 0, c; | ||
1441 | usb_lock_device(usb_dev); | ||
1442 | if (usb_dev->authorized == 1) | ||
1443 | goto out_authorized; | ||
1444 | kfree(usb_dev->product); | ||
1445 | usb_dev->product = NULL; | ||
1446 | kfree(usb_dev->manufacturer); | ||
1447 | usb_dev->manufacturer = NULL; | ||
1448 | kfree(usb_dev->serial); | ||
1449 | usb_dev->serial = NULL; | ||
1450 | result = usb_autoresume_device(usb_dev); | ||
1451 | if (result < 0) { | ||
1452 | dev_err(&usb_dev->dev, | ||
1453 | "can't autoresume for authorization: %d\n", result); | ||
1454 | goto error_autoresume; | ||
1455 | } | ||
1456 | result = usb_get_device_descriptor(usb_dev, sizeof(usb_dev->descriptor)); | ||
1457 | if (result < 0) { | ||
1458 | dev_err(&usb_dev->dev, "can't re-read device descriptor for " | ||
1459 | "authorization: %d\n", result); | ||
1460 | goto error_device_descriptor; | ||
1461 | } | ||
1462 | usb_dev->authorized = 1; | ||
1463 | result = usb_configure_device(usb_dev); | ||
1464 | if (result < 0) | ||
1465 | goto error_configure; | ||
1466 | /* Choose and set the configuration. This registers the interfaces | ||
1467 | * with the driver core and lets interface drivers bind to them. | ||
1468 | */ | ||
1469 | c = usb_choose_configuration(usb_dev); | ||
1470 | if (c >= 0) { | ||
1471 | result = usb_set_configuration(usb_dev, c); | ||
1472 | if (result) { | ||
1473 | dev_err(&usb_dev->dev, | ||
1474 | "can't set config #%d, error %d\n", c, result); | ||
1475 | /* This need not be fatal. The user can try to | ||
1476 | * set other configurations. */ | ||
1477 | } | ||
1478 | } | ||
1479 | dev_info(&usb_dev->dev, "authorized to connect\n"); | ||
1480 | error_configure: | ||
1481 | error_device_descriptor: | ||
1482 | error_autoresume: | ||
1483 | out_authorized: | ||
1484 | usb_unlock_device(usb_dev); // complements locktree | ||
1485 | return result; | ||
1486 | } | ||
1487 | |||
1488 | |||
1362 | static int hub_port_status(struct usb_hub *hub, int port1, | 1489 | static int hub_port_status(struct usb_hub *hub, int port1, |
1363 | u16 *status, u16 *change) | 1490 | u16 *status, u16 *change) |
1364 | { | 1491 | { |
@@ -1460,6 +1587,11 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
1460 | { | 1587 | { |
1461 | int i, status; | 1588 | int i, status; |
1462 | 1589 | ||
1590 | /* Block EHCI CF initialization during the port reset. | ||
1591 | * Some companion controllers don't like it when they mix. | ||
1592 | */ | ||
1593 | down_read(&ehci_cf_port_reset_rwsem); | ||
1594 | |||
1463 | /* Reset the port */ | 1595 | /* Reset the port */ |
1464 | for (i = 0; i < PORT_RESET_TRIES; i++) { | 1596 | for (i = 0; i < PORT_RESET_TRIES; i++) { |
1465 | status = set_port_feature(hub->hdev, | 1597 | status = set_port_feature(hub->hdev, |
@@ -1481,6 +1613,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
1481 | case 0: | 1613 | case 0: |
1482 | /* TRSTRCY = 10 ms; plus some extra */ | 1614 | /* TRSTRCY = 10 ms; plus some extra */ |
1483 | msleep(10 + 40); | 1615 | msleep(10 + 40); |
1616 | udev->devnum = 0; /* Device now at address 0 */ | ||
1484 | /* FALL THROUGH */ | 1617 | /* FALL THROUGH */ |
1485 | case -ENOTCONN: | 1618 | case -ENOTCONN: |
1486 | case -ENODEV: | 1619 | case -ENODEV: |
@@ -1490,7 +1623,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
1490 | usb_set_device_state(udev, status | 1623 | usb_set_device_state(udev, status |
1491 | ? USB_STATE_NOTATTACHED | 1624 | ? USB_STATE_NOTATTACHED |
1492 | : USB_STATE_DEFAULT); | 1625 | : USB_STATE_DEFAULT); |
1493 | return status; | 1626 | goto done; |
1494 | } | 1627 | } |
1495 | 1628 | ||
1496 | dev_dbg (hub->intfdev, | 1629 | dev_dbg (hub->intfdev, |
@@ -1503,6 +1636,8 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
1503 | "Cannot enable port %i. Maybe the USB cable is bad?\n", | 1636 | "Cannot enable port %i. Maybe the USB cable is bad?\n", |
1504 | port1); | 1637 | port1); |
1505 | 1638 | ||
1639 | done: | ||
1640 | up_read(&ehci_cf_port_reset_rwsem); | ||
1506 | return status; | 1641 | return status; |
1507 | } | 1642 | } |
1508 | 1643 | ||
@@ -1833,14 +1968,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | |||
1833 | struct usb_device *udev; | 1968 | struct usb_device *udev; |
1834 | 1969 | ||
1835 | udev = hdev->children [port1-1]; | 1970 | udev = hdev->children [port1-1]; |
1836 | if (udev && msg.event == PM_EVENT_SUSPEND && | 1971 | if (udev && udev->can_submit) { |
1837 | #ifdef CONFIG_USB_SUSPEND | ||
1838 | udev->state != USB_STATE_SUSPENDED | ||
1839 | #else | ||
1840 | udev->dev.power.power_state.event | ||
1841 | == PM_EVENT_ON | ||
1842 | #endif | ||
1843 | ) { | ||
1844 | if (!hdev->auto_pm) | 1972 | if (!hdev->auto_pm) |
1845 | dev_dbg(&intf->dev, "port %d nyet suspended\n", | 1973 | dev_dbg(&intf->dev, "port %d nyet suspended\n", |
1846 | port1); | 1974 | port1); |
@@ -1999,26 +2127,27 @@ static void ep0_reinit(struct usb_device *udev) | |||
1999 | { | 2127 | { |
2000 | usb_disable_endpoint(udev, 0 + USB_DIR_IN); | 2128 | usb_disable_endpoint(udev, 0 + USB_DIR_IN); |
2001 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT); | 2129 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT); |
2002 | udev->ep_in[0] = udev->ep_out[0] = &udev->ep0; | 2130 | usb_enable_endpoint(udev, &udev->ep0); |
2003 | } | 2131 | } |
2004 | 2132 | ||
2005 | #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) | 2133 | #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) |
2006 | #define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) | 2134 | #define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) |
2007 | 2135 | ||
2008 | static int hub_set_address(struct usb_device *udev) | 2136 | static int hub_set_address(struct usb_device *udev, int devnum) |
2009 | { | 2137 | { |
2010 | int retval; | 2138 | int retval; |
2011 | 2139 | ||
2012 | if (udev->devnum == 0) | 2140 | if (devnum <= 1) |
2013 | return -EINVAL; | 2141 | return -EINVAL; |
2014 | if (udev->state == USB_STATE_ADDRESS) | 2142 | if (udev->state == USB_STATE_ADDRESS) |
2015 | return 0; | 2143 | return 0; |
2016 | if (udev->state != USB_STATE_DEFAULT) | 2144 | if (udev->state != USB_STATE_DEFAULT) |
2017 | return -EINVAL; | 2145 | return -EINVAL; |
2018 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), | 2146 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), |
2019 | USB_REQ_SET_ADDRESS, 0, udev->devnum, 0, | 2147 | USB_REQ_SET_ADDRESS, 0, devnum, 0, |
2020 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 2148 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
2021 | if (retval == 0) { | 2149 | if (retval == 0) { |
2150 | udev->devnum = devnum; /* Device now using proper address */ | ||
2022 | usb_set_device_state(udev, USB_STATE_ADDRESS); | 2151 | usb_set_device_state(udev, USB_STATE_ADDRESS); |
2023 | ep0_reinit(udev); | 2152 | ep0_reinit(udev); |
2024 | } | 2153 | } |
@@ -2045,6 +2174,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2045 | unsigned delay = HUB_SHORT_RESET_TIME; | 2174 | unsigned delay = HUB_SHORT_RESET_TIME; |
2046 | enum usb_device_speed oldspeed = udev->speed; | 2175 | enum usb_device_speed oldspeed = udev->speed; |
2047 | char *speed, *type; | 2176 | char *speed, *type; |
2177 | int devnum = udev->devnum; | ||
2048 | 2178 | ||
2049 | /* root hub ports have a slightly longer reset period | 2179 | /* root hub ports have a slightly longer reset period |
2050 | * (from USB 2.0 spec, section 7.1.7.5) | 2180 | * (from USB 2.0 spec, section 7.1.7.5) |
@@ -2074,7 +2204,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2074 | goto fail; | 2204 | goto fail; |
2075 | } | 2205 | } |
2076 | oldspeed = udev->speed; | 2206 | oldspeed = udev->speed; |
2077 | 2207 | ||
2078 | /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... | 2208 | /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... |
2079 | * it's fixed size except for full speed devices. | 2209 | * it's fixed size except for full speed devices. |
2080 | * For Wireless USB devices, ep0 max packet is always 512 (tho | 2210 | * For Wireless USB devices, ep0 max packet is always 512 (tho |
@@ -2115,7 +2245,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2115 | dev_info (&udev->dev, | 2245 | dev_info (&udev->dev, |
2116 | "%s %s speed %sUSB device using %s and address %d\n", | 2246 | "%s %s speed %sUSB device using %s and address %d\n", |
2117 | (udev->config) ? "reset" : "new", speed, type, | 2247 | (udev->config) ? "reset" : "new", speed, type, |
2118 | udev->bus->controller->driver->name, udev->devnum); | 2248 | udev->bus->controller->driver->name, devnum); |
2119 | 2249 | ||
2120 | /* Set up TT records, if needed */ | 2250 | /* Set up TT records, if needed */ |
2121 | if (hdev->tt) { | 2251 | if (hdev->tt) { |
@@ -2202,7 +2332,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2202 | } | 2332 | } |
2203 | 2333 | ||
2204 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { | 2334 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { |
2205 | retval = hub_set_address(udev); | 2335 | retval = hub_set_address(udev, devnum); |
2206 | if (retval >= 0) | 2336 | if (retval >= 0) |
2207 | break; | 2337 | break; |
2208 | msleep(200); | 2338 | msleep(200); |
@@ -2210,7 +2340,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2210 | if (retval < 0) { | 2340 | if (retval < 0) { |
2211 | dev_err(&udev->dev, | 2341 | dev_err(&udev->dev, |
2212 | "device not accepting address %d, error %d\n", | 2342 | "device not accepting address %d, error %d\n", |
2213 | udev->devnum, retval); | 2343 | devnum, retval); |
2214 | goto fail; | 2344 | goto fail; |
2215 | } | 2345 | } |
2216 | 2346 | ||
@@ -2263,8 +2393,10 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2263 | retval = 0; | 2393 | retval = 0; |
2264 | 2394 | ||
2265 | fail: | 2395 | fail: |
2266 | if (retval) | 2396 | if (retval) { |
2267 | hub_port_disable(hub, port1, 0); | 2397 | hub_port_disable(hub, port1, 0); |
2398 | udev->devnum = devnum; /* for disconnect processing */ | ||
2399 | } | ||
2268 | mutex_unlock(&usb_address0_mutex); | 2400 | mutex_unlock(&usb_address0_mutex); |
2269 | return retval; | 2401 | return retval; |
2270 | } | 2402 | } |
@@ -2699,9 +2831,9 @@ static void hub_events(void) | |||
2699 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); | 2831 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); |
2700 | if (hubstatus & HUB_STATUS_LOCAL_POWER) | 2832 | if (hubstatus & HUB_STATUS_LOCAL_POWER) |
2701 | /* FIXME: Is this always true? */ | 2833 | /* FIXME: Is this always true? */ |
2702 | hub->limited_power = 0; | ||
2703 | else | ||
2704 | hub->limited_power = 1; | 2834 | hub->limited_power = 1; |
2835 | else | ||
2836 | hub->limited_power = 0; | ||
2705 | } | 2837 | } |
2706 | if (hubchange & HUB_CHANGE_OVERCURRENT) { | 2838 | if (hubchange & HUB_CHANGE_OVERCURRENT) { |
2707 | dev_dbg (hub_dev, "overcurrent change\n"); | 2839 | dev_dbg (hub_dev, "overcurrent change\n"); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index d8f7b089a8f0..c021af390372 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -59,8 +59,8 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) | |||
59 | dev_dbg(&urb->dev->dev, | 59 | dev_dbg(&urb->dev->dev, |
60 | "%s timed out on ep%d%s len=%d/%d\n", | 60 | "%s timed out on ep%d%s len=%d/%d\n", |
61 | current->comm, | 61 | current->comm, |
62 | usb_pipeendpoint(urb->pipe), | 62 | usb_endpoint_num(&urb->ep->desc), |
63 | usb_pipein(urb->pipe) ? "in" : "out", | 63 | usb_urb_dir_in(urb) ? "in" : "out", |
64 | urb->actual_length, | 64 | urb->actual_length, |
65 | urb->transfer_buffer_length); | 65 | urb->transfer_buffer_length); |
66 | } else | 66 | } else |
@@ -250,7 +250,8 @@ static void sg_clean (struct usb_sg_request *io) | |||
250 | io->urbs = NULL; | 250 | io->urbs = NULL; |
251 | } | 251 | } |
252 | if (io->dev->dev.dma_mask != NULL) | 252 | if (io->dev->dev.dma_mask != NULL) |
253 | usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents); | 253 | usb_buffer_unmap_sg (io->dev, usb_pipein(io->pipe), |
254 | io->sg, io->nents); | ||
254 | io->dev = NULL; | 255 | io->dev = NULL; |
255 | } | 256 | } |
256 | 257 | ||
@@ -278,8 +279,8 @@ static void sg_complete (struct urb *urb) | |||
278 | dev_err (io->dev->bus->controller, | 279 | dev_err (io->dev->bus->controller, |
279 | "dev %s ep%d%s scatterlist error %d/%d\n", | 280 | "dev %s ep%d%s scatterlist error %d/%d\n", |
280 | io->dev->devpath, | 281 | io->dev->devpath, |
281 | usb_pipeendpoint (urb->pipe), | 282 | usb_endpoint_num(&urb->ep->desc), |
282 | usb_pipein (urb->pipe) ? "in" : "out", | 283 | usb_urb_dir_in(urb) ? "in" : "out", |
283 | status, io->status); | 284 | status, io->status); |
284 | // BUG (); | 285 | // BUG (); |
285 | } | 286 | } |
@@ -379,7 +380,8 @@ int usb_sg_init ( | |||
379 | */ | 380 | */ |
380 | dma = (dev->dev.dma_mask != NULL); | 381 | dma = (dev->dev.dma_mask != NULL); |
381 | if (dma) | 382 | if (dma) |
382 | io->entries = usb_buffer_map_sg (dev, pipe, sg, nents); | 383 | io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe), |
384 | sg, nents); | ||
383 | else | 385 | else |
384 | io->entries = nents; | 386 | io->entries = nents; |
385 | 387 | ||
@@ -1013,8 +1015,11 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) | |||
1013 | ep = dev->ep_in[epnum]; | 1015 | ep = dev->ep_in[epnum]; |
1014 | dev->ep_in[epnum] = NULL; | 1016 | dev->ep_in[epnum] = NULL; |
1015 | } | 1017 | } |
1016 | if (ep && dev->bus) | 1018 | if (ep) { |
1017 | usb_hcd_endpoint_disable(dev, ep); | 1019 | ep->enabled = 0; |
1020 | usb_hcd_flush_endpoint(dev, ep); | ||
1021 | usb_hcd_disable_endpoint(dev, ep); | ||
1022 | } | ||
1018 | } | 1023 | } |
1019 | 1024 | ||
1020 | /** | 1025 | /** |
@@ -1096,23 +1101,21 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1096 | * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers. | 1101 | * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers. |
1097 | * For control endpoints, both the input and output sides are handled. | 1102 | * For control endpoints, both the input and output sides are handled. |
1098 | */ | 1103 | */ |
1099 | static void | 1104 | void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) |
1100 | usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) | ||
1101 | { | 1105 | { |
1102 | unsigned int epaddr = ep->desc.bEndpointAddress; | 1106 | int epnum = usb_endpoint_num(&ep->desc); |
1103 | unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; | 1107 | int is_out = usb_endpoint_dir_out(&ep->desc); |
1104 | int is_control; | 1108 | int is_control = usb_endpoint_xfer_control(&ep->desc); |
1105 | 1109 | ||
1106 | is_control = ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1110 | if (is_out || is_control) { |
1107 | == USB_ENDPOINT_XFER_CONTROL); | ||
1108 | if (usb_endpoint_out(epaddr) || is_control) { | ||
1109 | usb_settoggle(dev, epnum, 1, 0); | 1111 | usb_settoggle(dev, epnum, 1, 0); |
1110 | dev->ep_out[epnum] = ep; | 1112 | dev->ep_out[epnum] = ep; |
1111 | } | 1113 | } |
1112 | if (!usb_endpoint_out(epaddr) || is_control) { | 1114 | if (!is_out || is_control) { |
1113 | usb_settoggle(dev, epnum, 0, 0); | 1115 | usb_settoggle(dev, epnum, 0, 0); |
1114 | dev->ep_in[epnum] = ep; | 1116 | dev->ep_in[epnum] = ep; |
1115 | } | 1117 | } |
1118 | ep->enabled = 1; | ||
1116 | } | 1119 | } |
1117 | 1120 | ||
1118 | /* | 1121 | /* |
@@ -1171,6 +1174,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1171 | struct usb_host_interface *alt; | 1174 | struct usb_host_interface *alt; |
1172 | int ret; | 1175 | int ret; |
1173 | int manual = 0; | 1176 | int manual = 0; |
1177 | int changed; | ||
1174 | 1178 | ||
1175 | if (dev->state == USB_STATE_SUSPENDED) | 1179 | if (dev->state == USB_STATE_SUSPENDED) |
1176 | return -EHOSTUNREACH; | 1180 | return -EHOSTUNREACH; |
@@ -1210,7 +1214,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1210 | */ | 1214 | */ |
1211 | 1215 | ||
1212 | /* prevent submissions using previous endpoint settings */ | 1216 | /* prevent submissions using previous endpoint settings */ |
1213 | if (device_is_registered(&iface->dev)) | 1217 | changed = (iface->cur_altsetting != alt); |
1218 | if (changed && device_is_registered(&iface->dev)) | ||
1214 | usb_remove_sysfs_intf_files(iface); | 1219 | usb_remove_sysfs_intf_files(iface); |
1215 | usb_disable_interface(dev, iface); | 1220 | usb_disable_interface(dev, iface); |
1216 | 1221 | ||
@@ -1247,7 +1252,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1247 | * (Likewise, EP0 never "halts" on well designed devices.) | 1252 | * (Likewise, EP0 never "halts" on well designed devices.) |
1248 | */ | 1253 | */ |
1249 | usb_enable_interface(dev, iface); | 1254 | usb_enable_interface(dev, iface); |
1250 | if (device_is_registered(&iface->dev)) | 1255 | if (changed && device_is_registered(&iface->dev)) |
1251 | usb_create_sysfs_intf_files(iface); | 1256 | usb_create_sysfs_intf_files(iface); |
1252 | 1257 | ||
1253 | return 0; | 1258 | return 0; |
@@ -1328,7 +1333,7 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1328 | return 0; | 1333 | return 0; |
1329 | } | 1334 | } |
1330 | 1335 | ||
1331 | void usb_release_interface(struct device *dev) | 1336 | static void usb_release_interface(struct device *dev) |
1332 | { | 1337 | { |
1333 | struct usb_interface *intf = to_usb_interface(dev); | 1338 | struct usb_interface *intf = to_usb_interface(dev); |
1334 | struct usb_interface_cache *intfc = | 1339 | struct usb_interface_cache *intfc = |
@@ -1339,14 +1344,11 @@ void usb_release_interface(struct device *dev) | |||
1339 | } | 1344 | } |
1340 | 1345 | ||
1341 | #ifdef CONFIG_HOTPLUG | 1346 | #ifdef CONFIG_HOTPLUG |
1342 | static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | 1347 | static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) |
1343 | char *buffer, int buffer_size) | ||
1344 | { | 1348 | { |
1345 | struct usb_device *usb_dev; | 1349 | struct usb_device *usb_dev; |
1346 | struct usb_interface *intf; | 1350 | struct usb_interface *intf; |
1347 | struct usb_host_interface *alt; | 1351 | struct usb_host_interface *alt; |
1348 | int i = 0; | ||
1349 | int length = 0; | ||
1350 | 1352 | ||
1351 | if (!dev) | 1353 | if (!dev) |
1352 | return -ENODEV; | 1354 | return -ENODEV; |
@@ -1359,39 +1361,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | |||
1359 | alt = intf->cur_altsetting; | 1361 | alt = intf->cur_altsetting; |
1360 | 1362 | ||
1361 | #ifdef CONFIG_USB_DEVICEFS | 1363 | #ifdef CONFIG_USB_DEVICEFS |
1362 | if (add_uevent_var(envp, num_envp, &i, | 1364 | if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d", |
1363 | buffer, buffer_size, &length, | ||
1364 | "DEVICE=/proc/bus/usb/%03d/%03d", | ||
1365 | usb_dev->bus->busnum, usb_dev->devnum)) | 1365 | usb_dev->bus->busnum, usb_dev->devnum)) |
1366 | return -ENOMEM; | 1366 | return -ENOMEM; |
1367 | #endif | 1367 | #endif |
1368 | 1368 | ||
1369 | if (add_uevent_var(envp, num_envp, &i, | 1369 | if (add_uevent_var(env, "PRODUCT=%x/%x/%x", |
1370 | buffer, buffer_size, &length, | ||
1371 | "PRODUCT=%x/%x/%x", | ||
1372 | le16_to_cpu(usb_dev->descriptor.idVendor), | 1370 | le16_to_cpu(usb_dev->descriptor.idVendor), |
1373 | le16_to_cpu(usb_dev->descriptor.idProduct), | 1371 | le16_to_cpu(usb_dev->descriptor.idProduct), |
1374 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) | 1372 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) |
1375 | return -ENOMEM; | 1373 | return -ENOMEM; |
1376 | 1374 | ||
1377 | if (add_uevent_var(envp, num_envp, &i, | 1375 | if (add_uevent_var(env, "TYPE=%d/%d/%d", |
1378 | buffer, buffer_size, &length, | ||
1379 | "TYPE=%d/%d/%d", | ||
1380 | usb_dev->descriptor.bDeviceClass, | 1376 | usb_dev->descriptor.bDeviceClass, |
1381 | usb_dev->descriptor.bDeviceSubClass, | 1377 | usb_dev->descriptor.bDeviceSubClass, |
1382 | usb_dev->descriptor.bDeviceProtocol)) | 1378 | usb_dev->descriptor.bDeviceProtocol)) |
1383 | return -ENOMEM; | 1379 | return -ENOMEM; |
1384 | 1380 | ||
1385 | if (add_uevent_var(envp, num_envp, &i, | 1381 | if (add_uevent_var(env, "INTERFACE=%d/%d/%d", |
1386 | buffer, buffer_size, &length, | ||
1387 | "INTERFACE=%d/%d/%d", | ||
1388 | alt->desc.bInterfaceClass, | 1382 | alt->desc.bInterfaceClass, |
1389 | alt->desc.bInterfaceSubClass, | 1383 | alt->desc.bInterfaceSubClass, |
1390 | alt->desc.bInterfaceProtocol)) | 1384 | alt->desc.bInterfaceProtocol)) |
1391 | return -ENOMEM; | 1385 | return -ENOMEM; |
1392 | 1386 | ||
1393 | if (add_uevent_var(envp, num_envp, &i, | 1387 | if (add_uevent_var(env, |
1394 | buffer, buffer_size, &length, | ||
1395 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", | 1388 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", |
1396 | le16_to_cpu(usb_dev->descriptor.idVendor), | 1389 | le16_to_cpu(usb_dev->descriptor.idVendor), |
1397 | le16_to_cpu(usb_dev->descriptor.idProduct), | 1390 | le16_to_cpu(usb_dev->descriptor.idProduct), |
@@ -1404,14 +1397,12 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | |||
1404 | alt->desc.bInterfaceProtocol)) | 1397 | alt->desc.bInterfaceProtocol)) |
1405 | return -ENOMEM; | 1398 | return -ENOMEM; |
1406 | 1399 | ||
1407 | envp[i] = NULL; | ||
1408 | return 0; | 1400 | return 0; |
1409 | } | 1401 | } |
1410 | 1402 | ||
1411 | #else | 1403 | #else |
1412 | 1404 | ||
1413 | static int usb_if_uevent(struct device *dev, char **envp, | 1405 | static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) |
1414 | int num_envp, char *buffer, int buffer_size) | ||
1415 | { | 1406 | { |
1416 | return -ENODEV; | 1407 | return -ENODEV; |
1417 | } | 1408 | } |
@@ -1481,6 +1472,9 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev, | |||
1481 | * channels are available independently; and choosing between open | 1472 | * channels are available independently; and choosing between open |
1482 | * standard device protocols (like CDC) or proprietary ones. | 1473 | * standard device protocols (like CDC) or proprietary ones. |
1483 | * | 1474 | * |
1475 | * Note that a non-authorized device (dev->authorized == 0) will only | ||
1476 | * be put in unconfigured mode. | ||
1477 | * | ||
1484 | * Note that USB has an additional level of device configurability, | 1478 | * Note that USB has an additional level of device configurability, |
1485 | * associated with interfaces. That configurability is accessed using | 1479 | * associated with interfaces. That configurability is accessed using |
1486 | * usb_set_interface(). | 1480 | * usb_set_interface(). |
@@ -1502,7 +1496,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) | |||
1502 | struct usb_interface **new_interfaces = NULL; | 1496 | struct usb_interface **new_interfaces = NULL; |
1503 | int n, nintf; | 1497 | int n, nintf; |
1504 | 1498 | ||
1505 | if (configuration == -1) | 1499 | if (dev->authorized == 0 || configuration == -1) |
1506 | configuration = 0; | 1500 | configuration = 0; |
1507 | else { | 1501 | else { |
1508 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { | 1502 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index ebf3dc20110a..d42c561c75f1 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -32,52 +32,6 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
32 | { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, | 32 | { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, |
33 | /* HP 5300/5370C scanner */ | 33 | /* HP 5300/5370C scanner */ |
34 | { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, | 34 | { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, |
35 | /* Hewlett-Packard PhotoSmart 720 / PhotoSmart 935 (storage) */ | ||
36 | { USB_DEVICE(0x03f0, 0x4002), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
37 | |||
38 | /* SGS Thomson Microelectronics 4in1 card reader */ | ||
39 | { USB_DEVICE(0x0483, 0x0321), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
40 | |||
41 | /* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */ | ||
42 | { USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
43 | /* Benq S2W 3300U */ | ||
44 | { USB_DEVICE(0x04a5, 0x20b0), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
45 | /* Canon, Inc. CanoScan N1240U/LiDE30 */ | ||
46 | { USB_DEVICE(0x04a9, 0x220e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
47 | /* Canon, Inc. CanoScan N650U/N656U */ | ||
48 | { USB_DEVICE(0x04a9, 0x2206), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
49 | /* Canon, Inc. CanoScan 1220U */ | ||
50 | { USB_DEVICE(0x04a9, 0x2207), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
51 | /* Canon, Inc. CanoScan N670U/N676U/LiDE 20 */ | ||
52 | { USB_DEVICE(0x04a9, 0x220d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
53 | /* old Cannon scanner */ | ||
54 | { USB_DEVICE(0x04a9, 0x2220), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
55 | /* Seiko Epson Corp. Perfection 1200 */ | ||
56 | { USB_DEVICE(0x04b8, 0x0104), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
57 | /* Seiko Epson Corp. Perfection 660 */ | ||
58 | { USB_DEVICE(0x04b8, 0x0114), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
59 | /* Epson Perfection 1260 Photo */ | ||
60 | { USB_DEVICE(0x04b8, 0x011d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
61 | /* Seiko Epson Corp - Perfection 1670 */ | ||
62 | { USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
63 | /* EPSON Perfection 2480 */ | ||
64 | { USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
65 | /* Seiko Epson Corp.*/ | ||
66 | { USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
67 | /* Samsung ML-2010 printer */ | ||
68 | { USB_DEVICE(0x04e8, 0x326c), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
69 | /* Samsung ML-2510 Series printer */ | ||
70 | { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
71 | /* Elsa MicroLink 56k (V.250) */ | ||
72 | { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
73 | /* Ultima Electronics Corp.*/ | ||
74 | { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
75 | |||
76 | /* Genesys USB-to-IDE */ | ||
77 | { USB_DEVICE(0x0503, 0x0702), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
78 | |||
79 | /* USB Graphical LCD - EEH Datalink GmbH */ | ||
80 | { USB_DEVICE(0x060c, 0x04eb), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
81 | 35 | ||
82 | /* INTEL VALUE SSD */ | 36 | /* INTEL VALUE SSD */ |
83 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, | 37 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, |
@@ -85,44 +39,15 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
85 | /* M-Systems Flash Disk Pioneers */ | 39 | /* M-Systems Flash Disk Pioneers */ |
86 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 40 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
87 | 41 | ||
88 | /* Agfa Snapscan1212u */ | ||
89 | { USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
90 | /* Seagate RSS LLC */ | ||
91 | { USB_DEVICE(0x0bc2, 0x3000), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
92 | /* Umax [hex] Astra 3400U */ | ||
93 | { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
94 | |||
95 | /* Philips PSC805 audio device */ | 42 | /* Philips PSC805 audio device */ |
96 | { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, | 43 | { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, |
97 | 44 | ||
98 | /* Alcor multi-card reader */ | ||
99 | { USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
100 | |||
101 | /* Canon EOS 5D in PC Connection mode */ | ||
102 | { USB_DEVICE(0x04a9, 0x3101), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
103 | |||
104 | /* RIM Blackberry */ | ||
105 | { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
106 | { USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
107 | { USB_DEVICE(0x0fca, 0x0006), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
108 | |||
109 | /* Apple iPhone */ | ||
110 | { USB_DEVICE(0x05ac, 0x1290), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
111 | |||
112 | /* SKYMEDI USB_DRIVE */ | 45 | /* SKYMEDI USB_DRIVE */ |
113 | { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, | 46 | { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, |
114 | 47 | ||
115 | { } /* terminating entry must be last */ | 48 | { } /* terminating entry must be last */ |
116 | }; | 49 | }; |
117 | 50 | ||
118 | static void usb_autosuspend_quirk(struct usb_device *udev) | ||
119 | { | ||
120 | #ifdef CONFIG_USB_SUSPEND | ||
121 | /* disable autosuspend, but allow the user to re-enable it via sysfs */ | ||
122 | udev->autosuspend_disabled = 1; | ||
123 | #endif | ||
124 | } | ||
125 | |||
126 | static const struct usb_device_id *find_id(struct usb_device *udev) | 51 | static const struct usb_device_id *find_id(struct usb_device *udev) |
127 | { | 52 | { |
128 | const struct usb_device_id *id = usb_quirk_list; | 53 | const struct usb_device_id *id = usb_quirk_list; |
@@ -149,13 +74,9 @@ void usb_detect_quirks(struct usb_device *udev) | |||
149 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", | 74 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", |
150 | udev->quirks); | 75 | udev->quirks); |
151 | 76 | ||
152 | /* do any special quirk handling here if needed */ | ||
153 | if (udev->quirks & USB_QUIRK_NO_AUTOSUSPEND) | ||
154 | usb_autosuspend_quirk(udev); | ||
155 | |||
156 | /* By default, disable autosuspend for all non-hubs */ | 77 | /* By default, disable autosuspend for all non-hubs */ |
157 | #ifdef CONFIG_USB_SUSPEND | 78 | #ifdef CONFIG_USB_SUSPEND |
158 | if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) | 79 | if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) |
159 | udev->autosuspend_delay = -1; | 80 | udev->autosuspend_disabled = 1; |
160 | #endif | 81 | #endif |
161 | } | 82 | } |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 2ab222be8fd1..b04afd06e502 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -169,6 +169,16 @@ show_quirks(struct device *dev, struct device_attribute *attr, char *buf) | |||
169 | } | 169 | } |
170 | static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); | 170 | static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); |
171 | 171 | ||
172 | static ssize_t | ||
173 | show_urbnum(struct device *dev, struct device_attribute *attr, char *buf) | ||
174 | { | ||
175 | struct usb_device *udev; | ||
176 | |||
177 | udev = to_usb_device(dev); | ||
178 | return sprintf(buf, "%d\n", atomic_read(&udev->urbnum)); | ||
179 | } | ||
180 | static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL); | ||
181 | |||
172 | 182 | ||
173 | #if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND) | 183 | #if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND) |
174 | static const char power_group[] = "power"; | 184 | static const char power_group[] = "power"; |
@@ -413,6 +423,44 @@ usb_descriptor_attr(bDeviceProtocol, "%02x\n") | |||
413 | usb_descriptor_attr(bNumConfigurations, "%d\n") | 423 | usb_descriptor_attr(bNumConfigurations, "%d\n") |
414 | usb_descriptor_attr(bMaxPacketSize0, "%d\n") | 424 | usb_descriptor_attr(bMaxPacketSize0, "%d\n") |
415 | 425 | ||
426 | |||
427 | |||
428 | /* show if the device is authorized (1) or not (0) */ | ||
429 | static ssize_t usb_dev_authorized_show(struct device *dev, | ||
430 | struct device_attribute *attr, | ||
431 | char *buf) | ||
432 | { | ||
433 | struct usb_device *usb_dev = to_usb_device(dev); | ||
434 | return snprintf(buf, PAGE_SIZE, "%u\n", usb_dev->authorized); | ||
435 | } | ||
436 | |||
437 | |||
438 | /* | ||
439 | * Authorize a device to be used in the system | ||
440 | * | ||
441 | * Writing a 0 deauthorizes the device, writing a 1 authorizes it. | ||
442 | */ | ||
443 | static ssize_t usb_dev_authorized_store(struct device *dev, | ||
444 | struct device_attribute *attr, | ||
445 | const char *buf, size_t size) | ||
446 | { | ||
447 | ssize_t result; | ||
448 | struct usb_device *usb_dev = to_usb_device(dev); | ||
449 | unsigned val; | ||
450 | result = sscanf(buf, "%u\n", &val); | ||
451 | if (result != 1) | ||
452 | result = -EINVAL; | ||
453 | else if (val == 0) | ||
454 | result = usb_deauthorize_device(usb_dev); | ||
455 | else | ||
456 | result = usb_authorize_device(usb_dev); | ||
457 | return result < 0? result : size; | ||
458 | } | ||
459 | |||
460 | static DEVICE_ATTR(authorized, 0644, | ||
461 | usb_dev_authorized_show, usb_dev_authorized_store); | ||
462 | |||
463 | |||
416 | static struct attribute *dev_attrs[] = { | 464 | static struct attribute *dev_attrs[] = { |
417 | /* current configuration's attributes */ | 465 | /* current configuration's attributes */ |
418 | &dev_attr_configuration.attr, | 466 | &dev_attr_configuration.attr, |
@@ -420,6 +468,7 @@ static struct attribute *dev_attrs[] = { | |||
420 | &dev_attr_bConfigurationValue.attr, | 468 | &dev_attr_bConfigurationValue.attr, |
421 | &dev_attr_bmAttributes.attr, | 469 | &dev_attr_bmAttributes.attr, |
422 | &dev_attr_bMaxPower.attr, | 470 | &dev_attr_bMaxPower.attr, |
471 | &dev_attr_urbnum.attr, | ||
423 | /* device attributes */ | 472 | /* device attributes */ |
424 | &dev_attr_idVendor.attr, | 473 | &dev_attr_idVendor.attr, |
425 | &dev_attr_idProduct.attr, | 474 | &dev_attr_idProduct.attr, |
@@ -435,6 +484,7 @@ static struct attribute *dev_attrs[] = { | |||
435 | &dev_attr_version.attr, | 484 | &dev_attr_version.attr, |
436 | &dev_attr_maxchild.attr, | 485 | &dev_attr_maxchild.attr, |
437 | &dev_attr_quirks.attr, | 486 | &dev_attr_quirks.attr, |
487 | &dev_attr_authorized.attr, | ||
438 | NULL, | 488 | NULL, |
439 | }; | 489 | }; |
440 | static struct attribute_group dev_attr_grp = { | 490 | static struct attribute_group dev_attr_grp = { |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index be630228461c..c20c03aaf012 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/bitops.h> | 3 | #include <linux/bitops.h> |
4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/log2.h> | ||
6 | #include <linux/usb.h> | 7 | #include <linux/usb.h> |
7 | #include <linux/wait.h> | 8 | #include <linux/wait.h> |
8 | #include "hcd.h" | 9 | #include "hcd.h" |
@@ -38,7 +39,6 @@ void usb_init_urb(struct urb *urb) | |||
38 | if (urb) { | 39 | if (urb) { |
39 | memset(urb, 0, sizeof(*urb)); | 40 | memset(urb, 0, sizeof(*urb)); |
40 | kref_init(&urb->kref); | 41 | kref_init(&urb->kref); |
41 | spin_lock_init(&urb->lock); | ||
42 | INIT_LIST_HEAD(&urb->anchor_list); | 42 | INIT_LIST_HEAD(&urb->anchor_list); |
43 | } | 43 | } |
44 | } | 44 | } |
@@ -277,44 +277,58 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); | |||
277 | */ | 277 | */ |
278 | int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | 278 | int usb_submit_urb(struct urb *urb, gfp_t mem_flags) |
279 | { | 279 | { |
280 | int pipe, temp, max; | 280 | int xfertype, max; |
281 | struct usb_device *dev; | 281 | struct usb_device *dev; |
282 | int is_out; | 282 | struct usb_host_endpoint *ep; |
283 | int is_out; | ||
283 | 284 | ||
284 | if (!urb || urb->hcpriv || !urb->complete) | 285 | if (!urb || urb->hcpriv || !urb->complete) |
285 | return -EINVAL; | 286 | return -EINVAL; |
286 | if (!(dev = urb->dev) || | 287 | if (!(dev = urb->dev) || dev->state < USB_STATE_DEFAULT) |
287 | (dev->state < USB_STATE_DEFAULT) || | ||
288 | (!dev->bus) || (dev->devnum <= 0)) | ||
289 | return -ENODEV; | 288 | return -ENODEV; |
290 | if (dev->bus->controller->power.power_state.event != PM_EVENT_ON | ||
291 | || dev->state == USB_STATE_SUSPENDED) | ||
292 | return -EHOSTUNREACH; | ||
293 | 289 | ||
290 | /* For now, get the endpoint from the pipe. Eventually drivers | ||
291 | * will be required to set urb->ep directly and we will eliminate | ||
292 | * urb->pipe. | ||
293 | */ | ||
294 | ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out) | ||
295 | [usb_pipeendpoint(urb->pipe)]; | ||
296 | if (!ep) | ||
297 | return -ENOENT; | ||
298 | |||
299 | urb->ep = ep; | ||
294 | urb->status = -EINPROGRESS; | 300 | urb->status = -EINPROGRESS; |
295 | urb->actual_length = 0; | 301 | urb->actual_length = 0; |
296 | 302 | ||
297 | /* Lots of sanity checks, so HCDs can rely on clean data | 303 | /* Lots of sanity checks, so HCDs can rely on clean data |
298 | * and don't need to duplicate tests | 304 | * and don't need to duplicate tests |
299 | */ | 305 | */ |
300 | pipe = urb->pipe; | 306 | xfertype = usb_endpoint_type(&ep->desc); |
301 | temp = usb_pipetype(pipe); | 307 | if (xfertype == USB_ENDPOINT_XFER_CONTROL) { |
302 | is_out = usb_pipeout(pipe); | 308 | struct usb_ctrlrequest *setup = |
309 | (struct usb_ctrlrequest *) urb->setup_packet; | ||
310 | |||
311 | if (!setup) | ||
312 | return -ENOEXEC; | ||
313 | is_out = !(setup->bRequestType & USB_DIR_IN) || | ||
314 | !setup->wLength; | ||
315 | } else { | ||
316 | is_out = usb_endpoint_dir_out(&ep->desc); | ||
317 | } | ||
303 | 318 | ||
304 | if (!usb_pipecontrol(pipe) && dev->state < USB_STATE_CONFIGURED) | 319 | /* Cache the direction for later use */ |
305 | return -ENODEV; | 320 | urb->transfer_flags = (urb->transfer_flags & ~URB_DIR_MASK) | |
321 | (is_out ? URB_DIR_OUT : URB_DIR_IN); | ||
306 | 322 | ||
307 | /* FIXME there should be a sharable lock protecting us against | 323 | if (xfertype != USB_ENDPOINT_XFER_CONTROL && |
308 | * config/altsetting changes and disconnects, kicking in here. | 324 | dev->state < USB_STATE_CONFIGURED) |
309 | * (here == before maxpacket, and eventually endpoint type, | 325 | return -ENODEV; |
310 | * checks get made.) | ||
311 | */ | ||
312 | 326 | ||
313 | max = usb_maxpacket(dev, pipe, is_out); | 327 | max = le16_to_cpu(ep->desc.wMaxPacketSize); |
314 | if (max <= 0) { | 328 | if (max <= 0) { |
315 | dev_dbg(&dev->dev, | 329 | dev_dbg(&dev->dev, |
316 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", | 330 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", |
317 | usb_pipeendpoint(pipe), is_out ? "out" : "in", | 331 | usb_endpoint_num(&ep->desc), is_out ? "out" : "in", |
318 | __FUNCTION__, max); | 332 | __FUNCTION__, max); |
319 | return -EMSGSIZE; | 333 | return -EMSGSIZE; |
320 | } | 334 | } |
@@ -323,7 +337,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
323 | * but drivers only control those sizes for ISO. | 337 | * but drivers only control those sizes for ISO. |
324 | * while we're checking, initialize return status. | 338 | * while we're checking, initialize return status. |
325 | */ | 339 | */ |
326 | if (temp == PIPE_ISOCHRONOUS) { | 340 | if (xfertype == USB_ENDPOINT_XFER_ISOC) { |
327 | int n, len; | 341 | int n, len; |
328 | 342 | ||
329 | /* "high bandwidth" mode, 1-3 packets/uframe? */ | 343 | /* "high bandwidth" mode, 1-3 packets/uframe? */ |
@@ -358,20 +372,20 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
358 | 372 | ||
359 | /* enforce simple/standard policy */ | 373 | /* enforce simple/standard policy */ |
360 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | | 374 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | |
361 | URB_NO_INTERRUPT); | 375 | URB_NO_INTERRUPT | URB_DIR_MASK); |
362 | switch (temp) { | 376 | switch (xfertype) { |
363 | case PIPE_BULK: | 377 | case USB_ENDPOINT_XFER_BULK: |
364 | if (is_out) | 378 | if (is_out) |
365 | allowed |= URB_ZERO_PACKET; | 379 | allowed |= URB_ZERO_PACKET; |
366 | /* FALLTHROUGH */ | 380 | /* FALLTHROUGH */ |
367 | case PIPE_CONTROL: | 381 | case USB_ENDPOINT_XFER_CONTROL: |
368 | allowed |= URB_NO_FSBR; /* only affects UHCI */ | 382 | allowed |= URB_NO_FSBR; /* only affects UHCI */ |
369 | /* FALLTHROUGH */ | 383 | /* FALLTHROUGH */ |
370 | default: /* all non-iso endpoints */ | 384 | default: /* all non-iso endpoints */ |
371 | if (!is_out) | 385 | if (!is_out) |
372 | allowed |= URB_SHORT_NOT_OK; | 386 | allowed |= URB_SHORT_NOT_OK; |
373 | break; | 387 | break; |
374 | case PIPE_ISOCHRONOUS: | 388 | case USB_ENDPOINT_XFER_ISOC: |
375 | allowed |= URB_ISO_ASAP; | 389 | allowed |= URB_ISO_ASAP; |
376 | break; | 390 | break; |
377 | } | 391 | } |
@@ -393,9 +407,9 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
393 | * supports different values... this uses EHCI/UHCI defaults (and | 407 | * supports different values... this uses EHCI/UHCI defaults (and |
394 | * EHCI can use smaller non-default values). | 408 | * EHCI can use smaller non-default values). |
395 | */ | 409 | */ |
396 | switch (temp) { | 410 | switch (xfertype) { |
397 | case PIPE_ISOCHRONOUS: | 411 | case USB_ENDPOINT_XFER_ISOC: |
398 | case PIPE_INTERRUPT: | 412 | case USB_ENDPOINT_XFER_INT: |
399 | /* too small? */ | 413 | /* too small? */ |
400 | if (urb->interval <= 0) | 414 | if (urb->interval <= 0) |
401 | return -EINVAL; | 415 | return -EINVAL; |
@@ -405,29 +419,27 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
405 | // NOTE usb handles 2^15 | 419 | // NOTE usb handles 2^15 |
406 | if (urb->interval > (1024 * 8)) | 420 | if (urb->interval > (1024 * 8)) |
407 | urb->interval = 1024 * 8; | 421 | urb->interval = 1024 * 8; |
408 | temp = 1024 * 8; | 422 | max = 1024 * 8; |
409 | break; | 423 | break; |
410 | case USB_SPEED_FULL: /* units are frames/msec */ | 424 | case USB_SPEED_FULL: /* units are frames/msec */ |
411 | case USB_SPEED_LOW: | 425 | case USB_SPEED_LOW: |
412 | if (temp == PIPE_INTERRUPT) { | 426 | if (xfertype == USB_ENDPOINT_XFER_INT) { |
413 | if (urb->interval > 255) | 427 | if (urb->interval > 255) |
414 | return -EINVAL; | 428 | return -EINVAL; |
415 | // NOTE ohci only handles up to 32 | 429 | // NOTE ohci only handles up to 32 |
416 | temp = 128; | 430 | max = 128; |
417 | } else { | 431 | } else { |
418 | if (urb->interval > 1024) | 432 | if (urb->interval > 1024) |
419 | urb->interval = 1024; | 433 | urb->interval = 1024; |
420 | // NOTE usb and ohci handle up to 2^15 | 434 | // NOTE usb and ohci handle up to 2^15 |
421 | temp = 1024; | 435 | max = 1024; |
422 | } | 436 | } |
423 | break; | 437 | break; |
424 | default: | 438 | default: |
425 | return -EINVAL; | 439 | return -EINVAL; |
426 | } | 440 | } |
427 | /* power of two? */ | 441 | /* Round down to a power of 2, no more than max */ |
428 | while (temp > urb->interval) | 442 | urb->interval = min(max, 1 << ilog2(urb->interval)); |
429 | temp >>= 1; | ||
430 | urb->interval = temp; | ||
431 | } | 443 | } |
432 | 444 | ||
433 | return usb_hcd_submit_urb(urb, mem_flags); | 445 | return usb_hcd_submit_urb(urb, mem_flags); |
@@ -496,8 +508,10 @@ int usb_unlink_urb(struct urb *urb) | |||
496 | { | 508 | { |
497 | if (!urb) | 509 | if (!urb) |
498 | return -EINVAL; | 510 | return -EINVAL; |
499 | if (!(urb->dev && urb->dev->bus)) | 511 | if (!urb->dev) |
500 | return -ENODEV; | 512 | return -ENODEV; |
513 | if (!urb->ep) | ||
514 | return -EIDRM; | ||
501 | return usb_hcd_unlink_urb(urb, -ECONNRESET); | 515 | return usb_hcd_unlink_urb(urb, -ECONNRESET); |
502 | } | 516 | } |
503 | 517 | ||
@@ -523,19 +537,21 @@ int usb_unlink_urb(struct urb *urb) | |||
523 | */ | 537 | */ |
524 | void usb_kill_urb(struct urb *urb) | 538 | void usb_kill_urb(struct urb *urb) |
525 | { | 539 | { |
540 | static DEFINE_MUTEX(reject_mutex); | ||
541 | |||
526 | might_sleep(); | 542 | might_sleep(); |
527 | if (!(urb && urb->dev && urb->dev->bus)) | 543 | if (!(urb && urb->dev && urb->ep)) |
528 | return; | 544 | return; |
529 | spin_lock_irq(&urb->lock); | 545 | mutex_lock(&reject_mutex); |
530 | ++urb->reject; | 546 | ++urb->reject; |
531 | spin_unlock_irq(&urb->lock); | 547 | mutex_unlock(&reject_mutex); |
532 | 548 | ||
533 | usb_hcd_unlink_urb(urb, -ENOENT); | 549 | usb_hcd_unlink_urb(urb, -ENOENT); |
534 | wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); | 550 | wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); |
535 | 551 | ||
536 | spin_lock_irq(&urb->lock); | 552 | mutex_lock(&reject_mutex); |
537 | --urb->reject; | 553 | --urb->reject; |
538 | spin_unlock_irq(&urb->lock); | 554 | mutex_unlock(&reject_mutex); |
539 | } | 555 | } |
540 | 556 | ||
541 | /** | 557 | /** |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 0fee5c66fd64..c99938d5f78e 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -223,6 +223,15 @@ static void ksuspend_usb_cleanup(void) | |||
223 | 223 | ||
224 | #endif /* CONFIG_PM */ | 224 | #endif /* CONFIG_PM */ |
225 | 225 | ||
226 | |||
227 | /* Returns 1 if @usb_bus is WUSB, 0 otherwise */ | ||
228 | static unsigned usb_bus_is_wusb(struct usb_bus *bus) | ||
229 | { | ||
230 | struct usb_hcd *hcd = container_of(bus, struct usb_hcd, self); | ||
231 | return hcd->wireless; | ||
232 | } | ||
233 | |||
234 | |||
226 | /** | 235 | /** |
227 | * usb_alloc_dev - usb device constructor (usbcore-internal) | 236 | * usb_alloc_dev - usb device constructor (usbcore-internal) |
228 | * @parent: hub to which device is connected; null to allocate a root hub | 237 | * @parent: hub to which device is connected; null to allocate a root hub |
@@ -239,6 +248,8 @@ struct usb_device * | |||
239 | usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | 248 | usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) |
240 | { | 249 | { |
241 | struct usb_device *dev; | 250 | struct usb_device *dev; |
251 | struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self); | ||
252 | unsigned root_hub = 0; | ||
242 | 253 | ||
243 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 254 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
244 | if (!dev) | 255 | if (!dev) |
@@ -255,12 +266,14 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
255 | dev->dev.dma_mask = bus->controller->dma_mask; | 266 | dev->dev.dma_mask = bus->controller->dma_mask; |
256 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); | 267 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); |
257 | dev->state = USB_STATE_ATTACHED; | 268 | dev->state = USB_STATE_ATTACHED; |
269 | atomic_set(&dev->urbnum, 0); | ||
258 | 270 | ||
259 | INIT_LIST_HEAD(&dev->ep0.urb_list); | 271 | INIT_LIST_HEAD(&dev->ep0.urb_list); |
260 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; | 272 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; |
261 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; | 273 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; |
262 | /* ep0 maxpacket comes later, from device descriptor */ | 274 | /* ep0 maxpacket comes later, from device descriptor */ |
263 | dev->ep_in[0] = dev->ep_out[0] = &dev->ep0; | 275 | usb_enable_endpoint(dev, &dev->ep0); |
276 | dev->can_submit = 1; | ||
264 | 277 | ||
265 | /* Save readable and stable topology id, distinguishing devices | 278 | /* Save readable and stable topology id, distinguishing devices |
266 | * by location for diagnostics, tools, driver model, etc. The | 279 | * by location for diagnostics, tools, driver model, etc. The |
@@ -275,6 +288,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
275 | 288 | ||
276 | dev->dev.parent = bus->controller; | 289 | dev->dev.parent = bus->controller; |
277 | sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum); | 290 | sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum); |
291 | root_hub = 1; | ||
278 | } else { | 292 | } else { |
279 | /* match any labeling on the hubs; it's one-based */ | 293 | /* match any labeling on the hubs; it's one-based */ |
280 | if (parent->devpath[0] == '0') | 294 | if (parent->devpath[0] == '0') |
@@ -301,6 +315,12 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
301 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); | 315 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); |
302 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; | 316 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; |
303 | #endif | 317 | #endif |
318 | if (root_hub) /* Root hub always ok [and always wired] */ | ||
319 | dev->authorized = 1; | ||
320 | else { | ||
321 | dev->authorized = usb_hcd->authorized_default; | ||
322 | dev->wusb = usb_bus_is_wusb(bus)? 1 : 0; | ||
323 | } | ||
304 | return dev; | 324 | return dev; |
305 | } | 325 | } |
306 | 326 | ||
@@ -748,7 +768,7 @@ void usb_buffer_unmap(struct urb *urb) | |||
748 | /** | 768 | /** |
749 | * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint | 769 | * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint |
750 | * @dev: device to which the scatterlist will be mapped | 770 | * @dev: device to which the scatterlist will be mapped |
751 | * @pipe: endpoint defining the mapping direction | 771 | * @is_in: mapping transfer direction |
752 | * @sg: the scatterlist to map | 772 | * @sg: the scatterlist to map |
753 | * @nents: the number of entries in the scatterlist | 773 | * @nents: the number of entries in the scatterlist |
754 | * | 774 | * |
@@ -771,14 +791,13 @@ void usb_buffer_unmap(struct urb *urb) | |||
771 | * | 791 | * |
772 | * Reverse the effect of this call with usb_buffer_unmap_sg(). | 792 | * Reverse the effect of this call with usb_buffer_unmap_sg(). |
773 | */ | 793 | */ |
774 | int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | 794 | int usb_buffer_map_sg(const struct usb_device *dev, int is_in, |
775 | struct scatterlist *sg, int nents) | 795 | struct scatterlist *sg, int nents) |
776 | { | 796 | { |
777 | struct usb_bus *bus; | 797 | struct usb_bus *bus; |
778 | struct device *controller; | 798 | struct device *controller; |
779 | 799 | ||
780 | if (!dev | 800 | if (!dev |
781 | || usb_pipecontrol(pipe) | ||
782 | || !(bus = dev->bus) | 801 | || !(bus = dev->bus) |
783 | || !(controller = bus->controller) | 802 | || !(controller = bus->controller) |
784 | || !controller->dma_mask) | 803 | || !controller->dma_mask) |
@@ -786,7 +805,7 @@ int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | |||
786 | 805 | ||
787 | // FIXME generic api broken like pci, can't report errors | 806 | // FIXME generic api broken like pci, can't report errors |
788 | return dma_map_sg(controller, sg, nents, | 807 | return dma_map_sg(controller, sg, nents, |
789 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 808 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
790 | } | 809 | } |
791 | 810 | ||
792 | /* XXX DISABLED, no users currently. If you wish to re-enable this | 811 | /* XXX DISABLED, no users currently. If you wish to re-enable this |
@@ -799,14 +818,14 @@ int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | |||
799 | /** | 818 | /** |
800 | * usb_buffer_dmasync_sg - synchronize DMA and CPU view of scatterlist buffer(s) | 819 | * usb_buffer_dmasync_sg - synchronize DMA and CPU view of scatterlist buffer(s) |
801 | * @dev: device to which the scatterlist will be mapped | 820 | * @dev: device to which the scatterlist will be mapped |
802 | * @pipe: endpoint defining the mapping direction | 821 | * @is_in: mapping transfer direction |
803 | * @sg: the scatterlist to synchronize | 822 | * @sg: the scatterlist to synchronize |
804 | * @n_hw_ents: the positive return value from usb_buffer_map_sg | 823 | * @n_hw_ents: the positive return value from usb_buffer_map_sg |
805 | * | 824 | * |
806 | * Use this when you are re-using a scatterlist's data buffers for | 825 | * Use this when you are re-using a scatterlist's data buffers for |
807 | * another USB request. | 826 | * another USB request. |
808 | */ | 827 | */ |
809 | void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, | 828 | void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in, |
810 | struct scatterlist *sg, int n_hw_ents) | 829 | struct scatterlist *sg, int n_hw_ents) |
811 | { | 830 | { |
812 | struct usb_bus *bus; | 831 | struct usb_bus *bus; |
@@ -819,20 +838,20 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, | |||
819 | return; | 838 | return; |
820 | 839 | ||
821 | dma_sync_sg(controller, sg, n_hw_ents, | 840 | dma_sync_sg(controller, sg, n_hw_ents, |
822 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 841 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
823 | } | 842 | } |
824 | #endif | 843 | #endif |
825 | 844 | ||
826 | /** | 845 | /** |
827 | * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist | 846 | * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist |
828 | * @dev: device to which the scatterlist will be mapped | 847 | * @dev: device to which the scatterlist will be mapped |
829 | * @pipe: endpoint defining the mapping direction | 848 | * @is_in: mapping transfer direction |
830 | * @sg: the scatterlist to unmap | 849 | * @sg: the scatterlist to unmap |
831 | * @n_hw_ents: the positive return value from usb_buffer_map_sg | 850 | * @n_hw_ents: the positive return value from usb_buffer_map_sg |
832 | * | 851 | * |
833 | * Reverses the effect of usb_buffer_map_sg(). | 852 | * Reverses the effect of usb_buffer_map_sg(). |
834 | */ | 853 | */ |
835 | void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, | 854 | void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in, |
836 | struct scatterlist *sg, int n_hw_ents) | 855 | struct scatterlist *sg, int n_hw_ents) |
837 | { | 856 | { |
838 | struct usb_bus *bus; | 857 | struct usb_bus *bus; |
@@ -845,7 +864,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, | |||
845 | return; | 864 | return; |
846 | 865 | ||
847 | dma_unmap_sg(controller, sg, n_hw_ents, | 866 | dma_unmap_sg(controller, sg, n_hw_ents, |
848 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 867 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
849 | } | 868 | } |
850 | 869 | ||
851 | /* format to disable USB on kernel command line is: nousb */ | 870 | /* format to disable USB on kernel command line is: nousb */ |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index ad5fa0338f49..c52626c51f70 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -8,17 +8,22 @@ extern int usb_create_ep_files(struct device *parent, struct usb_host_endpoint * | |||
8 | struct usb_device *udev); | 8 | struct usb_device *udev); |
9 | extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); | 9 | extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); |
10 | 10 | ||
11 | extern void usb_enable_endpoint(struct usb_device *dev, | ||
12 | struct usb_host_endpoint *ep); | ||
11 | extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); | 13 | extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); |
12 | extern void usb_disable_interface (struct usb_device *dev, | 14 | extern void usb_disable_interface (struct usb_device *dev, |
13 | struct usb_interface *intf); | 15 | struct usb_interface *intf); |
14 | extern void usb_release_interface_cache(struct kref *ref); | 16 | extern void usb_release_interface_cache(struct kref *ref); |
15 | extern void usb_disable_device (struct usb_device *dev, int skip_ep0); | 17 | extern void usb_disable_device (struct usb_device *dev, int skip_ep0); |
18 | extern int usb_deauthorize_device (struct usb_device *); | ||
19 | extern int usb_authorize_device (struct usb_device *); | ||
16 | extern void usb_detect_quirks(struct usb_device *udev); | 20 | extern void usb_detect_quirks(struct usb_device *udev); |
17 | 21 | ||
18 | extern int usb_get_device_descriptor(struct usb_device *dev, | 22 | extern int usb_get_device_descriptor(struct usb_device *dev, |
19 | unsigned int size); | 23 | unsigned int size); |
20 | extern char *usb_cache_string(struct usb_device *udev, int index); | 24 | extern char *usb_cache_string(struct usb_device *udev, int index); |
21 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 25 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
26 | extern int usb_choose_configuration(struct usb_device *udev); | ||
22 | 27 | ||
23 | extern void usb_kick_khubd(struct usb_device *dev); | 28 | extern void usb_kick_khubd(struct usb_device *dev); |
24 | extern int usb_match_device(struct usb_device *dev, | 29 | extern int usb_match_device(struct usb_device *dev, |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 767aed5b4bea..f81d08d6538b 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -67,6 +67,17 @@ config USB_GADGET_DEBUG_FILES | |||
67 | driver on a new board. Enable these files by choosing "Y" | 67 | driver on a new board. Enable these files by choosing "Y" |
68 | here. If in doubt, or to conserve kernel memory, say "N". | 68 | here. If in doubt, or to conserve kernel memory, say "N". |
69 | 69 | ||
70 | config USB_GADGET_DEBUG_FS | ||
71 | boolean "Debugging information files in debugfs" | ||
72 | depends on USB_GADGET && DEBUG_FS | ||
73 | help | ||
74 | Some of the drivers in the "gadget" framework can expose | ||
75 | debugging information in files under /sys/kernel/debug/. | ||
76 | The information in these files may help when you're | ||
77 | troubleshooting or bringing up a driver on a new board. | ||
78 | Enable these files by choosing "Y" here. If in doubt, or | ||
79 | to conserve kernel memory, say "N". | ||
80 | |||
70 | config USB_GADGET_SELECTED | 81 | config USB_GADGET_SELECTED |
71 | boolean | 82 | boolean |
72 | 83 | ||
@@ -103,6 +114,20 @@ config USB_AMD5536UDC | |||
103 | default USB_GADGET | 114 | default USB_GADGET |
104 | select USB_GADGET_SELECTED | 115 | select USB_GADGET_SELECTED |
105 | 116 | ||
117 | config USB_GADGET_ATMEL_USBA | ||
118 | boolean "Atmel USBA" | ||
119 | select USB_GADGET_DUALSPEED | ||
120 | depends on AVR32 | ||
121 | help | ||
122 | USBA is the integrated high-speed USB Device controller on | ||
123 | the AT32AP700x processors from Atmel. | ||
124 | |||
125 | config USB_ATMEL_USBA | ||
126 | tristate | ||
127 | depends on USB_GADGET_ATMEL_USBA | ||
128 | default USB_GADGET | ||
129 | select USB_GADGET_SELECTED | ||
130 | |||
106 | config USB_GADGET_FSL_USB2 | 131 | config USB_GADGET_FSL_USB2 |
107 | boolean "Freescale Highspeed USB DR Peripheral Controller" | 132 | boolean "Freescale Highspeed USB DR Peripheral Controller" |
108 | depends on MPC834x || PPC_MPC831x | 133 | depends on MPC834x || PPC_MPC831x |
@@ -228,7 +253,6 @@ config USB_LH7A40X | |||
228 | default USB_GADGET | 253 | default USB_GADGET |
229 | select USB_GADGET_SELECTED | 254 | select USB_GADGET_SELECTED |
230 | 255 | ||
231 | |||
232 | config USB_GADGET_OMAP | 256 | config USB_GADGET_OMAP |
233 | boolean "OMAP USB Device Controller" | 257 | boolean "OMAP USB Device Controller" |
234 | depends on ARCH_OMAP | 258 | depends on ARCH_OMAP |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 1bc0f03550ce..904e57bf6112 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_OMAP) += omap_udc.o | |||
14 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o | 14 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o |
15 | obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o | 15 | obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o |
16 | obj-$(CONFIG_USB_AT91) += at91_udc.o | 16 | obj-$(CONFIG_USB_AT91) += at91_udc.o |
17 | obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o | ||
17 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | 18 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o |
18 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | 19 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
19 | 20 | ||
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 714156ca8fe4..1c8040602525 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -69,7 +69,7 @@ | |||
69 | 69 | ||
70 | /* gadget stack */ | 70 | /* gadget stack */ |
71 | #include <linux/usb/ch9.h> | 71 | #include <linux/usb/ch9.h> |
72 | #include <linux/usb_gadget.h> | 72 | #include <linux/usb/gadget.h> |
73 | 73 | ||
74 | /* udc specific */ | 74 | /* udc specific */ |
75 | #include "amd5536udc.h" | 75 | #include "amd5536udc.h" |
@@ -3244,7 +3244,6 @@ static int udc_pci_probe( | |||
3244 | retval = -ENOMEM; | 3244 | retval = -ENOMEM; |
3245 | goto finished; | 3245 | goto finished; |
3246 | } | 3246 | } |
3247 | memset(dev, 0, sizeof(struct udc)); | ||
3248 | 3247 | ||
3249 | /* pci setup */ | 3248 | /* pci setup */ |
3250 | if (pci_enable_device(pdev) < 0) { | 3249 | if (pci_enable_device(pdev) < 0) { |
@@ -3286,14 +3285,12 @@ static int udc_pci_probe( | |||
3286 | 3285 | ||
3287 | pci_set_drvdata(pdev, dev); | 3286 | pci_set_drvdata(pdev, dev); |
3288 | 3287 | ||
3289 | /* chip revision */ | 3288 | /* chip revision for Hs AMD5536 */ |
3290 | dev->chiprev = 0; | 3289 | dev->chiprev = pdev->revision; |
3291 | 3290 | ||
3292 | pci_set_master(pdev); | 3291 | pci_set_master(pdev); |
3293 | pci_set_mwi(pdev); | 3292 | pci_set_mwi(pdev); |
3294 | 3293 | ||
3295 | /* chip rev for Hs AMD5536 */ | ||
3296 | pci_read_config_byte(pdev, PCI_REVISION_ID, (u8 *) &dev->chiprev); | ||
3297 | /* init dma pools */ | 3294 | /* init dma pools */ |
3298 | if (use_dma) { | 3295 | if (use_dma) { |
3299 | retval = init_dma_pools(dev); | 3296 | retval = init_dma_pools(dev); |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 63d7d6568699..a6adf7e0f6f8 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/proc_fs.h> | 38 | #include <linux/proc_fs.h> |
39 | #include <linux/clk.h> | 39 | #include <linux/clk.h> |
40 | #include <linux/usb/ch9.h> | 40 | #include <linux/usb/ch9.h> |
41 | #include <linux/usb_gadget.h> | 41 | #include <linux/usb/gadget.h> |
42 | 42 | ||
43 | #include <asm/byteorder.h> | 43 | #include <asm/byteorder.h> |
44 | #include <asm/hardware.h> | 44 | #include <asm/hardware.h> |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c new file mode 100644 index 000000000000..4fb5ff469574 --- /dev/null +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -0,0 +1,2077 @@ | |||
1 | /* | ||
2 | * Driver for the Atmel USBA high speed USB device controller | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Atmel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/clk.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/dma-mapping.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/usb/ch9.h> | ||
20 | #include <linux/usb/gadget.h> | ||
21 | #include <linux/delay.h> | ||
22 | |||
23 | #include <asm/gpio.h> | ||
24 | #include <asm/arch/board.h> | ||
25 | |||
26 | #include "atmel_usba_udc.h" | ||
27 | |||
28 | |||
29 | static struct usba_udc the_udc; | ||
30 | |||
31 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
32 | #include <linux/debugfs.h> | ||
33 | #include <linux/uaccess.h> | ||
34 | |||
35 | static int queue_dbg_open(struct inode *inode, struct file *file) | ||
36 | { | ||
37 | struct usba_ep *ep = inode->i_private; | ||
38 | struct usba_request *req, *req_copy; | ||
39 | struct list_head *queue_data; | ||
40 | |||
41 | queue_data = kmalloc(sizeof(*queue_data), GFP_KERNEL); | ||
42 | if (!queue_data) | ||
43 | return -ENOMEM; | ||
44 | INIT_LIST_HEAD(queue_data); | ||
45 | |||
46 | spin_lock_irq(&ep->udc->lock); | ||
47 | list_for_each_entry(req, &ep->queue, queue) { | ||
48 | req_copy = kmalloc(sizeof(*req_copy), GFP_ATOMIC); | ||
49 | if (!req_copy) | ||
50 | goto fail; | ||
51 | memcpy(req_copy, req, sizeof(*req_copy)); | ||
52 | list_add_tail(&req_copy->queue, queue_data); | ||
53 | } | ||
54 | spin_unlock_irq(&ep->udc->lock); | ||
55 | |||
56 | file->private_data = queue_data; | ||
57 | return 0; | ||
58 | |||
59 | fail: | ||
60 | spin_unlock_irq(&ep->udc->lock); | ||
61 | list_for_each_entry_safe(req, req_copy, queue_data, queue) { | ||
62 | list_del(&req->queue); | ||
63 | kfree(req); | ||
64 | } | ||
65 | kfree(queue_data); | ||
66 | return -ENOMEM; | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * bbbbbbbb llllllll IZS sssss nnnn FDL\n\0 | ||
71 | * | ||
72 | * b: buffer address | ||
73 | * l: buffer length | ||
74 | * I/i: interrupt/no interrupt | ||
75 | * Z/z: zero/no zero | ||
76 | * S/s: short ok/short not ok | ||
77 | * s: status | ||
78 | * n: nr_packets | ||
79 | * F/f: submitted/not submitted to FIFO | ||
80 | * D/d: using/not using DMA | ||
81 | * L/l: last transaction/not last transaction | ||
82 | */ | ||
83 | static ssize_t queue_dbg_read(struct file *file, char __user *buf, | ||
84 | size_t nbytes, loff_t *ppos) | ||
85 | { | ||
86 | struct list_head *queue = file->private_data; | ||
87 | struct usba_request *req, *tmp_req; | ||
88 | size_t len, remaining, actual = 0; | ||
89 | char tmpbuf[38]; | ||
90 | |||
91 | if (!access_ok(VERIFY_WRITE, buf, nbytes)) | ||
92 | return -EFAULT; | ||
93 | |||
94 | mutex_lock(&file->f_dentry->d_inode->i_mutex); | ||
95 | list_for_each_entry_safe(req, tmp_req, queue, queue) { | ||
96 | len = snprintf(tmpbuf, sizeof(tmpbuf), | ||
97 | "%8p %08x %c%c%c %5d %c%c%c\n", | ||
98 | req->req.buf, req->req.length, | ||
99 | req->req.no_interrupt ? 'i' : 'I', | ||
100 | req->req.zero ? 'Z' : 'z', | ||
101 | req->req.short_not_ok ? 's' : 'S', | ||
102 | req->req.status, | ||
103 | req->submitted ? 'F' : 'f', | ||
104 | req->using_dma ? 'D' : 'd', | ||
105 | req->last_transaction ? 'L' : 'l'); | ||
106 | len = min(len, sizeof(tmpbuf)); | ||
107 | if (len > nbytes) | ||
108 | break; | ||
109 | |||
110 | list_del(&req->queue); | ||
111 | kfree(req); | ||
112 | |||
113 | remaining = __copy_to_user(buf, tmpbuf, len); | ||
114 | actual += len - remaining; | ||
115 | if (remaining) | ||
116 | break; | ||
117 | |||
118 | nbytes -= len; | ||
119 | buf += len; | ||
120 | } | ||
121 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | ||
122 | |||
123 | return actual; | ||
124 | } | ||
125 | |||
126 | static int queue_dbg_release(struct inode *inode, struct file *file) | ||
127 | { | ||
128 | struct list_head *queue_data = file->private_data; | ||
129 | struct usba_request *req, *tmp_req; | ||
130 | |||
131 | list_for_each_entry_safe(req, tmp_req, queue_data, queue) { | ||
132 | list_del(&req->queue); | ||
133 | kfree(req); | ||
134 | } | ||
135 | kfree(queue_data); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int regs_dbg_open(struct inode *inode, struct file *file) | ||
140 | { | ||
141 | struct usba_udc *udc; | ||
142 | unsigned int i; | ||
143 | u32 *data; | ||
144 | int ret = -ENOMEM; | ||
145 | |||
146 | mutex_lock(&inode->i_mutex); | ||
147 | udc = inode->i_private; | ||
148 | data = kmalloc(inode->i_size, GFP_KERNEL); | ||
149 | if (!data) | ||
150 | goto out; | ||
151 | |||
152 | spin_lock_irq(&udc->lock); | ||
153 | for (i = 0; i < inode->i_size / 4; i++) | ||
154 | data[i] = __raw_readl(udc->regs + i * 4); | ||
155 | spin_unlock_irq(&udc->lock); | ||
156 | |||
157 | file->private_data = data; | ||
158 | ret = 0; | ||
159 | |||
160 | out: | ||
161 | mutex_unlock(&inode->i_mutex); | ||
162 | |||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static ssize_t regs_dbg_read(struct file *file, char __user *buf, | ||
167 | size_t nbytes, loff_t *ppos) | ||
168 | { | ||
169 | struct inode *inode = file->f_dentry->d_inode; | ||
170 | int ret; | ||
171 | |||
172 | mutex_lock(&inode->i_mutex); | ||
173 | ret = simple_read_from_buffer(buf, nbytes, ppos, | ||
174 | file->private_data, | ||
175 | file->f_dentry->d_inode->i_size); | ||
176 | mutex_unlock(&inode->i_mutex); | ||
177 | |||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | static int regs_dbg_release(struct inode *inode, struct file *file) | ||
182 | { | ||
183 | kfree(file->private_data); | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | const struct file_operations queue_dbg_fops = { | ||
188 | .owner = THIS_MODULE, | ||
189 | .open = queue_dbg_open, | ||
190 | .llseek = no_llseek, | ||
191 | .read = queue_dbg_read, | ||
192 | .release = queue_dbg_release, | ||
193 | }; | ||
194 | |||
195 | const struct file_operations regs_dbg_fops = { | ||
196 | .owner = THIS_MODULE, | ||
197 | .open = regs_dbg_open, | ||
198 | .llseek = generic_file_llseek, | ||
199 | .read = regs_dbg_read, | ||
200 | .release = regs_dbg_release, | ||
201 | }; | ||
202 | |||
203 | static void usba_ep_init_debugfs(struct usba_udc *udc, | ||
204 | struct usba_ep *ep) | ||
205 | { | ||
206 | struct dentry *ep_root; | ||
207 | |||
208 | ep_root = debugfs_create_dir(ep->ep.name, udc->debugfs_root); | ||
209 | if (!ep_root) | ||
210 | goto err_root; | ||
211 | ep->debugfs_dir = ep_root; | ||
212 | |||
213 | ep->debugfs_queue = debugfs_create_file("queue", 0400, ep_root, | ||
214 | ep, &queue_dbg_fops); | ||
215 | if (!ep->debugfs_queue) | ||
216 | goto err_queue; | ||
217 | |||
218 | if (ep->can_dma) { | ||
219 | ep->debugfs_dma_status | ||
220 | = debugfs_create_u32("dma_status", 0400, ep_root, | ||
221 | &ep->last_dma_status); | ||
222 | if (!ep->debugfs_dma_status) | ||
223 | goto err_dma_status; | ||
224 | } | ||
225 | if (ep_is_control(ep)) { | ||
226 | ep->debugfs_state | ||
227 | = debugfs_create_u32("state", 0400, ep_root, | ||
228 | &ep->state); | ||
229 | if (!ep->debugfs_state) | ||
230 | goto err_state; | ||
231 | } | ||
232 | |||
233 | return; | ||
234 | |||
235 | err_state: | ||
236 | if (ep->can_dma) | ||
237 | debugfs_remove(ep->debugfs_dma_status); | ||
238 | err_dma_status: | ||
239 | debugfs_remove(ep->debugfs_queue); | ||
240 | err_queue: | ||
241 | debugfs_remove(ep_root); | ||
242 | err_root: | ||
243 | dev_err(&ep->udc->pdev->dev, | ||
244 | "failed to create debugfs directory for %s\n", ep->ep.name); | ||
245 | } | ||
246 | |||
247 | static void usba_ep_cleanup_debugfs(struct usba_ep *ep) | ||
248 | { | ||
249 | debugfs_remove(ep->debugfs_queue); | ||
250 | debugfs_remove(ep->debugfs_dma_status); | ||
251 | debugfs_remove(ep->debugfs_state); | ||
252 | debugfs_remove(ep->debugfs_dir); | ||
253 | ep->debugfs_dma_status = NULL; | ||
254 | ep->debugfs_dir = NULL; | ||
255 | } | ||
256 | |||
257 | static void usba_init_debugfs(struct usba_udc *udc) | ||
258 | { | ||
259 | struct dentry *root, *regs; | ||
260 | struct resource *regs_resource; | ||
261 | |||
262 | root = debugfs_create_dir(udc->gadget.name, NULL); | ||
263 | if (IS_ERR(root) || !root) | ||
264 | goto err_root; | ||
265 | udc->debugfs_root = root; | ||
266 | |||
267 | regs = debugfs_create_file("regs", 0400, root, udc, ®s_dbg_fops); | ||
268 | if (!regs) | ||
269 | goto err_regs; | ||
270 | |||
271 | regs_resource = platform_get_resource(udc->pdev, IORESOURCE_MEM, | ||
272 | CTRL_IOMEM_ID); | ||
273 | regs->d_inode->i_size = regs_resource->end - regs_resource->start + 1; | ||
274 | udc->debugfs_regs = regs; | ||
275 | |||
276 | usba_ep_init_debugfs(udc, to_usba_ep(udc->gadget.ep0)); | ||
277 | |||
278 | return; | ||
279 | |||
280 | err_regs: | ||
281 | debugfs_remove(root); | ||
282 | err_root: | ||
283 | udc->debugfs_root = NULL; | ||
284 | dev_err(&udc->pdev->dev, "debugfs is not available\n"); | ||
285 | } | ||
286 | |||
287 | static void usba_cleanup_debugfs(struct usba_udc *udc) | ||
288 | { | ||
289 | usba_ep_cleanup_debugfs(to_usba_ep(udc->gadget.ep0)); | ||
290 | debugfs_remove(udc->debugfs_regs); | ||
291 | debugfs_remove(udc->debugfs_root); | ||
292 | udc->debugfs_regs = NULL; | ||
293 | udc->debugfs_root = NULL; | ||
294 | } | ||
295 | #else | ||
296 | static inline void usba_ep_init_debugfs(struct usba_udc *udc, | ||
297 | struct usba_ep *ep) | ||
298 | { | ||
299 | |||
300 | } | ||
301 | |||
302 | static inline void usba_ep_cleanup_debugfs(struct usba_ep *ep) | ||
303 | { | ||
304 | |||
305 | } | ||
306 | |||
307 | static inline void usba_init_debugfs(struct usba_udc *udc) | ||
308 | { | ||
309 | |||
310 | } | ||
311 | |||
312 | static inline void usba_cleanup_debugfs(struct usba_udc *udc) | ||
313 | { | ||
314 | |||
315 | } | ||
316 | #endif | ||
317 | |||
318 | static int vbus_is_present(struct usba_udc *udc) | ||
319 | { | ||
320 | if (udc->vbus_pin != -1) | ||
321 | return gpio_get_value(udc->vbus_pin); | ||
322 | |||
323 | /* No Vbus detection: Assume always present */ | ||
324 | return 1; | ||
325 | } | ||
326 | |||
327 | static void copy_to_fifo(void __iomem *fifo, const void *buf, int len) | ||
328 | { | ||
329 | unsigned long tmp; | ||
330 | |||
331 | DBG(DBG_FIFO, "copy to FIFO (len %d):\n", len); | ||
332 | for (; len > 0; len -= 4, buf += 4, fifo += 4) { | ||
333 | tmp = *(unsigned long *)buf; | ||
334 | if (len >= 4) { | ||
335 | DBG(DBG_FIFO, " -> %08lx\n", tmp); | ||
336 | __raw_writel(tmp, fifo); | ||
337 | } else { | ||
338 | do { | ||
339 | DBG(DBG_FIFO, " -> %02lx\n", tmp >> 24); | ||
340 | __raw_writeb(tmp >> 24, fifo); | ||
341 | fifo++; | ||
342 | tmp <<= 8; | ||
343 | } while (--len); | ||
344 | break; | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | |||
349 | static void copy_from_fifo(void *buf, void __iomem *fifo, int len) | ||
350 | { | ||
351 | union { | ||
352 | unsigned long *w; | ||
353 | unsigned char *b; | ||
354 | } p; | ||
355 | unsigned long tmp; | ||
356 | |||
357 | DBG(DBG_FIFO, "copy from FIFO (len %d):\n", len); | ||
358 | for (p.w = buf; len > 0; len -= 4, p.w++, fifo += 4) { | ||
359 | if (len >= 4) { | ||
360 | tmp = __raw_readl(fifo); | ||
361 | *p.w = tmp; | ||
362 | DBG(DBG_FIFO, " -> %08lx\n", tmp); | ||
363 | } else { | ||
364 | do { | ||
365 | tmp = __raw_readb(fifo); | ||
366 | *p.b = tmp; | ||
367 | DBG(DBG_FIFO, " -> %02lx\n", tmp); | ||
368 | fifo++, p.b++; | ||
369 | } while (--len); | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | |||
374 | static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req) | ||
375 | { | ||
376 | unsigned int transaction_len; | ||
377 | |||
378 | transaction_len = req->req.length - req->req.actual; | ||
379 | req->last_transaction = 1; | ||
380 | if (transaction_len > ep->ep.maxpacket) { | ||
381 | transaction_len = ep->ep.maxpacket; | ||
382 | req->last_transaction = 0; | ||
383 | } else if (transaction_len == ep->ep.maxpacket && req->req.zero) | ||
384 | req->last_transaction = 0; | ||
385 | |||
386 | DBG(DBG_QUEUE, "%s: submit_transaction, req %p (length %d)%s\n", | ||
387 | ep->ep.name, req, transaction_len, | ||
388 | req->last_transaction ? ", done" : ""); | ||
389 | |||
390 | copy_to_fifo(ep->fifo, req->req.buf + req->req.actual, transaction_len); | ||
391 | usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); | ||
392 | req->req.actual += transaction_len; | ||
393 | } | ||
394 | |||
395 | static void submit_request(struct usba_ep *ep, struct usba_request *req) | ||
396 | { | ||
397 | DBG(DBG_QUEUE, "%s: submit_request: req %p (length %d)\n", | ||
398 | ep->ep.name, req, req->req.length); | ||
399 | |||
400 | req->req.actual = 0; | ||
401 | req->submitted = 1; | ||
402 | |||
403 | if (req->using_dma) { | ||
404 | if (req->req.length == 0) { | ||
405 | usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); | ||
406 | return; | ||
407 | } | ||
408 | |||
409 | if (req->req.zero) | ||
410 | usba_ep_writel(ep, CTL_ENB, USBA_SHORT_PACKET); | ||
411 | else | ||
412 | usba_ep_writel(ep, CTL_DIS, USBA_SHORT_PACKET); | ||
413 | |||
414 | usba_dma_writel(ep, ADDRESS, req->req.dma); | ||
415 | usba_dma_writel(ep, CONTROL, req->ctrl); | ||
416 | } else { | ||
417 | next_fifo_transaction(ep, req); | ||
418 | if (req->last_transaction) { | ||
419 | usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY); | ||
420 | usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); | ||
421 | } else { | ||
422 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
423 | usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); | ||
424 | } | ||
425 | } | ||
426 | } | ||
427 | |||
428 | static void submit_next_request(struct usba_ep *ep) | ||
429 | { | ||
430 | struct usba_request *req; | ||
431 | |||
432 | if (list_empty(&ep->queue)) { | ||
433 | usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY | USBA_RX_BK_RDY); | ||
434 | return; | ||
435 | } | ||
436 | |||
437 | req = list_entry(ep->queue.next, struct usba_request, queue); | ||
438 | if (!req->submitted) | ||
439 | submit_request(ep, req); | ||
440 | } | ||
441 | |||
442 | static void send_status(struct usba_udc *udc, struct usba_ep *ep) | ||
443 | { | ||
444 | ep->state = STATUS_STAGE_IN; | ||
445 | usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); | ||
446 | usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); | ||
447 | } | ||
448 | |||
449 | static void receive_data(struct usba_ep *ep) | ||
450 | { | ||
451 | struct usba_udc *udc = ep->udc; | ||
452 | struct usba_request *req; | ||
453 | unsigned long status; | ||
454 | unsigned int bytecount, nr_busy; | ||
455 | int is_complete = 0; | ||
456 | |||
457 | status = usba_ep_readl(ep, STA); | ||
458 | nr_busy = USBA_BFEXT(BUSY_BANKS, status); | ||
459 | |||
460 | DBG(DBG_QUEUE, "receive data: nr_busy=%u\n", nr_busy); | ||
461 | |||
462 | while (nr_busy > 0) { | ||
463 | if (list_empty(&ep->queue)) { | ||
464 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
465 | break; | ||
466 | } | ||
467 | req = list_entry(ep->queue.next, | ||
468 | struct usba_request, queue); | ||
469 | |||
470 | bytecount = USBA_BFEXT(BYTE_COUNT, status); | ||
471 | |||
472 | if (status & (1 << 31)) | ||
473 | is_complete = 1; | ||
474 | if (req->req.actual + bytecount >= req->req.length) { | ||
475 | is_complete = 1; | ||
476 | bytecount = req->req.length - req->req.actual; | ||
477 | } | ||
478 | |||
479 | copy_from_fifo(req->req.buf + req->req.actual, | ||
480 | ep->fifo, bytecount); | ||
481 | req->req.actual += bytecount; | ||
482 | |||
483 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | ||
484 | |||
485 | if (is_complete) { | ||
486 | DBG(DBG_QUEUE, "%s: request done\n", ep->ep.name); | ||
487 | req->req.status = 0; | ||
488 | list_del_init(&req->queue); | ||
489 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
490 | spin_unlock(&udc->lock); | ||
491 | req->req.complete(&ep->ep, &req->req); | ||
492 | spin_lock(&udc->lock); | ||
493 | } | ||
494 | |||
495 | status = usba_ep_readl(ep, STA); | ||
496 | nr_busy = USBA_BFEXT(BUSY_BANKS, status); | ||
497 | |||
498 | if (is_complete && ep_is_control(ep)) { | ||
499 | send_status(udc, ep); | ||
500 | break; | ||
501 | } | ||
502 | } | ||
503 | } | ||
504 | |||
505 | static void | ||
506 | request_complete(struct usba_ep *ep, struct usba_request *req, int status) | ||
507 | { | ||
508 | struct usba_udc *udc = ep->udc; | ||
509 | |||
510 | WARN_ON(!list_empty(&req->queue)); | ||
511 | |||
512 | if (req->req.status == -EINPROGRESS) | ||
513 | req->req.status = status; | ||
514 | |||
515 | if (req->mapped) { | ||
516 | dma_unmap_single( | ||
517 | &udc->pdev->dev, req->req.dma, req->req.length, | ||
518 | ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
519 | req->req.dma = DMA_ADDR_INVALID; | ||
520 | req->mapped = 0; | ||
521 | } | ||
522 | |||
523 | DBG(DBG_GADGET | DBG_REQ, | ||
524 | "%s: req %p complete: status %d, actual %u\n", | ||
525 | ep->ep.name, req, req->req.status, req->req.actual); | ||
526 | |||
527 | spin_unlock(&udc->lock); | ||
528 | req->req.complete(&ep->ep, &req->req); | ||
529 | spin_lock(&udc->lock); | ||
530 | } | ||
531 | |||
532 | static void | ||
533 | request_complete_list(struct usba_ep *ep, struct list_head *list, int status) | ||
534 | { | ||
535 | struct usba_request *req, *tmp_req; | ||
536 | |||
537 | list_for_each_entry_safe(req, tmp_req, list, queue) { | ||
538 | list_del_init(&req->queue); | ||
539 | request_complete(ep, req, status); | ||
540 | } | ||
541 | } | ||
542 | |||
543 | static int | ||
544 | usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | ||
545 | { | ||
546 | struct usba_ep *ep = to_usba_ep(_ep); | ||
547 | struct usba_udc *udc = ep->udc; | ||
548 | unsigned long flags, ept_cfg, maxpacket; | ||
549 | unsigned int nr_trans; | ||
550 | |||
551 | DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep->ep.name, desc); | ||
552 | |||
553 | maxpacket = le16_to_cpu(desc->wMaxPacketSize) & 0x7ff; | ||
554 | |||
555 | if (((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != ep->index) | ||
556 | || ep->index == 0 | ||
557 | || desc->bDescriptorType != USB_DT_ENDPOINT | ||
558 | || maxpacket == 0 | ||
559 | || maxpacket > ep->fifo_size) { | ||
560 | DBG(DBG_ERR, "ep_enable: Invalid argument"); | ||
561 | return -EINVAL; | ||
562 | } | ||
563 | |||
564 | ep->is_isoc = 0; | ||
565 | ep->is_in = 0; | ||
566 | |||
567 | if (maxpacket <= 8) | ||
568 | ept_cfg = USBA_BF(EPT_SIZE, USBA_EPT_SIZE_8); | ||
569 | else | ||
570 | /* LSB is bit 1, not 0 */ | ||
571 | ept_cfg = USBA_BF(EPT_SIZE, fls(maxpacket - 1) - 3); | ||
572 | |||
573 | DBG(DBG_HW, "%s: EPT_SIZE = %lu (maxpacket = %lu)\n", | ||
574 | ep->ep.name, ept_cfg, maxpacket); | ||
575 | |||
576 | if ((desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { | ||
577 | ep->is_in = 1; | ||
578 | ept_cfg |= USBA_EPT_DIR_IN; | ||
579 | } | ||
580 | |||
581 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
582 | case USB_ENDPOINT_XFER_CONTROL: | ||
583 | ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL); | ||
584 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE); | ||
585 | break; | ||
586 | case USB_ENDPOINT_XFER_ISOC: | ||
587 | if (!ep->can_isoc) { | ||
588 | DBG(DBG_ERR, "ep_enable: %s is not isoc capable\n", | ||
589 | ep->ep.name); | ||
590 | return -EINVAL; | ||
591 | } | ||
592 | |||
593 | /* | ||
594 | * Bits 11:12 specify number of _additional_ | ||
595 | * transactions per microframe. | ||
596 | */ | ||
597 | nr_trans = ((le16_to_cpu(desc->wMaxPacketSize) >> 11) & 3) + 1; | ||
598 | if (nr_trans > 3) | ||
599 | return -EINVAL; | ||
600 | |||
601 | ep->is_isoc = 1; | ||
602 | ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_ISO); | ||
603 | |||
604 | /* | ||
605 | * Do triple-buffering on high-bandwidth iso endpoints. | ||
606 | */ | ||
607 | if (nr_trans > 1 && ep->nr_banks == 3) | ||
608 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_TRIPLE); | ||
609 | else | ||
610 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE); | ||
611 | ept_cfg |= USBA_BF(NB_TRANS, nr_trans); | ||
612 | break; | ||
613 | case USB_ENDPOINT_XFER_BULK: | ||
614 | ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK); | ||
615 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE); | ||
616 | break; | ||
617 | case USB_ENDPOINT_XFER_INT: | ||
618 | ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_INT); | ||
619 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE); | ||
620 | break; | ||
621 | } | ||
622 | |||
623 | spin_lock_irqsave(&ep->udc->lock, flags); | ||
624 | |||
625 | if (ep->desc) { | ||
626 | spin_unlock_irqrestore(&ep->udc->lock, flags); | ||
627 | DBG(DBG_ERR, "ep%d already enabled\n", ep->index); | ||
628 | return -EBUSY; | ||
629 | } | ||
630 | |||
631 | ep->desc = desc; | ||
632 | ep->ep.maxpacket = maxpacket; | ||
633 | |||
634 | usba_ep_writel(ep, CFG, ept_cfg); | ||
635 | usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE); | ||
636 | |||
637 | if (ep->can_dma) { | ||
638 | u32 ctrl; | ||
639 | |||
640 | usba_writel(udc, INT_ENB, | ||
641 | (usba_readl(udc, INT_ENB) | ||
642 | | USBA_BF(EPT_INT, 1 << ep->index) | ||
643 | | USBA_BF(DMA_INT, 1 << ep->index))); | ||
644 | ctrl = USBA_AUTO_VALID | USBA_INTDIS_DMA; | ||
645 | usba_ep_writel(ep, CTL_ENB, ctrl); | ||
646 | } else { | ||
647 | usba_writel(udc, INT_ENB, | ||
648 | (usba_readl(udc, INT_ENB) | ||
649 | | USBA_BF(EPT_INT, 1 << ep->index))); | ||
650 | } | ||
651 | |||
652 | spin_unlock_irqrestore(&udc->lock, flags); | ||
653 | |||
654 | DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index, | ||
655 | (unsigned long)usba_ep_readl(ep, CFG)); | ||
656 | DBG(DBG_HW, "INT_ENB after init: %#08lx\n", | ||
657 | (unsigned long)usba_readl(udc, INT_ENB)); | ||
658 | |||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | static int usba_ep_disable(struct usb_ep *_ep) | ||
663 | { | ||
664 | struct usba_ep *ep = to_usba_ep(_ep); | ||
665 | struct usba_udc *udc = ep->udc; | ||
666 | LIST_HEAD(req_list); | ||
667 | unsigned long flags; | ||
668 | |||
669 | DBG(DBG_GADGET, "ep_disable: %s\n", ep->ep.name); | ||
670 | |||
671 | spin_lock_irqsave(&udc->lock, flags); | ||
672 | |||
673 | if (!ep->desc) { | ||
674 | spin_unlock_irqrestore(&udc->lock, flags); | ||
675 | DBG(DBG_ERR, "ep_disable: %s not enabled\n", ep->ep.name); | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | ep->desc = NULL; | ||
679 | |||
680 | list_splice_init(&ep->queue, &req_list); | ||
681 | if (ep->can_dma) { | ||
682 | usba_dma_writel(ep, CONTROL, 0); | ||
683 | usba_dma_writel(ep, ADDRESS, 0); | ||
684 | usba_dma_readl(ep, STATUS); | ||
685 | } | ||
686 | usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE); | ||
687 | usba_writel(udc, INT_ENB, | ||
688 | usba_readl(udc, INT_ENB) | ||
689 | & ~USBA_BF(EPT_INT, 1 << ep->index)); | ||
690 | |||
691 | request_complete_list(ep, &req_list, -ESHUTDOWN); | ||
692 | |||
693 | spin_unlock_irqrestore(&udc->lock, flags); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | static struct usb_request * | ||
699 | usba_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) | ||
700 | { | ||
701 | struct usba_request *req; | ||
702 | |||
703 | DBG(DBG_GADGET, "ep_alloc_request: %p, 0x%x\n", _ep, gfp_flags); | ||
704 | |||
705 | req = kzalloc(sizeof(*req), gfp_flags); | ||
706 | if (!req) | ||
707 | return NULL; | ||
708 | |||
709 | INIT_LIST_HEAD(&req->queue); | ||
710 | req->req.dma = DMA_ADDR_INVALID; | ||
711 | |||
712 | return &req->req; | ||
713 | } | ||
714 | |||
715 | static void | ||
716 | usba_ep_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
717 | { | ||
718 | struct usba_request *req = to_usba_req(_req); | ||
719 | |||
720 | DBG(DBG_GADGET, "ep_free_request: %p, %p\n", _ep, _req); | ||
721 | |||
722 | kfree(req); | ||
723 | } | ||
724 | |||
725 | static int queue_dma(struct usba_udc *udc, struct usba_ep *ep, | ||
726 | struct usba_request *req, gfp_t gfp_flags) | ||
727 | { | ||
728 | unsigned long flags; | ||
729 | int ret; | ||
730 | |||
731 | DBG(DBG_DMA, "%s: req l/%u d/%08x %c%c%c\n", | ||
732 | ep->ep.name, req->req.length, req->req.dma, | ||
733 | req->req.zero ? 'Z' : 'z', | ||
734 | req->req.short_not_ok ? 'S' : 's', | ||
735 | req->req.no_interrupt ? 'I' : 'i'); | ||
736 | |||
737 | if (req->req.length > 0x10000) { | ||
738 | /* Lengths from 0 to 65536 (inclusive) are supported */ | ||
739 | DBG(DBG_ERR, "invalid request length %u\n", req->req.length); | ||
740 | return -EINVAL; | ||
741 | } | ||
742 | |||
743 | req->using_dma = 1; | ||
744 | |||
745 | if (req->req.dma == DMA_ADDR_INVALID) { | ||
746 | req->req.dma = dma_map_single( | ||
747 | &udc->pdev->dev, req->req.buf, req->req.length, | ||
748 | ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
749 | req->mapped = 1; | ||
750 | } else { | ||
751 | dma_sync_single_for_device( | ||
752 | &udc->pdev->dev, req->req.dma, req->req.length, | ||
753 | ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
754 | req->mapped = 0; | ||
755 | } | ||
756 | |||
757 | req->ctrl = USBA_BF(DMA_BUF_LEN, req->req.length) | ||
758 | | USBA_DMA_CH_EN | USBA_DMA_END_BUF_IE | ||
759 | | USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; | ||
760 | |||
761 | if (ep->is_in) | ||
762 | req->ctrl |= USBA_DMA_END_BUF_EN; | ||
763 | |||
764 | /* | ||
765 | * Add this request to the queue and submit for DMA if | ||
766 | * possible. Check if we're still alive first -- we may have | ||
767 | * received a reset since last time we checked. | ||
768 | */ | ||
769 | ret = -ESHUTDOWN; | ||
770 | spin_lock_irqsave(&udc->lock, flags); | ||
771 | if (ep->desc) { | ||
772 | if (list_empty(&ep->queue)) | ||
773 | submit_request(ep, req); | ||
774 | |||
775 | list_add_tail(&req->queue, &ep->queue); | ||
776 | ret = 0; | ||
777 | } | ||
778 | spin_unlock_irqrestore(&udc->lock, flags); | ||
779 | |||
780 | return ret; | ||
781 | } | ||
782 | |||
783 | static int | ||
784 | usba_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | ||
785 | { | ||
786 | struct usba_request *req = to_usba_req(_req); | ||
787 | struct usba_ep *ep = to_usba_ep(_ep); | ||
788 | struct usba_udc *udc = ep->udc; | ||
789 | unsigned long flags; | ||
790 | int ret; | ||
791 | |||
792 | DBG(DBG_GADGET | DBG_QUEUE | DBG_REQ, "%s: queue req %p, len %u\n", | ||
793 | ep->ep.name, req, _req->length); | ||
794 | |||
795 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN || !ep->desc) | ||
796 | return -ESHUTDOWN; | ||
797 | |||
798 | req->submitted = 0; | ||
799 | req->using_dma = 0; | ||
800 | req->last_transaction = 0; | ||
801 | |||
802 | _req->status = -EINPROGRESS; | ||
803 | _req->actual = 0; | ||
804 | |||
805 | if (ep->can_dma) | ||
806 | return queue_dma(udc, ep, req, gfp_flags); | ||
807 | |||
808 | /* May have received a reset since last time we checked */ | ||
809 | ret = -ESHUTDOWN; | ||
810 | spin_lock_irqsave(&udc->lock, flags); | ||
811 | if (ep->desc) { | ||
812 | list_add_tail(&req->queue, &ep->queue); | ||
813 | |||
814 | if (ep->is_in || (ep_is_control(ep) | ||
815 | && (ep->state == DATA_STAGE_IN | ||
816 | || ep->state == STATUS_STAGE_IN))) | ||
817 | usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); | ||
818 | else | ||
819 | usba_ep_writel(ep, CTL_ENB, USBA_RX_BK_RDY); | ||
820 | ret = 0; | ||
821 | } | ||
822 | spin_unlock_irqrestore(&udc->lock, flags); | ||
823 | |||
824 | return ret; | ||
825 | } | ||
826 | |||
827 | static void | ||
828 | usba_update_req(struct usba_ep *ep, struct usba_request *req, u32 status) | ||
829 | { | ||
830 | req->req.actual = req->req.length - USBA_BFEXT(DMA_BUF_LEN, status); | ||
831 | } | ||
832 | |||
833 | static int stop_dma(struct usba_ep *ep, u32 *pstatus) | ||
834 | { | ||
835 | unsigned int timeout; | ||
836 | u32 status; | ||
837 | |||
838 | /* | ||
839 | * Stop the DMA controller. When writing both CH_EN | ||
840 | * and LINK to 0, the other bits are not affected. | ||
841 | */ | ||
842 | usba_dma_writel(ep, CONTROL, 0); | ||
843 | |||
844 | /* Wait for the FIFO to empty */ | ||
845 | for (timeout = 40; timeout; --timeout) { | ||
846 | status = usba_dma_readl(ep, STATUS); | ||
847 | if (!(status & USBA_DMA_CH_EN)) | ||
848 | break; | ||
849 | udelay(1); | ||
850 | } | ||
851 | |||
852 | if (pstatus) | ||
853 | *pstatus = status; | ||
854 | |||
855 | if (timeout == 0) { | ||
856 | dev_err(&ep->udc->pdev->dev, | ||
857 | "%s: timed out waiting for DMA FIFO to empty\n", | ||
858 | ep->ep.name); | ||
859 | return -ETIMEDOUT; | ||
860 | } | ||
861 | |||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
866 | { | ||
867 | struct usba_ep *ep = to_usba_ep(_ep); | ||
868 | struct usba_udc *udc = ep->udc; | ||
869 | struct usba_request *req = to_usba_req(_req); | ||
870 | unsigned long flags; | ||
871 | u32 status; | ||
872 | |||
873 | DBG(DBG_GADGET | DBG_QUEUE, "ep_dequeue: %s, req %p\n", | ||
874 | ep->ep.name, req); | ||
875 | |||
876 | spin_lock_irqsave(&udc->lock, flags); | ||
877 | |||
878 | if (req->using_dma) { | ||
879 | /* | ||
880 | * If this request is currently being transferred, | ||
881 | * stop the DMA controller and reset the FIFO. | ||
882 | */ | ||
883 | if (ep->queue.next == &req->queue) { | ||
884 | status = usba_dma_readl(ep, STATUS); | ||
885 | if (status & USBA_DMA_CH_EN) | ||
886 | stop_dma(ep, &status); | ||
887 | |||
888 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
889 | ep->last_dma_status = status; | ||
890 | #endif | ||
891 | |||
892 | usba_writel(udc, EPT_RST, 1 << ep->index); | ||
893 | |||
894 | usba_update_req(ep, req, status); | ||
895 | } | ||
896 | } | ||
897 | |||
898 | /* | ||
899 | * Errors should stop the queue from advancing until the | ||
900 | * completion function returns. | ||
901 | */ | ||
902 | list_del_init(&req->queue); | ||
903 | |||
904 | request_complete(ep, req, -ECONNRESET); | ||
905 | |||
906 | /* Process the next request if any */ | ||
907 | submit_next_request(ep); | ||
908 | spin_unlock_irqrestore(&udc->lock, flags); | ||
909 | |||
910 | return 0; | ||
911 | } | ||
912 | |||
913 | static int usba_ep_set_halt(struct usb_ep *_ep, int value) | ||
914 | { | ||
915 | struct usba_ep *ep = to_usba_ep(_ep); | ||
916 | struct usba_udc *udc = ep->udc; | ||
917 | unsigned long flags; | ||
918 | int ret = 0; | ||
919 | |||
920 | DBG(DBG_GADGET, "endpoint %s: %s HALT\n", ep->ep.name, | ||
921 | value ? "set" : "clear"); | ||
922 | |||
923 | if (!ep->desc) { | ||
924 | DBG(DBG_ERR, "Attempted to halt uninitialized ep %s\n", | ||
925 | ep->ep.name); | ||
926 | return -ENODEV; | ||
927 | } | ||
928 | if (ep->is_isoc) { | ||
929 | DBG(DBG_ERR, "Attempted to halt isochronous ep %s\n", | ||
930 | ep->ep.name); | ||
931 | return -ENOTTY; | ||
932 | } | ||
933 | |||
934 | spin_lock_irqsave(&udc->lock, flags); | ||
935 | |||
936 | /* | ||
937 | * We can't halt IN endpoints while there are still data to be | ||
938 | * transferred | ||
939 | */ | ||
940 | if (!list_empty(&ep->queue) | ||
941 | || ((value && ep->is_in && (usba_ep_readl(ep, STA) | ||
942 | & USBA_BF(BUSY_BANKS, -1L))))) { | ||
943 | ret = -EAGAIN; | ||
944 | } else { | ||
945 | if (value) | ||
946 | usba_ep_writel(ep, SET_STA, USBA_FORCE_STALL); | ||
947 | else | ||
948 | usba_ep_writel(ep, CLR_STA, | ||
949 | USBA_FORCE_STALL | USBA_TOGGLE_CLR); | ||
950 | usba_ep_readl(ep, STA); | ||
951 | } | ||
952 | |||
953 | spin_unlock_irqrestore(&udc->lock, flags); | ||
954 | |||
955 | return ret; | ||
956 | } | ||
957 | |||
958 | static int usba_ep_fifo_status(struct usb_ep *_ep) | ||
959 | { | ||
960 | struct usba_ep *ep = to_usba_ep(_ep); | ||
961 | |||
962 | return USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA)); | ||
963 | } | ||
964 | |||
965 | static void usba_ep_fifo_flush(struct usb_ep *_ep) | ||
966 | { | ||
967 | struct usba_ep *ep = to_usba_ep(_ep); | ||
968 | struct usba_udc *udc = ep->udc; | ||
969 | |||
970 | usba_writel(udc, EPT_RST, 1 << ep->index); | ||
971 | } | ||
972 | |||
973 | static const struct usb_ep_ops usba_ep_ops = { | ||
974 | .enable = usba_ep_enable, | ||
975 | .disable = usba_ep_disable, | ||
976 | .alloc_request = usba_ep_alloc_request, | ||
977 | .free_request = usba_ep_free_request, | ||
978 | .queue = usba_ep_queue, | ||
979 | .dequeue = usba_ep_dequeue, | ||
980 | .set_halt = usba_ep_set_halt, | ||
981 | .fifo_status = usba_ep_fifo_status, | ||
982 | .fifo_flush = usba_ep_fifo_flush, | ||
983 | }; | ||
984 | |||
985 | static int usba_udc_get_frame(struct usb_gadget *gadget) | ||
986 | { | ||
987 | struct usba_udc *udc = to_usba_udc(gadget); | ||
988 | |||
989 | return USBA_BFEXT(FRAME_NUMBER, usba_readl(udc, FNUM)); | ||
990 | } | ||
991 | |||
992 | static int usba_udc_wakeup(struct usb_gadget *gadget) | ||
993 | { | ||
994 | struct usba_udc *udc = to_usba_udc(gadget); | ||
995 | unsigned long flags; | ||
996 | u32 ctrl; | ||
997 | int ret = -EINVAL; | ||
998 | |||
999 | spin_lock_irqsave(&udc->lock, flags); | ||
1000 | if (udc->devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { | ||
1001 | ctrl = usba_readl(udc, CTRL); | ||
1002 | usba_writel(udc, CTRL, ctrl | USBA_REMOTE_WAKE_UP); | ||
1003 | ret = 0; | ||
1004 | } | ||
1005 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1006 | |||
1007 | return ret; | ||
1008 | } | ||
1009 | |||
1010 | static int | ||
1011 | usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered) | ||
1012 | { | ||
1013 | struct usba_udc *udc = to_usba_udc(gadget); | ||
1014 | unsigned long flags; | ||
1015 | |||
1016 | spin_lock_irqsave(&udc->lock, flags); | ||
1017 | if (is_selfpowered) | ||
1018 | udc->devstatus |= 1 << USB_DEVICE_SELF_POWERED; | ||
1019 | else | ||
1020 | udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED); | ||
1021 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1022 | |||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | static const struct usb_gadget_ops usba_udc_ops = { | ||
1027 | .get_frame = usba_udc_get_frame, | ||
1028 | .wakeup = usba_udc_wakeup, | ||
1029 | .set_selfpowered = usba_udc_set_selfpowered, | ||
1030 | }; | ||
1031 | |||
1032 | #define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ | ||
1033 | { \ | ||
1034 | .ep = { \ | ||
1035 | .ops = &usba_ep_ops, \ | ||
1036 | .name = nam, \ | ||
1037 | .maxpacket = maxpkt, \ | ||
1038 | }, \ | ||
1039 | .udc = &the_udc, \ | ||
1040 | .queue = LIST_HEAD_INIT(usba_ep[idx].queue), \ | ||
1041 | .fifo_size = maxpkt, \ | ||
1042 | .nr_banks = maxbk, \ | ||
1043 | .index = idx, \ | ||
1044 | .can_dma = dma, \ | ||
1045 | .can_isoc = isoc, \ | ||
1046 | } | ||
1047 | |||
1048 | static struct usba_ep usba_ep[] = { | ||
1049 | EP("ep0", 0, 64, 1, 0, 0), | ||
1050 | EP("ep1in-bulk", 1, 512, 2, 1, 1), | ||
1051 | EP("ep2out-bulk", 2, 512, 2, 1, 1), | ||
1052 | EP("ep3in-int", 3, 64, 3, 1, 0), | ||
1053 | EP("ep4out-int", 4, 64, 3, 1, 0), | ||
1054 | EP("ep5in-iso", 5, 1024, 3, 1, 1), | ||
1055 | EP("ep6out-iso", 6, 1024, 3, 1, 1), | ||
1056 | }; | ||
1057 | #undef EP | ||
1058 | |||
1059 | static struct usb_endpoint_descriptor usba_ep0_desc = { | ||
1060 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
1061 | .bDescriptorType = USB_DT_ENDPOINT, | ||
1062 | .bEndpointAddress = 0, | ||
1063 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
1064 | .wMaxPacketSize = __constant_cpu_to_le16(64), | ||
1065 | /* FIXME: I have no idea what to put here */ | ||
1066 | .bInterval = 1, | ||
1067 | }; | ||
1068 | |||
1069 | static void nop_release(struct device *dev) | ||
1070 | { | ||
1071 | |||
1072 | } | ||
1073 | |||
1074 | static struct usba_udc the_udc = { | ||
1075 | .gadget = { | ||
1076 | .ops = &usba_udc_ops, | ||
1077 | .ep0 = &usba_ep[0].ep, | ||
1078 | .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list), | ||
1079 | .is_dualspeed = 1, | ||
1080 | .name = "atmel_usba_udc", | ||
1081 | .dev = { | ||
1082 | .bus_id = "gadget", | ||
1083 | .release = nop_release, | ||
1084 | }, | ||
1085 | }, | ||
1086 | |||
1087 | .lock = SPIN_LOCK_UNLOCKED, | ||
1088 | }; | ||
1089 | |||
1090 | /* | ||
1091 | * Called with interrupts disabled and udc->lock held. | ||
1092 | */ | ||
1093 | static void reset_all_endpoints(struct usba_udc *udc) | ||
1094 | { | ||
1095 | struct usba_ep *ep; | ||
1096 | struct usba_request *req, *tmp_req; | ||
1097 | |||
1098 | usba_writel(udc, EPT_RST, ~0UL); | ||
1099 | |||
1100 | ep = to_usba_ep(udc->gadget.ep0); | ||
1101 | list_for_each_entry_safe(req, tmp_req, &ep->queue, queue) { | ||
1102 | list_del_init(&req->queue); | ||
1103 | request_complete(ep, req, -ECONNRESET); | ||
1104 | } | ||
1105 | |||
1106 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { | ||
1107 | if (ep->desc) { | ||
1108 | spin_unlock(&udc->lock); | ||
1109 | usba_ep_disable(&ep->ep); | ||
1110 | spin_lock(&udc->lock); | ||
1111 | } | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | static struct usba_ep *get_ep_by_addr(struct usba_udc *udc, u16 wIndex) | ||
1116 | { | ||
1117 | struct usba_ep *ep; | ||
1118 | |||
1119 | if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0) | ||
1120 | return to_usba_ep(udc->gadget.ep0); | ||
1121 | |||
1122 | list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) { | ||
1123 | u8 bEndpointAddress; | ||
1124 | |||
1125 | if (!ep->desc) | ||
1126 | continue; | ||
1127 | bEndpointAddress = ep->desc->bEndpointAddress; | ||
1128 | if ((wIndex ^ bEndpointAddress) & USB_DIR_IN) | ||
1129 | continue; | ||
1130 | if ((bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) | ||
1131 | == (wIndex & USB_ENDPOINT_NUMBER_MASK)) | ||
1132 | return ep; | ||
1133 | } | ||
1134 | |||
1135 | return NULL; | ||
1136 | } | ||
1137 | |||
1138 | /* Called with interrupts disabled and udc->lock held */ | ||
1139 | static inline void set_protocol_stall(struct usba_udc *udc, struct usba_ep *ep) | ||
1140 | { | ||
1141 | usba_ep_writel(ep, SET_STA, USBA_FORCE_STALL); | ||
1142 | ep->state = WAIT_FOR_SETUP; | ||
1143 | } | ||
1144 | |||
1145 | static inline int is_stalled(struct usba_udc *udc, struct usba_ep *ep) | ||
1146 | { | ||
1147 | if (usba_ep_readl(ep, STA) & USBA_FORCE_STALL) | ||
1148 | return 1; | ||
1149 | return 0; | ||
1150 | } | ||
1151 | |||
1152 | static inline void set_address(struct usba_udc *udc, unsigned int addr) | ||
1153 | { | ||
1154 | u32 regval; | ||
1155 | |||
1156 | DBG(DBG_BUS, "setting address %u...\n", addr); | ||
1157 | regval = usba_readl(udc, CTRL); | ||
1158 | regval = USBA_BFINS(DEV_ADDR, addr, regval); | ||
1159 | usba_writel(udc, CTRL, regval); | ||
1160 | } | ||
1161 | |||
1162 | static int do_test_mode(struct usba_udc *udc) | ||
1163 | { | ||
1164 | static const char test_packet_buffer[] = { | ||
1165 | /* JKJKJKJK * 9 */ | ||
1166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
1167 | /* JJKKJJKK * 8 */ | ||
1168 | 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, | ||
1169 | /* JJKKJJKK * 8 */ | ||
1170 | 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, | ||
1171 | /* JJJJJJJKKKKKKK * 8 */ | ||
1172 | 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
1173 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
1174 | /* JJJJJJJK * 8 */ | ||
1175 | 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, | ||
1176 | /* {JKKKKKKK * 10}, JK */ | ||
1177 | 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E | ||
1178 | }; | ||
1179 | struct usba_ep *ep; | ||
1180 | struct device *dev = &udc->pdev->dev; | ||
1181 | int test_mode; | ||
1182 | |||
1183 | test_mode = udc->test_mode; | ||
1184 | |||
1185 | /* Start from a clean slate */ | ||
1186 | reset_all_endpoints(udc); | ||
1187 | |||
1188 | switch (test_mode) { | ||
1189 | case 0x0100: | ||
1190 | /* Test_J */ | ||
1191 | usba_writel(udc, TST, USBA_TST_J_MODE); | ||
1192 | dev_info(dev, "Entering Test_J mode...\n"); | ||
1193 | break; | ||
1194 | case 0x0200: | ||
1195 | /* Test_K */ | ||
1196 | usba_writel(udc, TST, USBA_TST_K_MODE); | ||
1197 | dev_info(dev, "Entering Test_K mode...\n"); | ||
1198 | break; | ||
1199 | case 0x0300: | ||
1200 | /* | ||
1201 | * Test_SE0_NAK: Force high-speed mode and set up ep0 | ||
1202 | * for Bulk IN transfers | ||
1203 | */ | ||
1204 | ep = &usba_ep[0]; | ||
1205 | usba_writel(udc, TST, | ||
1206 | USBA_BF(SPEED_CFG, USBA_SPEED_CFG_FORCE_HIGH)); | ||
1207 | usba_ep_writel(ep, CFG, | ||
1208 | USBA_BF(EPT_SIZE, USBA_EPT_SIZE_64) | ||
1209 | | USBA_EPT_DIR_IN | ||
1210 | | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK) | ||
1211 | | USBA_BF(BK_NUMBER, 1)); | ||
1212 | if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) { | ||
1213 | set_protocol_stall(udc, ep); | ||
1214 | dev_err(dev, "Test_SE0_NAK: ep0 not mapped\n"); | ||
1215 | } else { | ||
1216 | usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE); | ||
1217 | dev_info(dev, "Entering Test_SE0_NAK mode...\n"); | ||
1218 | } | ||
1219 | break; | ||
1220 | case 0x0400: | ||
1221 | /* Test_Packet */ | ||
1222 | ep = &usba_ep[0]; | ||
1223 | usba_ep_writel(ep, CFG, | ||
1224 | USBA_BF(EPT_SIZE, USBA_EPT_SIZE_64) | ||
1225 | | USBA_EPT_DIR_IN | ||
1226 | | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK) | ||
1227 | | USBA_BF(BK_NUMBER, 1)); | ||
1228 | if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) { | ||
1229 | set_protocol_stall(udc, ep); | ||
1230 | dev_err(dev, "Test_Packet: ep0 not mapped\n"); | ||
1231 | } else { | ||
1232 | usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE); | ||
1233 | usba_writel(udc, TST, USBA_TST_PKT_MODE); | ||
1234 | copy_to_fifo(ep->fifo, test_packet_buffer, | ||
1235 | sizeof(test_packet_buffer)); | ||
1236 | usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); | ||
1237 | dev_info(dev, "Entering Test_Packet mode...\n"); | ||
1238 | } | ||
1239 | break; | ||
1240 | default: | ||
1241 | dev_err(dev, "Invalid test mode: 0x%04x\n", test_mode); | ||
1242 | return -EINVAL; | ||
1243 | } | ||
1244 | |||
1245 | return 0; | ||
1246 | } | ||
1247 | |||
1248 | /* Avoid overly long expressions */ | ||
1249 | static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq) | ||
1250 | { | ||
1251 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) | ||
1252 | return true; | ||
1253 | return false; | ||
1254 | } | ||
1255 | |||
1256 | static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq) | ||
1257 | { | ||
1258 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE)) | ||
1259 | return true; | ||
1260 | return false; | ||
1261 | } | ||
1262 | |||
1263 | static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) | ||
1264 | { | ||
1265 | if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT)) | ||
1266 | return true; | ||
1267 | return false; | ||
1268 | } | ||
1269 | |||
1270 | static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | ||
1271 | struct usb_ctrlrequest *crq) | ||
1272 | { | ||
1273 | int retval = 0;; | ||
1274 | |||
1275 | switch (crq->bRequest) { | ||
1276 | case USB_REQ_GET_STATUS: { | ||
1277 | u16 status; | ||
1278 | |||
1279 | if (crq->bRequestType == (USB_DIR_IN | USB_RECIP_DEVICE)) { | ||
1280 | status = cpu_to_le16(udc->devstatus); | ||
1281 | } else if (crq->bRequestType | ||
1282 | == (USB_DIR_IN | USB_RECIP_INTERFACE)) { | ||
1283 | status = __constant_cpu_to_le16(0); | ||
1284 | } else if (crq->bRequestType | ||
1285 | == (USB_DIR_IN | USB_RECIP_ENDPOINT)) { | ||
1286 | struct usba_ep *target; | ||
1287 | |||
1288 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); | ||
1289 | if (!target) | ||
1290 | goto stall; | ||
1291 | |||
1292 | status = 0; | ||
1293 | if (is_stalled(udc, target)) | ||
1294 | status |= __constant_cpu_to_le16(1); | ||
1295 | } else | ||
1296 | goto delegate; | ||
1297 | |||
1298 | /* Write directly to the FIFO. No queueing is done. */ | ||
1299 | if (crq->wLength != __constant_cpu_to_le16(sizeof(status))) | ||
1300 | goto stall; | ||
1301 | ep->state = DATA_STAGE_IN; | ||
1302 | __raw_writew(status, ep->fifo); | ||
1303 | usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); | ||
1304 | break; | ||
1305 | } | ||
1306 | |||
1307 | case USB_REQ_CLEAR_FEATURE: { | ||
1308 | if (crq->bRequestType == USB_RECIP_DEVICE) { | ||
1309 | if (feature_is_dev_remote_wakeup(crq)) | ||
1310 | udc->devstatus | ||
1311 | &= ~(1 << USB_DEVICE_REMOTE_WAKEUP); | ||
1312 | else | ||
1313 | /* Can't CLEAR_FEATURE TEST_MODE */ | ||
1314 | goto stall; | ||
1315 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | ||
1316 | struct usba_ep *target; | ||
1317 | |||
1318 | if (crq->wLength != __constant_cpu_to_le16(0) | ||
1319 | || !feature_is_ep_halt(crq)) | ||
1320 | goto stall; | ||
1321 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); | ||
1322 | if (!target) | ||
1323 | goto stall; | ||
1324 | |||
1325 | usba_ep_writel(target, CLR_STA, USBA_FORCE_STALL); | ||
1326 | if (target->index != 0) | ||
1327 | usba_ep_writel(target, CLR_STA, | ||
1328 | USBA_TOGGLE_CLR); | ||
1329 | } else { | ||
1330 | goto delegate; | ||
1331 | } | ||
1332 | |||
1333 | send_status(udc, ep); | ||
1334 | break; | ||
1335 | } | ||
1336 | |||
1337 | case USB_REQ_SET_FEATURE: { | ||
1338 | if (crq->bRequestType == USB_RECIP_DEVICE) { | ||
1339 | if (feature_is_dev_test_mode(crq)) { | ||
1340 | send_status(udc, ep); | ||
1341 | ep->state = STATUS_STAGE_TEST; | ||
1342 | udc->test_mode = le16_to_cpu(crq->wIndex); | ||
1343 | return 0; | ||
1344 | } else if (feature_is_dev_remote_wakeup(crq)) { | ||
1345 | udc->devstatus |= 1 << USB_DEVICE_REMOTE_WAKEUP; | ||
1346 | } else { | ||
1347 | goto stall; | ||
1348 | } | ||
1349 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | ||
1350 | struct usba_ep *target; | ||
1351 | |||
1352 | if (crq->wLength != __constant_cpu_to_le16(0) | ||
1353 | || !feature_is_ep_halt(crq)) | ||
1354 | goto stall; | ||
1355 | |||
1356 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); | ||
1357 | if (!target) | ||
1358 | goto stall; | ||
1359 | |||
1360 | usba_ep_writel(target, SET_STA, USBA_FORCE_STALL); | ||
1361 | } else | ||
1362 | goto delegate; | ||
1363 | |||
1364 | send_status(udc, ep); | ||
1365 | break; | ||
1366 | } | ||
1367 | |||
1368 | case USB_REQ_SET_ADDRESS: | ||
1369 | if (crq->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE)) | ||
1370 | goto delegate; | ||
1371 | |||
1372 | set_address(udc, le16_to_cpu(crq->wValue)); | ||
1373 | send_status(udc, ep); | ||
1374 | ep->state = STATUS_STAGE_ADDR; | ||
1375 | break; | ||
1376 | |||
1377 | default: | ||
1378 | delegate: | ||
1379 | spin_unlock(&udc->lock); | ||
1380 | retval = udc->driver->setup(&udc->gadget, crq); | ||
1381 | spin_lock(&udc->lock); | ||
1382 | } | ||
1383 | |||
1384 | return retval; | ||
1385 | |||
1386 | stall: | ||
1387 | printk(KERN_ERR | ||
1388 | "udc: %s: Invalid setup request: %02x.%02x v%04x i%04x l%d, " | ||
1389 | "halting endpoint...\n", | ||
1390 | ep->ep.name, crq->bRequestType, crq->bRequest, | ||
1391 | le16_to_cpu(crq->wValue), le16_to_cpu(crq->wIndex), | ||
1392 | le16_to_cpu(crq->wLength)); | ||
1393 | set_protocol_stall(udc, ep); | ||
1394 | return -1; | ||
1395 | } | ||
1396 | |||
1397 | static void usba_control_irq(struct usba_udc *udc, struct usba_ep *ep) | ||
1398 | { | ||
1399 | struct usba_request *req; | ||
1400 | u32 epstatus; | ||
1401 | u32 epctrl; | ||
1402 | |||
1403 | restart: | ||
1404 | epstatus = usba_ep_readl(ep, STA); | ||
1405 | epctrl = usba_ep_readl(ep, CTL); | ||
1406 | |||
1407 | DBG(DBG_INT, "%s [%d]: s/%08x c/%08x\n", | ||
1408 | ep->ep.name, ep->state, epstatus, epctrl); | ||
1409 | |||
1410 | req = NULL; | ||
1411 | if (!list_empty(&ep->queue)) | ||
1412 | req = list_entry(ep->queue.next, | ||
1413 | struct usba_request, queue); | ||
1414 | |||
1415 | if ((epctrl & USBA_TX_PK_RDY) && !(epstatus & USBA_TX_PK_RDY)) { | ||
1416 | if (req->submitted) | ||
1417 | next_fifo_transaction(ep, req); | ||
1418 | else | ||
1419 | submit_request(ep, req); | ||
1420 | |||
1421 | if (req->last_transaction) { | ||
1422 | usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY); | ||
1423 | usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); | ||
1424 | } | ||
1425 | goto restart; | ||
1426 | } | ||
1427 | if ((epstatus & epctrl) & USBA_TX_COMPLETE) { | ||
1428 | usba_ep_writel(ep, CLR_STA, USBA_TX_COMPLETE); | ||
1429 | |||
1430 | switch (ep->state) { | ||
1431 | case DATA_STAGE_IN: | ||
1432 | usba_ep_writel(ep, CTL_ENB, USBA_RX_BK_RDY); | ||
1433 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
1434 | ep->state = STATUS_STAGE_OUT; | ||
1435 | break; | ||
1436 | case STATUS_STAGE_ADDR: | ||
1437 | /* Activate our new address */ | ||
1438 | usba_writel(udc, CTRL, (usba_readl(udc, CTRL) | ||
1439 | | USBA_FADDR_EN)); | ||
1440 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
1441 | ep->state = WAIT_FOR_SETUP; | ||
1442 | break; | ||
1443 | case STATUS_STAGE_IN: | ||
1444 | if (req) { | ||
1445 | list_del_init(&req->queue); | ||
1446 | request_complete(ep, req, 0); | ||
1447 | submit_next_request(ep); | ||
1448 | } | ||
1449 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
1450 | ep->state = WAIT_FOR_SETUP; | ||
1451 | break; | ||
1452 | case STATUS_STAGE_TEST: | ||
1453 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
1454 | ep->state = WAIT_FOR_SETUP; | ||
1455 | if (do_test_mode(udc)) | ||
1456 | set_protocol_stall(udc, ep); | ||
1457 | break; | ||
1458 | default: | ||
1459 | printk(KERN_ERR | ||
1460 | "udc: %s: TXCOMP: Invalid endpoint state %d, " | ||
1461 | "halting endpoint...\n", | ||
1462 | ep->ep.name, ep->state); | ||
1463 | set_protocol_stall(udc, ep); | ||
1464 | break; | ||
1465 | } | ||
1466 | |||
1467 | goto restart; | ||
1468 | } | ||
1469 | if ((epstatus & epctrl) & USBA_RX_BK_RDY) { | ||
1470 | switch (ep->state) { | ||
1471 | case STATUS_STAGE_OUT: | ||
1472 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | ||
1473 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
1474 | |||
1475 | if (req) { | ||
1476 | list_del_init(&req->queue); | ||
1477 | request_complete(ep, req, 0); | ||
1478 | } | ||
1479 | ep->state = WAIT_FOR_SETUP; | ||
1480 | break; | ||
1481 | |||
1482 | case DATA_STAGE_OUT: | ||
1483 | receive_data(ep); | ||
1484 | break; | ||
1485 | |||
1486 | default: | ||
1487 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | ||
1488 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
1489 | printk(KERN_ERR | ||
1490 | "udc: %s: RXRDY: Invalid endpoint state %d, " | ||
1491 | "halting endpoint...\n", | ||
1492 | ep->ep.name, ep->state); | ||
1493 | set_protocol_stall(udc, ep); | ||
1494 | break; | ||
1495 | } | ||
1496 | |||
1497 | goto restart; | ||
1498 | } | ||
1499 | if (epstatus & USBA_RX_SETUP) { | ||
1500 | union { | ||
1501 | struct usb_ctrlrequest crq; | ||
1502 | unsigned long data[2]; | ||
1503 | } crq; | ||
1504 | unsigned int pkt_len; | ||
1505 | int ret; | ||
1506 | |||
1507 | if (ep->state != WAIT_FOR_SETUP) { | ||
1508 | /* | ||
1509 | * Didn't expect a SETUP packet at this | ||
1510 | * point. Clean up any pending requests (which | ||
1511 | * may be successful). | ||
1512 | */ | ||
1513 | int status = -EPROTO; | ||
1514 | |||
1515 | /* | ||
1516 | * RXRDY and TXCOMP are dropped when SETUP | ||
1517 | * packets arrive. Just pretend we received | ||
1518 | * the status packet. | ||
1519 | */ | ||
1520 | if (ep->state == STATUS_STAGE_OUT | ||
1521 | || ep->state == STATUS_STAGE_IN) { | ||
1522 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
1523 | status = 0; | ||
1524 | } | ||
1525 | |||
1526 | if (req) { | ||
1527 | list_del_init(&req->queue); | ||
1528 | request_complete(ep, req, status); | ||
1529 | } | ||
1530 | } | ||
1531 | |||
1532 | pkt_len = USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA)); | ||
1533 | DBG(DBG_HW, "Packet length: %u\n", pkt_len); | ||
1534 | if (pkt_len != sizeof(crq)) { | ||
1535 | printk(KERN_WARNING "udc: Invalid packet length %u " | ||
1536 | "(expected %lu)\n", pkt_len, sizeof(crq)); | ||
1537 | set_protocol_stall(udc, ep); | ||
1538 | return; | ||
1539 | } | ||
1540 | |||
1541 | DBG(DBG_FIFO, "Copying ctrl request from 0x%p:\n", ep->fifo); | ||
1542 | copy_from_fifo(crq.data, ep->fifo, sizeof(crq)); | ||
1543 | |||
1544 | /* Free up one bank in the FIFO so that we can | ||
1545 | * generate or receive a reply right away. */ | ||
1546 | usba_ep_writel(ep, CLR_STA, USBA_RX_SETUP); | ||
1547 | |||
1548 | /* printk(KERN_DEBUG "setup: %d: %02x.%02x\n", | ||
1549 | ep->state, crq.crq.bRequestType, | ||
1550 | crq.crq.bRequest); */ | ||
1551 | |||
1552 | if (crq.crq.bRequestType & USB_DIR_IN) { | ||
1553 | /* | ||
1554 | * The USB 2.0 spec states that "if wLength is | ||
1555 | * zero, there is no data transfer phase." | ||
1556 | * However, testusb #14 seems to actually | ||
1557 | * expect a data phase even if wLength = 0... | ||
1558 | */ | ||
1559 | ep->state = DATA_STAGE_IN; | ||
1560 | } else { | ||
1561 | if (crq.crq.wLength != __constant_cpu_to_le16(0)) | ||
1562 | ep->state = DATA_STAGE_OUT; | ||
1563 | else | ||
1564 | ep->state = STATUS_STAGE_IN; | ||
1565 | } | ||
1566 | |||
1567 | ret = -1; | ||
1568 | if (ep->index == 0) | ||
1569 | ret = handle_ep0_setup(udc, ep, &crq.crq); | ||
1570 | else { | ||
1571 | spin_unlock(&udc->lock); | ||
1572 | ret = udc->driver->setup(&udc->gadget, &crq.crq); | ||
1573 | spin_lock(&udc->lock); | ||
1574 | } | ||
1575 | |||
1576 | DBG(DBG_BUS, "req %02x.%02x, length %d, state %d, ret %d\n", | ||
1577 | crq.crq.bRequestType, crq.crq.bRequest, | ||
1578 | le16_to_cpu(crq.crq.wLength), ep->state, ret); | ||
1579 | |||
1580 | if (ret < 0) { | ||
1581 | /* Let the host know that we failed */ | ||
1582 | set_protocol_stall(udc, ep); | ||
1583 | } | ||
1584 | } | ||
1585 | } | ||
1586 | |||
1587 | static void usba_ep_irq(struct usba_udc *udc, struct usba_ep *ep) | ||
1588 | { | ||
1589 | struct usba_request *req; | ||
1590 | u32 epstatus; | ||
1591 | u32 epctrl; | ||
1592 | |||
1593 | epstatus = usba_ep_readl(ep, STA); | ||
1594 | epctrl = usba_ep_readl(ep, CTL); | ||
1595 | |||
1596 | DBG(DBG_INT, "%s: interrupt, status: 0x%08x\n", ep->ep.name, epstatus); | ||
1597 | |||
1598 | while ((epctrl & USBA_TX_PK_RDY) && !(epstatus & USBA_TX_PK_RDY)) { | ||
1599 | DBG(DBG_BUS, "%s: TX PK ready\n", ep->ep.name); | ||
1600 | |||
1601 | if (list_empty(&ep->queue)) { | ||
1602 | dev_warn(&udc->pdev->dev, "ep_irq: queue empty\n"); | ||
1603 | usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY); | ||
1604 | return; | ||
1605 | } | ||
1606 | |||
1607 | req = list_entry(ep->queue.next, struct usba_request, queue); | ||
1608 | |||
1609 | if (req->using_dma) { | ||
1610 | /* Send a zero-length packet */ | ||
1611 | usba_ep_writel(ep, SET_STA, | ||
1612 | USBA_TX_PK_RDY); | ||
1613 | usba_ep_writel(ep, CTL_DIS, | ||
1614 | USBA_TX_PK_RDY); | ||
1615 | list_del_init(&req->queue); | ||
1616 | submit_next_request(ep); | ||
1617 | request_complete(ep, req, 0); | ||
1618 | } else { | ||
1619 | if (req->submitted) | ||
1620 | next_fifo_transaction(ep, req); | ||
1621 | else | ||
1622 | submit_request(ep, req); | ||
1623 | |||
1624 | if (req->last_transaction) { | ||
1625 | list_del_init(&req->queue); | ||
1626 | submit_next_request(ep); | ||
1627 | request_complete(ep, req, 0); | ||
1628 | } | ||
1629 | } | ||
1630 | |||
1631 | epstatus = usba_ep_readl(ep, STA); | ||
1632 | epctrl = usba_ep_readl(ep, CTL); | ||
1633 | } | ||
1634 | if ((epstatus & epctrl) & USBA_RX_BK_RDY) { | ||
1635 | DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name); | ||
1636 | receive_data(ep); | ||
1637 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | ||
1638 | } | ||
1639 | } | ||
1640 | |||
1641 | static void usba_dma_irq(struct usba_udc *udc, struct usba_ep *ep) | ||
1642 | { | ||
1643 | struct usba_request *req; | ||
1644 | u32 status, control, pending; | ||
1645 | |||
1646 | status = usba_dma_readl(ep, STATUS); | ||
1647 | control = usba_dma_readl(ep, CONTROL); | ||
1648 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
1649 | ep->last_dma_status = status; | ||
1650 | #endif | ||
1651 | pending = status & control; | ||
1652 | DBG(DBG_INT | DBG_DMA, "dma irq, s/%#08x, c/%#08x\n", status, control); | ||
1653 | |||
1654 | if (status & USBA_DMA_CH_EN) { | ||
1655 | dev_err(&udc->pdev->dev, | ||
1656 | "DMA_CH_EN is set after transfer is finished!\n"); | ||
1657 | dev_err(&udc->pdev->dev, | ||
1658 | "status=%#08x, pending=%#08x, control=%#08x\n", | ||
1659 | status, pending, control); | ||
1660 | |||
1661 | /* | ||
1662 | * try to pretend nothing happened. We might have to | ||
1663 | * do something here... | ||
1664 | */ | ||
1665 | } | ||
1666 | |||
1667 | if (list_empty(&ep->queue)) | ||
1668 | /* Might happen if a reset comes along at the right moment */ | ||
1669 | return; | ||
1670 | |||
1671 | if (pending & (USBA_DMA_END_TR_ST | USBA_DMA_END_BUF_ST)) { | ||
1672 | req = list_entry(ep->queue.next, struct usba_request, queue); | ||
1673 | usba_update_req(ep, req, status); | ||
1674 | |||
1675 | list_del_init(&req->queue); | ||
1676 | submit_next_request(ep); | ||
1677 | request_complete(ep, req, 0); | ||
1678 | } | ||
1679 | } | ||
1680 | |||
1681 | static irqreturn_t usba_udc_irq(int irq, void *devid) | ||
1682 | { | ||
1683 | struct usba_udc *udc = devid; | ||
1684 | u32 status; | ||
1685 | u32 dma_status; | ||
1686 | u32 ep_status; | ||
1687 | |||
1688 | spin_lock(&udc->lock); | ||
1689 | |||
1690 | status = usba_readl(udc, INT_STA); | ||
1691 | DBG(DBG_INT, "irq, status=%#08x\n", status); | ||
1692 | |||
1693 | if (status & USBA_DET_SUSPEND) { | ||
1694 | usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); | ||
1695 | DBG(DBG_BUS, "Suspend detected\n"); | ||
1696 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | ||
1697 | && udc->driver && udc->driver->suspend) { | ||
1698 | spin_unlock(&udc->lock); | ||
1699 | udc->driver->suspend(&udc->gadget); | ||
1700 | spin_lock(&udc->lock); | ||
1701 | } | ||
1702 | } | ||
1703 | |||
1704 | if (status & USBA_WAKE_UP) { | ||
1705 | usba_writel(udc, INT_CLR, USBA_WAKE_UP); | ||
1706 | DBG(DBG_BUS, "Wake Up CPU detected\n"); | ||
1707 | } | ||
1708 | |||
1709 | if (status & USBA_END_OF_RESUME) { | ||
1710 | usba_writel(udc, INT_CLR, USBA_END_OF_RESUME); | ||
1711 | DBG(DBG_BUS, "Resume detected\n"); | ||
1712 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | ||
1713 | && udc->driver && udc->driver->resume) { | ||
1714 | spin_unlock(&udc->lock); | ||
1715 | udc->driver->resume(&udc->gadget); | ||
1716 | spin_lock(&udc->lock); | ||
1717 | } | ||
1718 | } | ||
1719 | |||
1720 | dma_status = USBA_BFEXT(DMA_INT, status); | ||
1721 | if (dma_status) { | ||
1722 | int i; | ||
1723 | |||
1724 | for (i = 1; i < USBA_NR_ENDPOINTS; i++) | ||
1725 | if (dma_status & (1 << i)) | ||
1726 | usba_dma_irq(udc, &usba_ep[i]); | ||
1727 | } | ||
1728 | |||
1729 | ep_status = USBA_BFEXT(EPT_INT, status); | ||
1730 | if (ep_status) { | ||
1731 | int i; | ||
1732 | |||
1733 | for (i = 0; i < USBA_NR_ENDPOINTS; i++) | ||
1734 | if (ep_status & (1 << i)) { | ||
1735 | if (ep_is_control(&usba_ep[i])) | ||
1736 | usba_control_irq(udc, &usba_ep[i]); | ||
1737 | else | ||
1738 | usba_ep_irq(udc, &usba_ep[i]); | ||
1739 | } | ||
1740 | } | ||
1741 | |||
1742 | if (status & USBA_END_OF_RESET) { | ||
1743 | struct usba_ep *ep0; | ||
1744 | |||
1745 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); | ||
1746 | reset_all_endpoints(udc); | ||
1747 | |||
1748 | if (status & USBA_HIGH_SPEED) { | ||
1749 | DBG(DBG_BUS, "High-speed bus reset detected\n"); | ||
1750 | udc->gadget.speed = USB_SPEED_HIGH; | ||
1751 | } else { | ||
1752 | DBG(DBG_BUS, "Full-speed bus reset detected\n"); | ||
1753 | udc->gadget.speed = USB_SPEED_FULL; | ||
1754 | } | ||
1755 | |||
1756 | ep0 = &usba_ep[0]; | ||
1757 | ep0->desc = &usba_ep0_desc; | ||
1758 | ep0->state = WAIT_FOR_SETUP; | ||
1759 | usba_ep_writel(ep0, CFG, | ||
1760 | (USBA_BF(EPT_SIZE, EP0_EPT_SIZE) | ||
1761 | | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL) | ||
1762 | | USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE))); | ||
1763 | usba_ep_writel(ep0, CTL_ENB, | ||
1764 | USBA_EPT_ENABLE | USBA_RX_SETUP); | ||
1765 | usba_writel(udc, INT_ENB, | ||
1766 | (usba_readl(udc, INT_ENB) | ||
1767 | | USBA_BF(EPT_INT, 1) | ||
1768 | | USBA_DET_SUSPEND | ||
1769 | | USBA_END_OF_RESUME)); | ||
1770 | |||
1771 | if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED)) | ||
1772 | dev_warn(&udc->pdev->dev, | ||
1773 | "WARNING: EP0 configuration is invalid!\n"); | ||
1774 | } | ||
1775 | |||
1776 | spin_unlock(&udc->lock); | ||
1777 | |||
1778 | return IRQ_HANDLED; | ||
1779 | } | ||
1780 | |||
1781 | static irqreturn_t usba_vbus_irq(int irq, void *devid) | ||
1782 | { | ||
1783 | struct usba_udc *udc = devid; | ||
1784 | int vbus; | ||
1785 | |||
1786 | /* debounce */ | ||
1787 | udelay(10); | ||
1788 | |||
1789 | spin_lock(&udc->lock); | ||
1790 | |||
1791 | /* May happen if Vbus pin toggles during probe() */ | ||
1792 | if (!udc->driver) | ||
1793 | goto out; | ||
1794 | |||
1795 | vbus = gpio_get_value(udc->vbus_pin); | ||
1796 | if (vbus != udc->vbus_prev) { | ||
1797 | if (vbus) { | ||
1798 | usba_writel(udc, CTRL, USBA_EN_USBA); | ||
1799 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | ||
1800 | } else { | ||
1801 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1802 | reset_all_endpoints(udc); | ||
1803 | usba_writel(udc, CTRL, 0); | ||
1804 | spin_unlock(&udc->lock); | ||
1805 | udc->driver->disconnect(&udc->gadget); | ||
1806 | spin_lock(&udc->lock); | ||
1807 | } | ||
1808 | udc->vbus_prev = vbus; | ||
1809 | } | ||
1810 | |||
1811 | out: | ||
1812 | spin_unlock(&udc->lock); | ||
1813 | |||
1814 | return IRQ_HANDLED; | ||
1815 | } | ||
1816 | |||
1817 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
1818 | { | ||
1819 | struct usba_udc *udc = &the_udc; | ||
1820 | unsigned long flags; | ||
1821 | int ret; | ||
1822 | |||
1823 | if (!udc->pdev) | ||
1824 | return -ENODEV; | ||
1825 | |||
1826 | spin_lock_irqsave(&udc->lock, flags); | ||
1827 | if (udc->driver) { | ||
1828 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1829 | return -EBUSY; | ||
1830 | } | ||
1831 | |||
1832 | udc->devstatus = 1 << USB_DEVICE_SELF_POWERED; | ||
1833 | udc->driver = driver; | ||
1834 | udc->gadget.dev.driver = &driver->driver; | ||
1835 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1836 | |||
1837 | clk_enable(udc->pclk); | ||
1838 | clk_enable(udc->hclk); | ||
1839 | |||
1840 | ret = driver->bind(&udc->gadget); | ||
1841 | if (ret) { | ||
1842 | DBG(DBG_ERR, "Could not bind to driver %s: error %d\n", | ||
1843 | driver->driver.name, ret); | ||
1844 | goto err_driver_bind; | ||
1845 | } | ||
1846 | |||
1847 | DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name); | ||
1848 | |||
1849 | udc->vbus_prev = 0; | ||
1850 | if (udc->vbus_pin != -1) | ||
1851 | enable_irq(gpio_to_irq(udc->vbus_pin)); | ||
1852 | |||
1853 | /* If Vbus is present, enable the controller and wait for reset */ | ||
1854 | spin_lock_irqsave(&udc->lock, flags); | ||
1855 | if (vbus_is_present(udc) && udc->vbus_prev == 0) { | ||
1856 | usba_writel(udc, CTRL, USBA_EN_USBA); | ||
1857 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | ||
1858 | } | ||
1859 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1860 | |||
1861 | return 0; | ||
1862 | |||
1863 | err_driver_bind: | ||
1864 | udc->driver = NULL; | ||
1865 | udc->gadget.dev.driver = NULL; | ||
1866 | return ret; | ||
1867 | } | ||
1868 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
1869 | |||
1870 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
1871 | { | ||
1872 | struct usba_udc *udc = &the_udc; | ||
1873 | unsigned long flags; | ||
1874 | |||
1875 | if (!udc->pdev) | ||
1876 | return -ENODEV; | ||
1877 | if (driver != udc->driver) | ||
1878 | return -EINVAL; | ||
1879 | |||
1880 | if (udc->vbus_pin != -1) | ||
1881 | disable_irq(gpio_to_irq(udc->vbus_pin)); | ||
1882 | |||
1883 | spin_lock_irqsave(&udc->lock, flags); | ||
1884 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1885 | reset_all_endpoints(udc); | ||
1886 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1887 | |||
1888 | /* This will also disable the DP pullup */ | ||
1889 | usba_writel(udc, CTRL, 0); | ||
1890 | |||
1891 | driver->unbind(&udc->gadget); | ||
1892 | udc->gadget.dev.driver = NULL; | ||
1893 | udc->driver = NULL; | ||
1894 | |||
1895 | clk_disable(udc->hclk); | ||
1896 | clk_disable(udc->pclk); | ||
1897 | |||
1898 | DBG(DBG_GADGET, "unregistered driver `%s'\n", driver->driver.name); | ||
1899 | |||
1900 | return 0; | ||
1901 | } | ||
1902 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
1903 | |||
1904 | static int __init usba_udc_probe(struct platform_device *pdev) | ||
1905 | { | ||
1906 | struct usba_platform_data *pdata = pdev->dev.platform_data; | ||
1907 | struct resource *regs, *fifo; | ||
1908 | struct clk *pclk, *hclk; | ||
1909 | struct usba_udc *udc = &the_udc; | ||
1910 | int irq, ret, i; | ||
1911 | |||
1912 | regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID); | ||
1913 | fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID); | ||
1914 | if (!regs || !fifo) | ||
1915 | return -ENXIO; | ||
1916 | |||
1917 | irq = platform_get_irq(pdev, 0); | ||
1918 | if (irq < 0) | ||
1919 | return irq; | ||
1920 | |||
1921 | pclk = clk_get(&pdev->dev, "pclk"); | ||
1922 | if (IS_ERR(pclk)) | ||
1923 | return PTR_ERR(pclk); | ||
1924 | hclk = clk_get(&pdev->dev, "hclk"); | ||
1925 | if (IS_ERR(hclk)) { | ||
1926 | ret = PTR_ERR(hclk); | ||
1927 | goto err_get_hclk; | ||
1928 | } | ||
1929 | |||
1930 | udc->pdev = pdev; | ||
1931 | udc->pclk = pclk; | ||
1932 | udc->hclk = hclk; | ||
1933 | udc->vbus_pin = -1; | ||
1934 | |||
1935 | ret = -ENOMEM; | ||
1936 | udc->regs = ioremap(regs->start, regs->end - regs->start + 1); | ||
1937 | if (!udc->regs) { | ||
1938 | dev_err(&pdev->dev, "Unable to map I/O memory, aborting.\n"); | ||
1939 | goto err_map_regs; | ||
1940 | } | ||
1941 | dev_info(&pdev->dev, "MMIO registers at 0x%08lx mapped at %p\n", | ||
1942 | (unsigned long)regs->start, udc->regs); | ||
1943 | udc->fifo = ioremap(fifo->start, fifo->end - fifo->start + 1); | ||
1944 | if (!udc->fifo) { | ||
1945 | dev_err(&pdev->dev, "Unable to map FIFO, aborting.\n"); | ||
1946 | goto err_map_fifo; | ||
1947 | } | ||
1948 | dev_info(&pdev->dev, "FIFO at 0x%08lx mapped at %p\n", | ||
1949 | (unsigned long)fifo->start, udc->fifo); | ||
1950 | |||
1951 | device_initialize(&udc->gadget.dev); | ||
1952 | udc->gadget.dev.parent = &pdev->dev; | ||
1953 | udc->gadget.dev.dma_mask = pdev->dev.dma_mask; | ||
1954 | |||
1955 | platform_set_drvdata(pdev, udc); | ||
1956 | |||
1957 | /* Make sure we start from a clean slate */ | ||
1958 | clk_enable(pclk); | ||
1959 | usba_writel(udc, CTRL, 0); | ||
1960 | clk_disable(pclk); | ||
1961 | |||
1962 | INIT_LIST_HEAD(&usba_ep[0].ep.ep_list); | ||
1963 | usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0); | ||
1964 | usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0); | ||
1965 | usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0); | ||
1966 | for (i = 1; i < ARRAY_SIZE(usba_ep); i++) { | ||
1967 | struct usba_ep *ep = &usba_ep[i]; | ||
1968 | |||
1969 | ep->ep_regs = udc->regs + USBA_EPT_BASE(i); | ||
1970 | ep->dma_regs = udc->regs + USBA_DMA_BASE(i); | ||
1971 | ep->fifo = udc->fifo + USBA_FIFO_BASE(i); | ||
1972 | |||
1973 | list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); | ||
1974 | } | ||
1975 | |||
1976 | ret = request_irq(irq, usba_udc_irq, 0, "atmel_usba_udc", udc); | ||
1977 | if (ret) { | ||
1978 | dev_err(&pdev->dev, "Cannot request irq %d (error %d)\n", | ||
1979 | irq, ret); | ||
1980 | goto err_request_irq; | ||
1981 | } | ||
1982 | udc->irq = irq; | ||
1983 | |||
1984 | ret = device_add(&udc->gadget.dev); | ||
1985 | if (ret) { | ||
1986 | dev_dbg(&pdev->dev, "Could not add gadget: %d\n", ret); | ||
1987 | goto err_device_add; | ||
1988 | } | ||
1989 | |||
1990 | if (pdata && pdata->vbus_pin != GPIO_PIN_NONE) { | ||
1991 | if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) { | ||
1992 | udc->vbus_pin = pdata->vbus_pin; | ||
1993 | |||
1994 | ret = request_irq(gpio_to_irq(udc->vbus_pin), | ||
1995 | usba_vbus_irq, 0, | ||
1996 | "atmel_usba_udc", udc); | ||
1997 | if (ret) { | ||
1998 | gpio_free(udc->vbus_pin); | ||
1999 | udc->vbus_pin = -1; | ||
2000 | dev_warn(&udc->pdev->dev, | ||
2001 | "failed to request vbus irq; " | ||
2002 | "assuming always on\n"); | ||
2003 | } else { | ||
2004 | disable_irq(gpio_to_irq(udc->vbus_pin)); | ||
2005 | } | ||
2006 | } | ||
2007 | } | ||
2008 | |||
2009 | usba_init_debugfs(udc); | ||
2010 | for (i = 1; i < ARRAY_SIZE(usba_ep); i++) | ||
2011 | usba_ep_init_debugfs(udc, &usba_ep[i]); | ||
2012 | |||
2013 | return 0; | ||
2014 | |||
2015 | err_device_add: | ||
2016 | free_irq(irq, udc); | ||
2017 | err_request_irq: | ||
2018 | iounmap(udc->fifo); | ||
2019 | err_map_fifo: | ||
2020 | iounmap(udc->regs); | ||
2021 | err_map_regs: | ||
2022 | clk_put(hclk); | ||
2023 | err_get_hclk: | ||
2024 | clk_put(pclk); | ||
2025 | |||
2026 | platform_set_drvdata(pdev, NULL); | ||
2027 | |||
2028 | return ret; | ||
2029 | } | ||
2030 | |||
2031 | static int __exit usba_udc_remove(struct platform_device *pdev) | ||
2032 | { | ||
2033 | struct usba_udc *udc; | ||
2034 | int i; | ||
2035 | |||
2036 | udc = platform_get_drvdata(pdev); | ||
2037 | |||
2038 | for (i = 1; i < ARRAY_SIZE(usba_ep); i++) | ||
2039 | usba_ep_cleanup_debugfs(&usba_ep[i]); | ||
2040 | usba_cleanup_debugfs(udc); | ||
2041 | |||
2042 | if (udc->vbus_pin != -1) | ||
2043 | gpio_free(udc->vbus_pin); | ||
2044 | |||
2045 | free_irq(udc->irq, udc); | ||
2046 | iounmap(udc->fifo); | ||
2047 | iounmap(udc->regs); | ||
2048 | clk_put(udc->hclk); | ||
2049 | clk_put(udc->pclk); | ||
2050 | |||
2051 | device_unregister(&udc->gadget.dev); | ||
2052 | |||
2053 | return 0; | ||
2054 | } | ||
2055 | |||
2056 | static struct platform_driver udc_driver = { | ||
2057 | .remove = __exit_p(usba_udc_remove), | ||
2058 | .driver = { | ||
2059 | .name = "atmel_usba_udc", | ||
2060 | }, | ||
2061 | }; | ||
2062 | |||
2063 | static int __init udc_init(void) | ||
2064 | { | ||
2065 | return platform_driver_probe(&udc_driver, usba_udc_probe); | ||
2066 | } | ||
2067 | module_init(udc_init); | ||
2068 | |||
2069 | static void __exit udc_exit(void) | ||
2070 | { | ||
2071 | platform_driver_unregister(&udc_driver); | ||
2072 | } | ||
2073 | module_exit(udc_exit); | ||
2074 | |||
2075 | MODULE_DESCRIPTION("Atmel USBA UDC driver"); | ||
2076 | MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); | ||
2077 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h new file mode 100644 index 000000000000..a68304e31a68 --- /dev/null +++ b/drivers/usb/gadget/atmel_usba_udc.h | |||
@@ -0,0 +1,352 @@ | |||
1 | /* | ||
2 | * Driver for the Atmel USBA high speed USB device controller | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Atmel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #ifndef __LINUX_USB_GADGET_USBA_UDC_H__ | ||
11 | #define __LINUX_USB_GADGET_USBA_UDC_H__ | ||
12 | |||
13 | /* USB register offsets */ | ||
14 | #define USBA_CTRL 0x0000 | ||
15 | #define USBA_FNUM 0x0004 | ||
16 | #define USBA_INT_ENB 0x0010 | ||
17 | #define USBA_INT_STA 0x0014 | ||
18 | #define USBA_INT_CLR 0x0018 | ||
19 | #define USBA_EPT_RST 0x001c | ||
20 | #define USBA_TST 0x00e0 | ||
21 | |||
22 | /* USB endpoint register offsets */ | ||
23 | #define USBA_EPT_CFG 0x0000 | ||
24 | #define USBA_EPT_CTL_ENB 0x0004 | ||
25 | #define USBA_EPT_CTL_DIS 0x0008 | ||
26 | #define USBA_EPT_CTL 0x000c | ||
27 | #define USBA_EPT_SET_STA 0x0014 | ||
28 | #define USBA_EPT_CLR_STA 0x0018 | ||
29 | #define USBA_EPT_STA 0x001c | ||
30 | |||
31 | /* USB DMA register offsets */ | ||
32 | #define USBA_DMA_NXT_DSC 0x0000 | ||
33 | #define USBA_DMA_ADDRESS 0x0004 | ||
34 | #define USBA_DMA_CONTROL 0x0008 | ||
35 | #define USBA_DMA_STATUS 0x000c | ||
36 | |||
37 | /* Bitfields in CTRL */ | ||
38 | #define USBA_DEV_ADDR_OFFSET 0 | ||
39 | #define USBA_DEV_ADDR_SIZE 7 | ||
40 | #define USBA_FADDR_EN (1 << 7) | ||
41 | #define USBA_EN_USBA (1 << 8) | ||
42 | #define USBA_DETACH (1 << 9) | ||
43 | #define USBA_REMOTE_WAKE_UP (1 << 10) | ||
44 | |||
45 | /* Bitfields in FNUM */ | ||
46 | #define USBA_MICRO_FRAME_NUM_OFFSET 0 | ||
47 | #define USBA_MICRO_FRAME_NUM_SIZE 3 | ||
48 | #define USBA_FRAME_NUMBER_OFFSET 3 | ||
49 | #define USBA_FRAME_NUMBER_SIZE 11 | ||
50 | #define USBA_FRAME_NUM_ERROR (1 << 31) | ||
51 | |||
52 | /* Bitfields in INT_ENB/INT_STA/INT_CLR */ | ||
53 | #define USBA_HIGH_SPEED (1 << 0) | ||
54 | #define USBA_DET_SUSPEND (1 << 1) | ||
55 | #define USBA_MICRO_SOF (1 << 2) | ||
56 | #define USBA_SOF (1 << 3) | ||
57 | #define USBA_END_OF_RESET (1 << 4) | ||
58 | #define USBA_WAKE_UP (1 << 5) | ||
59 | #define USBA_END_OF_RESUME (1 << 6) | ||
60 | #define USBA_UPSTREAM_RESUME (1 << 7) | ||
61 | #define USBA_EPT_INT_OFFSET 8 | ||
62 | #define USBA_EPT_INT_SIZE 16 | ||
63 | #define USBA_DMA_INT_OFFSET 24 | ||
64 | #define USBA_DMA_INT_SIZE 8 | ||
65 | |||
66 | /* Bitfields in EPT_RST */ | ||
67 | #define USBA_RST_OFFSET 0 | ||
68 | #define USBA_RST_SIZE 16 | ||
69 | |||
70 | /* Bitfields in USBA_TST */ | ||
71 | #define USBA_SPEED_CFG_OFFSET 0 | ||
72 | #define USBA_SPEED_CFG_SIZE 2 | ||
73 | #define USBA_TST_J_MODE (1 << 2) | ||
74 | #define USBA_TST_K_MODE (1 << 3) | ||
75 | #define USBA_TST_PKT_MODE (1 << 4) | ||
76 | #define USBA_OPMODE2 (1 << 5) | ||
77 | |||
78 | /* Bitfields in EPT_CFG */ | ||
79 | #define USBA_EPT_SIZE_OFFSET 0 | ||
80 | #define USBA_EPT_SIZE_SIZE 3 | ||
81 | #define USBA_EPT_DIR_IN (1 << 3) | ||
82 | #define USBA_EPT_TYPE_OFFSET 4 | ||
83 | #define USBA_EPT_TYPE_SIZE 2 | ||
84 | #define USBA_BK_NUMBER_OFFSET 6 | ||
85 | #define USBA_BK_NUMBER_SIZE 2 | ||
86 | #define USBA_NB_TRANS_OFFSET 8 | ||
87 | #define USBA_NB_TRANS_SIZE 2 | ||
88 | #define USBA_EPT_MAPPED (1 << 31) | ||
89 | |||
90 | /* Bitfields in EPT_CTL/EPT_CTL_ENB/EPT_CTL_DIS */ | ||
91 | #define USBA_EPT_ENABLE (1 << 0) | ||
92 | #define USBA_AUTO_VALID (1 << 1) | ||
93 | #define USBA_INTDIS_DMA (1 << 3) | ||
94 | #define USBA_NYET_DIS (1 << 4) | ||
95 | #define USBA_DATAX_RX (1 << 6) | ||
96 | #define USBA_MDATA_RX (1 << 7) | ||
97 | /* Bits 8-15 and 31 enable interrupts for respective bits in EPT_STA */ | ||
98 | #define USBA_BUSY_BANK_IE (1 << 18) | ||
99 | |||
100 | /* Bitfields in EPT_SET_STA/EPT_CLR_STA/EPT_STA */ | ||
101 | #define USBA_FORCE_STALL (1 << 5) | ||
102 | #define USBA_TOGGLE_CLR (1 << 6) | ||
103 | #define USBA_TOGGLE_SEQ_OFFSET 6 | ||
104 | #define USBA_TOGGLE_SEQ_SIZE 2 | ||
105 | #define USBA_ERR_OVFLW (1 << 8) | ||
106 | #define USBA_RX_BK_RDY (1 << 9) | ||
107 | #define USBA_KILL_BANK (1 << 9) | ||
108 | #define USBA_TX_COMPLETE (1 << 10) | ||
109 | #define USBA_TX_PK_RDY (1 << 11) | ||
110 | #define USBA_ISO_ERR_TRANS (1 << 11) | ||
111 | #define USBA_RX_SETUP (1 << 12) | ||
112 | #define USBA_ISO_ERR_FLOW (1 << 12) | ||
113 | #define USBA_STALL_SENT (1 << 13) | ||
114 | #define USBA_ISO_ERR_CRC (1 << 13) | ||
115 | #define USBA_ISO_ERR_NBTRANS (1 << 13) | ||
116 | #define USBA_NAK_IN (1 << 14) | ||
117 | #define USBA_ISO_ERR_FLUSH (1 << 14) | ||
118 | #define USBA_NAK_OUT (1 << 15) | ||
119 | #define USBA_CURRENT_BANK_OFFSET 16 | ||
120 | #define USBA_CURRENT_BANK_SIZE 2 | ||
121 | #define USBA_BUSY_BANKS_OFFSET 18 | ||
122 | #define USBA_BUSY_BANKS_SIZE 2 | ||
123 | #define USBA_BYTE_COUNT_OFFSET 20 | ||
124 | #define USBA_BYTE_COUNT_SIZE 11 | ||
125 | #define USBA_SHORT_PACKET (1 << 31) | ||
126 | |||
127 | /* Bitfields in DMA_CONTROL */ | ||
128 | #define USBA_DMA_CH_EN (1 << 0) | ||
129 | #define USBA_DMA_LINK (1 << 1) | ||
130 | #define USBA_DMA_END_TR_EN (1 << 2) | ||
131 | #define USBA_DMA_END_BUF_EN (1 << 3) | ||
132 | #define USBA_DMA_END_TR_IE (1 << 4) | ||
133 | #define USBA_DMA_END_BUF_IE (1 << 5) | ||
134 | #define USBA_DMA_DESC_LOAD_IE (1 << 6) | ||
135 | #define USBA_DMA_BURST_LOCK (1 << 7) | ||
136 | #define USBA_DMA_BUF_LEN_OFFSET 16 | ||
137 | #define USBA_DMA_BUF_LEN_SIZE 16 | ||
138 | |||
139 | /* Bitfields in DMA_STATUS */ | ||
140 | #define USBA_DMA_CH_ACTIVE (1 << 1) | ||
141 | #define USBA_DMA_END_TR_ST (1 << 4) | ||
142 | #define USBA_DMA_END_BUF_ST (1 << 5) | ||
143 | #define USBA_DMA_DESC_LOAD_ST (1 << 6) | ||
144 | |||
145 | /* Constants for SPEED_CFG */ | ||
146 | #define USBA_SPEED_CFG_NORMAL 0 | ||
147 | #define USBA_SPEED_CFG_FORCE_HIGH 2 | ||
148 | #define USBA_SPEED_CFG_FORCE_FULL 3 | ||
149 | |||
150 | /* Constants for EPT_SIZE */ | ||
151 | #define USBA_EPT_SIZE_8 0 | ||
152 | #define USBA_EPT_SIZE_16 1 | ||
153 | #define USBA_EPT_SIZE_32 2 | ||
154 | #define USBA_EPT_SIZE_64 3 | ||
155 | #define USBA_EPT_SIZE_128 4 | ||
156 | #define USBA_EPT_SIZE_256 5 | ||
157 | #define USBA_EPT_SIZE_512 6 | ||
158 | #define USBA_EPT_SIZE_1024 7 | ||
159 | |||
160 | /* Constants for EPT_TYPE */ | ||
161 | #define USBA_EPT_TYPE_CONTROL 0 | ||
162 | #define USBA_EPT_TYPE_ISO 1 | ||
163 | #define USBA_EPT_TYPE_BULK 2 | ||
164 | #define USBA_EPT_TYPE_INT 3 | ||
165 | |||
166 | /* Constants for BK_NUMBER */ | ||
167 | #define USBA_BK_NUMBER_ZERO 0 | ||
168 | #define USBA_BK_NUMBER_ONE 1 | ||
169 | #define USBA_BK_NUMBER_DOUBLE 2 | ||
170 | #define USBA_BK_NUMBER_TRIPLE 3 | ||
171 | |||
172 | /* Bit manipulation macros */ | ||
173 | #define USBA_BF(name, value) \ | ||
174 | (((value) & ((1 << USBA_##name##_SIZE) - 1)) \ | ||
175 | << USBA_##name##_OFFSET) | ||
176 | #define USBA_BFEXT(name, value) \ | ||
177 | (((value) >> USBA_##name##_OFFSET) \ | ||
178 | & ((1 << USBA_##name##_SIZE) - 1)) | ||
179 | #define USBA_BFINS(name, value, old) \ | ||
180 | (((old) & ~(((1 << USBA_##name##_SIZE) - 1) \ | ||
181 | << USBA_##name##_OFFSET)) \ | ||
182 | | USBA_BF(name, value)) | ||
183 | |||
184 | /* Register access macros */ | ||
185 | #define usba_readl(udc, reg) \ | ||
186 | __raw_readl((udc)->regs + USBA_##reg) | ||
187 | #define usba_writel(udc, reg, value) \ | ||
188 | __raw_writel((value), (udc)->regs + USBA_##reg) | ||
189 | #define usba_ep_readl(ep, reg) \ | ||
190 | __raw_readl((ep)->ep_regs + USBA_EPT_##reg) | ||
191 | #define usba_ep_writel(ep, reg, value) \ | ||
192 | __raw_writel((value), (ep)->ep_regs + USBA_EPT_##reg) | ||
193 | #define usba_dma_readl(ep, reg) \ | ||
194 | __raw_readl((ep)->dma_regs + USBA_DMA_##reg) | ||
195 | #define usba_dma_writel(ep, reg, value) \ | ||
196 | __raw_writel((value), (ep)->dma_regs + USBA_DMA_##reg) | ||
197 | |||
198 | /* Calculate base address for a given endpoint or DMA controller */ | ||
199 | #define USBA_EPT_BASE(x) (0x100 + (x) * 0x20) | ||
200 | #define USBA_DMA_BASE(x) (0x300 + (x) * 0x10) | ||
201 | #define USBA_FIFO_BASE(x) ((x) << 16) | ||
202 | |||
203 | /* Synth parameters */ | ||
204 | #define USBA_NR_ENDPOINTS 7 | ||
205 | |||
206 | #define EP0_FIFO_SIZE 64 | ||
207 | #define EP0_EPT_SIZE USBA_EPT_SIZE_64 | ||
208 | #define EP0_NR_BANKS 1 | ||
209 | |||
210 | /* | ||
211 | * REVISIT: Try to eliminate this value. Can we rely on req->mapped to | ||
212 | * provide this information? | ||
213 | */ | ||
214 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
215 | |||
216 | #define FIFO_IOMEM_ID 0 | ||
217 | #define CTRL_IOMEM_ID 1 | ||
218 | |||
219 | #ifdef DEBUG | ||
220 | #define DBG_ERR 0x0001 /* report all error returns */ | ||
221 | #define DBG_HW 0x0002 /* debug hardware initialization */ | ||
222 | #define DBG_GADGET 0x0004 /* calls to/from gadget driver */ | ||
223 | #define DBG_INT 0x0008 /* interrupts */ | ||
224 | #define DBG_BUS 0x0010 /* report changes in bus state */ | ||
225 | #define DBG_QUEUE 0x0020 /* debug request queue processing */ | ||
226 | #define DBG_FIFO 0x0040 /* debug FIFO contents */ | ||
227 | #define DBG_DMA 0x0080 /* debug DMA handling */ | ||
228 | #define DBG_REQ 0x0100 /* print out queued request length */ | ||
229 | #define DBG_ALL 0xffff | ||
230 | #define DBG_NONE 0x0000 | ||
231 | |||
232 | #define DEBUG_LEVEL (DBG_ERR) | ||
233 | #define DBG(level, fmt, ...) \ | ||
234 | do { \ | ||
235 | if ((level) & DEBUG_LEVEL) \ | ||
236 | printk(KERN_DEBUG "udc: " fmt, ## __VA_ARGS__); \ | ||
237 | } while (0) | ||
238 | #else | ||
239 | #define DBG(level, fmt...) | ||
240 | #endif | ||
241 | |||
242 | enum usba_ctrl_state { | ||
243 | WAIT_FOR_SETUP, | ||
244 | DATA_STAGE_IN, | ||
245 | DATA_STAGE_OUT, | ||
246 | STATUS_STAGE_IN, | ||
247 | STATUS_STAGE_OUT, | ||
248 | STATUS_STAGE_ADDR, | ||
249 | STATUS_STAGE_TEST, | ||
250 | }; | ||
251 | /* | ||
252 | EP_STATE_IDLE, | ||
253 | EP_STATE_SETUP, | ||
254 | EP_STATE_IN_DATA, | ||
255 | EP_STATE_OUT_DATA, | ||
256 | EP_STATE_SET_ADDR_STATUS, | ||
257 | EP_STATE_RX_STATUS, | ||
258 | EP_STATE_TX_STATUS, | ||
259 | EP_STATE_HALT, | ||
260 | */ | ||
261 | |||
262 | struct usba_dma_desc { | ||
263 | dma_addr_t next; | ||
264 | dma_addr_t addr; | ||
265 | u32 ctrl; | ||
266 | }; | ||
267 | |||
268 | struct usba_ep { | ||
269 | int state; | ||
270 | void __iomem *ep_regs; | ||
271 | void __iomem *dma_regs; | ||
272 | void __iomem *fifo; | ||
273 | struct usb_ep ep; | ||
274 | struct usba_udc *udc; | ||
275 | |||
276 | struct list_head queue; | ||
277 | const struct usb_endpoint_descriptor *desc; | ||
278 | |||
279 | u16 fifo_size; | ||
280 | u8 nr_banks; | ||
281 | u8 index; | ||
282 | unsigned int can_dma:1; | ||
283 | unsigned int can_isoc:1; | ||
284 | unsigned int is_isoc:1; | ||
285 | unsigned int is_in:1; | ||
286 | |||
287 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
288 | u32 last_dma_status; | ||
289 | struct dentry *debugfs_dir; | ||
290 | struct dentry *debugfs_queue; | ||
291 | struct dentry *debugfs_dma_status; | ||
292 | struct dentry *debugfs_state; | ||
293 | #endif | ||
294 | }; | ||
295 | |||
296 | struct usba_request { | ||
297 | struct usb_request req; | ||
298 | struct list_head queue; | ||
299 | |||
300 | u32 ctrl; | ||
301 | |||
302 | unsigned int submitted:1; | ||
303 | unsigned int last_transaction:1; | ||
304 | unsigned int using_dma:1; | ||
305 | unsigned int mapped:1; | ||
306 | }; | ||
307 | |||
308 | struct usba_udc { | ||
309 | /* Protect hw registers from concurrent modifications */ | ||
310 | spinlock_t lock; | ||
311 | |||
312 | void __iomem *regs; | ||
313 | void __iomem *fifo; | ||
314 | |||
315 | struct usb_gadget gadget; | ||
316 | struct usb_gadget_driver *driver; | ||
317 | struct platform_device *pdev; | ||
318 | int irq; | ||
319 | int vbus_pin; | ||
320 | struct clk *pclk; | ||
321 | struct clk *hclk; | ||
322 | |||
323 | u16 devstatus; | ||
324 | |||
325 | u16 test_mode; | ||
326 | int vbus_prev; | ||
327 | |||
328 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
329 | struct dentry *debugfs_root; | ||
330 | struct dentry *debugfs_regs; | ||
331 | #endif | ||
332 | }; | ||
333 | |||
334 | static inline struct usba_ep *to_usba_ep(struct usb_ep *ep) | ||
335 | { | ||
336 | return container_of(ep, struct usba_ep, ep); | ||
337 | } | ||
338 | |||
339 | static inline struct usba_request *to_usba_req(struct usb_request *req) | ||
340 | { | ||
341 | return container_of(req, struct usba_request, req); | ||
342 | } | ||
343 | |||
344 | static inline struct usba_udc *to_usba_udc(struct usb_gadget *gadget) | ||
345 | { | ||
346 | return container_of(gadget, struct usba_udc, gadget); | ||
347 | } | ||
348 | |||
349 | #define ep_is_control(ep) ((ep)->index == 0) | ||
350 | #define ep_is_idle(ep) ((ep)->state == EP_STATE_IDLE) | ||
351 | |||
352 | #endif /* __LINUX_USB_GADGET_USBA_UDC_H */ | ||
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index c6760aee1e5c..a4e54b2743f0 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | 26 | ||
27 | #include <linux/usb/ch9.h> | 27 | #include <linux/usb/ch9.h> |
28 | #include <linux/usb_gadget.h> | 28 | #include <linux/usb/gadget.h> |
29 | 29 | ||
30 | 30 | ||
31 | /** | 31 | /** |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index d008d1360a7a..9db2482bdfa2 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <linux/interrupt.h> | 46 | #include <linux/interrupt.h> |
47 | #include <linux/platform_device.h> | 47 | #include <linux/platform_device.h> |
48 | #include <linux/usb.h> | 48 | #include <linux/usb.h> |
49 | #include <linux/usb_gadget.h> | 49 | #include <linux/usb/gadget.h> |
50 | 50 | ||
51 | #include <asm/byteorder.h> | 51 | #include <asm/byteorder.h> |
52 | #include <asm/io.h> | 52 | #include <asm/io.h> |
@@ -962,13 +962,13 @@ static struct platform_driver dummy_udc_driver = { | |||
962 | 962 | ||
963 | static int dummy_urb_enqueue ( | 963 | static int dummy_urb_enqueue ( |
964 | struct usb_hcd *hcd, | 964 | struct usb_hcd *hcd, |
965 | struct usb_host_endpoint *ep, | ||
966 | struct urb *urb, | 965 | struct urb *urb, |
967 | gfp_t mem_flags | 966 | gfp_t mem_flags |
968 | ) { | 967 | ) { |
969 | struct dummy *dum; | 968 | struct dummy *dum; |
970 | struct urbp *urbp; | 969 | struct urbp *urbp; |
971 | unsigned long flags; | 970 | unsigned long flags; |
971 | int rc; | ||
972 | 972 | ||
973 | if (!urb->transfer_buffer && urb->transfer_buffer_length) | 973 | if (!urb->transfer_buffer && urb->transfer_buffer_length) |
974 | return -EINVAL; | 974 | return -EINVAL; |
@@ -980,6 +980,11 @@ static int dummy_urb_enqueue ( | |||
980 | 980 | ||
981 | dum = hcd_to_dummy (hcd); | 981 | dum = hcd_to_dummy (hcd); |
982 | spin_lock_irqsave (&dum->lock, flags); | 982 | spin_lock_irqsave (&dum->lock, flags); |
983 | rc = usb_hcd_link_urb_to_ep(hcd, urb); | ||
984 | if (rc) { | ||
985 | kfree(urbp); | ||
986 | goto done; | ||
987 | } | ||
983 | 988 | ||
984 | if (!dum->udev) { | 989 | if (!dum->udev) { |
985 | dum->udev = urb->dev; | 990 | dum->udev = urb->dev; |
@@ -996,36 +1001,35 @@ static int dummy_urb_enqueue ( | |||
996 | if (!timer_pending (&dum->timer)) | 1001 | if (!timer_pending (&dum->timer)) |
997 | mod_timer (&dum->timer, jiffies + 1); | 1002 | mod_timer (&dum->timer, jiffies + 1); |
998 | 1003 | ||
999 | spin_unlock_irqrestore (&dum->lock, flags); | 1004 | done: |
1000 | return 0; | 1005 | spin_unlock_irqrestore(&dum->lock, flags); |
1006 | return rc; | ||
1001 | } | 1007 | } |
1002 | 1008 | ||
1003 | static int dummy_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 1009 | static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
1004 | { | 1010 | { |
1005 | struct dummy *dum; | 1011 | struct dummy *dum; |
1006 | unsigned long flags; | 1012 | unsigned long flags; |
1013 | int rc; | ||
1007 | 1014 | ||
1008 | /* giveback happens automatically in timer callback, | 1015 | /* giveback happens automatically in timer callback, |
1009 | * so make sure the callback happens */ | 1016 | * so make sure the callback happens */ |
1010 | dum = hcd_to_dummy (hcd); | 1017 | dum = hcd_to_dummy (hcd); |
1011 | spin_lock_irqsave (&dum->lock, flags); | 1018 | spin_lock_irqsave (&dum->lock, flags); |
1012 | if (dum->rh_state != DUMMY_RH_RUNNING && !list_empty(&dum->urbp_list)) | 1019 | |
1020 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
1021 | if (!rc && dum->rh_state != DUMMY_RH_RUNNING && | ||
1022 | !list_empty(&dum->urbp_list)) | ||
1013 | mod_timer (&dum->timer, jiffies); | 1023 | mod_timer (&dum->timer, jiffies); |
1014 | spin_unlock_irqrestore (&dum->lock, flags); | ||
1015 | return 0; | ||
1016 | } | ||
1017 | 1024 | ||
1018 | static void maybe_set_status (struct urb *urb, int status) | 1025 | spin_unlock_irqrestore (&dum->lock, flags); |
1019 | { | 1026 | return rc; |
1020 | spin_lock (&urb->lock); | ||
1021 | if (urb->status == -EINPROGRESS) | ||
1022 | urb->status = status; | ||
1023 | spin_unlock (&urb->lock); | ||
1024 | } | 1027 | } |
1025 | 1028 | ||
1026 | /* transfer up to a frame's worth; caller must own lock */ | 1029 | /* transfer up to a frame's worth; caller must own lock */ |
1027 | static int | 1030 | static int |
1028 | transfer (struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit) | 1031 | transfer(struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit, |
1032 | int *status) | ||
1029 | { | 1033 | { |
1030 | struct dummy_request *req; | 1034 | struct dummy_request *req; |
1031 | 1035 | ||
@@ -1088,24 +1092,20 @@ top: | |||
1088 | * | 1092 | * |
1089 | * partially filling a buffer optionally blocks queue advances | 1093 | * partially filling a buffer optionally blocks queue advances |
1090 | * (so completion handlers can clean up the queue) but we don't | 1094 | * (so completion handlers can clean up the queue) but we don't |
1091 | * need to emulate such data-in-flight. so we only show part | 1095 | * need to emulate such data-in-flight. |
1092 | * of the URB_SHORT_NOT_OK effect: completion status. | ||
1093 | */ | 1096 | */ |
1094 | if (is_short) { | 1097 | if (is_short) { |
1095 | if (host_len == dev_len) { | 1098 | if (host_len == dev_len) { |
1096 | req->req.status = 0; | 1099 | req->req.status = 0; |
1097 | maybe_set_status (urb, 0); | 1100 | *status = 0; |
1098 | } else if (to_host) { | 1101 | } else if (to_host) { |
1099 | req->req.status = 0; | 1102 | req->req.status = 0; |
1100 | if (dev_len > host_len) | 1103 | if (dev_len > host_len) |
1101 | maybe_set_status (urb, -EOVERFLOW); | 1104 | *status = -EOVERFLOW; |
1102 | else | 1105 | else |
1103 | maybe_set_status (urb, | 1106 | *status = 0; |
1104 | (urb->transfer_flags | ||
1105 | & URB_SHORT_NOT_OK) | ||
1106 | ? -EREMOTEIO : 0); | ||
1107 | } else if (!to_host) { | 1107 | } else if (!to_host) { |
1108 | maybe_set_status (urb, 0); | 1108 | *status = 0; |
1109 | if (host_len > dev_len) | 1109 | if (host_len > dev_len) |
1110 | req->req.status = -EOVERFLOW; | 1110 | req->req.status = -EOVERFLOW; |
1111 | else | 1111 | else |
@@ -1119,9 +1119,8 @@ top: | |||
1119 | req->req.status = 0; | 1119 | req->req.status = 0; |
1120 | if (urb->transfer_buffer_length == urb->actual_length | 1120 | if (urb->transfer_buffer_length == urb->actual_length |
1121 | && !(urb->transfer_flags | 1121 | && !(urb->transfer_flags |
1122 | & URB_ZERO_PACKET)) { | 1122 | & URB_ZERO_PACKET)) |
1123 | maybe_set_status (urb, 0); | 1123 | *status = 0; |
1124 | } | ||
1125 | } | 1124 | } |
1126 | 1125 | ||
1127 | /* device side completion --> continuable */ | 1126 | /* device side completion --> continuable */ |
@@ -1137,7 +1136,7 @@ top: | |||
1137 | } | 1136 | } |
1138 | 1137 | ||
1139 | /* host side completion --> terminate */ | 1138 | /* host side completion --> terminate */ |
1140 | if (urb->status != -EINPROGRESS) | 1139 | if (*status != -EINPROGRESS) |
1141 | break; | 1140 | break; |
1142 | 1141 | ||
1143 | /* rescan to continue with any other queued i/o */ | 1142 | /* rescan to continue with any other queued i/o */ |
@@ -1248,12 +1247,12 @@ restart: | |||
1248 | u8 address; | 1247 | u8 address; |
1249 | struct dummy_ep *ep = NULL; | 1248 | struct dummy_ep *ep = NULL; |
1250 | int type; | 1249 | int type; |
1250 | int status = -EINPROGRESS; | ||
1251 | 1251 | ||
1252 | urb = urbp->urb; | 1252 | urb = urbp->urb; |
1253 | if (urb->status != -EINPROGRESS) { | 1253 | if (urb->unlinked) |
1254 | /* likely it was just unlinked */ | ||
1255 | goto return_urb; | 1254 | goto return_urb; |
1256 | } else if (dum->rh_state != DUMMY_RH_RUNNING) | 1255 | else if (dum->rh_state != DUMMY_RH_RUNNING) |
1257 | continue; | 1256 | continue; |
1258 | type = usb_pipetype (urb->pipe); | 1257 | type = usb_pipetype (urb->pipe); |
1259 | 1258 | ||
@@ -1274,7 +1273,7 @@ restart: | |||
1274 | dev_dbg (dummy_dev(dum), | 1273 | dev_dbg (dummy_dev(dum), |
1275 | "no ep configured for urb %p\n", | 1274 | "no ep configured for urb %p\n", |
1276 | urb); | 1275 | urb); |
1277 | maybe_set_status (urb, -EPROTO); | 1276 | status = -EPROTO; |
1278 | goto return_urb; | 1277 | goto return_urb; |
1279 | } | 1278 | } |
1280 | 1279 | ||
@@ -1289,7 +1288,7 @@ restart: | |||
1289 | /* NOTE: must not be iso! */ | 1288 | /* NOTE: must not be iso! */ |
1290 | dev_dbg (dummy_dev(dum), "ep %s halted, urb %p\n", | 1289 | dev_dbg (dummy_dev(dum), "ep %s halted, urb %p\n", |
1291 | ep->ep.name, urb); | 1290 | ep->ep.name, urb); |
1292 | maybe_set_status (urb, -EPIPE); | 1291 | status = -EPIPE; |
1293 | goto return_urb; | 1292 | goto return_urb; |
1294 | } | 1293 | } |
1295 | /* FIXME make sure both ends agree on maxpacket */ | 1294 | /* FIXME make sure both ends agree on maxpacket */ |
@@ -1307,7 +1306,7 @@ restart: | |||
1307 | w_value = le16_to_cpu(setup.wValue); | 1306 | w_value = le16_to_cpu(setup.wValue); |
1308 | if (le16_to_cpu(setup.wLength) != | 1307 | if (le16_to_cpu(setup.wLength) != |
1309 | urb->transfer_buffer_length) { | 1308 | urb->transfer_buffer_length) { |
1310 | maybe_set_status (urb, -EOVERFLOW); | 1309 | status = -EOVERFLOW; |
1311 | goto return_urb; | 1310 | goto return_urb; |
1312 | } | 1311 | } |
1313 | 1312 | ||
@@ -1337,7 +1336,7 @@ restart: | |||
1337 | if (setup.bRequestType != Dev_Request) | 1336 | if (setup.bRequestType != Dev_Request) |
1338 | break; | 1337 | break; |
1339 | dum->address = w_value; | 1338 | dum->address = w_value; |
1340 | maybe_set_status (urb, 0); | 1339 | status = 0; |
1341 | dev_dbg (udc_dev(dum), "set_address = %d\n", | 1340 | dev_dbg (udc_dev(dum), "set_address = %d\n", |
1342 | w_value); | 1341 | w_value); |
1343 | value = 0; | 1342 | value = 0; |
@@ -1364,7 +1363,7 @@ restart: | |||
1364 | if (value == 0) { | 1363 | if (value == 0) { |
1365 | dum->devstatus |= | 1364 | dum->devstatus |= |
1366 | (1 << w_value); | 1365 | (1 << w_value); |
1367 | maybe_set_status (urb, 0); | 1366 | status = 0; |
1368 | } | 1367 | } |
1369 | 1368 | ||
1370 | } else if (setup.bRequestType == Ep_Request) { | 1369 | } else if (setup.bRequestType == Ep_Request) { |
@@ -1376,7 +1375,7 @@ restart: | |||
1376 | } | 1375 | } |
1377 | ep2->halted = 1; | 1376 | ep2->halted = 1; |
1378 | value = 0; | 1377 | value = 0; |
1379 | maybe_set_status (urb, 0); | 1378 | status = 0; |
1380 | } | 1379 | } |
1381 | break; | 1380 | break; |
1382 | case USB_REQ_CLEAR_FEATURE: | 1381 | case USB_REQ_CLEAR_FEATURE: |
@@ -1386,7 +1385,7 @@ restart: | |||
1386 | dum->devstatus &= ~(1 << | 1385 | dum->devstatus &= ~(1 << |
1387 | USB_DEVICE_REMOTE_WAKEUP); | 1386 | USB_DEVICE_REMOTE_WAKEUP); |
1388 | value = 0; | 1387 | value = 0; |
1389 | maybe_set_status (urb, 0); | 1388 | status = 0; |
1390 | break; | 1389 | break; |
1391 | default: | 1390 | default: |
1392 | value = -EOPNOTSUPP; | 1391 | value = -EOPNOTSUPP; |
@@ -1401,7 +1400,7 @@ restart: | |||
1401 | } | 1400 | } |
1402 | ep2->halted = 0; | 1401 | ep2->halted = 0; |
1403 | value = 0; | 1402 | value = 0; |
1404 | maybe_set_status (urb, 0); | 1403 | status = 0; |
1405 | } | 1404 | } |
1406 | break; | 1405 | break; |
1407 | case USB_REQ_GET_STATUS: | 1406 | case USB_REQ_GET_STATUS: |
@@ -1438,7 +1437,7 @@ restart: | |||
1438 | urb->actual_length = min (2, | 1437 | urb->actual_length = min (2, |
1439 | urb->transfer_buffer_length); | 1438 | urb->transfer_buffer_length); |
1440 | value = 0; | 1439 | value = 0; |
1441 | maybe_set_status (urb, 0); | 1440 | status = 0; |
1442 | } | 1441 | } |
1443 | break; | 1442 | break; |
1444 | } | 1443 | } |
@@ -1465,7 +1464,7 @@ restart: | |||
1465 | dev_dbg (udc_dev(dum), | 1464 | dev_dbg (udc_dev(dum), |
1466 | "setup --> %d\n", | 1465 | "setup --> %d\n", |
1467 | value); | 1466 | value); |
1468 | maybe_set_status (urb, -EPIPE); | 1467 | status = -EPIPE; |
1469 | urb->actual_length = 0; | 1468 | urb->actual_length = 0; |
1470 | } | 1469 | } |
1471 | 1470 | ||
@@ -1482,7 +1481,7 @@ restart: | |||
1482 | * report random errors, to debug drivers. | 1481 | * report random errors, to debug drivers. |
1483 | */ | 1482 | */ |
1484 | limit = max (limit, periodic_bytes (dum, ep)); | 1483 | limit = max (limit, periodic_bytes (dum, ep)); |
1485 | maybe_set_status (urb, -ENOSYS); | 1484 | status = -ENOSYS; |
1486 | break; | 1485 | break; |
1487 | 1486 | ||
1488 | case PIPE_INTERRUPT: | 1487 | case PIPE_INTERRUPT: |
@@ -1496,23 +1495,23 @@ restart: | |||
1496 | default: | 1495 | default: |
1497 | treat_control_like_bulk: | 1496 | treat_control_like_bulk: |
1498 | ep->last_io = jiffies; | 1497 | ep->last_io = jiffies; |
1499 | total = transfer (dum, urb, ep, limit); | 1498 | total = transfer(dum, urb, ep, limit, &status); |
1500 | break; | 1499 | break; |
1501 | } | 1500 | } |
1502 | 1501 | ||
1503 | /* incomplete transfer? */ | 1502 | /* incomplete transfer? */ |
1504 | if (urb->status == -EINPROGRESS) | 1503 | if (status == -EINPROGRESS) |
1505 | continue; | 1504 | continue; |
1506 | 1505 | ||
1507 | return_urb: | 1506 | return_urb: |
1508 | urb->hcpriv = NULL; | ||
1509 | list_del (&urbp->urbp_list); | 1507 | list_del (&urbp->urbp_list); |
1510 | kfree (urbp); | 1508 | kfree (urbp); |
1511 | if (ep) | 1509 | if (ep) |
1512 | ep->already_seen = ep->setup_stage = 0; | 1510 | ep->already_seen = ep->setup_stage = 0; |
1513 | 1511 | ||
1512 | usb_hcd_unlink_urb_from_ep(dummy_to_hcd(dum), urb); | ||
1514 | spin_unlock (&dum->lock); | 1513 | spin_unlock (&dum->lock); |
1515 | usb_hcd_giveback_urb (dummy_to_hcd(dum), urb); | 1514 | usb_hcd_giveback_urb(dummy_to_hcd(dum), urb, status); |
1516 | spin_lock (&dum->lock); | 1515 | spin_lock (&dum->lock); |
1517 | 1516 | ||
1518 | goto restart; | 1517 | goto restart; |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 3aa46cfa66ba..f9d07108bc30 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
29 | 29 | ||
30 | #include <linux/usb/ch9.h> | 30 | #include <linux/usb/ch9.h> |
31 | #include <linux/usb_gadget.h> | 31 | #include <linux/usb/gadget.h> |
32 | 32 | ||
33 | #include "gadget_chips.h" | 33 | #include "gadget_chips.h" |
34 | 34 | ||
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index f70055473a00..9e732bff9df0 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -19,40 +19,18 @@ | |||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | /* #define VERBOSE_DEBUG */ | ||
22 | 23 | ||
23 | // #define DEBUG 1 | ||
24 | // #define VERBOSE | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
28 | #include <linux/delay.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/errno.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/timer.h> | ||
34 | #include <linux/list.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | #include <linux/utsname.h> | 25 | #include <linux/utsname.h> |
37 | #include <linux/device.h> | 26 | #include <linux/device.h> |
38 | #include <linux/moduleparam.h> | ||
39 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
40 | 28 | #include <linux/etherdevice.h> | |
41 | #include <asm/byteorder.h> | 29 | #include <linux/ethtool.h> |
42 | #include <asm/io.h> | ||
43 | #include <asm/irq.h> | ||
44 | #include <asm/system.h> | ||
45 | #include <asm/uaccess.h> | ||
46 | #include <asm/unaligned.h> | ||
47 | 30 | ||
48 | #include <linux/usb/ch9.h> | 31 | #include <linux/usb/ch9.h> |
49 | #include <linux/usb/cdc.h> | 32 | #include <linux/usb/cdc.h> |
50 | #include <linux/usb_gadget.h> | 33 | #include <linux/usb/gadget.h> |
51 | |||
52 | #include <linux/random.h> | ||
53 | #include <linux/netdevice.h> | ||
54 | #include <linux/etherdevice.h> | ||
55 | #include <linux/ethtool.h> | ||
56 | 34 | ||
57 | #include "gadget_chips.h" | 35 | #include "gadget_chips.h" |
58 | 36 | ||
@@ -356,15 +334,15 @@ module_param (qmult, uint, S_IRUGO|S_IWUSR); | |||
356 | #define qlen(gadget) \ | 334 | #define qlen(gadget) \ |
357 | (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1)) | 335 | (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1)) |
358 | 336 | ||
359 | /* also defer IRQs on highspeed TX */ | ||
360 | #define TX_DELAY qmult | ||
361 | |||
362 | static inline int BITRATE(struct usb_gadget *g) | 337 | static inline int BITRATE(struct usb_gadget *g) |
363 | { | 338 | { |
364 | return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS; | 339 | return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS; |
365 | } | 340 | } |
366 | 341 | ||
367 | #else /* full speed (low speed doesn't do bulk) */ | 342 | #else /* full speed (low speed doesn't do bulk) */ |
343 | |||
344 | #define qmult 1 | ||
345 | |||
368 | #define DEVSPEED USB_SPEED_FULL | 346 | #define DEVSPEED USB_SPEED_FULL |
369 | 347 | ||
370 | #define qlen(gadget) DEFAULT_QLEN | 348 | #define qlen(gadget) DEFAULT_QLEN |
@@ -390,7 +368,7 @@ static inline int BITRATE(struct usb_gadget *g) | |||
390 | do { } while (0) | 368 | do { } while (0) |
391 | #endif /* DEBUG */ | 369 | #endif /* DEBUG */ |
392 | 370 | ||
393 | #ifdef VERBOSE | 371 | #ifdef VERBOSE_DEBUG |
394 | #define VDEBUG DEBUG | 372 | #define VDEBUG DEBUG |
395 | #else | 373 | #else |
396 | #define VDEBUG(dev,fmt,args...) \ | 374 | #define VDEBUG(dev,fmt,args...) \ |
@@ -830,8 +808,6 @@ static const struct usb_descriptor_header *fs_rndis_function [] = { | |||
830 | }; | 808 | }; |
831 | #endif | 809 | #endif |
832 | 810 | ||
833 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
834 | |||
835 | /* | 811 | /* |
836 | * usb 2.0 devices need to expose both high speed and full speed | 812 | * usb 2.0 devices need to expose both high speed and full speed |
837 | * descriptors, unless they only run at full speed. | 813 | * descriptors, unless they only run at full speed. |
@@ -934,18 +910,15 @@ static const struct usb_descriptor_header *hs_rndis_function [] = { | |||
934 | 910 | ||
935 | 911 | ||
936 | /* maxpacket and other transfer characteristics vary by speed. */ | 912 | /* maxpacket and other transfer characteristics vary by speed. */ |
937 | #define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs)) | 913 | static inline struct usb_endpoint_descriptor * |
938 | 914 | ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, | |
939 | #else | 915 | struct usb_endpoint_descriptor *fs) |
940 | |||
941 | /* if there's no high speed support, maxpacket doesn't change. */ | ||
942 | #define ep_desc(g,hs,fs) (((void)(g)), (fs)) | ||
943 | |||
944 | static inline void __init hs_subset_descriptors(void) | ||
945 | { | 916 | { |
917 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
918 | return hs; | ||
919 | return fs; | ||
946 | } | 920 | } |
947 | 921 | ||
948 | #endif /* !CONFIG_USB_GADGET_DUALSPEED */ | ||
949 | 922 | ||
950 | /*-------------------------------------------------------------------------*/ | 923 | /*-------------------------------------------------------------------------*/ |
951 | 924 | ||
@@ -989,22 +962,19 @@ static struct usb_gadget_strings stringtab = { | |||
989 | * complications: class descriptors, and an altsetting. | 962 | * complications: class descriptors, and an altsetting. |
990 | */ | 963 | */ |
991 | static int | 964 | static int |
992 | config_buf (enum usb_device_speed speed, | 965 | config_buf(struct usb_gadget *g, u8 *buf, u8 type, unsigned index, int is_otg) |
993 | u8 *buf, u8 type, | ||
994 | unsigned index, int is_otg) | ||
995 | { | 966 | { |
996 | int len; | 967 | int len; |
997 | const struct usb_config_descriptor *config; | 968 | const struct usb_config_descriptor *config; |
998 | const struct usb_descriptor_header **function; | 969 | const struct usb_descriptor_header **function; |
999 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 970 | int hs = 0; |
1000 | int hs = (speed == USB_SPEED_HIGH); | ||
1001 | 971 | ||
1002 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 972 | if (gadget_is_dualspeed(g)) { |
1003 | hs = !hs; | 973 | hs = (g->speed == USB_SPEED_HIGH); |
974 | if (type == USB_DT_OTHER_SPEED_CONFIG) | ||
975 | hs = !hs; | ||
976 | } | ||
1004 | #define which_fn(t) (hs ? hs_ ## t ## _function : fs_ ## t ## _function) | 977 | #define which_fn(t) (hs ? hs_ ## t ## _function : fs_ ## t ## _function) |
1005 | #else | ||
1006 | #define which_fn(t) (fs_ ## t ## _function) | ||
1007 | #endif | ||
1008 | 978 | ||
1009 | if (index >= device_desc.bNumConfigurations) | 979 | if (index >= device_desc.bNumConfigurations) |
1010 | return -EINVAL; | 980 | return -EINVAL; |
@@ -1217,7 +1187,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags) | |||
1217 | if (number) | 1187 | if (number) |
1218 | eth_reset_config (dev); | 1188 | eth_reset_config (dev); |
1219 | usb_gadget_vbus_draw(dev->gadget, | 1189 | usb_gadget_vbus_draw(dev->gadget, |
1220 | dev->gadget->is_otg ? 8 : 100); | 1190 | gadget_is_otg(dev->gadget) ? 8 : 100); |
1221 | } else { | 1191 | } else { |
1222 | char *speed; | 1192 | char *speed; |
1223 | unsigned power; | 1193 | unsigned power; |
@@ -1399,24 +1369,22 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1399 | value = min (wLength, (u16) sizeof device_desc); | 1369 | value = min (wLength, (u16) sizeof device_desc); |
1400 | memcpy (req->buf, &device_desc, value); | 1370 | memcpy (req->buf, &device_desc, value); |
1401 | break; | 1371 | break; |
1402 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1403 | case USB_DT_DEVICE_QUALIFIER: | 1372 | case USB_DT_DEVICE_QUALIFIER: |
1404 | if (!gadget->is_dualspeed) | 1373 | if (!gadget_is_dualspeed(gadget)) |
1405 | break; | 1374 | break; |
1406 | value = min (wLength, (u16) sizeof dev_qualifier); | 1375 | value = min (wLength, (u16) sizeof dev_qualifier); |
1407 | memcpy (req->buf, &dev_qualifier, value); | 1376 | memcpy (req->buf, &dev_qualifier, value); |
1408 | break; | 1377 | break; |
1409 | 1378 | ||
1410 | case USB_DT_OTHER_SPEED_CONFIG: | 1379 | case USB_DT_OTHER_SPEED_CONFIG: |
1411 | if (!gadget->is_dualspeed) | 1380 | if (!gadget_is_dualspeed(gadget)) |
1412 | break; | 1381 | break; |
1413 | // FALLTHROUGH | 1382 | // FALLTHROUGH |
1414 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1415 | case USB_DT_CONFIG: | 1383 | case USB_DT_CONFIG: |
1416 | value = config_buf (gadget->speed, req->buf, | 1384 | value = config_buf(gadget, req->buf, |
1417 | wValue >> 8, | 1385 | wValue >> 8, |
1418 | wValue & 0xff, | 1386 | wValue & 0xff, |
1419 | gadget->is_otg); | 1387 | gadget_is_otg(gadget)); |
1420 | if (value >= 0) | 1388 | if (value >= 0) |
1421 | value = min (wLength, (u16) value); | 1389 | value = min (wLength, (u16) value); |
1422 | break; | 1390 | break; |
@@ -1585,12 +1553,12 @@ done_set_intf: | |||
1585 | && rndis_control_intf.bInterfaceNumber | 1553 | && rndis_control_intf.bInterfaceNumber |
1586 | == wIndex) { | 1554 | == wIndex) { |
1587 | u8 *buf; | 1555 | u8 *buf; |
1556 | u32 n; | ||
1588 | 1557 | ||
1589 | /* return the result */ | 1558 | /* return the result */ |
1590 | buf = rndis_get_next_response (dev->rndis_config, | 1559 | buf = rndis_get_next_response(dev->rndis_config, &n); |
1591 | &value); | ||
1592 | if (buf) { | 1560 | if (buf) { |
1593 | memcpy (req->buf, buf, value); | 1561 | memcpy(req->buf, buf, n); |
1594 | req->complete = rndis_response_complete; | 1562 | req->complete = rndis_response_complete; |
1595 | rndis_free_response(dev->rndis_config, buf); | 1563 | rndis_free_response(dev->rndis_config, buf); |
1596 | } | 1564 | } |
@@ -1989,8 +1957,20 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) | |||
1989 | } | 1957 | } |
1990 | 1958 | ||
1991 | spin_lock_irqsave(&dev->req_lock, flags); | 1959 | spin_lock_irqsave(&dev->req_lock, flags); |
1960 | /* | ||
1961 | * this freelist can be empty if an interrupt triggered disconnect() | ||
1962 | * and reconfigured the gadget (shutting down this queue) after the | ||
1963 | * network stack decided to xmit but before we got the spinlock. | ||
1964 | */ | ||
1965 | if (list_empty(&dev->tx_reqs)) { | ||
1966 | spin_unlock_irqrestore(&dev->req_lock, flags); | ||
1967 | return 1; | ||
1968 | } | ||
1969 | |||
1992 | req = container_of (dev->tx_reqs.next, struct usb_request, list); | 1970 | req = container_of (dev->tx_reqs.next, struct usb_request, list); |
1993 | list_del (&req->list); | 1971 | list_del (&req->list); |
1972 | |||
1973 | /* temporarily stop TX queue when the freelist empties */ | ||
1994 | if (list_empty (&dev->tx_reqs)) | 1974 | if (list_empty (&dev->tx_reqs)) |
1995 | netif_stop_queue (net); | 1975 | netif_stop_queue (net); |
1996 | spin_unlock_irqrestore(&dev->req_lock, flags); | 1976 | spin_unlock_irqrestore(&dev->req_lock, flags); |
@@ -2026,12 +2006,11 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) | |||
2026 | 2006 | ||
2027 | req->length = length; | 2007 | req->length = length; |
2028 | 2008 | ||
2029 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
2030 | /* throttle highspeed IRQ rate back slightly */ | 2009 | /* throttle highspeed IRQ rate back slightly */ |
2031 | req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) | 2010 | if (gadget_is_dualspeed(dev->gadget)) |
2032 | ? ((atomic_read (&dev->tx_qlen) % TX_DELAY) != 0) | 2011 | req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) |
2033 | : 0; | 2012 | ? ((atomic_read(&dev->tx_qlen) % qmult) != 0) |
2034 | #endif | 2013 | : 0; |
2035 | 2014 | ||
2036 | retval = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC); | 2015 | retval = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC); |
2037 | switch (retval) { | 2016 | switch (retval) { |
@@ -2188,8 +2167,7 @@ static int eth_stop (struct net_device *net) | |||
2188 | } | 2167 | } |
2189 | 2168 | ||
2190 | if (rndis_active(dev)) { | 2169 | if (rndis_active(dev)) { |
2191 | rndis_set_param_medium (dev->rndis_config, | 2170 | rndis_set_param_medium(dev->rndis_config, NDIS_MEDIUM_802_3, 0); |
2192 | NDIS_MEDIUM_802_3, 0); | ||
2193 | (void) rndis_signal_disconnect (dev->rndis_config); | 2171 | (void) rndis_signal_disconnect (dev->rndis_config); |
2194 | } | 2172 | } |
2195 | 2173 | ||
@@ -2443,26 +2421,28 @@ autoconf_fail: | |||
2443 | if (rndis) | 2421 | if (rndis) |
2444 | device_desc.bNumConfigurations = 2; | 2422 | device_desc.bNumConfigurations = 2; |
2445 | 2423 | ||
2446 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 2424 | if (gadget_is_dualspeed(gadget)) { |
2447 | if (rndis) | 2425 | if (rndis) |
2448 | dev_qualifier.bNumConfigurations = 2; | 2426 | dev_qualifier.bNumConfigurations = 2; |
2449 | else if (!cdc) | 2427 | else if (!cdc) |
2450 | dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC; | 2428 | dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC; |
2451 | 2429 | ||
2452 | /* assumes ep0 uses the same value for both speeds ... */ | 2430 | /* assumes ep0 uses the same value for both speeds ... */ |
2453 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; | 2431 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; |
2454 | 2432 | ||
2455 | /* and that all endpoints are dual-speed */ | 2433 | /* and that all endpoints are dual-speed */ |
2456 | hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; | 2434 | hs_source_desc.bEndpointAddress = |
2457 | hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; | 2435 | fs_source_desc.bEndpointAddress; |
2436 | hs_sink_desc.bEndpointAddress = | ||
2437 | fs_sink_desc.bEndpointAddress; | ||
2458 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | 2438 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) |
2459 | if (status_ep) | 2439 | if (status_ep) |
2460 | hs_status_desc.bEndpointAddress = | 2440 | hs_status_desc.bEndpointAddress = |
2461 | fs_status_desc.bEndpointAddress; | 2441 | fs_status_desc.bEndpointAddress; |
2462 | #endif | 2442 | #endif |
2463 | #endif /* DUALSPEED */ | 2443 | } |
2464 | 2444 | ||
2465 | if (gadget->is_otg) { | 2445 | if (gadget_is_otg(gadget)) { |
2466 | otg_descriptor.bmAttributes |= USB_OTG_HNP, | 2446 | otg_descriptor.bmAttributes |= USB_OTG_HNP, |
2467 | eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 2447 | eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
2468 | eth_config.bMaxPower = 4; | 2448 | eth_config.bMaxPower = 4; |
@@ -2598,12 +2578,11 @@ fail0: | |||
2598 | if (rndis_set_param_dev (dev->rndis_config, dev->net, | 2578 | if (rndis_set_param_dev (dev->rndis_config, dev->net, |
2599 | &dev->stats, &dev->cdc_filter)) | 2579 | &dev->stats, &dev->cdc_filter)) |
2600 | goto fail0; | 2580 | goto fail0; |
2601 | if (rndis_set_param_vendor (dev->rndis_config, vendorID, | 2581 | if (rndis_set_param_vendor(dev->rndis_config, vendorID, |
2602 | manufacturer)) | 2582 | manufacturer)) |
2603 | goto fail0; | 2583 | goto fail0; |
2604 | if (rndis_set_param_medium (dev->rndis_config, | 2584 | if (rndis_set_param_medium(dev->rndis_config, |
2605 | NDIS_MEDIUM_802_3, | 2585 | NDIS_MEDIUM_802_3, 0)) |
2606 | 0)) | ||
2607 | goto fail0; | 2586 | goto fail0; |
2608 | INFO (dev, "RNDIS ready\n"); | 2587 | INFO (dev, "RNDIS ready\n"); |
2609 | } | 2588 | } |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 965ad7bec7b7..73726c570a6e 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * file_storage.c -- File-backed USB Storage Gadget, for USB development | 2 | * file_storage.c -- File-backed USB Storage Gadget, for USB development |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2005 Alan Stern | 4 | * Copyright (C) 2003-2007 Alan Stern |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
@@ -217,17 +217,11 @@ | |||
217 | */ | 217 | */ |
218 | 218 | ||
219 | 219 | ||
220 | #undef DEBUG | 220 | /* #define VERBOSE_DEBUG */ |
221 | #undef VERBOSE | 221 | /* #define DUMP_MSGS */ |
222 | #undef DUMP_MSGS | ||
223 | |||
224 | 222 | ||
225 | #include <asm/system.h> | ||
226 | #include <asm/uaccess.h> | ||
227 | 223 | ||
228 | #include <linux/bitops.h> | ||
229 | #include <linux/blkdev.h> | 224 | #include <linux/blkdev.h> |
230 | #include <linux/compiler.h> | ||
231 | #include <linux/completion.h> | 225 | #include <linux/completion.h> |
232 | #include <linux/dcache.h> | 226 | #include <linux/dcache.h> |
233 | #include <linux/delay.h> | 227 | #include <linux/delay.h> |
@@ -235,18 +229,10 @@ | |||
235 | #include <linux/fcntl.h> | 229 | #include <linux/fcntl.h> |
236 | #include <linux/file.h> | 230 | #include <linux/file.h> |
237 | #include <linux/fs.h> | 231 | #include <linux/fs.h> |
238 | #include <linux/init.h> | ||
239 | #include <linux/kernel.h> | ||
240 | #include <linux/kref.h> | 232 | #include <linux/kref.h> |
241 | #include <linux/kthread.h> | 233 | #include <linux/kthread.h> |
242 | #include <linux/limits.h> | 234 | #include <linux/limits.h> |
243 | #include <linux/list.h> | ||
244 | #include <linux/module.h> | ||
245 | #include <linux/moduleparam.h> | ||
246 | #include <linux/pagemap.h> | ||
247 | #include <linux/rwsem.h> | 235 | #include <linux/rwsem.h> |
248 | #include <linux/sched.h> | ||
249 | #include <linux/signal.h> | ||
250 | #include <linux/slab.h> | 236 | #include <linux/slab.h> |
251 | #include <linux/spinlock.h> | 237 | #include <linux/spinlock.h> |
252 | #include <linux/string.h> | 238 | #include <linux/string.h> |
@@ -254,7 +240,7 @@ | |||
254 | #include <linux/utsname.h> | 240 | #include <linux/utsname.h> |
255 | 241 | ||
256 | #include <linux/usb/ch9.h> | 242 | #include <linux/usb/ch9.h> |
257 | #include <linux/usb_gadget.h> | 243 | #include <linux/usb/gadget.h> |
258 | 244 | ||
259 | #include "gadget_chips.h" | 245 | #include "gadget_chips.h" |
260 | 246 | ||
@@ -263,7 +249,7 @@ | |||
263 | 249 | ||
264 | #define DRIVER_DESC "File-backed Storage Gadget" | 250 | #define DRIVER_DESC "File-backed Storage Gadget" |
265 | #define DRIVER_NAME "g_file_storage" | 251 | #define DRIVER_NAME "g_file_storage" |
266 | #define DRIVER_VERSION "28 November 2005" | 252 | #define DRIVER_VERSION "7 August 2007" |
267 | 253 | ||
268 | static const char longname[] = DRIVER_DESC; | 254 | static const char longname[] = DRIVER_DESC; |
269 | static const char shortname[] = DRIVER_NAME; | 255 | static const char shortname[] = DRIVER_NAME; |
@@ -289,57 +275,48 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
289 | 275 | ||
290 | /*-------------------------------------------------------------------------*/ | 276 | /*-------------------------------------------------------------------------*/ |
291 | 277 | ||
292 | #define xprintk(f,level,fmt,args...) \ | ||
293 | dev_printk(level , &(f)->gadget->dev , fmt , ## args) | ||
294 | #define yprintk(l,level,fmt,args...) \ | ||
295 | dev_printk(level , &(l)->dev , fmt , ## args) | ||
296 | |||
297 | #ifdef DEBUG | 278 | #ifdef DEBUG |
298 | #define DBG(fsg,fmt,args...) \ | ||
299 | xprintk(fsg , KERN_DEBUG , fmt , ## args) | ||
300 | #define LDBG(lun,fmt,args...) \ | 279 | #define LDBG(lun,fmt,args...) \ |
301 | yprintk(lun , KERN_DEBUG , fmt , ## args) | 280 | dev_dbg(&(lun)->dev , fmt , ## args) |
302 | #define MDBG(fmt,args...) \ | 281 | #define MDBG(fmt,args...) \ |
303 | printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args) | 282 | printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args) |
304 | #else | 283 | #else |
305 | #define DBG(fsg,fmt,args...) \ | ||
306 | do { } while (0) | ||
307 | #define LDBG(lun,fmt,args...) \ | 284 | #define LDBG(lun,fmt,args...) \ |
308 | do { } while (0) | 285 | do { } while (0) |
309 | #define MDBG(fmt,args...) \ | 286 | #define MDBG(fmt,args...) \ |
310 | do { } while (0) | 287 | do { } while (0) |
311 | #undef VERBOSE | 288 | #undef VERBOSE_DEBUG |
312 | #undef DUMP_MSGS | 289 | #undef DUMP_MSGS |
313 | #endif /* DEBUG */ | 290 | #endif /* DEBUG */ |
314 | 291 | ||
315 | #ifdef VERBOSE | 292 | #ifdef VERBOSE_DEBUG |
316 | #define VDBG DBG | ||
317 | #define VLDBG LDBG | 293 | #define VLDBG LDBG |
318 | #else | 294 | #else |
319 | #define VDBG(fsg,fmt,args...) \ | ||
320 | do { } while (0) | ||
321 | #define VLDBG(lun,fmt,args...) \ | 295 | #define VLDBG(lun,fmt,args...) \ |
322 | do { } while (0) | 296 | do { } while (0) |
323 | #endif /* VERBOSE */ | 297 | #endif /* VERBOSE_DEBUG */ |
324 | 298 | ||
325 | #define ERROR(fsg,fmt,args...) \ | ||
326 | xprintk(fsg , KERN_ERR , fmt , ## args) | ||
327 | #define LERROR(lun,fmt,args...) \ | 299 | #define LERROR(lun,fmt,args...) \ |
328 | yprintk(lun , KERN_ERR , fmt , ## args) | 300 | dev_err(&(lun)->dev , fmt , ## args) |
329 | |||
330 | #define WARN(fsg,fmt,args...) \ | ||
331 | xprintk(fsg , KERN_WARNING , fmt , ## args) | ||
332 | #define LWARN(lun,fmt,args...) \ | 301 | #define LWARN(lun,fmt,args...) \ |
333 | yprintk(lun , KERN_WARNING , fmt , ## args) | 302 | dev_warn(&(lun)->dev , fmt , ## args) |
334 | |||
335 | #define INFO(fsg,fmt,args...) \ | ||
336 | xprintk(fsg , KERN_INFO , fmt , ## args) | ||
337 | #define LINFO(lun,fmt,args...) \ | 303 | #define LINFO(lun,fmt,args...) \ |
338 | yprintk(lun , KERN_INFO , fmt , ## args) | 304 | dev_info(&(lun)->dev , fmt , ## args) |
339 | 305 | ||
340 | #define MINFO(fmt,args...) \ | 306 | #define MINFO(fmt,args...) \ |
341 | printk(KERN_INFO DRIVER_NAME ": " fmt , ## args) | 307 | printk(KERN_INFO DRIVER_NAME ": " fmt , ## args) |
342 | 308 | ||
309 | #define DBG(d, fmt, args...) \ | ||
310 | dev_dbg(&(d)->gadget->dev , fmt , ## args) | ||
311 | #define VDBG(d, fmt, args...) \ | ||
312 | dev_vdbg(&(d)->gadget->dev , fmt , ## args) | ||
313 | #define ERROR(d, fmt, args...) \ | ||
314 | dev_err(&(d)->gadget->dev , fmt , ## args) | ||
315 | #define WARN(d, fmt, args...) \ | ||
316 | dev_warn(&(d)->gadget->dev , fmt , ## args) | ||
317 | #define INFO(d, fmt, args...) \ | ||
318 | dev_info(&(d)->gadget->dev , fmt , ## args) | ||
319 | |||
343 | 320 | ||
344 | /*-------------------------------------------------------------------------*/ | 321 | /*-------------------------------------------------------------------------*/ |
345 | 322 | ||
@@ -350,8 +327,8 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
350 | static struct { | 327 | static struct { |
351 | char *file[MAX_LUNS]; | 328 | char *file[MAX_LUNS]; |
352 | int ro[MAX_LUNS]; | 329 | int ro[MAX_LUNS]; |
353 | int num_filenames; | 330 | unsigned int num_filenames; |
354 | int num_ros; | 331 | unsigned int num_ros; |
355 | unsigned int nluns; | 332 | unsigned int nluns; |
356 | 333 | ||
357 | int removable; | 334 | int removable; |
@@ -578,7 +555,7 @@ struct lun { | |||
578 | 555 | ||
579 | #define backing_file_is_open(curlun) ((curlun)->filp != NULL) | 556 | #define backing_file_is_open(curlun) ((curlun)->filp != NULL) |
580 | 557 | ||
581 | static inline struct lun *dev_to_lun(struct device *dev) | 558 | static struct lun *dev_to_lun(struct device *dev) |
582 | { | 559 | { |
583 | return container_of(dev, struct lun, dev); | 560 | return container_of(dev, struct lun, dev); |
584 | } | 561 | } |
@@ -711,13 +688,13 @@ struct fsg_dev { | |||
711 | 688 | ||
712 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 689 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
713 | 690 | ||
714 | static int inline exception_in_progress(struct fsg_dev *fsg) | 691 | static int exception_in_progress(struct fsg_dev *fsg) |
715 | { | 692 | { |
716 | return (fsg->state > FSG_STATE_IDLE); | 693 | return (fsg->state > FSG_STATE_IDLE); |
717 | } | 694 | } |
718 | 695 | ||
719 | /* Make bulk-out requests be divisible by the maxpacket size */ | 696 | /* Make bulk-out requests be divisible by the maxpacket size */ |
720 | static void inline set_bulk_out_req_length(struct fsg_dev *fsg, | 697 | static void set_bulk_out_req_length(struct fsg_dev *fsg, |
721 | struct fsg_buffhd *bh, unsigned int length) | 698 | struct fsg_buffhd *bh, unsigned int length) |
722 | { | 699 | { |
723 | unsigned int rem; | 700 | unsigned int rem; |
@@ -743,50 +720,36 @@ static void close_all_backing_files(struct fsg_dev *fsg); | |||
743 | static void dump_msg(struct fsg_dev *fsg, const char *label, | 720 | static void dump_msg(struct fsg_dev *fsg, const char *label, |
744 | const u8 *buf, unsigned int length) | 721 | const u8 *buf, unsigned int length) |
745 | { | 722 | { |
746 | unsigned int start, num, i; | 723 | if (length < 512) { |
747 | char line[52], *p; | 724 | DBG(fsg, "%s, length %u:\n", label, length); |
748 | 725 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, | |
749 | if (length >= 512) | 726 | 16, 1, buf, length, 0); |
750 | return; | ||
751 | DBG(fsg, "%s, length %u:\n", label, length); | ||
752 | |||
753 | start = 0; | ||
754 | while (length > 0) { | ||
755 | num = min(length, 16u); | ||
756 | p = line; | ||
757 | for (i = 0; i < num; ++i) { | ||
758 | if (i == 8) | ||
759 | *p++ = ' '; | ||
760 | sprintf(p, " %02x", buf[i]); | ||
761 | p += 3; | ||
762 | } | ||
763 | *p = 0; | ||
764 | printk(KERN_DEBUG "%6x: %s\n", start, line); | ||
765 | buf += num; | ||
766 | start += num; | ||
767 | length -= num; | ||
768 | } | 727 | } |
769 | } | 728 | } |
770 | 729 | ||
771 | static void inline dump_cdb(struct fsg_dev *fsg) | 730 | static void dump_cdb(struct fsg_dev *fsg) |
772 | {} | 731 | {} |
773 | 732 | ||
774 | #else | 733 | #else |
775 | 734 | ||
776 | static void inline dump_msg(struct fsg_dev *fsg, const char *label, | 735 | static void dump_msg(struct fsg_dev *fsg, const char *label, |
777 | const u8 *buf, unsigned int length) | 736 | const u8 *buf, unsigned int length) |
778 | {} | 737 | {} |
779 | 738 | ||
780 | static void inline dump_cdb(struct fsg_dev *fsg) | 739 | #ifdef VERBOSE_DEBUG |
781 | { | ||
782 | int i; | ||
783 | char cmdbuf[3*MAX_COMMAND_SIZE + 1]; | ||
784 | 740 | ||
785 | for (i = 0; i < fsg->cmnd_size; ++i) | 741 | static void dump_cdb(struct fsg_dev *fsg) |
786 | sprintf(cmdbuf + i*3, " %02x", fsg->cmnd[i]); | 742 | { |
787 | VDBG(fsg, "SCSI CDB: %s\n", cmdbuf); | 743 | print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE, |
744 | 16, 1, fsg->cmnd, fsg->cmnd_size, 0); | ||
788 | } | 745 | } |
789 | 746 | ||
747 | #else | ||
748 | |||
749 | static void dump_cdb(struct fsg_dev *fsg) | ||
750 | {} | ||
751 | |||
752 | #endif /* VERBOSE_DEBUG */ | ||
790 | #endif /* DUMP_MSGS */ | 753 | #endif /* DUMP_MSGS */ |
791 | 754 | ||
792 | 755 | ||
@@ -809,24 +772,24 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | |||
809 | 772 | ||
810 | /* Routines for unaligned data access */ | 773 | /* Routines for unaligned data access */ |
811 | 774 | ||
812 | static u16 inline get_be16(u8 *buf) | 775 | static u16 get_be16(u8 *buf) |
813 | { | 776 | { |
814 | return ((u16) buf[0] << 8) | ((u16) buf[1]); | 777 | return ((u16) buf[0] << 8) | ((u16) buf[1]); |
815 | } | 778 | } |
816 | 779 | ||
817 | static u32 inline get_be32(u8 *buf) | 780 | static u32 get_be32(u8 *buf) |
818 | { | 781 | { |
819 | return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) | | 782 | return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) | |
820 | ((u32) buf[2] << 8) | ((u32) buf[3]); | 783 | ((u32) buf[2] << 8) | ((u32) buf[3]); |
821 | } | 784 | } |
822 | 785 | ||
823 | static void inline put_be16(u8 *buf, u16 val) | 786 | static void put_be16(u8 *buf, u16 val) |
824 | { | 787 | { |
825 | buf[0] = val >> 8; | 788 | buf[0] = val >> 8; |
826 | buf[1] = val; | 789 | buf[1] = val; |
827 | } | 790 | } |
828 | 791 | ||
829 | static void inline put_be32(u8 *buf, u32 val) | 792 | static void put_be32(u8 *buf, u32 val) |
830 | { | 793 | { |
831 | buf[0] = val >> 24; | 794 | buf[0] = val >> 24; |
832 | buf[1] = val >> 16; | 795 | buf[1] = val >> 16; |
@@ -950,8 +913,6 @@ static const struct usb_descriptor_header *fs_function[] = { | |||
950 | #define FS_FUNCTION_PRE_EP_ENTRIES 2 | 913 | #define FS_FUNCTION_PRE_EP_ENTRIES 2 |
951 | 914 | ||
952 | 915 | ||
953 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
954 | |||
955 | /* | 916 | /* |
956 | * USB 2.0 devices need to expose both high speed and full speed | 917 | * USB 2.0 devices need to expose both high speed and full speed |
957 | * descriptors, unless they only run at full speed. | 918 | * descriptors, unless they only run at full speed. |
@@ -1014,14 +975,14 @@ static const struct usb_descriptor_header *hs_function[] = { | |||
1014 | #define HS_FUNCTION_PRE_EP_ENTRIES 2 | 975 | #define HS_FUNCTION_PRE_EP_ENTRIES 2 |
1015 | 976 | ||
1016 | /* Maxpacket and other transfer characteristics vary by speed. */ | 977 | /* Maxpacket and other transfer characteristics vary by speed. */ |
1017 | #define ep_desc(g,fs,hs) (((g)->speed==USB_SPEED_HIGH) ? (hs) : (fs)) | 978 | static struct usb_endpoint_descriptor * |
1018 | 979 | ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, | |
1019 | #else | 980 | struct usb_endpoint_descriptor *hs) |
1020 | 981 | { | |
1021 | /* If there's no high speed support, always use the full-speed descriptor. */ | 982 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) |
1022 | #define ep_desc(g,fs,hs) fs | 983 | return hs; |
1023 | 984 | return fs; | |
1024 | #endif /* !CONFIG_USB_GADGET_DUALSPEED */ | 985 | } |
1025 | 986 | ||
1026 | 987 | ||
1027 | /* The CBI specification limits the serial string to 12 uppercase hexadecimal | 988 | /* The CBI specification limits the serial string to 12 uppercase hexadecimal |
@@ -1053,26 +1014,22 @@ static struct usb_gadget_strings stringtab = { | |||
1053 | static int populate_config_buf(struct usb_gadget *gadget, | 1014 | static int populate_config_buf(struct usb_gadget *gadget, |
1054 | u8 *buf, u8 type, unsigned index) | 1015 | u8 *buf, u8 type, unsigned index) |
1055 | { | 1016 | { |
1056 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1057 | enum usb_device_speed speed = gadget->speed; | 1017 | enum usb_device_speed speed = gadget->speed; |
1058 | #endif | ||
1059 | int len; | 1018 | int len; |
1060 | const struct usb_descriptor_header **function; | 1019 | const struct usb_descriptor_header **function; |
1061 | 1020 | ||
1062 | if (index > 0) | 1021 | if (index > 0) |
1063 | return -EINVAL; | 1022 | return -EINVAL; |
1064 | 1023 | ||
1065 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1024 | if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG) |
1066 | if (type == USB_DT_OTHER_SPEED_CONFIG) | ||
1067 | speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; | 1025 | speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; |
1068 | if (speed == USB_SPEED_HIGH) | 1026 | if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH) |
1069 | function = hs_function; | 1027 | function = hs_function; |
1070 | else | 1028 | else |
1071 | #endif | ||
1072 | function = fs_function; | 1029 | function = fs_function; |
1073 | 1030 | ||
1074 | /* for now, don't advertise srp-only devices */ | 1031 | /* for now, don't advertise srp-only devices */ |
1075 | if (!gadget->is_otg) | 1032 | if (!gadget_is_otg(gadget)) |
1076 | function++; | 1033 | function++; |
1077 | 1034 | ||
1078 | len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); | 1035 | len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); |
@@ -1394,10 +1351,9 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1394 | value = sizeof device_desc; | 1351 | value = sizeof device_desc; |
1395 | memcpy(req->buf, &device_desc, value); | 1352 | memcpy(req->buf, &device_desc, value); |
1396 | break; | 1353 | break; |
1397 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1398 | case USB_DT_DEVICE_QUALIFIER: | 1354 | case USB_DT_DEVICE_QUALIFIER: |
1399 | VDBG(fsg, "get device qualifier\n"); | 1355 | VDBG(fsg, "get device qualifier\n"); |
1400 | if (!fsg->gadget->is_dualspeed) | 1356 | if (!gadget_is_dualspeed(fsg->gadget)) |
1401 | break; | 1357 | break; |
1402 | value = sizeof dev_qualifier; | 1358 | value = sizeof dev_qualifier; |
1403 | memcpy(req->buf, &dev_qualifier, value); | 1359 | memcpy(req->buf, &dev_qualifier, value); |
@@ -1405,15 +1361,12 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1405 | 1361 | ||
1406 | case USB_DT_OTHER_SPEED_CONFIG: | 1362 | case USB_DT_OTHER_SPEED_CONFIG: |
1407 | VDBG(fsg, "get other-speed config descriptor\n"); | 1363 | VDBG(fsg, "get other-speed config descriptor\n"); |
1408 | if (!fsg->gadget->is_dualspeed) | 1364 | if (!gadget_is_dualspeed(fsg->gadget)) |
1409 | break; | 1365 | break; |
1410 | goto get_config; | 1366 | goto get_config; |
1411 | #endif | ||
1412 | case USB_DT_CONFIG: | 1367 | case USB_DT_CONFIG: |
1413 | VDBG(fsg, "get configuration descriptor\n"); | 1368 | VDBG(fsg, "get configuration descriptor\n"); |
1414 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1369 | get_config: |
1415 | get_config: | ||
1416 | #endif | ||
1417 | value = populate_config_buf(fsg->gadget, | 1370 | value = populate_config_buf(fsg->gadget, |
1418 | req->buf, | 1371 | req->buf, |
1419 | w_value >> 8, | 1372 | w_value >> 8, |
@@ -1646,7 +1599,8 @@ static int do_read(struct fsg_dev *fsg) | |||
1646 | /* Wait for the next buffer to become available */ | 1599 | /* Wait for the next buffer to become available */ |
1647 | bh = fsg->next_buffhd_to_fill; | 1600 | bh = fsg->next_buffhd_to_fill; |
1648 | while (bh->state != BUF_STATE_EMPTY) { | 1601 | while (bh->state != BUF_STATE_EMPTY) { |
1649 | if ((rc = sleep_thread(fsg)) != 0) | 1602 | rc = sleep_thread(fsg); |
1603 | if (rc) | ||
1650 | return rc; | 1604 | return rc; |
1651 | } | 1605 | } |
1652 | 1606 | ||
@@ -1885,7 +1839,8 @@ static int do_write(struct fsg_dev *fsg) | |||
1885 | } | 1839 | } |
1886 | 1840 | ||
1887 | /* Wait for something to happen */ | 1841 | /* Wait for something to happen */ |
1888 | if ((rc = sleep_thread(fsg)) != 0) | 1842 | rc = sleep_thread(fsg); |
1843 | if (rc) | ||
1889 | return rc; | 1844 | return rc; |
1890 | } | 1845 | } |
1891 | 1846 | ||
@@ -2369,7 +2324,8 @@ static int pad_with_zeros(struct fsg_dev *fsg) | |||
2369 | 2324 | ||
2370 | /* Wait for the next buffer to be free */ | 2325 | /* Wait for the next buffer to be free */ |
2371 | while (bh->state != BUF_STATE_EMPTY) { | 2326 | while (bh->state != BUF_STATE_EMPTY) { |
2372 | if ((rc = sleep_thread(fsg)) != 0) | 2327 | rc = sleep_thread(fsg); |
2328 | if (rc) | ||
2373 | return rc; | 2329 | return rc; |
2374 | } | 2330 | } |
2375 | 2331 | ||
@@ -2429,7 +2385,8 @@ static int throw_away_data(struct fsg_dev *fsg) | |||
2429 | } | 2385 | } |
2430 | 2386 | ||
2431 | /* Otherwise wait for something to happen */ | 2387 | /* Otherwise wait for something to happen */ |
2432 | if ((rc = sleep_thread(fsg)) != 0) | 2388 | rc = sleep_thread(fsg); |
2389 | if (rc) | ||
2433 | return rc; | 2390 | return rc; |
2434 | } | 2391 | } |
2435 | return 0; | 2392 | return 0; |
@@ -2551,7 +2508,8 @@ static int send_status(struct fsg_dev *fsg) | |||
2551 | /* Wait for the next buffer to become available */ | 2508 | /* Wait for the next buffer to become available */ |
2552 | bh = fsg->next_buffhd_to_fill; | 2509 | bh = fsg->next_buffhd_to_fill; |
2553 | while (bh->state != BUF_STATE_EMPTY) { | 2510 | while (bh->state != BUF_STATE_EMPTY) { |
2554 | if ((rc = sleep_thread(fsg)) != 0) | 2511 | rc = sleep_thread(fsg); |
2512 | if (rc) | ||
2555 | return rc; | 2513 | return rc; |
2556 | } | 2514 | } |
2557 | 2515 | ||
@@ -2771,9 +2729,10 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2771 | /* Wait for the next buffer to become available for data or status */ | 2729 | /* Wait for the next buffer to become available for data or status */ |
2772 | bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill; | 2730 | bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill; |
2773 | while (bh->state != BUF_STATE_EMPTY) { | 2731 | while (bh->state != BUF_STATE_EMPTY) { |
2774 | if ((rc = sleep_thread(fsg)) != 0) | 2732 | rc = sleep_thread(fsg); |
2733 | if (rc) | ||
2775 | return rc; | 2734 | return rc; |
2776 | } | 2735 | } |
2777 | fsg->phase_error = 0; | 2736 | fsg->phase_error = 0; |
2778 | fsg->short_packet_received = 0; | 2737 | fsg->short_packet_received = 0; |
2779 | 2738 | ||
@@ -3005,7 +2964,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
3005 | 2964 | ||
3006 | /* Is the CBW meaningful? */ | 2965 | /* Is the CBW meaningful? */ |
3007 | if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG || | 2966 | if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG || |
3008 | cbw->Length < 6 || cbw->Length > MAX_COMMAND_SIZE) { | 2967 | cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) { |
3009 | DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " | 2968 | DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " |
3010 | "cmdlen %u\n", | 2969 | "cmdlen %u\n", |
3011 | cbw->Lun, cbw->Flags, cbw->Length); | 2970 | cbw->Lun, cbw->Flags, cbw->Length); |
@@ -3045,9 +3004,10 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3045 | /* Wait for the next buffer to become available */ | 3004 | /* Wait for the next buffer to become available */ |
3046 | bh = fsg->next_buffhd_to_fill; | 3005 | bh = fsg->next_buffhd_to_fill; |
3047 | while (bh->state != BUF_STATE_EMPTY) { | 3006 | while (bh->state != BUF_STATE_EMPTY) { |
3048 | if ((rc = sleep_thread(fsg)) != 0) | 3007 | rc = sleep_thread(fsg); |
3008 | if (rc) | ||
3049 | return rc; | 3009 | return rc; |
3050 | } | 3010 | } |
3051 | 3011 | ||
3052 | /* Queue a request to read a Bulk-only CBW */ | 3012 | /* Queue a request to read a Bulk-only CBW */ |
3053 | set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); | 3013 | set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); |
@@ -3061,9 +3021,10 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3061 | 3021 | ||
3062 | /* Wait for the CBW to arrive */ | 3022 | /* Wait for the CBW to arrive */ |
3063 | while (bh->state != BUF_STATE_FULL) { | 3023 | while (bh->state != BUF_STATE_FULL) { |
3064 | if ((rc = sleep_thread(fsg)) != 0) | 3024 | rc = sleep_thread(fsg); |
3025 | if (rc) | ||
3065 | return rc; | 3026 | return rc; |
3066 | } | 3027 | } |
3067 | smp_rmb(); | 3028 | smp_rmb(); |
3068 | rc = received_cbw(fsg, bh); | 3029 | rc = received_cbw(fsg, bh); |
3069 | bh->state = BUF_STATE_EMPTY; | 3030 | bh->state = BUF_STATE_EMPTY; |
@@ -3072,9 +3033,10 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3072 | 3033 | ||
3073 | /* Wait for the next command to arrive */ | 3034 | /* Wait for the next command to arrive */ |
3074 | while (fsg->cbbuf_cmnd_size == 0) { | 3035 | while (fsg->cbbuf_cmnd_size == 0) { |
3075 | if ((rc = sleep_thread(fsg)) != 0) | 3036 | rc = sleep_thread(fsg); |
3037 | if (rc) | ||
3076 | return rc; | 3038 | return rc; |
3077 | } | 3039 | } |
3078 | 3040 | ||
3079 | /* Is the previous status interrupt request still busy? | 3041 | /* Is the previous status interrupt request still busy? |
3080 | * The host is allowed to skip reading the status, | 3042 | * The host is allowed to skip reading the status, |
@@ -3595,7 +3557,8 @@ static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char * | |||
3595 | return sprintf(buf, "%d\n", curlun->ro); | 3557 | return sprintf(buf, "%d\n", curlun->ro); |
3596 | } | 3558 | } |
3597 | 3559 | ||
3598 | static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) | 3560 | static ssize_t show_file(struct device *dev, struct device_attribute *attr, |
3561 | char *buf) | ||
3599 | { | 3562 | { |
3600 | struct lun *curlun = dev_to_lun(dev); | 3563 | struct lun *curlun = dev_to_lun(dev); |
3601 | struct fsg_dev *fsg = dev_get_drvdata(dev); | 3564 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
@@ -3604,8 +3567,8 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char | |||
3604 | 3567 | ||
3605 | down_read(&fsg->filesem); | 3568 | down_read(&fsg->filesem); |
3606 | if (backing_file_is_open(curlun)) { // Get the complete pathname | 3569 | if (backing_file_is_open(curlun)) { // Get the complete pathname |
3607 | p = d_path(curlun->filp->f_path.dentry, curlun->filp->f_path.mnt, | 3570 | p = d_path(curlun->filp->f_path.dentry, |
3608 | buf, PAGE_SIZE - 1); | 3571 | curlun->filp->f_path.mnt, buf, PAGE_SIZE - 1); |
3609 | if (IS_ERR(p)) | 3572 | if (IS_ERR(p)) |
3610 | rc = PTR_ERR(p); | 3573 | rc = PTR_ERR(p); |
3611 | else { | 3574 | else { |
@@ -3623,7 +3586,8 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char | |||
3623 | } | 3586 | } |
3624 | 3587 | ||
3625 | 3588 | ||
3626 | static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 3589 | static ssize_t store_ro(struct device *dev, struct device_attribute *attr, |
3590 | const char *buf, size_t count) | ||
3627 | { | 3591 | { |
3628 | ssize_t rc = count; | 3592 | ssize_t rc = count; |
3629 | struct lun *curlun = dev_to_lun(dev); | 3593 | struct lun *curlun = dev_to_lun(dev); |
@@ -3647,7 +3611,8 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const | |||
3647 | return rc; | 3611 | return rc; |
3648 | } | 3612 | } |
3649 | 3613 | ||
3650 | static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 3614 | static ssize_t store_file(struct device *dev, struct device_attribute *attr, |
3615 | const char *buf, size_t count) | ||
3651 | { | 3616 | { |
3652 | struct lun *curlun = dev_to_lun(dev); | 3617 | struct lun *curlun = dev_to_lun(dev); |
3653 | struct fsg_dev *fsg = dev_get_drvdata(dev); | 3618 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
@@ -3859,7 +3824,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3859 | /* Find out how many LUNs there should be */ | 3824 | /* Find out how many LUNs there should be */ |
3860 | i = mod_data.nluns; | 3825 | i = mod_data.nluns; |
3861 | if (i == 0) | 3826 | if (i == 0) |
3862 | i = max(mod_data.num_filenames, 1); | 3827 | i = max(mod_data.num_filenames, 1u); |
3863 | if (i > MAX_LUNS) { | 3828 | if (i > MAX_LUNS) { |
3864 | ERROR(fsg, "invalid number of LUNs: %d\n", i); | 3829 | ERROR(fsg, "invalid number of LUNs: %d\n", i); |
3865 | rc = -EINVAL; | 3830 | rc = -EINVAL; |
@@ -3944,21 +3909,23 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3944 | intf_desc.bInterfaceProtocol = mod_data.transport_type; | 3909 | intf_desc.bInterfaceProtocol = mod_data.transport_type; |
3945 | fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL; | 3910 | fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL; |
3946 | 3911 | ||
3947 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 3912 | if (gadget_is_dualspeed(gadget)) { |
3948 | hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL; | 3913 | hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL; |
3949 | 3914 | ||
3950 | /* Assume ep0 uses the same maxpacket value for both speeds */ | 3915 | /* Assume ep0 uses the same maxpacket value for both speeds */ |
3951 | dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; | 3916 | dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; |
3952 | 3917 | ||
3953 | /* Assume that all endpoint addresses are the same for both speeds */ | 3918 | /* Assume endpoint addresses are the same for both speeds */ |
3954 | hs_bulk_in_desc.bEndpointAddress = fs_bulk_in_desc.bEndpointAddress; | 3919 | hs_bulk_in_desc.bEndpointAddress = |
3955 | hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress; | 3920 | fs_bulk_in_desc.bEndpointAddress; |
3956 | hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress; | 3921 | hs_bulk_out_desc.bEndpointAddress = |
3957 | #endif | 3922 | fs_bulk_out_desc.bEndpointAddress; |
3923 | hs_intr_in_desc.bEndpointAddress = | ||
3924 | fs_intr_in_desc.bEndpointAddress; | ||
3925 | } | ||
3958 | 3926 | ||
3959 | if (gadget->is_otg) { | 3927 | if (gadget_is_otg(gadget)) |
3960 | otg_desc.bmAttributes |= USB_OTG_HNP; | 3928 | otg_desc.bmAttributes |= USB_OTG_HNP; |
3961 | } | ||
3962 | 3929 | ||
3963 | rc = -ENOMEM; | 3930 | rc = -ENOMEM; |
3964 | 3931 | ||
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index d57bcfbc08a5..9bb7f64a85cd 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/moduleparam.h> | 35 | #include <linux/moduleparam.h> |
36 | #include <linux/device.h> | 36 | #include <linux/device.h> |
37 | #include <linux/usb/ch9.h> | 37 | #include <linux/usb/ch9.h> |
38 | #include <linux/usb_gadget.h> | 38 | #include <linux/usb/gadget.h> |
39 | #include <linux/usb/otg.h> | 39 | #include <linux/usb/otg.h> |
40 | #include <linux/dma-mapping.h> | 40 | #include <linux/dma-mapping.h> |
41 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
@@ -1090,14 +1090,11 @@ static int fsl_vbus_session(struct usb_gadget *gadget, int is_active) | |||
1090 | */ | 1090 | */ |
1091 | static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA) | 1091 | static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA) |
1092 | { | 1092 | { |
1093 | #ifdef CONFIG_USB_OTG | ||
1094 | struct fsl_udc *udc; | 1093 | struct fsl_udc *udc; |
1095 | 1094 | ||
1096 | udc = container_of(gadget, struct fsl_udc, gadget); | 1095 | udc = container_of(gadget, struct fsl_udc, gadget); |
1097 | |||
1098 | if (udc->transceiver) | 1096 | if (udc->transceiver) |
1099 | return otg_set_power(udc->transceiver, mA); | 1097 | return otg_set_power(udc->transceiver, mA); |
1100 | #endif | ||
1101 | return -ENOTSUPP; | 1098 | return -ENOTSUPP; |
1102 | } | 1099 | } |
1103 | 1100 | ||
@@ -1120,7 +1117,7 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) | |||
1120 | return 0; | 1117 | return 0; |
1121 | } | 1118 | } |
1122 | 1119 | ||
1123 | /* defined in usb_gadget.h */ | 1120 | /* defined in gadget.h */ |
1124 | static struct usb_gadget_ops fsl_gadget_ops = { | 1121 | static struct usb_gadget_ops fsl_gadget_ops = { |
1125 | .get_frame = fsl_get_frame, | 1122 | .get_frame = fsl_get_frame, |
1126 | .wakeup = fsl_wakeup, | 1123 | .wakeup = fsl_wakeup, |
@@ -1321,7 +1318,7 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
1321 | | USB_TYPE_STANDARD)) { | 1318 | | USB_TYPE_STANDARD)) { |
1322 | /* Note: The driver has not include OTG support yet. | 1319 | /* Note: The driver has not include OTG support yet. |
1323 | * This will be set when OTG support is added */ | 1320 | * This will be set when OTG support is added */ |
1324 | if (!udc->gadget.is_otg) | 1321 | if (!gadget_is_otg(udc->gadget)) |
1325 | break; | 1322 | break; |
1326 | else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) | 1323 | else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) |
1327 | udc->gadget.b_hnp_enable = 1; | 1324 | udc->gadget.b_hnp_enable = 1; |
@@ -1330,6 +1327,8 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
1330 | else if (setup->bRequest == | 1327 | else if (setup->bRequest == |
1331 | USB_DEVICE_A_ALT_HNP_SUPPORT) | 1328 | USB_DEVICE_A_ALT_HNP_SUPPORT) |
1332 | udc->gadget.a_alt_hnp_support = 1; | 1329 | udc->gadget.a_alt_hnp_support = 1; |
1330 | else | ||
1331 | break; | ||
1333 | rc = 0; | 1332 | rc = 0; |
1334 | } else | 1333 | } else |
1335 | break; | 1334 | break; |
@@ -1840,10 +1839,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1840 | if (!driver || driver != udc_controller->driver || !driver->unbind) | 1839 | if (!driver || driver != udc_controller->driver || !driver->unbind) |
1841 | return -EINVAL; | 1840 | return -EINVAL; |
1842 | 1841 | ||
1843 | #ifdef CONFIG_USB_OTG | ||
1844 | if (udc_controller->transceiver) | 1842 | if (udc_controller->transceiver) |
1845 | (void)otg_set_peripheral(udc_controller->transceiver, 0); | 1843 | (void)otg_set_peripheral(udc_controller->transceiver, 0); |
1846 | #endif | ||
1847 | 1844 | ||
1848 | /* stop DR, disable intr */ | 1845 | /* stop DR, disable intr */ |
1849 | dr_controller_stop(udc_controller); | 1846 | dr_controller_stop(udc_controller); |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 1c5aa49d7432..0689189550bc 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -18,17 +18,11 @@ | |||
18 | * http://www.usb.org/developers/devclass_docs/midi10.pdf | 18 | * http://www.usb.org/developers/devclass_docs/midi10.pdf |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define DEBUG 1 | 21 | /* #define VERBOSE_DEBUG */ |
22 | // #define VERBOSE | ||
23 | 22 | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
26 | #include <linux/delay.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/utsname.h> | 24 | #include <linux/utsname.h> |
30 | #include <linux/device.h> | 25 | #include <linux/device.h> |
31 | #include <linux/moduleparam.h> | ||
32 | 26 | ||
33 | #include <sound/driver.h> | 27 | #include <sound/driver.h> |
34 | #include <sound/core.h> | 28 | #include <sound/core.h> |
@@ -36,7 +30,7 @@ | |||
36 | #include <sound/rawmidi.h> | 30 | #include <sound/rawmidi.h> |
37 | 31 | ||
38 | #include <linux/usb/ch9.h> | 32 | #include <linux/usb/ch9.h> |
39 | #include <linux/usb_gadget.h> | 33 | #include <linux/usb/gadget.h> |
40 | #include <linux/usb/audio.h> | 34 | #include <linux/usb/audio.h> |
41 | #include <linux/usb/midi.h> | 35 | #include <linux/usb/midi.h> |
42 | 36 | ||
@@ -139,30 +133,16 @@ struct gmidi_device { | |||
139 | static void gmidi_transmit(struct gmidi_device* dev, struct usb_request* req); | 133 | static void gmidi_transmit(struct gmidi_device* dev, struct usb_request* req); |
140 | 134 | ||
141 | 135 | ||
142 | #define xprintk(d,level,fmt,args...) \ | 136 | #define DBG(d, fmt, args...) \ |
143 | dev_printk(level , &(d)->gadget->dev , fmt , ## args) | 137 | dev_dbg(&(d)->gadget->dev , fmt , ## args) |
144 | 138 | #define VDBG(d, fmt, args...) \ | |
145 | #ifdef DEBUG | 139 | dev_vdbg(&(d)->gadget->dev , fmt , ## args) |
146 | #define DBG(dev,fmt,args...) \ | 140 | #define ERROR(d, fmt, args...) \ |
147 | xprintk(dev , KERN_DEBUG , fmt , ## args) | 141 | dev_err(&(d)->gadget->dev , fmt , ## args) |
148 | #else | 142 | #define WARN(d, fmt, args...) \ |
149 | #define DBG(dev,fmt,args...) \ | 143 | dev_warn(&(d)->gadget->dev , fmt , ## args) |
150 | do { } while (0) | 144 | #define INFO(d, fmt, args...) \ |
151 | #endif /* DEBUG */ | 145 | dev_info(&(d)->gadget->dev , fmt , ## args) |
152 | |||
153 | #ifdef VERBOSE | ||
154 | #define VDBG DBG | ||
155 | #else | ||
156 | #define VDBG(dev,fmt,args...) \ | ||
157 | do { } while (0) | ||
158 | #endif /* VERBOSE */ | ||
159 | |||
160 | #define ERROR(dev,fmt,args...) \ | ||
161 | xprintk(dev , KERN_ERR , fmt , ## args) | ||
162 | #define WARN(dev,fmt,args...) \ | ||
163 | xprintk(dev , KERN_WARNING , fmt , ## args) | ||
164 | #define INFO(dev,fmt,args...) \ | ||
165 | xprintk(dev , KERN_INFO , fmt , ## args) | ||
166 | 146 | ||
167 | 147 | ||
168 | static unsigned buflen = 256; | 148 | static unsigned buflen = 256; |
@@ -425,7 +405,7 @@ static int config_buf(struct usb_gadget *gadget, | |||
425 | return len; | 405 | return len; |
426 | } | 406 | } |
427 | 407 | ||
428 | static struct usb_request* alloc_ep_req(struct usb_ep *ep, unsigned length) | 408 | static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length) |
429 | { | 409 | { |
430 | struct usb_request *req; | 410 | struct usb_request *req; |
431 | 411 | ||
@@ -455,7 +435,7 @@ static const uint8_t gmidi_cin_length[] = { | |||
455 | * Receives a chunk of MIDI data. | 435 | * Receives a chunk of MIDI data. |
456 | */ | 436 | */ |
457 | static void gmidi_read_data(struct usb_ep *ep, int cable, | 437 | static void gmidi_read_data(struct usb_ep *ep, int cable, |
458 | uint8_t* data, int length) | 438 | uint8_t *data, int length) |
459 | { | 439 | { |
460 | struct gmidi_device *dev = ep->driver_data; | 440 | struct gmidi_device *dev = ep->driver_data; |
461 | /* cable is ignored, because for now we only have one. */ | 441 | /* cable is ignored, because for now we only have one. */ |
@@ -541,7 +521,7 @@ static int set_gmidi_config(struct gmidi_device *dev, gfp_t gfp_flags) | |||
541 | { | 521 | { |
542 | int err = 0; | 522 | int err = 0; |
543 | struct usb_request *req; | 523 | struct usb_request *req; |
544 | struct usb_ep* ep; | 524 | struct usb_ep *ep; |
545 | unsigned i; | 525 | unsigned i; |
546 | 526 | ||
547 | err = usb_ep_enable(dev->in_ep, &bulk_in_desc); | 527 | err = usb_ep_enable(dev->in_ep, &bulk_in_desc); |
@@ -628,7 +608,7 @@ gmidi_set_config(struct gmidi_device *dev, unsigned number, gfp_t gfp_flags) | |||
628 | 608 | ||
629 | if (gadget_is_sa1100(gadget) && dev->config) { | 609 | if (gadget_is_sa1100(gadget) && dev->config) { |
630 | /* tx fifo is full, but we can't clear it...*/ | 610 | /* tx fifo is full, but we can't clear it...*/ |
631 | INFO(dev, "can't change configurations\n"); | 611 | ERROR(dev, "can't change configurations\n"); |
632 | return -ESPIPE; | 612 | return -ESPIPE; |
633 | } | 613 | } |
634 | gmidi_reset_config(dev); | 614 | gmidi_reset_config(dev); |
@@ -843,7 +823,7 @@ static void gmidi_disconnect(struct usb_gadget *gadget) | |||
843 | static void /* __init_or_exit */ gmidi_unbind(struct usb_gadget *gadget) | 823 | static void /* __init_or_exit */ gmidi_unbind(struct usb_gadget *gadget) |
844 | { | 824 | { |
845 | struct gmidi_device *dev = get_gadget_data(gadget); | 825 | struct gmidi_device *dev = get_gadget_data(gadget); |
846 | struct snd_card* card; | 826 | struct snd_card *card; |
847 | 827 | ||
848 | DBG(dev, "unbind\n"); | 828 | DBG(dev, "unbind\n"); |
849 | 829 | ||
@@ -867,12 +847,12 @@ static int gmidi_snd_free(struct snd_device *device) | |||
867 | return 0; | 847 | return 0; |
868 | } | 848 | } |
869 | 849 | ||
870 | static void gmidi_transmit_packet(struct usb_request* req, uint8_t p0, | 850 | static void gmidi_transmit_packet(struct usb_request *req, uint8_t p0, |
871 | uint8_t p1, uint8_t p2, uint8_t p3) | 851 | uint8_t p1, uint8_t p2, uint8_t p3) |
872 | { | 852 | { |
873 | unsigned length = req->length; | 853 | unsigned length = req->length; |
854 | u8 *buf = (u8 *)req->buf + length; | ||
874 | 855 | ||
875 | uint8_t* buf = (uint8_t*)req->buf + length; | ||
876 | buf[0] = p0; | 856 | buf[0] = p0; |
877 | buf[1] = p1; | 857 | buf[1] = p1; |
878 | buf[2] = p2; | 858 | buf[2] = p2; |
@@ -883,8 +863,8 @@ static void gmidi_transmit_packet(struct usb_request* req, uint8_t p0, | |||
883 | /* | 863 | /* |
884 | * Converts MIDI commands to USB MIDI packets. | 864 | * Converts MIDI commands to USB MIDI packets. |
885 | */ | 865 | */ |
886 | static void gmidi_transmit_byte(struct usb_request* req, | 866 | static void gmidi_transmit_byte(struct usb_request *req, |
887 | struct gmidi_in_port* port, uint8_t b) | 867 | struct gmidi_in_port *port, uint8_t b) |
888 | { | 868 | { |
889 | uint8_t p0 = port->cable; | 869 | uint8_t p0 = port->cable; |
890 | 870 | ||
@@ -981,10 +961,10 @@ static void gmidi_transmit_byte(struct usb_request* req, | |||
981 | } | 961 | } |
982 | } | 962 | } |
983 | 963 | ||
984 | static void gmidi_transmit(struct gmidi_device* dev, struct usb_request* req) | 964 | static void gmidi_transmit(struct gmidi_device *dev, struct usb_request *req) |
985 | { | 965 | { |
986 | struct usb_ep* ep = dev->in_ep; | 966 | struct usb_ep *ep = dev->in_ep; |
987 | struct gmidi_in_port* port = &dev->in_port; | 967 | struct gmidi_in_port *port = &dev->in_port; |
988 | 968 | ||
989 | if (!ep) { | 969 | if (!ep) { |
990 | return; | 970 | return; |
@@ -1020,14 +1000,14 @@ static void gmidi_transmit(struct gmidi_device* dev, struct usb_request* req) | |||
1020 | 1000 | ||
1021 | static void gmidi_in_tasklet(unsigned long data) | 1001 | static void gmidi_in_tasklet(unsigned long data) |
1022 | { | 1002 | { |
1023 | struct gmidi_device* dev = (struct gmidi_device*)data; | 1003 | struct gmidi_device *dev = (struct gmidi_device *)data; |
1024 | 1004 | ||
1025 | gmidi_transmit(dev, NULL); | 1005 | gmidi_transmit(dev, NULL); |
1026 | } | 1006 | } |
1027 | 1007 | ||
1028 | static int gmidi_in_open(struct snd_rawmidi_substream *substream) | 1008 | static int gmidi_in_open(struct snd_rawmidi_substream *substream) |
1029 | { | 1009 | { |
1030 | struct gmidi_device* dev = substream->rmidi->private_data; | 1010 | struct gmidi_device *dev = substream->rmidi->private_data; |
1031 | 1011 | ||
1032 | VDBG(dev, "gmidi_in_open\n"); | 1012 | VDBG(dev, "gmidi_in_open\n"); |
1033 | dev->in_substream = substream; | 1013 | dev->in_substream = substream; |
@@ -1037,13 +1017,15 @@ static int gmidi_in_open(struct snd_rawmidi_substream *substream) | |||
1037 | 1017 | ||
1038 | static int gmidi_in_close(struct snd_rawmidi_substream *substream) | 1018 | static int gmidi_in_close(struct snd_rawmidi_substream *substream) |
1039 | { | 1019 | { |
1020 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
1021 | |||
1040 | VDBG(dev, "gmidi_in_close\n"); | 1022 | VDBG(dev, "gmidi_in_close\n"); |
1041 | return 0; | 1023 | return 0; |
1042 | } | 1024 | } |
1043 | 1025 | ||
1044 | static void gmidi_in_trigger(struct snd_rawmidi_substream *substream, int up) | 1026 | static void gmidi_in_trigger(struct snd_rawmidi_substream *substream, int up) |
1045 | { | 1027 | { |
1046 | struct gmidi_device* dev = substream->rmidi->private_data; | 1028 | struct gmidi_device *dev = substream->rmidi->private_data; |
1047 | 1029 | ||
1048 | VDBG(dev, "gmidi_in_trigger %d\n", up); | 1030 | VDBG(dev, "gmidi_in_trigger %d\n", up); |
1049 | dev->in_port.active = up; | 1031 | dev->in_port.active = up; |
@@ -1054,7 +1036,7 @@ static void gmidi_in_trigger(struct snd_rawmidi_substream *substream, int up) | |||
1054 | 1036 | ||
1055 | static int gmidi_out_open(struct snd_rawmidi_substream *substream) | 1037 | static int gmidi_out_open(struct snd_rawmidi_substream *substream) |
1056 | { | 1038 | { |
1057 | struct gmidi_device* dev = substream->rmidi->private_data; | 1039 | struct gmidi_device *dev = substream->rmidi->private_data; |
1058 | 1040 | ||
1059 | VDBG(dev, "gmidi_out_open\n"); | 1041 | VDBG(dev, "gmidi_out_open\n"); |
1060 | dev->out_substream = substream; | 1042 | dev->out_substream = substream; |
@@ -1063,13 +1045,15 @@ static int gmidi_out_open(struct snd_rawmidi_substream *substream) | |||
1063 | 1045 | ||
1064 | static int gmidi_out_close(struct snd_rawmidi_substream *substream) | 1046 | static int gmidi_out_close(struct snd_rawmidi_substream *substream) |
1065 | { | 1047 | { |
1048 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
1049 | |||
1066 | VDBG(dev, "gmidi_out_close\n"); | 1050 | VDBG(dev, "gmidi_out_close\n"); |
1067 | return 0; | 1051 | return 0; |
1068 | } | 1052 | } |
1069 | 1053 | ||
1070 | static void gmidi_out_trigger(struct snd_rawmidi_substream *substream, int up) | 1054 | static void gmidi_out_trigger(struct snd_rawmidi_substream *substream, int up) |
1071 | { | 1055 | { |
1072 | struct gmidi_device* dev = substream->rmidi->private_data; | 1056 | struct gmidi_device *dev = substream->rmidi->private_data; |
1073 | 1057 | ||
1074 | VDBG(dev, "gmidi_out_trigger %d\n", up); | 1058 | VDBG(dev, "gmidi_out_trigger %d\n", up); |
1075 | if (up) { | 1059 | if (up) { |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 349b8166f34a..2ec9d196a8cf 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/device.h> | 38 | #include <linux/device.h> |
39 | #include <linux/usb/ch9.h> | 39 | #include <linux/usb/ch9.h> |
40 | #include <linux/usb_gadget.h> | 40 | #include <linux/usb/gadget.h> |
41 | 41 | ||
42 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
43 | #include <asm/io.h> | 43 | #include <asm/io.h> |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 173004f60fea..47ef8bd58a00 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -20,8 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | 22 | ||
23 | // #define DEBUG /* data to help fault diagnosis */ | 23 | /* #define VERBOSE_DEBUG */ |
24 | // #define VERBOSE /* extra debug messages (success too) */ | ||
25 | 24 | ||
26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
@@ -38,7 +37,7 @@ | |||
38 | #include <linux/moduleparam.h> | 37 | #include <linux/moduleparam.h> |
39 | 38 | ||
40 | #include <linux/usb/gadgetfs.h> | 39 | #include <linux/usb/gadgetfs.h> |
41 | #include <linux/usb_gadget.h> | 40 | #include <linux/usb/gadget.h> |
42 | 41 | ||
43 | 42 | ||
44 | /* | 43 | /* |
@@ -253,7 +252,7 @@ static const char *CHIP; | |||
253 | do { } while (0) | 252 | do { } while (0) |
254 | #endif /* DEBUG */ | 253 | #endif /* DEBUG */ |
255 | 254 | ||
256 | #ifdef VERBOSE | 255 | #ifdef VERBOSE_DEBUG |
257 | #define VDEBUG DBG | 256 | #define VDEBUG DBG |
258 | #else | 257 | #else |
259 | #define VDEBUG(dev,fmt,args...) \ | 258 | #define VDEBUG(dev,fmt,args...) \ |
@@ -1010,11 +1009,12 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
1010 | /* assume that was SET_CONFIGURATION */ | 1009 | /* assume that was SET_CONFIGURATION */ |
1011 | if (dev->current_config) { | 1010 | if (dev->current_config) { |
1012 | unsigned power; | 1011 | unsigned power; |
1013 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1012 | |
1014 | if (dev->gadget->speed == USB_SPEED_HIGH) | 1013 | if (gadget_is_dualspeed(dev->gadget) |
1014 | && (dev->gadget->speed | ||
1015 | == USB_SPEED_HIGH)) | ||
1015 | power = dev->hs_config->bMaxPower; | 1016 | power = dev->hs_config->bMaxPower; |
1016 | else | 1017 | else |
1017 | #endif | ||
1018 | power = dev->config->bMaxPower; | 1018 | power = dev->config->bMaxPower; |
1019 | usb_gadget_vbus_draw(dev->gadget, 2 * power); | 1019 | usb_gadget_vbus_draw(dev->gadget, 2 * power); |
1020 | } | 1020 | } |
@@ -1355,24 +1355,21 @@ static int | |||
1355 | config_buf (struct dev_data *dev, u8 type, unsigned index) | 1355 | config_buf (struct dev_data *dev, u8 type, unsigned index) |
1356 | { | 1356 | { |
1357 | int len; | 1357 | int len; |
1358 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1358 | int hs = 0; |
1359 | int hs; | ||
1360 | #endif | ||
1361 | 1359 | ||
1362 | /* only one configuration */ | 1360 | /* only one configuration */ |
1363 | if (index > 0) | 1361 | if (index > 0) |
1364 | return -EINVAL; | 1362 | return -EINVAL; |
1365 | 1363 | ||
1366 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1364 | if (gadget_is_dualspeed(dev->gadget)) { |
1367 | hs = (dev->gadget->speed == USB_SPEED_HIGH); | 1365 | hs = (dev->gadget->speed == USB_SPEED_HIGH); |
1368 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 1366 | if (type == USB_DT_OTHER_SPEED_CONFIG) |
1369 | hs = !hs; | 1367 | hs = !hs; |
1368 | } | ||
1370 | if (hs) { | 1369 | if (hs) { |
1371 | dev->req->buf = dev->hs_config; | 1370 | dev->req->buf = dev->hs_config; |
1372 | len = le16_to_cpu(dev->hs_config->wTotalLength); | 1371 | len = le16_to_cpu(dev->hs_config->wTotalLength); |
1373 | } else | 1372 | } else { |
1374 | #endif | ||
1375 | { | ||
1376 | dev->req->buf = dev->config; | 1373 | dev->req->buf = dev->config; |
1377 | len = le16_to_cpu(dev->config->wTotalLength); | 1374 | len = le16_to_cpu(dev->config->wTotalLength); |
1378 | } | 1375 | } |
@@ -1393,13 +1390,13 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1393 | spin_lock (&dev->lock); | 1390 | spin_lock (&dev->lock); |
1394 | dev->setup_abort = 0; | 1391 | dev->setup_abort = 0; |
1395 | if (dev->state == STATE_DEV_UNCONNECTED) { | 1392 | if (dev->state == STATE_DEV_UNCONNECTED) { |
1396 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1393 | if (gadget_is_dualspeed(gadget) |
1397 | if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == NULL) { | 1394 | && gadget->speed == USB_SPEED_HIGH |
1395 | && dev->hs_config == NULL) { | ||
1398 | spin_unlock(&dev->lock); | 1396 | spin_unlock(&dev->lock); |
1399 | ERROR (dev, "no high speed config??\n"); | 1397 | ERROR (dev, "no high speed config??\n"); |
1400 | return -EINVAL; | 1398 | return -EINVAL; |
1401 | } | 1399 | } |
1402 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1403 | 1400 | ||
1404 | dev->state = STATE_DEV_CONNECTED; | 1401 | dev->state = STATE_DEV_CONNECTED; |
1405 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; | 1402 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; |
@@ -1469,13 +1466,12 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1469 | // user mode expected to disable endpoints | 1466 | // user mode expected to disable endpoints |
1470 | } else { | 1467 | } else { |
1471 | u8 config, power; | 1468 | u8 config, power; |
1472 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1469 | |
1473 | if (gadget->speed == USB_SPEED_HIGH) { | 1470 | if (gadget_is_dualspeed(gadget) |
1471 | && gadget->speed == USB_SPEED_HIGH) { | ||
1474 | config = dev->hs_config->bConfigurationValue; | 1472 | config = dev->hs_config->bConfigurationValue; |
1475 | power = dev->hs_config->bMaxPower; | 1473 | power = dev->hs_config->bMaxPower; |
1476 | } else | 1474 | } else { |
1477 | #endif | ||
1478 | { | ||
1479 | config = dev->config->bConfigurationValue; | 1475 | config = dev->config->bConfigurationValue; |
1480 | power = dev->config->bMaxPower; | 1476 | power = dev->config->bMaxPower; |
1481 | } | 1477 | } |
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h index b3fe197e1eeb..1ecfd6366b9a 100644 --- a/drivers/usb/gadget/lh7a40x_udc.h +++ b/drivers/usb/gadget/lh7a40x_udc.h | |||
@@ -50,7 +50,7 @@ | |||
50 | #include <asm/hardware.h> | 50 | #include <asm/hardware.h> |
51 | 51 | ||
52 | #include <linux/usb/ch9.h> | 52 | #include <linux/usb/ch9.h> |
53 | #include <linux/usb_gadget.h> | 53 | #include <linux/usb/gadget.h> |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Memory map | 56 | * Memory map |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 4b27d12f049d..ebc5536aa271 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | 28 | ||
29 | #include <linux/usb/ch9.h> | 29 | #include <linux/usb/ch9.h> |
30 | #include <linux/usb_gadget.h> | 30 | #include <linux/usb/gadget.h> |
31 | 31 | ||
32 | #include "m66592-udc.h" | 32 | #include "m66592-udc.h" |
33 | 33 | ||
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index c3d364ecd4f8..d5d473f8144b 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #include <linux/moduleparam.h> | 62 | #include <linux/moduleparam.h> |
63 | #include <linux/device.h> | 63 | #include <linux/device.h> |
64 | #include <linux/usb/ch9.h> | 64 | #include <linux/usb/ch9.h> |
65 | #include <linux/usb_gadget.h> | 65 | #include <linux/usb/gadget.h> |
66 | 66 | ||
67 | #include <asm/byteorder.h> | 67 | #include <asm/byteorder.h> |
68 | #include <asm/io.h> | 68 | #include <asm/io.h> |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 9b0f0925dddf..87c4f50dfb61 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/moduleparam.h> | 38 | #include <linux/moduleparam.h> |
39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
40 | #include <linux/usb/ch9.h> | 40 | #include <linux/usb/ch9.h> |
41 | #include <linux/usb_gadget.h> | 41 | #include <linux/usb/gadget.h> |
42 | #include <linux/usb/otg.h> | 42 | #include <linux/usb/otg.h> |
43 | #include <linux/dma-mapping.h> | 43 | #include <linux/dma-mapping.h> |
44 | #include <linux/clk.h> | 44 | #include <linux/clk.h> |
@@ -1241,19 +1241,15 @@ static void pullup_enable(struct omap_udc *udc) | |||
1241 | udc->gadget.dev.parent->power.power_state = PMSG_ON; | 1241 | udc->gadget.dev.parent->power.power_state = PMSG_ON; |
1242 | udc->gadget.dev.power.power_state = PMSG_ON; | 1242 | udc->gadget.dev.power.power_state = PMSG_ON; |
1243 | UDC_SYSCON1_REG |= UDC_PULLUP_EN; | 1243 | UDC_SYSCON1_REG |= UDC_PULLUP_EN; |
1244 | #ifndef CONFIG_USB_OTG | 1244 | if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx()) |
1245 | if (!cpu_is_omap15xx()) | ||
1246 | OTG_CTRL_REG |= OTG_BSESSVLD; | 1245 | OTG_CTRL_REG |= OTG_BSESSVLD; |
1247 | #endif | ||
1248 | UDC_IRQ_EN_REG = UDC_DS_CHG_IE; | 1246 | UDC_IRQ_EN_REG = UDC_DS_CHG_IE; |
1249 | } | 1247 | } |
1250 | 1248 | ||
1251 | static void pullup_disable(struct omap_udc *udc) | 1249 | static void pullup_disable(struct omap_udc *udc) |
1252 | { | 1250 | { |
1253 | #ifndef CONFIG_USB_OTG | 1251 | if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx()) |
1254 | if (!cpu_is_omap15xx()) | ||
1255 | OTG_CTRL_REG &= ~OTG_BSESSVLD; | 1252 | OTG_CTRL_REG &= ~OTG_BSESSVLD; |
1256 | #endif | ||
1257 | UDC_IRQ_EN_REG = UDC_DS_CHG_IE; | 1253 | UDC_IRQ_EN_REG = UDC_DS_CHG_IE; |
1258 | UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; | 1254 | UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; |
1259 | } | 1255 | } |
@@ -1390,7 +1386,7 @@ static void update_otg(struct omap_udc *udc) | |||
1390 | { | 1386 | { |
1391 | u16 devstat; | 1387 | u16 devstat; |
1392 | 1388 | ||
1393 | if (!udc->gadget.is_otg) | 1389 | if (!gadget_is_otg(udc->gadget)) |
1394 | return; | 1390 | return; |
1395 | 1391 | ||
1396 | if (OTG_CTRL_REG & OTG_ID) | 1392 | if (OTG_CTRL_REG & OTG_ID) |
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 1407ad1c8128..3e715082de36 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #include <asm/hardware.h> | 54 | #include <asm/hardware.h> |
55 | 55 | ||
56 | #include <linux/usb/ch9.h> | 56 | #include <linux/usb/ch9.h> |
57 | #include <linux/usb_gadget.h> | 57 | #include <linux/usb/gadget.h> |
58 | 58 | ||
59 | #include <asm/mach/udc_pxa2xx.h> | 59 | #include <asm/mach/udc_pxa2xx.h> |
60 | 60 | ||
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 0be80c635c48..e3e90f8a75e7 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/seq_file.h> | 42 | #include <linux/seq_file.h> |
43 | 43 | ||
44 | #include <linux/usb.h> | 44 | #include <linux/usb.h> |
45 | #include <linux/usb_gadget.h> | 45 | #include <linux/usb/gadget.h> |
46 | 46 | ||
47 | #include <asm/byteorder.h> | 47 | #include <asm/byteorder.h> |
48 | #include <asm/io.h> | 48 | #include <asm/io.h> |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index ce4d2e09633d..f5738eb8e765 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -17,34 +17,15 @@ | |||
17 | * | 17 | * |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
22 | #include <linux/delay.h> | ||
23 | #include <linux/ioport.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/timer.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/utsname.h> | 21 | #include <linux/utsname.h> |
31 | #include <linux/wait.h> | ||
32 | #include <linux/proc_fs.h> | ||
33 | #include <linux/device.h> | 22 | #include <linux/device.h> |
34 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
35 | #include <linux/tty_flip.h> | 24 | #include <linux/tty_flip.h> |
36 | #include <linux/mutex.h> | ||
37 | |||
38 | #include <asm/byteorder.h> | ||
39 | #include <asm/io.h> | ||
40 | #include <asm/irq.h> | ||
41 | #include <asm/system.h> | ||
42 | #include <asm/unaligned.h> | ||
43 | #include <asm/uaccess.h> | ||
44 | 25 | ||
45 | #include <linux/usb/ch9.h> | 26 | #include <linux/usb/ch9.h> |
46 | #include <linux/usb/cdc.h> | 27 | #include <linux/usb/cdc.h> |
47 | #include <linux/usb_gadget.h> | 28 | #include <linux/usb/gadget.h> |
48 | 29 | ||
49 | #include "gadget_chips.h" | 30 | #include "gadget_chips.h" |
50 | 31 | ||
@@ -89,30 +70,29 @@ | |||
89 | #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY | 70 | #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY |
90 | #define GS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS | 71 | #define GS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS |
91 | 72 | ||
92 | /* select highspeed/fullspeed, hiding highspeed if not configured */ | 73 | /* maxpacket and other transfer characteristics vary by speed. */ |
93 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 74 | static inline struct usb_endpoint_descriptor * |
94 | #define GS_SPEED_SELECT(is_hs,hs,fs) ((is_hs) ? (hs) : (fs)) | 75 | choose_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, |
95 | #else | 76 | struct usb_endpoint_descriptor *fs) |
96 | #define GS_SPEED_SELECT(is_hs,hs,fs) (fs) | 77 | { |
97 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 78 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) |
79 | return hs; | ||
80 | return fs; | ||
81 | } | ||
82 | |||
98 | 83 | ||
99 | /* debug settings */ | 84 | /* debug settings */ |
100 | #ifdef GS_DEBUG | 85 | #ifdef DEBUG |
101 | static int debug = 1; | 86 | static int debug = 1; |
87 | #else | ||
88 | #define debug 0 | ||
89 | #endif | ||
102 | 90 | ||
103 | #define gs_debug(format, arg...) \ | 91 | #define gs_debug(format, arg...) \ |
104 | do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0) | 92 | do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0) |
105 | #define gs_debug_level(level, format, arg...) \ | 93 | #define gs_debug_level(level, format, arg...) \ |
106 | do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0) | 94 | do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0) |
107 | 95 | ||
108 | #else | ||
109 | |||
110 | #define gs_debug(format, arg...) \ | ||
111 | do { } while(0) | ||
112 | #define gs_debug_level(level, format, arg...) \ | ||
113 | do { } while(0) | ||
114 | |||
115 | #endif /* GS_DEBUG */ | ||
116 | 96 | ||
117 | /* Thanks to NetChip Technologies for donating this product ID. | 97 | /* Thanks to NetChip Technologies for donating this product ID. |
118 | * | 98 | * |
@@ -147,10 +127,10 @@ struct gs_req_entry { | |||
147 | 127 | ||
148 | /* the port structure holds info for each port, one for each minor number */ | 128 | /* the port structure holds info for each port, one for each minor number */ |
149 | struct gs_port { | 129 | struct gs_port { |
150 | struct gs_dev *port_dev; /* pointer to device struct */ | 130 | struct gs_dev *port_dev; /* pointer to device struct */ |
151 | struct tty_struct *port_tty; /* pointer to tty struct */ | 131 | struct tty_struct *port_tty; /* pointer to tty struct */ |
152 | spinlock_t port_lock; | 132 | spinlock_t port_lock; |
153 | int port_num; | 133 | int port_num; |
154 | int port_open_count; | 134 | int port_open_count; |
155 | int port_in_use; /* open/close in progress */ | 135 | int port_in_use; /* open/close in progress */ |
156 | wait_queue_head_t port_write_wait;/* waiting to write */ | 136 | wait_queue_head_t port_write_wait;/* waiting to write */ |
@@ -188,7 +168,7 @@ static void __exit gs_module_exit(void); | |||
188 | /* tty driver */ | 168 | /* tty driver */ |
189 | static int gs_open(struct tty_struct *tty, struct file *file); | 169 | static int gs_open(struct tty_struct *tty, struct file *file); |
190 | static void gs_close(struct tty_struct *tty, struct file *file); | 170 | static void gs_close(struct tty_struct *tty, struct file *file); |
191 | static int gs_write(struct tty_struct *tty, | 171 | static int gs_write(struct tty_struct *tty, |
192 | const unsigned char *buf, int count); | 172 | const unsigned char *buf, int count); |
193 | static void gs_put_char(struct tty_struct *tty, unsigned char ch); | 173 | static void gs_put_char(struct tty_struct *tty, unsigned char ch); |
194 | static void gs_flush_chars(struct tty_struct *tty); | 174 | static void gs_flush_chars(struct tty_struct *tty); |
@@ -222,7 +202,7 @@ static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req); | |||
222 | static void gs_disconnect(struct usb_gadget *gadget); | 202 | static void gs_disconnect(struct usb_gadget *gadget); |
223 | static int gs_set_config(struct gs_dev *dev, unsigned config); | 203 | static int gs_set_config(struct gs_dev *dev, unsigned config); |
224 | static void gs_reset_config(struct gs_dev *dev); | 204 | static void gs_reset_config(struct gs_dev *dev); |
225 | static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | 205 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, |
226 | u8 type, unsigned int index, int is_otg); | 206 | u8 type, unsigned int index, int is_otg); |
227 | 207 | ||
228 | static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, | 208 | static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, |
@@ -415,18 +395,18 @@ static const struct usb_cdc_header_desc gs_header_desc = { | |||
415 | }; | 395 | }; |
416 | 396 | ||
417 | static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = { | 397 | static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = { |
418 | .bLength = sizeof(gs_call_mgmt_descriptor), | 398 | .bLength = sizeof(gs_call_mgmt_descriptor), |
419 | .bDescriptorType = USB_DT_CS_INTERFACE, | 399 | .bDescriptorType = USB_DT_CS_INTERFACE, |
420 | .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, | 400 | .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, |
421 | .bmCapabilities = 0, | 401 | .bmCapabilities = 0, |
422 | .bDataInterface = 1, /* index of data interface */ | 402 | .bDataInterface = 1, /* index of data interface */ |
423 | }; | 403 | }; |
424 | 404 | ||
425 | static struct usb_cdc_acm_descriptor gs_acm_descriptor = { | 405 | static struct usb_cdc_acm_descriptor gs_acm_descriptor = { |
426 | .bLength = sizeof(gs_acm_descriptor), | 406 | .bLength = sizeof(gs_acm_descriptor), |
427 | .bDescriptorType = USB_DT_CS_INTERFACE, | 407 | .bDescriptorType = USB_DT_CS_INTERFACE, |
428 | .bDescriptorSubType = USB_CDC_ACM_TYPE, | 408 | .bDescriptorSubType = USB_CDC_ACM_TYPE, |
429 | .bmCapabilities = 0, | 409 | .bmCapabilities = 0, |
430 | }; | 410 | }; |
431 | 411 | ||
432 | static const struct usb_cdc_union_desc gs_union_desc = { | 412 | static const struct usb_cdc_union_desc gs_union_desc = { |
@@ -436,7 +416,7 @@ static const struct usb_cdc_union_desc gs_union_desc = { | |||
436 | .bMasterInterface0 = 0, /* index of control interface */ | 416 | .bMasterInterface0 = 0, /* index of control interface */ |
437 | .bSlaveInterface0 = 1, /* index of data interface */ | 417 | .bSlaveInterface0 = 1, /* index of data interface */ |
438 | }; | 418 | }; |
439 | 419 | ||
440 | static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = { | 420 | static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = { |
441 | .bLength = USB_DT_ENDPOINT_SIZE, | 421 | .bLength = USB_DT_ENDPOINT_SIZE, |
442 | .bDescriptorType = USB_DT_ENDPOINT, | 422 | .bDescriptorType = USB_DT_ENDPOINT, |
@@ -482,7 +462,6 @@ static const struct usb_descriptor_header *gs_acm_fullspeed_function[] = { | |||
482 | NULL, | 462 | NULL, |
483 | }; | 463 | }; |
484 | 464 | ||
485 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
486 | static struct usb_endpoint_descriptor gs_highspeed_notify_desc = { | 465 | static struct usb_endpoint_descriptor gs_highspeed_notify_desc = { |
487 | .bLength = USB_DT_ENDPOINT_SIZE, | 466 | .bLength = USB_DT_ENDPOINT_SIZE, |
488 | .bDescriptorType = USB_DT_ENDPOINT, | 467 | .bDescriptorType = USB_DT_ENDPOINT, |
@@ -536,15 +515,13 @@ static const struct usb_descriptor_header *gs_acm_highspeed_function[] = { | |||
536 | NULL, | 515 | NULL, |
537 | }; | 516 | }; |
538 | 517 | ||
539 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
540 | |||
541 | 518 | ||
542 | /* Module */ | 519 | /* Module */ |
543 | MODULE_DESCRIPTION(GS_LONG_NAME); | 520 | MODULE_DESCRIPTION(GS_LONG_NAME); |
544 | MODULE_AUTHOR("Al Borchers"); | 521 | MODULE_AUTHOR("Al Borchers"); |
545 | MODULE_LICENSE("GPL"); | 522 | MODULE_LICENSE("GPL"); |
546 | 523 | ||
547 | #ifdef GS_DEBUG | 524 | #ifdef DEBUG |
548 | module_param(debug, int, S_IRUGO|S_IWUSR); | 525 | module_param(debug, int, S_IRUGO|S_IWUSR); |
549 | MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); | 526 | MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); |
550 | #endif | 527 | #endif |
@@ -915,7 +892,8 @@ static void gs_put_char(struct tty_struct *tty, unsigned char ch) | |||
915 | return; | 892 | return; |
916 | } | 893 | } |
917 | 894 | ||
918 | gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p, %p, %p\n", port->port_num, tty, ch, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2)); | 895 | gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p\n", |
896 | port->port_num, tty, ch, __builtin_return_address(0)); | ||
919 | 897 | ||
920 | spin_lock_irqsave(&port->port_lock, flags); | 898 | spin_lock_irqsave(&port->port_lock, flags); |
921 | 899 | ||
@@ -1116,7 +1094,11 @@ static int gs_send(struct gs_dev *dev) | |||
1116 | len = gs_send_packet(dev, req->buf, ep->maxpacket); | 1094 | len = gs_send_packet(dev, req->buf, ep->maxpacket); |
1117 | 1095 | ||
1118 | if (len > 0) { | 1096 | if (len > 0) { |
1119 | gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2)); | 1097 | gs_debug_level(3, "gs_send: len=%d, 0x%2.2x " |
1098 | "0x%2.2x 0x%2.2x ...\n", len, | ||
1099 | *((unsigned char *)req->buf), | ||
1100 | *((unsigned char *)req->buf+1), | ||
1101 | *((unsigned char *)req->buf+2)); | ||
1120 | list_del(&req_entry->re_entry); | 1102 | list_del(&req_entry->re_entry); |
1121 | req->length = len; | 1103 | req->length = len; |
1122 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 1104 | spin_unlock_irqrestore(&dev->dev_lock, flags); |
@@ -1269,7 +1251,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) | |||
1269 | 1251 | ||
1270 | switch(req->status) { | 1252 | switch(req->status) { |
1271 | case 0: | 1253 | case 0: |
1272 | /* normal completion */ | 1254 | /* normal completion */ |
1273 | gs_recv_packet(dev, req->buf, req->actual); | 1255 | gs_recv_packet(dev, req->buf, req->actual); |
1274 | requeue: | 1256 | requeue: |
1275 | req->length = ep->maxpacket; | 1257 | req->length = ep->maxpacket; |
@@ -1406,23 +1388,24 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1406 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | 1388 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; |
1407 | gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | 1389 | gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; |
1408 | 1390 | ||
1409 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1391 | if (gadget_is_dualspeed(gadget)) { |
1410 | gs_qualifier_desc.bDeviceClass = use_acm | 1392 | gs_qualifier_desc.bDeviceClass = use_acm |
1411 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | 1393 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; |
1412 | /* assume ep0 uses the same packet size for both speeds */ | 1394 | /* assume ep0 uses the same packet size for both speeds */ |
1413 | gs_qualifier_desc.bMaxPacketSize0 = gs_device_desc.bMaxPacketSize0; | 1395 | gs_qualifier_desc.bMaxPacketSize0 = |
1414 | /* assume endpoints are dual-speed */ | 1396 | gs_device_desc.bMaxPacketSize0; |
1415 | gs_highspeed_notify_desc.bEndpointAddress = | 1397 | /* assume endpoints are dual-speed */ |
1416 | gs_fullspeed_notify_desc.bEndpointAddress; | 1398 | gs_highspeed_notify_desc.bEndpointAddress = |
1417 | gs_highspeed_in_desc.bEndpointAddress = | 1399 | gs_fullspeed_notify_desc.bEndpointAddress; |
1418 | gs_fullspeed_in_desc.bEndpointAddress; | 1400 | gs_highspeed_in_desc.bEndpointAddress = |
1419 | gs_highspeed_out_desc.bEndpointAddress = | 1401 | gs_fullspeed_in_desc.bEndpointAddress; |
1420 | gs_fullspeed_out_desc.bEndpointAddress; | 1402 | gs_highspeed_out_desc.bEndpointAddress = |
1421 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 1403 | gs_fullspeed_out_desc.bEndpointAddress; |
1404 | } | ||
1422 | 1405 | ||
1423 | usb_gadget_set_selfpowered(gadget); | 1406 | usb_gadget_set_selfpowered(gadget); |
1424 | 1407 | ||
1425 | if (gadget->is_otg) { | 1408 | if (gadget_is_otg(gadget)) { |
1426 | gs_otg_descriptor.bmAttributes |= USB_OTG_HNP, | 1409 | gs_otg_descriptor.bmAttributes |= USB_OTG_HNP, |
1427 | gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1410 | gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
1428 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1411 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
@@ -1487,6 +1470,12 @@ static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget) | |||
1487 | dev->dev_ctrl_req = NULL; | 1470 | dev->dev_ctrl_req = NULL; |
1488 | } | 1471 | } |
1489 | gs_free_ports(dev); | 1472 | gs_free_ports(dev); |
1473 | if (dev->dev_notify_ep) | ||
1474 | usb_ep_disable(dev->dev_notify_ep); | ||
1475 | if (dev->dev_in_ep) | ||
1476 | usb_ep_disable(dev->dev_in_ep); | ||
1477 | if (dev->dev_out_ep) | ||
1478 | usb_ep_disable(dev->dev_out_ep); | ||
1490 | kfree(dev); | 1479 | kfree(dev); |
1491 | set_gadget_data(gadget, NULL); | 1480 | set_gadget_data(gadget, NULL); |
1492 | } | 1481 | } |
@@ -1570,9 +1559,8 @@ static int gs_setup_standard(struct usb_gadget *gadget, | |||
1570 | memcpy(req->buf, &gs_device_desc, ret); | 1559 | memcpy(req->buf, &gs_device_desc, ret); |
1571 | break; | 1560 | break; |
1572 | 1561 | ||
1573 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1574 | case USB_DT_DEVICE_QUALIFIER: | 1562 | case USB_DT_DEVICE_QUALIFIER: |
1575 | if (!gadget->is_dualspeed) | 1563 | if (!gadget_is_dualspeed(gadget)) |
1576 | break; | 1564 | break; |
1577 | ret = min(wLength, | 1565 | ret = min(wLength, |
1578 | (u16)sizeof(struct usb_qualifier_descriptor)); | 1566 | (u16)sizeof(struct usb_qualifier_descriptor)); |
@@ -1580,14 +1568,13 @@ static int gs_setup_standard(struct usb_gadget *gadget, | |||
1580 | break; | 1568 | break; |
1581 | 1569 | ||
1582 | case USB_DT_OTHER_SPEED_CONFIG: | 1570 | case USB_DT_OTHER_SPEED_CONFIG: |
1583 | if (!gadget->is_dualspeed) | 1571 | if (!gadget_is_dualspeed(gadget)) |
1584 | break; | 1572 | break; |
1585 | /* fall through */ | 1573 | /* fall through */ |
1586 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1587 | case USB_DT_CONFIG: | 1574 | case USB_DT_CONFIG: |
1588 | ret = gs_build_config_buf(req->buf, gadget->speed, | 1575 | ret = gs_build_config_buf(req->buf, gadget, |
1589 | wValue >> 8, wValue & 0xff, | 1576 | wValue >> 8, wValue & 0xff, |
1590 | gadget->is_otg); | 1577 | gadget_is_otg(gadget)); |
1591 | if (ret >= 0) | 1578 | if (ret >= 0) |
1592 | ret = min(wLength, (u16)ret); | 1579 | ret = min(wLength, (u16)ret); |
1593 | break; | 1580 | break; |
@@ -1827,8 +1814,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1827 | 1814 | ||
1828 | if (EP_NOTIFY_NAME | 1815 | if (EP_NOTIFY_NAME |
1829 | && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { | 1816 | && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { |
1830 | ep_desc = GS_SPEED_SELECT( | 1817 | ep_desc = choose_ep_desc(gadget, |
1831 | gadget->speed == USB_SPEED_HIGH, | ||
1832 | &gs_highspeed_notify_desc, | 1818 | &gs_highspeed_notify_desc, |
1833 | &gs_fullspeed_notify_desc); | 1819 | &gs_fullspeed_notify_desc); |
1834 | ret = usb_ep_enable(ep,ep_desc); | 1820 | ret = usb_ep_enable(ep,ep_desc); |
@@ -1844,9 +1830,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1844 | } | 1830 | } |
1845 | 1831 | ||
1846 | else if (strcmp(ep->name, EP_IN_NAME) == 0) { | 1832 | else if (strcmp(ep->name, EP_IN_NAME) == 0) { |
1847 | ep_desc = GS_SPEED_SELECT( | 1833 | ep_desc = choose_ep_desc(gadget, |
1848 | gadget->speed == USB_SPEED_HIGH, | 1834 | &gs_highspeed_in_desc, |
1849 | &gs_highspeed_in_desc, | ||
1850 | &gs_fullspeed_in_desc); | 1835 | &gs_fullspeed_in_desc); |
1851 | ret = usb_ep_enable(ep,ep_desc); | 1836 | ret = usb_ep_enable(ep,ep_desc); |
1852 | if (ret == 0) { | 1837 | if (ret == 0) { |
@@ -1861,8 +1846,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1861 | } | 1846 | } |
1862 | 1847 | ||
1863 | else if (strcmp(ep->name, EP_OUT_NAME) == 0) { | 1848 | else if (strcmp(ep->name, EP_OUT_NAME) == 0) { |
1864 | ep_desc = GS_SPEED_SELECT( | 1849 | ep_desc = choose_ep_desc(gadget, |
1865 | gadget->speed == USB_SPEED_HIGH, | ||
1866 | &gs_highspeed_out_desc, | 1850 | &gs_highspeed_out_desc, |
1867 | &gs_fullspeed_out_desc); | 1851 | &gs_fullspeed_out_desc); |
1868 | ret = usb_ep_enable(ep,ep_desc); | 1852 | ret = usb_ep_enable(ep,ep_desc); |
@@ -1981,11 +1965,11 @@ static void gs_reset_config(struct gs_dev *dev) | |||
1981 | * Builds the config descriptors in the given buffer and returns the | 1965 | * Builds the config descriptors in the given buffer and returns the |
1982 | * length, or a negative error number. | 1966 | * length, or a negative error number. |
1983 | */ | 1967 | */ |
1984 | static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | 1968 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, |
1985 | u8 type, unsigned int index, int is_otg) | 1969 | u8 type, unsigned int index, int is_otg) |
1986 | { | 1970 | { |
1987 | int len; | 1971 | int len; |
1988 | int high_speed; | 1972 | int high_speed = 0; |
1989 | const struct usb_config_descriptor *config_desc; | 1973 | const struct usb_config_descriptor *config_desc; |
1990 | const struct usb_descriptor_header **function; | 1974 | const struct usb_descriptor_header **function; |
1991 | 1975 | ||
@@ -1993,20 +1977,22 @@ static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | |||
1993 | return -EINVAL; | 1977 | return -EINVAL; |
1994 | 1978 | ||
1995 | /* other speed switches high and full speed */ | 1979 | /* other speed switches high and full speed */ |
1996 | high_speed = (speed == USB_SPEED_HIGH); | 1980 | if (gadget_is_dualspeed(g)) { |
1997 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 1981 | high_speed = (g->speed == USB_SPEED_HIGH); |
1998 | high_speed = !high_speed; | 1982 | if (type == USB_DT_OTHER_SPEED_CONFIG) |
1983 | high_speed = !high_speed; | ||
1984 | } | ||
1999 | 1985 | ||
2000 | if (use_acm) { | 1986 | if (use_acm) { |
2001 | config_desc = &gs_acm_config_desc; | 1987 | config_desc = &gs_acm_config_desc; |
2002 | function = GS_SPEED_SELECT(high_speed, | 1988 | function = high_speed |
2003 | gs_acm_highspeed_function, | 1989 | ? gs_acm_highspeed_function |
2004 | gs_acm_fullspeed_function); | 1990 | : gs_acm_fullspeed_function; |
2005 | } else { | 1991 | } else { |
2006 | config_desc = &gs_bulk_config_desc; | 1992 | config_desc = &gs_bulk_config_desc; |
2007 | function = GS_SPEED_SELECT(high_speed, | 1993 | function = high_speed |
2008 | gs_bulk_highspeed_function, | 1994 | ? gs_bulk_highspeed_function |
2009 | gs_bulk_fullspeed_function); | 1995 | : gs_bulk_fullspeed_function; |
2010 | } | 1996 | } |
2011 | 1997 | ||
2012 | /* for now, don't advertise srp-only devices */ | 1998 | /* for now, don't advertise srp-only devices */ |
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 3459ea6c6c0b..878e428a0ec1 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | 16 | ||
17 | #include <linux/usb/ch9.h> | 17 | #include <linux/usb/ch9.h> |
18 | #include <linux/usb_gadget.h> | 18 | #include <linux/usb/gadget.h> |
19 | 19 | ||
20 | #include <asm/unaligned.h> | 20 | #include <asm/unaligned.h> |
21 | 21 | ||
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index fcfe869acb94..fcde5d9c87df 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -1,38 +1,22 @@ | |||
1 | /* | 1 | /* |
2 | * zero.c -- Gadget Zero, for USB development | 2 | * zero.c -- Gadget Zero, for USB development |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2004 David Brownell | 4 | * Copyright (C) 2003-2007 David Brownell |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * modification, are permitted provided that the following conditions | 8 | * it under the terms of the GNU General Public License as published by |
9 | * are met: | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * (at your option) any later version. |
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 | * | 11 | * |
20 | * ALTERNATIVELY, this software may be distributed under the terms of the | 12 | * This program is distributed in the hope that it will be useful, |
21 | * GNU General Public License ("GPL") as published by the Free Software | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | * Foundation, either version 2 of that License or (at your option) any | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | * later version. | 15 | * GNU General Public License for more details. |
24 | * | 16 | * |
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | 17 | * You should have received a copy of the GNU General Public License |
26 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 18 | * along with this program; if not, write to the Free Software |
27 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
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 | */ | 20 | */ |
37 | 21 | ||
38 | 22 | ||
@@ -57,40 +41,28 @@ | |||
57 | * Many drivers will only have one configuration, letting them be much | 41 | * Many drivers will only have one configuration, letting them be much |
58 | * simpler if they also don't support high speed operation (like this | 42 | * simpler if they also don't support high speed operation (like this |
59 | * driver does). | 43 | * driver does). |
44 | * | ||
45 | * Why is *this* driver using two configurations, rather than setting up | ||
46 | * two interfaces with different functions? To help verify that multiple | ||
47 | * configuration infrastucture is working correctly; also, so that it can | ||
48 | * work with low capability USB controllers without four bulk endpoints. | ||
60 | */ | 49 | */ |
61 | 50 | ||
62 | #define DEBUG 1 | 51 | /* #define VERBOSE_DEBUG */ |
63 | // #define VERBOSE | ||
64 | 52 | ||
65 | #include <linux/module.h> | ||
66 | #include <linux/kernel.h> | 53 | #include <linux/kernel.h> |
67 | #include <linux/delay.h> | ||
68 | #include <linux/ioport.h> | ||
69 | #include <linux/slab.h> | ||
70 | #include <linux/errno.h> | ||
71 | #include <linux/init.h> | ||
72 | #include <linux/timer.h> | ||
73 | #include <linux/list.h> | ||
74 | #include <linux/interrupt.h> | ||
75 | #include <linux/utsname.h> | 54 | #include <linux/utsname.h> |
76 | #include <linux/device.h> | 55 | #include <linux/device.h> |
77 | #include <linux/moduleparam.h> | ||
78 | |||
79 | #include <asm/byteorder.h> | ||
80 | #include <asm/io.h> | ||
81 | #include <asm/irq.h> | ||
82 | #include <asm/system.h> | ||
83 | #include <asm/unaligned.h> | ||
84 | 56 | ||
85 | #include <linux/usb/ch9.h> | 57 | #include <linux/usb/ch9.h> |
86 | #include <linux/usb_gadget.h> | 58 | #include <linux/usb/gadget.h> |
87 | 59 | ||
88 | #include "gadget_chips.h" | 60 | #include "gadget_chips.h" |
89 | 61 | ||
90 | 62 | ||
91 | /*-------------------------------------------------------------------------*/ | 63 | /*-------------------------------------------------------------------------*/ |
92 | 64 | ||
93 | #define DRIVER_VERSION "St Patrick's Day 2004" | 65 | #define DRIVER_VERSION "Lughnasadh, 2007" |
94 | 66 | ||
95 | static const char shortname [] = "zero"; | 67 | static const char shortname [] = "zero"; |
96 | static const char longname [] = "Gadget Zero"; | 68 | static const char longname [] = "Gadget Zero"; |
@@ -131,30 +103,16 @@ struct zero_dev { | |||
131 | struct timer_list resume; | 103 | struct timer_list resume; |
132 | }; | 104 | }; |
133 | 105 | ||
134 | #define xprintk(d,level,fmt,args...) \ | 106 | #define DBG(d, fmt, args...) \ |
135 | dev_printk(level , &(d)->gadget->dev , fmt , ## args) | 107 | dev_dbg(&(d)->gadget->dev , fmt , ## args) |
136 | 108 | #define VDBG(d, fmt, args...) \ | |
137 | #ifdef DEBUG | 109 | dev_vdbg(&(d)->gadget->dev , fmt , ## args) |
138 | #define DBG(dev,fmt,args...) \ | 110 | #define ERROR(d, fmt, args...) \ |
139 | xprintk(dev , KERN_DEBUG , fmt , ## args) | 111 | dev_err(&(d)->gadget->dev , fmt , ## args) |
140 | #else | 112 | #define WARN(d, fmt, args...) \ |
141 | #define DBG(dev,fmt,args...) \ | 113 | dev_warn(&(d)->gadget->dev , fmt , ## args) |
142 | do { } while (0) | 114 | #define INFO(d, fmt, args...) \ |
143 | #endif /* DEBUG */ | 115 | dev_info(&(d)->gadget->dev , fmt , ## args) |
144 | |||
145 | #ifdef VERBOSE | ||
146 | #define VDBG DBG | ||
147 | #else | ||
148 | #define VDBG(dev,fmt,args...) \ | ||
149 | do { } while (0) | ||
150 | #endif /* VERBOSE */ | ||
151 | |||
152 | #define ERROR(dev,fmt,args...) \ | ||
153 | xprintk(dev , KERN_ERR , fmt , ## args) | ||
154 | #define WARN(dev,fmt,args...) \ | ||
155 | xprintk(dev , KERN_WARNING , fmt , ## args) | ||
156 | #define INFO(dev,fmt,args...) \ | ||
157 | xprintk(dev , KERN_INFO , fmt , ## args) | ||
158 | 116 | ||
159 | /*-------------------------------------------------------------------------*/ | 117 | /*-------------------------------------------------------------------------*/ |
160 | 118 | ||
@@ -326,8 +284,6 @@ static const struct usb_descriptor_header *fs_loopback_function [] = { | |||
326 | NULL, | 284 | NULL, |
327 | }; | 285 | }; |
328 | 286 | ||
329 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
330 | |||
331 | /* | 287 | /* |
332 | * usb 2.0 devices need to expose both high speed and full speed | 288 | * usb 2.0 devices need to expose both high speed and full speed |
333 | * descriptors, unless they only run at full speed. | 289 | * descriptors, unless they only run at full speed. |
@@ -383,17 +339,20 @@ static const struct usb_descriptor_header *hs_loopback_function [] = { | |||
383 | }; | 339 | }; |
384 | 340 | ||
385 | /* maxpacket and other transfer characteristics vary by speed. */ | 341 | /* maxpacket and other transfer characteristics vary by speed. */ |
386 | #define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs)) | 342 | static inline struct usb_endpoint_descriptor * |
387 | 343 | ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, | |
388 | #else | 344 | struct usb_endpoint_descriptor *fs) |
345 | { | ||
346 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
347 | return hs; | ||
348 | return fs; | ||
349 | } | ||
389 | 350 | ||
390 | /* if there's no high speed support, maxpacket doesn't change. */ | 351 | static char manufacturer[50]; |
391 | #define ep_desc(g,hs,fs) fs | ||
392 | 352 | ||
393 | #endif /* !CONFIG_USB_GADGET_DUALSPEED */ | 353 | /* default serial number takes at least two packets */ |
354 | static char serial[] = "0123456789.0123456789.0123456789"; | ||
394 | 355 | ||
395 | static char manufacturer [50]; | ||
396 | static char serial [40]; | ||
397 | 356 | ||
398 | /* static strings, in UTF-8 */ | 357 | /* static strings, in UTF-8 */ |
399 | static struct usb_string strings [] = { | 358 | static struct usb_string strings [] = { |
@@ -435,30 +394,29 @@ config_buf (struct usb_gadget *gadget, | |||
435 | int is_source_sink; | 394 | int is_source_sink; |
436 | int len; | 395 | int len; |
437 | const struct usb_descriptor_header **function; | 396 | const struct usb_descriptor_header **function; |
438 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 397 | int hs = 0; |
439 | int hs = (gadget->speed == USB_SPEED_HIGH); | ||
440 | #endif | ||
441 | 398 | ||
442 | /* two configurations will always be index 0 and index 1 */ | 399 | /* two configurations will always be index 0 and index 1 */ |
443 | if (index > 1) | 400 | if (index > 1) |
444 | return -EINVAL; | 401 | return -EINVAL; |
445 | is_source_sink = loopdefault ? (index == 1) : (index == 0); | 402 | is_source_sink = loopdefault ? (index == 1) : (index == 0); |
446 | 403 | ||
447 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 404 | if (gadget_is_dualspeed(gadget)) { |
448 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 405 | hs = (gadget->speed == USB_SPEED_HIGH); |
449 | hs = !hs; | 406 | if (type == USB_DT_OTHER_SPEED_CONFIG) |
407 | hs = !hs; | ||
408 | } | ||
450 | if (hs) | 409 | if (hs) |
451 | function = is_source_sink | 410 | function = is_source_sink |
452 | ? hs_source_sink_function | 411 | ? hs_source_sink_function |
453 | : hs_loopback_function; | 412 | : hs_loopback_function; |
454 | else | 413 | else |
455 | #endif | ||
456 | function = is_source_sink | 414 | function = is_source_sink |
457 | ? fs_source_sink_function | 415 | ? fs_source_sink_function |
458 | : fs_loopback_function; | 416 | : fs_loopback_function; |
459 | 417 | ||
460 | /* for now, don't advertise srp-only devices */ | 418 | /* for now, don't advertise srp-only devices */ |
461 | if (!gadget->is_otg) | 419 | if (!gadget_is_otg(gadget)) |
462 | function++; | 420 | function++; |
463 | 421 | ||
464 | len = usb_gadget_config_buf (is_source_sink | 422 | len = usb_gadget_config_buf (is_source_sink |
@@ -498,6 +456,19 @@ static void free_ep_req (struct usb_ep *ep, struct usb_request *req) | |||
498 | 456 | ||
499 | /*-------------------------------------------------------------------------*/ | 457 | /*-------------------------------------------------------------------------*/ |
500 | 458 | ||
459 | /* | ||
460 | * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripherals, | ||
461 | * this just sinks bulk packets OUT to the peripheral and sources them IN | ||
462 | * to the host, optionally with specific data patterns. | ||
463 | * | ||
464 | * In terms of control messaging, this supports all the standard requests | ||
465 | * plus two that support control-OUT tests. | ||
466 | * | ||
467 | * Note that because this doesn't queue more than one request at a time, | ||
468 | * some other function must be used to test queueing logic. The network | ||
469 | * link (g_ether) is probably the best option for that. | ||
470 | */ | ||
471 | |||
501 | /* optionally require specific source/sink data patterns */ | 472 | /* optionally require specific source/sink data patterns */ |
502 | 473 | ||
503 | static int | 474 | static int |
@@ -534,12 +505,7 @@ check_read_data ( | |||
534 | return 0; | 505 | return 0; |
535 | } | 506 | } |
536 | 507 | ||
537 | static void | 508 | static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) |
538 | reinit_write_data ( | ||
539 | struct zero_dev *dev, | ||
540 | struct usb_ep *ep, | ||
541 | struct usb_request *req | ||
542 | ) | ||
543 | { | 509 | { |
544 | unsigned i; | 510 | unsigned i; |
545 | u8 *buf = req->buf; | 511 | u8 *buf = req->buf; |
@@ -566,16 +532,16 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | |||
566 | 532 | ||
567 | switch (status) { | 533 | switch (status) { |
568 | 534 | ||
569 | case 0: /* normal completion? */ | 535 | case 0: /* normal completion? */ |
570 | if (ep == dev->out_ep) { | 536 | if (ep == dev->out_ep) { |
571 | check_read_data (dev, ep, req); | 537 | check_read_data (dev, ep, req); |
572 | memset (req->buf, 0x55, req->length); | 538 | memset (req->buf, 0x55, req->length); |
573 | } else | 539 | } else |
574 | reinit_write_data (dev, ep, req); | 540 | reinit_write_data(ep, req); |
575 | break; | 541 | break; |
576 | 542 | ||
577 | /* this endpoint is normally active while we're configured */ | 543 | /* this endpoint is normally active while we're configured */ |
578 | case -ECONNABORTED: /* hardware forced ep reset */ | 544 | case -ECONNABORTED: /* hardware forced ep reset */ |
579 | case -ECONNRESET: /* request dequeued */ | 545 | case -ECONNRESET: /* request dequeued */ |
580 | case -ESHUTDOWN: /* disconnect from host */ | 546 | case -ESHUTDOWN: /* disconnect from host */ |
581 | VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status, | 547 | VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status, |
@@ -607,8 +573,7 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | |||
607 | } | 573 | } |
608 | } | 574 | } |
609 | 575 | ||
610 | static struct usb_request * | 576 | static struct usb_request *source_sink_start_ep(struct usb_ep *ep) |
611 | source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) | ||
612 | { | 577 | { |
613 | struct usb_request *req; | 578 | struct usb_request *req; |
614 | int status; | 579 | int status; |
@@ -621,11 +586,11 @@ source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) | |||
621 | req->complete = source_sink_complete; | 586 | req->complete = source_sink_complete; |
622 | 587 | ||
623 | if (strcmp (ep->name, EP_IN_NAME) == 0) | 588 | if (strcmp (ep->name, EP_IN_NAME) == 0) |
624 | reinit_write_data (ep->driver_data, ep, req); | 589 | reinit_write_data(ep, req); |
625 | else | 590 | else |
626 | memset (req->buf, 0x55, req->length); | 591 | memset (req->buf, 0x55, req->length); |
627 | 592 | ||
628 | status = usb_ep_queue (ep, req, gfp_flags); | 593 | status = usb_ep_queue(ep, req, GFP_ATOMIC); |
629 | if (status) { | 594 | if (status) { |
630 | struct zero_dev *dev = ep->driver_data; | 595 | struct zero_dev *dev = ep->driver_data; |
631 | 596 | ||
@@ -637,8 +602,7 @@ source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) | |||
637 | return req; | 602 | return req; |
638 | } | 603 | } |
639 | 604 | ||
640 | static int | 605 | static int set_source_sink_config(struct zero_dev *dev) |
641 | set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) | ||
642 | { | 606 | { |
643 | int result = 0; | 607 | int result = 0; |
644 | struct usb_ep *ep; | 608 | struct usb_ep *ep; |
@@ -653,8 +617,7 @@ set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) | |||
653 | result = usb_ep_enable (ep, d); | 617 | result = usb_ep_enable (ep, d); |
654 | if (result == 0) { | 618 | if (result == 0) { |
655 | ep->driver_data = dev; | 619 | ep->driver_data = dev; |
656 | if (source_sink_start_ep(ep, gfp_flags) | 620 | if (source_sink_start_ep(ep) != NULL) { |
657 | != NULL) { | ||
658 | dev->in_ep = ep; | 621 | dev->in_ep = ep; |
659 | continue; | 622 | continue; |
660 | } | 623 | } |
@@ -668,8 +631,7 @@ set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) | |||
668 | result = usb_ep_enable (ep, d); | 631 | result = usb_ep_enable (ep, d); |
669 | if (result == 0) { | 632 | if (result == 0) { |
670 | ep->driver_data = dev; | 633 | ep->driver_data = dev; |
671 | if (source_sink_start_ep(ep, gfp_flags) | 634 | if (source_sink_start_ep(ep) != NULL) { |
672 | != NULL) { | ||
673 | dev->out_ep = ep; | 635 | dev->out_ep = ep; |
674 | continue; | 636 | continue; |
675 | } | 637 | } |
@@ -701,7 +663,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
701 | 663 | ||
702 | switch (status) { | 664 | switch (status) { |
703 | 665 | ||
704 | case 0: /* normal completion? */ | 666 | case 0: /* normal completion? */ |
705 | if (ep == dev->out_ep) { | 667 | if (ep == dev->out_ep) { |
706 | /* loop this OUT packet back IN to the host */ | 668 | /* loop this OUT packet back IN to the host */ |
707 | req->zero = (req->actual < req->length); | 669 | req->zero = (req->actual < req->length); |
@@ -735,7 +697,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
735 | * rely on the hardware driver to clean up on disconnect or | 697 | * rely on the hardware driver to clean up on disconnect or |
736 | * endpoint disable. | 698 | * endpoint disable. |
737 | */ | 699 | */ |
738 | case -ECONNABORTED: /* hardware forced ep reset */ | 700 | case -ECONNABORTED: /* hardware forced ep reset */ |
739 | case -ECONNRESET: /* request dequeued */ | 701 | case -ECONNRESET: /* request dequeued */ |
740 | case -ESHUTDOWN: /* disconnect from host */ | 702 | case -ESHUTDOWN: /* disconnect from host */ |
741 | free_ep_req (ep, req); | 703 | free_ep_req (ep, req); |
@@ -743,8 +705,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
743 | } | 705 | } |
744 | } | 706 | } |
745 | 707 | ||
746 | static int | 708 | static int set_loopback_config(struct zero_dev *dev) |
747 | set_loopback_config (struct zero_dev *dev, gfp_t gfp_flags) | ||
748 | { | 709 | { |
749 | int result = 0; | 710 | int result = 0; |
750 | struct usb_ep *ep; | 711 | struct usb_ep *ep; |
@@ -844,8 +805,7 @@ static void zero_reset_config (struct zero_dev *dev) | |||
844 | * code can do, perhaps by disallowing more than one configuration or | 805 | * code can do, perhaps by disallowing more than one configuration or |
845 | * by limiting configuration choices (like the pxa2xx). | 806 | * by limiting configuration choices (like the pxa2xx). |
846 | */ | 807 | */ |
847 | static int | 808 | static int zero_set_config(struct zero_dev *dev, unsigned number) |
848 | zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags) | ||
849 | { | 809 | { |
850 | int result = 0; | 810 | int result = 0; |
851 | struct usb_gadget *gadget = dev->gadget; | 811 | struct usb_gadget *gadget = dev->gadget; |
@@ -855,17 +815,17 @@ zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags) | |||
855 | 815 | ||
856 | if (gadget_is_sa1100 (gadget) && dev->config) { | 816 | if (gadget_is_sa1100 (gadget) && dev->config) { |
857 | /* tx fifo is full, but we can't clear it...*/ | 817 | /* tx fifo is full, but we can't clear it...*/ |
858 | INFO (dev, "can't change configurations\n"); | 818 | ERROR(dev, "can't change configurations\n"); |
859 | return -ESPIPE; | 819 | return -ESPIPE; |
860 | } | 820 | } |
861 | zero_reset_config (dev); | 821 | zero_reset_config (dev); |
862 | 822 | ||
863 | switch (number) { | 823 | switch (number) { |
864 | case CONFIG_SOURCE_SINK: | 824 | case CONFIG_SOURCE_SINK: |
865 | result = set_source_sink_config (dev, gfp_flags); | 825 | result = set_source_sink_config(dev); |
866 | break; | 826 | break; |
867 | case CONFIG_LOOPBACK: | 827 | case CONFIG_LOOPBACK: |
868 | result = set_loopback_config (dev, gfp_flags); | 828 | result = set_loopback_config(dev); |
869 | break; | 829 | break; |
870 | default: | 830 | default: |
871 | result = -EINVAL; | 831 | result = -EINVAL; |
@@ -885,7 +845,7 @@ zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags) | |||
885 | case USB_SPEED_LOW: speed = "low"; break; | 845 | case USB_SPEED_LOW: speed = "low"; break; |
886 | case USB_SPEED_FULL: speed = "full"; break; | 846 | case USB_SPEED_FULL: speed = "full"; break; |
887 | case USB_SPEED_HIGH: speed = "high"; break; | 847 | case USB_SPEED_HIGH: speed = "high"; break; |
888 | default: speed = "?"; break; | 848 | default: speed = "?"; break; |
889 | } | 849 | } |
890 | 850 | ||
891 | dev->config = number; | 851 | dev->config = number; |
@@ -938,19 +898,17 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
938 | value = min (w_length, (u16) sizeof device_desc); | 898 | value = min (w_length, (u16) sizeof device_desc); |
939 | memcpy (req->buf, &device_desc, value); | 899 | memcpy (req->buf, &device_desc, value); |
940 | break; | 900 | break; |
941 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
942 | case USB_DT_DEVICE_QUALIFIER: | 901 | case USB_DT_DEVICE_QUALIFIER: |
943 | if (!gadget->is_dualspeed) | 902 | if (!gadget_is_dualspeed(gadget)) |
944 | break; | 903 | break; |
945 | value = min (w_length, (u16) sizeof dev_qualifier); | 904 | value = min (w_length, (u16) sizeof dev_qualifier); |
946 | memcpy (req->buf, &dev_qualifier, value); | 905 | memcpy (req->buf, &dev_qualifier, value); |
947 | break; | 906 | break; |
948 | 907 | ||
949 | case USB_DT_OTHER_SPEED_CONFIG: | 908 | case USB_DT_OTHER_SPEED_CONFIG: |
950 | if (!gadget->is_dualspeed) | 909 | if (!gadget_is_dualspeed(gadget)) |
951 | break; | 910 | break; |
952 | // FALLTHROUGH | 911 | // FALLTHROUGH |
953 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
954 | case USB_DT_CONFIG: | 912 | case USB_DT_CONFIG: |
955 | value = config_buf (gadget, req->buf, | 913 | value = config_buf (gadget, req->buf, |
956 | w_value >> 8, | 914 | w_value >> 8, |
@@ -984,7 +942,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
984 | else | 942 | else |
985 | VDBG (dev, "HNP inactive\n"); | 943 | VDBG (dev, "HNP inactive\n"); |
986 | spin_lock (&dev->lock); | 944 | spin_lock (&dev->lock); |
987 | value = zero_set_config (dev, w_value, GFP_ATOMIC); | 945 | value = zero_set_config(dev, w_value); |
988 | spin_unlock (&dev->lock); | 946 | spin_unlock (&dev->lock); |
989 | break; | 947 | break; |
990 | case USB_REQ_GET_CONFIGURATION: | 948 | case USB_REQ_GET_CONFIGURATION: |
@@ -1013,7 +971,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1013 | * use this "reset the config" shortcut. | 971 | * use this "reset the config" shortcut. |
1014 | */ | 972 | */ |
1015 | zero_reset_config (dev); | 973 | zero_reset_config (dev); |
1016 | zero_set_config (dev, config, GFP_ATOMIC); | 974 | zero_set_config(dev, config); |
1017 | value = 0; | 975 | value = 0; |
1018 | } | 976 | } |
1019 | spin_unlock (&dev->lock); | 977 | spin_unlock (&dev->lock); |
@@ -1163,7 +1121,7 @@ autoconf_fail: | |||
1163 | } | 1121 | } |
1164 | EP_IN_NAME = ep->name; | 1122 | EP_IN_NAME = ep->name; |
1165 | ep->driver_data = ep; /* claim */ | 1123 | ep->driver_data = ep; /* claim */ |
1166 | 1124 | ||
1167 | ep = usb_ep_autoconfig (gadget, &fs_sink_desc); | 1125 | ep = usb_ep_autoconfig (gadget, &fs_sink_desc); |
1168 | if (!ep) | 1126 | if (!ep) |
1169 | goto autoconf_fail; | 1127 | goto autoconf_fail; |
@@ -1207,16 +1165,18 @@ autoconf_fail: | |||
1207 | 1165 | ||
1208 | device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | 1166 | device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; |
1209 | 1167 | ||
1210 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1168 | if (gadget_is_dualspeed(gadget)) { |
1211 | /* assume ep0 uses the same value for both speeds ... */ | 1169 | /* assume ep0 uses the same value for both speeds ... */ |
1212 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; | 1170 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; |
1213 | 1171 | ||
1214 | /* and that all endpoints are dual-speed */ | 1172 | /* and that all endpoints are dual-speed */ |
1215 | hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; | 1173 | hs_source_desc.bEndpointAddress = |
1216 | hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; | 1174 | fs_source_desc.bEndpointAddress; |
1217 | #endif | 1175 | hs_sink_desc.bEndpointAddress = |
1176 | fs_sink_desc.bEndpointAddress; | ||
1177 | } | ||
1218 | 1178 | ||
1219 | if (gadget->is_otg) { | 1179 | if (gadget_is_otg(gadget)) { |
1220 | otg_descriptor.bmAttributes |= USB_OTG_HNP, | 1180 | otg_descriptor.bmAttributes |= USB_OTG_HNP, |
1221 | source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1181 | source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
1222 | loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1182 | loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
@@ -1294,23 +1254,18 @@ static struct usb_gadget_driver zero_driver = { | |||
1294 | .suspend = zero_suspend, | 1254 | .suspend = zero_suspend, |
1295 | .resume = zero_resume, | 1255 | .resume = zero_resume, |
1296 | 1256 | ||
1297 | .driver = { | 1257 | .driver = { |
1298 | .name = (char *) shortname, | 1258 | .name = (char *) shortname, |
1299 | .owner = THIS_MODULE, | 1259 | .owner = THIS_MODULE, |
1300 | }, | 1260 | }, |
1301 | }; | 1261 | }; |
1302 | 1262 | ||
1303 | MODULE_AUTHOR ("David Brownell"); | 1263 | MODULE_AUTHOR("David Brownell"); |
1304 | MODULE_LICENSE ("Dual BSD/GPL"); | 1264 | MODULE_LICENSE("GPL"); |
1305 | 1265 | ||
1306 | 1266 | ||
1307 | static int __init init (void) | 1267 | static int __init init (void) |
1308 | { | 1268 | { |
1309 | /* a real value would likely come through some id prom | ||
1310 | * or module option. this one takes at least two packets. | ||
1311 | */ | ||
1312 | strlcpy (serial, "0123456789.0123456789.0123456789", sizeof serial); | ||
1313 | |||
1314 | return usb_gadget_register_driver (&zero_driver); | 1269 | return usb_gadget_register_driver (&zero_driver); |
1315 | } | 1270 | } |
1316 | module_init (init); | 1271 | module_init (init); |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 565d6ef4c4cf..c978d622fa8a 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -154,6 +154,19 @@ config USB_OHCI_HCD_PCI | |||
154 | Enables support for PCI-bus plug-in USB controller cards. | 154 | Enables support for PCI-bus plug-in USB controller cards. |
155 | If unsure, say Y. | 155 | If unsure, say Y. |
156 | 156 | ||
157 | config USB_OHCI_HCD_SSB | ||
158 | bool "OHCI support for Broadcom SSB OHCI core" | ||
159 | depends on USB_OHCI_HCD && SSB && EXPERIMENTAL | ||
160 | default n | ||
161 | ---help--- | ||
162 | Support for the Sonics Silicon Backplane (SSB) attached | ||
163 | Broadcom USB OHCI core. | ||
164 | |||
165 | This device is present in some embedded devices with | ||
166 | Broadcom based SSB bus. | ||
167 | |||
168 | If unsure, say N. | ||
169 | |||
157 | config USB_OHCI_BIG_ENDIAN_DESC | 170 | config USB_OHCI_BIG_ENDIAN_DESC |
158 | bool | 171 | bool |
159 | depends on USB_OHCI_HCD | 172 | depends on USB_OHCI_HCD |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index b1d19268cb23..766ef68a0b43 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -220,10 +220,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { | |||
220 | */ | 220 | */ |
221 | .hub_status_data = ehci_hub_status_data, | 221 | .hub_status_data = ehci_hub_status_data, |
222 | .hub_control = ehci_hub_control, | 222 | .hub_control = ehci_hub_control, |
223 | #ifdef CONFIG_PM | 223 | .bus_suspend = ehci_bus_suspend, |
224 | .hub_suspend = ehci_hub_suspend, | 224 | .bus_resume = ehci_bus_resume, |
225 | .hub_resume = ehci_hub_resume, | ||
226 | #endif | ||
227 | }; | 225 | }; |
228 | 226 | ||
229 | /*-------------------------------------------------------------------------*/ | 227 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 35cdba10411b..c1514442883e 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -570,10 +570,18 @@ static int ehci_run (struct usb_hcd *hcd) | |||
570 | * are explicitly handed to companion controller(s), so no TT is | 570 | * are explicitly handed to companion controller(s), so no TT is |
571 | * involved with the root hub. (Except where one is integrated, | 571 | * involved with the root hub. (Except where one is integrated, |
572 | * and there's no companion controller unless maybe for USB OTG.) | 572 | * and there's no companion controller unless maybe for USB OTG.) |
573 | * | ||
574 | * Turning on the CF flag will transfer ownership of all ports | ||
575 | * from the companions to the EHCI controller. If any of the | ||
576 | * companions are in the middle of a port reset at the time, it | ||
577 | * could cause trouble. Write-locking ehci_cf_port_reset_rwsem | ||
578 | * guarantees that no resets are in progress. | ||
573 | */ | 579 | */ |
580 | down_write(&ehci_cf_port_reset_rwsem); | ||
574 | hcd->state = HC_STATE_RUNNING; | 581 | hcd->state = HC_STATE_RUNNING; |
575 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); | 582 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
576 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ | 583 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
584 | up_write(&ehci_cf_port_reset_rwsem); | ||
577 | 585 | ||
578 | temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); | 586 | temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
579 | ehci_info (ehci, | 587 | ehci_info (ehci, |
@@ -719,7 +727,6 @@ dead: | |||
719 | */ | 727 | */ |
720 | static int ehci_urb_enqueue ( | 728 | static int ehci_urb_enqueue ( |
721 | struct usb_hcd *hcd, | 729 | struct usb_hcd *hcd, |
722 | struct usb_host_endpoint *ep, | ||
723 | struct urb *urb, | 730 | struct urb *urb, |
724 | gfp_t mem_flags | 731 | gfp_t mem_flags |
725 | ) { | 732 | ) { |
@@ -734,12 +741,12 @@ static int ehci_urb_enqueue ( | |||
734 | default: | 741 | default: |
735 | if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) | 742 | if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) |
736 | return -ENOMEM; | 743 | return -ENOMEM; |
737 | return submit_async (ehci, ep, urb, &qtd_list, mem_flags); | 744 | return submit_async(ehci, urb, &qtd_list, mem_flags); |
738 | 745 | ||
739 | case PIPE_INTERRUPT: | 746 | case PIPE_INTERRUPT: |
740 | if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) | 747 | if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) |
741 | return -ENOMEM; | 748 | return -ENOMEM; |
742 | return intr_submit (ehci, ep, urb, &qtd_list, mem_flags); | 749 | return intr_submit(ehci, urb, &qtd_list, mem_flags); |
743 | 750 | ||
744 | case PIPE_ISOCHRONOUS: | 751 | case PIPE_ISOCHRONOUS: |
745 | if (urb->dev->speed == USB_SPEED_HIGH) | 752 | if (urb->dev->speed == USB_SPEED_HIGH) |
@@ -777,13 +784,18 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
777 | * completions normally happen asynchronously | 784 | * completions normally happen asynchronously |
778 | */ | 785 | */ |
779 | 786 | ||
780 | static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 787 | static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
781 | { | 788 | { |
782 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 789 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
783 | struct ehci_qh *qh; | 790 | struct ehci_qh *qh; |
784 | unsigned long flags; | 791 | unsigned long flags; |
792 | int rc; | ||
785 | 793 | ||
786 | spin_lock_irqsave (&ehci->lock, flags); | 794 | spin_lock_irqsave (&ehci->lock, flags); |
795 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
796 | if (rc) | ||
797 | goto done; | ||
798 | |||
787 | switch (usb_pipetype (urb->pipe)) { | 799 | switch (usb_pipetype (urb->pipe)) { |
788 | // case PIPE_CONTROL: | 800 | // case PIPE_CONTROL: |
789 | // case PIPE_BULK: | 801 | // case PIPE_BULK: |
@@ -838,7 +850,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | |||
838 | } | 850 | } |
839 | done: | 851 | done: |
840 | spin_unlock_irqrestore (&ehci->lock, flags); | 852 | spin_unlock_irqrestore (&ehci->lock, flags); |
841 | return 0; | 853 | return rc; |
842 | } | 854 | } |
843 | 855 | ||
844 | /*-------------------------------------------------------------------------*/ | 856 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index a7816e392a85..ad0d4965f2fb 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -58,8 +58,6 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | |||
58 | if (!retval) | 58 | if (!retval) |
59 | ehci_dbg(ehci, "MWI active\n"); | 59 | ehci_dbg(ehci, "MWI active\n"); |
60 | 60 | ||
61 | ehci_port_power(ehci, 0); | ||
62 | |||
63 | return 0; | 61 | return 0; |
64 | } | 62 | } |
65 | 63 | ||
@@ -156,8 +154,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
156 | break; | 154 | break; |
157 | } | 155 | } |
158 | 156 | ||
159 | if (ehci_is_TDI(ehci)) | 157 | ehci_reset(ehci); |
160 | ehci_reset(ehci); | ||
161 | 158 | ||
162 | /* at least the Genesys GL880S needs fixup here */ | 159 | /* at least the Genesys GL880S needs fixup here */ |
163 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); | 160 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); |
diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index 4f99b0eb27bc..452d4b1bc859 100644 --- a/drivers/usb/host/ehci-ppc-soc.c +++ b/drivers/usb/host/ehci-ppc-soc.c | |||
@@ -160,10 +160,8 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { | |||
160 | */ | 160 | */ |
161 | .hub_status_data = ehci_hub_status_data, | 161 | .hub_status_data = ehci_hub_status_data, |
162 | .hub_control = ehci_hub_control, | 162 | .hub_control = ehci_hub_control, |
163 | #ifdef CONFIG_PM | 163 | .bus_suspend = ehci_bus_suspend, |
164 | .hub_suspend = ehci_hub_suspend, | 164 | .bus_resume = ehci_bus_resume, |
165 | .hub_resume = ehci_hub_resume, | ||
166 | #endif | ||
167 | }; | 165 | }; |
168 | 166 | ||
169 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) | 167 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 829fe649a981..03a6b2f4e6ed 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -47,7 +47,7 @@ static int ps3_ehci_hc_reset(struct usb_hcd *hcd) | |||
47 | if (result) | 47 | if (result) |
48 | return result; | 48 | return result; |
49 | 49 | ||
50 | ehci_port_power(ehci, 0); | 50 | ehci_reset(ehci); |
51 | 51 | ||
52 | return result; | 52 | return result; |
53 | } | 53 | } |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 140bfa423e07..b10f39c047e9 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -139,63 +139,65 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
139 | 139 | ||
140 | /*-------------------------------------------------------------------------*/ | 140 | /*-------------------------------------------------------------------------*/ |
141 | 141 | ||
142 | static void qtd_copy_status ( | 142 | static int qtd_copy_status ( |
143 | struct ehci_hcd *ehci, | 143 | struct ehci_hcd *ehci, |
144 | struct urb *urb, | 144 | struct urb *urb, |
145 | size_t length, | 145 | size_t length, |
146 | u32 token | 146 | u32 token |
147 | ) | 147 | ) |
148 | { | 148 | { |
149 | int status = -EINPROGRESS; | ||
150 | |||
149 | /* count IN/OUT bytes, not SETUP (even short packets) */ | 151 | /* count IN/OUT bytes, not SETUP (even short packets) */ |
150 | if (likely (QTD_PID (token) != 2)) | 152 | if (likely (QTD_PID (token) != 2)) |
151 | urb->actual_length += length - QTD_LENGTH (token); | 153 | urb->actual_length += length - QTD_LENGTH (token); |
152 | 154 | ||
153 | /* don't modify error codes */ | 155 | /* don't modify error codes */ |
154 | if (unlikely (urb->status != -EINPROGRESS)) | 156 | if (unlikely(urb->unlinked)) |
155 | return; | 157 | return status; |
156 | 158 | ||
157 | /* force cleanup after short read; not always an error */ | 159 | /* force cleanup after short read; not always an error */ |
158 | if (unlikely (IS_SHORT_READ (token))) | 160 | if (unlikely (IS_SHORT_READ (token))) |
159 | urb->status = -EREMOTEIO; | 161 | status = -EREMOTEIO; |
160 | 162 | ||
161 | /* serious "can't proceed" faults reported by the hardware */ | 163 | /* serious "can't proceed" faults reported by the hardware */ |
162 | if (token & QTD_STS_HALT) { | 164 | if (token & QTD_STS_HALT) { |
163 | if (token & QTD_STS_BABBLE) { | 165 | if (token & QTD_STS_BABBLE) { |
164 | /* FIXME "must" disable babbling device's port too */ | 166 | /* FIXME "must" disable babbling device's port too */ |
165 | urb->status = -EOVERFLOW; | 167 | status = -EOVERFLOW; |
166 | } else if (token & QTD_STS_MMF) { | 168 | } else if (token & QTD_STS_MMF) { |
167 | /* fs/ls interrupt xfer missed the complete-split */ | 169 | /* fs/ls interrupt xfer missed the complete-split */ |
168 | urb->status = -EPROTO; | 170 | status = -EPROTO; |
169 | } else if (token & QTD_STS_DBE) { | 171 | } else if (token & QTD_STS_DBE) { |
170 | urb->status = (QTD_PID (token) == 1) /* IN ? */ | 172 | status = (QTD_PID (token) == 1) /* IN ? */ |
171 | ? -ENOSR /* hc couldn't read data */ | 173 | ? -ENOSR /* hc couldn't read data */ |
172 | : -ECOMM; /* hc couldn't write data */ | 174 | : -ECOMM; /* hc couldn't write data */ |
173 | } else if (token & QTD_STS_XACT) { | 175 | } else if (token & QTD_STS_XACT) { |
174 | /* timeout, bad crc, wrong PID, etc; retried */ | 176 | /* timeout, bad crc, wrong PID, etc; retried */ |
175 | if (QTD_CERR (token)) | 177 | if (QTD_CERR (token)) |
176 | urb->status = -EPIPE; | 178 | status = -EPIPE; |
177 | else { | 179 | else { |
178 | ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n", | 180 | ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n", |
179 | urb->dev->devpath, | 181 | urb->dev->devpath, |
180 | usb_pipeendpoint (urb->pipe), | 182 | usb_pipeendpoint (urb->pipe), |
181 | usb_pipein (urb->pipe) ? "in" : "out"); | 183 | usb_pipein (urb->pipe) ? "in" : "out"); |
182 | urb->status = -EPROTO; | 184 | status = -EPROTO; |
183 | } | 185 | } |
184 | /* CERR nonzero + no errors + halt --> stall */ | 186 | /* CERR nonzero + no errors + halt --> stall */ |
185 | } else if (QTD_CERR (token)) | 187 | } else if (QTD_CERR (token)) |
186 | urb->status = -EPIPE; | 188 | status = -EPIPE; |
187 | else /* unknown */ | 189 | else /* unknown */ |
188 | urb->status = -EPROTO; | 190 | status = -EPROTO; |
189 | 191 | ||
190 | ehci_vdbg (ehci, | 192 | ehci_vdbg (ehci, |
191 | "dev%d ep%d%s qtd token %08x --> status %d\n", | 193 | "dev%d ep%d%s qtd token %08x --> status %d\n", |
192 | usb_pipedevice (urb->pipe), | 194 | usb_pipedevice (urb->pipe), |
193 | usb_pipeendpoint (urb->pipe), | 195 | usb_pipeendpoint (urb->pipe), |
194 | usb_pipein (urb->pipe) ? "in" : "out", | 196 | usb_pipein (urb->pipe) ? "in" : "out", |
195 | token, urb->status); | 197 | token, status); |
196 | 198 | ||
197 | /* if async CSPLIT failed, try cleaning out the TT buffer */ | 199 | /* if async CSPLIT failed, try cleaning out the TT buffer */ |
198 | if (urb->status != -EPIPE | 200 | if (status != -EPIPE |
199 | && urb->dev->tt && !usb_pipeint (urb->pipe) | 201 | && urb->dev->tt && !usb_pipeint (urb->pipe) |
200 | && ((token & QTD_STS_MMF) != 0 | 202 | && ((token & QTD_STS_MMF) != 0 |
201 | || QTD_CERR(token) == 0) | 203 | || QTD_CERR(token) == 0) |
@@ -212,10 +214,12 @@ static void qtd_copy_status ( | |||
212 | usb_hub_tt_clear_buffer (urb->dev, urb->pipe); | 214 | usb_hub_tt_clear_buffer (urb->dev, urb->pipe); |
213 | } | 215 | } |
214 | } | 216 | } |
217 | |||
218 | return status; | ||
215 | } | 219 | } |
216 | 220 | ||
217 | static void | 221 | static void |
218 | ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb) | 222 | ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status) |
219 | __releases(ehci->lock) | 223 | __releases(ehci->lock) |
220 | __acquires(ehci->lock) | 224 | __acquires(ehci->lock) |
221 | { | 225 | { |
@@ -231,25 +235,13 @@ __acquires(ehci->lock) | |||
231 | qh_put (qh); | 235 | qh_put (qh); |
232 | } | 236 | } |
233 | 237 | ||
234 | spin_lock (&urb->lock); | 238 | if (unlikely(urb->unlinked)) { |
235 | urb->hcpriv = NULL; | 239 | COUNT(ehci->stats.unlink); |
236 | switch (urb->status) { | 240 | } else { |
237 | case -EINPROGRESS: /* success */ | 241 | if (likely(status == -EINPROGRESS)) |
238 | urb->status = 0; | 242 | status = 0; |
239 | default: /* fault */ | 243 | COUNT(ehci->stats.complete); |
240 | COUNT (ehci->stats.complete); | ||
241 | break; | ||
242 | case -EREMOTEIO: /* fault or normal */ | ||
243 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) | ||
244 | urb->status = 0; | ||
245 | COUNT (ehci->stats.complete); | ||
246 | break; | ||
247 | case -ECONNRESET: /* canceled */ | ||
248 | case -ENOENT: | ||
249 | COUNT (ehci->stats.unlink); | ||
250 | break; | ||
251 | } | 244 | } |
252 | spin_unlock (&urb->lock); | ||
253 | 245 | ||
254 | #ifdef EHCI_URB_TRACE | 246 | #ifdef EHCI_URB_TRACE |
255 | ehci_dbg (ehci, | 247 | ehci_dbg (ehci, |
@@ -257,13 +249,14 @@ __acquires(ehci->lock) | |||
257 | __FUNCTION__, urb->dev->devpath, urb, | 249 | __FUNCTION__, urb->dev->devpath, urb, |
258 | usb_pipeendpoint (urb->pipe), | 250 | usb_pipeendpoint (urb->pipe), |
259 | usb_pipein (urb->pipe) ? "in" : "out", | 251 | usb_pipein (urb->pipe) ? "in" : "out", |
260 | urb->status, | 252 | status, |
261 | urb->actual_length, urb->transfer_buffer_length); | 253 | urb->actual_length, urb->transfer_buffer_length); |
262 | #endif | 254 | #endif |
263 | 255 | ||
264 | /* complete() can reenter this HCD */ | 256 | /* complete() can reenter this HCD */ |
257 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
265 | spin_unlock (&ehci->lock); | 258 | spin_unlock (&ehci->lock); |
266 | usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb); | 259 | usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status); |
267 | spin_lock (&ehci->lock); | 260 | spin_lock (&ehci->lock); |
268 | } | 261 | } |
269 | 262 | ||
@@ -283,6 +276,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
283 | { | 276 | { |
284 | struct ehci_qtd *last = NULL, *end = qh->dummy; | 277 | struct ehci_qtd *last = NULL, *end = qh->dummy; |
285 | struct list_head *entry, *tmp; | 278 | struct list_head *entry, *tmp; |
279 | int last_status = -EINPROGRESS; | ||
286 | int stopped; | 280 | int stopped; |
287 | unsigned count = 0; | 281 | unsigned count = 0; |
288 | int do_status = 0; | 282 | int do_status = 0; |
@@ -311,6 +305,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
311 | struct ehci_qtd *qtd; | 305 | struct ehci_qtd *qtd; |
312 | struct urb *urb; | 306 | struct urb *urb; |
313 | u32 token = 0; | 307 | u32 token = 0; |
308 | int qtd_status; | ||
314 | 309 | ||
315 | qtd = list_entry (entry, struct ehci_qtd, qtd_list); | 310 | qtd = list_entry (entry, struct ehci_qtd, qtd_list); |
316 | urb = qtd->urb; | 311 | urb = qtd->urb; |
@@ -318,11 +313,12 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
318 | /* clean up any state from previous QTD ...*/ | 313 | /* clean up any state from previous QTD ...*/ |
319 | if (last) { | 314 | if (last) { |
320 | if (likely (last->urb != urb)) { | 315 | if (likely (last->urb != urb)) { |
321 | ehci_urb_done (ehci, last->urb); | 316 | ehci_urb_done(ehci, last->urb, last_status); |
322 | count++; | 317 | count++; |
323 | } | 318 | } |
324 | ehci_qtd_free (ehci, last); | 319 | ehci_qtd_free (ehci, last); |
325 | last = NULL; | 320 | last = NULL; |
321 | last_status = -EINPROGRESS; | ||
326 | } | 322 | } |
327 | 323 | ||
328 | /* ignore urbs submitted during completions we reported */ | 324 | /* ignore urbs submitted during completions we reported */ |
@@ -358,13 +354,14 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
358 | stopped = 1; | 354 | stopped = 1; |
359 | 355 | ||
360 | if (unlikely (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) | 356 | if (unlikely (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) |
361 | urb->status = -ESHUTDOWN; | 357 | last_status = -ESHUTDOWN; |
362 | 358 | ||
363 | /* ignore active urbs unless some previous qtd | 359 | /* ignore active urbs unless some previous qtd |
364 | * for the urb faulted (including short read) or | 360 | * for the urb faulted (including short read) or |
365 | * its urb was canceled. we may patch qh or qtds. | 361 | * its urb was canceled. we may patch qh or qtds. |
366 | */ | 362 | */ |
367 | if (likely (urb->status == -EINPROGRESS)) | 363 | if (likely(last_status == -EINPROGRESS && |
364 | !urb->unlinked)) | ||
368 | continue; | 365 | continue; |
369 | 366 | ||
370 | /* issue status after short control reads */ | 367 | /* issue status after short control reads */ |
@@ -392,11 +389,14 @@ halt: | |||
392 | } | 389 | } |
393 | 390 | ||
394 | /* remove it from the queue */ | 391 | /* remove it from the queue */ |
395 | spin_lock (&urb->lock); | 392 | qtd_status = qtd_copy_status(ehci, urb, qtd->length, token); |
396 | qtd_copy_status (ehci, urb, qtd->length, token); | 393 | if (unlikely(qtd_status == -EREMOTEIO)) { |
397 | do_status = (urb->status == -EREMOTEIO) | 394 | do_status = (!urb->unlinked && |
398 | && usb_pipecontrol (urb->pipe); | 395 | usb_pipecontrol(urb->pipe)); |
399 | spin_unlock (&urb->lock); | 396 | qtd_status = 0; |
397 | } | ||
398 | if (likely(last_status == -EINPROGRESS)) | ||
399 | last_status = qtd_status; | ||
400 | 400 | ||
401 | if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { | 401 | if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { |
402 | last = list_entry (qtd->qtd_list.prev, | 402 | last = list_entry (qtd->qtd_list.prev, |
@@ -409,7 +409,7 @@ halt: | |||
409 | 409 | ||
410 | /* last urb's completion might still need calling */ | 410 | /* last urb's completion might still need calling */ |
411 | if (likely (last != NULL)) { | 411 | if (likely (last != NULL)) { |
412 | ehci_urb_done (ehci, last->urb); | 412 | ehci_urb_done(ehci, last->urb, last_status); |
413 | count++; | 413 | count++; |
414 | ehci_qtd_free (ehci, last); | 414 | ehci_qtd_free (ehci, last); |
415 | } | 415 | } |
@@ -913,7 +913,6 @@ static struct ehci_qh *qh_append_tds ( | |||
913 | static int | 913 | static int |
914 | submit_async ( | 914 | submit_async ( |
915 | struct ehci_hcd *ehci, | 915 | struct ehci_hcd *ehci, |
916 | struct usb_host_endpoint *ep, | ||
917 | struct urb *urb, | 916 | struct urb *urb, |
918 | struct list_head *qtd_list, | 917 | struct list_head *qtd_list, |
919 | gfp_t mem_flags | 918 | gfp_t mem_flags |
@@ -922,10 +921,10 @@ submit_async ( | |||
922 | int epnum; | 921 | int epnum; |
923 | unsigned long flags; | 922 | unsigned long flags; |
924 | struct ehci_qh *qh = NULL; | 923 | struct ehci_qh *qh = NULL; |
925 | int rc = 0; | 924 | int rc; |
926 | 925 | ||
927 | qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); | 926 | qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); |
928 | epnum = ep->desc.bEndpointAddress; | 927 | epnum = urb->ep->desc.bEndpointAddress; |
929 | 928 | ||
930 | #ifdef EHCI_URB_TRACE | 929 | #ifdef EHCI_URB_TRACE |
931 | ehci_dbg (ehci, | 930 | ehci_dbg (ehci, |
@@ -933,7 +932,7 @@ submit_async ( | |||
933 | __FUNCTION__, urb->dev->devpath, urb, | 932 | __FUNCTION__, urb->dev->devpath, urb, |
934 | epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out", | 933 | epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out", |
935 | urb->transfer_buffer_length, | 934 | urb->transfer_buffer_length, |
936 | qtd, ep->hcpriv); | 935 | qtd, urb->ep->hcpriv); |
937 | #endif | 936 | #endif |
938 | 937 | ||
939 | spin_lock_irqsave (&ehci->lock, flags); | 938 | spin_lock_irqsave (&ehci->lock, flags); |
@@ -942,9 +941,13 @@ submit_async ( | |||
942 | rc = -ESHUTDOWN; | 941 | rc = -ESHUTDOWN; |
943 | goto done; | 942 | goto done; |
944 | } | 943 | } |
944 | rc = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb); | ||
945 | if (unlikely(rc)) | ||
946 | goto done; | ||
945 | 947 | ||
946 | qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv); | 948 | qh = qh_append_tds(ehci, urb, qtd_list, epnum, &urb->ep->hcpriv); |
947 | if (unlikely(qh == NULL)) { | 949 | if (unlikely(qh == NULL)) { |
950 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
948 | rc = -ENOMEM; | 951 | rc = -ENOMEM; |
949 | goto done; | 952 | goto done; |
950 | } | 953 | } |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index e682f2342ef8..80d99bce2b38 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -797,7 +797,6 @@ done: | |||
797 | 797 | ||
798 | static int intr_submit ( | 798 | static int intr_submit ( |
799 | struct ehci_hcd *ehci, | 799 | struct ehci_hcd *ehci, |
800 | struct usb_host_endpoint *ep, | ||
801 | struct urb *urb, | 800 | struct urb *urb, |
802 | struct list_head *qtd_list, | 801 | struct list_head *qtd_list, |
803 | gfp_t mem_flags | 802 | gfp_t mem_flags |
@@ -805,23 +804,26 @@ static int intr_submit ( | |||
805 | unsigned epnum; | 804 | unsigned epnum; |
806 | unsigned long flags; | 805 | unsigned long flags; |
807 | struct ehci_qh *qh; | 806 | struct ehci_qh *qh; |
808 | int status = 0; | 807 | int status; |
809 | struct list_head empty; | 808 | struct list_head empty; |
810 | 809 | ||
811 | /* get endpoint and transfer/schedule data */ | 810 | /* get endpoint and transfer/schedule data */ |
812 | epnum = ep->desc.bEndpointAddress; | 811 | epnum = urb->ep->desc.bEndpointAddress; |
813 | 812 | ||
814 | spin_lock_irqsave (&ehci->lock, flags); | 813 | spin_lock_irqsave (&ehci->lock, flags); |
815 | 814 | ||
816 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, | 815 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, |
817 | &ehci_to_hcd(ehci)->flags))) { | 816 | &ehci_to_hcd(ehci)->flags))) { |
818 | status = -ESHUTDOWN; | 817 | status = -ESHUTDOWN; |
819 | goto done; | 818 | goto done_not_linked; |
820 | } | 819 | } |
820 | status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb); | ||
821 | if (unlikely(status)) | ||
822 | goto done_not_linked; | ||
821 | 823 | ||
822 | /* get qh and force any scheduling errors */ | 824 | /* get qh and force any scheduling errors */ |
823 | INIT_LIST_HEAD (&empty); | 825 | INIT_LIST_HEAD (&empty); |
824 | qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv); | 826 | qh = qh_append_tds(ehci, urb, &empty, epnum, &urb->ep->hcpriv); |
825 | if (qh == NULL) { | 827 | if (qh == NULL) { |
826 | status = -ENOMEM; | 828 | status = -ENOMEM; |
827 | goto done; | 829 | goto done; |
@@ -832,13 +834,16 @@ static int intr_submit ( | |||
832 | } | 834 | } |
833 | 835 | ||
834 | /* then queue the urb's tds to the qh */ | 836 | /* then queue the urb's tds to the qh */ |
835 | qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv); | 837 | qh = qh_append_tds(ehci, urb, qtd_list, epnum, &urb->ep->hcpriv); |
836 | BUG_ON (qh == NULL); | 838 | BUG_ON (qh == NULL); |
837 | 839 | ||
838 | /* ... update usbfs periodic stats */ | 840 | /* ... update usbfs periodic stats */ |
839 | ehci_to_hcd(ehci)->self.bandwidth_int_reqs++; | 841 | ehci_to_hcd(ehci)->self.bandwidth_int_reqs++; |
840 | 842 | ||
841 | done: | 843 | done: |
844 | if (unlikely(status)) | ||
845 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
846 | done_not_linked: | ||
842 | spin_unlock_irqrestore (&ehci->lock, flags); | 847 | spin_unlock_irqrestore (&ehci->lock, flags); |
843 | if (status) | 848 | if (status) |
844 | qtd_list_free (ehci, urb, qtd_list); | 849 | qtd_list_free (ehci, urb, qtd_list); |
@@ -1622,7 +1627,7 @@ itd_complete ( | |||
1622 | 1627 | ||
1623 | /* give urb back to the driver ... can be out-of-order */ | 1628 | /* give urb back to the driver ... can be out-of-order */ |
1624 | dev = urb->dev; | 1629 | dev = urb->dev; |
1625 | ehci_urb_done (ehci, urb); | 1630 | ehci_urb_done(ehci, urb, 0); |
1626 | urb = NULL; | 1631 | urb = NULL; |
1627 | 1632 | ||
1628 | /* defer stopping schedule; completion can submit */ | 1633 | /* defer stopping schedule; completion can submit */ |
@@ -1686,12 +1691,19 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, | |||
1686 | /* schedule ... need to lock */ | 1691 | /* schedule ... need to lock */ |
1687 | spin_lock_irqsave (&ehci->lock, flags); | 1692 | spin_lock_irqsave (&ehci->lock, flags); |
1688 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, | 1693 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, |
1689 | &ehci_to_hcd(ehci)->flags))) | 1694 | &ehci_to_hcd(ehci)->flags))) { |
1690 | status = -ESHUTDOWN; | 1695 | status = -ESHUTDOWN; |
1691 | else | 1696 | goto done_not_linked; |
1692 | status = iso_stream_schedule (ehci, urb, stream); | 1697 | } |
1698 | status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb); | ||
1699 | if (unlikely(status)) | ||
1700 | goto done_not_linked; | ||
1701 | status = iso_stream_schedule(ehci, urb, stream); | ||
1693 | if (likely (status == 0)) | 1702 | if (likely (status == 0)) |
1694 | itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); | 1703 | itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); |
1704 | else | ||
1705 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
1706 | done_not_linked: | ||
1695 | spin_unlock_irqrestore (&ehci->lock, flags); | 1707 | spin_unlock_irqrestore (&ehci->lock, flags); |
1696 | 1708 | ||
1697 | done: | 1709 | done: |
@@ -1988,7 +2000,7 @@ sitd_complete ( | |||
1988 | 2000 | ||
1989 | /* give urb back to the driver */ | 2001 | /* give urb back to the driver */ |
1990 | dev = urb->dev; | 2002 | dev = urb->dev; |
1991 | ehci_urb_done (ehci, urb); | 2003 | ehci_urb_done(ehci, urb, 0); |
1992 | urb = NULL; | 2004 | urb = NULL; |
1993 | 2005 | ||
1994 | /* defer stopping schedule; completion can submit */ | 2006 | /* defer stopping schedule; completion can submit */ |
@@ -2049,12 +2061,19 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, | |||
2049 | /* schedule ... need to lock */ | 2061 | /* schedule ... need to lock */ |
2050 | spin_lock_irqsave (&ehci->lock, flags); | 2062 | spin_lock_irqsave (&ehci->lock, flags); |
2051 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, | 2063 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, |
2052 | &ehci_to_hcd(ehci)->flags))) | 2064 | &ehci_to_hcd(ehci)->flags))) { |
2053 | status = -ESHUTDOWN; | 2065 | status = -ESHUTDOWN; |
2054 | else | 2066 | goto done_not_linked; |
2055 | status = iso_stream_schedule (ehci, urb, stream); | 2067 | } |
2068 | status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb); | ||
2069 | if (unlikely(status)) | ||
2070 | goto done_not_linked; | ||
2071 | status = iso_stream_schedule(ehci, urb, stream); | ||
2056 | if (status == 0) | 2072 | if (status == 0) |
2057 | sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); | 2073 | sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); |
2074 | else | ||
2075 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
2076 | done_not_linked: | ||
2058 | spin_unlock_irqrestore (&ehci->lock, flags); | 2077 | spin_unlock_irqrestore (&ehci->lock, flags); |
2059 | 2078 | ||
2060 | done: | 2079 | done: |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 5c851a36de72..c27417f5b9d8 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -277,12 +277,11 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
277 | processed urbs. | 277 | processed urbs. |
278 | */ | 278 | */ |
279 | static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, | 279 | static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, |
280 | struct urb *urb) | 280 | struct urb *urb, int status) |
281 | __releases(isp116x->lock) __acquires(isp116x->lock) | 281 | __releases(isp116x->lock) __acquires(isp116x->lock) |
282 | { | 282 | { |
283 | unsigned i; | 283 | unsigned i; |
284 | 284 | ||
285 | urb->hcpriv = NULL; | ||
286 | ep->error_count = 0; | 285 | ep->error_count = 0; |
287 | 286 | ||
288 | if (usb_pipecontrol(urb->pipe)) | 287 | if (usb_pipecontrol(urb->pipe)) |
@@ -290,8 +289,9 @@ __releases(isp116x->lock) __acquires(isp116x->lock) | |||
290 | 289 | ||
291 | urb_dbg(urb, "Finish"); | 290 | urb_dbg(urb, "Finish"); |
292 | 291 | ||
292 | usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb); | ||
293 | spin_unlock(&isp116x->lock); | 293 | spin_unlock(&isp116x->lock); |
294 | usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); | 294 | usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, status); |
295 | spin_lock(&isp116x->lock); | 295 | spin_lock(&isp116x->lock); |
296 | 296 | ||
297 | /* take idle endpoints out of the schedule */ | 297 | /* take idle endpoints out of the schedule */ |
@@ -445,12 +445,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
445 | if (PTD_GET_ACTIVE(ptd) | 445 | if (PTD_GET_ACTIVE(ptd) |
446 | || (cc != TD_CC_NOERROR && cc < 0x0E)) | 446 | || (cc != TD_CC_NOERROR && cc < 0x0E)) |
447 | break; | 447 | break; |
448 | if ((urb->transfer_flags & URB_SHORT_NOT_OK) && | 448 | status = 0; |
449 | urb->actual_length < | ||
450 | urb->transfer_buffer_length) | ||
451 | status = -EREMOTEIO; | ||
452 | else | ||
453 | status = 0; | ||
454 | ep->nextpid = 0; | 449 | ep->nextpid = 0; |
455 | break; | 450 | break; |
456 | default: | 451 | default: |
@@ -458,14 +453,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
458 | } | 453 | } |
459 | 454 | ||
460 | done: | 455 | done: |
461 | if (status != -EINPROGRESS) { | 456 | if (status != -EINPROGRESS || urb->unlinked) |
462 | spin_lock(&urb->lock); | 457 | finish_request(isp116x, ep, urb, status); |
463 | if (urb->status == -EINPROGRESS) | ||
464 | urb->status = status; | ||
465 | spin_unlock(&urb->lock); | ||
466 | } | ||
467 | if (urb->status != -EINPROGRESS) | ||
468 | finish_request(isp116x, ep, urb); | ||
469 | } | 458 | } |
470 | } | 459 | } |
471 | 460 | ||
@@ -673,7 +662,7 @@ static int balance(struct isp116x *isp116x, u16 period, u16 load) | |||
673 | /*-----------------------------------------------------------------*/ | 662 | /*-----------------------------------------------------------------*/ |
674 | 663 | ||
675 | static int isp116x_urb_enqueue(struct usb_hcd *hcd, | 664 | static int isp116x_urb_enqueue(struct usb_hcd *hcd, |
676 | struct usb_host_endpoint *hep, struct urb *urb, | 665 | struct urb *urb, |
677 | gfp_t mem_flags) | 666 | gfp_t mem_flags) |
678 | { | 667 | { |
679 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 668 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
@@ -682,6 +671,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
682 | int is_out = !usb_pipein(pipe); | 671 | int is_out = !usb_pipein(pipe); |
683 | int type = usb_pipetype(pipe); | 672 | int type = usb_pipetype(pipe); |
684 | int epnum = usb_pipeendpoint(pipe); | 673 | int epnum = usb_pipeendpoint(pipe); |
674 | struct usb_host_endpoint *hep = urb->ep; | ||
685 | struct isp116x_ep *ep = NULL; | 675 | struct isp116x_ep *ep = NULL; |
686 | unsigned long flags; | 676 | unsigned long flags; |
687 | int i; | 677 | int i; |
@@ -705,7 +695,12 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
705 | if (!HC_IS_RUNNING(hcd->state)) { | 695 | if (!HC_IS_RUNNING(hcd->state)) { |
706 | kfree(ep); | 696 | kfree(ep); |
707 | ret = -ENODEV; | 697 | ret = -ENODEV; |
708 | goto fail; | 698 | goto fail_not_linked; |
699 | } | ||
700 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
701 | if (ret) { | ||
702 | kfree(ep); | ||
703 | goto fail_not_linked; | ||
709 | } | 704 | } |
710 | 705 | ||
711 | if (hep->hcpriv) | 706 | if (hep->hcpriv) |
@@ -808,16 +803,13 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
808 | } | 803 | } |
809 | } | 804 | } |
810 | 805 | ||
811 | /* in case of unlink-during-submit */ | ||
812 | if (urb->status != -EINPROGRESS) { | ||
813 | finish_request(isp116x, ep, urb); | ||
814 | ret = 0; | ||
815 | goto fail; | ||
816 | } | ||
817 | urb->hcpriv = hep; | 806 | urb->hcpriv = hep; |
818 | start_atl_transfers(isp116x); | 807 | start_atl_transfers(isp116x); |
819 | 808 | ||
820 | fail: | 809 | fail: |
810 | if (ret) | ||
811 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
812 | fail_not_linked: | ||
821 | spin_unlock_irqrestore(&isp116x->lock, flags); | 813 | spin_unlock_irqrestore(&isp116x->lock, flags); |
822 | return ret; | 814 | return ret; |
823 | } | 815 | } |
@@ -825,20 +817,21 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
825 | /* | 817 | /* |
826 | Dequeue URBs. | 818 | Dequeue URBs. |
827 | */ | 819 | */ |
828 | static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 820 | static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, |
821 | int status) | ||
829 | { | 822 | { |
830 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 823 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
831 | struct usb_host_endpoint *hep; | 824 | struct usb_host_endpoint *hep; |
832 | struct isp116x_ep *ep, *ep_act; | 825 | struct isp116x_ep *ep, *ep_act; |
833 | unsigned long flags; | 826 | unsigned long flags; |
827 | int rc; | ||
834 | 828 | ||
835 | spin_lock_irqsave(&isp116x->lock, flags); | 829 | spin_lock_irqsave(&isp116x->lock, flags); |
830 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
831 | if (rc) | ||
832 | goto done; | ||
833 | |||
836 | hep = urb->hcpriv; | 834 | hep = urb->hcpriv; |
837 | /* URB already unlinked (or never linked)? */ | ||
838 | if (!hep) { | ||
839 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
840 | return 0; | ||
841 | } | ||
842 | ep = hep->hcpriv; | 835 | ep = hep->hcpriv; |
843 | WARN_ON(hep != ep->hep); | 836 | WARN_ON(hep != ep->hep); |
844 | 837 | ||
@@ -855,10 +848,10 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
855 | } | 848 | } |
856 | 849 | ||
857 | if (urb) | 850 | if (urb) |
858 | finish_request(isp116x, ep, urb); | 851 | finish_request(isp116x, ep, urb, status); |
859 | 852 | done: | |
860 | spin_unlock_irqrestore(&isp116x->lock, flags); | 853 | spin_unlock_irqrestore(&isp116x->lock, flags); |
861 | return 0; | 854 | return rc; |
862 | } | 855 | } |
863 | 856 | ||
864 | static void isp116x_endpoint_disable(struct usb_hcd *hcd, | 857 | static void isp116x_endpoint_disable(struct usb_hcd *hcd, |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index f61c6cdd06f2..ebab5ce8f5ce 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * small: 0) header + data packets 1) just header | 24 | * small: 0) header + data packets 1) just header |
25 | */ | 25 | */ |
26 | static void __maybe_unused | 26 | static void __maybe_unused |
27 | urb_print (struct urb * urb, char * str, int small) | 27 | urb_print(struct urb * urb, char * str, int small, int status) |
28 | { | 28 | { |
29 | unsigned int pipe= urb->pipe; | 29 | unsigned int pipe= urb->pipe; |
30 | 30 | ||
@@ -34,7 +34,7 @@ urb_print (struct urb * urb, char * str, int small) | |||
34 | } | 34 | } |
35 | 35 | ||
36 | #ifndef OHCI_VERBOSE_DEBUG | 36 | #ifndef OHCI_VERBOSE_DEBUG |
37 | if (urb->status != 0) | 37 | if (status != 0) |
38 | #endif | 38 | #endif |
39 | dbg("%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d", | 39 | dbg("%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d", |
40 | str, | 40 | str, |
@@ -46,7 +46,7 @@ urb_print (struct urb * urb, char * str, int small) | |||
46 | urb->transfer_flags, | 46 | urb->transfer_flags, |
47 | urb->actual_length, | 47 | urb->actual_length, |
48 | urb->transfer_buffer_length, | 48 | urb->transfer_buffer_length, |
49 | urb->status); | 49 | status); |
50 | 50 | ||
51 | #ifdef OHCI_VERBOSE_DEBUG | 51 | #ifdef OHCI_VERBOSE_DEBUG |
52 | if (!small) { | 52 | if (!small) { |
@@ -66,7 +66,7 @@ urb_print (struct urb * urb, char * str, int small) | |||
66 | urb->transfer_buffer_length: urb->actual_length; | 66 | urb->transfer_buffer_length: urb->actual_length; |
67 | for (i = 0; i < 16 && i < len; i++) | 67 | for (i = 0; i < 16 && i < len; i++) |
68 | printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); | 68 | printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); |
69 | printk ("%s stat:%d\n", i < len? "...": "", urb->status); | 69 | printk ("%s stat:%d\n", i < len? "...": "", status); |
70 | } | 70 | } |
71 | } | 71 | } |
72 | #endif | 72 | #endif |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 6edf4097d2d2..240c7f507541 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -81,7 +81,6 @@ static void ohci_dump (struct ohci_hcd *ohci, int verbose); | |||
81 | static int ohci_init (struct ohci_hcd *ohci); | 81 | static int ohci_init (struct ohci_hcd *ohci); |
82 | static void ohci_stop (struct usb_hcd *hcd); | 82 | static void ohci_stop (struct usb_hcd *hcd); |
83 | static int ohci_restart (struct ohci_hcd *ohci); | 83 | static int ohci_restart (struct ohci_hcd *ohci); |
84 | static void ohci_quirk_nec_worker (struct work_struct *work); | ||
85 | 84 | ||
86 | #include "ohci-hub.c" | 85 | #include "ohci-hub.c" |
87 | #include "ohci-dbg.c" | 86 | #include "ohci-dbg.c" |
@@ -118,7 +117,6 @@ MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake"); | |||
118 | */ | 117 | */ |
119 | static int ohci_urb_enqueue ( | 118 | static int ohci_urb_enqueue ( |
120 | struct usb_hcd *hcd, | 119 | struct usb_hcd *hcd, |
121 | struct usb_host_endpoint *ep, | ||
122 | struct urb *urb, | 120 | struct urb *urb, |
123 | gfp_t mem_flags | 121 | gfp_t mem_flags |
124 | ) { | 122 | ) { |
@@ -131,11 +129,11 @@ static int ohci_urb_enqueue ( | |||
131 | int retval = 0; | 129 | int retval = 0; |
132 | 130 | ||
133 | #ifdef OHCI_VERBOSE_DEBUG | 131 | #ifdef OHCI_VERBOSE_DEBUG |
134 | urb_print (urb, "SUB", usb_pipein (pipe)); | 132 | urb_print(urb, "SUB", usb_pipein(pipe), -EINPROGRESS); |
135 | #endif | 133 | #endif |
136 | 134 | ||
137 | /* every endpoint has a ed, locate and maybe (re)initialize it */ | 135 | /* every endpoint has a ed, locate and maybe (re)initialize it */ |
138 | if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval))) | 136 | if (! (ed = ed_get (ohci, urb->ep, urb->dev, pipe, urb->interval))) |
139 | return -ENOMEM; | 137 | return -ENOMEM; |
140 | 138 | ||
141 | /* for the private part of the URB we need the number of TDs (size) */ | 139 | /* for the private part of the URB we need the number of TDs (size) */ |
@@ -200,22 +198,17 @@ static int ohci_urb_enqueue ( | |||
200 | retval = -ENODEV; | 198 | retval = -ENODEV; |
201 | goto fail; | 199 | goto fail; |
202 | } | 200 | } |
203 | 201 | retval = usb_hcd_link_urb_to_ep(hcd, urb); | |
204 | /* in case of unlink-during-submit */ | 202 | if (retval) |
205 | spin_lock (&urb->lock); | ||
206 | if (urb->status != -EINPROGRESS) { | ||
207 | spin_unlock (&urb->lock); | ||
208 | urb->hcpriv = urb_priv; | ||
209 | finish_urb (ohci, urb); | ||
210 | retval = 0; | ||
211 | goto fail; | 203 | goto fail; |
212 | } | ||
213 | 204 | ||
214 | /* schedule the ed if needed */ | 205 | /* schedule the ed if needed */ |
215 | if (ed->state == ED_IDLE) { | 206 | if (ed->state == ED_IDLE) { |
216 | retval = ed_schedule (ohci, ed); | 207 | retval = ed_schedule (ohci, ed); |
217 | if (retval < 0) | 208 | if (retval < 0) { |
218 | goto fail0; | 209 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
210 | goto fail; | ||
211 | } | ||
219 | if (ed->type == PIPE_ISOCHRONOUS) { | 212 | if (ed->type == PIPE_ISOCHRONOUS) { |
220 | u16 frame = ohci_frame_no(ohci); | 213 | u16 frame = ohci_frame_no(ohci); |
221 | 214 | ||
@@ -239,8 +232,6 @@ static int ohci_urb_enqueue ( | |||
239 | urb->hcpriv = urb_priv; | 232 | urb->hcpriv = urb_priv; |
240 | td_submit_urb (ohci, urb); | 233 | td_submit_urb (ohci, urb); |
241 | 234 | ||
242 | fail0: | ||
243 | spin_unlock (&urb->lock); | ||
244 | fail: | 235 | fail: |
245 | if (retval) | 236 | if (retval) |
246 | urb_free_priv (ohci, urb_priv); | 237 | urb_free_priv (ohci, urb_priv); |
@@ -249,22 +240,26 @@ fail: | |||
249 | } | 240 | } |
250 | 241 | ||
251 | /* | 242 | /* |
252 | * decouple the URB from the HC queues (TDs, urb_priv); it's | 243 | * decouple the URB from the HC queues (TDs, urb_priv). |
253 | * already marked using urb->status. reporting is always done | 244 | * reporting is always done |
254 | * asynchronously, and we might be dealing with an urb that's | 245 | * asynchronously, and we might be dealing with an urb that's |
255 | * partially transferred, or an ED with other urbs being unlinked. | 246 | * partially transferred, or an ED with other urbs being unlinked. |
256 | */ | 247 | */ |
257 | static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 248 | static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
258 | { | 249 | { |
259 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 250 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
260 | unsigned long flags; | 251 | unsigned long flags; |
252 | int rc; | ||
261 | 253 | ||
262 | #ifdef OHCI_VERBOSE_DEBUG | 254 | #ifdef OHCI_VERBOSE_DEBUG |
263 | urb_print (urb, "UNLINK", 1); | 255 | urb_print(urb, "UNLINK", 1, status); |
264 | #endif | 256 | #endif |
265 | 257 | ||
266 | spin_lock_irqsave (&ohci->lock, flags); | 258 | spin_lock_irqsave (&ohci->lock, flags); |
267 | if (HC_IS_RUNNING(hcd->state)) { | 259 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
260 | if (rc) { | ||
261 | ; /* Do nothing */ | ||
262 | } else if (HC_IS_RUNNING(hcd->state)) { | ||
268 | urb_priv_t *urb_priv; | 263 | urb_priv_t *urb_priv; |
269 | 264 | ||
270 | /* Unless an IRQ completed the unlink while it was being | 265 | /* Unless an IRQ completed the unlink while it was being |
@@ -282,10 +277,10 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | |||
282 | * any more ... just clean up every urb's memory. | 277 | * any more ... just clean up every urb's memory. |
283 | */ | 278 | */ |
284 | if (urb->hcpriv) | 279 | if (urb->hcpriv) |
285 | finish_urb (ohci, urb); | 280 | finish_urb(ohci, urb, status); |
286 | } | 281 | } |
287 | spin_unlock_irqrestore (&ohci->lock, flags); | 282 | spin_unlock_irqrestore (&ohci->lock, flags); |
288 | return 0; | 283 | return rc; |
289 | } | 284 | } |
290 | 285 | ||
291 | /*-------------------------------------------------------------------------*/ | 286 | /*-------------------------------------------------------------------------*/ |
@@ -314,6 +309,8 @@ rescan: | |||
314 | if (!HC_IS_RUNNING (hcd->state)) { | 309 | if (!HC_IS_RUNNING (hcd->state)) { |
315 | sanitize: | 310 | sanitize: |
316 | ed->state = ED_IDLE; | 311 | ed->state = ED_IDLE; |
312 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | ||
313 | ohci->eds_scheduled--; | ||
317 | finish_unlinks (ohci, 0); | 314 | finish_unlinks (ohci, 0); |
318 | } | 315 | } |
319 | 316 | ||
@@ -321,7 +318,12 @@ sanitize: | |||
321 | case ED_UNLINK: /* wait for hw to finish? */ | 318 | case ED_UNLINK: /* wait for hw to finish? */ |
322 | /* major IRQ delivery trouble loses INTR_SF too... */ | 319 | /* major IRQ delivery trouble loses INTR_SF too... */ |
323 | if (limit-- == 0) { | 320 | if (limit-- == 0) { |
324 | ohci_warn (ohci, "IRQ INTR_SF lossage\n"); | 321 | ohci_warn(ohci, "ED unlink timeout\n"); |
322 | if (quirk_zfmicro(ohci)) { | ||
323 | ohci_warn(ohci, "Attempting ZF TD recovery\n"); | ||
324 | ohci->ed_to_check = ed; | ||
325 | ohci->zf_delay = 2; | ||
326 | } | ||
325 | goto sanitize; | 327 | goto sanitize; |
326 | } | 328 | } |
327 | spin_unlock_irqrestore (&ohci->lock, flags); | 329 | spin_unlock_irqrestore (&ohci->lock, flags); |
@@ -379,6 +381,93 @@ ohci_shutdown (struct usb_hcd *hcd) | |||
379 | (void) ohci_readl (ohci, &ohci->regs->control); | 381 | (void) ohci_readl (ohci, &ohci->regs->control); |
380 | } | 382 | } |
381 | 383 | ||
384 | static int check_ed(struct ohci_hcd *ohci, struct ed *ed) | ||
385 | { | ||
386 | return (hc32_to_cpu(ohci, ed->hwINFO) & ED_IN) != 0 | ||
387 | && (hc32_to_cpu(ohci, ed->hwHeadP) & TD_MASK) | ||
388 | == (hc32_to_cpu(ohci, ed->hwTailP) & TD_MASK) | ||
389 | && !list_empty(&ed->td_list); | ||
390 | } | ||
391 | |||
392 | /* ZF Micro watchdog timer callback. The ZF Micro chipset sometimes completes | ||
393 | * an interrupt TD but neglects to add it to the donelist. On systems with | ||
394 | * this chipset, we need to periodically check the state of the queues to look | ||
395 | * for such "lost" TDs. | ||
396 | */ | ||
397 | static void unlink_watchdog_func(unsigned long _ohci) | ||
398 | { | ||
399 | long flags; | ||
400 | unsigned max; | ||
401 | unsigned seen_count = 0; | ||
402 | unsigned i; | ||
403 | struct ed **seen = NULL; | ||
404 | struct ohci_hcd *ohci = (struct ohci_hcd *) _ohci; | ||
405 | |||
406 | spin_lock_irqsave(&ohci->lock, flags); | ||
407 | max = ohci->eds_scheduled; | ||
408 | if (!max) | ||
409 | goto done; | ||
410 | |||
411 | if (ohci->ed_to_check) | ||
412 | goto out; | ||
413 | |||
414 | seen = kcalloc(max, sizeof *seen, GFP_ATOMIC); | ||
415 | if (!seen) | ||
416 | goto out; | ||
417 | |||
418 | for (i = 0; i < NUM_INTS; i++) { | ||
419 | struct ed *ed = ohci->periodic[i]; | ||
420 | |||
421 | while (ed) { | ||
422 | unsigned temp; | ||
423 | |||
424 | /* scan this branch of the periodic schedule tree */ | ||
425 | for (temp = 0; temp < seen_count; temp++) { | ||
426 | if (seen[temp] == ed) { | ||
427 | /* we've checked it and what's after */ | ||
428 | ed = NULL; | ||
429 | break; | ||
430 | } | ||
431 | } | ||
432 | if (!ed) | ||
433 | break; | ||
434 | seen[seen_count++] = ed; | ||
435 | if (!check_ed(ohci, ed)) { | ||
436 | ed = ed->ed_next; | ||
437 | continue; | ||
438 | } | ||
439 | |||
440 | /* HC's TD list is empty, but HCD sees at least one | ||
441 | * TD that's not been sent through the donelist. | ||
442 | */ | ||
443 | ohci->ed_to_check = ed; | ||
444 | ohci->zf_delay = 2; | ||
445 | |||
446 | /* The HC may wait until the next frame to report the | ||
447 | * TD as done through the donelist and INTR_WDH. (We | ||
448 | * just *assume* it's not a multi-TD interrupt URB; | ||
449 | * those could defer the IRQ more than one frame, using | ||
450 | * DI...) Check again after the next INTR_SF. | ||
451 | */ | ||
452 | ohci_writel(ohci, OHCI_INTR_SF, | ||
453 | &ohci->regs->intrstatus); | ||
454 | ohci_writel(ohci, OHCI_INTR_SF, | ||
455 | &ohci->regs->intrenable); | ||
456 | |||
457 | /* flush those writes */ | ||
458 | (void) ohci_readl(ohci, &ohci->regs->control); | ||
459 | |||
460 | goto out; | ||
461 | } | ||
462 | } | ||
463 | out: | ||
464 | kfree(seen); | ||
465 | if (ohci->eds_scheduled) | ||
466 | mod_timer(&ohci->unlink_watchdog, round_jiffies_relative(HZ)); | ||
467 | done: | ||
468 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
469 | } | ||
470 | |||
382 | /*-------------------------------------------------------------------------* | 471 | /*-------------------------------------------------------------------------* |
383 | * HC functions | 472 | * HC functions |
384 | *-------------------------------------------------------------------------*/ | 473 | *-------------------------------------------------------------------------*/ |
@@ -616,6 +705,15 @@ retry: | |||
616 | mdelay ((temp >> 23) & 0x1fe); | 705 | mdelay ((temp >> 23) & 0x1fe); |
617 | hcd->state = HC_STATE_RUNNING; | 706 | hcd->state = HC_STATE_RUNNING; |
618 | 707 | ||
708 | if (quirk_zfmicro(ohci)) { | ||
709 | /* Create timer to watch for bad queue state on ZF Micro */ | ||
710 | setup_timer(&ohci->unlink_watchdog, unlink_watchdog_func, | ||
711 | (unsigned long) ohci); | ||
712 | |||
713 | ohci->eds_scheduled = 0; | ||
714 | ohci->ed_to_check = NULL; | ||
715 | } | ||
716 | |||
619 | ohci_dump (ohci, 1); | 717 | ohci_dump (ohci, 1); |
620 | 718 | ||
621 | return 0; | 719 | return 0; |
@@ -629,10 +727,11 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
629 | { | 727 | { |
630 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 728 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
631 | struct ohci_regs __iomem *regs = ohci->regs; | 729 | struct ohci_regs __iomem *regs = ohci->regs; |
632 | int ints; | 730 | int ints; |
633 | 731 | ||
634 | /* we can eliminate a (slow) ohci_readl() | 732 | /* we can eliminate a (slow) ohci_readl() |
635 | if _only_ WDH caused this irq */ | 733 | * if _only_ WDH caused this irq |
734 | */ | ||
636 | if ((ohci->hcca->done_head != 0) | 735 | if ((ohci->hcca->done_head != 0) |
637 | && ! (hc32_to_cpup (ohci, &ohci->hcca->done_head) | 736 | && ! (hc32_to_cpup (ohci, &ohci->hcca->done_head) |
638 | & 0x01)) { | 737 | & 0x01)) { |
@@ -651,7 +750,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
651 | 750 | ||
652 | if (ints & OHCI_INTR_UE) { | 751 | if (ints & OHCI_INTR_UE) { |
653 | // e.g. due to PCI Master/Target Abort | 752 | // e.g. due to PCI Master/Target Abort |
654 | if (ohci->flags & OHCI_QUIRK_NEC) { | 753 | if (quirk_nec(ohci)) { |
655 | /* Workaround for a silicon bug in some NEC chips used | 754 | /* Workaround for a silicon bug in some NEC chips used |
656 | * in Apple's PowerBooks. Adapted from Darwin code. | 755 | * in Apple's PowerBooks. Adapted from Darwin code. |
657 | */ | 756 | */ |
@@ -713,6 +812,31 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
713 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); | 812 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); |
714 | } | 813 | } |
715 | 814 | ||
815 | if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) { | ||
816 | spin_lock(&ohci->lock); | ||
817 | if (ohci->ed_to_check) { | ||
818 | struct ed *ed = ohci->ed_to_check; | ||
819 | |||
820 | if (check_ed(ohci, ed)) { | ||
821 | /* HC thinks the TD list is empty; HCD knows | ||
822 | * at least one TD is outstanding | ||
823 | */ | ||
824 | if (--ohci->zf_delay == 0) { | ||
825 | struct td *td = list_entry( | ||
826 | ed->td_list.next, | ||
827 | struct td, td_list); | ||
828 | ohci_warn(ohci, | ||
829 | "Reclaiming orphan TD %p\n", | ||
830 | td); | ||
831 | takeback_td(ohci, td); | ||
832 | ohci->ed_to_check = NULL; | ||
833 | } | ||
834 | } else | ||
835 | ohci->ed_to_check = NULL; | ||
836 | } | ||
837 | spin_unlock(&ohci->lock); | ||
838 | } | ||
839 | |||
716 | /* could track INTR_SO to reduce available PCI/... bandwidth */ | 840 | /* could track INTR_SO to reduce available PCI/... bandwidth */ |
717 | 841 | ||
718 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled | 842 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled |
@@ -721,7 +845,9 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
721 | spin_lock (&ohci->lock); | 845 | spin_lock (&ohci->lock); |
722 | if (ohci->ed_rm_list) | 846 | if (ohci->ed_rm_list) |
723 | finish_unlinks (ohci, ohci_frame_no(ohci)); | 847 | finish_unlinks (ohci, ohci_frame_no(ohci)); |
724 | if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list | 848 | if ((ints & OHCI_INTR_SF) != 0 |
849 | && !ohci->ed_rm_list | ||
850 | && !ohci->ed_to_check | ||
725 | && HC_IS_RUNNING(hcd->state)) | 851 | && HC_IS_RUNNING(hcd->state)) |
726 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); | 852 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); |
727 | spin_unlock (&ohci->lock); | 853 | spin_unlock (&ohci->lock); |
@@ -751,6 +877,9 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
751 | free_irq(hcd->irq, hcd); | 877 | free_irq(hcd->irq, hcd); |
752 | hcd->irq = -1; | 878 | hcd->irq = -1; |
753 | 879 | ||
880 | if (quirk_zfmicro(ohci)) | ||
881 | del_timer(&ohci->unlink_watchdog); | ||
882 | |||
754 | remove_debug_files (ohci); | 883 | remove_debug_files (ohci); |
755 | ohci_mem_cleanup (ohci); | 884 | ohci_mem_cleanup (ohci); |
756 | if (ohci->hcca) { | 885 | if (ohci->hcca) { |
@@ -798,9 +927,8 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
798 | ed, ed->state); | 927 | ed, ed->state); |
799 | } | 928 | } |
800 | 929 | ||
801 | spin_lock (&urb->lock); | 930 | if (!urb->unlinked) |
802 | urb->status = -ESHUTDOWN; | 931 | urb->unlinked = -ESHUTDOWN; |
803 | spin_unlock (&urb->lock); | ||
804 | } | 932 | } |
805 | finish_unlinks (ohci, 0); | 933 | finish_unlinks (ohci, 0); |
806 | spin_unlock_irq(&ohci->lock); | 934 | spin_unlock_irq(&ohci->lock); |
@@ -828,27 +956,6 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
828 | 956 | ||
829 | /*-------------------------------------------------------------------------*/ | 957 | /*-------------------------------------------------------------------------*/ |
830 | 958 | ||
831 | /* NEC workaround */ | ||
832 | static void ohci_quirk_nec_worker(struct work_struct *work) | ||
833 | { | ||
834 | struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work); | ||
835 | int status; | ||
836 | |||
837 | status = ohci_init(ohci); | ||
838 | if (status != 0) { | ||
839 | ohci_err(ohci, "Restarting NEC controller failed " | ||
840 | "in ohci_init, %d\n", status); | ||
841 | return; | ||
842 | } | ||
843 | |||
844 | status = ohci_restart(ohci); | ||
845 | if (status != 0) | ||
846 | ohci_err(ohci, "Restarting NEC controller failed " | ||
847 | "in ohci_restart, %d\n", status); | ||
848 | } | ||
849 | |||
850 | /*-------------------------------------------------------------------------*/ | ||
851 | |||
852 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC | 959 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC |
853 | 960 | ||
854 | MODULE_AUTHOR (DRIVER_AUTHOR); | 961 | MODULE_AUTHOR (DRIVER_AUTHOR); |
@@ -926,11 +1033,17 @@ MODULE_LICENSE ("GPL"); | |||
926 | #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver | 1033 | #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver |
927 | #endif | 1034 | #endif |
928 | 1035 | ||
1036 | #ifdef CONFIG_USB_OHCI_HCD_SSB | ||
1037 | #include "ohci-ssb.c" | ||
1038 | #define SSB_OHCI_DRIVER ssb_ohci_driver | ||
1039 | #endif | ||
1040 | |||
929 | #if !defined(PCI_DRIVER) && \ | 1041 | #if !defined(PCI_DRIVER) && \ |
930 | !defined(PLATFORM_DRIVER) && \ | 1042 | !defined(PLATFORM_DRIVER) && \ |
931 | !defined(OF_PLATFORM_DRIVER) && \ | 1043 | !defined(OF_PLATFORM_DRIVER) && \ |
932 | !defined(SA1111_DRIVER) && \ | 1044 | !defined(SA1111_DRIVER) && \ |
933 | !defined(PS3_SYSTEM_BUS_DRIVER) | 1045 | !defined(PS3_SYSTEM_BUS_DRIVER) && \ |
1046 | !defined(SSB_OHCI_DRIVER) | ||
934 | #error "missing bus glue for ohci-hcd" | 1047 | #error "missing bus glue for ohci-hcd" |
935 | #endif | 1048 | #endif |
936 | 1049 | ||
@@ -975,10 +1088,20 @@ static int __init ohci_hcd_mod_init(void) | |||
975 | goto error_pci; | 1088 | goto error_pci; |
976 | #endif | 1089 | #endif |
977 | 1090 | ||
1091 | #ifdef SSB_OHCI_DRIVER | ||
1092 | retval = ssb_driver_register(&SSB_OHCI_DRIVER); | ||
1093 | if (retval) | ||
1094 | goto error_ssb; | ||
1095 | #endif | ||
1096 | |||
978 | return retval; | 1097 | return retval; |
979 | 1098 | ||
980 | /* Error path */ | 1099 | /* Error path */ |
1100 | #ifdef SSB_OHCI_DRIVER | ||
1101 | error_ssb: | ||
1102 | #endif | ||
981 | #ifdef PCI_DRIVER | 1103 | #ifdef PCI_DRIVER |
1104 | pci_unregister_driver(&PCI_DRIVER); | ||
982 | error_pci: | 1105 | error_pci: |
983 | #endif | 1106 | #endif |
984 | #ifdef SA1111_DRIVER | 1107 | #ifdef SA1111_DRIVER |
@@ -1003,6 +1126,9 @@ module_init(ohci_hcd_mod_init); | |||
1003 | 1126 | ||
1004 | static void __exit ohci_hcd_mod_exit(void) | 1127 | static void __exit ohci_hcd_mod_exit(void) |
1005 | { | 1128 | { |
1129 | #ifdef SSB_OHCI_DRIVER | ||
1130 | ssb_driver_unregister(&SSB_OHCI_DRIVER); | ||
1131 | #endif | ||
1006 | #ifdef PCI_DRIVER | 1132 | #ifdef PCI_DRIVER |
1007 | pci_unregister_driver(&PCI_DRIVER); | 1133 | pci_unregister_driver(&PCI_DRIVER); |
1008 | #endif | 1134 | #endif |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 450c7b460c5a..2f20d3dc895b 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -28,7 +28,6 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) | |||
28 | ohci->next_statechange = jiffies; | 28 | ohci->next_statechange = jiffies; |
29 | spin_lock_init (&ohci->lock); | 29 | spin_lock_init (&ohci->lock); |
30 | INIT_LIST_HEAD (&ohci->pending); | 30 | INIT_LIST_HEAD (&ohci->pending); |
31 | INIT_WORK (&ohci->nec_work, ohci_quirk_nec_worker); | ||
32 | } | 31 | } |
33 | 32 | ||
34 | /*-------------------------------------------------------------------------*/ | 33 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index a5e2eb85d073..d0360f65ebd9 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -84,7 +84,7 @@ static int ohci_quirk_zfmicro(struct usb_hcd *hcd) | |||
84 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 84 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
85 | 85 | ||
86 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | 86 | ohci->flags |= OHCI_QUIRK_ZFMICRO; |
87 | ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n"); | 87 | ohci_dbg(ohci, "enabled Compaq ZFMicro chipset quirks\n"); |
88 | 88 | ||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
@@ -113,11 +113,31 @@ static int ohci_quirk_toshiba_scc(struct usb_hcd *hcd) | |||
113 | 113 | ||
114 | /* Check for NEC chip and apply quirk for allegedly lost interrupts. | 114 | /* Check for NEC chip and apply quirk for allegedly lost interrupts. |
115 | */ | 115 | */ |
116 | |||
117 | static void ohci_quirk_nec_worker(struct work_struct *work) | ||
118 | { | ||
119 | struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work); | ||
120 | int status; | ||
121 | |||
122 | status = ohci_init(ohci); | ||
123 | if (status != 0) { | ||
124 | ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n", | ||
125 | "ohci_init", status); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | status = ohci_restart(ohci); | ||
130 | if (status != 0) | ||
131 | ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n", | ||
132 | "ohci_restart", status); | ||
133 | } | ||
134 | |||
116 | static int ohci_quirk_nec(struct usb_hcd *hcd) | 135 | static int ohci_quirk_nec(struct usb_hcd *hcd) |
117 | { | 136 | { |
118 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 137 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
119 | 138 | ||
120 | ohci->flags |= OHCI_QUIRK_NEC; | 139 | ohci->flags |= OHCI_QUIRK_NEC; |
140 | INIT_WORK(&ohci->nec_work, ohci_quirk_nec_worker); | ||
121 | ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n"); | 141 | ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n"); |
122 | 142 | ||
123 | return 0; | 143 | return 0; |
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index c43b66acd4d5..0a7426920150 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c | |||
@@ -134,8 +134,11 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | ohci = hcd_to_ohci(hcd); | 136 | ohci = hcd_to_ohci(hcd); |
137 | if (is_bigendian) | 137 | if (is_bigendian) { |
138 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | 138 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; |
139 | if (of_device_is_compatible(dn, "mpc5200-ohci")) | ||
140 | ohci->flags |= OHCI_QUIRK_FRAME_NO; | ||
141 | } | ||
139 | 142 | ||
140 | ohci_hcd_init(ohci); | 143 | ohci_hcd_init(ohci); |
141 | 144 | ||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 1a2e1777ca61..f95be1896b0d 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -73,6 +73,11 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
73 | 73 | ||
74 | ohci = hcd_to_ohci(hcd); | 74 | ohci = hcd_to_ohci(hcd); |
75 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | 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 | ||
76 | ohci_hcd_init(ohci); | 81 | ohci_hcd_init(ohci); |
77 | 82 | ||
78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 83 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 830a3fe8615e..51817322232b 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -36,29 +36,15 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) | |||
36 | * PRECONDITION: ohci lock held, irqs blocked. | 36 | * PRECONDITION: ohci lock held, irqs blocked. |
37 | */ | 37 | */ |
38 | static void | 38 | static void |
39 | finish_urb (struct ohci_hcd *ohci, struct urb *urb) | 39 | finish_urb(struct ohci_hcd *ohci, struct urb *urb, int status) |
40 | __releases(ohci->lock) | 40 | __releases(ohci->lock) |
41 | __acquires(ohci->lock) | 41 | __acquires(ohci->lock) |
42 | { | 42 | { |
43 | // ASSERT (urb->hcpriv != 0); | 43 | // ASSERT (urb->hcpriv != 0); |
44 | 44 | ||
45 | urb_free_priv (ohci, urb->hcpriv); | 45 | urb_free_priv (ohci, urb->hcpriv); |
46 | urb->hcpriv = NULL; | 46 | if (likely(status == -EINPROGRESS)) |
47 | 47 | status = 0; | |
48 | spin_lock (&urb->lock); | ||
49 | if (likely (urb->status == -EINPROGRESS)) | ||
50 | urb->status = 0; | ||
51 | /* report short control reads right even though the data TD always | ||
52 | * has TD_R set. (much simpler, but creates the 1-td limit.) | ||
53 | */ | ||
54 | if (unlikely (urb->transfer_flags & URB_SHORT_NOT_OK) | ||
55 | && unlikely (usb_pipecontrol (urb->pipe)) | ||
56 | && urb->actual_length < urb->transfer_buffer_length | ||
57 | && usb_pipein (urb->pipe) | ||
58 | && urb->status == 0) { | ||
59 | urb->status = -EREMOTEIO; | ||
60 | } | ||
61 | spin_unlock (&urb->lock); | ||
62 | 48 | ||
63 | switch (usb_pipetype (urb->pipe)) { | 49 | switch (usb_pipetype (urb->pipe)) { |
64 | case PIPE_ISOCHRONOUS: | 50 | case PIPE_ISOCHRONOUS: |
@@ -70,12 +56,13 @@ __acquires(ohci->lock) | |||
70 | } | 56 | } |
71 | 57 | ||
72 | #ifdef OHCI_VERBOSE_DEBUG | 58 | #ifdef OHCI_VERBOSE_DEBUG |
73 | urb_print (urb, "RET", usb_pipeout (urb->pipe)); | 59 | urb_print(urb, "RET", usb_pipeout (urb->pipe), status); |
74 | #endif | 60 | #endif |
75 | 61 | ||
76 | /* urb->complete() can reenter this HCD */ | 62 | /* urb->complete() can reenter this HCD */ |
63 | usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb); | ||
77 | spin_unlock (&ohci->lock); | 64 | spin_unlock (&ohci->lock); |
78 | usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb); | 65 | usb_hcd_giveback_urb(ohci_to_hcd(ohci), urb, status); |
79 | spin_lock (&ohci->lock); | 66 | spin_lock (&ohci->lock); |
80 | 67 | ||
81 | /* stop periodic dma if it's not needed */ | 68 | /* stop periodic dma if it's not needed */ |
@@ -179,6 +166,10 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) | |||
179 | ed->ed_prev = NULL; | 166 | ed->ed_prev = NULL; |
180 | ed->ed_next = NULL; | 167 | ed->ed_next = NULL; |
181 | ed->hwNextED = 0; | 168 | ed->hwNextED = 0; |
169 | if (quirk_zfmicro(ohci) | ||
170 | && (ed->type == PIPE_INTERRUPT) | ||
171 | && !(ohci->eds_scheduled++)) | ||
172 | mod_timer(&ohci->unlink_watchdog, round_jiffies_relative(HZ)); | ||
182 | wmb (); | 173 | wmb (); |
183 | 174 | ||
184 | /* we care about rm_list when setting CLE/BLE in case the HC was at | 175 | /* we care about rm_list when setting CLE/BLE in case the HC was at |
@@ -708,19 +699,18 @@ static void td_submit_urb ( | |||
708 | * Done List handling functions | 699 | * Done List handling functions |
709 | *-------------------------------------------------------------------------*/ | 700 | *-------------------------------------------------------------------------*/ |
710 | 701 | ||
711 | /* calculate transfer length/status and update the urb | 702 | /* calculate transfer length/status and update the urb */ |
712 | * PRECONDITION: irqsafe (only for urb->status locking) | 703 | static int td_done(struct ohci_hcd *ohci, struct urb *urb, struct td *td) |
713 | */ | ||
714 | static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | ||
715 | { | 704 | { |
716 | u32 tdINFO = hc32_to_cpup (ohci, &td->hwINFO); | 705 | u32 tdINFO = hc32_to_cpup (ohci, &td->hwINFO); |
717 | int cc = 0; | 706 | int cc = 0; |
707 | int status = -EINPROGRESS; | ||
718 | 708 | ||
719 | list_del (&td->td_list); | 709 | list_del (&td->td_list); |
720 | 710 | ||
721 | /* ISO ... drivers see per-TD length/status */ | 711 | /* ISO ... drivers see per-TD length/status */ |
722 | if (tdINFO & TD_ISO) { | 712 | if (tdINFO & TD_ISO) { |
723 | u16 tdPSW = ohci_hwPSW (ohci, td, 0); | 713 | u16 tdPSW = ohci_hwPSW(ohci, td, 0); |
724 | int dlen = 0; | 714 | int dlen = 0; |
725 | 715 | ||
726 | /* NOTE: assumes FC in tdINFO == 0, and that | 716 | /* NOTE: assumes FC in tdINFO == 0, and that |
@@ -729,7 +719,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
729 | 719 | ||
730 | cc = (tdPSW >> 12) & 0xF; | 720 | cc = (tdPSW >> 12) & 0xF; |
731 | if (tdINFO & TD_CC) /* hc didn't touch? */ | 721 | if (tdINFO & TD_CC) /* hc didn't touch? */ |
732 | return; | 722 | return status; |
733 | 723 | ||
734 | if (usb_pipeout (urb->pipe)) | 724 | if (usb_pipeout (urb->pipe)) |
735 | dlen = urb->iso_frame_desc [td->index].length; | 725 | dlen = urb->iso_frame_desc [td->index].length; |
@@ -762,12 +752,8 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
762 | if (cc == TD_DATAUNDERRUN | 752 | if (cc == TD_DATAUNDERRUN |
763 | && !(urb->transfer_flags & URB_SHORT_NOT_OK)) | 753 | && !(urb->transfer_flags & URB_SHORT_NOT_OK)) |
764 | cc = TD_CC_NOERROR; | 754 | cc = TD_CC_NOERROR; |
765 | if (cc != TD_CC_NOERROR && cc < 0x0E) { | 755 | if (cc != TD_CC_NOERROR && cc < 0x0E) |
766 | spin_lock (&urb->lock); | 756 | status = cc_to_error[cc]; |
767 | if (urb->status == -EINPROGRESS) | ||
768 | urb->status = cc_to_error [cc]; | ||
769 | spin_unlock (&urb->lock); | ||
770 | } | ||
771 | 757 | ||
772 | /* count all non-empty packets except control SETUP packet */ | 758 | /* count all non-empty packets except control SETUP packet */ |
773 | if ((type != PIPE_CONTROL || td->index != 0) && tdBE != 0) { | 759 | if ((type != PIPE_CONTROL || td->index != 0) && tdBE != 0) { |
@@ -786,14 +772,15 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
786 | urb->actual_length, | 772 | urb->actual_length, |
787 | urb->transfer_buffer_length); | 773 | urb->transfer_buffer_length); |
788 | } | 774 | } |
775 | return status; | ||
789 | } | 776 | } |
790 | 777 | ||
791 | /*-------------------------------------------------------------------------*/ | 778 | /*-------------------------------------------------------------------------*/ |
792 | 779 | ||
793 | static inline struct td * | 780 | static void ed_halted(struct ohci_hcd *ohci, struct td *td, int cc) |
794 | ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | ||
795 | { | 781 | { |
796 | struct urb *urb = td->urb; | 782 | struct urb *urb = td->urb; |
783 | urb_priv_t *urb_priv = urb->hcpriv; | ||
797 | struct ed *ed = td->ed; | 784 | struct ed *ed = td->ed; |
798 | struct list_head *tmp = td->td_list.next; | 785 | struct list_head *tmp = td->td_list.next; |
799 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); | 786 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); |
@@ -805,13 +792,12 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
805 | wmb (); | 792 | wmb (); |
806 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); | 793 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); |
807 | 794 | ||
808 | /* put any later tds from this urb onto the donelist, after 'td', | 795 | /* Get rid of all later tds from this urb. We don't have |
809 | * order won't matter here: no errors, and nothing was transferred. | 796 | * to be careful: no errors and nothing was transferred. |
810 | * also patch the ed so it looks as if those tds completed normally. | 797 | * Also patch the ed so it looks as if those tds completed normally. |
811 | */ | 798 | */ |
812 | while (tmp != &ed->td_list) { | 799 | while (tmp != &ed->td_list) { |
813 | struct td *next; | 800 | struct td *next; |
814 | __hc32 info; | ||
815 | 801 | ||
816 | next = list_entry (tmp, struct td, td_list); | 802 | next = list_entry (tmp, struct td, td_list); |
817 | tmp = next->td_list.next; | 803 | tmp = next->td_list.next; |
@@ -826,14 +812,9 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
826 | * then we need to leave the control STATUS packet queued | 812 | * then we need to leave the control STATUS packet queued |
827 | * and clear ED_SKIP. | 813 | * and clear ED_SKIP. |
828 | */ | 814 | */ |
829 | info = next->hwINFO; | ||
830 | info |= cpu_to_hc32 (ohci, TD_DONE); | ||
831 | info &= ~cpu_to_hc32 (ohci, TD_CC); | ||
832 | next->hwINFO = info; | ||
833 | |||
834 | next->next_dl_td = rev; | ||
835 | rev = next; | ||
836 | 815 | ||
816 | list_del(&next->td_list); | ||
817 | urb_priv->td_cnt++; | ||
837 | ed->hwHeadP = next->hwNextTD | toggle; | 818 | ed->hwHeadP = next->hwNextTD | toggle; |
838 | } | 819 | } |
839 | 820 | ||
@@ -859,8 +840,6 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
859 | hc32_to_cpu (ohci, td->hwINFO), | 840 | hc32_to_cpu (ohci, td->hwINFO), |
860 | cc, cc_to_error [cc]); | 841 | cc, cc_to_error [cc]); |
861 | } | 842 | } |
862 | |||
863 | return rev; | ||
864 | } | 843 | } |
865 | 844 | ||
866 | /* replies to the request have to be on a FIFO basis so | 845 | /* replies to the request have to be on a FIFO basis so |
@@ -897,7 +876,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | |||
897 | */ | 876 | */ |
898 | if (cc != TD_CC_NOERROR | 877 | if (cc != TD_CC_NOERROR |
899 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) | 878 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) |
900 | td_rev = ed_halted (ohci, td, cc, td_rev); | 879 | ed_halted(ohci, td, cc); |
901 | 880 | ||
902 | td->next_dl_td = td_rev; | 881 | td->next_dl_td = td_rev; |
903 | td_rev = td; | 882 | td_rev = td; |
@@ -940,8 +919,12 @@ skip_ed: | |||
940 | TD_MASK; | 919 | TD_MASK; |
941 | 920 | ||
942 | /* INTR_WDH may need to clean up first */ | 921 | /* INTR_WDH may need to clean up first */ |
943 | if (td->td_dma != head) | 922 | if (td->td_dma != head) { |
944 | goto skip_ed; | 923 | if (ed == ohci->ed_to_check) |
924 | ohci->ed_to_check = NULL; | ||
925 | else | ||
926 | goto skip_ed; | ||
927 | } | ||
945 | } | 928 | } |
946 | } | 929 | } |
947 | 930 | ||
@@ -974,7 +957,7 @@ rescan_this: | |||
974 | urb = td->urb; | 957 | urb = td->urb; |
975 | urb_priv = td->urb->hcpriv; | 958 | urb_priv = td->urb->hcpriv; |
976 | 959 | ||
977 | if (urb->status == -EINPROGRESS) { | 960 | if (!urb->unlinked) { |
978 | prev = &td->hwNextTD; | 961 | prev = &td->hwNextTD; |
979 | continue; | 962 | continue; |
980 | } | 963 | } |
@@ -990,7 +973,7 @@ rescan_this: | |||
990 | /* if URB is done, clean up */ | 973 | /* if URB is done, clean up */ |
991 | if (urb_priv->td_cnt == urb_priv->length) { | 974 | if (urb_priv->td_cnt == urb_priv->length) { |
992 | modified = completed = 1; | 975 | modified = completed = 1; |
993 | finish_urb (ohci, urb); | 976 | finish_urb(ohci, urb, 0); |
994 | } | 977 | } |
995 | } | 978 | } |
996 | if (completed && !list_empty (&ed->td_list)) | 979 | if (completed && !list_empty (&ed->td_list)) |
@@ -998,6 +981,8 @@ rescan_this: | |||
998 | 981 | ||
999 | /* ED's now officially unlinked, hc doesn't see */ | 982 | /* ED's now officially unlinked, hc doesn't see */ |
1000 | ed->state = ED_IDLE; | 983 | ed->state = ED_IDLE; |
984 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | ||
985 | ohci->eds_scheduled--; | ||
1001 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); | 986 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); |
1002 | ed->hwNextED = 0; | 987 | ed->hwNextED = 0; |
1003 | wmb (); | 988 | wmb (); |
@@ -1021,7 +1006,7 @@ rescan_this: | |||
1021 | 1006 | ||
1022 | if (ohci->ed_controltail) { | 1007 | if (ohci->ed_controltail) { |
1023 | command |= OHCI_CLF; | 1008 | command |= OHCI_CLF; |
1024 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1009 | if (quirk_zfmicro(ohci)) |
1025 | mdelay(1); | 1010 | mdelay(1); |
1026 | if (!(ohci->hc_control & OHCI_CTRL_CLE)) { | 1011 | if (!(ohci->hc_control & OHCI_CTRL_CLE)) { |
1027 | control |= OHCI_CTRL_CLE; | 1012 | control |= OHCI_CTRL_CLE; |
@@ -1031,7 +1016,7 @@ rescan_this: | |||
1031 | } | 1016 | } |
1032 | if (ohci->ed_bulktail) { | 1017 | if (ohci->ed_bulktail) { |
1033 | command |= OHCI_BLF; | 1018 | command |= OHCI_BLF; |
1034 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1019 | if (quirk_zfmicro(ohci)) |
1035 | mdelay(1); | 1020 | mdelay(1); |
1036 | if (!(ohci->hc_control & OHCI_CTRL_BLE)) { | 1021 | if (!(ohci->hc_control & OHCI_CTRL_BLE)) { |
1037 | control |= OHCI_CTRL_BLE; | 1022 | control |= OHCI_CTRL_BLE; |
@@ -1043,13 +1028,13 @@ rescan_this: | |||
1043 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ | 1028 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ |
1044 | if (control) { | 1029 | if (control) { |
1045 | ohci->hc_control |= control; | 1030 | ohci->hc_control |= control; |
1046 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1031 | if (quirk_zfmicro(ohci)) |
1047 | mdelay(1); | 1032 | mdelay(1); |
1048 | ohci_writel (ohci, ohci->hc_control, | 1033 | ohci_writel (ohci, ohci->hc_control, |
1049 | &ohci->regs->control); | 1034 | &ohci->regs->control); |
1050 | } | 1035 | } |
1051 | if (command) { | 1036 | if (command) { |
1052 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1037 | if (quirk_zfmicro(ohci)) |
1053 | mdelay(1); | 1038 | mdelay(1); |
1054 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); | 1039 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); |
1055 | } | 1040 | } |
@@ -1061,11 +1046,60 @@ rescan_this: | |||
1061 | /*-------------------------------------------------------------------------*/ | 1046 | /*-------------------------------------------------------------------------*/ |
1062 | 1047 | ||
1063 | /* | 1048 | /* |
1049 | * Used to take back a TD from the host controller. This would normally be | ||
1050 | * called from within dl_done_list, however it may be called directly if the | ||
1051 | * HC no longer sees the TD and it has not appeared on the donelist (after | ||
1052 | * two frames). This bug has been observed on ZF Micro systems. | ||
1053 | */ | ||
1054 | static void takeback_td(struct ohci_hcd *ohci, struct td *td) | ||
1055 | { | ||
1056 | struct urb *urb = td->urb; | ||
1057 | urb_priv_t *urb_priv = urb->hcpriv; | ||
1058 | struct ed *ed = td->ed; | ||
1059 | int status; | ||
1060 | |||
1061 | /* update URB's length and status from TD */ | ||
1062 | status = td_done(ohci, urb, td); | ||
1063 | urb_priv->td_cnt++; | ||
1064 | |||
1065 | /* If all this urb's TDs are done, call complete() */ | ||
1066 | if (urb_priv->td_cnt == urb_priv->length) | ||
1067 | finish_urb(ohci, urb, status); | ||
1068 | |||
1069 | /* clean schedule: unlink EDs that are no longer busy */ | ||
1070 | if (list_empty(&ed->td_list)) { | ||
1071 | if (ed->state == ED_OPER) | ||
1072 | start_ed_unlink(ohci, ed); | ||
1073 | |||
1074 | /* ... reenabling halted EDs only after fault cleanup */ | ||
1075 | } else if ((ed->hwINFO & cpu_to_hc32(ohci, ED_SKIP | ED_DEQUEUE)) | ||
1076 | == cpu_to_hc32(ohci, ED_SKIP)) { | ||
1077 | td = list_entry(ed->td_list.next, struct td, td_list); | ||
1078 | if (!(td->hwINFO & cpu_to_hc32(ohci, TD_DONE))) { | ||
1079 | ed->hwINFO &= ~cpu_to_hc32(ohci, ED_SKIP); | ||
1080 | /* ... hc may need waking-up */ | ||
1081 | switch (ed->type) { | ||
1082 | case PIPE_CONTROL: | ||
1083 | ohci_writel(ohci, OHCI_CLF, | ||
1084 | &ohci->regs->cmdstatus); | ||
1085 | break; | ||
1086 | case PIPE_BULK: | ||
1087 | ohci_writel(ohci, OHCI_BLF, | ||
1088 | &ohci->regs->cmdstatus); | ||
1089 | break; | ||
1090 | } | ||
1091 | } | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | /* | ||
1064 | * Process normal completions (error or success) and clean the schedules. | 1096 | * Process normal completions (error or success) and clean the schedules. |
1065 | * | 1097 | * |
1066 | * This is the main path for handing urbs back to drivers. The only other | 1098 | * This is the main path for handing urbs back to drivers. The only other |
1067 | * path is finish_unlinks(), which unlinks URBs using ed_rm_list, instead of | 1099 | * normal path is finish_unlinks(), which unlinks URBs using ed_rm_list, |
1068 | * scanning the (re-reversed) donelist as this does. | 1100 | * instead of scanning the (re-reversed) donelist as this does. There's |
1101 | * an abnormal path too, handling a quirk in some Compaq silicon: URBs | ||
1102 | * with TDs that appear to be orphaned are directly reclaimed. | ||
1069 | */ | 1103 | */ |
1070 | static void | 1104 | static void |
1071 | dl_done_list (struct ohci_hcd *ohci) | 1105 | dl_done_list (struct ohci_hcd *ohci) |
@@ -1074,44 +1108,7 @@ dl_done_list (struct ohci_hcd *ohci) | |||
1074 | 1108 | ||
1075 | while (td) { | 1109 | while (td) { |
1076 | struct td *td_next = td->next_dl_td; | 1110 | struct td *td_next = td->next_dl_td; |
1077 | struct urb *urb = td->urb; | 1111 | takeback_td(ohci, td); |
1078 | urb_priv_t *urb_priv = urb->hcpriv; | ||
1079 | struct ed *ed = td->ed; | ||
1080 | |||
1081 | /* update URB's length and status from TD */ | ||
1082 | td_done (ohci, urb, td); | ||
1083 | urb_priv->td_cnt++; | ||
1084 | |||
1085 | /* If all this urb's TDs are done, call complete() */ | ||
1086 | if (urb_priv->td_cnt == urb_priv->length) | ||
1087 | finish_urb (ohci, urb); | ||
1088 | |||
1089 | /* clean schedule: unlink EDs that are no longer busy */ | ||
1090 | if (list_empty (&ed->td_list)) { | ||
1091 | if (ed->state == ED_OPER) | ||
1092 | start_ed_unlink (ohci, ed); | ||
1093 | |||
1094 | /* ... reenabling halted EDs only after fault cleanup */ | ||
1095 | } else if ((ed->hwINFO & cpu_to_hc32 (ohci, | ||
1096 | ED_SKIP | ED_DEQUEUE)) | ||
1097 | == cpu_to_hc32 (ohci, ED_SKIP)) { | ||
1098 | td = list_entry (ed->td_list.next, struct td, td_list); | ||
1099 | if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) { | ||
1100 | ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP); | ||
1101 | /* ... hc may need waking-up */ | ||
1102 | switch (ed->type) { | ||
1103 | case PIPE_CONTROL: | ||
1104 | ohci_writel (ohci, OHCI_CLF, | ||
1105 | &ohci->regs->cmdstatus); | ||
1106 | break; | ||
1107 | case PIPE_BULK: | ||
1108 | ohci_writel (ohci, OHCI_BLF, | ||
1109 | &ohci->regs->cmdstatus); | ||
1110 | break; | ||
1111 | } | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | td = td_next; | 1112 | td = td_next; |
1116 | } | 1113 | } |
1117 | } | 1114 | } |
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c new file mode 100644 index 000000000000..bc3e785d8c00 --- /dev/null +++ b/drivers/usb/host/ohci-ssb.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /* | ||
2 | * Sonics Silicon Backplane | ||
3 | * Broadcom USB-core OHCI driver | ||
4 | * | ||
5 | * Copyright 2007 Michael Buesch <mb@bu3sch.de> | ||
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 | #ifdef CONFIG_PM | ||
64 | static int ssb_ohci_hcd_suspend(struct usb_hcd *hcd, pm_message_t message) | ||
65 | { | ||
66 | struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); | ||
67 | struct ohci_hcd *ohci = &ohcidev->ohci; | ||
68 | unsigned long flags; | ||
69 | |||
70 | spin_lock_irqsave(&ohci->lock, flags); | ||
71 | |||
72 | ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | ||
73 | ohci_readl(ohci, &ohci->regs->intrdisable); /* commit write */ | ||
74 | |||
75 | /* make sure snapshot being resumed re-enumerates everything */ | ||
76 | if (message.event == PM_EVENT_PRETHAW) | ||
77 | ohci_usb_reset(ohci); | ||
78 | |||
79 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
80 | |||
81 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int ssb_ohci_hcd_resume(struct usb_hcd *hcd) | ||
86 | { | ||
87 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
88 | usb_hcd_resume_root_hub(hcd); | ||
89 | return 0; | ||
90 | } | ||
91 | #endif /* CONFIG_PM */ | ||
92 | |||
93 | static const struct hc_driver ssb_ohci_hc_driver = { | ||
94 | .description = "ssb-usb-ohci", | ||
95 | .product_desc = "SSB OHCI Controller", | ||
96 | .hcd_priv_size = sizeof(struct ssb_ohci_device), | ||
97 | |||
98 | .irq = ohci_irq, | ||
99 | .flags = HCD_MEMORY | HCD_USB11, | ||
100 | |||
101 | .reset = ssb_ohci_reset, | ||
102 | .start = ssb_ohci_start, | ||
103 | .stop = ohci_stop, | ||
104 | .shutdown = ohci_shutdown, | ||
105 | |||
106 | #ifdef CONFIG_PM | ||
107 | .suspend = ssb_ohci_hcd_suspend, | ||
108 | .resume = ssb_ohci_hcd_resume, | ||
109 | #endif | ||
110 | |||
111 | .urb_enqueue = ohci_urb_enqueue, | ||
112 | .urb_dequeue = ohci_urb_dequeue, | ||
113 | .endpoint_disable = ohci_endpoint_disable, | ||
114 | |||
115 | .get_frame_number = ohci_get_frame, | ||
116 | |||
117 | .hub_status_data = ohci_hub_status_data, | ||
118 | .hub_control = ohci_hub_control, | ||
119 | .hub_irq_enable = ohci_rhsc_enable, | ||
120 | .bus_suspend = ohci_bus_suspend, | ||
121 | .bus_resume = ohci_bus_resume, | ||
122 | |||
123 | .start_port_reset = ohci_start_port_reset, | ||
124 | }; | ||
125 | |||
126 | static void ssb_ohci_detach(struct ssb_device *dev) | ||
127 | { | ||
128 | struct usb_hcd *hcd = ssb_get_drvdata(dev); | ||
129 | |||
130 | usb_remove_hcd(hcd); | ||
131 | iounmap(hcd->regs); | ||
132 | usb_put_hcd(hcd); | ||
133 | ssb_device_disable(dev, 0); | ||
134 | } | ||
135 | |||
136 | static int ssb_ohci_attach(struct ssb_device *dev) | ||
137 | { | ||
138 | struct ssb_ohci_device *ohcidev; | ||
139 | struct usb_hcd *hcd; | ||
140 | int err = -ENOMEM; | ||
141 | u32 tmp, flags = 0; | ||
142 | |||
143 | if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) | ||
144 | flags |= SSB_OHCI_TMSLOW_HOSTMODE; | ||
145 | |||
146 | ssb_device_enable(dev, flags); | ||
147 | |||
148 | hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev, | ||
149 | dev->dev->bus_id); | ||
150 | if (!hcd) | ||
151 | goto err_dev_disable; | ||
152 | ohcidev = hcd_to_ssb_ohci(hcd); | ||
153 | ohcidev->enable_flags = flags; | ||
154 | |||
155 | tmp = ssb_read32(dev, SSB_ADMATCH0); | ||
156 | hcd->rsrc_start = ssb_admatch_base(tmp); | ||
157 | hcd->rsrc_len = ssb_admatch_size(tmp); | ||
158 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | ||
159 | if (!hcd->regs) | ||
160 | goto err_put_hcd; | ||
161 | err = usb_add_hcd(hcd, dev->irq, IRQF_SHARED); | ||
162 | if (err) | ||
163 | goto err_iounmap; | ||
164 | |||
165 | ssb_set_drvdata(dev, hcd); | ||
166 | |||
167 | return err; | ||
168 | |||
169 | err_iounmap: | ||
170 | iounmap(hcd->regs); | ||
171 | err_put_hcd: | ||
172 | usb_put_hcd(hcd); | ||
173 | err_dev_disable: | ||
174 | ssb_device_disable(dev, flags); | ||
175 | return err; | ||
176 | } | ||
177 | |||
178 | static int ssb_ohci_probe(struct ssb_device *dev, | ||
179 | const struct ssb_device_id *id) | ||
180 | { | ||
181 | int err; | ||
182 | u16 chipid_top; | ||
183 | |||
184 | /* USBcores are only connected on embedded devices. */ | ||
185 | chipid_top = (dev->bus->chip_id & 0xFF00); | ||
186 | if (chipid_top != 0x4700 && chipid_top != 0x5300) | ||
187 | return -ENODEV; | ||
188 | |||
189 | /* TODO: Probably need checks here; is the core connected? */ | ||
190 | |||
191 | if (usb_disabled()) | ||
192 | return -ENODEV; | ||
193 | |||
194 | /* We currently always attach SSB_DEV_USB11_HOSTDEV | ||
195 | * as HOST OHCI. If we want to attach it as Client device, | ||
196 | * we must branch here and call into the (yet to | ||
197 | * be written) Client mode driver. Same for remove(). */ | ||
198 | |||
199 | err = ssb_ohci_attach(dev); | ||
200 | |||
201 | return err; | ||
202 | } | ||
203 | |||
204 | static void ssb_ohci_remove(struct ssb_device *dev) | ||
205 | { | ||
206 | ssb_ohci_detach(dev); | ||
207 | } | ||
208 | |||
209 | #ifdef CONFIG_PM | ||
210 | |||
211 | static int ssb_ohci_suspend(struct ssb_device *dev, pm_message_t state) | ||
212 | { | ||
213 | ssb_device_disable(dev, 0); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static int ssb_ohci_resume(struct ssb_device *dev) | ||
219 | { | ||
220 | struct usb_hcd *hcd = ssb_get_drvdata(dev); | ||
221 | struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); | ||
222 | |||
223 | ssb_device_enable(dev, ohcidev->enable_flags); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | #else /* !CONFIG_PM */ | ||
229 | #define ssb_ohci_suspend NULL | ||
230 | #define ssb_ohci_resume NULL | ||
231 | #endif /* CONFIG_PM */ | ||
232 | |||
233 | static const struct ssb_device_id ssb_ohci_table[] = { | ||
234 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV), | ||
235 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV), | ||
236 | SSB_DEVTABLE_END | ||
237 | }; | ||
238 | MODULE_DEVICE_TABLE(ssb, ssb_ohci_table); | ||
239 | |||
240 | static struct ssb_driver ssb_ohci_driver = { | ||
241 | .name = KBUILD_MODNAME, | ||
242 | .id_table = ssb_ohci_table, | ||
243 | .probe = ssb_ohci_probe, | ||
244 | .remove = ssb_ohci_remove, | ||
245 | .suspend = ssb_ohci_suspend, | ||
246 | .resume = ssb_ohci_resume, | ||
247 | }; | ||
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 4ada43cf1387..47c5c66a282c 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -398,11 +398,38 @@ struct ohci_hcd { | |||
398 | #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ | 398 | #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ |
399 | #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ | 399 | #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ |
400 | #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ | 400 | #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ |
401 | #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ | ||
401 | // there are also chip quirks/bugs in init logic | 402 | // there are also chip quirks/bugs in init logic |
402 | 403 | ||
403 | struct work_struct nec_work; /* Worker for NEC quirk */ | 404 | struct work_struct nec_work; /* Worker for NEC quirk */ |
405 | |||
406 | /* Needed for ZF Micro quirk */ | ||
407 | struct timer_list unlink_watchdog; | ||
408 | unsigned eds_scheduled; | ||
409 | struct ed *ed_to_check; | ||
410 | unsigned zf_delay; | ||
404 | }; | 411 | }; |
405 | 412 | ||
413 | #ifdef CONFIG_PCI | ||
414 | static inline int quirk_nec(struct ohci_hcd *ohci) | ||
415 | { | ||
416 | return ohci->flags & OHCI_QUIRK_NEC; | ||
417 | } | ||
418 | static inline int quirk_zfmicro(struct ohci_hcd *ohci) | ||
419 | { | ||
420 | return ohci->flags & OHCI_QUIRK_ZFMICRO; | ||
421 | } | ||
422 | #else | ||
423 | static inline int quirk_nec(struct ohci_hcd *ohci) | ||
424 | { | ||
425 | return 0; | ||
426 | } | ||
427 | static inline int quirk_zfmicro(struct ohci_hcd *ohci) | ||
428 | { | ||
429 | return 0; | ||
430 | } | ||
431 | #endif | ||
432 | |||
406 | /* convert between an hcd pointer and the corresponding ohci_hcd */ | 433 | /* convert between an hcd pointer and the corresponding ohci_hcd */ |
407 | static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd) | 434 | static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd) |
408 | { | 435 | { |
@@ -607,15 +634,12 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
607 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all | 634 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all |
608 | * hardware handles 16 bit reads. That creates a different confusion on | 635 | * hardware handles 16 bit reads. That creates a different confusion on |
609 | * some big-endian SOC implementations. Same thing happens with PSW access. | 636 | * some big-endian SOC implementations. Same thing happens with PSW access. |
610 | * | ||
611 | * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over | ||
612 | * to arch/powerpc | ||
613 | */ | 637 | */ |
614 | 638 | ||
615 | #ifdef CONFIG_STB03xxx | 639 | #ifdef CONFIG_PPC_MPC52xx |
616 | #define OHCI_BE_FRAME_NO_SHIFT 16 | 640 | #define big_endian_frame_no_quirk(ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO) |
617 | #else | 641 | #else |
618 | #define OHCI_BE_FRAME_NO_SHIFT 0 | 642 | #define big_endian_frame_no_quirk(ohci) 0 |
619 | #endif | 643 | #endif |
620 | 644 | ||
621 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | 645 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) |
@@ -623,7 +647,8 @@ static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | |||
623 | u32 tmp; | 647 | u32 tmp; |
624 | if (big_endian_desc(ohci)) { | 648 | if (big_endian_desc(ohci)) { |
625 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); | 649 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); |
626 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; | 650 | if (!big_endian_frame_no_quirk(ohci)) |
651 | tmp >>= 16; | ||
627 | } else | 652 | } else |
628 | tmp = le32_to_cpup((__force __le32 *)&ohci->hcca->frame_no); | 653 | tmp = le32_to_cpup((__force __le32 *)&ohci->hcca->frame_no); |
629 | 654 | ||
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 40a1de4c256e..ae8ec4474eb8 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -782,10 +782,12 @@ static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address) | |||
782 | kfree(td); | 782 | kfree(td); |
783 | 783 | ||
784 | if (urb) { | 784 | if (urb) { |
785 | urb->status = -ENODEV; | 785 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), |
786 | urb->hcpriv = NULL; | 786 | urb); |
787 | |||
787 | spin_unlock(&r8a66597->lock); | 788 | spin_unlock(&r8a66597->lock); |
788 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb); | 789 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb, |
790 | -ENODEV); | ||
789 | spin_lock(&r8a66597->lock); | 791 | spin_lock(&r8a66597->lock); |
790 | } | 792 | } |
791 | break; | 793 | break; |
@@ -832,7 +834,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, | |||
832 | info.pipenum = get_empty_pipenum(r8a66597, ep); | 834 | info.pipenum = get_empty_pipenum(r8a66597, ep); |
833 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); | 835 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); |
834 | info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 836 | info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; |
835 | info.maxpacket = ep->wMaxPacketSize; | 837 | info.maxpacket = le16_to_cpu(ep->wMaxPacketSize); |
836 | info.type = get_r8a66597_type(ep->bmAttributes | 838 | info.type = get_r8a66597_type(ep->bmAttributes |
837 | & USB_ENDPOINT_XFERTYPE_MASK); | 839 | & USB_ENDPOINT_XFERTYPE_MASK); |
838 | info.bufnum = get_bufnum(info.pipenum); | 840 | info.bufnum = get_bufnum(info.pipenum); |
@@ -923,7 +925,7 @@ static void prepare_setup_packet(struct r8a66597 *r8a66597, | |||
923 | r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1); | 925 | r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1); |
924 | 926 | ||
925 | for (i = 0; i < 4; i++) { | 927 | for (i = 0; i < 4; i++) { |
926 | r8a66597_write(r8a66597, p[i], setup_addr); | 928 | r8a66597_write(r8a66597, cpu_to_le16(p[i]), setup_addr); |
927 | setup_addr += 2; | 929 | setup_addr += 2; |
928 | } | 930 | } |
929 | r8a66597_write(r8a66597, SUREQ, DCPCTR); | 931 | r8a66597_write(r8a66597, SUREQ, DCPCTR); |
@@ -1032,6 +1034,15 @@ static void prepare_status_packet(struct r8a66597 *r8a66597, | |||
1032 | pipe_start(r8a66597, td->pipe); | 1034 | pipe_start(r8a66597, td->pipe); |
1033 | } | 1035 | } |
1034 | 1036 | ||
1037 | static int is_set_address(unsigned char *setup_packet) | ||
1038 | { | ||
1039 | if (((setup_packet[0] & USB_TYPE_MASK) == USB_TYPE_STANDARD) && | ||
1040 | setup_packet[1] == USB_REQ_SET_ADDRESS) | ||
1041 | return 1; | ||
1042 | else | ||
1043 | return 0; | ||
1044 | } | ||
1045 | |||
1035 | /* this function must be called with interrupt disabled */ | 1046 | /* this function must be called with interrupt disabled */ |
1036 | static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td) | 1047 | static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td) |
1037 | { | 1048 | { |
@@ -1039,7 +1050,7 @@ static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td) | |||
1039 | 1050 | ||
1040 | switch (td->type) { | 1051 | switch (td->type) { |
1041 | case USB_PID_SETUP: | 1052 | case USB_PID_SETUP: |
1042 | if (td->urb->setup_packet[1] == USB_REQ_SET_ADDRESS) { | 1053 | if (is_set_address(td->urb->setup_packet)) { |
1043 | td->set_address = 1; | 1054 | td->set_address = 1; |
1044 | td->urb->setup_packet[2] = alloc_usb_address(r8a66597, | 1055 | td->urb->setup_packet[2] = alloc_usb_address(r8a66597, |
1045 | td->urb); | 1056 | td->urb); |
@@ -1106,8 +1117,9 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td) | |||
1106 | } | 1117 | } |
1107 | 1118 | ||
1108 | /* this function must be called with interrupt disabled */ | 1119 | /* this function must be called with interrupt disabled */ |
1109 | static void done(struct r8a66597 *r8a66597, struct r8a66597_td *td, | 1120 | static void finish_request(struct r8a66597 *r8a66597, struct r8a66597_td *td, |
1110 | u16 pipenum, struct urb *urb) | 1121 | u16 pipenum, struct urb *urb, int status) |
1122 | __releases(r8a66597->lock) __acquires(r8a66597->lock) | ||
1111 | { | 1123 | { |
1112 | int restart = 0; | 1124 | int restart = 0; |
1113 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); | 1125 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); |
@@ -1115,7 +1127,7 @@ static void done(struct r8a66597 *r8a66597, struct r8a66597_td *td, | |||
1115 | r8a66597->timeout_map &= ~(1 << pipenum); | 1127 | r8a66597->timeout_map &= ~(1 << pipenum); |
1116 | 1128 | ||
1117 | if (likely(td)) { | 1129 | if (likely(td)) { |
1118 | if (td->set_address && urb->status != 0) | 1130 | if (td->set_address && (status != 0 || urb->unlinked)) |
1119 | r8a66597->address_map &= ~(1 << urb->setup_packet[2]); | 1131 | r8a66597->address_map &= ~(1 << urb->setup_packet[2]); |
1120 | 1132 | ||
1121 | pipe_toggle_save(r8a66597, td->pipe, urb); | 1133 | pipe_toggle_save(r8a66597, td->pipe, urb); |
@@ -1130,9 +1142,9 @@ static void done(struct r8a66597 *r8a66597, struct r8a66597_td *td, | |||
1130 | if (usb_pipeisoc(urb->pipe)) | 1142 | if (usb_pipeisoc(urb->pipe)) |
1131 | urb->start_frame = r8a66597_get_frame(hcd); | 1143 | urb->start_frame = r8a66597_get_frame(hcd); |
1132 | 1144 | ||
1133 | urb->hcpriv = NULL; | 1145 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); |
1134 | spin_unlock(&r8a66597->lock); | 1146 | spin_unlock(&r8a66597->lock); |
1135 | usb_hcd_giveback_urb(hcd, urb); | 1147 | usb_hcd_giveback_urb(hcd, urb, status); |
1136 | spin_lock(&r8a66597->lock); | 1148 | spin_lock(&r8a66597->lock); |
1137 | } | 1149 | } |
1138 | 1150 | ||
@@ -1146,14 +1158,6 @@ static void done(struct r8a66597 *r8a66597, struct r8a66597_td *td, | |||
1146 | } | 1158 | } |
1147 | } | 1159 | } |
1148 | 1160 | ||
1149 | /* this function must be called with interrupt disabled */ | ||
1150 | static void finish_request(struct r8a66597 *r8a66597, struct r8a66597_td *td, | ||
1151 | u16 pipenum, struct urb *urb) | ||
1152 | __releases(r8a66597->lock) __acquires(r8a66597->lock) | ||
1153 | { | ||
1154 | done(r8a66597, td, pipenum, urb); | ||
1155 | } | ||
1156 | |||
1157 | static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | 1161 | static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) |
1158 | { | 1162 | { |
1159 | u16 tmp; | 1163 | u16 tmp; |
@@ -1162,6 +1166,7 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | |||
1162 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum); | 1166 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum); |
1163 | struct urb *urb; | 1167 | struct urb *urb; |
1164 | int finish = 0; | 1168 | int finish = 0; |
1169 | int status = 0; | ||
1165 | 1170 | ||
1166 | if (unlikely(!td)) | 1171 | if (unlikely(!td)) |
1167 | return; | 1172 | return; |
@@ -1170,17 +1175,15 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | |||
1170 | fifo_change_from_pipe(r8a66597, td->pipe); | 1175 | fifo_change_from_pipe(r8a66597, td->pipe); |
1171 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); | 1176 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); |
1172 | if (unlikely((tmp & FRDY) == 0)) { | 1177 | if (unlikely((tmp & FRDY) == 0)) { |
1173 | urb->status = -EPIPE; | ||
1174 | pipe_stop(r8a66597, td->pipe); | 1178 | pipe_stop(r8a66597, td->pipe); |
1175 | pipe_irq_disable(r8a66597, pipenum); | 1179 | pipe_irq_disable(r8a66597, pipenum); |
1176 | err("in fifo not ready (%d)", pipenum); | 1180 | err("in fifo not ready (%d)", pipenum); |
1177 | finish_request(r8a66597, td, pipenum, td->urb); | 1181 | finish_request(r8a66597, td, pipenum, td->urb, -EPIPE); |
1178 | return; | 1182 | return; |
1179 | } | 1183 | } |
1180 | 1184 | ||
1181 | /* prepare parameters */ | 1185 | /* prepare parameters */ |
1182 | rcv_len = tmp & DTLN; | 1186 | rcv_len = tmp & DTLN; |
1183 | bufsize = td->maxpacket; | ||
1184 | if (usb_pipeisoc(urb->pipe)) { | 1187 | if (usb_pipeisoc(urb->pipe)) { |
1185 | buf = (u16 *)(urb->transfer_buffer + | 1188 | buf = (u16 *)(urb->transfer_buffer + |
1186 | urb->iso_frame_desc[td->iso_cnt].offset); | 1189 | urb->iso_frame_desc[td->iso_cnt].offset); |
@@ -1189,29 +1192,31 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | |||
1189 | buf = (void *)urb->transfer_buffer + urb->actual_length; | 1192 | buf = (void *)urb->transfer_buffer + urb->actual_length; |
1190 | urb_len = urb->transfer_buffer_length - urb->actual_length; | 1193 | urb_len = urb->transfer_buffer_length - urb->actual_length; |
1191 | } | 1194 | } |
1192 | if (rcv_len < bufsize) | 1195 | bufsize = min(urb_len, (int) td->maxpacket); |
1193 | size = min(rcv_len, urb_len); | 1196 | if (rcv_len <= bufsize) { |
1194 | else | 1197 | size = rcv_len; |
1195 | size = min(bufsize, urb_len); | 1198 | } else { |
1199 | size = bufsize; | ||
1200 | status = -EOVERFLOW; | ||
1201 | finish = 1; | ||
1202 | } | ||
1196 | 1203 | ||
1197 | /* update parameters */ | 1204 | /* update parameters */ |
1198 | urb->actual_length += size; | 1205 | urb->actual_length += size; |
1199 | if (rcv_len == 0) | 1206 | if (rcv_len == 0) |
1200 | td->zero_packet = 1; | 1207 | td->zero_packet = 1; |
1201 | if ((size % td->maxpacket) > 0) { | 1208 | if (rcv_len < bufsize) { |
1202 | td->short_packet = 1; | 1209 | td->short_packet = 1; |
1203 | if (urb->transfer_buffer_length != urb->actual_length && | ||
1204 | urb->transfer_flags & URB_SHORT_NOT_OK) | ||
1205 | td->urb->status = -EREMOTEIO; | ||
1206 | } | 1210 | } |
1207 | if (usb_pipeisoc(urb->pipe)) { | 1211 | if (usb_pipeisoc(urb->pipe)) { |
1208 | urb->iso_frame_desc[td->iso_cnt].actual_length = size; | 1212 | urb->iso_frame_desc[td->iso_cnt].actual_length = size; |
1209 | urb->iso_frame_desc[td->iso_cnt].status = 0; | 1213 | urb->iso_frame_desc[td->iso_cnt].status = status; |
1210 | td->iso_cnt++; | 1214 | td->iso_cnt++; |
1215 | finish = 0; | ||
1211 | } | 1216 | } |
1212 | 1217 | ||
1213 | /* check transfer finish */ | 1218 | /* check transfer finish */ |
1214 | if (check_transfer_finish(td, urb)) { | 1219 | if (finish || check_transfer_finish(td, urb)) { |
1215 | pipe_stop(r8a66597, td->pipe); | 1220 | pipe_stop(r8a66597, td->pipe); |
1216 | pipe_irq_disable(r8a66597, pipenum); | 1221 | pipe_irq_disable(r8a66597, pipenum); |
1217 | finish = 1; | 1222 | finish = 1; |
@@ -1226,11 +1231,8 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | |||
1226 | buf, size); | 1231 | buf, size); |
1227 | } | 1232 | } |
1228 | 1233 | ||
1229 | if (finish && pipenum != 0) { | 1234 | if (finish && pipenum != 0) |
1230 | if (td->urb->status == -EINPROGRESS) | 1235 | finish_request(r8a66597, td, pipenum, urb, status); |
1231 | td->urb->status = 0; | ||
1232 | finish_request(r8a66597, td, pipenum, urb); | ||
1233 | } | ||
1234 | } | 1236 | } |
1235 | 1237 | ||
1236 | static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | 1238 | static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) |
@@ -1248,11 +1250,10 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | |||
1248 | fifo_change_from_pipe(r8a66597, td->pipe); | 1250 | fifo_change_from_pipe(r8a66597, td->pipe); |
1249 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); | 1251 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); |
1250 | if (unlikely((tmp & FRDY) == 0)) { | 1252 | if (unlikely((tmp & FRDY) == 0)) { |
1251 | urb->status = -EPIPE; | ||
1252 | pipe_stop(r8a66597, td->pipe); | 1253 | pipe_stop(r8a66597, td->pipe); |
1253 | pipe_irq_disable(r8a66597, pipenum); | 1254 | pipe_irq_disable(r8a66597, pipenum); |
1254 | err("out write fifo not ready. (%d)", pipenum); | 1255 | err("out write fifo not ready. (%d)", pipenum); |
1255 | finish_request(r8a66597, td, pipenum, td->urb); | 1256 | finish_request(r8a66597, td, pipenum, urb, -EPIPE); |
1256 | return; | 1257 | return; |
1257 | } | 1258 | } |
1258 | 1259 | ||
@@ -1297,7 +1298,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | |||
1297 | } | 1298 | } |
1298 | 1299 | ||
1299 | 1300 | ||
1300 | static void check_next_phase(struct r8a66597 *r8a66597) | 1301 | static void check_next_phase(struct r8a66597 *r8a66597, int status) |
1301 | { | 1302 | { |
1302 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, 0); | 1303 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, 0); |
1303 | struct urb *urb; | 1304 | struct urb *urb; |
@@ -1310,49 +1311,41 @@ static void check_next_phase(struct r8a66597 *r8a66597) | |||
1310 | switch (td->type) { | 1311 | switch (td->type) { |
1311 | case USB_PID_IN: | 1312 | case USB_PID_IN: |
1312 | case USB_PID_OUT: | 1313 | case USB_PID_OUT: |
1313 | if (urb->status != -EINPROGRESS) { | ||
1314 | finish = 1; | ||
1315 | break; | ||
1316 | } | ||
1317 | if (check_transfer_finish(td, urb)) | 1314 | if (check_transfer_finish(td, urb)) |
1318 | td->type = USB_PID_ACK; | 1315 | td->type = USB_PID_ACK; |
1319 | break; | 1316 | break; |
1320 | case USB_PID_SETUP: | 1317 | case USB_PID_SETUP: |
1321 | if (urb->status != -EINPROGRESS) | 1318 | if (urb->transfer_buffer_length == urb->actual_length) |
1322 | finish = 1; | ||
1323 | else if (urb->transfer_buffer_length == urb->actual_length) { | ||
1324 | td->type = USB_PID_ACK; | 1319 | td->type = USB_PID_ACK; |
1325 | urb->status = 0; | 1320 | else if (usb_pipeout(urb->pipe)) |
1326 | } else if (usb_pipeout(urb->pipe)) | ||
1327 | td->type = USB_PID_OUT; | 1321 | td->type = USB_PID_OUT; |
1328 | else | 1322 | else |
1329 | td->type = USB_PID_IN; | 1323 | td->type = USB_PID_IN; |
1330 | break; | 1324 | break; |
1331 | case USB_PID_ACK: | 1325 | case USB_PID_ACK: |
1332 | finish = 1; | 1326 | finish = 1; |
1333 | if (urb->status == -EINPROGRESS) | ||
1334 | urb->status = 0; | ||
1335 | break; | 1327 | break; |
1336 | } | 1328 | } |
1337 | 1329 | ||
1338 | if (finish) | 1330 | if (finish || status != 0 || urb->unlinked) |
1339 | finish_request(r8a66597, td, 0, urb); | 1331 | finish_request(r8a66597, td, 0, urb, status); |
1340 | else | 1332 | else |
1341 | start_transfer(r8a66597, td); | 1333 | start_transfer(r8a66597, td); |
1342 | } | 1334 | } |
1343 | 1335 | ||
1344 | static void set_urb_error(struct r8a66597 *r8a66597, u16 pipenum) | 1336 | static int get_urb_error(struct r8a66597 *r8a66597, u16 pipenum) |
1345 | { | 1337 | { |
1346 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum); | 1338 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum); |
1347 | 1339 | ||
1348 | if (td && td->urb) { | 1340 | if (td) { |
1349 | u16 pid = r8a66597_read(r8a66597, td->pipe->pipectr) & PID; | 1341 | u16 pid = r8a66597_read(r8a66597, td->pipe->pipectr) & PID; |
1350 | 1342 | ||
1351 | if (pid == PID_NAK) | 1343 | if (pid == PID_NAK) |
1352 | td->urb->status = -ECONNRESET; | 1344 | return -ECONNRESET; |
1353 | else | 1345 | else |
1354 | td->urb->status = -EPIPE; | 1346 | return -EPIPE; |
1355 | } | 1347 | } |
1348 | return 0; | ||
1356 | } | 1349 | } |
1357 | 1350 | ||
1358 | static void irq_pipe_ready(struct r8a66597 *r8a66597) | 1351 | static void irq_pipe_ready(struct r8a66597 *r8a66597) |
@@ -1371,7 +1364,7 @@ static void irq_pipe_ready(struct r8a66597 *r8a66597) | |||
1371 | packet_read(r8a66597, 0); | 1364 | packet_read(r8a66597, 0); |
1372 | else | 1365 | else |
1373 | pipe_irq_disable(r8a66597, 0); | 1366 | pipe_irq_disable(r8a66597, 0); |
1374 | check_next_phase(r8a66597); | 1367 | check_next_phase(r8a66597, 0); |
1375 | } | 1368 | } |
1376 | 1369 | ||
1377 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { | 1370 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { |
@@ -1405,7 +1398,7 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597) | |||
1405 | td = r8a66597_get_td(r8a66597, 0); | 1398 | td = r8a66597_get_td(r8a66597, 0); |
1406 | if (td && td->type != USB_PID_OUT) | 1399 | if (td && td->type != USB_PID_OUT) |
1407 | disable_irq_empty(r8a66597, 0); | 1400 | disable_irq_empty(r8a66597, 0); |
1408 | check_next_phase(r8a66597); | 1401 | check_next_phase(r8a66597, 0); |
1409 | } | 1402 | } |
1410 | 1403 | ||
1411 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { | 1404 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { |
@@ -1420,9 +1413,8 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597) | |||
1420 | if ((tmp & INBUFM) == 0) { | 1413 | if ((tmp & INBUFM) == 0) { |
1421 | disable_irq_empty(r8a66597, pipenum); | 1414 | disable_irq_empty(r8a66597, pipenum); |
1422 | pipe_irq_disable(r8a66597, pipenum); | 1415 | pipe_irq_disable(r8a66597, pipenum); |
1423 | if (td->urb->status == -EINPROGRESS) | 1416 | finish_request(r8a66597, td, pipenum, td->urb, |
1424 | td->urb->status = 0; | 1417 | 0); |
1425 | finish_request(r8a66597, td, pipenum, td->urb); | ||
1426 | } | 1418 | } |
1427 | } | 1419 | } |
1428 | } | 1420 | } |
@@ -1433,15 +1425,16 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) | |||
1433 | u16 check; | 1425 | u16 check; |
1434 | u16 pipenum; | 1426 | u16 pipenum; |
1435 | u16 mask; | 1427 | u16 mask; |
1428 | int status; | ||
1436 | 1429 | ||
1437 | mask = r8a66597_read(r8a66597, NRDYSTS) | 1430 | mask = r8a66597_read(r8a66597, NRDYSTS) |
1438 | & r8a66597_read(r8a66597, NRDYENB); | 1431 | & r8a66597_read(r8a66597, NRDYENB); |
1439 | r8a66597_write(r8a66597, ~mask, NRDYSTS); | 1432 | r8a66597_write(r8a66597, ~mask, NRDYSTS); |
1440 | if (mask & NRDY0) { | 1433 | if (mask & NRDY0) { |
1441 | cfifo_change(r8a66597, 0); | 1434 | cfifo_change(r8a66597, 0); |
1442 | set_urb_error(r8a66597, 0); | 1435 | status = get_urb_error(r8a66597, 0); |
1443 | pipe_irq_disable(r8a66597, 0); | 1436 | pipe_irq_disable(r8a66597, 0); |
1444 | check_next_phase(r8a66597); | 1437 | check_next_phase(r8a66597, status); |
1445 | } | 1438 | } |
1446 | 1439 | ||
1447 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { | 1440 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { |
@@ -1452,10 +1445,10 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) | |||
1452 | if (unlikely(!td)) | 1445 | if (unlikely(!td)) |
1453 | continue; | 1446 | continue; |
1454 | 1447 | ||
1455 | set_urb_error(r8a66597, pipenum); | 1448 | status = get_urb_error(r8a66597, pipenum); |
1456 | pipe_irq_disable(r8a66597, pipenum); | 1449 | pipe_irq_disable(r8a66597, pipenum); |
1457 | pipe_stop(r8a66597, td->pipe); | 1450 | pipe_stop(r8a66597, td->pipe); |
1458 | finish_request(r8a66597, td, pipenum, td->urb); | 1451 | finish_request(r8a66597, td, pipenum, td->urb, status); |
1459 | } | 1452 | } |
1460 | } | 1453 | } |
1461 | } | 1454 | } |
@@ -1475,6 +1468,7 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1475 | u16 intsts0, intsts1, intsts2; | 1468 | u16 intsts0, intsts1, intsts2; |
1476 | u16 intenb0, intenb1, intenb2; | 1469 | u16 intenb0, intenb1, intenb2; |
1477 | u16 mask0, mask1, mask2; | 1470 | u16 mask0, mask1, mask2; |
1471 | int status; | ||
1478 | 1472 | ||
1479 | spin_lock(&r8a66597->lock); | 1473 | spin_lock(&r8a66597->lock); |
1480 | 1474 | ||
@@ -1518,12 +1512,12 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1518 | } | 1512 | } |
1519 | if (mask1 & SIGN) { | 1513 | if (mask1 & SIGN) { |
1520 | r8a66597_write(r8a66597, ~SIGN, INTSTS1); | 1514 | r8a66597_write(r8a66597, ~SIGN, INTSTS1); |
1521 | set_urb_error(r8a66597, 0); | 1515 | status = get_urb_error(r8a66597, 0); |
1522 | check_next_phase(r8a66597); | 1516 | check_next_phase(r8a66597, status); |
1523 | } | 1517 | } |
1524 | if (mask1 & SACK) { | 1518 | if (mask1 & SACK) { |
1525 | r8a66597_write(r8a66597, ~SACK, INTSTS1); | 1519 | r8a66597_write(r8a66597, ~SACK, INTSTS1); |
1526 | check_next_phase(r8a66597); | 1520 | check_next_phase(r8a66597, 0); |
1527 | } | 1521 | } |
1528 | } | 1522 | } |
1529 | if (mask0) { | 1523 | if (mask0) { |
@@ -1722,21 +1716,25 @@ static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597, | |||
1722 | } | 1716 | } |
1723 | 1717 | ||
1724 | static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | 1718 | static int r8a66597_urb_enqueue(struct usb_hcd *hcd, |
1725 | struct usb_host_endpoint *hep, | ||
1726 | struct urb *urb, | 1719 | struct urb *urb, |
1727 | gfp_t mem_flags) | 1720 | gfp_t mem_flags) |
1728 | { | 1721 | { |
1722 | struct usb_host_endpoint *hep = urb->ep; | ||
1729 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | 1723 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); |
1730 | struct r8a66597_td *td = NULL; | 1724 | struct r8a66597_td *td = NULL; |
1731 | int ret = 0, request = 0; | 1725 | int ret, request = 0; |
1732 | unsigned long flags; | 1726 | unsigned long flags; |
1733 | 1727 | ||
1734 | spin_lock_irqsave(&r8a66597->lock, flags); | 1728 | spin_lock_irqsave(&r8a66597->lock, flags); |
1735 | if (!get_urb_to_r8a66597_dev(r8a66597, urb)) { | 1729 | if (!get_urb_to_r8a66597_dev(r8a66597, urb)) { |
1736 | ret = -ENODEV; | 1730 | ret = -ENODEV; |
1737 | goto error; | 1731 | goto error_not_linked; |
1738 | } | 1732 | } |
1739 | 1733 | ||
1734 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
1735 | if (ret) | ||
1736 | goto error_not_linked; | ||
1737 | |||
1740 | if (!hep->hcpriv) { | 1738 | if (!hep->hcpriv) { |
1741 | hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), | 1739 | hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), |
1742 | GFP_ATOMIC); | 1740 | GFP_ATOMIC); |
@@ -1761,15 +1759,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | |||
1761 | if (list_empty(&r8a66597->pipe_queue[td->pipenum])) | 1759 | if (list_empty(&r8a66597->pipe_queue[td->pipenum])) |
1762 | request = 1; | 1760 | request = 1; |
1763 | list_add_tail(&td->queue, &r8a66597->pipe_queue[td->pipenum]); | 1761 | list_add_tail(&td->queue, &r8a66597->pipe_queue[td->pipenum]); |
1764 | |||
1765 | spin_lock(&urb->lock); | ||
1766 | if (urb->status != -EINPROGRESS) { | ||
1767 | spin_unlock(&urb->lock); | ||
1768 | ret = -EPIPE; | ||
1769 | goto error; | ||
1770 | } | ||
1771 | urb->hcpriv = td; | 1762 | urb->hcpriv = td; |
1772 | spin_unlock(&urb->lock); | ||
1773 | 1763 | ||
1774 | if (request) { | 1764 | if (request) { |
1775 | ret = start_transfer(r8a66597, td); | 1765 | ret = start_transfer(r8a66597, td); |
@@ -1781,26 +1771,36 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | |||
1781 | set_td_timer(r8a66597, td); | 1771 | set_td_timer(r8a66597, td); |
1782 | 1772 | ||
1783 | error: | 1773 | error: |
1774 | if (ret) | ||
1775 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
1776 | error_not_linked: | ||
1784 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 1777 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
1785 | return ret; | 1778 | return ret; |
1786 | } | 1779 | } |
1787 | 1780 | ||
1788 | static int r8a66597_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 1781 | static int r8a66597_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, |
1782 | int status) | ||
1789 | { | 1783 | { |
1790 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | 1784 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); |
1791 | struct r8a66597_td *td; | 1785 | struct r8a66597_td *td; |
1792 | unsigned long flags; | 1786 | unsigned long flags; |
1787 | int rc; | ||
1793 | 1788 | ||
1794 | spin_lock_irqsave(&r8a66597->lock, flags); | 1789 | spin_lock_irqsave(&r8a66597->lock, flags); |
1790 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
1791 | if (rc) | ||
1792 | goto done; | ||
1793 | |||
1795 | if (urb->hcpriv) { | 1794 | if (urb->hcpriv) { |
1796 | td = urb->hcpriv; | 1795 | td = urb->hcpriv; |
1797 | pipe_stop(r8a66597, td->pipe); | 1796 | pipe_stop(r8a66597, td->pipe); |
1798 | pipe_irq_disable(r8a66597, td->pipenum); | 1797 | pipe_irq_disable(r8a66597, td->pipenum); |
1799 | disable_irq_empty(r8a66597, td->pipenum); | 1798 | disable_irq_empty(r8a66597, td->pipenum); |
1800 | done(r8a66597, td, td->pipenum, urb); | 1799 | finish_request(r8a66597, td, td->pipenum, urb, status); |
1801 | } | 1800 | } |
1801 | done: | ||
1802 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 1802 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
1803 | return 0; | 1803 | return rc; |
1804 | } | 1804 | } |
1805 | 1805 | ||
1806 | static void r8a66597_endpoint_disable(struct usb_hcd *hcd, | 1806 | static void r8a66597_endpoint_disable(struct usb_hcd *hcd, |
@@ -1830,7 +1830,7 @@ static void r8a66597_endpoint_disable(struct usb_hcd *hcd, | |||
1830 | td = r8a66597_get_td(r8a66597, pipenum); | 1830 | td = r8a66597_get_td(r8a66597, pipenum); |
1831 | if (td) | 1831 | if (td) |
1832 | urb = td->urb; | 1832 | urb = td->urb; |
1833 | done(r8a66597, td, pipenum, urb); | 1833 | finish_request(r8a66597, td, pipenum, urb, -ESHUTDOWN); |
1834 | kfree(hep->hcpriv); | 1834 | kfree(hep->hcpriv); |
1835 | hep->hcpriv = NULL; | 1835 | hep->hcpriv = NULL; |
1836 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 1836 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
@@ -2027,7 +2027,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2027 | case GetPortStatus: | 2027 | case GetPortStatus: |
2028 | if (wIndex > R8A66597_MAX_ROOT_HUB) | 2028 | if (wIndex > R8A66597_MAX_ROOT_HUB) |
2029 | goto error; | 2029 | goto error; |
2030 | *(u32 *)buf = rh->port; | 2030 | *(u32 *)buf = cpu_to_le32(rh->port); |
2031 | break; | 2031 | break; |
2032 | case SetPortFeature: | 2032 | case SetPortFeature: |
2033 | if (wIndex > R8A66597_MAX_ROOT_HUB) | 2033 | if (wIndex > R8A66597_MAX_ROOT_HUB) |
@@ -2126,8 +2126,8 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev) | |||
2126 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); | 2126 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); |
2127 | 2127 | ||
2128 | del_timer_sync(&r8a66597->rh_timer); | 2128 | del_timer_sync(&r8a66597->rh_timer); |
2129 | iounmap((void *)r8a66597->reg); | ||
2130 | usb_remove_hcd(hcd); | 2129 | usb_remove_hcd(hcd); |
2130 | iounmap((void *)r8a66597->reg); | ||
2131 | usb_put_hcd(hcd); | 2131 | usb_put_hcd(hcd); |
2132 | return 0; | 2132 | return 0; |
2133 | } | 2133 | } |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 4cfa3ff2c993..94d859aa73f8 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -435,14 +435,9 @@ static void finish_request( | |||
435 | if (usb_pipecontrol(urb->pipe)) | 435 | if (usb_pipecontrol(urb->pipe)) |
436 | ep->nextpid = USB_PID_SETUP; | 436 | ep->nextpid = USB_PID_SETUP; |
437 | 437 | ||
438 | spin_lock(&urb->lock); | 438 | usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb); |
439 | if (urb->status == -EINPROGRESS) | ||
440 | urb->status = status; | ||
441 | urb->hcpriv = NULL; | ||
442 | spin_unlock(&urb->lock); | ||
443 | |||
444 | spin_unlock(&sl811->lock); | 439 | spin_unlock(&sl811->lock); |
445 | usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb); | 440 | usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, status); |
446 | spin_lock(&sl811->lock); | 441 | spin_lock(&sl811->lock); |
447 | 442 | ||
448 | /* leave active endpoints in the schedule */ | 443 | /* leave active endpoints in the schedule */ |
@@ -538,35 +533,21 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank) | |||
538 | bank + SL11H_XFERCNTREG); | 533 | bank + SL11H_XFERCNTREG); |
539 | if (len > ep->length) { | 534 | if (len > ep->length) { |
540 | len = ep->length; | 535 | len = ep->length; |
541 | urb->status = -EOVERFLOW; | 536 | urbstat = -EOVERFLOW; |
542 | } | 537 | } |
543 | urb->actual_length += len; | 538 | urb->actual_length += len; |
544 | sl811_read_buf(sl811, SL811HS_PACKET_BUF(bank == 0), | 539 | sl811_read_buf(sl811, SL811HS_PACKET_BUF(bank == 0), |
545 | buf, len); | 540 | buf, len); |
546 | usb_dotoggle(udev, ep->epnum, 0); | 541 | usb_dotoggle(udev, ep->epnum, 0); |
547 | if (urb->actual_length == urb->transfer_buffer_length) | 542 | if (urbstat == -EINPROGRESS && |
548 | urbstat = 0; | 543 | (len < ep->maxpacket || |
549 | else if (len < ep->maxpacket) { | 544 | urb->actual_length == |
550 | if (urb->transfer_flags & URB_SHORT_NOT_OK) | 545 | urb->transfer_buffer_length)) { |
551 | urbstat = -EREMOTEIO; | 546 | if (usb_pipecontrol(urb->pipe)) |
547 | ep->nextpid = USB_PID_ACK; | ||
552 | else | 548 | else |
553 | urbstat = 0; | 549 | urbstat = 0; |
554 | } | 550 | } |
555 | if (usb_pipecontrol(urb->pipe) | ||
556 | && (urbstat == -EREMOTEIO | ||
557 | || urbstat == 0)) { | ||
558 | |||
559 | /* NOTE if the status stage STALLs (why?), | ||
560 | * this reports the wrong urb status. | ||
561 | */ | ||
562 | spin_lock(&urb->lock); | ||
563 | if (urb->status == -EINPROGRESS) | ||
564 | urb->status = urbstat; | ||
565 | spin_unlock(&urb->lock); | ||
566 | |||
567 | urb = NULL; | ||
568 | ep->nextpid = USB_PID_ACK; | ||
569 | } | ||
570 | break; | 551 | break; |
571 | case USB_PID_SETUP: | 552 | case USB_PID_SETUP: |
572 | // PACKET("...ACK/setup_%02x qh%p\n", bank, ep); | 553 | // PACKET("...ACK/setup_%02x qh%p\n", bank, ep); |
@@ -605,7 +586,7 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank) | |||
605 | bank, status, ep, urbstat); | 586 | bank, status, ep, urbstat); |
606 | } | 587 | } |
607 | 588 | ||
608 | if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS)) | 589 | if (urbstat != -EINPROGRESS || urb->unlinked) |
609 | finish_request(sl811, ep, urb, urbstat); | 590 | finish_request(sl811, ep, urb, urbstat); |
610 | } | 591 | } |
611 | 592 | ||
@@ -807,7 +788,6 @@ static int balance(struct sl811 *sl811, u16 period, u16 load) | |||
807 | 788 | ||
808 | static int sl811h_urb_enqueue( | 789 | static int sl811h_urb_enqueue( |
809 | struct usb_hcd *hcd, | 790 | struct usb_hcd *hcd, |
810 | struct usb_host_endpoint *hep, | ||
811 | struct urb *urb, | 791 | struct urb *urb, |
812 | gfp_t mem_flags | 792 | gfp_t mem_flags |
813 | ) { | 793 | ) { |
@@ -820,7 +800,8 @@ static int sl811h_urb_enqueue( | |||
820 | struct sl811h_ep *ep = NULL; | 800 | struct sl811h_ep *ep = NULL; |
821 | unsigned long flags; | 801 | unsigned long flags; |
822 | int i; | 802 | int i; |
823 | int retval = 0; | 803 | int retval; |
804 | struct usb_host_endpoint *hep = urb->ep; | ||
824 | 805 | ||
825 | #ifdef DISABLE_ISO | 806 | #ifdef DISABLE_ISO |
826 | if (type == PIPE_ISOCHRONOUS) | 807 | if (type == PIPE_ISOCHRONOUS) |
@@ -838,7 +819,12 @@ static int sl811h_urb_enqueue( | |||
838 | || !HC_IS_RUNNING(hcd->state)) { | 819 | || !HC_IS_RUNNING(hcd->state)) { |
839 | retval = -ENODEV; | 820 | retval = -ENODEV; |
840 | kfree(ep); | 821 | kfree(ep); |
841 | goto fail; | 822 | goto fail_not_linked; |
823 | } | ||
824 | retval = usb_hcd_link_urb_to_ep(hcd, urb); | ||
825 | if (retval) { | ||
826 | kfree(ep); | ||
827 | goto fail_not_linked; | ||
842 | } | 828 | } |
843 | 829 | ||
844 | if (hep->hcpriv) { | 830 | if (hep->hcpriv) { |
@@ -951,37 +937,31 @@ static int sl811h_urb_enqueue( | |||
951 | sofirq_on(sl811); | 937 | sofirq_on(sl811); |
952 | } | 938 | } |
953 | 939 | ||
954 | /* in case of unlink-during-submit */ | ||
955 | spin_lock(&urb->lock); | ||
956 | if (urb->status != -EINPROGRESS) { | ||
957 | spin_unlock(&urb->lock); | ||
958 | finish_request(sl811, ep, urb, 0); | ||
959 | retval = 0; | ||
960 | goto fail; | ||
961 | } | ||
962 | urb->hcpriv = hep; | 940 | urb->hcpriv = hep; |
963 | spin_unlock(&urb->lock); | ||
964 | |||
965 | start_transfer(sl811); | 941 | start_transfer(sl811); |
966 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); | 942 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); |
967 | fail: | 943 | fail: |
944 | if (retval) | ||
945 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
946 | fail_not_linked: | ||
968 | spin_unlock_irqrestore(&sl811->lock, flags); | 947 | spin_unlock_irqrestore(&sl811->lock, flags); |
969 | return retval; | 948 | return retval; |
970 | } | 949 | } |
971 | 950 | ||
972 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 951 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
973 | { | 952 | { |
974 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 953 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
975 | struct usb_host_endpoint *hep; | 954 | struct usb_host_endpoint *hep; |
976 | unsigned long flags; | 955 | unsigned long flags; |
977 | struct sl811h_ep *ep; | 956 | struct sl811h_ep *ep; |
978 | int retval = 0; | 957 | int retval; |
979 | 958 | ||
980 | spin_lock_irqsave(&sl811->lock, flags); | 959 | spin_lock_irqsave(&sl811->lock, flags); |
981 | hep = urb->hcpriv; | 960 | retval = usb_hcd_check_unlink_urb(hcd, urb, status); |
982 | if (!hep) | 961 | if (retval) |
983 | goto fail; | 962 | goto fail; |
984 | 963 | ||
964 | hep = urb->hcpriv; | ||
985 | ep = hep->hcpriv; | 965 | ep = hep->hcpriv; |
986 | if (ep) { | 966 | if (ep) { |
987 | /* finish right away if this urb can't be active ... | 967 | /* finish right away if this urb can't be active ... |
@@ -1029,8 +1009,8 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
1029 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, | 1009 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, |
1030 | (sl811->active_a == ep) ? "A" : "B"); | 1010 | (sl811->active_a == ep) ? "A" : "B"); |
1031 | } else | 1011 | } else |
1032 | fail: | ||
1033 | retval = -EINVAL; | 1012 | retval = -EINVAL; |
1013 | fail: | ||
1034 | spin_unlock_irqrestore(&sl811->lock, flags); | 1014 | spin_unlock_irqrestore(&sl811->lock, flags); |
1035 | return retval; | 1015 | return retval; |
1036 | } | 1016 | } |
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index b88eb3c62c02..ac283b09a63f 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #include <linux/usb.h> | 51 | #include <linux/usb.h> |
52 | #include <linux/workqueue.h> | 52 | #include <linux/workqueue.h> |
53 | #include <linux/platform_device.h> | 53 | #include <linux/platform_device.h> |
54 | #include <linux/pci_ids.h> | ||
55 | #include <linux/mutex.h> | 54 | #include <linux/mutex.h> |
56 | #include <asm/io.h> | 55 | #include <asm/io.h> |
57 | #include <asm/irq.h> | 56 | #include <asm/irq.h> |
@@ -184,7 +183,7 @@ struct u132_ring { | |||
184 | struct u132 { | 183 | struct u132 { |
185 | struct kref kref; | 184 | struct kref kref; |
186 | struct list_head u132_list; | 185 | struct list_head u132_list; |
187 | struct semaphore sw_lock; | 186 | struct mutex sw_lock; |
188 | struct semaphore scheduler_lock; | 187 | struct semaphore scheduler_lock; |
189 | struct u132_platform_data *board; | 188 | struct u132_platform_data *board; |
190 | struct platform_device *platform_dev; | 189 | struct platform_device *platform_dev; |
@@ -493,20 +492,20 @@ static void u132_hcd_monitor_work(struct work_struct *work) | |||
493 | return; | 492 | return; |
494 | } else { | 493 | } else { |
495 | int retval; | 494 | int retval; |
496 | down(&u132->sw_lock); | 495 | mutex_lock(&u132->sw_lock); |
497 | retval = read_roothub_info(u132); | 496 | retval = read_roothub_info(u132); |
498 | if (retval) { | 497 | if (retval) { |
499 | struct usb_hcd *hcd = u132_to_hcd(u132); | 498 | struct usb_hcd *hcd = u132_to_hcd(u132); |
500 | u132_disable(u132); | 499 | u132_disable(u132); |
501 | u132->going = 1; | 500 | u132->going = 1; |
502 | up(&u132->sw_lock); | 501 | mutex_unlock(&u132->sw_lock); |
503 | usb_hc_died(hcd); | 502 | usb_hc_died(hcd); |
504 | ftdi_elan_gone_away(u132->platform_dev); | 503 | ftdi_elan_gone_away(u132->platform_dev); |
505 | u132_monitor_put_kref(u132); | 504 | u132_monitor_put_kref(u132); |
506 | return; | 505 | return; |
507 | } else { | 506 | } else { |
508 | u132_monitor_requeue_work(u132, 500); | 507 | u132_monitor_requeue_work(u132, 500); |
509 | up(&u132->sw_lock); | 508 | mutex_unlock(&u132->sw_lock); |
510 | return; | 509 | return; |
511 | } | 510 | } |
512 | } | 511 | } |
@@ -519,9 +518,8 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, | |||
519 | unsigned long irqs; | 518 | unsigned long irqs; |
520 | struct usb_hcd *hcd = u132_to_hcd(u132); | 519 | struct usb_hcd *hcd = u132_to_hcd(u132); |
521 | urb->error_count = 0; | 520 | urb->error_count = 0; |
522 | urb->status = status; | ||
523 | urb->hcpriv = NULL; | ||
524 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 521 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
522 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
525 | endp->queue_next += 1; | 523 | endp->queue_next += 1; |
526 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { | 524 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { |
527 | endp->active = 0; | 525 | endp->active = 0; |
@@ -543,7 +541,7 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, | |||
543 | u132_ring_queue_work(u132, ring, 0); | 541 | u132_ring_queue_work(u132, ring, 0); |
544 | up(&u132->scheduler_lock); | 542 | up(&u132->scheduler_lock); |
545 | u132_endp_put_kref(u132, endp); | 543 | u132_endp_put_kref(u132, endp); |
546 | usb_hcd_giveback_urb(hcd, urb); | 544 | usb_hcd_giveback_urb(hcd, urb, status); |
547 | return; | 545 | return; |
548 | } | 546 | } |
549 | 547 | ||
@@ -559,9 +557,8 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, | |||
559 | unsigned long irqs; | 557 | unsigned long irqs; |
560 | struct usb_hcd *hcd = u132_to_hcd(u132); | 558 | struct usb_hcd *hcd = u132_to_hcd(u132); |
561 | urb->error_count = 0; | 559 | urb->error_count = 0; |
562 | urb->status = status; | ||
563 | urb->hcpriv = NULL; | ||
564 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 560 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
561 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
565 | endp->queue_next += 1; | 562 | endp->queue_next += 1; |
566 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { | 563 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { |
567 | endp->active = 0; | 564 | endp->active = 0; |
@@ -576,7 +573,7 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, | |||
576 | endp->active = 0; | 573 | endp->active = 0; |
577 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 574 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
578 | kfree(urbq); | 575 | kfree(urbq); |
579 | } usb_hcd_giveback_urb(hcd, urb); | 576 | } usb_hcd_giveback_urb(hcd, urb, status); |
580 | return; | 577 | return; |
581 | } | 578 | } |
582 | 579 | ||
@@ -646,12 +643,12 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, | |||
646 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 643 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
647 | return; | 644 | return; |
648 | } else if (u132->going > 0) { | 645 | } else if (u132->going > 0) { |
649 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 646 | dev_err(&u132->platform_dev->dev, "device is being removed " |
650 | "%p status=%d\n", urb, urb->status); | 647 | "urb=%p\n", urb); |
651 | up(&u132->scheduler_lock); | 648 | up(&u132->scheduler_lock); |
652 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 649 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
653 | return; | 650 | return; |
654 | } else if (urb->status == -EINPROGRESS) { | 651 | } else if (!urb->unlinked) { |
655 | struct u132_ring *ring = endp->ring; | 652 | struct u132_ring *ring = endp->ring; |
656 | u8 *u = urb->transfer_buffer + urb->actual_length; | 653 | u8 *u = urb->transfer_buffer + urb->actual_length; |
657 | u8 *b = buf; | 654 | u8 *b = buf; |
@@ -717,10 +714,10 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, | |||
717 | return; | 714 | return; |
718 | } | 715 | } |
719 | } else { | 716 | } else { |
720 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 717 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
721 | "s=%d\n", urb, urb->status); | 718 | "unlinked=%d\n", urb, urb->unlinked); |
722 | up(&u132->scheduler_lock); | 719 | up(&u132->scheduler_lock); |
723 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 720 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
724 | return; | 721 | return; |
725 | } | 722 | } |
726 | } | 723 | } |
@@ -745,12 +742,12 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, | |||
745 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 742 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
746 | return; | 743 | return; |
747 | } else if (u132->going > 0) { | 744 | } else if (u132->going > 0) { |
748 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 745 | dev_err(&u132->platform_dev->dev, "device is being removed " |
749 | "%p status=%d\n", urb, urb->status); | 746 | "urb=%p\n", urb); |
750 | up(&u132->scheduler_lock); | 747 | up(&u132->scheduler_lock); |
751 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 748 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
752 | return; | 749 | return; |
753 | } else if (urb->status == -EINPROGRESS) { | 750 | } else if (!urb->unlinked) { |
754 | struct u132_ring *ring = endp->ring; | 751 | struct u132_ring *ring = endp->ring; |
755 | urb->actual_length += len; | 752 | urb->actual_length += len; |
756 | endp->toggle_bits = toggle_bits; | 753 | endp->toggle_bits = toggle_bits; |
@@ -769,10 +766,10 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, | |||
769 | return; | 766 | return; |
770 | } | 767 | } |
771 | } else { | 768 | } else { |
772 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 769 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
773 | "s=%d\n", urb, urb->status); | 770 | "unlinked=%d\n", urb, urb->unlinked); |
774 | up(&u132->scheduler_lock); | 771 | up(&u132->scheduler_lock); |
775 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 772 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
776 | return; | 773 | return; |
777 | } | 774 | } |
778 | } | 775 | } |
@@ -798,12 +795,12 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, | |||
798 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 795 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
799 | return; | 796 | return; |
800 | } else if (u132->going > 0) { | 797 | } else if (u132->going > 0) { |
801 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 798 | dev_err(&u132->platform_dev->dev, "device is being removed " |
802 | "%p status=%d\n", urb, urb->status); | 799 | "urb=%p\n", urb); |
803 | up(&u132->scheduler_lock); | 800 | up(&u132->scheduler_lock); |
804 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 801 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
805 | return; | 802 | return; |
806 | } else if (urb->status == -EINPROGRESS) { | 803 | } else if (!urb->unlinked) { |
807 | struct u132_ring *ring = endp->ring; | 804 | struct u132_ring *ring = endp->ring; |
808 | u8 *u = urb->transfer_buffer + urb->actual_length; | 805 | u8 *u = urb->transfer_buffer + urb->actual_length; |
809 | u8 *b = buf; | 806 | u8 *b = buf; |
@@ -872,10 +869,10 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, | |||
872 | return; | 869 | return; |
873 | } | 870 | } |
874 | } else { | 871 | } else { |
875 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 872 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
876 | "s=%d\n", urb, urb->status); | 873 | "unlinked=%d\n", urb, urb->unlinked); |
877 | up(&u132->scheduler_lock); | 874 | up(&u132->scheduler_lock); |
878 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 875 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
879 | return; | 876 | return; |
880 | } | 877 | } |
881 | } | 878 | } |
@@ -899,20 +896,20 @@ static void u132_hcd_configure_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
899 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 896 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
900 | return; | 897 | return; |
901 | } else if (u132->going > 0) { | 898 | } else if (u132->going > 0) { |
902 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 899 | dev_err(&u132->platform_dev->dev, "device is being removed " |
903 | "%p status=%d\n", urb, urb->status); | 900 | "urb=%p\n", urb); |
904 | up(&u132->scheduler_lock); | 901 | up(&u132->scheduler_lock); |
905 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 902 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
906 | return; | 903 | return; |
907 | } else if (urb->status == -EINPROGRESS) { | 904 | } else if (!urb->unlinked) { |
908 | up(&u132->scheduler_lock); | 905 | up(&u132->scheduler_lock); |
909 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 906 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
910 | return; | 907 | return; |
911 | } else { | 908 | } else { |
912 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 909 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
913 | "s=%d\n", urb, urb->status); | 910 | "unlinked=%d\n", urb, urb->unlinked); |
914 | up(&u132->scheduler_lock); | 911 | up(&u132->scheduler_lock); |
915 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 912 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
916 | return; | 913 | return; |
917 | } | 914 | } |
918 | } | 915 | } |
@@ -937,12 +934,12 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, | |||
937 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 934 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
938 | return; | 935 | return; |
939 | } else if (u132->going > 0) { | 936 | } else if (u132->going > 0) { |
940 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 937 | dev_err(&u132->platform_dev->dev, "device is being removed " |
941 | "%p status=%d\n", urb, urb->status); | 938 | "urb=%p\n", urb); |
942 | up(&u132->scheduler_lock); | 939 | up(&u132->scheduler_lock); |
943 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 940 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
944 | return; | 941 | return; |
945 | } else if (urb->status == -EINPROGRESS) { | 942 | } else if (!urb->unlinked) { |
946 | struct u132_ring *ring = endp->ring; | 943 | struct u132_ring *ring = endp->ring; |
947 | u8 *u = urb->transfer_buffer; | 944 | u8 *u = urb->transfer_buffer; |
948 | u8 *b = buf; | 945 | u8 *b = buf; |
@@ -981,10 +978,10 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, | |||
981 | return; | 978 | return; |
982 | } | 979 | } |
983 | } else { | 980 | } else { |
984 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 981 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
985 | "s=%d\n", urb, urb->status); | 982 | "unlinked=%d\n", urb, urb->unlinked); |
986 | up(&u132->scheduler_lock); | 983 | up(&u132->scheduler_lock); |
987 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 984 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
988 | return; | 985 | return; |
989 | } | 986 | } |
990 | } | 987 | } |
@@ -1008,20 +1005,20 @@ static void u132_hcd_configure_empty_recv(void *data, struct urb *urb, u8 *buf, | |||
1008 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1005 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1009 | return; | 1006 | return; |
1010 | } else if (u132->going > 0) { | 1007 | } else if (u132->going > 0) { |
1011 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1008 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1012 | "%p status=%d\n", urb, urb->status); | 1009 | "urb=%p\n", urb); |
1013 | up(&u132->scheduler_lock); | 1010 | up(&u132->scheduler_lock); |
1014 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1011 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1015 | return; | 1012 | return; |
1016 | } else if (urb->status == -EINPROGRESS) { | 1013 | } else if (!urb->unlinked) { |
1017 | up(&u132->scheduler_lock); | 1014 | up(&u132->scheduler_lock); |
1018 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1015 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1019 | return; | 1016 | return; |
1020 | } else { | 1017 | } else { |
1021 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1018 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1022 | "s=%d\n", urb, urb->status); | 1019 | "unlinked=%d\n", urb, urb->unlinked); |
1023 | up(&u132->scheduler_lock); | 1020 | up(&u132->scheduler_lock); |
1024 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1021 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1025 | return; | 1022 | return; |
1026 | } | 1023 | } |
1027 | } | 1024 | } |
@@ -1046,12 +1043,12 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1046 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1043 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1047 | return; | 1044 | return; |
1048 | } else if (u132->going > 0) { | 1045 | } else if (u132->going > 0) { |
1049 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1046 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1050 | "%p status=%d\n", urb, urb->status); | 1047 | "urb=%p\n", urb); |
1051 | up(&u132->scheduler_lock); | 1048 | up(&u132->scheduler_lock); |
1052 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1049 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1053 | return; | 1050 | return; |
1054 | } else if (urb->status == -EINPROGRESS) { | 1051 | } else if (!urb->unlinked) { |
1055 | if (usb_pipein(urb->pipe)) { | 1052 | if (usb_pipein(urb->pipe)) { |
1056 | int retval; | 1053 | int retval; |
1057 | struct u132_ring *ring = endp->ring; | 1054 | struct u132_ring *ring = endp->ring; |
@@ -1078,10 +1075,10 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1078 | return; | 1075 | return; |
1079 | } | 1076 | } |
1080 | } else { | 1077 | } else { |
1081 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1078 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1082 | "s=%d\n", urb, urb->status); | 1079 | "unlinked=%d\n", urb, urb->unlinked); |
1083 | up(&u132->scheduler_lock); | 1080 | up(&u132->scheduler_lock); |
1084 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1081 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1085 | return; | 1082 | return; |
1086 | } | 1083 | } |
1087 | } | 1084 | } |
@@ -1107,22 +1104,22 @@ static void u132_hcd_enumeration_empty_recv(void *data, struct urb *urb, | |||
1107 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1104 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1108 | return; | 1105 | return; |
1109 | } else if (u132->going > 0) { | 1106 | } else if (u132->going > 0) { |
1110 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1107 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1111 | "%p status=%d\n", urb, urb->status); | 1108 | "urb=%p\n", urb); |
1112 | up(&u132->scheduler_lock); | 1109 | up(&u132->scheduler_lock); |
1113 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1110 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1114 | return; | 1111 | return; |
1115 | } else if (urb->status == -EINPROGRESS) { | 1112 | } else if (!urb->unlinked) { |
1116 | u132->addr[0].address = 0; | 1113 | u132->addr[0].address = 0; |
1117 | endp->usb_addr = udev->usb_addr; | 1114 | endp->usb_addr = udev->usb_addr; |
1118 | up(&u132->scheduler_lock); | 1115 | up(&u132->scheduler_lock); |
1119 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1116 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1120 | return; | 1117 | return; |
1121 | } else { | 1118 | } else { |
1122 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1119 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1123 | "s=%d\n", urb, urb->status); | 1120 | "unlinked=%d\n", urb, urb->unlinked); |
1124 | up(&u132->scheduler_lock); | 1121 | up(&u132->scheduler_lock); |
1125 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1122 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1126 | return; | 1123 | return; |
1127 | } | 1124 | } |
1128 | } | 1125 | } |
@@ -1146,12 +1143,12 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, | |||
1146 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1143 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1147 | return; | 1144 | return; |
1148 | } else if (u132->going > 0) { | 1145 | } else if (u132->going > 0) { |
1149 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1146 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1150 | "%p status=%d\n", urb, urb->status); | 1147 | "urb=%p\n", urb); |
1151 | up(&u132->scheduler_lock); | 1148 | up(&u132->scheduler_lock); |
1152 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1149 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1153 | return; | 1150 | return; |
1154 | } else if (urb->status == -EINPROGRESS) { | 1151 | } else if (!urb->unlinked) { |
1155 | int retval; | 1152 | int retval; |
1156 | struct u132_ring *ring = endp->ring; | 1153 | struct u132_ring *ring = endp->ring; |
1157 | up(&u132->scheduler_lock); | 1154 | up(&u132->scheduler_lock); |
@@ -1163,10 +1160,10 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, | |||
1163 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1160 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1164 | return; | 1161 | return; |
1165 | } else { | 1162 | } else { |
1166 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1163 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1167 | "s=%d\n", urb, urb->status); | 1164 | "unlinked=%d\n", urb, urb->unlinked); |
1168 | up(&u132->scheduler_lock); | 1165 | up(&u132->scheduler_lock); |
1169 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1166 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1170 | return; | 1167 | return; |
1171 | } | 1168 | } |
1172 | } | 1169 | } |
@@ -1190,20 +1187,20 @@ static void u132_hcd_initial_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
1190 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1187 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1191 | return; | 1188 | return; |
1192 | } else if (u132->going > 0) { | 1189 | } else if (u132->going > 0) { |
1193 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1190 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1194 | "%p status=%d\n", urb, urb->status); | 1191 | "urb=%p\n", urb); |
1195 | up(&u132->scheduler_lock); | 1192 | up(&u132->scheduler_lock); |
1196 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1193 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1197 | return; | 1194 | return; |
1198 | } else if (urb->status == -EINPROGRESS) { | 1195 | } else if (!urb->unlinked) { |
1199 | up(&u132->scheduler_lock); | 1196 | up(&u132->scheduler_lock); |
1200 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1197 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1201 | return; | 1198 | return; |
1202 | } else { | 1199 | } else { |
1203 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1200 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1204 | "s=%d\n", urb, urb->status); | 1201 | "unlinked=%d\n", urb, urb->unlinked); |
1205 | up(&u132->scheduler_lock); | 1202 | up(&u132->scheduler_lock); |
1206 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1203 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1207 | return; | 1204 | return; |
1208 | } | 1205 | } |
1209 | } | 1206 | } |
@@ -1228,12 +1225,12 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, | |||
1228 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1225 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1229 | return; | 1226 | return; |
1230 | } else if (u132->going > 0) { | 1227 | } else if (u132->going > 0) { |
1231 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1228 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1232 | "%p status=%d\n", urb, urb->status); | 1229 | "urb=%p\n", urb); |
1233 | up(&u132->scheduler_lock); | 1230 | up(&u132->scheduler_lock); |
1234 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1231 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1235 | return; | 1232 | return; |
1236 | } else if (urb->status == -EINPROGRESS) { | 1233 | } else if (!urb->unlinked) { |
1237 | int retval; | 1234 | int retval; |
1238 | struct u132_ring *ring = endp->ring; | 1235 | struct u132_ring *ring = endp->ring; |
1239 | u8 *u = urb->transfer_buffer; | 1236 | u8 *u = urb->transfer_buffer; |
@@ -1252,10 +1249,10 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, | |||
1252 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1249 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1253 | return; | 1250 | return; |
1254 | } else { | 1251 | } else { |
1255 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1252 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1256 | "s=%d\n", urb, urb->status); | 1253 | "unlinked=%d\n", urb, urb->unlinked); |
1257 | up(&u132->scheduler_lock); | 1254 | up(&u132->scheduler_lock); |
1258 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1255 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1259 | return; | 1256 | return; |
1260 | } | 1257 | } |
1261 | } | 1258 | } |
@@ -1280,12 +1277,12 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1280 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1277 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1281 | return; | 1278 | return; |
1282 | } else if (u132->going > 0) { | 1279 | } else if (u132->going > 0) { |
1283 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1280 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1284 | "%p status=%d\n", urb, urb->status); | 1281 | "urb=%p\n", urb); |
1285 | up(&u132->scheduler_lock); | 1282 | up(&u132->scheduler_lock); |
1286 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1283 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1287 | return; | 1284 | return; |
1288 | } else if (urb->status == -EINPROGRESS) { | 1285 | } else if (!urb->unlinked) { |
1289 | int retval; | 1286 | int retval; |
1290 | struct u132_ring *ring = endp->ring; | 1287 | struct u132_ring *ring = endp->ring; |
1291 | up(&u132->scheduler_lock); | 1288 | up(&u132->scheduler_lock); |
@@ -1297,10 +1294,10 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1297 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1294 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1298 | return; | 1295 | return; |
1299 | } else { | 1296 | } else { |
1300 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1297 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1301 | "s=%d\n", urb, urb->status); | 1298 | "unlinked=%d\n", urb, urb->unlinked); |
1302 | up(&u132->scheduler_lock); | 1299 | up(&u132->scheduler_lock); |
1303 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1300 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1304 | return; | 1301 | return; |
1305 | } | 1302 | } |
1306 | } | 1303 | } |
@@ -1805,10 +1802,10 @@ static void u132_hcd_stop(struct usb_hcd *hcd) | |||
1805 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" | 1802 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" |
1806 | "ed\n", hcd); | 1803 | "ed\n", hcd); |
1807 | } else { | 1804 | } else { |
1808 | down(&u132->sw_lock); | 1805 | mutex_lock(&u132->sw_lock); |
1809 | msleep(100); | 1806 | msleep(100); |
1810 | u132_power(u132, 0); | 1807 | u132_power(u132, 0); |
1811 | up(&u132->sw_lock); | 1808 | mutex_unlock(&u132->sw_lock); |
1812 | } | 1809 | } |
1813 | } | 1810 | } |
1814 | 1811 | ||
@@ -1830,7 +1827,7 @@ static int u132_hcd_start(struct usb_hcd *hcd) | |||
1830 | (pdev->dev.platform_data))->vendor; | 1827 | (pdev->dev.platform_data))->vendor; |
1831 | u16 device = ((struct u132_platform_data *) | 1828 | u16 device = ((struct u132_platform_data *) |
1832 | (pdev->dev.platform_data))->device; | 1829 | (pdev->dev.platform_data))->device; |
1833 | down(&u132->sw_lock); | 1830 | mutex_lock(&u132->sw_lock); |
1834 | msleep(10); | 1831 | msleep(10); |
1835 | if (vendor == PCI_VENDOR_ID_AMD && device == 0x740c) { | 1832 | if (vendor == PCI_VENDOR_ID_AMD && device == 0x740c) { |
1836 | u132->flags = OHCI_QUIRK_AMD756; | 1833 | u132->flags = OHCI_QUIRK_AMD756; |
@@ -1845,7 +1842,7 @@ static int u132_hcd_start(struct usb_hcd *hcd) | |||
1845 | u132->going = 1; | 1842 | u132->going = 1; |
1846 | } | 1843 | } |
1847 | msleep(100); | 1844 | msleep(100); |
1848 | up(&u132->sw_lock); | 1845 | mutex_unlock(&u132->sw_lock); |
1849 | return retval; | 1846 | return retval; |
1850 | } else { | 1847 | } else { |
1851 | dev_err(&u132->platform_dev->dev, "platform_device missing\n"); | 1848 | dev_err(&u132->platform_dev->dev, "platform_device missing\n"); |
@@ -1865,32 +1862,44 @@ static int u132_hcd_reset(struct usb_hcd *hcd) | |||
1865 | return -ESHUTDOWN; | 1862 | return -ESHUTDOWN; |
1866 | } else { | 1863 | } else { |
1867 | int retval; | 1864 | int retval; |
1868 | down(&u132->sw_lock); | 1865 | mutex_lock(&u132->sw_lock); |
1869 | retval = u132_init(u132); | 1866 | retval = u132_init(u132); |
1870 | if (retval) { | 1867 | if (retval) { |
1871 | u132_disable(u132); | 1868 | u132_disable(u132); |
1872 | u132->going = 1; | 1869 | u132->going = 1; |
1873 | } | 1870 | } |
1874 | up(&u132->sw_lock); | 1871 | mutex_unlock(&u132->sw_lock); |
1875 | return retval; | 1872 | return retval; |
1876 | } | 1873 | } |
1877 | } | 1874 | } |
1878 | 1875 | ||
1879 | static int create_endpoint_and_queue_int(struct u132 *u132, | 1876 | static int create_endpoint_and_queue_int(struct u132 *u132, |
1880 | struct u132_udev *udev, struct usb_host_endpoint *hep, struct urb *urb, | 1877 | struct u132_udev *udev, struct urb *urb, |
1881 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, | 1878 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, |
1882 | gfp_t mem_flags) | 1879 | gfp_t mem_flags) |
1883 | { | 1880 | { |
1884 | struct u132_ring *ring; | 1881 | struct u132_ring *ring; |
1885 | unsigned long irqs; | 1882 | unsigned long irqs; |
1886 | u8 endp_number = ++u132->num_endpoints; | 1883 | int rc; |
1887 | struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] = | 1884 | u8 endp_number; |
1888 | kmalloc(sizeof(struct u132_endp), mem_flags); | 1885 | struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); |
1886 | |||
1889 | if (!endp) { | 1887 | if (!endp) { |
1890 | return -ENOMEM; | 1888 | return -ENOMEM; |
1891 | } | 1889 | } |
1890 | |||
1891 | spin_lock_init(&endp->queue_lock.slock); | ||
1892 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
1893 | rc = usb_hcd_link_urb_to_ep(u132_to_hcd(u132), urb); | ||
1894 | if (rc) { | ||
1895 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
1896 | kfree(endp); | ||
1897 | return rc; | ||
1898 | } | ||
1899 | |||
1900 | endp_number = ++u132->num_endpoints; | ||
1901 | urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; | ||
1892 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); | 1902 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
1893 | spin_lock_init(&endp->queue_lock.slock); | ||
1894 | INIT_LIST_HEAD(&endp->urb_more); | 1903 | INIT_LIST_HEAD(&endp->urb_more); |
1895 | ring = endp->ring = &u132->ring[0]; | 1904 | ring = endp->ring = &u132->ring[0]; |
1896 | if (ring->curr_endp) { | 1905 | if (ring->curr_endp) { |
@@ -1906,7 +1915,7 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1906 | endp->delayed = 0; | 1915 | endp->delayed = 0; |
1907 | endp->endp_number = endp_number; | 1916 | endp->endp_number = endp_number; |
1908 | endp->u132 = u132; | 1917 | endp->u132 = u132; |
1909 | endp->hep = hep; | 1918 | endp->hep = urb->ep; |
1910 | endp->pipetype = usb_pipetype(urb->pipe); | 1919 | endp->pipetype = usb_pipetype(urb->pipe); |
1911 | u132_endp_init_kref(u132, endp); | 1920 | u132_endp_init_kref(u132, endp); |
1912 | if (usb_pipein(urb->pipe)) { | 1921 | if (usb_pipein(urb->pipe)) { |
@@ -1925,7 +1934,6 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1925 | u132_udev_get_kref(u132, udev); | 1934 | u132_udev_get_kref(u132, udev); |
1926 | } | 1935 | } |
1927 | urb->hcpriv = u132; | 1936 | urb->hcpriv = u132; |
1928 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
1929 | endp->delayed = 1; | 1937 | endp->delayed = 1; |
1930 | endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); | 1938 | endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); |
1931 | endp->udev_number = address; | 1939 | endp->udev_number = address; |
@@ -1940,8 +1948,8 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1940 | return 0; | 1948 | return 0; |
1941 | } | 1949 | } |
1942 | 1950 | ||
1943 | static int queue_int_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | 1951 | static int queue_int_on_old_endpoint(struct u132 *u132, |
1944 | struct usb_host_endpoint *hep, struct urb *urb, | 1952 | struct u132_udev *udev, struct urb *urb, |
1945 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, | 1953 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, |
1946 | u8 usb_endp, u8 address) | 1954 | u8 usb_endp, u8 address) |
1947 | { | 1955 | { |
@@ -1965,21 +1973,33 @@ static int queue_int_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | |||
1965 | } | 1973 | } |
1966 | 1974 | ||
1967 | static int create_endpoint_and_queue_bulk(struct u132 *u132, | 1975 | static int create_endpoint_and_queue_bulk(struct u132 *u132, |
1968 | struct u132_udev *udev, struct usb_host_endpoint *hep, struct urb *urb, | 1976 | struct u132_udev *udev, struct urb *urb, |
1969 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, | 1977 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, |
1970 | gfp_t mem_flags) | 1978 | gfp_t mem_flags) |
1971 | { | 1979 | { |
1972 | int ring_number; | 1980 | int ring_number; |
1973 | struct u132_ring *ring; | 1981 | struct u132_ring *ring; |
1974 | unsigned long irqs; | 1982 | unsigned long irqs; |
1975 | u8 endp_number = ++u132->num_endpoints; | 1983 | int rc; |
1976 | struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] = | 1984 | u8 endp_number; |
1977 | kmalloc(sizeof(struct u132_endp), mem_flags); | 1985 | struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); |
1986 | |||
1978 | if (!endp) { | 1987 | if (!endp) { |
1979 | return -ENOMEM; | 1988 | return -ENOMEM; |
1980 | } | 1989 | } |
1990 | |||
1991 | spin_lock_init(&endp->queue_lock.slock); | ||
1992 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
1993 | rc = usb_hcd_link_urb_to_ep(u132_to_hcd(u132), urb); | ||
1994 | if (rc) { | ||
1995 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
1996 | kfree(endp); | ||
1997 | return rc; | ||
1998 | } | ||
1999 | |||
2000 | endp_number = ++u132->num_endpoints; | ||
2001 | urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; | ||
1981 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); | 2002 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
1982 | spin_lock_init(&endp->queue_lock.slock); | ||
1983 | INIT_LIST_HEAD(&endp->urb_more); | 2003 | INIT_LIST_HEAD(&endp->urb_more); |
1984 | endp->dequeueing = 0; | 2004 | endp->dequeueing = 0; |
1985 | endp->edset_flush = 0; | 2005 | endp->edset_flush = 0; |
@@ -1987,7 +2007,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
1987 | endp->delayed = 0; | 2007 | endp->delayed = 0; |
1988 | endp->endp_number = endp_number; | 2008 | endp->endp_number = endp_number; |
1989 | endp->u132 = u132; | 2009 | endp->u132 = u132; |
1990 | endp->hep = hep; | 2010 | endp->hep = urb->ep; |
1991 | endp->pipetype = usb_pipetype(urb->pipe); | 2011 | endp->pipetype = usb_pipetype(urb->pipe); |
1992 | u132_endp_init_kref(u132, endp); | 2012 | u132_endp_init_kref(u132, endp); |
1993 | if (usb_pipein(urb->pipe)) { | 2013 | if (usb_pipein(urb->pipe)) { |
@@ -2016,7 +2036,6 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
2016 | } | 2036 | } |
2017 | ring->length += 1; | 2037 | ring->length += 1; |
2018 | urb->hcpriv = u132; | 2038 | urb->hcpriv = u132; |
2019 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2020 | endp->udev_number = address; | 2039 | endp->udev_number = address; |
2021 | endp->usb_addr = usb_addr; | 2040 | endp->usb_addr = usb_addr; |
2022 | endp->usb_endp = usb_endp; | 2041 | endp->usb_endp = usb_endp; |
@@ -2030,7 +2049,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
2030 | } | 2049 | } |
2031 | 2050 | ||
2032 | static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | 2051 | static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, |
2033 | struct usb_host_endpoint *hep, struct urb *urb, | 2052 | struct urb *urb, |
2034 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, | 2053 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, |
2035 | u8 usb_endp, u8 address) | 2054 | u8 usb_endp, u8 address) |
2036 | { | 2055 | { |
@@ -2052,19 +2071,32 @@ static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | |||
2052 | } | 2071 | } |
2053 | 2072 | ||
2054 | static int create_endpoint_and_queue_control(struct u132 *u132, | 2073 | static int create_endpoint_and_queue_control(struct u132 *u132, |
2055 | struct usb_host_endpoint *hep, struct urb *urb, | 2074 | struct urb *urb, |
2056 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, | 2075 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, |
2057 | gfp_t mem_flags) | 2076 | gfp_t mem_flags) |
2058 | { | 2077 | { |
2059 | struct u132_ring *ring; | 2078 | struct u132_ring *ring; |
2060 | u8 endp_number = ++u132->num_endpoints; | 2079 | unsigned long irqs; |
2061 | struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] = | 2080 | int rc; |
2062 | kmalloc(sizeof(struct u132_endp), mem_flags); | 2081 | u8 endp_number; |
2082 | struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); | ||
2083 | |||
2063 | if (!endp) { | 2084 | if (!endp) { |
2064 | return -ENOMEM; | 2085 | return -ENOMEM; |
2065 | } | 2086 | } |
2087 | |||
2088 | spin_lock_init(&endp->queue_lock.slock); | ||
2089 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2090 | rc = usb_hcd_link_urb_to_ep(u132_to_hcd(u132), urb); | ||
2091 | if (rc) { | ||
2092 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
2093 | kfree(endp); | ||
2094 | return rc; | ||
2095 | } | ||
2096 | |||
2097 | endp_number = ++u132->num_endpoints; | ||
2098 | urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; | ||
2066 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); | 2099 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
2067 | spin_lock_init(&endp->queue_lock.slock); | ||
2068 | INIT_LIST_HEAD(&endp->urb_more); | 2100 | INIT_LIST_HEAD(&endp->urb_more); |
2069 | ring = endp->ring = &u132->ring[0]; | 2101 | ring = endp->ring = &u132->ring[0]; |
2070 | if (ring->curr_endp) { | 2102 | if (ring->curr_endp) { |
@@ -2080,11 +2112,10 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2080 | endp->delayed = 0; | 2112 | endp->delayed = 0; |
2081 | endp->endp_number = endp_number; | 2113 | endp->endp_number = endp_number; |
2082 | endp->u132 = u132; | 2114 | endp->u132 = u132; |
2083 | endp->hep = hep; | 2115 | endp->hep = urb->ep; |
2084 | u132_endp_init_kref(u132, endp); | 2116 | u132_endp_init_kref(u132, endp); |
2085 | u132_endp_get_kref(u132, endp); | 2117 | u132_endp_get_kref(u132, endp); |
2086 | if (usb_addr == 0) { | 2118 | if (usb_addr == 0) { |
2087 | unsigned long irqs; | ||
2088 | u8 address = u132->addr[usb_addr].address; | 2119 | u8 address = u132->addr[usb_addr].address; |
2089 | struct u132_udev *udev = &u132->udev[address]; | 2120 | struct u132_udev *udev = &u132->udev[address]; |
2090 | endp->udev_number = address; | 2121 | endp->udev_number = address; |
@@ -2098,7 +2129,6 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2098 | udev->endp_number_in[usb_endp] = endp_number; | 2129 | udev->endp_number_in[usb_endp] = endp_number; |
2099 | udev->endp_number_out[usb_endp] = endp_number; | 2130 | udev->endp_number_out[usb_endp] = endp_number; |
2100 | urb->hcpriv = u132; | 2131 | urb->hcpriv = u132; |
2101 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2102 | endp->queue_size = 1; | 2132 | endp->queue_size = 1; |
2103 | endp->queue_last = 0; | 2133 | endp->queue_last = 0; |
2104 | endp->queue_next = 0; | 2134 | endp->queue_next = 0; |
@@ -2107,7 +2137,6 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2107 | u132_endp_queue_work(u132, endp, 0); | 2137 | u132_endp_queue_work(u132, endp, 0); |
2108 | return 0; | 2138 | return 0; |
2109 | } else { /*(usb_addr > 0) */ | 2139 | } else { /*(usb_addr > 0) */ |
2110 | unsigned long irqs; | ||
2111 | u8 address = u132->addr[usb_addr].address; | 2140 | u8 address = u132->addr[usb_addr].address; |
2112 | struct u132_udev *udev = &u132->udev[address]; | 2141 | struct u132_udev *udev = &u132->udev[address]; |
2113 | endp->udev_number = address; | 2142 | endp->udev_number = address; |
@@ -2121,7 +2150,6 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2121 | udev->endp_number_in[usb_endp] = endp_number; | 2150 | udev->endp_number_in[usb_endp] = endp_number; |
2122 | udev->endp_number_out[usb_endp] = endp_number; | 2151 | udev->endp_number_out[usb_endp] = endp_number; |
2123 | urb->hcpriv = u132; | 2152 | urb->hcpriv = u132; |
2124 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2125 | endp->queue_size = 1; | 2153 | endp->queue_size = 1; |
2126 | endp->queue_last = 0; | 2154 | endp->queue_last = 0; |
2127 | endp->queue_next = 0; | 2155 | endp->queue_next = 0; |
@@ -2133,7 +2161,7 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2133 | } | 2161 | } |
2134 | 2162 | ||
2135 | static int queue_control_on_old_endpoint(struct u132 *u132, | 2163 | static int queue_control_on_old_endpoint(struct u132 *u132, |
2136 | struct usb_host_endpoint *hep, struct urb *urb, | 2164 | struct urb *urb, |
2137 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, | 2165 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, |
2138 | u8 usb_endp) | 2166 | u8 usb_endp) |
2139 | { | 2167 | { |
@@ -2233,8 +2261,8 @@ static int queue_control_on_old_endpoint(struct u132 *u132, | |||
2233 | } | 2261 | } |
2234 | } | 2262 | } |
2235 | 2263 | ||
2236 | static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | 2264 | static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, |
2237 | struct urb *urb, gfp_t mem_flags) | 2265 | gfp_t mem_flags) |
2238 | { | 2266 | { |
2239 | struct u132 *u132 = hcd_to_u132(hcd); | 2267 | struct u132 *u132 = hcd_to_u132(hcd); |
2240 | if (irqs_disabled()) { | 2268 | if (irqs_disabled()) { |
@@ -2249,8 +2277,8 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2249 | , u132->going); | 2277 | , u132->going); |
2250 | return -ENODEV; | 2278 | return -ENODEV; |
2251 | } else if (u132->going > 0) { | 2279 | } else if (u132->going > 0) { |
2252 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 2280 | dev_err(&u132->platform_dev->dev, "device is being removed " |
2253 | "%p status=%d\n", urb, urb->status); | 2281 | "urb=%p\n", urb); |
2254 | return -ESHUTDOWN; | 2282 | return -ESHUTDOWN; |
2255 | } else { | 2283 | } else { |
2256 | u8 usb_addr = usb_pipedevice(urb->pipe); | 2284 | u8 usb_addr = usb_pipedevice(urb->pipe); |
@@ -2259,16 +2287,24 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2259 | if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { | 2287 | if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { |
2260 | u8 address = u132->addr[usb_addr].address; | 2288 | u8 address = u132->addr[usb_addr].address; |
2261 | struct u132_udev *udev = &u132->udev[address]; | 2289 | struct u132_udev *udev = &u132->udev[address]; |
2262 | struct u132_endp *endp = hep->hcpriv; | 2290 | struct u132_endp *endp = urb->ep->hcpriv; |
2263 | urb->actual_length = 0; | 2291 | urb->actual_length = 0; |
2264 | if (endp) { | 2292 | if (endp) { |
2265 | unsigned long irqs; | 2293 | unsigned long irqs; |
2266 | int retval; | 2294 | int retval; |
2267 | spin_lock_irqsave(&endp->queue_lock.slock, | 2295 | spin_lock_irqsave(&endp->queue_lock.slock, |
2268 | irqs); | 2296 | irqs); |
2269 | retval = queue_int_on_old_endpoint(u132, udev, | 2297 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2270 | hep, urb, usb_dev, endp, usb_addr, | 2298 | if (retval == 0) { |
2271 | usb_endp, address); | 2299 | retval = queue_int_on_old_endpoint( |
2300 | u132, udev, urb, | ||
2301 | usb_dev, endp, | ||
2302 | usb_addr, usb_endp, | ||
2303 | address); | ||
2304 | if (retval) | ||
2305 | usb_hcd_unlink_urb_from_ep( | ||
2306 | hcd, urb); | ||
2307 | } | ||
2272 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2308 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
2273 | irqs); | 2309 | irqs); |
2274 | if (retval) { | 2310 | if (retval) { |
@@ -2283,8 +2319,8 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2283 | return -EINVAL; | 2319 | return -EINVAL; |
2284 | } else { /*(endp == NULL) */ | 2320 | } else { /*(endp == NULL) */ |
2285 | return create_endpoint_and_queue_int(u132, udev, | 2321 | return create_endpoint_and_queue_int(u132, udev, |
2286 | hep, urb, usb_dev, usb_addr, usb_endp, | 2322 | urb, usb_dev, usb_addr, |
2287 | address, mem_flags); | 2323 | usb_endp, address, mem_flags); |
2288 | } | 2324 | } |
2289 | } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | 2325 | } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { |
2290 | dev_err(&u132->platform_dev->dev, "the hardware does no" | 2326 | dev_err(&u132->platform_dev->dev, "the hardware does no" |
@@ -2293,16 +2329,24 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2293 | } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { | 2329 | } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { |
2294 | u8 address = u132->addr[usb_addr].address; | 2330 | u8 address = u132->addr[usb_addr].address; |
2295 | struct u132_udev *udev = &u132->udev[address]; | 2331 | struct u132_udev *udev = &u132->udev[address]; |
2296 | struct u132_endp *endp = hep->hcpriv; | 2332 | struct u132_endp *endp = urb->ep->hcpriv; |
2297 | urb->actual_length = 0; | 2333 | urb->actual_length = 0; |
2298 | if (endp) { | 2334 | if (endp) { |
2299 | unsigned long irqs; | 2335 | unsigned long irqs; |
2300 | int retval; | 2336 | int retval; |
2301 | spin_lock_irqsave(&endp->queue_lock.slock, | 2337 | spin_lock_irqsave(&endp->queue_lock.slock, |
2302 | irqs); | 2338 | irqs); |
2303 | retval = queue_bulk_on_old_endpoint(u132, udev, | 2339 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2304 | hep, urb, usb_dev, endp, usb_addr, | 2340 | if (retval == 0) { |
2305 | usb_endp, address); | 2341 | retval = queue_bulk_on_old_endpoint( |
2342 | u132, udev, urb, | ||
2343 | usb_dev, endp, | ||
2344 | usb_addr, usb_endp, | ||
2345 | address); | ||
2346 | if (retval) | ||
2347 | usb_hcd_unlink_urb_from_ep( | ||
2348 | hcd, urb); | ||
2349 | } | ||
2306 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2350 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
2307 | irqs); | 2351 | irqs); |
2308 | if (retval) { | 2352 | if (retval) { |
@@ -2315,10 +2359,10 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2315 | return -EINVAL; | 2359 | return -EINVAL; |
2316 | } else | 2360 | } else |
2317 | return create_endpoint_and_queue_bulk(u132, | 2361 | return create_endpoint_and_queue_bulk(u132, |
2318 | udev, hep, urb, usb_dev, usb_addr, | 2362 | udev, urb, usb_dev, usb_addr, |
2319 | usb_endp, address, mem_flags); | 2363 | usb_endp, address, mem_flags); |
2320 | } else { | 2364 | } else { |
2321 | struct u132_endp *endp = hep->hcpriv; | 2365 | struct u132_endp *endp = urb->ep->hcpriv; |
2322 | u16 urb_size = 8; | 2366 | u16 urb_size = 8; |
2323 | u8 *b = urb->setup_packet; | 2367 | u8 *b = urb->setup_packet; |
2324 | int i = 0; | 2368 | int i = 0; |
@@ -2341,9 +2385,16 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2341 | int retval; | 2385 | int retval; |
2342 | spin_lock_irqsave(&endp->queue_lock.slock, | 2386 | spin_lock_irqsave(&endp->queue_lock.slock, |
2343 | irqs); | 2387 | irqs); |
2344 | retval = queue_control_on_old_endpoint(u132, | 2388 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2345 | hep, urb, usb_dev, endp, usb_addr, | 2389 | if (retval == 0) { |
2346 | usb_endp); | 2390 | retval = queue_control_on_old_endpoint( |
2391 | u132, urb, usb_dev, | ||
2392 | endp, usb_addr, | ||
2393 | usb_endp); | ||
2394 | if (retval) | ||
2395 | usb_hcd_unlink_urb_from_ep( | ||
2396 | hcd, urb); | ||
2397 | } | ||
2347 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2398 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
2348 | irqs); | 2399 | irqs); |
2349 | if (retval) { | 2400 | if (retval) { |
@@ -2356,7 +2407,7 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2356 | return -EINVAL; | 2407 | return -EINVAL; |
2357 | } else | 2408 | } else |
2358 | return create_endpoint_and_queue_control(u132, | 2409 | return create_endpoint_and_queue_control(u132, |
2359 | hep, urb, usb_dev, usb_addr, usb_endp, | 2410 | urb, usb_dev, usb_addr, usb_endp, |
2360 | mem_flags); | 2411 | mem_flags); |
2361 | } | 2412 | } |
2362 | } | 2413 | } |
@@ -2375,8 +2426,7 @@ static int dequeue_from_overflow_chain(struct u132 *u132, | |||
2375 | list_del(scan); | 2426 | list_del(scan); |
2376 | endp->queue_size -= 1; | 2427 | endp->queue_size -= 1; |
2377 | urb->error_count = 0; | 2428 | urb->error_count = 0; |
2378 | urb->hcpriv = NULL; | 2429 | usb_hcd_giveback_urb(hcd, urb, 0); |
2379 | usb_hcd_giveback_urb(hcd, urb); | ||
2380 | return 0; | 2430 | return 0; |
2381 | } else | 2431 | } else |
2382 | continue; | 2432 | continue; |
@@ -2391,10 +2441,17 @@ static int dequeue_from_overflow_chain(struct u132 *u132, | |||
2391 | } | 2441 | } |
2392 | 2442 | ||
2393 | static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | 2443 | static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, |
2394 | struct urb *urb) | 2444 | struct urb *urb, int status) |
2395 | { | 2445 | { |
2396 | unsigned long irqs; | 2446 | unsigned long irqs; |
2447 | int rc; | ||
2448 | |||
2397 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 2449 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
2450 | rc = usb_hcd_check_unlink_urb(u132_to_hcd(u132), urb, status); | ||
2451 | if (rc) { | ||
2452 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
2453 | return rc; | ||
2454 | } | ||
2398 | if (endp->queue_size == 0) { | 2455 | if (endp->queue_size == 0) { |
2399 | dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]" | 2456 | dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]" |
2400 | "=%p ring[%d] %c%c usb_endp=%d usb_addr=%d\n", urb, | 2457 | "=%p ring[%d] %c%c usb_endp=%d usb_addr=%d\n", urb, |
@@ -2410,11 +2467,10 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2410 | endp->edset_flush = 1; | 2467 | endp->edset_flush = 1; |
2411 | u132_endp_queue_work(u132, endp, 0); | 2468 | u132_endp_queue_work(u132, endp, 0); |
2412 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2469 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2413 | urb->hcpriv = NULL; | ||
2414 | return 0; | 2470 | return 0; |
2415 | } else { | 2471 | } else { |
2416 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2472 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2417 | u132_hcd_abandon_urb(u132, endp, urb, urb->status); | 2473 | u132_hcd_abandon_urb(u132, endp, urb, status); |
2418 | return 0; | 2474 | return 0; |
2419 | } | 2475 | } |
2420 | } else { | 2476 | } else { |
@@ -2439,6 +2495,8 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2439 | } | 2495 | } |
2440 | if (urb_slot) { | 2496 | if (urb_slot) { |
2441 | struct usb_hcd *hcd = u132_to_hcd(u132); | 2497 | struct usb_hcd *hcd = u132_to_hcd(u132); |
2498 | |||
2499 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
2442 | endp->queue_size -= 1; | 2500 | endp->queue_size -= 1; |
2443 | if (list_empty(&endp->urb_more)) { | 2501 | if (list_empty(&endp->urb_more)) { |
2444 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2502 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
@@ -2453,8 +2511,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2453 | irqs); | 2511 | irqs); |
2454 | kfree(urbq); | 2512 | kfree(urbq); |
2455 | } urb->error_count = 0; | 2513 | } urb->error_count = 0; |
2456 | urb->hcpriv = NULL; | 2514 | usb_hcd_giveback_urb(hcd, urb, status); |
2457 | usb_hcd_giveback_urb(hcd, urb); | ||
2458 | return 0; | 2515 | return 0; |
2459 | } else if (list_empty(&endp->urb_more)) { | 2516 | } else if (list_empty(&endp->urb_more)) { |
2460 | dev_err(&u132->platform_dev->dev, "urb=%p not found in " | 2517 | dev_err(&u132->platform_dev->dev, "urb=%p not found in " |
@@ -2468,7 +2525,10 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2468 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2525 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2469 | return -EINVAL; | 2526 | return -EINVAL; |
2470 | } else { | 2527 | } else { |
2471 | int retval = dequeue_from_overflow_chain(u132, endp, | 2528 | int retval; |
2529 | |||
2530 | usb_hcd_unlink_urb_from_ep(u132_to_hcd(u132), urb); | ||
2531 | retval = dequeue_from_overflow_chain(u132, endp, | ||
2472 | urb); | 2532 | urb); |
2473 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2533 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2474 | return retval; | 2534 | return retval; |
@@ -2476,7 +2536,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2476 | } | 2536 | } |
2477 | } | 2537 | } |
2478 | 2538 | ||
2479 | static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 2539 | static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
2480 | { | 2540 | { |
2481 | struct u132 *u132 = hcd_to_u132(hcd); | 2541 | struct u132 *u132 = hcd_to_u132(hcd); |
2482 | if (u132->going > 2) { | 2542 | if (u132->going > 2) { |
@@ -2491,11 +2551,11 @@ static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
2491 | if (usb_pipein(urb->pipe)) { | 2551 | if (usb_pipein(urb->pipe)) { |
2492 | u8 endp_number = udev->endp_number_in[usb_endp]; | 2552 | u8 endp_number = udev->endp_number_in[usb_endp]; |
2493 | struct u132_endp *endp = u132->endp[endp_number - 1]; | 2553 | struct u132_endp *endp = u132->endp[endp_number - 1]; |
2494 | return u132_endp_urb_dequeue(u132, endp, urb); | 2554 | return u132_endp_urb_dequeue(u132, endp, urb, status); |
2495 | } else { | 2555 | } else { |
2496 | u8 endp_number = udev->endp_number_out[usb_endp]; | 2556 | u8 endp_number = udev->endp_number_out[usb_endp]; |
2497 | struct u132_endp *endp = u132->endp[endp_number - 1]; | 2557 | struct u132_endp *endp = u132->endp[endp_number - 1]; |
2498 | return u132_endp_urb_dequeue(u132, endp, urb); | 2558 | return u132_endp_urb_dequeue(u132, endp, urb, status); |
2499 | } | 2559 | } |
2500 | } | 2560 | } |
2501 | } | 2561 | } |
@@ -2805,7 +2865,7 @@ static int u132_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2805 | return -ESHUTDOWN; | 2865 | return -ESHUTDOWN; |
2806 | } else { | 2866 | } else { |
2807 | int retval = 0; | 2867 | int retval = 0; |
2808 | down(&u132->sw_lock); | 2868 | mutex_lock(&u132->sw_lock); |
2809 | switch (typeReq) { | 2869 | switch (typeReq) { |
2810 | case ClearHubFeature: | 2870 | case ClearHubFeature: |
2811 | switch (wValue) { | 2871 | switch (wValue) { |
@@ -2868,7 +2928,7 @@ static int u132_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2868 | stall:retval = -EPIPE; | 2928 | stall:retval = -EPIPE; |
2869 | break; | 2929 | break; |
2870 | } | 2930 | } |
2871 | up(&u132->sw_lock); | 2931 | mutex_unlock(&u132->sw_lock); |
2872 | return retval; | 2932 | return retval; |
2873 | } | 2933 | } |
2874 | } | 2934 | } |
@@ -3004,7 +3064,7 @@ static int __devexit u132_remove(struct platform_device *pdev) | |||
3004 | dev_err(&u132->platform_dev->dev, "removing device u132" | 3064 | dev_err(&u132->platform_dev->dev, "removing device u132" |
3005 | ".%d\n", u132->sequence_num); | 3065 | ".%d\n", u132->sequence_num); |
3006 | msleep(100); | 3066 | msleep(100); |
3007 | down(&u132->sw_lock); | 3067 | mutex_lock(&u132->sw_lock); |
3008 | u132_monitor_cancel_work(u132); | 3068 | u132_monitor_cancel_work(u132); |
3009 | while (rings-- > 0) { | 3069 | while (rings-- > 0) { |
3010 | struct u132_ring *ring = &u132->ring[rings]; | 3070 | struct u132_ring *ring = &u132->ring[rings]; |
@@ -3017,7 +3077,7 @@ static int __devexit u132_remove(struct platform_device *pdev) | |||
3017 | u132->going += 1; | 3077 | u132->going += 1; |
3018 | printk(KERN_INFO "removing device u132.%d\n", | 3078 | printk(KERN_INFO "removing device u132.%d\n", |
3019 | u132->sequence_num); | 3079 | u132->sequence_num); |
3020 | up(&u132->sw_lock); | 3080 | mutex_unlock(&u132->sw_lock); |
3021 | usb_remove_hcd(hcd); | 3081 | usb_remove_hcd(hcd); |
3022 | u132_u132_put_kref(u132); | 3082 | u132_u132_put_kref(u132); |
3023 | return 0; | 3083 | return 0; |
@@ -3037,7 +3097,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3037 | u132->platform_dev = pdev; | 3097 | u132->platform_dev = pdev; |
3038 | u132->power = 0; | 3098 | u132->power = 0; |
3039 | u132->reset = 0; | 3099 | u132->reset = 0; |
3040 | init_MUTEX(&u132->sw_lock); | 3100 | mutex_init(&u132->sw_lock); |
3041 | init_MUTEX(&u132->scheduler_lock); | 3101 | init_MUTEX(&u132->scheduler_lock); |
3042 | while (rings-- > 0) { | 3102 | while (rings-- > 0) { |
3043 | struct u132_ring *ring = &u132->ring[rings]; | 3103 | struct u132_ring *ring = &u132->ring[rings]; |
@@ -3047,7 +3107,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3047 | ring->curr_endp = NULL; | 3107 | ring->curr_endp = NULL; |
3048 | INIT_DELAYED_WORK(&ring->scheduler, | 3108 | INIT_DELAYED_WORK(&ring->scheduler, |
3049 | u132_hcd_ring_work_scheduler); | 3109 | u132_hcd_ring_work_scheduler); |
3050 | } down(&u132->sw_lock); | 3110 | } mutex_lock(&u132->sw_lock); |
3051 | INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); | 3111 | INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); |
3052 | while (ports-- > 0) { | 3112 | while (ports-- > 0) { |
3053 | struct u132_port *port = &u132->port[ports]; | 3113 | struct u132_port *port = &u132->port[ports]; |
@@ -3077,7 +3137,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3077 | while (endps-- > 0) { | 3137 | while (endps-- > 0) { |
3078 | u132->endp[endps] = NULL; | 3138 | u132->endp[endps] = NULL; |
3079 | } | 3139 | } |
3080 | up(&u132->sw_lock); | 3140 | mutex_unlock(&u132->sw_lock); |
3081 | return; | 3141 | return; |
3082 | } | 3142 | } |
3083 | 3143 | ||
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 1497371583b9..20cc58b97807 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -120,8 +120,8 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) | |||
120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); | 120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); |
121 | out += sprintf(out, " Actlen=%d", urbp->urb->actual_length); | 121 | out += sprintf(out, " Actlen=%d", urbp->urb->actual_length); |
122 | 122 | ||
123 | if (urbp->urb->status != -EINPROGRESS) | 123 | if (urbp->urb->unlinked) |
124 | out += sprintf(out, " Status=%d", urbp->urb->status); | 124 | out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked); |
125 | out += sprintf(out, "\n"); | 125 | out += sprintf(out, "\n"); |
126 | 126 | ||
127 | i = nactive = ninactive = 0; | 127 | i = nactive = ninactive = 0; |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 1b3d23406ac4..340d6ed3e6e9 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -146,7 +146,6 @@ struct uhci_qh { | |||
146 | short phase; /* Between 0 and period-1 */ | 146 | short phase; /* Between 0 and period-1 */ |
147 | short load; /* Periodic time requirement, in us */ | 147 | short load; /* Periodic time requirement, in us */ |
148 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ | 148 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ |
149 | int iso_status; /* Status for Isochronous URBs */ | ||
150 | 149 | ||
151 | int state; /* QH_STATE_xxx; see above */ | 150 | int state; /* QH_STATE_xxx; see above */ |
152 | int type; /* Queue type (control, bulk, etc) */ | 151 | int type; /* Queue type (control, bulk, etc) */ |
@@ -457,21 +456,6 @@ struct urb_priv { | |||
457 | }; | 456 | }; |
458 | 457 | ||
459 | 458 | ||
460 | /* | ||
461 | * Locking in uhci.c | ||
462 | * | ||
463 | * Almost everything relating to the hardware schedule and processing | ||
464 | * of URBs is protected by uhci->lock. urb->status is protected by | ||
465 | * urb->lock; that's the one exception. | ||
466 | * | ||
467 | * To prevent deadlocks, never lock uhci->lock while holding urb->lock. | ||
468 | * The safe order of locking is: | ||
469 | * | ||
470 | * #1 uhci->lock | ||
471 | * #2 urb->lock | ||
472 | */ | ||
473 | |||
474 | |||
475 | /* Some special IDs */ | 459 | /* Some special IDs */ |
476 | 460 | ||
477 | #define PCI_VENDOR_ID_GENESYS 0x17a0 | 461 | #define PCI_VENDOR_ID_GENESYS 0x17a0 |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 3bb908ca38e9..e5d60d5b105a 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -757,7 +757,6 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci, | |||
757 | uhci_free_td(uhci, td); | 757 | uhci_free_td(uhci, td); |
758 | } | 758 | } |
759 | 759 | ||
760 | urbp->urb->hcpriv = NULL; | ||
761 | kmem_cache_free(uhci_up_cachep, urbp); | 760 | kmem_cache_free(uhci_up_cachep, urbp); |
762 | } | 761 | } |
763 | 762 | ||
@@ -1324,7 +1323,6 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1324 | if (list_empty(&qh->queue)) { | 1323 | if (list_empty(&qh->queue)) { |
1325 | qh->iso_packet_desc = &urb->iso_frame_desc[0]; | 1324 | qh->iso_packet_desc = &urb->iso_frame_desc[0]; |
1326 | qh->iso_frame = urb->start_frame; | 1325 | qh->iso_frame = urb->start_frame; |
1327 | qh->iso_status = 0; | ||
1328 | } | 1326 | } |
1329 | 1327 | ||
1330 | qh->skel = SKEL_ISO; | 1328 | qh->skel = SKEL_ISO; |
@@ -1361,22 +1359,18 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1361 | qh->iso_packet_desc->actual_length = actlength; | 1359 | qh->iso_packet_desc->actual_length = actlength; |
1362 | qh->iso_packet_desc->status = status; | 1360 | qh->iso_packet_desc->status = status; |
1363 | } | 1361 | } |
1364 | 1362 | if (status) | |
1365 | if (status) { | ||
1366 | urb->error_count++; | 1363 | urb->error_count++; |
1367 | qh->iso_status = status; | ||
1368 | } | ||
1369 | 1364 | ||
1370 | uhci_remove_td_from_urbp(td); | 1365 | uhci_remove_td_from_urbp(td); |
1371 | uhci_free_td(uhci, td); | 1366 | uhci_free_td(uhci, td); |
1372 | qh->iso_frame += qh->period; | 1367 | qh->iso_frame += qh->period; |
1373 | ++qh->iso_packet_desc; | 1368 | ++qh->iso_packet_desc; |
1374 | } | 1369 | } |
1375 | return qh->iso_status; | 1370 | return 0; |
1376 | } | 1371 | } |
1377 | 1372 | ||
1378 | static int uhci_urb_enqueue(struct usb_hcd *hcd, | 1373 | static int uhci_urb_enqueue(struct usb_hcd *hcd, |
1379 | struct usb_host_endpoint *hep, | ||
1380 | struct urb *urb, gfp_t mem_flags) | 1374 | struct urb *urb, gfp_t mem_flags) |
1381 | { | 1375 | { |
1382 | int ret; | 1376 | int ret; |
@@ -1387,19 +1381,19 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1387 | 1381 | ||
1388 | spin_lock_irqsave(&uhci->lock, flags); | 1382 | spin_lock_irqsave(&uhci->lock, flags); |
1389 | 1383 | ||
1390 | ret = urb->status; | 1384 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
1391 | if (ret != -EINPROGRESS) /* URB already unlinked! */ | 1385 | if (ret) |
1392 | goto done; | 1386 | goto done_not_linked; |
1393 | 1387 | ||
1394 | ret = -ENOMEM; | 1388 | ret = -ENOMEM; |
1395 | urbp = uhci_alloc_urb_priv(uhci, urb); | 1389 | urbp = uhci_alloc_urb_priv(uhci, urb); |
1396 | if (!urbp) | 1390 | if (!urbp) |
1397 | goto done; | 1391 | goto done; |
1398 | 1392 | ||
1399 | if (hep->hcpriv) | 1393 | if (urb->ep->hcpriv) |
1400 | qh = (struct uhci_qh *) hep->hcpriv; | 1394 | qh = urb->ep->hcpriv; |
1401 | else { | 1395 | else { |
1402 | qh = uhci_alloc_qh(uhci, urb->dev, hep); | 1396 | qh = uhci_alloc_qh(uhci, urb->dev, urb->ep); |
1403 | if (!qh) | 1397 | if (!qh) |
1404 | goto err_no_qh; | 1398 | goto err_no_qh; |
1405 | } | 1399 | } |
@@ -1440,27 +1434,29 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1440 | err_submit_failed: | 1434 | err_submit_failed: |
1441 | if (qh->state == QH_STATE_IDLE) | 1435 | if (qh->state == QH_STATE_IDLE) |
1442 | uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */ | 1436 | uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */ |
1443 | |||
1444 | err_no_qh: | 1437 | err_no_qh: |
1445 | uhci_free_urb_priv(uhci, urbp); | 1438 | uhci_free_urb_priv(uhci, urbp); |
1446 | |||
1447 | done: | 1439 | done: |
1440 | if (ret) | ||
1441 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
1442 | done_not_linked: | ||
1448 | spin_unlock_irqrestore(&uhci->lock, flags); | 1443 | spin_unlock_irqrestore(&uhci->lock, flags); |
1449 | return ret; | 1444 | return ret; |
1450 | } | 1445 | } |
1451 | 1446 | ||
1452 | static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 1447 | static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
1453 | { | 1448 | { |
1454 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 1449 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
1455 | unsigned long flags; | 1450 | unsigned long flags; |
1456 | struct urb_priv *urbp; | ||
1457 | struct uhci_qh *qh; | 1451 | struct uhci_qh *qh; |
1452 | int rc; | ||
1458 | 1453 | ||
1459 | spin_lock_irqsave(&uhci->lock, flags); | 1454 | spin_lock_irqsave(&uhci->lock, flags); |
1460 | urbp = urb->hcpriv; | 1455 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
1461 | if (!urbp) /* URB was never linked! */ | 1456 | if (rc) |
1462 | goto done; | 1457 | goto done; |
1463 | qh = urbp->qh; | 1458 | |
1459 | qh = ((struct urb_priv *) urb->hcpriv)->qh; | ||
1464 | 1460 | ||
1465 | /* Remove Isochronous TDs from the frame list ASAP */ | 1461 | /* Remove Isochronous TDs from the frame list ASAP */ |
1466 | if (qh->type == USB_ENDPOINT_XFER_ISOC) { | 1462 | if (qh->type == USB_ENDPOINT_XFER_ISOC) { |
@@ -1477,14 +1473,14 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
1477 | 1473 | ||
1478 | done: | 1474 | done: |
1479 | spin_unlock_irqrestore(&uhci->lock, flags); | 1475 | spin_unlock_irqrestore(&uhci->lock, flags); |
1480 | return 0; | 1476 | return rc; |
1481 | } | 1477 | } |
1482 | 1478 | ||
1483 | /* | 1479 | /* |
1484 | * Finish unlinking an URB and give it back | 1480 | * Finish unlinking an URB and give it back |
1485 | */ | 1481 | */ |
1486 | static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, | 1482 | static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, |
1487 | struct urb *urb) | 1483 | struct urb *urb, int status) |
1488 | __releases(uhci->lock) | 1484 | __releases(uhci->lock) |
1489 | __acquires(uhci->lock) | 1485 | __acquires(uhci->lock) |
1490 | { | 1486 | { |
@@ -1497,13 +1493,6 @@ __acquires(uhci->lock) | |||
1497 | * unlinked first. Regardless, don't confuse people with a | 1493 | * unlinked first. Regardless, don't confuse people with a |
1498 | * negative length. */ | 1494 | * negative length. */ |
1499 | urb->actual_length = max(urb->actual_length, 0); | 1495 | urb->actual_length = max(urb->actual_length, 0); |
1500 | |||
1501 | /* Report erroneous short transfers */ | ||
1502 | if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && | ||
1503 | urb->actual_length < | ||
1504 | urb->transfer_buffer_length && | ||
1505 | urb->status == 0)) | ||
1506 | urb->status = -EREMOTEIO; | ||
1507 | } | 1496 | } |
1508 | 1497 | ||
1509 | /* When giving back the first URB in an Isochronous queue, | 1498 | /* When giving back the first URB in an Isochronous queue, |
@@ -1516,7 +1505,6 @@ __acquires(uhci->lock) | |||
1516 | 1505 | ||
1517 | qh->iso_packet_desc = &nurb->iso_frame_desc[0]; | 1506 | qh->iso_packet_desc = &nurb->iso_frame_desc[0]; |
1518 | qh->iso_frame = nurb->start_frame; | 1507 | qh->iso_frame = nurb->start_frame; |
1519 | qh->iso_status = 0; | ||
1520 | } | 1508 | } |
1521 | 1509 | ||
1522 | /* Take the URB off the QH's queue. If the queue is now empty, | 1510 | /* Take the URB off the QH's queue. If the queue is now empty, |
@@ -1529,9 +1517,10 @@ __acquires(uhci->lock) | |||
1529 | } | 1517 | } |
1530 | 1518 | ||
1531 | uhci_free_urb_priv(uhci, urbp); | 1519 | uhci_free_urb_priv(uhci, urbp); |
1520 | usb_hcd_unlink_urb_from_ep(uhci_to_hcd(uhci), urb); | ||
1532 | 1521 | ||
1533 | spin_unlock(&uhci->lock); | 1522 | spin_unlock(&uhci->lock); |
1534 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); | 1523 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, status); |
1535 | spin_lock(&uhci->lock); | 1524 | spin_lock(&uhci->lock); |
1536 | 1525 | ||
1537 | /* If the queue is now empty, we can unlink the QH and give up its | 1526 | /* If the queue is now empty, we can unlink the QH and give up its |
@@ -1567,24 +1556,17 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1567 | if (status == -EINPROGRESS) | 1556 | if (status == -EINPROGRESS) |
1568 | break; | 1557 | break; |
1569 | 1558 | ||
1570 | spin_lock(&urb->lock); | ||
1571 | if (urb->status == -EINPROGRESS) /* Not dequeued */ | ||
1572 | urb->status = status; | ||
1573 | else | ||
1574 | status = ECONNRESET; /* Not -ECONNRESET */ | ||
1575 | spin_unlock(&urb->lock); | ||
1576 | |||
1577 | /* Dequeued but completed URBs can't be given back unless | 1559 | /* Dequeued but completed URBs can't be given back unless |
1578 | * the QH is stopped or has finished unlinking. */ | 1560 | * the QH is stopped or has finished unlinking. */ |
1579 | if (status == ECONNRESET) { | 1561 | if (urb->unlinked) { |
1580 | if (QH_FINISHED_UNLINKING(qh)) | 1562 | if (QH_FINISHED_UNLINKING(qh)) |
1581 | qh->is_stopped = 1; | 1563 | qh->is_stopped = 1; |
1582 | else if (!qh->is_stopped) | 1564 | else if (!qh->is_stopped) |
1583 | return; | 1565 | return; |
1584 | } | 1566 | } |
1585 | 1567 | ||
1586 | uhci_giveback_urb(uhci, qh, urb); | 1568 | uhci_giveback_urb(uhci, qh, urb, status); |
1587 | if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC) | 1569 | if (status < 0) |
1588 | break; | 1570 | break; |
1589 | } | 1571 | } |
1590 | 1572 | ||
@@ -1599,7 +1581,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1599 | restart: | 1581 | restart: |
1600 | list_for_each_entry(urbp, &qh->queue, node) { | 1582 | list_for_each_entry(urbp, &qh->queue, node) { |
1601 | urb = urbp->urb; | 1583 | urb = urbp->urb; |
1602 | if (urb->status != -EINPROGRESS) { | 1584 | if (urb->unlinked) { |
1603 | 1585 | ||
1604 | /* Fix up the TD links and save the toggles for | 1586 | /* Fix up the TD links and save the toggles for |
1605 | * non-Isochronous queues. For Isochronous queues, | 1587 | * non-Isochronous queues. For Isochronous queues, |
@@ -1608,7 +1590,7 @@ restart: | |||
1608 | qh->is_stopped = 0; | 1590 | qh->is_stopped = 0; |
1609 | return; | 1591 | return; |
1610 | } | 1592 | } |
1611 | uhci_giveback_urb(uhci, qh, urb); | 1593 | uhci_giveback_urb(uhci, qh, urb, 0); |
1612 | goto restart; | 1594 | goto restart; |
1613 | } | 1595 | } |
1614 | } | 1596 | } |
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index e9fdbc8997b3..5131cbfb2f52 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -188,7 +188,8 @@ static void adu_interrupt_in_callback(struct urb *urb) | |||
188 | spin_lock(&dev->buflock); | 188 | spin_lock(&dev->buflock); |
189 | 189 | ||
190 | if (status != 0) { | 190 | if (status != 0) { |
191 | if ((status != -ENOENT) && (status != -ECONNRESET)) { | 191 | if ((status != -ENOENT) && (status != -ECONNRESET) && |
192 | (status != -ESHUTDOWN)) { | ||
192 | dbg(1," %s : nonzero status received: %d", | 193 | dbg(1," %s : nonzero status received: %d", |
193 | __FUNCTION__, status); | 194 | __FUNCTION__, status); |
194 | } | 195 | } |
diff --git a/drivers/usb/misc/berry_charge.c b/drivers/usb/misc/berry_charge.c index 92c1d2768df9..24e2dc3148a4 100644 --- a/drivers/usb/misc/berry_charge.c +++ b/drivers/usb/misc/berry_charge.c | |||
@@ -71,7 +71,7 @@ static int magic_charge(struct usb_device *udev) | |||
71 | if (retval != 2) { | 71 | if (retval != 2) { |
72 | dev_err(&udev->dev, "First magic command failed: %d.\n", | 72 | dev_err(&udev->dev, "First magic command failed: %d.\n", |
73 | retval); | 73 | retval); |
74 | return retval; | 74 | goto exit; |
75 | } | 75 | } |
76 | 76 | ||
77 | dbg(&udev->dev, "Sending second magic command\n"); | 77 | dbg(&udev->dev, "Sending second magic command\n"); |
@@ -80,7 +80,7 @@ static int magic_charge(struct usb_device *udev) | |||
80 | if (retval != 0) { | 80 | if (retval != 0) { |
81 | dev_err(&udev->dev, "Second magic command failed: %d.\n", | 81 | dev_err(&udev->dev, "Second magic command failed: %d.\n", |
82 | retval); | 82 | retval); |
83 | return retval; | 83 | goto exit; |
84 | } | 84 | } |
85 | 85 | ||
86 | dbg(&udev->dev, "Calling set_configuration\n"); | 86 | dbg(&udev->dev, "Calling set_configuration\n"); |
@@ -88,6 +88,8 @@ static int magic_charge(struct usb_device *udev) | |||
88 | if (retval) | 88 | if (retval) |
89 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); | 89 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); |
90 | 90 | ||
91 | exit: | ||
92 | kfree(dummy_buffer); | ||
91 | return retval; | 93 | return retval; |
92 | } | 94 | } |
93 | 95 | ||
@@ -112,6 +114,7 @@ static int magic_dual_mode(struct usb_device *udev) | |||
112 | if (retval) | 114 | if (retval) |
113 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); | 115 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); |
114 | 116 | ||
117 | kfree(dummy_buffer); | ||
115 | return retval; | 118 | return retval; |
116 | } | 119 | } |
117 | 120 | ||
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 538b535e955b..d3d8cd6ff103 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -2777,12 +2777,14 @@ static int ftdi_elan_probe(struct usb_interface *interface, | |||
2777 | size_t buffer_size; | 2777 | size_t buffer_size; |
2778 | int i; | 2778 | int i; |
2779 | int retval = -ENOMEM; | 2779 | int retval = -ENOMEM; |
2780 | struct usb_ftdi *ftdi = kmalloc(sizeof(struct usb_ftdi), GFP_KERNEL); | 2780 | struct usb_ftdi *ftdi; |
2781 | if (ftdi == NULL) { | 2781 | |
2782 | ftdi = kzalloc(sizeof(struct usb_ftdi), GFP_KERNEL); | ||
2783 | if (!ftdi) { | ||
2782 | printk(KERN_ERR "Out of memory\n"); | 2784 | printk(KERN_ERR "Out of memory\n"); |
2783 | return -ENOMEM; | 2785 | return -ENOMEM; |
2784 | } | 2786 | } |
2785 | memset(ftdi, 0x00, sizeof(struct usb_ftdi)); | 2787 | |
2786 | mutex_lock(&ftdi_module_lock); | 2788 | mutex_lock(&ftdi_module_lock); |
2787 | list_add_tail(&ftdi->ftdi_list, &ftdi_static_list); | 2789 | list_add_tail(&ftdi->ftdi_list, &ftdi_static_list); |
2788 | ftdi->sequence_num = ++ftdi_instances; | 2790 | ftdi->sequence_num = ++ftdi_instances; |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index b64ca91d9b02..9244d067cec1 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | * | 34 | * |
35 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 35 | * Author: Thomas Winischhofer <thomas@winischhofer.net> |
36 | * | 36 | * |
37 | */ | 37 | */ |
38 | 38 | ||
@@ -962,12 +962,12 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
962 | packet.address = 0x00000194; | 962 | packet.address = 0x00000194; |
963 | packet.data = addr; | 963 | packet.data = addr; |
964 | ret = sisusb_send_bridge_packet(sisusb, 10, | 964 | ret = sisusb_send_bridge_packet(sisusb, 10, |
965 | &packet, 0); | 965 | &packet, 0); |
966 | packet.header = 0x001f; | 966 | packet.header = 0x001f; |
967 | packet.address = 0x00000190; | 967 | packet.address = 0x00000190; |
968 | packet.data = (length & ~3); | 968 | packet.data = (length & ~3); |
969 | ret |= sisusb_send_bridge_packet(sisusb, 10, | 969 | ret |= sisusb_send_bridge_packet(sisusb, 10, |
970 | &packet, 0); | 970 | &packet, 0); |
971 | if (sisusb->flagb0 != 0x16) { | 971 | if (sisusb->flagb0 != 0x16) { |
972 | packet.header = 0x001f; | 972 | packet.header = 0x001f; |
973 | packet.address = 0x00000180; | 973 | packet.address = 0x00000180; |
@@ -1003,23 +1003,17 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
1003 | if (ret) { | 1003 | if (ret) { |
1004 | msgcount++; | 1004 | msgcount++; |
1005 | if (msgcount < 500) | 1005 | if (msgcount < 500) |
1006 | printk(KERN_ERR | 1006 | dev_err(&sisusb->sisusb_dev->dev, "Wrote %zd of %d bytes, error %d\n", |
1007 | "sisusbvga[%d]: Wrote %zd of " | 1007 | *bytes_written, length, ret); |
1008 | "%d bytes, error %d\n", | ||
1009 | sisusb->minor, *bytes_written, | ||
1010 | length, ret); | ||
1011 | else if (msgcount == 500) | 1008 | else if (msgcount == 500) |
1012 | printk(KERN_ERR | 1009 | dev_err(&sisusb->sisusb_dev->dev, "Too many errors, logging stopped\n"); |
1013 | "sisusbvga[%d]: Too many errors" | ||
1014 | ", logging stopped\n", | ||
1015 | sisusb->minor); | ||
1016 | } | 1010 | } |
1017 | addr += (*bytes_written); | 1011 | addr += (*bytes_written); |
1018 | length -= (*bytes_written); | 1012 | length -= (*bytes_written); |
1019 | } | 1013 | } |
1020 | 1014 | ||
1021 | if (ret) | 1015 | if (ret) |
1022 | break; | 1016 | break; |
1023 | 1017 | ||
1024 | } | 1018 | } |
1025 | 1019 | ||
@@ -1261,51 +1255,10 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
1261 | addr += 4; | 1255 | addr += 4; |
1262 | length -= 4; | 1256 | length -= 4; |
1263 | } | 1257 | } |
1264 | #if 0 /* That does not work, as EP 2 is an OUT EP! */ | ||
1265 | default: | ||
1266 | CLEARPACKET(&packet); | ||
1267 | packet.header = 0x001f; | ||
1268 | packet.address = 0x000001a0; | ||
1269 | packet.data = 0x00000006; | ||
1270 | ret |= sisusb_send_bridge_packet(sisusb, 10, | ||
1271 | &packet, 0); | ||
1272 | packet.header = 0x001f; | ||
1273 | packet.address = 0x000001b0; | ||
1274 | packet.data = (length & ~3) | 0x40000000; | ||
1275 | ret |= sisusb_send_bridge_packet(sisusb, 10, | ||
1276 | &packet, 0); | ||
1277 | packet.header = 0x001f; | ||
1278 | packet.address = 0x000001b4; | ||
1279 | packet.data = addr; | ||
1280 | ret |= sisusb_send_bridge_packet(sisusb, 10, | ||
1281 | &packet, 0); | ||
1282 | packet.header = 0x001f; | ||
1283 | packet.address = 0x000001a4; | ||
1284 | packet.data = 0x00000001; | ||
1285 | ret |= sisusb_send_bridge_packet(sisusb, 10, | ||
1286 | &packet, 0); | ||
1287 | if (userbuffer) { | ||
1288 | ret |= sisusb_recv_bulk_msg(sisusb, | ||
1289 | SISUSB_EP_GFX_BULK_IN, | ||
1290 | (length & ~3), | ||
1291 | NULL, userbuffer, | ||
1292 | bytes_read, 0); | ||
1293 | if (!ret) userbuffer += (*bytes_read); | ||
1294 | } else { | ||
1295 | ret |= sisusb_recv_bulk_msg(sisusb, | ||
1296 | SISUSB_EP_GFX_BULK_IN, | ||
1297 | (length & ~3), | ||
1298 | kernbuffer, NULL, | ||
1299 | bytes_read, 0); | ||
1300 | if (!ret) kernbuffer += (*bytes_read); | ||
1301 | } | ||
1302 | addr += (*bytes_read); | ||
1303 | length -= (*bytes_read); | ||
1304 | #endif | ||
1305 | } | 1258 | } |
1306 | 1259 | ||
1307 | if (ret) | 1260 | if (ret) |
1308 | break; | 1261 | break; |
1309 | } | 1262 | } |
1310 | 1263 | ||
1311 | return ret; | 1264 | return ret; |
@@ -1401,22 +1354,6 @@ sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data) | |||
1401 | return(sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data)); | 1354 | return(sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data)); |
1402 | } | 1355 | } |
1403 | 1356 | ||
1404 | #if 0 | ||
1405 | |||
1406 | int | ||
1407 | sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data) | ||
1408 | { | ||
1409 | return(sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, adr, data)); | ||
1410 | } | ||
1411 | |||
1412 | int | ||
1413 | sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data) | ||
1414 | { | ||
1415 | return(sisusb_read_memio_word(sisusb, SISUSB_TYPE_MEM, adr, data)); | ||
1416 | } | ||
1417 | |||
1418 | #endif /* 0 */ | ||
1419 | |||
1420 | int | 1357 | int |
1421 | sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, | 1358 | sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, |
1422 | u32 dest, int length, size_t *bytes_written) | 1359 | u32 dest, int length, size_t *bytes_written) |
@@ -1446,10 +1383,10 @@ sisusb_testreadwrite(struct sisusb_usb_data *sisusb) | |||
1446 | sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7, &dummy); | 1383 | sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7, &dummy); |
1447 | 1384 | ||
1448 | for(i = 1; i <= 7; i++) { | 1385 | for(i = 1; i <= 7; i++) { |
1449 | printk(KERN_DEBUG "sisusb: rwtest %d bytes\n", i); | 1386 | dev_dbg(&sisusb->sisusb_dev->dev, "sisusb: rwtest %d bytes\n", i); |
1450 | sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i, &dummy); | 1387 | sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i, &dummy); |
1451 | for(j = 0; j < i; j++) { | 1388 | for(j = 0; j < i; j++) { |
1452 | printk(KERN_DEBUG "sisusb: rwtest read[%d] = %x\n", j, destbuffer[j]); | 1389 | dev_dbg(&sisusb->sisusb_dev->dev, "rwtest read[%d] = %x\n", j, destbuffer[j]); |
1453 | } | 1390 | } |
1454 | } | 1391 | } |
1455 | } | 1392 | } |
@@ -1533,9 +1470,9 @@ sisusb_clear_vram(struct sisusb_usb_data *sisusb, u32 address, int length) | |||
1533 | #define SETIREGAND(r,i,a) sisusb_setidxregand(sisusb, r, i, a) | 1470 | #define SETIREGAND(r,i,a) sisusb_setidxregand(sisusb, r, i, a) |
1534 | #define SETIREGANDOR(r,i,a,o) sisusb_setidxregandor(sisusb, r, i, a, o) | 1471 | #define SETIREGANDOR(r,i,a,o) sisusb_setidxregandor(sisusb, r, i, a, o) |
1535 | #define READL(a,d) sisusb_read_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) | 1472 | #define READL(a,d) sisusb_read_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) |
1536 | #define WRITEL(a,d) sisusb_write_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) | 1473 | #define WRITEL(a,d) sisusb_write_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) |
1537 | #define READB(a,d) sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) | 1474 | #define READB(a,d) sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) |
1538 | #define WRITEB(a,d) sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) | 1475 | #define WRITEB(a,d) sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) |
1539 | 1476 | ||
1540 | static int | 1477 | static int |
1541 | sisusb_triggersr16(struct sisusb_usb_data *sisusb, u8 ramtype) | 1478 | sisusb_triggersr16(struct sisusb_usb_data *sisusb, u8 ramtype) |
@@ -2008,7 +1945,7 @@ sisusb_set_default_mode(struct sisusb_usb_data *sisusb, int touchengines) | |||
2008 | SETIREG(SISSR, 0x26, 0x00); | 1945 | SETIREG(SISSR, 0x26, 0x00); |
2009 | } | 1946 | } |
2010 | 1947 | ||
2011 | SETIREG(SISCR, 0x34, 0x44); /* we just set std mode #44 */ | 1948 | SETIREG(SISCR, 0x34, 0x44); /* we just set std mode #44 */ |
2012 | 1949 | ||
2013 | return ret; | 1950 | return ret; |
2014 | } | 1951 | } |
@@ -2168,17 +2105,12 @@ sisusb_init_gfxcore(struct sisusb_usb_data *sisusb) | |||
2168 | if (ramtype <= 1) { | 2105 | if (ramtype <= 1) { |
2169 | ret |= sisusb_get_sdram_size(sisusb, &iret, bw, chab); | 2106 | ret |= sisusb_get_sdram_size(sisusb, &iret, bw, chab); |
2170 | if (iret) { | 2107 | if (iret) { |
2171 | printk(KERN_ERR "sisusbvga[%d]: RAM size " | 2108 | dev_err(&sisusb->sisusb_dev->dev,"RAM size detection failed, assuming 8MB video RAM\n"); |
2172 | "detection failed, " | ||
2173 | "assuming 8MB video RAM\n", | ||
2174 | sisusb->minor); | ||
2175 | ret |= SETIREG(SISSR,0x14,0x31); | 2109 | ret |= SETIREG(SISSR,0x14,0x31); |
2176 | /* TODO */ | 2110 | /* TODO */ |
2177 | } | 2111 | } |
2178 | } else { | 2112 | } else { |
2179 | printk(KERN_ERR "sisusbvga[%d]: DDR RAM device found, " | 2113 | dev_err(&sisusb->sisusb_dev->dev, "DDR RAM device found, assuming 8MB video RAM\n"); |
2180 | "assuming 8MB video RAM\n", | ||
2181 | sisusb->minor); | ||
2182 | ret |= SETIREG(SISSR,0x14,0x31); | 2114 | ret |= SETIREG(SISSR,0x14,0x31); |
2183 | /* *** TODO *** */ | 2115 | /* *** TODO *** */ |
2184 | } | 2116 | } |
@@ -2249,8 +2181,7 @@ sisusb_get_ramconfig(struct sisusb_usb_data *sisusb) | |||
2249 | break; | 2181 | break; |
2250 | } | 2182 | } |
2251 | 2183 | ||
2252 | printk(KERN_INFO "sisusbvga[%d]: %dMB %s %s, bus width %d\n", | 2184 | dev_info(&sisusb->sisusb_dev->dev, "%dMB %s %s, bus width %d\n", (sisusb->vramsize >> 20), ramtypetext1, |
2253 | sisusb->minor, (sisusb->vramsize >> 20), ramtypetext1, | ||
2254 | ramtypetext2[ramtype], bw); | 2185 | ramtypetext2[ramtype], bw); |
2255 | } | 2186 | } |
2256 | 2187 | ||
@@ -2509,11 +2440,8 @@ sisusb_open(struct inode *inode, struct file *file) | |||
2509 | struct usb_interface *interface; | 2440 | struct usb_interface *interface; |
2510 | int subminor = iminor(inode); | 2441 | int subminor = iminor(inode); |
2511 | 2442 | ||
2512 | if (!(interface = usb_find_interface(&sisusb_driver, subminor))) { | 2443 | if (!(interface = usb_find_interface(&sisusb_driver, subminor))) |
2513 | printk(KERN_ERR "sisusb[%d]: Failed to find interface\n", | ||
2514 | subminor); | ||
2515 | return -ENODEV; | 2444 | return -ENODEV; |
2516 | } | ||
2517 | 2445 | ||
2518 | if (!(sisusb = usb_get_intfdata(interface))) | 2446 | if (!(sisusb = usb_get_intfdata(interface))) |
2519 | return -ENODEV; | 2447 | return -ENODEV; |
@@ -2534,18 +2462,12 @@ sisusb_open(struct inode *inode, struct file *file) | |||
2534 | if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) { | 2462 | if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) { |
2535 | if (sisusb_init_gfxdevice(sisusb, 0)) { | 2463 | if (sisusb_init_gfxdevice(sisusb, 0)) { |
2536 | mutex_unlock(&sisusb->lock); | 2464 | mutex_unlock(&sisusb->lock); |
2537 | printk(KERN_ERR | 2465 | dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n"); |
2538 | "sisusbvga[%d]: Failed to initialize " | ||
2539 | "device\n", | ||
2540 | sisusb->minor); | ||
2541 | return -EIO; | 2466 | return -EIO; |
2542 | } | 2467 | } |
2543 | } else { | 2468 | } else { |
2544 | mutex_unlock(&sisusb->lock); | 2469 | mutex_unlock(&sisusb->lock); |
2545 | printk(KERN_ERR | 2470 | dev_err(&sisusb->sisusb_dev->dev, "Device not attached to USB 2.0 hub\n"); |
2546 | "sisusbvga[%d]: Device not attached to " | ||
2547 | "USB 2.0 hub\n", | ||
2548 | sisusb->minor); | ||
2549 | return -EIO; | 2471 | return -EIO; |
2550 | } | 2472 | } |
2551 | } | 2473 | } |
@@ -2586,7 +2508,6 @@ static int | |||
2586 | sisusb_release(struct inode *inode, struct file *file) | 2508 | sisusb_release(struct inode *inode, struct file *file) |
2587 | { | 2509 | { |
2588 | struct sisusb_usb_data *sisusb; | 2510 | struct sisusb_usb_data *sisusb; |
2589 | int myminor; | ||
2590 | 2511 | ||
2591 | if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) | 2512 | if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) |
2592 | return -ENODEV; | 2513 | return -ENODEV; |
@@ -2599,8 +2520,6 @@ sisusb_release(struct inode *inode, struct file *file) | |||
2599 | sisusb_kill_all_busy(sisusb); | 2520 | sisusb_kill_all_busy(sisusb); |
2600 | } | 2521 | } |
2601 | 2522 | ||
2602 | myminor = sisusb->minor; | ||
2603 | |||
2604 | sisusb->isopen = 0; | 2523 | sisusb->isopen = 0; |
2605 | file->private_data = NULL; | 2524 | file->private_data = NULL; |
2606 | 2525 | ||
@@ -2942,7 +2861,7 @@ static int | |||
2942 | sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y, | 2861 | sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y, |
2943 | unsigned long arg) | 2862 | unsigned long arg) |
2944 | { | 2863 | { |
2945 | int retval, port, length; | 2864 | int retval, port, length; |
2946 | u32 address; | 2865 | u32 address; |
2947 | 2866 | ||
2948 | /* All our commands require the device | 2867 | /* All our commands require the device |
@@ -3065,12 +2984,12 @@ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y, | |||
3065 | 2984 | ||
3066 | static int | 2985 | static int |
3067 | sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 2986 | sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
3068 | unsigned long arg) | 2987 | unsigned long arg) |
3069 | { | 2988 | { |
3070 | struct sisusb_usb_data *sisusb; | 2989 | struct sisusb_usb_data *sisusb; |
3071 | struct sisusb_info x; | 2990 | struct sisusb_info x; |
3072 | struct sisusb_command y; | 2991 | struct sisusb_command y; |
3073 | int retval = 0; | 2992 | int retval = 0; |
3074 | u32 __user *argp = (u32 __user *)arg; | 2993 | u32 __user *argp = (u32 __user *)arg; |
3075 | 2994 | ||
3076 | if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) | 2995 | if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) |
@@ -3095,7 +3014,7 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
3095 | 3014 | ||
3096 | case SISUSB_GET_CONFIG: | 3015 | case SISUSB_GET_CONFIG: |
3097 | 3016 | ||
3098 | x.sisusb_id = SISUSB_ID; | 3017 | x.sisusb_id = SISUSB_ID; |
3099 | x.sisusb_version = SISUSB_VERSION; | 3018 | x.sisusb_version = SISUSB_VERSION; |
3100 | x.sisusb_revision = SISUSB_REVISION; | 3019 | x.sisusb_revision = SISUSB_REVISION; |
3101 | x.sisusb_patchlevel = SISUSB_PATCHLEVEL; | 3020 | x.sisusb_patchlevel = SISUSB_PATCHLEVEL; |
@@ -3164,7 +3083,7 @@ static const struct file_operations usb_sisusb_fops = { | |||
3164 | .release = sisusb_release, | 3083 | .release = sisusb_release, |
3165 | .read = sisusb_read, | 3084 | .read = sisusb_read, |
3166 | .write = sisusb_write, | 3085 | .write = sisusb_write, |
3167 | .llseek = sisusb_lseek, | 3086 | .llseek = sisusb_lseek, |
3168 | #ifdef SISUSB_NEW_CONFIG_COMPAT | 3087 | #ifdef SISUSB_NEW_CONFIG_COMPAT |
3169 | .compat_ioctl = sisusb_compat_ioctl, | 3088 | .compat_ioctl = sisusb_compat_ioctl, |
3170 | #endif | 3089 | #endif |
@@ -3183,17 +3102,13 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3183 | struct usb_device *dev = interface_to_usbdev(intf); | 3102 | struct usb_device *dev = interface_to_usbdev(intf); |
3184 | struct sisusb_usb_data *sisusb; | 3103 | struct sisusb_usb_data *sisusb; |
3185 | int retval = 0, i; | 3104 | int retval = 0, i; |
3186 | const char *memfail = | ||
3187 | KERN_ERR | ||
3188 | "sisusbvga[%d]: Failed to allocate memory for %s buffer\n"; | ||
3189 | 3105 | ||
3190 | printk(KERN_INFO "sisusb: USB2VGA dongle found at address %d\n", | 3106 | dev_info(&dev->dev, "USB2VGA dongle found at address %d\n", |
3191 | dev->devnum); | 3107 | dev->devnum); |
3192 | 3108 | ||
3193 | /* Allocate memory for our private */ | 3109 | /* Allocate memory for our private */ |
3194 | if (!(sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL))) { | 3110 | if (!(sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL))) { |
3195 | printk(KERN_ERR | 3111 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for private data\n"); |
3196 | "sisusb: Failed to allocate memory for private data\n"); | ||
3197 | return -ENOMEM; | 3112 | return -ENOMEM; |
3198 | } | 3113 | } |
3199 | kref_init(&sisusb->kref); | 3114 | kref_init(&sisusb->kref); |
@@ -3202,8 +3117,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3202 | 3117 | ||
3203 | /* Register device */ | 3118 | /* Register device */ |
3204 | if ((retval = usb_register_dev(intf, &usb_sisusb_class))) { | 3119 | if ((retval = usb_register_dev(intf, &usb_sisusb_class))) { |
3205 | printk(KERN_ERR | 3120 | dev_err(&sisusb->sisusb_dev->dev, "Failed to get a minor for device %d\n", |
3206 | "sisusb: Failed to get a minor for device %d\n", | ||
3207 | dev->devnum); | 3121 | dev->devnum); |
3208 | retval = -ENODEV; | 3122 | retval = -ENODEV; |
3209 | goto error_1; | 3123 | goto error_1; |
@@ -3221,7 +3135,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3221 | sisusb->ibufsize = SISUSB_IBUF_SIZE; | 3135 | sisusb->ibufsize = SISUSB_IBUF_SIZE; |
3222 | if (!(sisusb->ibuf = usb_buffer_alloc(dev, SISUSB_IBUF_SIZE, | 3136 | if (!(sisusb->ibuf = usb_buffer_alloc(dev, SISUSB_IBUF_SIZE, |
3223 | GFP_KERNEL, &sisusb->transfer_dma_in))) { | 3137 | GFP_KERNEL, &sisusb->transfer_dma_in))) { |
3224 | printk(memfail, "input", sisusb->minor); | 3138 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for input buffer"); |
3225 | retval = -ENOMEM; | 3139 | retval = -ENOMEM; |
3226 | goto error_2; | 3140 | goto error_2; |
3227 | } | 3141 | } |
@@ -3233,7 +3147,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3233 | GFP_KERNEL, | 3147 | GFP_KERNEL, |
3234 | &sisusb->transfer_dma_out[i]))) { | 3148 | &sisusb->transfer_dma_out[i]))) { |
3235 | if (i == 0) { | 3149 | if (i == 0) { |
3236 | printk(memfail, "output", sisusb->minor); | 3150 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for output buffer\n"); |
3237 | retval = -ENOMEM; | 3151 | retval = -ENOMEM; |
3238 | goto error_3; | 3152 | goto error_3; |
3239 | } | 3153 | } |
@@ -3245,9 +3159,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3245 | 3159 | ||
3246 | /* Allocate URBs */ | 3160 | /* Allocate URBs */ |
3247 | if (!(sisusb->sisurbin = usb_alloc_urb(0, GFP_KERNEL))) { | 3161 | if (!(sisusb->sisurbin = usb_alloc_urb(0, GFP_KERNEL))) { |
3248 | printk(KERN_ERR | 3162 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate URBs\n"); |
3249 | "sisusbvga[%d]: Failed to allocate URBs\n", | ||
3250 | sisusb->minor); | ||
3251 | retval = -ENOMEM; | 3163 | retval = -ENOMEM; |
3252 | goto error_3; | 3164 | goto error_3; |
3253 | } | 3165 | } |
@@ -3255,9 +3167,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3255 | 3167 | ||
3256 | for (i = 0; i < sisusb->numobufs; i++) { | 3168 | for (i = 0; i < sisusb->numobufs; i++) { |
3257 | if (!(sisusb->sisurbout[i] = usb_alloc_urb(0, GFP_KERNEL))) { | 3169 | if (!(sisusb->sisurbout[i] = usb_alloc_urb(0, GFP_KERNEL))) { |
3258 | printk(KERN_ERR | 3170 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate URBs\n"); |
3259 | "sisusbvga[%d]: Failed to allocate URBs\n", | ||
3260 | sisusb->minor); | ||
3261 | retval = -ENOMEM; | 3171 | retval = -ENOMEM; |
3262 | goto error_4; | 3172 | goto error_4; |
3263 | } | 3173 | } |
@@ -3266,15 +3176,12 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3266 | sisusb->urbstatus[i] = 0; | 3176 | sisusb->urbstatus[i] = 0; |
3267 | } | 3177 | } |
3268 | 3178 | ||
3269 | printk(KERN_INFO "sisusbvga[%d]: Allocated %d output buffers\n", | 3179 | dev_info(&sisusb->sisusb_dev->dev, "Allocated %d output buffers\n", sisusb->numobufs); |
3270 | sisusb->minor, sisusb->numobufs); | ||
3271 | 3180 | ||
3272 | #ifdef INCL_SISUSB_CON | 3181 | #ifdef INCL_SISUSB_CON |
3273 | /* Allocate our SiS_Pr */ | 3182 | /* Allocate our SiS_Pr */ |
3274 | if (!(sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL))) { | 3183 | if (!(sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL))) { |
3275 | printk(KERN_ERR | 3184 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate SiS_Pr\n"); |
3276 | "sisusbvga[%d]: Failed to allocate SiS_Pr\n", | ||
3277 | sisusb->minor); | ||
3278 | } | 3185 | } |
3279 | #endif | 3186 | #endif |
3280 | 3187 | ||
@@ -3296,10 +3203,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3296 | ret |= register_ioctl32_conversion(SISUSB_GET_CONFIG, NULL); | 3203 | ret |= register_ioctl32_conversion(SISUSB_GET_CONFIG, NULL); |
3297 | ret |= register_ioctl32_conversion(SISUSB_COMMAND, NULL); | 3204 | ret |= register_ioctl32_conversion(SISUSB_COMMAND, NULL); |
3298 | if (ret) | 3205 | if (ret) |
3299 | printk(KERN_ERR | 3206 | dev_err(&sisusb->sisusb_dev->dev, "Error registering ioctl32 translations\n"); |
3300 | "sisusbvga[%d]: Error registering ioctl32 " | ||
3301 | "translations\n", | ||
3302 | sisusb->minor); | ||
3303 | else | 3207 | else |
3304 | sisusb->ioctl32registered = 1; | 3208 | sisusb->ioctl32registered = 1; |
3305 | } | 3209 | } |
@@ -3315,23 +3219,17 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3315 | initscreen = 0; | 3219 | initscreen = 0; |
3316 | #endif | 3220 | #endif |
3317 | if (sisusb_init_gfxdevice(sisusb, initscreen)) | 3221 | if (sisusb_init_gfxdevice(sisusb, initscreen)) |
3318 | printk(KERN_ERR | 3222 | dev_err(&sisusb->sisusb_dev->dev, "Failed to early initialize device\n"); |
3319 | "sisusbvga[%d]: Failed to early " | ||
3320 | "initialize device\n", | ||
3321 | sisusb->minor); | ||
3322 | 3223 | ||
3323 | } else | 3224 | } else |
3324 | printk(KERN_INFO | 3225 | dev_info(&sisusb->sisusb_dev->dev, "Not attached to USB 2.0 hub, deferring init\n"); |
3325 | "sisusbvga[%d]: Not attached to USB 2.0 hub, " | ||
3326 | "deferring init\n", | ||
3327 | sisusb->minor); | ||
3328 | 3226 | ||
3329 | sisusb->ready = 1; | 3227 | sisusb->ready = 1; |
3330 | 3228 | ||
3331 | #ifdef SISUSBENDIANTEST | 3229 | #ifdef SISUSBENDIANTEST |
3332 | printk(KERN_DEBUG "sisusb: *** RWTEST ***\n"); | 3230 | dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST ***\n"); |
3333 | sisusb_testreadwrite(sisusb); | 3231 | sisusb_testreadwrite(sisusb); |
3334 | printk(KERN_DEBUG "sisusb: *** RWTEST END ***\n"); | 3232 | dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST END ***\n"); |
3335 | #endif | 3233 | #endif |
3336 | 3234 | ||
3337 | #ifdef INCL_SISUSB_CON | 3235 | #ifdef INCL_SISUSB_CON |
@@ -3354,7 +3252,6 @@ error_1: | |||
3354 | static void sisusb_disconnect(struct usb_interface *intf) | 3252 | static void sisusb_disconnect(struct usb_interface *intf) |
3355 | { | 3253 | { |
3356 | struct sisusb_usb_data *sisusb; | 3254 | struct sisusb_usb_data *sisusb; |
3357 | int minor; | ||
3358 | 3255 | ||
3359 | /* This should *not* happen */ | 3256 | /* This should *not* happen */ |
3360 | if (!(sisusb = usb_get_intfdata(intf))) | 3257 | if (!(sisusb = usb_get_intfdata(intf))) |
@@ -3364,8 +3261,6 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3364 | sisusb_console_exit(sisusb); | 3261 | sisusb_console_exit(sisusb); |
3365 | #endif | 3262 | #endif |
3366 | 3263 | ||
3367 | minor = sisusb->minor; | ||
3368 | |||
3369 | usb_deregister_dev(intf, &usb_sisusb_class); | 3264 | usb_deregister_dev(intf, &usb_sisusb_class); |
3370 | 3265 | ||
3371 | mutex_lock(&sisusb->lock); | 3266 | mutex_lock(&sisusb->lock); |
@@ -3384,10 +3279,7 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3384 | ret |= unregister_ioctl32_conversion(SISUSB_GET_CONFIG); | 3279 | ret |= unregister_ioctl32_conversion(SISUSB_GET_CONFIG); |
3385 | ret |= unregister_ioctl32_conversion(SISUSB_COMMAND); | 3280 | ret |= unregister_ioctl32_conversion(SISUSB_COMMAND); |
3386 | if (ret) { | 3281 | if (ret) { |
3387 | printk(KERN_ERR | 3282 | dev_err(&sisusb->sisusb_dev->dev, "Error unregistering ioctl32 translations\n"); |
3388 | "sisusbvga[%d]: Error unregistering " | ||
3389 | "ioctl32 translations\n", | ||
3390 | minor); | ||
3391 | } | 3283 | } |
3392 | } | 3284 | } |
3393 | #endif | 3285 | #endif |
@@ -3400,7 +3292,7 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3400 | /* decrement our usage count */ | 3292 | /* decrement our usage count */ |
3401 | kref_put(&sisusb->kref, sisusb_delete); | 3293 | kref_put(&sisusb->kref, sisusb_delete); |
3402 | 3294 | ||
3403 | printk(KERN_INFO "sisusbvga[%d]: Disconnected\n", minor); | 3295 | dev_info(&sisusb->sisusb_dev->dev, "Disconnected\n"); |
3404 | } | 3296 | } |
3405 | 3297 | ||
3406 | static struct usb_device_id sisusb_table [] = { | 3298 | static struct usb_device_id sisusb_table [] = { |
@@ -3424,22 +3316,12 @@ static struct usb_driver sisusb_driver = { | |||
3424 | 3316 | ||
3425 | static int __init usb_sisusb_init(void) | 3317 | static int __init usb_sisusb_init(void) |
3426 | { | 3318 | { |
3427 | int retval; | ||
3428 | 3319 | ||
3429 | #ifdef INCL_SISUSB_CON | 3320 | #ifdef INCL_SISUSB_CON |
3430 | sisusb_init_concode(); | 3321 | sisusb_init_concode(); |
3431 | #endif | 3322 | #endif |
3432 | 3323 | ||
3433 | if (!(retval = usb_register(&sisusb_driver))) { | 3324 | return usb_register(&sisusb_driver); |
3434 | |||
3435 | printk(KERN_INFO "sisusb: Driver version %d.%d.%d\n", | ||
3436 | SISUSB_VERSION, SISUSB_REVISION, SISUSB_PATCHLEVEL); | ||
3437 | printk(KERN_INFO | ||
3438 | "sisusb: Copyright (C) 2005 Thomas Winischhofer\n"); | ||
3439 | |||
3440 | } | ||
3441 | |||
3442 | return retval; | ||
3443 | } | 3325 | } |
3444 | 3326 | ||
3445 | static void __exit usb_sisusb_exit(void) | 3327 | static void __exit usb_sisusb_exit(void) |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h index 8e1120a64806..d2d7872cd022 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.h +++ b/drivers/usb/misc/sisusbvga/sisusb.h | |||
@@ -8,29 +8,29 @@ | |||
8 | * | 8 | * |
9 | * Otherwise, the following license terms apply: | 9 | * Otherwise, the following license terms apply: |
10 | * | 10 | * |
11 | * * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions |
13 | * * are met: | 13 | * are met: |
14 | * * 1) Redistributions of source code must retain the above copyright | 14 | * 1) Redistributions of source code must retain the above copyright |
15 | * * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. |
16 | * * 2) Redistributions in binary form must reproduce the above copyright | 16 | * 2) Redistributions in binary form must reproduce the above copyright |
17 | * * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the |
18 | * * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. |
19 | * * 3) The name of the author may not be used to endorse or promote products | 19 | * 3) The name of the author may not be used to endorse or promote products |
20 | * * derived from this software without specific prior written permission. | 20 | * derived from this software without specific prior written permission. |
21 | * * | ||
22 | * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR | ||
23 | * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
24 | * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
25 | * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
26 | * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
27 | * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
28 | * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
29 | * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
30 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
31 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | * | 21 | * |
33 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR |
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | * | ||
33 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | ||
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | 36 | ||
@@ -44,16 +44,14 @@ | |||
44 | #include <linux/mutex.h> | 44 | #include <linux/mutex.h> |
45 | 45 | ||
46 | /* For older kernels, support for text consoles is by default | 46 | /* For older kernels, support for text consoles is by default |
47 | * off. To ensable text console support, change the following: | 47 | * off. To enable text console support, change the following: |
48 | */ | 48 | */ |
49 | #if 0 | 49 | /* #define CONFIG_USB_SISUSBVGA_CON */ |
50 | #define CONFIG_USB_SISUSBVGA_CON | ||
51 | #endif | ||
52 | 50 | ||
53 | /* Version Information */ | 51 | /* Version Information */ |
54 | 52 | ||
55 | #define SISUSB_VERSION 0 | 53 | #define SISUSB_VERSION 0 |
56 | #define SISUSB_REVISION 0 | 54 | #define SISUSB_REVISION 0 |
57 | #define SISUSB_PATCHLEVEL 8 | 55 | #define SISUSB_PATCHLEVEL 8 |
58 | 56 | ||
59 | /* Include console and mode switching code? */ | 57 | /* Include console and mode switching code? */ |
@@ -74,7 +72,7 @@ | |||
74 | #define SISUSB_IBUF_SIZE 0x01000 | 72 | #define SISUSB_IBUF_SIZE 0x01000 |
75 | #define SISUSB_OBUF_SIZE 0x10000 /* fixed */ | 73 | #define SISUSB_OBUF_SIZE 0x10000 /* fixed */ |
76 | 74 | ||
77 | #define NUMOBUFS 8 /* max number of output buffers/output URBs */ | 75 | #define NUMOBUFS 8 /* max number of output buffers/output URBs */ |
78 | 76 | ||
79 | /* About endianness: | 77 | /* About endianness: |
80 | * | 78 | * |
@@ -93,7 +91,7 @@ | |||
93 | */ | 91 | */ |
94 | 92 | ||
95 | #ifdef __BIG_ENDIAN | 93 | #ifdef __BIG_ENDIAN |
96 | #define SISUSB_CORRECT_ENDIANNESS_PACKET(p) \ | 94 | #define SISUSB_CORRECT_ENDIANNESS_PACKET(p) \ |
97 | do { \ | 95 | do { \ |
98 | p->header = cpu_to_le16(p->header); \ | 96 | p->header = cpu_to_le16(p->header); \ |
99 | p->address = cpu_to_le32(p->address); \ | 97 | p->address = cpu_to_le32(p->address); \ |
@@ -105,7 +103,7 @@ | |||
105 | 103 | ||
106 | struct sisusb_usb_data; | 104 | struct sisusb_usb_data; |
107 | 105 | ||
108 | struct sisusb_urb_context { /* urb->context for outbound bulk URBs */ | 106 | struct sisusb_urb_context { /* urb->context for outbound bulk URBs */ |
109 | struct sisusb_usb_data *sisusb; | 107 | struct sisusb_usb_data *sisusb; |
110 | int urbindex; | 108 | int urbindex; |
111 | int *actual_length; | 109 | int *actual_length; |
@@ -116,16 +114,16 @@ struct sisusb_usb_data { | |||
116 | struct usb_interface *interface; | 114 | struct usb_interface *interface; |
117 | struct kref kref; | 115 | struct kref kref; |
118 | wait_queue_head_t wait_q; /* for syncind and timeouts */ | 116 | wait_queue_head_t wait_q; /* for syncind and timeouts */ |
119 | struct mutex lock; /* general race avoidance */ | 117 | struct mutex lock; /* general race avoidance */ |
120 | unsigned int ifnum; /* interface number of the USB device */ | 118 | unsigned int ifnum; /* interface number of the USB device */ |
121 | int minor; /* minor (for logging clarity) */ | 119 | int minor; /* minor (for logging clarity) */ |
122 | int isopen; /* !=0 if open */ | 120 | int isopen; /* !=0 if open */ |
123 | int present; /* !=0 if device is present on the bus */ | 121 | int present; /* !=0 if device is present on the bus */ |
124 | int ready; /* !=0 if device is ready for userland */ | 122 | int ready; /* !=0 if device is ready for userland */ |
125 | #ifdef SISUSB_OLD_CONFIG_COMPAT | 123 | #ifdef SISUSB_OLD_CONFIG_COMPAT |
126 | int ioctl32registered; | 124 | int ioctl32registered; |
127 | #endif | 125 | #endif |
128 | int numobufs; /* number of obufs = number of out urbs */ | 126 | int numobufs; /* number of obufs = number of out urbs */ |
129 | char *obuf[NUMOBUFS], *ibuf; /* transfer buffers */ | 127 | char *obuf[NUMOBUFS], *ibuf; /* transfer buffers */ |
130 | int obufsize, ibufsize; | 128 | int obufsize, ibufsize; |
131 | dma_addr_t transfer_dma_out[NUMOBUFS]; | 129 | dma_addr_t transfer_dma_out[NUMOBUFS]; |
@@ -136,13 +134,13 @@ struct sisusb_usb_data { | |||
136 | unsigned char completein; | 134 | unsigned char completein; |
137 | struct sisusb_urb_context urbout_context[NUMOBUFS]; | 135 | struct sisusb_urb_context urbout_context[NUMOBUFS]; |
138 | unsigned long flagb0; | 136 | unsigned long flagb0; |
139 | unsigned long vrambase; /* framebuffer base */ | 137 | unsigned long vrambase; /* framebuffer base */ |
140 | unsigned int vramsize; /* framebuffer size (bytes) */ | 138 | unsigned int vramsize; /* framebuffer size (bytes) */ |
141 | unsigned long mmiobase; | 139 | unsigned long mmiobase; |
142 | unsigned int mmiosize; | 140 | unsigned int mmiosize; |
143 | unsigned long ioportbase; | 141 | unsigned long ioportbase; |
144 | unsigned char devinit; /* device initialized? */ | 142 | unsigned char devinit; /* device initialized? */ |
145 | unsigned char gfxinit; /* graphics core initialized? */ | 143 | unsigned char gfxinit; /* graphics core initialized? */ |
146 | unsigned short chipid, chipvendor; | 144 | unsigned short chipid, chipvendor; |
147 | unsigned short chiprevision; | 145 | unsigned short chiprevision; |
148 | #ifdef INCL_SISUSB_CON | 146 | #ifdef INCL_SISUSB_CON |
@@ -152,7 +150,7 @@ struct sisusb_usb_data { | |||
152 | int haveconsole, con_first, con_last; | 150 | int haveconsole, con_first, con_last; |
153 | int havethisconsole[MAX_NR_CONSOLES]; | 151 | int havethisconsole[MAX_NR_CONSOLES]; |
154 | int textmodedestroyed; | 152 | int textmodedestroyed; |
155 | unsigned int sisusb_num_columns; /* real number, not vt's idea */ | 153 | unsigned int sisusb_num_columns; /* real number, not vt's idea */ |
156 | int cur_start_addr, con_rolled_over; | 154 | int cur_start_addr, con_rolled_over; |
157 | int sisusb_cursor_loc, bad_cursor_pos; | 155 | int sisusb_cursor_loc, bad_cursor_pos; |
158 | int sisusb_cursor_size_from; | 156 | int sisusb_cursor_size_from; |
@@ -197,7 +195,7 @@ struct sisusb_packet { | |||
197 | unsigned short header; | 195 | unsigned short header; |
198 | u32 address; | 196 | u32 address; |
199 | u32 data; | 197 | u32 data; |
200 | } __attribute__((__packed__)); | 198 | } __attribute__ ((__packed__)); |
201 | 199 | ||
202 | #define CLEARPACKET(packet) memset(packet, 0, 10) | 200 | #define CLEARPACKET(packet) memset(packet, 0, 10) |
203 | 201 | ||
@@ -265,36 +263,36 @@ struct sisusb_packet { | |||
265 | 263 | ||
266 | /* Structure argument for SISUSB_GET_INFO ioctl */ | 264 | /* Structure argument for SISUSB_GET_INFO ioctl */ |
267 | struct sisusb_info { | 265 | struct sisusb_info { |
268 | __u32 sisusb_id; /* for identifying sisusb */ | 266 | __u32 sisusb_id; /* for identifying sisusb */ |
269 | #define SISUSB_ID 0x53495355 /* Identify myself with 'SISU' */ | 267 | #define SISUSB_ID 0x53495355 /* Identify myself with 'SISU' */ |
270 | __u8 sisusb_version; | 268 | __u8 sisusb_version; |
271 | __u8 sisusb_revision; | 269 | __u8 sisusb_revision; |
272 | __u8 sisusb_patchlevel; | 270 | __u8 sisusb_patchlevel; |
273 | __u8 sisusb_gfxinit; /* graphics core initialized? */ | 271 | __u8 sisusb_gfxinit; /* graphics core initialized? */ |
274 | 272 | ||
275 | __u32 sisusb_vrambase; | 273 | __u32 sisusb_vrambase; |
276 | __u32 sisusb_mmiobase; | 274 | __u32 sisusb_mmiobase; |
277 | __u32 sisusb_iobase; | 275 | __u32 sisusb_iobase; |
278 | __u32 sisusb_pcibase; | 276 | __u32 sisusb_pcibase; |
279 | 277 | ||
280 | __u32 sisusb_vramsize; /* framebuffer size in bytes */ | 278 | __u32 sisusb_vramsize; /* framebuffer size in bytes */ |
281 | 279 | ||
282 | __u32 sisusb_minor; | 280 | __u32 sisusb_minor; |
283 | 281 | ||
284 | __u32 sisusb_fbdevactive; /* != 0 if framebuffer device active */ | 282 | __u32 sisusb_fbdevactive; /* != 0 if framebuffer device active */ |
285 | 283 | ||
286 | __u32 sisusb_conactive; /* != 0 if console driver active */ | 284 | __u32 sisusb_conactive; /* != 0 if console driver active */ |
287 | 285 | ||
288 | __u8 sisusb_reserved[28]; /* for future use */ | 286 | __u8 sisusb_reserved[28]; /* for future use */ |
289 | }; | 287 | }; |
290 | 288 | ||
291 | struct sisusb_command { | 289 | struct sisusb_command { |
292 | __u8 operation; /* see below */ | 290 | __u8 operation; /* see below */ |
293 | __u8 data0; /* operation dependent */ | 291 | __u8 data0; /* operation dependent */ |
294 | __u8 data1; /* operation dependent */ | 292 | __u8 data1; /* operation dependent */ |
295 | __u8 data2; /* operation dependent */ | 293 | __u8 data2; /* operation dependent */ |
296 | __u32 data3; /* operation dependent */ | 294 | __u32 data3; /* operation dependent */ |
297 | __u32 data4; /* for future use */ | 295 | __u32 data4; /* for future use */ |
298 | }; | 296 | }; |
299 | 297 | ||
300 | #define SUCMD_GET 0x01 /* for all: data0 = index, data3 = port */ | 298 | #define SUCMD_GET 0x01 /* for all: data0 = index, data3 = port */ |
@@ -306,7 +304,7 @@ struct sisusb_command { | |||
306 | 304 | ||
307 | #define SUCMD_CLRSCR 0x07 /* data0:1:2 = length, data3 = address */ | 305 | #define SUCMD_CLRSCR 0x07 /* data0:1:2 = length, data3 = address */ |
308 | 306 | ||
309 | #define SUCMD_HANDLETEXTMODE 0x08 /* Reset/destroy text mode */ | 307 | #define SUCMD_HANDLETEXTMODE 0x08 /* Reset/destroy text mode */ |
310 | 308 | ||
311 | #define SUCMD_SETMODE 0x09 /* Set a display mode (data3 = SiS mode) */ | 309 | #define SUCMD_SETMODE 0x09 /* Set a display mode (data3 = SiS mode) */ |
312 | #define SUCMD_SETVESAMODE 0x0a /* Set a display mode (data3 = VESA mode) */ | 310 | #define SUCMD_SETVESAMODE 0x0a /* Set a display mode (data3 = VESA mode) */ |
@@ -315,6 +313,4 @@ struct sisusb_command { | |||
315 | #define SISUSB_GET_CONFIG_SIZE _IOR(0xF3,0x3E,__u32) | 313 | #define SISUSB_GET_CONFIG_SIZE _IOR(0xF3,0x3E,__u32) |
316 | #define SISUSB_GET_CONFIG _IOR(0xF3,0x3F,struct sisusb_info) | 314 | #define SISUSB_GET_CONFIG _IOR(0xF3,0x3F,struct sisusb_info) |
317 | 315 | ||
318 | |||
319 | #endif /* SISUSB_H */ | 316 | #endif /* SISUSB_H */ |
320 | |||
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index 8d0edc867f33..43722e5a49d1 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/kernel.h> | 52 | #include <linux/kernel.h> |
53 | #include <linux/signal.h> | 53 | #include <linux/signal.h> |
54 | #include <linux/fs.h> | 54 | #include <linux/fs.h> |
55 | #include <linux/usb.h> | ||
55 | #include <linux/tty.h> | 56 | #include <linux/tty.h> |
56 | #include <linux/console.h> | 57 | #include <linux/console.h> |
57 | #include <linux/string.h> | 58 | #include <linux/string.h> |
@@ -373,14 +374,6 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x) | |||
373 | return; | 374 | return; |
374 | 375 | ||
375 | /* sisusb->lock is down */ | 376 | /* sisusb->lock is down */ |
376 | |||
377 | /* Don't need to put the character into buffer ourselves, | ||
378 | * because the vt does this BEFORE calling us. | ||
379 | */ | ||
380 | #if 0 | ||
381 | sisusbcon_writew(ch, SISUSB_VADDR(x, y)); | ||
382 | #endif | ||
383 | |||
384 | if (sisusb_is_inactive(c, sisusb)) { | 377 | if (sisusb_is_inactive(c, sisusb)) { |
385 | mutex_unlock(&sisusb->lock); | 378 | mutex_unlock(&sisusb->lock); |
386 | return; | 379 | return; |
@@ -490,10 +483,6 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx, | |||
490 | struct sisusb_usb_data *sisusb; | 483 | struct sisusb_usb_data *sisusb; |
491 | ssize_t written; | 484 | ssize_t written; |
492 | int cols, length; | 485 | int cols, length; |
493 | #if 0 | ||
494 | u16 *src, *dest; | ||
495 | int i; | ||
496 | #endif | ||
497 | 486 | ||
498 | if (width <= 0 || height <= 0) | 487 | if (width <= 0 || height <= 0) |
499 | return; | 488 | return; |
@@ -505,41 +494,6 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx, | |||
505 | 494 | ||
506 | cols = sisusb->sisusb_num_columns; | 495 | cols = sisusb->sisusb_num_columns; |
507 | 496 | ||
508 | /* Don't need to move data outselves, because | ||
509 | * vt does this BEFORE calling us. | ||
510 | * This is only used by vt's insert/deletechar. | ||
511 | */ | ||
512 | #if 0 | ||
513 | if (sx == 0 && dx == 0 && width >= c->vc_cols && width <= cols) { | ||
514 | |||
515 | sisusbcon_memmovew(SISUSB_VADDR(0, dy), SISUSB_VADDR(0, sy), | ||
516 | height * width * 2); | ||
517 | |||
518 | } else if (dy < sy || (dy == sy && dx < sx)) { | ||
519 | |||
520 | src = SISUSB_VADDR(sx, sy); | ||
521 | dest = SISUSB_VADDR(dx, dy); | ||
522 | |||
523 | for (i = height; i > 0; i--) { | ||
524 | sisusbcon_memmovew(dest, src, width * 2); | ||
525 | src += cols; | ||
526 | dest += cols; | ||
527 | } | ||
528 | |||
529 | } else { | ||
530 | |||
531 | src = SISUSB_VADDR(sx, sy + height - 1); | ||
532 | dest = SISUSB_VADDR(dx, dy + height - 1); | ||
533 | |||
534 | for (i = height; i > 0; i--) { | ||
535 | sisusbcon_memmovew(dest, src, width * 2); | ||
536 | src -= cols; | ||
537 | dest -= cols; | ||
538 | } | ||
539 | |||
540 | } | ||
541 | #endif | ||
542 | |||
543 | if (sisusb_is_inactive(c, sisusb)) { | 497 | if (sisusb_is_inactive(c, sisusb)) { |
544 | mutex_unlock(&sisusb->lock); | 498 | mutex_unlock(&sisusb->lock); |
545 | return; | 499 | return; |
@@ -584,7 +538,7 @@ sisusbcon_switch(struct vc_data *c) | |||
584 | */ | 538 | */ |
585 | if (c->vc_origin == (unsigned long)c->vc_screenbuf) { | 539 | if (c->vc_origin == (unsigned long)c->vc_screenbuf) { |
586 | mutex_unlock(&sisusb->lock); | 540 | mutex_unlock(&sisusb->lock); |
587 | printk(KERN_DEBUG "sisusb: ASSERT ORIGIN != SCREENBUF!\n"); | 541 | dev_dbg(&sisusb->sisusb_dev->dev, "ASSERT ORIGIN != SCREENBUF!\n"); |
588 | return 0; | 542 | return 0; |
589 | } | 543 | } |
590 | 544 | ||
@@ -1475,7 +1429,7 @@ static const struct consw sisusb_dummy_con = { | |||
1475 | int | 1429 | int |
1476 | sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) | 1430 | sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) |
1477 | { | 1431 | { |
1478 | int i, ret, minor = sisusb->minor; | 1432 | int i, ret; |
1479 | 1433 | ||
1480 | mutex_lock(&sisusb->lock); | 1434 | mutex_lock(&sisusb->lock); |
1481 | 1435 | ||
@@ -1508,9 +1462,7 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) | |||
1508 | /* Set up text mode (and upload default font) */ | 1462 | /* Set up text mode (and upload default font) */ |
1509 | if (sisusb_reset_text_mode(sisusb, 1)) { | 1463 | if (sisusb_reset_text_mode(sisusb, 1)) { |
1510 | mutex_unlock(&sisusb->lock); | 1464 | mutex_unlock(&sisusb->lock); |
1511 | printk(KERN_ERR | 1465 | dev_err(&sisusb->sisusb_dev->dev, "Failed to set up text mode\n"); |
1512 | "sisusbvga[%d]: Failed to set up text mode\n", | ||
1513 | minor); | ||
1514 | return 1; | 1466 | return 1; |
1515 | } | 1467 | } |
1516 | 1468 | ||
@@ -1531,9 +1483,7 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) | |||
1531 | /* Allocate screen buffer */ | 1483 | /* Allocate screen buffer */ |
1532 | if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) { | 1484 | if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) { |
1533 | mutex_unlock(&sisusb->lock); | 1485 | mutex_unlock(&sisusb->lock); |
1534 | printk(KERN_ERR | 1486 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate screen buffer\n"); |
1535 | "sisusbvga[%d]: Failed to allocate screen buffer\n", | ||
1536 | minor); | ||
1537 | return 1; | 1487 | return 1; |
1538 | } | 1488 | } |
1539 | 1489 | ||
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c index 9b30f8962814..273de5d0934e 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.c +++ b/drivers/usb/misc/sisusbvga/sisusb_init.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | * | 34 | * |
35 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 35 | * Author: Thomas Winischhofer <thomas@winischhofer.net> |
36 | * | 36 | * |
37 | */ | 37 | */ |
38 | 38 | ||
@@ -55,109 +55,18 @@ | |||
55 | /* POINTER INITIALIZATION */ | 55 | /* POINTER INITIALIZATION */ |
56 | /*********************************************/ | 56 | /*********************************************/ |
57 | 57 | ||
58 | static void | 58 | static void SiSUSB_InitPtr(struct SiS_Private *SiS_Pr) |
59 | SiSUSB_InitPtr(struct SiS_Private *SiS_Pr) | ||
60 | { | 59 | { |
61 | SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo; | 60 | SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo; |
62 | SiS_Pr->SiS_StandTable = SiSUSB_StandTable; | 61 | SiS_Pr->SiS_StandTable = SiSUSB_StandTable; |
63 | |||
64 | SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable; | ||
65 | SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable; | ||
66 | SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex; | ||
67 | SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table; | ||
68 | |||
69 | SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData; | ||
70 | } | ||
71 | |||
72 | /*********************************************/ | ||
73 | /* HELPER: Get ModeID */ | ||
74 | /*********************************************/ | ||
75 | 62 | ||
76 | #if 0 | 63 | SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable; |
77 | unsigned short | 64 | SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable; |
78 | SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth) | 65 | SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex; |
79 | { | 66 | SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table; |
80 | unsigned short ModeIndex = 0; | ||
81 | |||
82 | switch (HDisplay) | ||
83 | { | ||
84 | case 320: | ||
85 | if (VDisplay == 200) | ||
86 | ModeIndex = ModeIndex_320x200[Depth]; | ||
87 | else if (VDisplay == 240) | ||
88 | ModeIndex = ModeIndex_320x240[Depth]; | ||
89 | break; | ||
90 | case 400: | ||
91 | if (VDisplay == 300) | ||
92 | ModeIndex = ModeIndex_400x300[Depth]; | ||
93 | break; | ||
94 | case 512: | ||
95 | if (VDisplay == 384) | ||
96 | ModeIndex = ModeIndex_512x384[Depth]; | ||
97 | break; | ||
98 | case 640: | ||
99 | if (VDisplay == 480) | ||
100 | ModeIndex = ModeIndex_640x480[Depth]; | ||
101 | else if (VDisplay == 400) | ||
102 | ModeIndex = ModeIndex_640x400[Depth]; | ||
103 | break; | ||
104 | case 720: | ||
105 | if (VDisplay == 480) | ||
106 | ModeIndex = ModeIndex_720x480[Depth]; | ||
107 | else if (VDisplay == 576) | ||
108 | ModeIndex = ModeIndex_720x576[Depth]; | ||
109 | break; | ||
110 | case 768: | ||
111 | if (VDisplay == 576) | ||
112 | ModeIndex = ModeIndex_768x576[Depth]; | ||
113 | break; | ||
114 | case 800: | ||
115 | if (VDisplay == 600) | ||
116 | ModeIndex = ModeIndex_800x600[Depth]; | ||
117 | else if (VDisplay == 480) | ||
118 | ModeIndex = ModeIndex_800x480[Depth]; | ||
119 | break; | ||
120 | case 848: | ||
121 | if (VDisplay == 480) | ||
122 | ModeIndex = ModeIndex_848x480[Depth]; | ||
123 | break; | ||
124 | case 856: | ||
125 | if (VDisplay == 480) | ||
126 | ModeIndex = ModeIndex_856x480[Depth]; | ||
127 | break; | ||
128 | case 960: | ||
129 | if (VDisplay == 540) | ||
130 | ModeIndex = ModeIndex_960x540[Depth]; | ||
131 | else if (VDisplay == 600) | ||
132 | ModeIndex = ModeIndex_960x600[Depth]; | ||
133 | break; | ||
134 | case 1024: | ||
135 | if (VDisplay == 576) | ||
136 | ModeIndex = ModeIndex_1024x576[Depth]; | ||
137 | else if (VDisplay == 768) | ||
138 | ModeIndex = ModeIndex_1024x768[Depth]; | ||
139 | break; | ||
140 | case 1152: | ||
141 | if (VDisplay == 864) | ||
142 | ModeIndex = ModeIndex_1152x864[Depth]; | ||
143 | break; | ||
144 | case 1280: | ||
145 | switch (VDisplay) { | ||
146 | case 720: | ||
147 | ModeIndex = ModeIndex_1280x720[Depth]; | ||
148 | break; | ||
149 | case 768: | ||
150 | ModeIndex = ModeIndex_1280x768[Depth]; | ||
151 | break; | ||
152 | case 1024: | ||
153 | ModeIndex = ModeIndex_1280x1024[Depth]; | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | 67 | ||
158 | return ModeIndex; | 68 | SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData; |
159 | } | 69 | } |
160 | #endif /* 0 */ | ||
161 | 70 | ||
162 | /*********************************************/ | 71 | /*********************************************/ |
163 | /* HELPER: SetReg, GetReg */ | 72 | /* HELPER: SetReg, GetReg */ |
@@ -165,21 +74,20 @@ SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth) | |||
165 | 74 | ||
166 | static void | 75 | static void |
167 | SiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port, | 76 | SiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port, |
168 | unsigned short index, unsigned short data) | 77 | unsigned short index, unsigned short data) |
169 | { | 78 | { |
170 | sisusb_setidxreg(SiS_Pr->sisusb, port, index, data); | 79 | sisusb_setidxreg(SiS_Pr->sisusb, port, index, data); |
171 | } | 80 | } |
172 | 81 | ||
173 | static void | 82 | static void |
174 | SiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port, | 83 | SiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port, |
175 | unsigned short data) | 84 | unsigned short data) |
176 | { | 85 | { |
177 | sisusb_setreg(SiS_Pr->sisusb, port, data); | 86 | sisusb_setreg(SiS_Pr->sisusb, port, data); |
178 | } | 87 | } |
179 | 88 | ||
180 | static unsigned char | 89 | static unsigned char |
181 | SiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port, | 90 | SiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short index) |
182 | unsigned short index) | ||
183 | { | 91 | { |
184 | u8 data; | 92 | u8 data; |
185 | 93 | ||
@@ -200,22 +108,22 @@ SiS_GetRegByte(struct SiS_Private *SiS_Pr, unsigned long port) | |||
200 | 108 | ||
201 | static void | 109 | static void |
202 | SiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port, | 110 | SiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port, |
203 | unsigned short index, unsigned short DataAND, | 111 | unsigned short index, unsigned short DataAND, |
204 | unsigned short DataOR) | 112 | unsigned short DataOR) |
205 | { | 113 | { |
206 | sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR); | 114 | sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR); |
207 | } | 115 | } |
208 | 116 | ||
209 | static void | 117 | static void |
210 | SiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port, | 118 | SiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port, |
211 | unsigned short index, unsigned short DataAND) | 119 | unsigned short index, unsigned short DataAND) |
212 | { | 120 | { |
213 | sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND); | 121 | sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND); |
214 | } | 122 | } |
215 | 123 | ||
216 | static void | 124 | static void |
217 | SiS_SetRegOR(struct SiS_Private *SiS_Pr,unsigned long port, | 125 | SiS_SetRegOR(struct SiS_Private *SiS_Pr, unsigned long port, |
218 | unsigned short index, unsigned short DataOR) | 126 | unsigned short index, unsigned short DataOR) |
219 | { | 127 | { |
220 | sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR); | 128 | sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR); |
221 | } | 129 | } |
@@ -224,8 +132,7 @@ SiS_SetRegOR(struct SiS_Private *SiS_Pr,unsigned long port, | |||
224 | /* HELPER: DisplayOn, DisplayOff */ | 132 | /* HELPER: DisplayOn, DisplayOff */ |
225 | /*********************************************/ | 133 | /*********************************************/ |
226 | 134 | ||
227 | static void | 135 | static void SiS_DisplayOn(struct SiS_Private *SiS_Pr) |
228 | SiS_DisplayOn(struct SiS_Private *SiS_Pr) | ||
229 | { | 136 | { |
230 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF); | 137 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF); |
231 | } | 138 | } |
@@ -234,8 +141,7 @@ SiS_DisplayOn(struct SiS_Private *SiS_Pr) | |||
234 | /* HELPER: Init Port Addresses */ | 141 | /* HELPER: Init Port Addresses */ |
235 | /*********************************************/ | 142 | /*********************************************/ |
236 | 143 | ||
237 | static void | 144 | static void SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) |
238 | SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) | ||
239 | { | 145 | { |
240 | SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; | 146 | SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; |
241 | SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; | 147 | SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; |
@@ -258,8 +164,7 @@ SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) | |||
258 | /* HELPER: GetSysFlags */ | 164 | /* HELPER: GetSysFlags */ |
259 | /*********************************************/ | 165 | /*********************************************/ |
260 | 166 | ||
261 | static void | 167 | static void SiS_GetSysFlags(struct SiS_Private *SiS_Pr) |
262 | SiS_GetSysFlags(struct SiS_Private *SiS_Pr) | ||
263 | { | 168 | { |
264 | SiS_Pr->SiS_MyCR63 = 0x63; | 169 | SiS_Pr->SiS_MyCR63 = 0x63; |
265 | } | 170 | } |
@@ -268,8 +173,7 @@ SiS_GetSysFlags(struct SiS_Private *SiS_Pr) | |||
268 | /* HELPER: Init PCI & Engines */ | 173 | /* HELPER: Init PCI & Engines */ |
269 | /*********************************************/ | 174 | /*********************************************/ |
270 | 175 | ||
271 | static void | 176 | static void SiSInitPCIetc(struct SiS_Private *SiS_Pr) |
272 | SiSInitPCIetc(struct SiS_Private *SiS_Pr) | ||
273 | { | 177 | { |
274 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1); | 178 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1); |
275 | /* - Enable 2D (0x40) | 179 | /* - Enable 2D (0x40) |
@@ -285,8 +189,7 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr) | |||
285 | /* HELPER: SET SEGMENT REGISTERS */ | 189 | /* HELPER: SET SEGMENT REGISTERS */ |
286 | /*********************************************/ | 190 | /*********************************************/ |
287 | 191 | ||
288 | static void | 192 | static void SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) |
289 | SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) | ||
290 | { | 193 | { |
291 | unsigned short temp; | 194 | unsigned short temp; |
292 | 195 | ||
@@ -299,8 +202,7 @@ SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) | |||
299 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); | 202 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); |
300 | } | 203 | } |
301 | 204 | ||
302 | static void | 205 | static void SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) |
303 | SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) | ||
304 | { | 206 | { |
305 | unsigned short temp; | 207 | unsigned short temp; |
306 | 208 | ||
@@ -313,15 +215,13 @@ SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) | |||
313 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); | 215 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); |
314 | } | 216 | } |
315 | 217 | ||
316 | static void | 218 | static void SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value) |
317 | SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value) | ||
318 | { | 219 | { |
319 | SiS_SetSegRegLower(SiS_Pr, value); | 220 | SiS_SetSegRegLower(SiS_Pr, value); |
320 | SiS_SetSegRegUpper(SiS_Pr, value); | 221 | SiS_SetSegRegUpper(SiS_Pr, value); |
321 | } | 222 | } |
322 | 223 | ||
323 | static void | 224 | static void SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr) |
324 | SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr) | ||
325 | { | 225 | { |
326 | SiS_SetSegmentReg(SiS_Pr, 0); | 226 | SiS_SetSegmentReg(SiS_Pr, 0); |
327 | } | 227 | } |
@@ -337,14 +237,12 @@ SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value) | |||
337 | SiS_SetSegmentReg(SiS_Pr, value); | 237 | SiS_SetSegmentReg(SiS_Pr, value); |
338 | } | 238 | } |
339 | 239 | ||
340 | static void | 240 | static void SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr) |
341 | SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr) | ||
342 | { | 241 | { |
343 | SiS_SetSegmentRegOver(SiS_Pr, 0); | 242 | SiS_SetSegmentRegOver(SiS_Pr, 0); |
344 | } | 243 | } |
345 | 244 | ||
346 | static void | 245 | static void SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) |
347 | SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) | ||
348 | { | 246 | { |
349 | SiS_ResetSegmentReg(SiS_Pr); | 247 | SiS_ResetSegmentReg(SiS_Pr); |
350 | SiS_ResetSegmentRegOver(SiS_Pr); | 248 | SiS_ResetSegmentRegOver(SiS_Pr); |
@@ -356,7 +254,7 @@ SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) | |||
356 | 254 | ||
357 | static int | 255 | static int |
358 | SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, | 256 | SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, |
359 | unsigned short *ModeIdIndex) | 257 | unsigned short *ModeIdIndex) |
360 | { | 258 | { |
361 | if ((*ModeNo) <= 0x13) { | 259 | if ((*ModeNo) <= 0x13) { |
362 | 260 | ||
@@ -367,12 +265,14 @@ SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, | |||
367 | 265 | ||
368 | } else { | 266 | } else { |
369 | 267 | ||
370 | for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) { | 268 | for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { |
371 | 269 | ||
372 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) | 270 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == |
271 | (*ModeNo)) | ||
373 | break; | 272 | break; |
374 | 273 | ||
375 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) | 274 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == |
275 | 0xFF) | ||
376 | return 0; | 276 | return 0; |
377 | } | 277 | } |
378 | 278 | ||
@@ -385,8 +285,7 @@ SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, | |||
385 | /* HELPER: ENABLE CRT1 */ | 285 | /* HELPER: ENABLE CRT1 */ |
386 | /*********************************************/ | 286 | /*********************************************/ |
387 | 287 | ||
388 | static void | 288 | static void SiS_HandleCRT1(struct SiS_Private *SiS_Pr) |
389 | SiS_HandleCRT1(struct SiS_Private *SiS_Pr) | ||
390 | { | 289 | { |
391 | /* Enable CRT1 gating */ | 290 | /* Enable CRT1 gating */ |
392 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf); | 291 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf); |
@@ -398,9 +297,9 @@ SiS_HandleCRT1(struct SiS_Private *SiS_Pr) | |||
398 | 297 | ||
399 | static unsigned short | 298 | static unsigned short |
400 | SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 299 | SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
401 | unsigned short ModeIdIndex) | 300 | unsigned short ModeIdIndex) |
402 | { | 301 | { |
403 | static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8}; | 302 | static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; |
404 | unsigned short modeflag; | 303 | unsigned short modeflag; |
405 | short index; | 304 | short index; |
406 | 305 | ||
@@ -411,7 +310,8 @@ SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
411 | } | 310 | } |
412 | 311 | ||
413 | index = (modeflag & ModeTypeMask) - ModeEGA; | 312 | index = (modeflag & ModeTypeMask) - ModeEGA; |
414 | if (index < 0) index = 0; | 313 | if (index < 0) |
314 | index = 0; | ||
415 | return ColorDepth[index]; | 315 | return ColorDepth[index]; |
416 | } | 316 | } |
417 | 317 | ||
@@ -421,7 +321,7 @@ SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
421 | 321 | ||
422 | static unsigned short | 322 | static unsigned short |
423 | SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 323 | SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
424 | unsigned short ModeIdIndex, unsigned short rrti) | 324 | unsigned short ModeIdIndex, unsigned short rrti) |
425 | { | 325 | { |
426 | unsigned short xres, temp, colordepth, infoflag; | 326 | unsigned short xres, temp, colordepth, infoflag; |
427 | 327 | ||
@@ -458,8 +358,8 @@ SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
458 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; | 358 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; |
459 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata); | 359 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata); |
460 | 360 | ||
461 | for(i = 2; i <= 4; i++) { | 361 | for (i = 2; i <= 4; i++) { |
462 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1]; | 362 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1]; |
463 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata); | 363 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata); |
464 | } | 364 | } |
465 | } | 365 | } |
@@ -488,7 +388,7 @@ SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
488 | 388 | ||
489 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); | 389 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); |
490 | 390 | ||
491 | for(i = 0; i <= 0x18; i++) { | 391 | for (i = 0; i <= 0x18; i++) { |
492 | CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; | 392 | CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; |
493 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, i, CRTCdata); | 393 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, i, CRTCdata); |
494 | } | 394 | } |
@@ -504,7 +404,7 @@ SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
504 | unsigned char ARdata; | 404 | unsigned char ARdata; |
505 | unsigned short i; | 405 | unsigned short i; |
506 | 406 | ||
507 | for(i = 0; i <= 0x13; i++) { | 407 | for (i = 0; i <= 0x13; i++) { |
508 | ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; | 408 | ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; |
509 | SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); | 409 | SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); |
510 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i); | 410 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i); |
@@ -529,7 +429,7 @@ SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
529 | unsigned char GRdata; | 429 | unsigned char GRdata; |
530 | unsigned short i; | 430 | unsigned short i; |
531 | 431 | ||
532 | for(i = 0; i <= 0x08; i++) { | 432 | for (i = 0; i <= 0x08; i++) { |
533 | GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; | 433 | GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; |
534 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3ce, i, GRdata); | 434 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3ce, i, GRdata); |
535 | } | 435 | } |
@@ -544,12 +444,11 @@ SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
544 | /* CLEAR EXTENDED REGISTERS */ | 444 | /* CLEAR EXTENDED REGISTERS */ |
545 | /*********************************************/ | 445 | /*********************************************/ |
546 | 446 | ||
547 | static void | 447 | static void SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) |
548 | SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | ||
549 | { | 448 | { |
550 | int i; | 449 | int i; |
551 | 450 | ||
552 | for(i = 0x0A; i <= 0x0E; i++) { | 451 | for (i = 0x0A; i <= 0x0E; i++) { |
553 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, 0x00); | 452 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, 0x00); |
554 | } | 453 | } |
555 | 454 | ||
@@ -562,15 +461,16 @@ SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
562 | 461 | ||
563 | static unsigned short | 462 | static unsigned short |
564 | SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 463 | SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
565 | unsigned short ModeIdIndex) | 464 | unsigned short ModeIdIndex) |
566 | { | 465 | { |
567 | unsigned short rrti, i, index, temp; | 466 | unsigned short rrti, i, index, temp; |
568 | 467 | ||
569 | if (ModeNo <= 0x13) | 468 | if (ModeNo <= 0x13) |
570 | return 0xFFFF; | 469 | return 0xFFFF; |
571 | 470 | ||
572 | index = SiS_GetReg(SiS_Pr,SiS_Pr->SiS_P3d4, 0x33) & 0x0F; | 471 | index = SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x33) & 0x0F; |
573 | if (index > 0) index--; | 472 | if (index > 0) |
473 | index--; | ||
574 | 474 | ||
575 | rrti = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; | 475 | rrti = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; |
576 | ModeNo = SiS_Pr->SiS_RefIndex[rrti].ModeID; | 476 | ModeNo = SiS_Pr->SiS_RefIndex[rrti].ModeID; |
@@ -580,13 +480,14 @@ SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
580 | if (SiS_Pr->SiS_RefIndex[rrti + i].ModeID != ModeNo) | 480 | if (SiS_Pr->SiS_RefIndex[rrti + i].ModeID != ModeNo) |
581 | break; | 481 | break; |
582 | 482 | ||
583 | temp = SiS_Pr->SiS_RefIndex[rrti + i].Ext_InfoFlag & ModeTypeMask; | 483 | temp = |
484 | SiS_Pr->SiS_RefIndex[rrti + i].Ext_InfoFlag & ModeTypeMask; | ||
584 | if (temp < SiS_Pr->SiS_ModeType) | 485 | if (temp < SiS_Pr->SiS_ModeType) |
585 | break; | 486 | break; |
586 | 487 | ||
587 | i++; | 488 | i++; |
588 | index--; | 489 | index--; |
589 | } while(index != 0xFFFF); | 490 | } while (index != 0xFFFF); |
590 | 491 | ||
591 | i--; | 492 | i--; |
592 | 493 | ||
@@ -597,8 +498,7 @@ SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
597 | /* SYNC */ | 498 | /* SYNC */ |
598 | /*********************************************/ | 499 | /*********************************************/ |
599 | 500 | ||
600 | static void | 501 | static void SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti) |
601 | SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti) | ||
602 | { | 502 | { |
603 | unsigned short sync = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag >> 8; | 503 | unsigned short sync = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag >> 8; |
604 | sync &= 0xC0; | 504 | sync &= 0xC0; |
@@ -612,39 +512,40 @@ SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti) | |||
612 | 512 | ||
613 | static void | 513 | static void |
614 | SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 514 | SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
615 | unsigned short ModeIdIndex, unsigned short rrti) | 515 | unsigned short ModeIdIndex, unsigned short rrti) |
616 | { | 516 | { |
617 | unsigned char index; | 517 | unsigned char index; |
618 | unsigned short temp, i, j, modeflag; | 518 | unsigned short temp, i, j, modeflag; |
619 | 519 | ||
620 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4,0x11,0x7f); | 520 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); |
621 | 521 | ||
622 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; | 522 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; |
623 | 523 | ||
624 | index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRT1CRTC; | 524 | index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRT1CRTC; |
625 | 525 | ||
626 | for(i = 0,j = 0; i <= 7; i++, j++) { | 526 | for (i = 0, j = 0; i <= 7; i++, j++) { |
627 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, | 527 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, |
628 | SiS_Pr->SiS_CRT1Table[index].CR[i]); | 528 | SiS_Pr->SiS_CRT1Table[index].CR[i]); |
629 | } | 529 | } |
630 | for(j = 0x10; i <= 10; i++, j++) { | 530 | for (j = 0x10; i <= 10; i++, j++) { |
631 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, | 531 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, |
632 | SiS_Pr->SiS_CRT1Table[index].CR[i]); | 532 | SiS_Pr->SiS_CRT1Table[index].CR[i]); |
633 | } | 533 | } |
634 | for(j = 0x15; i <= 12; i++, j++) { | 534 | for (j = 0x15; i <= 12; i++, j++) { |
635 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, | 535 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, |
636 | SiS_Pr->SiS_CRT1Table[index].CR[i]); | 536 | SiS_Pr->SiS_CRT1Table[index].CR[i]); |
637 | } | 537 | } |
638 | for(j = 0x0A; i <= 15; i++, j++) { | 538 | for (j = 0x0A; i <= 15; i++, j++) { |
639 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, j, | 539 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, j, |
640 | SiS_Pr->SiS_CRT1Table[index].CR[i]); | 540 | SiS_Pr->SiS_CRT1Table[index].CR[i]); |
641 | } | 541 | } |
642 | 542 | ||
643 | temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0; | 543 | temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0; |
644 | SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4, 0x0E, temp); | 544 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0E, temp); |
645 | 545 | ||
646 | temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5; | 546 | temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5; |
647 | if (modeflag & DoubleScanMode) temp |= 0x80; | 547 | if (modeflag & DoubleScanMode) |
548 | temp |= 0x80; | ||
648 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x09, 0x5F, temp); | 549 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x09, 0x5F, temp); |
649 | 550 | ||
650 | if (SiS_Pr->SiS_ModeType > ModeVGA) | 551 | if (SiS_Pr->SiS_ModeType > ModeVGA) |
@@ -659,10 +560,10 @@ SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
659 | 560 | ||
660 | static void | 561 | static void |
661 | SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 562 | SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
662 | unsigned short ModeIdIndex, unsigned short rrti) | 563 | unsigned short ModeIdIndex, unsigned short rrti) |
663 | { | 564 | { |
664 | unsigned short du = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, rrti); | 565 | unsigned short du = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, rrti); |
665 | unsigned short infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; | 566 | unsigned short infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; |
666 | unsigned short temp; | 567 | unsigned short temp; |
667 | 568 | ||
668 | temp = (du >> 8) & 0x0f; | 569 | temp = (du >> 8) & 0x0f; |
@@ -670,11 +571,13 @@ SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
670 | 571 | ||
671 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x13, (du & 0xFF)); | 572 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x13, (du & 0xFF)); |
672 | 573 | ||
673 | if (infoflag & InterlaceMode) du >>= 1; | 574 | if (infoflag & InterlaceMode) |
575 | du >>= 1; | ||
674 | 576 | ||
675 | du <<= 5; | 577 | du <<= 5; |
676 | temp = (du >> 8) & 0xff; | 578 | temp = (du >> 8) & 0xff; |
677 | if (du & 0xff) temp++; | 579 | if (du & 0xff) |
580 | temp++; | ||
678 | temp++; | 581 | temp++; |
679 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x10, temp); | 582 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x10, temp); |
680 | } | 583 | } |
@@ -685,17 +588,17 @@ SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
685 | 588 | ||
686 | static void | 589 | static void |
687 | SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 590 | SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
688 | unsigned short rrti) | 591 | unsigned short rrti) |
689 | { | 592 | { |
690 | unsigned short index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK; | 593 | unsigned short index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK; |
691 | unsigned short clka = SiS_Pr->SiS_VCLKData[index].SR2B; | 594 | unsigned short clka = SiS_Pr->SiS_VCLKData[index].SR2B; |
692 | unsigned short clkb = SiS_Pr->SiS_VCLKData[index].SR2C; | 595 | unsigned short clkb = SiS_Pr->SiS_VCLKData[index].SR2C; |
693 | 596 | ||
694 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x31,0xCF); | 597 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x31, 0xCF); |
695 | 598 | ||
696 | SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2B,clka); | 599 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2B, clka); |
697 | SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2C,clkb); | 600 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2C, clkb); |
698 | SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2D,0x01); | 601 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2D, 0x01); |
699 | } | 602 | } |
700 | 603 | ||
701 | /*********************************************/ | 604 | /*********************************************/ |
@@ -704,7 +607,7 @@ SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
704 | 607 | ||
705 | static void | 608 | static void |
706 | SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 609 | SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
707 | unsigned short mi) | 610 | unsigned short mi) |
708 | { | 611 | { |
709 | unsigned short modeflag = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag; | 612 | unsigned short modeflag = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag; |
710 | 613 | ||
@@ -729,7 +632,7 @@ SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
729 | 632 | ||
730 | static void | 633 | static void |
731 | SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 634 | SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
732 | unsigned short rrti) | 635 | unsigned short rrti) |
733 | { | 636 | { |
734 | unsigned short data = 0, VCLK = 0, index = 0; | 637 | unsigned short data = 0, VCLK = 0, index = 0; |
735 | 638 | ||
@@ -738,7 +641,8 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
738 | VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; | 641 | VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; |
739 | } | 642 | } |
740 | 643 | ||
741 | if (VCLK >= 166) data |= 0x0c; | 644 | if (VCLK >= 166) |
645 | data |= 0x0c; | ||
742 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x32, 0xf3, data); | 646 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x32, 0xf3, data); |
743 | 647 | ||
744 | if (VCLK >= 166) | 648 | if (VCLK >= 166) |
@@ -758,7 +662,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
758 | 662 | ||
759 | static void | 663 | static void |
760 | SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 664 | SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
761 | unsigned short ModeIdIndex, unsigned short rrti) | 665 | unsigned short ModeIdIndex, unsigned short rrti) |
762 | { | 666 | { |
763 | unsigned short data, infoflag = 0, modeflag; | 667 | unsigned short data, infoflag = 0, modeflag; |
764 | 668 | ||
@@ -778,17 +682,22 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
778 | data |= 0x02; | 682 | data |= 0x02; |
779 | data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2); | 683 | data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2); |
780 | } | 684 | } |
781 | if (infoflag & InterlaceMode) data |= 0x20; | 685 | if (infoflag & InterlaceMode) |
686 | data |= 0x20; | ||
782 | } | 687 | } |
783 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x06, 0xC0, data); | 688 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x06, 0xC0, data); |
784 | 689 | ||
785 | data = 0; | 690 | data = 0; |
786 | if (infoflag & InterlaceMode) { | 691 | if (infoflag & InterlaceMode) { |
787 | /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */ | 692 | /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */ |
788 | unsigned short hrs = (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x04) | | 693 | unsigned short hrs = |
789 | ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0xc0) << 2)) - 3; | 694 | (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x04) | |
790 | unsigned short hto = (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x00) | | 695 | ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0xc0) << 2)) |
791 | ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0x03) << 8)) + 5; | 696 | - 3; |
697 | unsigned short hto = | ||
698 | (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x00) | | ||
699 | ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0x03) << 8)) | ||
700 | + 5; | ||
792 | data = hrs - (hto >> 1) + 3; | 701 | data = hrs - (hto >> 1) + 3; |
793 | } | 702 | } |
794 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x19, (data & 0xFF)); | 703 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x19, (data & 0xFF)); |
@@ -829,20 +738,26 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
829 | 738 | ||
830 | static void | 739 | static void |
831 | SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData, | 740 | SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData, |
832 | unsigned short shiftflag, unsigned short dl, unsigned short ah, | 741 | unsigned short shiftflag, unsigned short dl, unsigned short ah, |
833 | unsigned short al, unsigned short dh) | 742 | unsigned short al, unsigned short dh) |
834 | { | 743 | { |
835 | unsigned short d1, d2, d3; | 744 | unsigned short d1, d2, d3; |
836 | 745 | ||
837 | switch (dl) { | 746 | switch (dl) { |
838 | case 0: | 747 | case 0: |
839 | d1 = dh; d2 = ah; d3 = al; | 748 | d1 = dh; |
840 | break; | 749 | d2 = ah; |
841 | case 1: | 750 | d3 = al; |
842 | d1 = ah; d2 = al; d3 = dh; | 751 | break; |
843 | break; | 752 | case 1: |
844 | default: | 753 | d1 = ah; |
845 | d1 = al; d2 = dh; d3 = ah; | 754 | d2 = al; |
755 | d3 = dh; | ||
756 | break; | ||
757 | default: | ||
758 | d1 = al; | ||
759 | d2 = dh; | ||
760 | d3 = ah; | ||
846 | } | 761 | } |
847 | SiS_SetRegByte(SiS_Pr, DACData, (d1 << shiftflag)); | 762 | SiS_SetRegByte(SiS_Pr, DACData, (d1 << shiftflag)); |
848 | SiS_SetRegByte(SiS_Pr, DACData, (d2 << shiftflag)); | 763 | SiS_SetRegByte(SiS_Pr, DACData, (d2 << shiftflag)); |
@@ -850,7 +765,8 @@ SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData, | |||
850 | } | 765 | } |
851 | 766 | ||
852 | static void | 767 | static void |
853 | SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short mi) | 768 | SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
769 | unsigned short mi) | ||
854 | { | 770 | { |
855 | unsigned short data, data2, time, i, j, k, m, n, o; | 771 | unsigned short data, data2, time, i, j, k, m, n, o; |
856 | unsigned short si, di, bx, sf; | 772 | unsigned short si, di, bx, sf; |
@@ -884,41 +800,45 @@ SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short mi | |||
884 | 800 | ||
885 | SiS_SetRegByte(SiS_Pr, DACAddr, 0x00); | 801 | SiS_SetRegByte(SiS_Pr, DACAddr, 0x00); |
886 | 802 | ||
887 | for(i = 0; i < j; i++) { | 803 | for (i = 0; i < j; i++) { |
888 | data = table[i]; | 804 | data = table[i]; |
889 | for(k = 0; k < 3; k++) { | 805 | for (k = 0; k < 3; k++) { |
890 | data2 = 0; | 806 | data2 = 0; |
891 | if (data & 0x01) data2 += 0x2A; | 807 | if (data & 0x01) |
892 | if (data & 0x02) data2 += 0x15; | 808 | data2 += 0x2A; |
809 | if (data & 0x02) | ||
810 | data2 += 0x15; | ||
893 | SiS_SetRegByte(SiS_Pr, DACData, (data2 << sf)); | 811 | SiS_SetRegByte(SiS_Pr, DACData, (data2 << sf)); |
894 | data >>= 2; | 812 | data >>= 2; |
895 | } | 813 | } |
896 | } | 814 | } |
897 | 815 | ||
898 | if (time == 256) { | 816 | if (time == 256) { |
899 | for(i = 16; i < 32; i++) { | 817 | for (i = 16; i < 32; i++) { |
900 | data = table[i] << sf; | 818 | data = table[i] << sf; |
901 | for(k = 0; k < 3; k++) | 819 | for (k = 0; k < 3; k++) |
902 | SiS_SetRegByte(SiS_Pr, DACData, data); | 820 | SiS_SetRegByte(SiS_Pr, DACData, data); |
903 | } | 821 | } |
904 | si = 32; | 822 | si = 32; |
905 | for(m = 0; m < 9; m++) { | 823 | for (m = 0; m < 9; m++) { |
906 | di = si; | 824 | di = si; |
907 | bx = si + 4; | 825 | bx = si + 4; |
908 | for(n = 0; n < 3; n++) { | 826 | for (n = 0; n < 3; n++) { |
909 | for(o = 0; o < 5; o++) { | 827 | for (o = 0; o < 5; o++) { |
910 | SiS_WriteDAC(SiS_Pr, DACData, sf, n, | 828 | SiS_WriteDAC(SiS_Pr, DACData, sf, n, |
911 | table[di], table[bx], table[si]); | 829 | table[di], table[bx], |
830 | table[si]); | ||
912 | si++; | 831 | si++; |
913 | } | 832 | } |
914 | si -= 2; | 833 | si -= 2; |
915 | for(o = 0; o < 3; o++) { | 834 | for (o = 0; o < 3; o++) { |
916 | SiS_WriteDAC(SiS_Pr, DACData, sf, n, | 835 | SiS_WriteDAC(SiS_Pr, DACData, sf, n, |
917 | table[di], table[si], table[bx]); | 836 | table[di], table[si], |
837 | table[bx]); | ||
918 | si--; | 838 | si--; |
919 | } | 839 | } |
920 | } | 840 | } |
921 | si += 5; | 841 | si += 5; |
922 | } | 842 | } |
923 | } | 843 | } |
924 | } | 844 | } |
@@ -929,7 +849,7 @@ SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short mi | |||
929 | 849 | ||
930 | static void | 850 | static void |
931 | SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 851 | SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
932 | unsigned short ModeIdIndex) | 852 | unsigned short ModeIdIndex) |
933 | { | 853 | { |
934 | unsigned short StandTableIndex, rrti; | 854 | unsigned short StandTableIndex, rrti; |
935 | 855 | ||
@@ -970,11 +890,10 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
970 | /* SiSSetMode() */ | 890 | /* SiSSetMode() */ |
971 | /*********************************************/ | 891 | /*********************************************/ |
972 | 892 | ||
973 | int | 893 | int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) |
974 | SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | ||
975 | { | 894 | { |
976 | unsigned short ModeIdIndex; | 895 | unsigned short ModeIdIndex; |
977 | unsigned long BaseAddr = SiS_Pr->IOAddress; | 896 | unsigned long BaseAddr = SiS_Pr->IOAddress; |
978 | 897 | ||
979 | SiSUSB_InitPtr(SiS_Pr); | 898 | SiSUSB_InitPtr(SiS_Pr); |
980 | SiSUSBRegInit(SiS_Pr, BaseAddr); | 899 | SiSUSBRegInit(SiS_Pr, BaseAddr); |
@@ -990,7 +909,7 @@ SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
990 | ModeNo &= 0x7f; | 909 | ModeNo &= 0x7f; |
991 | 910 | ||
992 | SiS_Pr->SiS_ModeType = | 911 | SiS_Pr->SiS_ModeType = |
993 | SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag & ModeTypeMask; | 912 | SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag & ModeTypeMask; |
994 | 913 | ||
995 | SiS_Pr->SiS_SetFlag = LowModeTests; | 914 | SiS_Pr->SiS_SetFlag = LowModeTests; |
996 | 915 | ||
@@ -1008,8 +927,7 @@ SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
1008 | return 1; | 927 | return 1; |
1009 | } | 928 | } |
1010 | 929 | ||
1011 | int | 930 | int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) |
1012 | SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) | ||
1013 | { | 931 | { |
1014 | unsigned short ModeNo = 0; | 932 | unsigned short ModeNo = 0; |
1015 | int i; | 933 | int i; |
@@ -1041,7 +959,3 @@ SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) | |||
1041 | } | 959 | } |
1042 | 960 | ||
1043 | #endif /* INCL_SISUSB_CON */ | 961 | #endif /* INCL_SISUSB_CON */ |
1044 | |||
1045 | |||
1046 | |||
1047 | |||
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.h b/drivers/usb/misc/sisusbvga/sisusb_init.h index 864bc0e96591..c46ce42d4489 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.h +++ b/drivers/usb/misc/sisusbvga/sisusb_init.h | |||
@@ -46,7 +46,7 @@ | |||
46 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 46 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
47 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 47 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
48 | * | 48 | * |
49 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 49 | * Author: Thomas Winischhofer <thomas@winischhofer.net> |
50 | * | 50 | * |
51 | */ | 51 | */ |
52 | 52 | ||
@@ -76,21 +76,21 @@ | |||
76 | #define CRT2Mode 0x0800 | 76 | #define CRT2Mode 0x0800 |
77 | #define HalfDCLK 0x1000 | 77 | #define HalfDCLK 0x1000 |
78 | #define NoSupportSimuTV 0x2000 | 78 | #define NoSupportSimuTV 0x2000 |
79 | #define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */ | 79 | #define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */ |
80 | #define DoubleScanMode 0x8000 | 80 | #define DoubleScanMode 0x8000 |
81 | 81 | ||
82 | /* Infoflag */ | 82 | /* Infoflag */ |
83 | #define SupportTV 0x0008 | 83 | #define SupportTV 0x0008 |
84 | #define SupportTV1024 0x0800 | 84 | #define SupportTV1024 0x0800 |
85 | #define SupportCHTV 0x0800 | 85 | #define SupportCHTV 0x0800 |
86 | #define Support64048060Hz 0x0800 /* Special for 640x480 LCD */ | 86 | #define Support64048060Hz 0x0800 /* Special for 640x480 LCD */ |
87 | #define SupportHiVision 0x0010 | 87 | #define SupportHiVision 0x0010 |
88 | #define SupportYPbPr750p 0x1000 | 88 | #define SupportYPbPr750p 0x1000 |
89 | #define SupportLCD 0x0020 | 89 | #define SupportLCD 0x0020 |
90 | #define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */ | 90 | #define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */ |
91 | #define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */ | 91 | #define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */ |
92 | #define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */ | 92 | #define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */ |
93 | #define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */ | 93 | #define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */ |
94 | #define InterlaceMode 0x0080 | 94 | #define InterlaceMode 0x0080 |
95 | #define SyncPP 0x0000 | 95 | #define SyncPP 0x0000 |
96 | #define SyncPN 0x4000 | 96 | #define SyncPN 0x4000 |
@@ -129,7 +129,7 @@ | |||
129 | #define SIS_RI_856x480 19 | 129 | #define SIS_RI_856x480 19 |
130 | #define SIS_RI_1280x768 20 | 130 | #define SIS_RI_1280x768 20 |
131 | #define SIS_RI_1400x1050 21 | 131 | #define SIS_RI_1400x1050 21 |
132 | #define SIS_RI_1152x864 22 /* Up to here SiS conforming */ | 132 | #define SIS_RI_1152x864 22 /* Up to here SiS conforming */ |
133 | #define SIS_RI_848x480 23 | 133 | #define SIS_RI_848x480 23 |
134 | #define SIS_RI_1360x768 24 | 134 | #define SIS_RI_1360x768 24 |
135 | #define SIS_RI_1024x600 25 | 135 | #define SIS_RI_1024x600 25 |
@@ -147,691 +147,691 @@ | |||
147 | #define SIS_CRT2_PORT_04 0x04 - 0x30 | 147 | #define SIS_CRT2_PORT_04 0x04 - 0x30 |
148 | 148 | ||
149 | /* Mode numbers */ | 149 | /* Mode numbers */ |
150 | static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f}; | 150 | static const unsigned short ModeIndex_320x200[] = { 0x59, 0x41, 0x00, 0x4f }; |
151 | static const unsigned short ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53}; | 151 | static const unsigned short ModeIndex_320x240[] = { 0x50, 0x56, 0x00, 0x53 }; |
152 | static const unsigned short ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54}; | 152 | static const unsigned short ModeIndex_400x300[] = { 0x51, 0x57, 0x00, 0x54 }; |
153 | static const unsigned short ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c}; | 153 | static const unsigned short ModeIndex_512x384[] = { 0x52, 0x58, 0x00, 0x5c }; |
154 | static const unsigned short ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e}; | 154 | static const unsigned short ModeIndex_640x400[] = { 0x2f, 0x5d, 0x00, 0x5e }; |
155 | static const unsigned short ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62}; | 155 | static const unsigned short ModeIndex_640x480[] = { 0x2e, 0x44, 0x00, 0x62 }; |
156 | static const unsigned short ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35}; | 156 | static const unsigned short ModeIndex_720x480[] = { 0x31, 0x33, 0x00, 0x35 }; |
157 | static const unsigned short ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36}; | 157 | static const unsigned short ModeIndex_720x576[] = { 0x32, 0x34, 0x00, 0x36 }; |
158 | static const unsigned short ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61}; | 158 | static const unsigned short ModeIndex_768x576[] = { 0x5f, 0x60, 0x00, 0x61 }; |
159 | static const unsigned short ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76}; | 159 | static const unsigned short ModeIndex_800x480[] = { 0x70, 0x7a, 0x00, 0x76 }; |
160 | static const unsigned short ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63}; | 160 | static const unsigned short ModeIndex_800x600[] = { 0x30, 0x47, 0x00, 0x63 }; |
161 | static const unsigned short ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e}; | 161 | static const unsigned short ModeIndex_848x480[] = { 0x39, 0x3b, 0x00, 0x3e }; |
162 | static const unsigned short ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45}; | 162 | static const unsigned short ModeIndex_856x480[] = { 0x3f, 0x42, 0x00, 0x45 }; |
163 | static const unsigned short ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f}; | 163 | static const unsigned short ModeIndex_960x540[] = { 0x1d, 0x1e, 0x00, 0x1f }; |
164 | static const unsigned short ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22}; | 164 | static const unsigned short ModeIndex_960x600[] = { 0x20, 0x21, 0x00, 0x22 }; |
165 | static const unsigned short ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64}; | 165 | static const unsigned short ModeIndex_1024x768[] = { 0x38, 0x4a, 0x00, 0x64 }; |
166 | static const unsigned short ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77}; | 166 | static const unsigned short ModeIndex_1024x576[] = { 0x71, 0x74, 0x00, 0x77 }; |
167 | static const unsigned short ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b}; | 167 | static const unsigned short ModeIndex_1152x864[] = { 0x29, 0x2a, 0x00, 0x2b }; |
168 | static const unsigned short ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78}; | 168 | static const unsigned short ModeIndex_1280x720[] = { 0x79, 0x75, 0x00, 0x78 }; |
169 | static const unsigned short ModeIndex_1280x768[] = {0x23, 0x24, 0x00, 0x25}; | 169 | static const unsigned short ModeIndex_1280x768[] = { 0x23, 0x24, 0x00, 0x25 }; |
170 | static const unsigned short ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65}; | 170 | static const unsigned short ModeIndex_1280x1024[] = { 0x3a, 0x4d, 0x00, 0x65 }; |
171 | 171 | ||
172 | static const unsigned char SiS_MDA_DAC[] = | 172 | static const unsigned char SiS_MDA_DAC[] = { |
173 | { | 173 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
174 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 174 | 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, |
175 | 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, | 175 | 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, |
176 | 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, | 176 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
177 | 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, | 177 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
178 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 178 | 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, |
179 | 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, | 179 | 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, |
180 | 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, | 180 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F |
181 | 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F | ||
182 | }; | 181 | }; |
183 | 182 | ||
184 | static const unsigned char SiS_CGA_DAC[] = | 183 | static const unsigned char SiS_CGA_DAC[] = { |
185 | { | 184 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
186 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 185 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
187 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 186 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, |
188 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, | 187 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, |
189 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, | 188 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
190 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 189 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
191 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 190 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, |
192 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, | 191 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F |
193 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F | ||
194 | }; | 192 | }; |
195 | 193 | ||
196 | static const unsigned char SiS_EGA_DAC[] = | 194 | static const unsigned char SiS_EGA_DAC[] = { |
197 | { | 195 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15, |
198 | 0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15, | 196 | 0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35, |
199 | 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35, | 197 | 0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D, |
200 | 0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D, | 198 | 0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D, |
201 | 0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D, | 199 | 0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17, |
202 | 0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17, | 200 | 0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37, |
203 | 0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37, | 201 | 0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F, |
204 | 0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F, | 202 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F |
205 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F | ||
206 | }; | 203 | }; |
207 | 204 | ||
208 | static const unsigned char SiS_VGA_DAC[] = | 205 | static const unsigned char SiS_VGA_DAC[] = { |
209 | { | 206 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
210 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 207 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, |
211 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, | 208 | 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18, |
212 | 0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18, | 209 | 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F, |
213 | 0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F, | 210 | 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F, |
214 | 0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F, | 211 | 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00, |
215 | 0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00, | 212 | 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18, |
216 | 0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18, | 213 | 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04, |
217 | 0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04, | 214 | 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10, |
218 | 0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10, | 215 | 0x0B, 0x0C, 0x0D, 0x0F, 0x10 |
219 | 0x0B,0x0C,0x0D,0x0F,0x10 | ||
220 | }; | 216 | }; |
221 | 217 | ||
222 | static const struct SiS_St SiSUSB_SModeIDTable[] = | 218 | static const struct SiS_St SiSUSB_SModeIDTable[] = { |
223 | { | 219 | {0x03, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x01, 0x03, 0x40}, |
224 | {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03,0x40}, | 220 | {0xff, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} |
225 | {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00} | ||
226 | }; | 221 | }; |
227 | 222 | ||
228 | static const struct SiS_StResInfo_S SiSUSB_StResInfo[] = | 223 | static const struct SiS_StResInfo_S SiSUSB_StResInfo[] = { |
229 | { | 224 | {640, 400}, |
230 | { 640,400}, | 225 | {640, 350}, |
231 | { 640,350}, | 226 | {720, 400}, |
232 | { 720,400}, | 227 | {720, 350}, |
233 | { 720,350}, | 228 | {640, 480} |
234 | { 640,480} | ||
235 | }; | 229 | }; |
236 | 230 | ||
237 | static const struct SiS_ModeResInfo SiSUSB_ModeResInfo[] = | 231 | static const struct SiS_ModeResInfo SiSUSB_ModeResInfo[] = { |
238 | { | 232 | {320, 200, 8, 8}, /* 0x00 */ |
239 | { 320, 200, 8, 8}, /* 0x00 */ | 233 | {320, 240, 8, 8}, /* 0x01 */ |
240 | { 320, 240, 8, 8}, /* 0x01 */ | 234 | {320, 400, 8, 8}, /* 0x02 */ |
241 | { 320, 400, 8, 8}, /* 0x02 */ | 235 | {400, 300, 8, 8}, /* 0x03 */ |
242 | { 400, 300, 8, 8}, /* 0x03 */ | 236 | {512, 384, 8, 8}, /* 0x04 */ |
243 | { 512, 384, 8, 8}, /* 0x04 */ | 237 | {640, 400, 8, 16}, /* 0x05 */ |
244 | { 640, 400, 8,16}, /* 0x05 */ | 238 | {640, 480, 8, 16}, /* 0x06 */ |
245 | { 640, 480, 8,16}, /* 0x06 */ | 239 | {800, 600, 8, 16}, /* 0x07 */ |
246 | { 800, 600, 8,16}, /* 0x07 */ | 240 | {1024, 768, 8, 16}, /* 0x08 */ |
247 | { 1024, 768, 8,16}, /* 0x08 */ | 241 | {1280, 1024, 8, 16}, /* 0x09 */ |
248 | { 1280,1024, 8,16}, /* 0x09 */ | 242 | {1600, 1200, 8, 16}, /* 0x0a */ |
249 | { 1600,1200, 8,16}, /* 0x0a */ | 243 | {1920, 1440, 8, 16}, /* 0x0b */ |
250 | { 1920,1440, 8,16}, /* 0x0b */ | 244 | {2048, 1536, 8, 16}, /* 0x0c */ |
251 | { 2048,1536, 8,16}, /* 0x0c */ | 245 | {720, 480, 8, 16}, /* 0x0d */ |
252 | { 720, 480, 8,16}, /* 0x0d */ | 246 | {720, 576, 8, 16}, /* 0x0e */ |
253 | { 720, 576, 8,16}, /* 0x0e */ | 247 | {1280, 960, 8, 16}, /* 0x0f */ |
254 | { 1280, 960, 8,16}, /* 0x0f */ | 248 | {800, 480, 8, 16}, /* 0x10 */ |
255 | { 800, 480, 8,16}, /* 0x10 */ | 249 | {1024, 576, 8, 16}, /* 0x11 */ |
256 | { 1024, 576, 8,16}, /* 0x11 */ | 250 | {1280, 720, 8, 16}, /* 0x12 */ |
257 | { 1280, 720, 8,16}, /* 0x12 */ | 251 | {856, 480, 8, 16}, /* 0x13 */ |
258 | { 856, 480, 8,16}, /* 0x13 */ | 252 | {1280, 768, 8, 16}, /* 0x14 */ |
259 | { 1280, 768, 8,16}, /* 0x14 */ | 253 | {1400, 1050, 8, 16}, /* 0x15 */ |
260 | { 1400,1050, 8,16}, /* 0x15 */ | 254 | {1152, 864, 8, 16}, /* 0x16 */ |
261 | { 1152, 864, 8,16}, /* 0x16 */ | 255 | {848, 480, 8, 16}, /* 0x17 */ |
262 | { 848, 480, 8,16}, /* 0x17 */ | 256 | {1360, 768, 8, 16}, /* 0x18 */ |
263 | { 1360, 768, 8,16}, /* 0x18 */ | 257 | {1024, 600, 8, 16}, /* 0x19 */ |
264 | { 1024, 600, 8,16}, /* 0x19 */ | 258 | {1152, 768, 8, 16}, /* 0x1a */ |
265 | { 1152, 768, 8,16}, /* 0x1a */ | 259 | {768, 576, 8, 16}, /* 0x1b */ |
266 | { 768, 576, 8,16}, /* 0x1b */ | 260 | {1360, 1024, 8, 16}, /* 0x1c */ |
267 | { 1360,1024, 8,16}, /* 0x1c */ | 261 | {1680, 1050, 8, 16}, /* 0x1d */ |
268 | { 1680,1050, 8,16}, /* 0x1d */ | 262 | {1280, 800, 8, 16}, /* 0x1e */ |
269 | { 1280, 800, 8,16}, /* 0x1e */ | 263 | {1920, 1080, 8, 16}, /* 0x1f */ |
270 | { 1920,1080, 8,16}, /* 0x1f */ | 264 | {960, 540, 8, 16}, /* 0x20 */ |
271 | { 960, 540, 8,16}, /* 0x20 */ | 265 | {960, 600, 8, 16} /* 0x21 */ |
272 | { 960, 600, 8,16} /* 0x21 */ | ||
273 | }; | 266 | }; |
274 | 267 | ||
275 | static const struct SiS_StandTable SiSUSB_StandTable[] = | 268 | static const struct SiS_StandTable SiSUSB_StandTable[] = { |
276 | { | ||
277 | /* MD_3_400 - mode 0x03 - 400 */ | 269 | /* MD_3_400 - mode 0x03 - 400 */ |
278 | { | 270 | { |
279 | 0x50,0x18,0x10,0x1000, | 271 | 0x50, 0x18, 0x10, 0x1000, |
280 | { 0x00,0x03,0x00,0x02 }, | 272 | {0x00, 0x03, 0x00, 0x02}, |
281 | 0x67, | 273 | 0x67, |
282 | { 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, | 274 | {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, |
283 | 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, | 275 | 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, |
284 | 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, | 276 | 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, |
285 | 0xff }, | 277 | 0xff}, |
286 | { 0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, | 278 | {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, |
287 | 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, | 279 | 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, |
288 | 0x0c,0x00,0x0f,0x08 }, | 280 | 0x0c, 0x00, 0x0f, 0x08}, |
289 | { 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, 0xff } | 281 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff} |
290 | }, | 282 | }, |
291 | /* Generic for VGA and higher */ | 283 | /* Generic for VGA and higher */ |
292 | { | 284 | { |
293 | 0x00,0x00,0x00,0x0000, | 285 | 0x00, 0x00, 0x00, 0x0000, |
294 | { 0x01,0x0f,0x00,0x0e }, | 286 | {0x01, 0x0f, 0x00, 0x0e}, |
295 | 0x23, | 287 | 0x23, |
296 | { 0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, | 288 | {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, |
297 | 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, | 289 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
298 | 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, | 290 | 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3, |
299 | 0xff }, | 291 | 0xff}, |
300 | { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, | 292 | {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
301 | 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, | 293 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
302 | 0x01,0x00,0x00,0x00 }, | 294 | 0x01, 0x00, 0x00, 0x00}, |
303 | { 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, 0xff } | 295 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff} |
304 | } | 296 | } |
305 | }; | 297 | }; |
306 | 298 | ||
307 | static const struct SiS_Ext SiSUSB_EModeIDTable[] = | 299 | static const struct SiS_Ext SiSUSB_EModeIDTable[] = { |
308 | { | 300 | {0x2e, 0x0a1b, 0x0101, SIS_RI_640x480, 0x00, 0x00, 0x05, 0x05, 0x08, 2}, /* 640x480x8 */ |
309 | {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */ | 301 | {0x2f, 0x0a1b, 0x0100, SIS_RI_640x400, 0x00, 0x00, 0x05, 0x05, 0x10, 0}, /* 640x400x8 */ |
310 | {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */ | 302 | {0x30, 0x2a1b, 0x0103, SIS_RI_800x600, 0x00, 0x00, 0x07, 0x06, 0x00, 3}, /* 800x600x8 */ |
311 | {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */ | 303 | {0x31, 0x4a1b, 0x0000, SIS_RI_720x480, 0x00, 0x00, 0x06, 0x06, 0x11, -1}, /* 720x480x8 */ |
312 | {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */ | 304 | {0x32, 0x4a1b, 0x0000, SIS_RI_720x576, 0x00, 0x00, 0x06, 0x06, 0x12, -1}, /* 720x576x8 */ |
313 | {0x32,0x4a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */ | 305 | {0x33, 0x4a1d, 0x0000, SIS_RI_720x480, 0x00, 0x00, 0x06, 0x06, 0x11, -1}, /* 720x480x16 */ |
314 | {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */ | 306 | {0x34, 0x6a1d, 0x0000, SIS_RI_720x576, 0x00, 0x00, 0x06, 0x06, 0x12, -1}, /* 720x576x16 */ |
315 | {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */ | 307 | {0x35, 0x4a1f, 0x0000, SIS_RI_720x480, 0x00, 0x00, 0x06, 0x06, 0x11, -1}, /* 720x480x32 */ |
316 | {0x35,0x4a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x32 */ | 308 | {0x36, 0x6a1f, 0x0000, SIS_RI_720x576, 0x00, 0x00, 0x06, 0x06, 0x12, -1}, /* 720x576x32 */ |
317 | {0x36,0x6a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x32 */ | 309 | {0x38, 0x0a1b, 0x0105, SIS_RI_1024x768, 0x00, 0x00, 0x08, 0x07, 0x13, 4}, /* 1024x768x8 */ |
318 | {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x8 */ | 310 | {0x3a, 0x0e3b, 0x0107, SIS_RI_1280x1024, 0x00, 0x00, 0x00, 0x00, 0x2f, 8}, /* 1280x1024x8 */ |
319 | {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x8 */ | 311 | {0x41, 0x9a1d, 0x010e, SIS_RI_320x200, 0x00, 0x00, 0x04, 0x04, 0x1a, 0}, /* 320x200x16 */ |
320 | {0x41,0x9a1d,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x16 */ | 312 | {0x44, 0x0a1d, 0x0111, SIS_RI_640x480, 0x00, 0x00, 0x05, 0x05, 0x08, 2}, /* 640x480x16 */ |
321 | {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x16 */ | 313 | {0x47, 0x2a1d, 0x0114, SIS_RI_800x600, 0x00, 0x00, 0x07, 0x06, 0x00, 3}, /* 800x600x16 */ |
322 | {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x16 */ | 314 | {0x4a, 0x0a3d, 0x0117, SIS_RI_1024x768, 0x00, 0x00, 0x08, 0x07, 0x13, 4}, /* 1024x768x16 */ |
323 | {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x16 */ | 315 | {0x4d, 0x0e7d, 0x011a, SIS_RI_1280x1024, 0x00, 0x00, 0x00, 0x00, 0x2f, 8}, /* 1280x1024x16 */ |
324 | {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x16 */ | 316 | {0x50, 0x9a1b, 0x0132, SIS_RI_320x240, 0x00, 0x00, 0x04, 0x04, 0x1b, 2}, /* 320x240x8 */ |
325 | {0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x8 */ | 317 | {0x51, 0xba1b, 0x0133, SIS_RI_400x300, 0x00, 0x00, 0x07, 0x07, 0x1c, 3}, /* 400x300x8 */ |
326 | {0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x8 */ | 318 | {0x52, 0xba1b, 0x0134, SIS_RI_512x384, 0x00, 0x00, 0x00, 0x00, 0x1d, 4}, /* 512x384x8 */ |
327 | {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x8 */ | 319 | {0x56, 0x9a1d, 0x0135, SIS_RI_320x240, 0x00, 0x00, 0x04, 0x04, 0x1b, 2}, /* 320x240x16 */ |
328 | {0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x16 */ | 320 | {0x57, 0xba1d, 0x0136, SIS_RI_400x300, 0x00, 0x00, 0x07, 0x07, 0x1c, 3}, /* 400x300x16 */ |
329 | {0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x16 */ | 321 | {0x58, 0xba1d, 0x0137, SIS_RI_512x384, 0x00, 0x00, 0x00, 0x00, 0x1d, 4}, /* 512x384x16 */ |
330 | {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x16 */ | 322 | {0x59, 0x9a1b, 0x0138, SIS_RI_320x200, 0x00, 0x00, 0x04, 0x04, 0x1a, 0}, /* 320x200x8 */ |
331 | {0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x8 */ | 323 | {0x5c, 0xba1f, 0x0000, SIS_RI_512x384, 0x00, 0x00, 0x00, 0x00, 0x1d, 4}, /* 512x384x32 */ |
332 | {0x5c,0xba1f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x32 */ | 324 | {0x5d, 0x0a1d, 0x0139, SIS_RI_640x400, 0x00, 0x00, 0x05, 0x07, 0x10, 0}, /* 640x400x16 */ |
333 | {0x5d,0x0a1d,0x0139,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x16 */ | 325 | {0x5e, 0x0a1f, 0x0000, SIS_RI_640x400, 0x00, 0x00, 0x05, 0x07, 0x10, 0}, /* 640x400x32 */ |
334 | {0x5e,0x0a1f,0x0000,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x32 */ | 326 | {0x62, 0x0a3f, 0x013a, SIS_RI_640x480, 0x00, 0x00, 0x05, 0x05, 0x08, 2}, /* 640x480x32 */ |
335 | {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x32 */ | 327 | {0x63, 0x2a3f, 0x013b, SIS_RI_800x600, 0x00, 0x00, 0x07, 0x06, 0x00, 3}, /* 800x600x32 */ |
336 | {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x32 */ | 328 | {0x64, 0x0a7f, 0x013c, SIS_RI_1024x768, 0x00, 0x00, 0x08, 0x07, 0x13, 4}, /* 1024x768x32 */ |
337 | {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x32 */ | 329 | {0x65, 0x0eff, 0x013d, SIS_RI_1280x1024, 0x00, 0x00, 0x00, 0x00, 0x2f, 8}, /* 1280x1024x32 */ |
338 | {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x32 */ | 330 | {0x70, 0x6a1b, 0x0000, SIS_RI_800x480, 0x00, 0x00, 0x07, 0x07, 0x1e, -1}, /* 800x480x8 */ |
339 | {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x8 */ | 331 | {0x71, 0x4a1b, 0x0000, SIS_RI_1024x576, 0x00, 0x00, 0x00, 0x00, 0x21, -1}, /* 1024x576x8 */ |
340 | {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x8 */ | 332 | {0x74, 0x4a1d, 0x0000, SIS_RI_1024x576, 0x00, 0x00, 0x00, 0x00, 0x21, -1}, /* 1024x576x16 */ |
341 | {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x16 */ | 333 | {0x75, 0x0a3d, 0x0000, SIS_RI_1280x720, 0x00, 0x00, 0x00, 0x00, 0x24, 5}, /* 1280x720x16 */ |
342 | {0x75,0x0a3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x16 */ | 334 | {0x76, 0x6a1f, 0x0000, SIS_RI_800x480, 0x00, 0x00, 0x07, 0x07, 0x1e, -1}, /* 800x480x32 */ |
343 | {0x76,0x6a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x32 */ | 335 | {0x77, 0x4a1f, 0x0000, SIS_RI_1024x576, 0x00, 0x00, 0x00, 0x00, 0x21, -1}, /* 1024x576x32 */ |
344 | {0x77,0x4a1f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x32 */ | 336 | {0x78, 0x0a3f, 0x0000, SIS_RI_1280x720, 0x00, 0x00, 0x00, 0x00, 0x24, 5}, /* 1280x720x32 */ |
345 | {0x78,0x0a3f,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x32 */ | 337 | {0x79, 0x0a3b, 0x0000, SIS_RI_1280x720, 0x00, 0x00, 0x00, 0x00, 0x24, 5}, /* 1280x720x8 */ |
346 | {0x79,0x0a3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x8 */ | 338 | {0x7a, 0x6a1d, 0x0000, SIS_RI_800x480, 0x00, 0x00, 0x07, 0x07, 0x1e, -1}, /* 800x480x16 */ |
347 | {0x7a,0x6a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x16 */ | 339 | {0x23, 0x0e3b, 0x0000, SIS_RI_1280x768, 0x00, 0x00, 0x00, 0x00, 0x27, 6}, /* 1280x768x8 */ |
348 | {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x8 */ | 340 | {0x24, 0x0e7d, 0x0000, SIS_RI_1280x768, 0x00, 0x00, 0x00, 0x00, 0x27, 6}, /* 1280x768x16 */ |
349 | {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x16 */ | 341 | {0x25, 0x0eff, 0x0000, SIS_RI_1280x768, 0x00, 0x00, 0x00, 0x00, 0x27, 6}, /* 1280x768x32 */ |
350 | {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x32 */ | 342 | {0x39, 0x6a1b, 0x0000, SIS_RI_848x480, 0x00, 0x00, 0x00, 0x00, 0x28, -1}, /* 848x480 */ |
351 | {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1}, /* 848x480 */ | 343 | {0x3b, 0x6a3d, 0x0000, SIS_RI_848x480, 0x00, 0x00, 0x00, 0x00, 0x28, |
352 | {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1}, | 344 | -1}, |
353 | {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1}, | 345 | {0x3e, 0x6a7f, 0x0000, SIS_RI_848x480, 0x00, 0x00, 0x00, 0x00, 0x28, |
354 | {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1}, /* 856x480 */ | 346 | -1}, |
355 | {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1}, | 347 | {0x3f, 0x6a1b, 0x0000, SIS_RI_856x480, 0x00, 0x00, 0x00, 0x00, 0x2a, -1}, /* 856x480 */ |
356 | {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1}, | 348 | {0x42, 0x6a3d, 0x0000, SIS_RI_856x480, 0x00, 0x00, 0x00, 0x00, 0x2a, |
357 | {0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x32 */ | 349 | -1}, |
358 | {0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x32 */ | 350 | {0x45, 0x6a7f, 0x0000, SIS_RI_856x480, 0x00, 0x00, 0x00, 0x00, 0x2a, |
359 | {0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x32 */ | 351 | -1}, |
360 | {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1}, /* 768x576 */ | 352 | {0x4f, 0x9a1f, 0x0000, SIS_RI_320x200, 0x00, 0x00, 0x04, 0x04, 0x1a, 0}, /* 320x200x32 */ |
361 | {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1}, | 353 | {0x53, 0x9a1f, 0x0000, SIS_RI_320x240, 0x00, 0x00, 0x04, 0x04, 0x1b, 2}, /* 320x240x32 */ |
362 | {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1}, | 354 | {0x54, 0xba1f, 0x0000, SIS_RI_400x300, 0x00, 0x00, 0x07, 0x07, 0x1c, 3}, /* 400x300x32 */ |
363 | {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1}, /* 960x540 */ | 355 | {0x5f, 0x6a1b, 0x0000, SIS_RI_768x576, 0x00, 0x00, 0x06, 0x06, 0x2c, -1}, /* 768x576 */ |
364 | {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1}, | 356 | {0x60, 0x6a1d, 0x0000, SIS_RI_768x576, 0x00, 0x00, 0x06, 0x06, 0x2c, |
365 | {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1}, | 357 | -1}, |
366 | {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1}, /* 960x600 */ | 358 | {0x61, 0x6a3f, 0x0000, SIS_RI_768x576, 0x00, 0x00, 0x06, 0x06, 0x2c, |
367 | {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1}, | 359 | -1}, |
368 | {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1}, | 360 | {0x1d, 0x6a1b, 0x0000, SIS_RI_960x540, 0x00, 0x00, 0x00, 0x00, 0x2d, -1}, /* 960x540 */ |
369 | {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1152x864 */ | 361 | {0x1e, 0x6a3d, 0x0000, SIS_RI_960x540, 0x00, 0x00, 0x00, 0x00, 0x2d, |
370 | {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1}, | 362 | -1}, |
371 | {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1}, | 363 | {0x1f, 0x6a7f, 0x0000, SIS_RI_960x540, 0x00, 0x00, 0x00, 0x00, 0x2d, |
372 | {0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1} | 364 | -1}, |
365 | {0x20, 0x6a1b, 0x0000, SIS_RI_960x600, 0x00, 0x00, 0x00, 0x00, 0x2e, -1}, /* 960x600 */ | ||
366 | {0x21, 0x6a3d, 0x0000, SIS_RI_960x600, 0x00, 0x00, 0x00, 0x00, 0x2e, | ||
367 | -1}, | ||
368 | {0x22, 0x6a7f, 0x0000, SIS_RI_960x600, 0x00, 0x00, 0x00, 0x00, 0x2e, | ||
369 | -1}, | ||
370 | {0x29, 0x4e1b, 0x0000, SIS_RI_1152x864, 0x00, 0x00, 0x00, 0x00, 0x33, -1}, /* 1152x864 */ | ||
371 | {0x2a, 0x4e3d, 0x0000, SIS_RI_1152x864, 0x00, 0x00, 0x00, 0x00, 0x33, | ||
372 | -1}, | ||
373 | {0x2b, 0x4e7f, 0x0000, SIS_RI_1152x864, 0x00, 0x00, 0x00, 0x00, 0x33, | ||
374 | -1}, | ||
375 | {0xff, 0x0000, 0x0000, 0, 0x00, 0x00, 0x00, 0x00, 0x00, -1} | ||
373 | }; | 376 | }; |
374 | 377 | ||
375 | static const struct SiS_Ext2 SiSUSB_RefIndex[] = | 378 | static const struct SiS_Ext2 SiSUSB_RefIndex[] = { |
376 | { | 379 | {0x085f, 0x0d, 0x03, 0x05, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x0 */ |
377 | {0x085f,0x0d,0x03,0x05,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x0 */ | 380 | {0x0067, 0x0e, 0x04, 0x05, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x1 */ |
378 | {0x0067,0x0e,0x04,0x05,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x1 */ | 381 | {0x0067, 0x0f, 0x08, 0x48, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x2 */ |
379 | {0x0067,0x0f,0x08,0x48,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x2 */ | 382 | {0x0067, 0x10, 0x07, 0x8b, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x3 */ |
380 | {0x0067,0x10,0x07,0x8b,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x3 */ | 383 | {0x0047, 0x11, 0x0a, 0x00, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x4 */ |
381 | {0x0047,0x11,0x0a,0x00,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x4 */ | 384 | {0x0047, 0x12, 0x0d, 0x00, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x5 */ |
382 | {0x0047,0x12,0x0d,0x00,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x5 */ | 385 | {0x0047, 0x13, 0x13, 0x00, 0x05, 0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x6 */ |
383 | {0x0047,0x13,0x13,0x00,0x05,0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x6 */ | 386 | {0x0107, 0x14, 0x1c, 0x00, 0x05, 0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x7 */ |
384 | {0x0107,0x14,0x1c,0x00,0x05,0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x7 */ | 387 | {0xc85f, 0x05, 0x00, 0x04, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x8 */ |
385 | {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x8 */ | 388 | {0xc067, 0x06, 0x02, 0x04, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x9 */ |
386 | {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x9 */ | 389 | {0xc067, 0x07, 0x02, 0x47, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xa */ |
387 | {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xa */ | 390 | {0xc067, 0x08, 0x03, 0x8a, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xb */ |
388 | {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xb */ | 391 | {0xc047, 0x09, 0x05, 0x00, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xc */ |
389 | {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xc */ | 392 | {0xc047, 0x0a, 0x09, 0x00, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xd */ |
390 | {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xd */ | 393 | {0xc047, 0x0b, 0x0e, 0x00, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xe */ |
391 | {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xe */ | 394 | {0xc047, 0x0c, 0x15, 0x00, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xf */ |
392 | {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xf */ | 395 | {0x487f, 0x04, 0x00, 0x00, 0x00, 0x2f, 640, 400, 0x30, 0x55, 0x6e}, /* 0x10 */ |
393 | {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30, 0x55, 0x6e}, /* 0x10 */ | 396 | {0xc06f, 0x3c, 0x01, 0x06, 0x13, 0x31, 720, 480, 0x30, 0x00, 0x00}, /* 0x11 */ |
394 | {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30, 0x00, 0x00}, /* 0x11 */ | 397 | {0x006f, 0x3d, 0x6f, 0x06, 0x14, 0x32, 720, 576, 0x30, 0x00, 0x00}, /* 0x12 (6f was 03) */ |
395 | {0x006f,0x3d,0x6f,0x06,0x14,0x32, 720, 576, 0x30, 0x00, 0x00}, /* 0x12 (6f was 03) */ | 398 | {0x0087, 0x15, 0x06, 0x00, 0x06, 0x38, 1024, 768, 0x30, 0x00, 0x00}, /* 0x13 */ |
396 | {0x0087,0x15,0x06,0x00,0x06,0x38,1024, 768, 0x30, 0x00, 0x00}, /* 0x13 */ | 399 | {0xc877, 0x16, 0x0b, 0x06, 0x06, 0x38, 1024, 768, 0x20, 0x00, 0x00}, /* 0x14 */ |
397 | {0xc877,0x16,0x0b,0x06,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x14 */ | 400 | {0xc067, 0x17, 0x0f, 0x49, 0x06, 0x38, 1024, 768, 0x20, 0x00, 0x00}, /* 0x15 */ |
398 | {0xc067,0x17,0x0f,0x49,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x15 */ | 401 | {0x0067, 0x18, 0x11, 0x00, 0x06, 0x38, 1024, 768, 0x20, 0x00, 0x00}, /* 0x16 */ |
399 | {0x0067,0x18,0x11,0x00,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x16 */ | 402 | {0x0047, 0x19, 0x16, 0x8c, 0x06, 0x38, 1024, 768, 0x20, 0x00, 0x00}, /* 0x17 */ |
400 | {0x0047,0x19,0x16,0x8c,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x17 */ | 403 | {0x0107, 0x1a, 0x1b, 0x00, 0x06, 0x38, 1024, 768, 0x10, 0x00, 0x00}, /* 0x18 */ |
401 | {0x0107,0x1a,0x1b,0x00,0x06,0x38,1024, 768, 0x10, 0x00, 0x00}, /* 0x18 */ | 404 | {0x0107, 0x1b, 0x1f, 0x00, 0x06, 0x38, 1024, 768, 0x10, 0x00, 0x00}, /* 0x19 */ |
402 | {0x0107,0x1b,0x1f,0x00,0x06,0x38,1024, 768, 0x10, 0x00, 0x00}, /* 0x19 */ | 405 | {0x407f, 0x00, 0x00, 0x00, 0x00, 0x41, 320, 200, 0x30, 0x56, 0x4e}, /* 0x1a */ |
403 | {0x407f,0x00,0x00,0x00,0x00,0x41, 320, 200, 0x30, 0x56, 0x4e}, /* 0x1a */ | 406 | {0xc07f, 0x01, 0x00, 0x04, 0x04, 0x50, 320, 240, 0x30, 0x00, 0x00}, /* 0x1b */ |
404 | {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30, 0x00, 0x00}, /* 0x1b */ | 407 | {0x007f, 0x02, 0x04, 0x05, 0x05, 0x51, 400, 300, 0x30, 0x00, 0x00}, /* 0x1c */ |
405 | {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30, 0x00, 0x00}, /* 0x1c */ | 408 | {0xc077, 0x03, 0x0b, 0x06, 0x06, 0x52, 512, 384, 0x30, 0x00, 0x00}, /* 0x1d */ |
406 | {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30, 0x00, 0x00}, /* 0x1d */ | 409 | {0x0077, 0x32, 0x40, 0x08, 0x18, 0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1e */ |
407 | {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1e */ | 410 | {0x0047, 0x33, 0x07, 0x08, 0x18, 0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1f */ |
408 | {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1f */ | 411 | {0x0047, 0x34, 0x0a, 0x08, 0x18, 0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x20 */ |
409 | {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x20 */ | 412 | {0x0077, 0x35, 0x0b, 0x09, 0x19, 0x71, 1024, 576, 0x30, 0x00, 0x00}, /* 0x21 */ |
410 | {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x21 */ | 413 | {0x0047, 0x36, 0x11, 0x09, 0x19, 0x71, 1024, 576, 0x30, 0x00, 0x00}, /* 0x22 */ |
411 | {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x22 */ | 414 | {0x0047, 0x37, 0x16, 0x09, 0x19, 0x71, 1024, 576, 0x30, 0x00, 0x00}, /* 0x23 */ |
412 | {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x23 */ | 415 | {0x1137, 0x38, 0x19, 0x0a, 0x0c, 0x75, 1280, 720, 0x30, 0x00, 0x00}, /* 0x24 */ |
413 | {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x24 */ | 416 | {0x1107, 0x39, 0x1e, 0x0a, 0x0c, 0x75, 1280, 720, 0x30, 0x00, 0x00}, /* 0x25 */ |
414 | {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x25 */ | 417 | {0x1307, 0x3a, 0x20, 0x0a, 0x0c, 0x75, 1280, 720, 0x30, 0x00, 0x00}, /* 0x26 */ |
415 | {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x26 */ | 418 | {0x0077, 0x42, 0x5b, 0x08, 0x11, 0x23, 1280, 768, 0x30, 0x00, 0x00}, /* 0x27 */ |
416 | {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00}, /* 0x27 */ | 419 | {0x0087, 0x45, 0x57, 0x00, 0x16, 0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x28 38Hzi */ |
417 | {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x28 38Hzi */ | 420 | {0xc067, 0x46, 0x55, 0x0b, 0x16, 0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x29 848x480-60Hz */ |
418 | {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x29 848x480-60Hz */ | 421 | {0x0087, 0x47, 0x57, 0x00, 0x17, 0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2a 856x480-38Hzi */ |
419 | {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2a 856x480-38Hzi */ | 422 | {0xc067, 0x48, 0x57, 0x00, 0x17, 0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2b 856x480-60Hz */ |
420 | {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2b 856x480-60Hz */ | 423 | {0x006f, 0x4d, 0x71, 0x06, 0x15, 0x5f, 768, 576, 0x30, 0x00, 0x00}, /* 0x2c 768x576-56Hz */ |
421 | {0x006f,0x4d,0x71,0x06,0x15,0x5f, 768, 576, 0x30, 0x00, 0x00}, /* 0x2c 768x576-56Hz */ | 424 | {0x0067, 0x52, 0x6a, 0x00, 0x1c, 0x1d, 960, 540, 0x30, 0x00, 0x00}, /* 0x2d 960x540 60Hz */ |
422 | {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30, 0x00, 0x00}, /* 0x2d 960x540 60Hz */ | 425 | {0x0077, 0x53, 0x6b, 0x0b, 0x1d, 0x20, 960, 600, 0x30, 0x00, 0x00}, /* 0x2e 960x600 60Hz */ |
423 | {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30, 0x00, 0x00}, /* 0x2e 960x600 60Hz */ | 426 | {0x0087, 0x1c, 0x11, 0x00, 0x07, 0x3a, 1280, 1024, 0x30, 0x00, 0x00}, /* 0x2f */ |
424 | {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30, 0x00, 0x00}, /* 0x2f */ | 427 | {0x0137, 0x1d, 0x19, 0x07, 0x07, 0x3a, 1280, 1024, 0x00, 0x00, 0x00}, /* 0x30 */ |
425 | {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x30 */ | 428 | {0x0107, 0x1e, 0x1e, 0x00, 0x07, 0x3a, 1280, 1024, 0x00, 0x00, 0x00}, /* 0x31 */ |
426 | {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x31 */ | 429 | {0x0207, 0x1f, 0x20, 0x00, 0x07, 0x3a, 1280, 1024, 0x00, 0x00, 0x00}, /* 0x32 */ |
427 | {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x32 */ | 430 | {0x0127, 0x54, 0x6d, 0x00, 0x1a, 0x29, 1152, 864, 0x30, 0x00, 0x00}, /* 0x33 1152x864-60Hz */ |
428 | {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x33 1152x864-60Hz */ | 431 | {0x0127, 0x44, 0x19, 0x00, 0x1a, 0x29, 1152, 864, 0x30, 0x00, 0x00}, /* 0x34 1152x864-75Hz */ |
429 | {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x34 1152x864-75Hz */ | 432 | {0x0127, 0x4a, 0x1e, 0x00, 0x1a, 0x29, 1152, 864, 0x30, 0x00, 0x00}, /* 0x35 1152x864-85Hz */ |
430 | {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x35 1152x864-85Hz */ | 433 | {0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 0, 0, 0x00, 0x00} |
431 | {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, 0x00, 0x00} | ||
432 | }; | 434 | }; |
433 | 435 | ||
434 | static const struct SiS_CRT1Table SiSUSB_CRT1Table[] = | 436 | static const struct SiS_CRT1Table SiSUSB_CRT1Table[] = { |
435 | { | 437 | {{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f, |
436 | {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, | 438 | 0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x00, |
437 | 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, | 439 | 0x00}}, /* 0x0 */ |
438 | 0x00}}, /* 0x0 */ | 440 | {{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e, |
439 | {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, | 441 | 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x00, |
440 | 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, | 442 | 0x00}}, /* 0x1 */ |
441 | 0x00}}, /* 0x1 */ | 443 | {{0x3d, 0x31, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0, |
442 | {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, | 444 | 0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x05, |
443 | 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05, | 445 | 0x01}}, /* 0x2 */ |
444 | 0x01}}, /* 0x2 */ | 446 | {{0x4f, 0x3f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5, |
445 | {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5, | 447 | 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x01, |
446 | 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01, | 448 | 0x01}}, /* 0x3 */ |
447 | 0x01}}, /* 0x3 */ | 449 | {{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, |
448 | {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, | 450 | 0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x05, |
449 | 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05, | 451 | 0x00}}, /* 0x4 */ |
450 | 0x00}}, /* 0x4 */ | 452 | {{0x5f, 0x4f, 0x4f, 0x83, 0x55, 0x81, 0x0b, 0x3e, |
451 | {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, | 453 | 0xe9, 0x8b, 0xdf, 0xe8, 0x0c, 0x00, 0x00, 0x05, |
452 | 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05, | 454 | 0x00}}, /* 0x5 */ |
453 | 0x00}}, /* 0x5 */ | 455 | {{0x63, 0x4f, 0x4f, 0x87, 0x56, 0x9b, 0x06, 0x3e, |
454 | {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, | 456 | 0xe8, 0x8a, 0xdf, 0xe7, 0x07, 0x00, 0x00, 0x01, |
455 | 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01, | 457 | 0x00}}, /* 0x6 */ |
456 | 0x00}}, /* 0x6 */ | 458 | {{0x64, 0x4f, 0x4f, 0x88, 0x55, 0x9d, 0xf2, 0x1f, |
457 | {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f, | 459 | 0xe0, 0x83, 0xdf, 0xdf, 0xf3, 0x10, 0x00, 0x01, |
458 | 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01, | 460 | 0x00}}, /* 0x7 */ |
459 | 0x00}}, /* 0x7 */ | 461 | {{0x63, 0x4f, 0x4f, 0x87, 0x5a, 0x81, 0xfb, 0x1f, |
460 | {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f, | 462 | 0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05, |
461 | 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, | 463 | 0x00}}, /* 0x8 */ |
462 | 0x00}}, /* 0x8 */ | 464 | {{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0xfb, 0x1f, |
463 | {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f, | 465 | 0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05, |
464 | 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, | 466 | 0x61}}, /* 0x9 */ |
465 | 0x61}}, /* 0x9 */ | 467 | {{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0x01, 0x3e, |
466 | {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e, | 468 | 0xe0, 0x83, 0xdf, 0xdf, 0x02, 0x00, 0x00, 0x05, |
467 | 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05, | 469 | 0x61}}, /* 0xa */ |
468 | 0x61}}, /* 0xa */ | 470 | {{0x67, 0x4f, 0x4f, 0x8b, 0x58, 0x81, 0x0d, 0x3e, |
469 | {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e, | 471 | 0xe0, 0x83, 0xdf, 0xdf, 0x0e, 0x00, 0x00, 0x05, |
470 | 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, | 472 | 0x61}}, /* 0xb */ |
471 | 0x61}}, /* 0xb */ | 473 | {{0x65, 0x4f, 0x4f, 0x89, 0x57, 0x9f, 0xfb, 0x1f, |
472 | {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f, | 474 | 0xe6, 0x8a, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x01, |
473 | 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, | 475 | 0x00}}, /* 0xc */ |
474 | 0x00}}, /* 0xc */ | 476 | {{0x7b, 0x63, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0, |
475 | {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0, | 477 | 0x58, 0x8a, 0x57, 0x57, 0x70, 0x20, 0x00, 0x05, |
476 | 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05, | 478 | 0x01}}, /* 0xd */ |
477 | 0x01}}, /* 0xd */ | 479 | {{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0, |
478 | {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0, | 480 | 0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x06, |
479 | 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06, | 481 | 0x01}}, /* 0xe */ |
480 | 0x01}}, /* 0xe */ | 482 | {{0x7d, 0x63, 0x63, 0x81, 0x6e, 0x1d, 0x98, 0xf0, |
481 | {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0, | 483 | 0x7c, 0x82, 0x57, 0x57, 0x99, 0x00, 0x00, 0x06, |
482 | 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06, | 484 | 0x01}}, /* 0xf */ |
483 | 0x01}}, /* 0xf */ | 485 | {{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xf0, |
484 | {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0, | 486 | 0x58, 0x8b, 0x57, 0x57, 0x70, 0x20, 0x00, 0x06, |
485 | 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06, | 487 | 0x01}}, /* 0x10 */ |
486 | 0x01}}, /* 0x10 */ | 488 | {{0x7e, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xf0, |
487 | {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0, | 489 | 0x58, 0x8b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06, |
488 | 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06, | 490 | 0x01}}, /* 0x11 */ |
489 | 0x01}}, /* 0x11 */ | 491 | {{0x81, 0x63, 0x63, 0x85, 0x6d, 0x18, 0x7a, 0xf0, |
490 | {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0, | 492 | 0x58, 0x8b, 0x57, 0x57, 0x7b, 0x20, 0x00, 0x06, |
491 | 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06, | 493 | 0x61}}, /* 0x12 */ |
492 | 0x61}}, /* 0x12 */ | 494 | {{0x83, 0x63, 0x63, 0x87, 0x6e, 0x19, 0x81, 0xf0, |
493 | {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0, | 495 | 0x58, 0x8b, 0x57, 0x57, 0x82, 0x20, 0x00, 0x06, |
494 | 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06, | 496 | 0x61}}, /* 0x13 */ |
495 | 0x61}}, /* 0x13 */ | 497 | {{0x85, 0x63, 0x63, 0x89, 0x6f, 0x1a, 0x91, 0xf0, |
496 | {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0, | 498 | 0x58, 0x8b, 0x57, 0x57, 0x92, 0x20, 0x00, 0x06, |
497 | 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06, | 499 | 0x61}}, /* 0x14 */ |
498 | 0x61}}, /* 0x14 */ | 500 | {{0x99, 0x7f, 0x7f, 0x9d, 0x84, 0x1a, 0x96, 0x1f, |
499 | {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f, | 501 | 0x7f, 0x83, 0x7f, 0x7f, 0x97, 0x10, 0x00, 0x02, |
500 | 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02, | 502 | 0x00}}, /* 0x15 */ |
501 | 0x00}}, /* 0x15 */ | 503 | {{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5, |
502 | {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, | 504 | 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02, |
503 | 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, | 505 | 0x01}}, /* 0x16 */ |
504 | 0x01}}, /* 0x16 */ | 506 | {{0xa1, 0x7f, 0x7f, 0x85, 0x86, 0x97, 0x24, 0xf5, |
505 | {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5, | 507 | 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02, |
506 | 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, | 508 | 0x01}}, /* 0x17 */ |
507 | 0x01}}, /* 0x17 */ | 509 | {{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf5, |
508 | {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5, | 510 | 0x00, 0x83, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02, |
509 | 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02, | 511 | 0x01}}, /* 0x18 */ |
510 | 0x01}}, /* 0x18 */ | 512 | {{0xa7, 0x7f, 0x7f, 0x8b, 0x89, 0x95, 0x26, 0xf5, |
511 | {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5, | 513 | 0x00, 0x83, 0xff, 0xff, 0x27, 0x10, 0x00, 0x02, |
512 | 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02, | 514 | 0x01}}, /* 0x19 */ |
513 | 0x01}}, /* 0x19 */ | 515 | {{0xa9, 0x7f, 0x7f, 0x8d, 0x8c, 0x9a, 0x2c, 0xf5, |
514 | {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5, | 516 | 0x00, 0x83, 0xff, 0xff, 0x2d, 0x14, 0x00, 0x02, |
515 | 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02, | 517 | 0x62}}, /* 0x1a */ |
516 | 0x62}}, /* 0x1a */ | 518 | {{0xab, 0x7f, 0x7f, 0x8f, 0x8d, 0x9b, 0x35, 0xf5, |
517 | {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5, | 519 | 0x00, 0x83, 0xff, 0xff, 0x36, 0x14, 0x00, 0x02, |
518 | 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02, | 520 | 0x62}}, /* 0x1b */ |
519 | 0x62}}, /* 0x1b */ | 521 | {{0xcf, 0x9f, 0x9f, 0x93, 0xb2, 0x01, 0x14, 0xba, |
520 | {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba, | 522 | 0x00, 0x83, 0xff, 0xff, 0x15, 0x00, 0x00, 0x03, |
521 | 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03, | 523 | 0x00}}, /* 0x1c */ |
522 | 0x00}}, /* 0x1c */ | 524 | {{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0x5a, |
523 | {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a, | 525 | 0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07, |
524 | 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, | 526 | 0x01}}, /* 0x1d */ |
525 | 0x01}}, /* 0x1d */ | 527 | {{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0x5a, |
526 | {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a, | 528 | 0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07, |
527 | 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, | 529 | 0x01}}, /* 0x1e */ |
528 | 0x01}}, /* 0x1e */ | 530 | {{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0x5a, |
529 | {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a, | 531 | 0x00, 0x83, 0xff, 0xff, 0x2f, 0x09, 0x00, 0x07, |
530 | 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07, | 532 | 0x01}}, /* 0x1f */ |
531 | 0x01}}, /* 0x1f */ | 533 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
532 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 534 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
533 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 535 | 0x00}}, /* 0x20 */ |
534 | 0x00}}, /* 0x20 */ | 536 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
535 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 537 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
536 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 538 | 0x00}}, /* 0x21 */ |
537 | 0x00}}, /* 0x21 */ | 539 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
538 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 540 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
539 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 541 | 0x00}}, /* 0x22 */ |
540 | 0x00}}, /* 0x22 */ | 542 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
541 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 543 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
542 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 544 | 0x00}}, /* 0x23 */ |
543 | 0x00}}, /* 0x23 */ | 545 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
544 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 546 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
545 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 547 | 0x00}}, /* 0x24 */ |
546 | 0x00}}, /* 0x24 */ | 548 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
547 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 549 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
548 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 550 | 0x00}}, /* 0x25 */ |
549 | 0x00}}, /* 0x25 */ | 551 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
550 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 552 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
551 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 553 | 0x00}}, /* 0x26 */ |
552 | 0x00}}, /* 0x26 */ | 554 | {{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f, |
553 | {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, | 555 | 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01, |
554 | 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, | 556 | 0x00}}, /* 0x27 */ |
555 | 0x00}}, /* 0x27 */ | 557 | {{0x43, 0xef, 0xef, 0x87, 0x06, 0x00, 0xd4, 0x1f, |
556 | {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f, | 558 | 0xa0, 0x83, 0x9f, 0x9f, 0xd5, 0x1f, 0x41, 0x05, |
557 | 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05, | 559 | 0x63}}, /* 0x28 */ |
558 | 0x63}}, /* 0x28 */ | 560 | {{0x45, 0xef, 0xef, 0x89, 0x07, 0x01, 0xd9, 0x1f, |
559 | {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f, | 561 | 0xa0, 0x83, 0x9f, 0x9f, 0xda, 0x1f, 0x41, 0x05, |
560 | 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05, | 562 | 0x63}}, /* 0x29 */ |
561 | 0x63}}, /* 0x29 */ | 563 | {{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f, |
562 | {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, | 564 | 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01, |
563 | 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, | 565 | 0x00}}, /* 0x2a */ |
564 | 0x00}}, /* 0x2a */ | 566 | {{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f, |
565 | {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, | 567 | 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01, |
566 | 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, | 568 | 0x00}}, /* 0x2b */ |
567 | 0x00}}, /* 0x2b */ | 569 | {{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f, |
568 | {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, | 570 | 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01, |
569 | 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, | 571 | 0x00}}, /* 0x2c */ |
570 | 0x00}}, /* 0x2c */ | 572 | {{0x59, 0xff, 0xff, 0x9d, 0x17, 0x13, 0x33, 0xba, |
571 | {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba, | 573 | 0x00, 0x83, 0xff, 0xff, 0x34, 0x0f, 0x41, 0x05, |
572 | 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05, | 574 | 0x44}}, /* 0x2d */ |
573 | 0x44}}, /* 0x2d */ | 575 | {{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x38, 0xba, |
574 | {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba, | 576 | 0x00, 0x83, 0xff, 0xff, 0x39, 0x0f, 0x41, 0x05, |
575 | 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05, | 577 | 0x44}}, /* 0x2e */ |
576 | 0x44}}, /* 0x2e */ | 578 | {{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x3d, 0xba, |
577 | {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba, | 579 | 0x00, 0x83, 0xff, 0xff, 0x3e, 0x0f, 0x41, 0x05, |
578 | 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05, | 580 | 0x44}}, /* 0x2f */ |
579 | 0x44}}, /* 0x2f */ | 581 | {{0x5d, 0xff, 0xff, 0x81, 0x19, 0x95, 0x41, 0xba, |
580 | {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba, | 582 | 0x00, 0x84, 0xff, 0xff, 0x42, 0x0f, 0x41, 0x05, |
581 | 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05, | 583 | 0x44}}, /* 0x30 */ |
582 | 0x44}}, /* 0x30 */ | 584 | {{0x55, 0xff, 0xff, 0x99, 0x0d, 0x0c, 0x3e, 0xba, |
583 | {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba, | 585 | 0x00, 0x84, 0xff, 0xff, 0x3f, 0x0f, 0x41, 0x05, |
584 | 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05, | 586 | 0x00}}, /* 0x31 */ |
585 | 0x00}}, /* 0x31 */ | 587 | {{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xba, |
586 | {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, | 588 | 0x27, 0x8b, 0xdf, 0xdf, 0x73, 0x00, 0x00, 0x06, |
587 | 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06, | 589 | 0x01}}, /* 0x32 */ |
588 | 0x01}}, /* 0x32 */ | 590 | {{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xba, |
589 | {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba, | 591 | 0x26, 0x89, 0xdf, 0xdf, 0x6f, 0x00, 0x00, 0x06, |
590 | 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06, | 592 | 0x01}}, /* 0x33 */ |
591 | 0x01}}, /* 0x33 */ | 593 | {{0x7f, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xba, |
592 | {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba, | 594 | 0x29, 0x8c, 0xdf, 0xdf, 0x75, 0x00, 0x00, 0x06, |
593 | 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06, | 595 | 0x01}}, /* 0x34 */ |
594 | 0x01}}, /* 0x34 */ | 596 | {{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf1, |
595 | {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1, | 597 | 0xaf, 0x85, 0x3f, 0x3f, 0x25, 0x30, 0x00, 0x02, |
596 | 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02, | 598 | 0x01}}, /* 0x35 */ |
597 | 0x01}}, /* 0x35 */ | 599 | {{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf1, |
598 | {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1, | 600 | 0xad, 0x81, 0x3f, 0x3f, 0x1f, 0x30, 0x00, 0x02, |
599 | 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02, | 601 | 0x01}}, /* 0x36 */ |
600 | 0x01}}, /* 0x36 */ | 602 | {{0xa7, 0x7f, 0x7f, 0x88, 0x89, 0x95, 0x26, 0xf1, |
601 | {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, | 603 | 0xb1, 0x85, 0x3f, 0x3f, 0x27, 0x30, 0x00, 0x02, |
602 | 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02, | 604 | 0x01}}, /* 0x37 */ |
603 | 0x01}}, /* 0x37 */ | 605 | {{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0xc4, |
604 | {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4, | 606 | 0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07, |
605 | 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, | 607 | 0x01}}, /* 0x38 */ |
606 | 0x01}}, /* 0x38 */ | 608 | {{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0xd4, |
607 | {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4, | 609 | 0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07, |
608 | 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, | 610 | 0x01}}, /* 0x39 */ |
609 | 0x01}}, /* 0x39 */ | 611 | {{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0xd4, |
610 | {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4, | 612 | 0x7d, 0x81, 0xcf, 0xcf, 0x2f, 0x21, 0x00, 0x07, |
611 | 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07, | 613 | 0x01}}, /* 0x3a */ |
612 | 0x01}}, /* 0x3a */ | 614 | {{0xdc, 0x9f, 0x9f, 0x80, 0xaf, 0x9d, 0xe6, 0xff, |
613 | {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, | 615 | 0xc0, 0x83, 0xbf, 0xbf, 0xe7, 0x10, 0x00, 0x07, |
614 | 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07, | 616 | 0x01}}, /* 0x3b */ |
615 | 0x01}}, /* 0x3b */ | 617 | {{0x6b, 0x59, 0x59, 0x8f, 0x5e, 0x8c, 0x0b, 0x3e, |
616 | {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e, | 618 | 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05, |
617 | 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05, | 619 | 0x00}}, /* 0x3c */ |
618 | 0x00}}, /* 0x3c */ | 620 | {{0x6d, 0x59, 0x59, 0x91, 0x60, 0x89, 0x53, 0xf0, |
619 | {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0, | 621 | 0x41, 0x84, 0x3f, 0x3f, 0x54, 0x00, 0x00, 0x05, |
620 | 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05, | 622 | 0x41}}, /* 0x3d */ |
621 | 0x41}}, /* 0x3d */ | 623 | {{0x86, 0x6a, 0x6a, 0x8a, 0x74, 0x06, 0x8c, 0x15, |
622 | {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15, | 624 | 0x4f, 0x83, 0xef, 0xef, 0x8d, 0x30, 0x00, 0x02, |
623 | 0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02, | 625 | 0x00}}, /* 0x3e */ |
624 | 0x00}}, /* 0x3e */ | 626 | {{0x81, 0x6a, 0x6a, 0x85, 0x70, 0x00, 0x0f, 0x3e, |
625 | {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e, | 627 | 0xeb, 0x8e, 0xdf, 0xdf, 0x10, 0x00, 0x00, 0x02, |
626 | 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02, | 628 | 0x00}}, /* 0x3f */ |
627 | 0x00}}, /* 0x3f */ | 629 | {{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x1e, 0xf1, |
628 | {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, | 630 | 0xae, 0x85, 0x57, 0x57, 0x1f, 0x30, 0x00, 0x02, |
629 | 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02, | 631 | 0x01}}, /* 0x40 */ |
630 | 0x01}}, /* 0x40 */ | 632 | {{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5, |
631 | {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, | 633 | 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02, |
632 | 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, | 634 | 0x01}}, /* 0x41 */ |
633 | 0x01}}, /* 0x41 */ | 635 | {{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x20, 0xf5, |
634 | {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, | 636 | 0x03, 0x88, 0xff, 0xff, 0x21, 0x10, 0x00, 0x07, |
635 | 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07, | 637 | 0x01}}, /* 0x42 */ |
636 | 0x01}}, /* 0x42 */ | 638 | {{0xe6, 0xae, 0xae, 0x8a, 0xbd, 0x90, 0x3d, 0x10, |
637 | {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10, | 639 | 0x1a, 0x8d, 0x19, 0x19, 0x3e, 0x2f, 0x00, 0x03, |
638 | 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03, | 640 | 0x00}}, /* 0x43 */ |
639 | 0x00}}, /* 0x43 */ | 641 | {{0xc3, 0x8f, 0x8f, 0x87, 0x9b, 0x0b, 0x82, 0xef, |
640 | {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, | 642 | 0x60, 0x83, 0x5f, 0x5f, 0x83, 0x10, 0x00, 0x07, |
641 | 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07, | 643 | 0x01}}, /* 0x44 */ |
642 | 0x01}}, /* 0x44 */ | 644 | {{0x86, 0x69, 0x69, 0x8A, 0x74, 0x06, 0x8C, 0x15, |
643 | {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, | 645 | 0x4F, 0x83, 0xEF, 0xEF, 0x8D, 0x30, 0x00, 0x02, |
644 | 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, | 646 | 0x00}}, /* 0x45 */ |
645 | 0x00}}, /* 0x45 */ | 647 | {{0x83, 0x69, 0x69, 0x87, 0x6f, 0x1d, 0x03, 0x3E, |
646 | {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, | 648 | 0xE5, 0x8d, 0xDF, 0xe4, 0x04, 0x00, 0x00, 0x06, |
647 | 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06, | 649 | 0x00}}, /* 0x46 */ |
648 | 0x00}}, /* 0x46 */ | 650 | {{0x86, 0x6A, 0x6A, 0x8A, 0x74, 0x06, 0x8C, 0x15, |
649 | {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, | 651 | 0x4F, 0x83, 0xEF, 0xEF, 0x8D, 0x30, 0x00, 0x02, |
650 | 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, | 652 | 0x00}}, /* 0x47 */ |
651 | 0x00}}, /* 0x47 */ | 653 | {{0x81, 0x6A, 0x6A, 0x85, 0x70, 0x00, 0x0F, 0x3E, |
652 | {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, | 654 | 0xEB, 0x8E, 0xDF, 0xDF, 0x10, 0x00, 0x00, 0x02, |
653 | 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02, | 655 | 0x00}}, /* 0x48 */ |
654 | 0x00}}, /* 0x48 */ | 656 | {{0xdd, 0xa9, 0xa9, 0x81, 0xb4, 0x97, 0x26, 0xfd, |
655 | {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, | 657 | 0x01, 0x8d, 0xff, 0x00, 0x27, 0x10, 0x00, 0x03, |
656 | 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03, | 658 | 0x01}}, /* 0x49 */ |
657 | 0x01}}, /* 0x49 */ | 659 | {{0xd9, 0x8f, 0x8f, 0x9d, 0xba, 0x0a, 0x8a, 0xff, |
658 | {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, | 660 | 0x60, 0x8b, 0x5f, 0x5f, 0x8b, 0x10, 0x00, 0x03, |
659 | 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03, | 661 | 0x01}}, /* 0x4a */ |
660 | 0x01}}, /* 0x4a */ | 662 | {{0xea, 0xae, 0xae, 0x8e, 0xba, 0x82, 0x40, 0x10, |
661 | {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, | 663 | 0x1b, 0x87, 0x19, 0x1a, 0x41, 0x0f, 0x00, 0x03, |
662 | 0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03, | 664 | 0x00}}, /* 0x4b */ |
663 | 0x00}}, /* 0x4b */ | 665 | {{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0xf1, 0xff, |
664 | {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, | 666 | 0xc0, 0x83, 0xbf, 0xbf, 0xf2, 0x10, 0x00, 0x07, |
665 | 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07, | 667 | 0x01}}, /* 0x4c */ |
666 | 0x01}}, /* 0x4c */ | 668 | {{0x75, 0x5f, 0x5f, 0x99, 0x66, 0x90, 0x53, 0xf0, |
667 | {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, | 669 | 0x41, 0x84, 0x3f, 0x3f, 0x54, 0x00, 0x00, 0x05, |
668 | 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05, | 670 | 0x41}}, |
669 | 0x41}}, | 671 | {{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e, |
670 | {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, | 672 | 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x00, |
671 | 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, | 673 | 0x00}}, /* 0x4e */ |
672 | 0x00}}, /* 0x4e */ | 674 | {{0xcd, 0x9f, 0x9f, 0x91, 0xab, 0x1c, 0x3a, 0xff, |
673 | {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, | 675 | 0x20, 0x83, 0x1f, 0x1f, 0x3b, 0x10, 0x00, 0x07, |
674 | 0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07, | 676 | 0x21}}, /* 0x4f */ |
675 | 0x21}}, /* 0x4f */ | 677 | {{0x15, 0xd1, 0xd1, 0x99, 0xe2, 0x19, 0x3d, 0x10, |
676 | {{0x15,0xd1,0xd1,0x99,0xe2,0x19,0x3d,0x10, | 678 | 0x1a, 0x8d, 0x19, 0x19, 0x3e, 0x2f, 0x01, 0x0c, |
677 | 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x01,0x0c, | 679 | 0x20}}, /* 0x50 */ |
678 | 0x20}}, /* 0x50 */ | 680 | {{0x0e, 0xef, 0xef, 0x92, 0xfe, 0x03, 0x30, 0xf0, |
679 | {{0x0e,0xef,0xef,0x92,0xfe,0x03,0x30,0xf0, | 681 | 0x1e, 0x83, 0x1b, 0x1c, 0x31, 0x00, 0x01, 0x00, |
680 | 0x1e,0x83,0x1b,0x1c,0x31,0x00,0x01,0x00, | 682 | 0x61}}, /* 0x51 */ |
681 | 0x61}}, /* 0x51 */ | 683 | {{0x85, 0x77, 0x77, 0x89, 0x7d, 0x01, 0x31, 0xf0, |
682 | {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0, | 684 | 0x1e, 0x84, 0x1b, 0x1c, 0x32, 0x00, 0x00, 0x02, |
683 | 0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02, | 685 | 0x41}}, /* 0x52 */ |
684 | 0x41}}, /* 0x52 */ | 686 | {{0x87, 0x77, 0x77, 0x8b, 0x81, 0x0b, 0x68, 0xf0, |
685 | {{0x87,0x77,0x77,0x8b,0x81,0x0b,0x68,0xf0, | 687 | 0x5a, 0x80, 0x57, 0x57, 0x69, 0x00, 0x00, 0x02, |
686 | 0x5a,0x80,0x57,0x57,0x69,0x00,0x00,0x02, | 688 | 0x01}}, /* 0x53 */ |
687 | 0x01}}, /* 0x53 */ | 689 | {{0xcd, 0x8f, 0x8f, 0x91, 0x9b, 0x1b, 0x7a, 0xff, |
688 | {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, | 690 | 0x64, 0x8c, 0x5f, 0x62, 0x7b, 0x10, 0x00, 0x07, |
689 | 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07, | 691 | 0x41}} /* 0x54 */ |
690 | 0x41}} /* 0x54 */ | ||
691 | }; | 692 | }; |
692 | 693 | ||
693 | static const struct SiS_VCLKData SiSUSB_VCLKData[] = | 694 | static const struct SiS_VCLKData SiSUSB_VCLKData[] = { |
694 | { | 695 | {0x1b, 0xe1, 25}, /* 0x00 */ |
695 | { 0x1b,0xe1, 25}, /* 0x00 */ | 696 | {0x4e, 0xe4, 28}, /* 0x01 */ |
696 | { 0x4e,0xe4, 28}, /* 0x01 */ | 697 | {0x57, 0xe4, 31}, /* 0x02 */ |
697 | { 0x57,0xe4, 31}, /* 0x02 */ | 698 | {0xc3, 0xc8, 36}, /* 0x03 */ |
698 | { 0xc3,0xc8, 36}, /* 0x03 */ | 699 | {0x42, 0xe2, 40}, /* 0x04 */ |
699 | { 0x42,0xe2, 40}, /* 0x04 */ | 700 | {0xfe, 0xcd, 43}, /* 0x05 */ |
700 | { 0xfe,0xcd, 43}, /* 0x05 */ | 701 | {0x5d, 0xc4, 44}, /* 0x06 */ |
701 | { 0x5d,0xc4, 44}, /* 0x06 */ | 702 | {0x52, 0xe2, 49}, /* 0x07 */ |
702 | { 0x52,0xe2, 49}, /* 0x07 */ | 703 | {0x53, 0xe2, 50}, /* 0x08 */ |
703 | { 0x53,0xe2, 50}, /* 0x08 */ | 704 | {0x74, 0x67, 52}, /* 0x09 */ |
704 | { 0x74,0x67, 52}, /* 0x09 */ | 705 | {0x6d, 0x66, 56}, /* 0x0a */ |
705 | { 0x6d,0x66, 56}, /* 0x0a */ | 706 | {0x5a, 0x64, 65}, /* 0x0b */ |
706 | { 0x5a,0x64, 65}, /* 0x0b */ | 707 | {0x46, 0x44, 67}, /* 0x0c */ |
707 | { 0x46,0x44, 67}, /* 0x0c */ | 708 | {0xb1, 0x46, 68}, /* 0x0d */ |
708 | { 0xb1,0x46, 68}, /* 0x0d */ | 709 | {0xd3, 0x4a, 72}, /* 0x0e */ |
709 | { 0xd3,0x4a, 72}, /* 0x0e */ | 710 | {0x29, 0x61, 75}, /* 0x0f */ |
710 | { 0x29,0x61, 75}, /* 0x0f */ | 711 | {0x6e, 0x46, 76}, /* 0x10 */ |
711 | { 0x6e,0x46, 76}, /* 0x10 */ | 712 | {0x2b, 0x61, 78}, /* 0x11 */ |
712 | { 0x2b,0x61, 78}, /* 0x11 */ | 713 | {0x31, 0x42, 79}, /* 0x12 */ |
713 | { 0x31,0x42, 79}, /* 0x12 */ | 714 | {0xab, 0x44, 83}, /* 0x13 */ |
714 | { 0xab,0x44, 83}, /* 0x13 */ | 715 | {0x46, 0x25, 84}, /* 0x14 */ |
715 | { 0x46,0x25, 84}, /* 0x14 */ | 716 | {0x78, 0x29, 86}, /* 0x15 */ |
716 | { 0x78,0x29, 86}, /* 0x15 */ | 717 | {0x62, 0x44, 94}, /* 0x16 */ |
717 | { 0x62,0x44, 94}, /* 0x16 */ | 718 | {0x2b, 0x41, 104}, /* 0x17 */ |
718 | { 0x2b,0x41,104}, /* 0x17 */ | 719 | {0x3a, 0x23, 105}, /* 0x18 */ |
719 | { 0x3a,0x23,105}, /* 0x18 */ | 720 | {0x70, 0x44, 108}, /* 0x19 */ |
720 | { 0x70,0x44,108}, /* 0x19 */ | 721 | {0x3c, 0x23, 109}, /* 0x1a */ |
721 | { 0x3c,0x23,109}, /* 0x1a */ | 722 | {0x5e, 0x43, 113}, /* 0x1b */ |
722 | { 0x5e,0x43,113}, /* 0x1b */ | 723 | {0xbc, 0x44, 116}, /* 0x1c */ |
723 | { 0xbc,0x44,116}, /* 0x1c */ | 724 | {0xe0, 0x46, 132}, /* 0x1d */ |
724 | { 0xe0,0x46,132}, /* 0x1d */ | 725 | {0x54, 0x42, 135}, /* 0x1e */ |
725 | { 0x54,0x42,135}, /* 0x1e */ | 726 | {0xea, 0x2a, 139}, /* 0x1f */ |
726 | { 0xea,0x2a,139}, /* 0x1f */ | 727 | {0x41, 0x22, 157}, /* 0x20 */ |
727 | { 0x41,0x22,157}, /* 0x20 */ | 728 | {0x70, 0x24, 162}, /* 0x21 */ |
728 | { 0x70,0x24,162}, /* 0x21 */ | 729 | {0x30, 0x21, 175}, /* 0x22 */ |
729 | { 0x30,0x21,175}, /* 0x22 */ | 730 | {0x4e, 0x22, 189}, /* 0x23 */ |
730 | { 0x4e,0x22,189}, /* 0x23 */ | 731 | {0xde, 0x26, 194}, /* 0x24 */ |
731 | { 0xde,0x26,194}, /* 0x24 */ | 732 | {0x62, 0x06, 202}, /* 0x25 */ |
732 | { 0x62,0x06,202}, /* 0x25 */ | 733 | {0x3f, 0x03, 229}, /* 0x26 */ |
733 | { 0x3f,0x03,229}, /* 0x26 */ | 734 | {0xb8, 0x06, 234}, /* 0x27 */ |
734 | { 0xb8,0x06,234}, /* 0x27 */ | 735 | {0x34, 0x02, 253}, /* 0x28 */ |
735 | { 0x34,0x02,253}, /* 0x28 */ | 736 | {0x58, 0x04, 255}, /* 0x29 */ |
736 | { 0x58,0x04,255}, /* 0x29 */ | 737 | {0x24, 0x01, 265}, /* 0x2a */ |
737 | { 0x24,0x01,265}, /* 0x2a */ | 738 | {0x9b, 0x02, 267}, /* 0x2b */ |
738 | { 0x9b,0x02,267}, /* 0x2b */ | 739 | {0x70, 0x05, 270}, /* 0x2c */ |
739 | { 0x70,0x05,270}, /* 0x2c */ | 740 | {0x25, 0x01, 272}, /* 0x2d */ |
740 | { 0x25,0x01,272}, /* 0x2d */ | 741 | {0x9c, 0x02, 277}, /* 0x2e */ |
741 | { 0x9c,0x02,277}, /* 0x2e */ | 742 | {0x27, 0x01, 286}, /* 0x2f */ |
742 | { 0x27,0x01,286}, /* 0x2f */ | 743 | {0x3c, 0x02, 291}, /* 0x30 */ |
743 | { 0x3c,0x02,291}, /* 0x30 */ | 744 | {0xef, 0x0a, 292}, /* 0x31 */ |
744 | { 0xef,0x0a,292}, /* 0x31 */ | 745 | {0xf6, 0x0a, 310}, /* 0x32 */ |
745 | { 0xf6,0x0a,310}, /* 0x32 */ | 746 | {0x95, 0x01, 315}, /* 0x33 */ |
746 | { 0x95,0x01,315}, /* 0x33 */ | 747 | {0xf0, 0x09, 324}, /* 0x34 */ |
747 | { 0xf0,0x09,324}, /* 0x34 */ | 748 | {0xfe, 0x0a, 331}, /* 0x35 */ |
748 | { 0xfe,0x0a,331}, /* 0x35 */ | 749 | {0xf3, 0x09, 332}, /* 0x36 */ |
749 | { 0xf3,0x09,332}, /* 0x36 */ | 750 | {0xea, 0x08, 340}, /* 0x37 */ |
750 | { 0xea,0x08,340}, /* 0x37 */ | 751 | {0xe8, 0x07, 376}, /* 0x38 */ |
751 | { 0xe8,0x07,376}, /* 0x38 */ | 752 | {0xde, 0x06, 389}, /* 0x39 */ |
752 | { 0xde,0x06,389}, /* 0x39 */ | 753 | {0x52, 0x2a, 54}, /* 0x3a 301 TV */ |
753 | { 0x52,0x2a, 54}, /* 0x3a 301 TV */ | 754 | {0x52, 0x6a, 27}, /* 0x3b 301 TV */ |
754 | { 0x52,0x6a, 27}, /* 0x3b 301 TV */ | 755 | {0x62, 0x24, 70}, /* 0x3c 301 TV */ |
755 | { 0x62,0x24, 70}, /* 0x3c 301 TV */ | 756 | {0x62, 0x64, 70}, /* 0x3d 301 TV */ |
756 | { 0x62,0x64, 70}, /* 0x3d 301 TV */ | 757 | {0xa8, 0x4c, 30}, /* 0x3e 301 TV */ |
757 | { 0xa8,0x4c, 30}, /* 0x3e 301 TV */ | 758 | {0x20, 0x26, 33}, /* 0x3f 301 TV */ |
758 | { 0x20,0x26, 33}, /* 0x3f 301 TV */ | 759 | {0x31, 0xc2, 39}, /* 0x40 */ |
759 | { 0x31,0xc2, 39}, /* 0x40 */ | 760 | {0x60, 0x36, 30}, /* 0x41 Chrontel */ |
760 | { 0x60,0x36, 30}, /* 0x41 Chrontel */ | 761 | {0x40, 0x4a, 28}, /* 0x42 Chrontel */ |
761 | { 0x40,0x4a, 28}, /* 0x42 Chrontel */ | 762 | {0x9f, 0x46, 44}, /* 0x43 Chrontel */ |
762 | { 0x9f,0x46, 44}, /* 0x43 Chrontel */ | 763 | {0x97, 0x2c, 26}, /* 0x44 */ |
763 | { 0x97,0x2c, 26}, /* 0x44 */ | 764 | {0x44, 0xe4, 25}, /* 0x45 Chrontel */ |
764 | { 0x44,0xe4, 25}, /* 0x45 Chrontel */ | 765 | {0x7e, 0x32, 47}, /* 0x46 Chrontel */ |
765 | { 0x7e,0x32, 47}, /* 0x46 Chrontel */ | 766 | {0x8a, 0x24, 31}, /* 0x47 Chrontel */ |
766 | { 0x8a,0x24, 31}, /* 0x47 Chrontel */ | 767 | {0x97, 0x2c, 26}, /* 0x48 Chrontel */ |
767 | { 0x97,0x2c, 26}, /* 0x48 Chrontel */ | 768 | {0xce, 0x3c, 39}, /* 0x49 */ |
768 | { 0xce,0x3c, 39}, /* 0x49 */ | 769 | {0x52, 0x4a, 36}, /* 0x4a Chrontel */ |
769 | { 0x52,0x4a, 36}, /* 0x4a Chrontel */ | 770 | {0x34, 0x61, 95}, /* 0x4b */ |
770 | { 0x34,0x61, 95}, /* 0x4b */ | 771 | {0x78, 0x27, 108}, /* 0x4c - was 102 */ |
771 | { 0x78,0x27,108}, /* 0x4c - was 102 */ | 772 | {0x66, 0x43, 123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */ |
772 | { 0x66,0x43,123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */ | 773 | {0x41, 0x4e, 21}, /* 0x4e */ |
773 | { 0x41,0x4e, 21}, /* 0x4e */ | 774 | {0xa1, 0x4a, 29}, /* 0x4f Chrontel */ |
774 | { 0xa1,0x4a, 29}, /* 0x4f Chrontel */ | 775 | {0x19, 0x42, 42}, /* 0x50 */ |
775 | { 0x19,0x42, 42}, /* 0x50 */ | 776 | {0x54, 0x46, 58}, /* 0x51 Chrontel */ |
776 | { 0x54,0x46, 58}, /* 0x51 Chrontel */ | 777 | {0x25, 0x42, 61}, /* 0x52 */ |
777 | { 0x25,0x42, 61}, /* 0x52 */ | 778 | {0x44, 0x44, 66}, /* 0x53 Chrontel */ |
778 | { 0x44,0x44, 66}, /* 0x53 Chrontel */ | 779 | {0x3a, 0x62, 70}, /* 0x54 Chrontel */ |
779 | { 0x3a,0x62, 70}, /* 0x54 Chrontel */ | 780 | {0x62, 0xc6, 34}, /* 0x55 848x480-60 */ |
780 | { 0x62,0xc6, 34}, /* 0x55 848x480-60 */ | 781 | {0x6a, 0xc6, 37}, /* 0x56 848x480-75 - TEMP */ |
781 | { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP */ | 782 | {0xbf, 0xc8, 35}, /* 0x57 856x480-38i,60 */ |
782 | { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */ | 783 | {0x30, 0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */ |
783 | { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */ | 784 | {0x52, 0x07, 149}, /* 0x59 1280x960-85 */ |
784 | { 0x52,0x07,149}, /* 0x59 1280x960-85 */ | 785 | {0x56, 0x07, 156}, /* 0x5a 1400x1050-75 */ |
785 | { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */ | 786 | {0x70, 0x29, 81}, /* 0x5b 1280x768 LCD */ |
786 | { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */ | 787 | {0x45, 0x25, 83}, /* 0x5c 1280x800 */ |
787 | { 0x45,0x25, 83}, /* 0x5c 1280x800 */ | 788 | {0x70, 0x0a, 147}, /* 0x5d 1680x1050 */ |
788 | { 0x70,0x0a,147}, /* 0x5d 1680x1050 */ | 789 | {0x70, 0x24, 162}, /* 0x5e 1600x1200 */ |
789 | { 0x70,0x24,162}, /* 0x5e 1600x1200 */ | 790 | {0x5a, 0x64, 65}, /* 0x5f 1280x720 - temp */ |
790 | { 0x5a,0x64, 65}, /* 0x5f 1280x720 - temp */ | 791 | {0x63, 0x46, 68}, /* 0x60 1280x768_2 */ |
791 | { 0x63,0x46, 68}, /* 0x60 1280x768_2 */ | 792 | {0x31, 0x42, 79}, /* 0x61 1280x768_3 - temp */ |
792 | { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */ | 793 | {0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */ |
793 | { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */ | 794 | {0x5a, 0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */ |
794 | { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */ | 795 | {0x70, 0x28, 90}, /* 0x64 1152x864@60 */ |
795 | { 0x70,0x28, 90}, /* 0x64 1152x864@60 */ | 796 | {0x41, 0xc4, 32}, /* 0x65 848x480@60 */ |
796 | { 0x41,0xc4, 32}, /* 0x65 848x480@60 */ | 797 | {0x5c, 0xc6, 32}, /* 0x66 856x480@60 */ |
797 | { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */ | 798 | {0x76, 0xe7, 27}, /* 0x67 720x480@60 */ |
798 | { 0x76,0xe7, 27}, /* 0x67 720x480@60 */ | 799 | {0x5f, 0xc6, 33}, /* 0x68 720/768x576@60 */ |
799 | { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */ | 800 | {0x52, 0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */ |
800 | { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */ | 801 | {0x7c, 0x6b, 38}, /* 0x6a 960x540@60 */ |
801 | { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */ | 802 | {0xe3, 0x56, 41}, /* 0x6b 960x600@60 */ |
802 | { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */ | 803 | {0x45, 0x25, 83}, /* 0x6c 1280x800 */ |
803 | { 0x45,0x25, 83}, /* 0x6c 1280x800 */ | 804 | {0x70, 0x28, 90}, /* 0x6d 1152x864@60 */ |
804 | { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */ | 805 | {0x15, 0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */ |
805 | { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */ | 806 | {0x5f, 0xc6, 33}, /* 0x6f 720x576@60 */ |
806 | { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */ | 807 | {0x37, 0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */ |
807 | { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */ | 808 | {0x2b, 0xc2, 35} /* 0x71 768@576@60 */ |
808 | { 0x2b,0xc2, 35} /* 0x71 768@576@60 */ | ||
809 | }; | 809 | }; |
810 | 810 | ||
811 | int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); | 811 | int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); |
812 | int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); | 812 | int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); |
813 | 813 | ||
814 | extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data); | 814 | extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data); |
815 | extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data); | 815 | extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 * data); |
816 | extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, | 816 | extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, |
817 | u8 index, u8 data); | 817 | u8 index, u8 data); |
818 | extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, | 818 | extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, |
819 | u8 index, u8 *data); | 819 | u8 index, u8 * data); |
820 | extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, | 820 | extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, |
821 | u8 idx, u8 myand, u8 myor); | 821 | u8 idx, u8 myand, u8 myor); |
822 | extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, | 822 | extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, |
823 | u8 index, u8 myor); | 823 | u8 index, u8 myor); |
824 | extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, | 824 | extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, |
825 | u8 idx, u8 myand); | 825 | u8 idx, u8 myand); |
826 | 826 | ||
827 | void sisusb_delete(struct kref *kref); | 827 | void sisusb_delete(struct kref *kref); |
828 | int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); | 828 | int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); |
829 | int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data); | 829 | int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 * data); |
830 | int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, | 830 | int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, |
831 | u32 dest, int length, size_t *bytes_written); | 831 | u32 dest, int length, size_t * bytes_written); |
832 | int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); | 832 | int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); |
833 | int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, | 833 | int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, |
834 | u8 *arg, int cmapsz, int ch512, int dorecalc, | 834 | u8 * arg, int cmapsz, int ch512, int dorecalc, |
835 | struct vc_data *c, int fh, int uplock); | 835 | struct vc_data *c, int fh, int uplock); |
836 | void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location); | 836 | void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location); |
837 | int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last); | 837 | int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last); |
@@ -839,4 +839,3 @@ void sisusb_console_exit(struct sisusb_usb_data *sisusb); | |||
839 | void sisusb_init_concode(void); | 839 | void sisusb_init_concode(void); |
840 | 840 | ||
841 | #endif | 841 | #endif |
842 | |||
diff --git a/drivers/usb/misc/sisusbvga/sisusb_struct.h b/drivers/usb/misc/sisusbvga/sisusb_struct.h index f325ecb29a61..1c4240e802c1 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_struct.h +++ b/drivers/usb/misc/sisusbvga/sisusb_struct.h | |||
@@ -44,7 +44,7 @@ | |||
44 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 44 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
45 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 45 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
46 | * | 46 | * |
47 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 47 | * Author: Thomas Winischhofer <thomas@winischhofer.net> |
48 | * | 48 | * |
49 | */ | 49 | */ |
50 | 50 | ||
@@ -52,85 +52,78 @@ | |||
52 | #define _SISUSB_STRUCT_H_ | 52 | #define _SISUSB_STRUCT_H_ |
53 | 53 | ||
54 | struct SiS_St { | 54 | struct SiS_St { |
55 | unsigned char St_ModeID; | 55 | unsigned char St_ModeID; |
56 | unsigned short St_ModeFlag; | 56 | unsigned short St_ModeFlag; |
57 | unsigned char St_StTableIndex; | 57 | unsigned char St_StTableIndex; |
58 | unsigned char St_CRT2CRTC; | 58 | unsigned char St_CRT2CRTC; |
59 | unsigned char St_ResInfo; | 59 | unsigned char St_ResInfo; |
60 | unsigned char VB_StTVFlickerIndex; | 60 | unsigned char VB_StTVFlickerIndex; |
61 | unsigned char VB_StTVEdgeIndex; | 61 | unsigned char VB_StTVEdgeIndex; |
62 | unsigned char VB_StTVYFilterIndex; | 62 | unsigned char VB_StTVYFilterIndex; |
63 | unsigned char St_PDC; | 63 | unsigned char St_PDC; |
64 | }; | 64 | }; |
65 | 65 | ||
66 | struct SiS_StandTable | 66 | struct SiS_StandTable { |
67 | { | 67 | unsigned char CRT_COLS; |
68 | unsigned char CRT_COLS; | 68 | unsigned char ROWS; |
69 | unsigned char ROWS; | 69 | unsigned char CHAR_HEIGHT; |
70 | unsigned char CHAR_HEIGHT; | 70 | unsigned short CRT_LEN; |
71 | unsigned short CRT_LEN; | 71 | unsigned char SR[4]; |
72 | unsigned char SR[4]; | 72 | unsigned char MISC; |
73 | unsigned char MISC; | 73 | unsigned char CRTC[0x19]; |
74 | unsigned char CRTC[0x19]; | 74 | unsigned char ATTR[0x14]; |
75 | unsigned char ATTR[0x14]; | 75 | unsigned char GRC[9]; |
76 | unsigned char GRC[9]; | ||
77 | }; | 76 | }; |
78 | 77 | ||
79 | struct SiS_StResInfo_S { | 78 | struct SiS_StResInfo_S { |
80 | unsigned short HTotal; | 79 | unsigned short HTotal; |
81 | unsigned short VTotal; | 80 | unsigned short VTotal; |
82 | }; | 81 | }; |
83 | 82 | ||
84 | struct SiS_Ext | 83 | struct SiS_Ext { |
85 | { | 84 | unsigned char Ext_ModeID; |
86 | unsigned char Ext_ModeID; | 85 | unsigned short Ext_ModeFlag; |
87 | unsigned short Ext_ModeFlag; | 86 | unsigned short Ext_VESAID; |
88 | unsigned short Ext_VESAID; | 87 | unsigned char Ext_RESINFO; |
89 | unsigned char Ext_RESINFO; | 88 | unsigned char VB_ExtTVFlickerIndex; |
90 | unsigned char VB_ExtTVFlickerIndex; | 89 | unsigned char VB_ExtTVEdgeIndex; |
91 | unsigned char VB_ExtTVEdgeIndex; | 90 | unsigned char VB_ExtTVYFilterIndex; |
92 | unsigned char VB_ExtTVYFilterIndex; | 91 | unsigned char VB_ExtTVYFilterIndexROM661; |
93 | unsigned char VB_ExtTVYFilterIndexROM661; | 92 | unsigned char REFindex; |
94 | unsigned char REFindex; | 93 | char ROMMODEIDX661; |
95 | char ROMMODEIDX661; | ||
96 | }; | 94 | }; |
97 | 95 | ||
98 | struct SiS_Ext2 | 96 | struct SiS_Ext2 { |
99 | { | 97 | unsigned short Ext_InfoFlag; |
100 | unsigned short Ext_InfoFlag; | 98 | unsigned char Ext_CRT1CRTC; |
101 | unsigned char Ext_CRT1CRTC; | 99 | unsigned char Ext_CRTVCLK; |
102 | unsigned char Ext_CRTVCLK; | 100 | unsigned char Ext_CRT2CRTC; |
103 | unsigned char Ext_CRT2CRTC; | 101 | unsigned char Ext_CRT2CRTC_NS; |
104 | unsigned char Ext_CRT2CRTC_NS; | 102 | unsigned char ModeID; |
105 | unsigned char ModeID; | 103 | unsigned short XRes; |
106 | unsigned short XRes; | 104 | unsigned short YRes; |
107 | unsigned short YRes; | 105 | unsigned char Ext_PDC; |
108 | unsigned char Ext_PDC; | 106 | unsigned char Ext_FakeCRT2CRTC; |
109 | unsigned char Ext_FakeCRT2CRTC; | 107 | unsigned char Ext_FakeCRT2Clk; |
110 | unsigned char Ext_FakeCRT2Clk; | ||
111 | }; | 108 | }; |
112 | 109 | ||
113 | struct SiS_CRT1Table | 110 | struct SiS_CRT1Table { |
114 | { | 111 | unsigned char CR[17]; |
115 | unsigned char CR[17]; | ||
116 | }; | 112 | }; |
117 | 113 | ||
118 | struct SiS_VCLKData | 114 | struct SiS_VCLKData { |
119 | { | 115 | unsigned char SR2B, SR2C; |
120 | unsigned char SR2B,SR2C; | 116 | unsigned short CLOCK; |
121 | unsigned short CLOCK; | ||
122 | }; | 117 | }; |
123 | 118 | ||
124 | struct SiS_ModeResInfo | 119 | struct SiS_ModeResInfo { |
125 | { | 120 | unsigned short HTotal; |
126 | unsigned short HTotal; | 121 | unsigned short VTotal; |
127 | unsigned short VTotal; | 122 | unsigned char XChar; |
128 | unsigned char XChar; | 123 | unsigned char YChar; |
129 | unsigned char YChar; | ||
130 | }; | 124 | }; |
131 | 125 | ||
132 | struct SiS_Private | 126 | struct SiS_Private { |
133 | { | ||
134 | void *sisusb; | 127 | void *sisusb; |
135 | 128 | ||
136 | unsigned long IOAddress; | 129 | unsigned long IOAddress; |
@@ -151,19 +144,18 @@ struct SiS_Private | |||
151 | unsigned long SiS_P3da; | 144 | unsigned long SiS_P3da; |
152 | unsigned long SiS_Part1Port; | 145 | unsigned long SiS_Part1Port; |
153 | 146 | ||
154 | unsigned char SiS_MyCR63; | 147 | unsigned char SiS_MyCR63; |
155 | unsigned short SiS_CRT1Mode; | 148 | unsigned short SiS_CRT1Mode; |
156 | unsigned short SiS_ModeType; | 149 | unsigned short SiS_ModeType; |
157 | unsigned short SiS_SetFlag; | 150 | unsigned short SiS_SetFlag; |
158 | 151 | ||
159 | const struct SiS_StandTable *SiS_StandTable; | 152 | const struct SiS_StandTable *SiS_StandTable; |
160 | const struct SiS_St *SiS_SModeIDTable; | 153 | const struct SiS_St *SiS_SModeIDTable; |
161 | const struct SiS_Ext *SiS_EModeIDTable; | 154 | const struct SiS_Ext *SiS_EModeIDTable; |
162 | const struct SiS_Ext2 *SiS_RefIndex; | 155 | const struct SiS_Ext2 *SiS_RefIndex; |
163 | const struct SiS_CRT1Table *SiS_CRT1Table; | 156 | const struct SiS_CRT1Table *SiS_CRT1Table; |
164 | const struct SiS_VCLKData *SiS_VCLKData; | 157 | const struct SiS_VCLKData *SiS_VCLKData; |
165 | const struct SiS_ModeResInfo *SiS_ModeResInfo; | 158 | const struct SiS_ModeResInfo *SiS_ModeResInfo; |
166 | }; | 159 | }; |
167 | 160 | ||
168 | #endif | 161 | #endif |
169 | |||
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index c03dfd7a9d36..f06e4e2b49d3 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -172,6 +172,10 @@ static inline struct mon_bin_hdr *MON_OFF2HDR(const struct mon_reader_bin *rp, | |||
172 | 172 | ||
173 | #define MON_RING_EMPTY(rp) ((rp)->b_cnt == 0) | 173 | #define MON_RING_EMPTY(rp) ((rp)->b_cnt == 0) |
174 | 174 | ||
175 | static unsigned char xfer_to_pipe[4] = { | ||
176 | PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT | ||
177 | }; | ||
178 | |||
175 | static struct class *mon_bin_class; | 179 | static struct class *mon_bin_class; |
176 | static dev_t mon_bin_dev0; | 180 | static dev_t mon_bin_dev0; |
177 | static struct cdev mon_bin_cdev; | 181 | static struct cdev mon_bin_cdev; |
@@ -354,13 +358,9 @@ static inline char mon_bin_get_setup(unsigned char *setupb, | |||
354 | const struct urb *urb, char ev_type) | 358 | const struct urb *urb, char ev_type) |
355 | { | 359 | { |
356 | 360 | ||
357 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') | 361 | if (!usb_endpoint_xfer_control(&urb->ep->desc) || ev_type != 'S') |
358 | return '-'; | 362 | return '-'; |
359 | 363 | ||
360 | if (urb->dev->bus->uses_dma && | ||
361 | (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { | ||
362 | return mon_dmapeek(setupb, urb->setup_dma, SETUP_LEN); | ||
363 | } | ||
364 | if (urb->setup_packet == NULL) | 364 | if (urb->setup_packet == NULL) |
365 | return 'Z'; | 365 | return 'Z'; |
366 | 366 | ||
@@ -386,13 +386,15 @@ static char mon_bin_get_data(const struct mon_reader_bin *rp, | |||
386 | } | 386 | } |
387 | 387 | ||
388 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | 388 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, |
389 | char ev_type) | 389 | char ev_type, int status) |
390 | { | 390 | { |
391 | const struct usb_endpoint_descriptor *epd = &urb->ep->desc; | ||
391 | unsigned long flags; | 392 | unsigned long flags; |
392 | struct timeval ts; | 393 | struct timeval ts; |
393 | unsigned int urb_length; | 394 | unsigned int urb_length; |
394 | unsigned int offset; | 395 | unsigned int offset; |
395 | unsigned int length; | 396 | unsigned int length; |
397 | unsigned char dir; | ||
396 | struct mon_bin_hdr *ep; | 398 | struct mon_bin_hdr *ep; |
397 | char data_tag = 0; | 399 | char data_tag = 0; |
398 | 400 | ||
@@ -410,16 +412,19 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
410 | if (length >= rp->b_size/5) | 412 | if (length >= rp->b_size/5) |
411 | length = rp->b_size/5; | 413 | length = rp->b_size/5; |
412 | 414 | ||
413 | if (usb_pipein(urb->pipe)) { | 415 | if (usb_urb_dir_in(urb)) { |
414 | if (ev_type == 'S') { | 416 | if (ev_type == 'S') { |
415 | length = 0; | 417 | length = 0; |
416 | data_tag = '<'; | 418 | data_tag = '<'; |
417 | } | 419 | } |
420 | /* Cannot rely on endpoint number in case of control ep.0 */ | ||
421 | dir = USB_DIR_IN; | ||
418 | } else { | 422 | } else { |
419 | if (ev_type == 'C') { | 423 | if (ev_type == 'C') { |
420 | length = 0; | 424 | length = 0; |
421 | data_tag = '>'; | 425 | data_tag = '>'; |
422 | } | 426 | } |
427 | dir = 0; | ||
423 | } | 428 | } |
424 | 429 | ||
425 | if (rp->mmap_active) | 430 | if (rp->mmap_active) |
@@ -440,15 +445,14 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
440 | */ | 445 | */ |
441 | memset(ep, 0, PKT_SIZE); | 446 | memset(ep, 0, PKT_SIZE); |
442 | ep->type = ev_type; | 447 | ep->type = ev_type; |
443 | ep->xfer_type = usb_pipetype(urb->pipe); | 448 | ep->xfer_type = xfer_to_pipe[usb_endpoint_type(epd)]; |
444 | /* We use the fact that usb_pipein() returns 0x80 */ | 449 | ep->epnum = dir | usb_endpoint_num(epd); |
445 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | 450 | ep->devnum = urb->dev->devnum; |
446 | ep->devnum = usb_pipedevice(urb->pipe); | ||
447 | ep->busnum = urb->dev->bus->busnum; | 451 | ep->busnum = urb->dev->bus->busnum; |
448 | ep->id = (unsigned long) urb; | 452 | ep->id = (unsigned long) urb; |
449 | ep->ts_sec = ts.tv_sec; | 453 | ep->ts_sec = ts.tv_sec; |
450 | ep->ts_usec = ts.tv_usec; | 454 | ep->ts_usec = ts.tv_usec; |
451 | ep->status = urb->status; | 455 | ep->status = status; |
452 | ep->len_urb = urb_length; | 456 | ep->len_urb = urb_length; |
453 | ep->len_cap = length; | 457 | ep->len_cap = length; |
454 | 458 | ||
@@ -471,13 +475,13 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
471 | static void mon_bin_submit(void *data, struct urb *urb) | 475 | static void mon_bin_submit(void *data, struct urb *urb) |
472 | { | 476 | { |
473 | struct mon_reader_bin *rp = data; | 477 | struct mon_reader_bin *rp = data; |
474 | mon_bin_event(rp, urb, 'S'); | 478 | mon_bin_event(rp, urb, 'S', -EINPROGRESS); |
475 | } | 479 | } |
476 | 480 | ||
477 | static void mon_bin_complete(void *data, struct urb *urb) | 481 | static void mon_bin_complete(void *data, struct urb *urb, int status) |
478 | { | 482 | { |
479 | struct mon_reader_bin *rp = data; | 483 | struct mon_reader_bin *rp = data; |
480 | mon_bin_event(rp, urb, 'C'); | 484 | mon_bin_event(rp, urb, 'C', status); |
481 | } | 485 | } |
482 | 486 | ||
483 | static void mon_bin_error(void *data, struct urb *urb, int error) | 487 | static void mon_bin_error(void *data, struct urb *urb, int error) |
@@ -500,10 +504,10 @@ static void mon_bin_error(void *data, struct urb *urb, int error) | |||
500 | 504 | ||
501 | memset(ep, 0, PKT_SIZE); | 505 | memset(ep, 0, PKT_SIZE); |
502 | ep->type = 'E'; | 506 | ep->type = 'E'; |
503 | ep->xfer_type = usb_pipetype(urb->pipe); | 507 | ep->xfer_type = xfer_to_pipe[usb_endpoint_type(&urb->ep->desc)]; |
504 | /* We use the fact that usb_pipein() returns 0x80 */ | 508 | ep->epnum = usb_urb_dir_in(urb) ? USB_DIR_IN : 0; |
505 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | 509 | ep->epnum |= usb_endpoint_num(&urb->ep->desc); |
506 | ep->devnum = usb_pipedevice(urb->pipe); | 510 | ep->devnum = urb->dev->devnum; |
507 | ep->busnum = urb->dev->bus->busnum; | 511 | ep->busnum = urb->dev->bus->busnum; |
508 | ep->id = (unsigned long) urb; | 512 | ep->id = (unsigned long) urb; |
509 | ep->status = error; | 513 | ep->status = error; |
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index ce61d8b0fd86..b371ffd39d36 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -129,7 +129,8 @@ static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) | |||
129 | 129 | ||
130 | /* | 130 | /* |
131 | */ | 131 | */ |
132 | static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb) | 132 | static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb, |
133 | int status) | ||
133 | { | 134 | { |
134 | unsigned long flags; | 135 | unsigned long flags; |
135 | struct list_head *pos; | 136 | struct list_head *pos; |
@@ -139,28 +140,18 @@ static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb) | |||
139 | mbus->cnt_events++; | 140 | mbus->cnt_events++; |
140 | list_for_each (pos, &mbus->r_list) { | 141 | list_for_each (pos, &mbus->r_list) { |
141 | r = list_entry(pos, struct mon_reader, r_link); | 142 | r = list_entry(pos, struct mon_reader, r_link); |
142 | r->rnf_complete(r->r_data, urb); | 143 | r->rnf_complete(r->r_data, urb, status); |
143 | } | 144 | } |
144 | spin_unlock_irqrestore(&mbus->lock, flags); | 145 | spin_unlock_irqrestore(&mbus->lock, flags); |
145 | } | 146 | } |
146 | 147 | ||
147 | static void mon_complete(struct usb_bus *ubus, struct urb *urb) | 148 | static void mon_complete(struct usb_bus *ubus, struct urb *urb, int status) |
148 | { | 149 | { |
149 | struct mon_bus *mbus; | 150 | struct mon_bus *mbus; |
150 | 151 | ||
151 | mbus = ubus->mon_bus; | 152 | if ((mbus = ubus->mon_bus) != NULL) |
152 | if (mbus == NULL) { | 153 | mon_bus_complete(mbus, urb, status); |
153 | /* | 154 | mon_bus_complete(&mon_bus0, urb, status); |
154 | * This should not happen. | ||
155 | * At this point we do not even know the bus number... | ||
156 | */ | ||
157 | printk(KERN_ERR TAG ": Null mon bus in URB, pipe 0x%x\n", | ||
158 | urb->pipe); | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | mon_bus_complete(mbus, urb); | ||
163 | mon_bus_complete(&mon_bus0, urb); | ||
164 | } | 155 | } |
165 | 156 | ||
166 | /* int (*unlink_urb) (struct urb *urb, int status); */ | 157 | /* int (*unlink_urb) (struct urb *urb, int status); */ |
@@ -170,7 +161,7 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) | |||
170 | */ | 161 | */ |
171 | static void mon_stop(struct mon_bus *mbus) | 162 | static void mon_stop(struct mon_bus *mbus) |
172 | { | 163 | { |
173 | struct usb_bus *ubus = mbus->u_bus; | 164 | struct usb_bus *ubus; |
174 | struct list_head *p; | 165 | struct list_head *p; |
175 | 166 | ||
176 | if (mbus == &mon_bus0) { | 167 | if (mbus == &mon_bus0) { |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 8f27a9e1c36b..ebb04ac4857b 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -50,10 +50,13 @@ struct mon_iso_desc { | |||
50 | struct mon_event_text { | 50 | struct mon_event_text { |
51 | struct list_head e_link; | 51 | struct list_head e_link; |
52 | int type; /* submit, complete, etc. */ | 52 | int type; /* submit, complete, etc. */ |
53 | unsigned int pipe; /* Pipe */ | ||
54 | unsigned long id; /* From pointer, most of the time */ | 53 | unsigned long id; /* From pointer, most of the time */ |
55 | unsigned int tstamp; | 54 | unsigned int tstamp; |
56 | int busnum; | 55 | int busnum; |
56 | char devnum; | ||
57 | char epnum; | ||
58 | char is_in; | ||
59 | char xfertype; | ||
57 | int length; /* Depends on type: xfer length or act length */ | 60 | int length; /* Depends on type: xfer length or act length */ |
58 | int status; | 61 | int status; |
59 | int interval; | 62 | int interval; |
@@ -121,13 +124,9 @@ static inline char mon_text_get_setup(struct mon_event_text *ep, | |||
121 | struct urb *urb, char ev_type, struct mon_bus *mbus) | 124 | struct urb *urb, char ev_type, struct mon_bus *mbus) |
122 | { | 125 | { |
123 | 126 | ||
124 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') | 127 | if (ep->xfertype != USB_ENDPOINT_XFER_CONTROL || ev_type != 'S') |
125 | return '-'; | 128 | return '-'; |
126 | 129 | ||
127 | if (urb->dev->bus->uses_dma && | ||
128 | (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { | ||
129 | return mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX); | ||
130 | } | ||
131 | if (urb->setup_packet == NULL) | 130 | if (urb->setup_packet == NULL) |
132 | return 'Z'; /* '0' would be not as pretty. */ | 131 | return 'Z'; /* '0' would be not as pretty. */ |
133 | 132 | ||
@@ -138,14 +137,12 @@ static inline char mon_text_get_setup(struct mon_event_text *ep, | |||
138 | static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | 137 | static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, |
139 | int len, char ev_type, struct mon_bus *mbus) | 138 | int len, char ev_type, struct mon_bus *mbus) |
140 | { | 139 | { |
141 | int pipe = urb->pipe; | ||
142 | |||
143 | if (len <= 0) | 140 | if (len <= 0) |
144 | return 'L'; | 141 | return 'L'; |
145 | if (len >= DATA_MAX) | 142 | if (len >= DATA_MAX) |
146 | len = DATA_MAX; | 143 | len = DATA_MAX; |
147 | 144 | ||
148 | if (usb_pipein(pipe)) { | 145 | if (ep->is_in) { |
149 | if (ev_type != 'C') | 146 | if (ev_type != 'C') |
150 | return '<'; | 147 | return '<'; |
151 | } else { | 148 | } else { |
@@ -186,7 +183,7 @@ static inline unsigned int mon_get_timestamp(void) | |||
186 | } | 183 | } |
187 | 184 | ||
188 | static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, | 185 | static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, |
189 | char ev_type) | 186 | char ev_type, int status) |
190 | { | 187 | { |
191 | struct mon_event_text *ep; | 188 | struct mon_event_text *ep; |
192 | unsigned int stamp; | 189 | unsigned int stamp; |
@@ -203,24 +200,28 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, | |||
203 | } | 200 | } |
204 | 201 | ||
205 | ep->type = ev_type; | 202 | ep->type = ev_type; |
206 | ep->pipe = urb->pipe; | ||
207 | ep->id = (unsigned long) urb; | 203 | ep->id = (unsigned long) urb; |
208 | ep->busnum = urb->dev->bus->busnum; | 204 | ep->busnum = urb->dev->bus->busnum; |
205 | ep->devnum = urb->dev->devnum; | ||
206 | ep->epnum = usb_endpoint_num(&urb->ep->desc); | ||
207 | ep->xfertype = usb_endpoint_type(&urb->ep->desc); | ||
208 | ep->is_in = usb_urb_dir_in(urb); | ||
209 | ep->tstamp = stamp; | 209 | ep->tstamp = stamp; |
210 | ep->length = (ev_type == 'S') ? | 210 | ep->length = (ev_type == 'S') ? |
211 | urb->transfer_buffer_length : urb->actual_length; | 211 | urb->transfer_buffer_length : urb->actual_length; |
212 | /* Collecting status makes debugging sense for submits, too */ | 212 | /* Collecting status makes debugging sense for submits, too */ |
213 | ep->status = urb->status; | 213 | ep->status = status; |
214 | 214 | ||
215 | if (usb_pipeint(urb->pipe)) { | 215 | if (ep->xfertype == USB_ENDPOINT_XFER_INT) { |
216 | ep->interval = urb->interval; | 216 | ep->interval = urb->interval; |
217 | } else if (usb_pipeisoc(urb->pipe)) { | 217 | } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) { |
218 | ep->interval = urb->interval; | 218 | ep->interval = urb->interval; |
219 | ep->start_frame = urb->start_frame; | 219 | ep->start_frame = urb->start_frame; |
220 | ep->error_count = urb->error_count; | 220 | ep->error_count = urb->error_count; |
221 | } | 221 | } |
222 | ep->numdesc = urb->number_of_packets; | 222 | ep->numdesc = urb->number_of_packets; |
223 | if (usb_pipeisoc(urb->pipe) && urb->number_of_packets > 0) { | 223 | if (ep->xfertype == USB_ENDPOINT_XFER_ISOC && |
224 | urb->number_of_packets > 0) { | ||
224 | if ((ndesc = urb->number_of_packets) > ISODESC_MAX) | 225 | if ((ndesc = urb->number_of_packets) > ISODESC_MAX) |
225 | ndesc = ISODESC_MAX; | 226 | ndesc = ISODESC_MAX; |
226 | fp = urb->iso_frame_desc; | 227 | fp = urb->iso_frame_desc; |
@@ -247,13 +248,13 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, | |||
247 | static void mon_text_submit(void *data, struct urb *urb) | 248 | static void mon_text_submit(void *data, struct urb *urb) |
248 | { | 249 | { |
249 | struct mon_reader_text *rp = data; | 250 | struct mon_reader_text *rp = data; |
250 | mon_text_event(rp, urb, 'S'); | 251 | mon_text_event(rp, urb, 'S', -EINPROGRESS); |
251 | } | 252 | } |
252 | 253 | ||
253 | static void mon_text_complete(void *data, struct urb *urb) | 254 | static void mon_text_complete(void *data, struct urb *urb, int status) |
254 | { | 255 | { |
255 | struct mon_reader_text *rp = data; | 256 | struct mon_reader_text *rp = data; |
256 | mon_text_event(rp, urb, 'C'); | 257 | mon_text_event(rp, urb, 'C', status); |
257 | } | 258 | } |
258 | 259 | ||
259 | static void mon_text_error(void *data, struct urb *urb, int error) | 260 | static void mon_text_error(void *data, struct urb *urb, int error) |
@@ -268,9 +269,12 @@ static void mon_text_error(void *data, struct urb *urb, int error) | |||
268 | } | 269 | } |
269 | 270 | ||
270 | ep->type = 'E'; | 271 | ep->type = 'E'; |
271 | ep->pipe = urb->pipe; | ||
272 | ep->id = (unsigned long) urb; | 272 | ep->id = (unsigned long) urb; |
273 | ep->busnum = 0; | 273 | ep->busnum = 0; |
274 | ep->devnum = urb->dev->devnum; | ||
275 | ep->epnum = usb_endpoint_num(&urb->ep->desc); | ||
276 | ep->xfertype = usb_endpoint_type(&urb->ep->desc); | ||
277 | ep->is_in = usb_urb_dir_in(urb); | ||
274 | ep->tstamp = 0; | 278 | ep->tstamp = 0; |
275 | ep->length = 0; | 279 | ep->length = 0; |
276 | ep->status = error; | 280 | ep->status = error; |
@@ -413,10 +417,10 @@ static ssize_t mon_text_read_u(struct file *file, char __user *buf, | |||
413 | mon_text_read_head_u(rp, &ptr, ep); | 417 | mon_text_read_head_u(rp, &ptr, ep); |
414 | if (ep->type == 'E') { | 418 | if (ep->type == 'E') { |
415 | mon_text_read_statset(rp, &ptr, ep); | 419 | mon_text_read_statset(rp, &ptr, ep); |
416 | } else if (usb_pipeisoc(ep->pipe)) { | 420 | } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) { |
417 | mon_text_read_isostat(rp, &ptr, ep); | 421 | mon_text_read_isostat(rp, &ptr, ep); |
418 | mon_text_read_isodesc(rp, &ptr, ep); | 422 | mon_text_read_isodesc(rp, &ptr, ep); |
419 | } else if (usb_pipeint(ep->pipe)) { | 423 | } else if (ep->xfertype == USB_ENDPOINT_XFER_INT) { |
420 | mon_text_read_intstat(rp, &ptr, ep); | 424 | mon_text_read_intstat(rp, &ptr, ep); |
421 | } else { | 425 | } else { |
422 | mon_text_read_statset(rp, &ptr, ep); | 426 | mon_text_read_statset(rp, &ptr, ep); |
@@ -468,18 +472,17 @@ static void mon_text_read_head_t(struct mon_reader_text *rp, | |||
468 | { | 472 | { |
469 | char udir, utype; | 473 | char udir, utype; |
470 | 474 | ||
471 | udir = usb_pipein(ep->pipe) ? 'i' : 'o'; | 475 | udir = (ep->is_in ? 'i' : 'o'); |
472 | switch (usb_pipetype(ep->pipe)) { | 476 | switch (ep->xfertype) { |
473 | case PIPE_ISOCHRONOUS: utype = 'Z'; break; | 477 | case USB_ENDPOINT_XFER_ISOC: utype = 'Z'; break; |
474 | case PIPE_INTERRUPT: utype = 'I'; break; | 478 | case USB_ENDPOINT_XFER_INT: utype = 'I'; break; |
475 | case PIPE_CONTROL: utype = 'C'; break; | 479 | case USB_ENDPOINT_XFER_CONTROL: utype = 'C'; break; |
476 | default: /* PIPE_BULK */ utype = 'B'; | 480 | default: /* PIPE_BULK */ utype = 'B'; |
477 | } | 481 | } |
478 | p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, | 482 | p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, |
479 | "%lx %u %c %c%c:%03u:%02u", | 483 | "%lx %u %c %c%c:%03u:%02u", |
480 | ep->id, ep->tstamp, ep->type, | 484 | ep->id, ep->tstamp, ep->type, |
481 | utype, udir, | 485 | utype, udir, ep->devnum, ep->epnum); |
482 | usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); | ||
483 | } | 486 | } |
484 | 487 | ||
485 | static void mon_text_read_head_u(struct mon_reader_text *rp, | 488 | static void mon_text_read_head_u(struct mon_reader_text *rp, |
@@ -487,18 +490,17 @@ static void mon_text_read_head_u(struct mon_reader_text *rp, | |||
487 | { | 490 | { |
488 | char udir, utype; | 491 | char udir, utype; |
489 | 492 | ||
490 | udir = usb_pipein(ep->pipe) ? 'i' : 'o'; | 493 | udir = (ep->is_in ? 'i' : 'o'); |
491 | switch (usb_pipetype(ep->pipe)) { | 494 | switch (ep->xfertype) { |
492 | case PIPE_ISOCHRONOUS: utype = 'Z'; break; | 495 | case USB_ENDPOINT_XFER_ISOC: utype = 'Z'; break; |
493 | case PIPE_INTERRUPT: utype = 'I'; break; | 496 | case USB_ENDPOINT_XFER_INT: utype = 'I'; break; |
494 | case PIPE_CONTROL: utype = 'C'; break; | 497 | case USB_ENDPOINT_XFER_CONTROL: utype = 'C'; break; |
495 | default: /* PIPE_BULK */ utype = 'B'; | 498 | default: /* PIPE_BULK */ utype = 'B'; |
496 | } | 499 | } |
497 | p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, | 500 | p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, |
498 | "%lx %u %c %c%c:%d:%03u:%u", | 501 | "%lx %u %c %c%c:%d:%03u:%u", |
499 | ep->id, ep->tstamp, ep->type, | 502 | ep->id, ep->tstamp, ep->type, |
500 | utype, udir, | 503 | utype, udir, ep->busnum, ep->devnum, ep->epnum); |
501 | ep->busnum, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); | ||
502 | } | 504 | } |
503 | 505 | ||
504 | static void mon_text_read_statset(struct mon_reader_text *rp, | 506 | static void mon_text_read_statset(struct mon_reader_text *rp, |
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index f68ad6d99ad7..f5d84ff8c101 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h | |||
@@ -46,7 +46,7 @@ struct mon_reader { | |||
46 | 46 | ||
47 | void (*rnf_submit)(void *data, struct urb *urb); | 47 | void (*rnf_submit)(void *data, struct urb *urb); |
48 | void (*rnf_error)(void *data, struct urb *urb, int error); | 48 | void (*rnf_error)(void *data, struct urb *urb, int error); |
49 | void (*rnf_complete)(void *data, struct urb *urb); | 49 | void (*rnf_complete)(void *data, struct urb *urb, int status); |
50 | }; | 50 | }; |
51 | 51 | ||
52 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); | 52 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 43d6db696f90..99fefed77919 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -92,6 +92,16 @@ config USB_SERIAL_BELKIN | |||
92 | To compile this driver as a module, choose M here: the | 92 | To compile this driver as a module, choose M here: the |
93 | module will be called belkin_sa. | 93 | module will be called belkin_sa. |
94 | 94 | ||
95 | config USB_SERIAL_CH341 | ||
96 | tristate "USB Winchiphead CH341 Single Port Serial Driver" | ||
97 | depends on USB_SERIAL | ||
98 | help | ||
99 | Say Y here if you want to use a Winchiphead CH341 single port | ||
100 | USB to serial adapter. | ||
101 | |||
102 | To compile this driver as a module, choose M here: the | ||
103 | module will be called ch341. | ||
104 | |||
95 | config USB_SERIAL_WHITEHEAT | 105 | config USB_SERIAL_WHITEHEAT |
96 | tristate "USB ConnectTech WhiteHEAT Serial Driver" | 106 | tristate "USB ConnectTech WhiteHEAT Serial Driver" |
97 | depends on USB_SERIAL | 107 | depends on USB_SERIAL |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 07a976eca6b7..d6fb384e52b2 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -15,6 +15,7 @@ obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o | |||
15 | obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o | 15 | obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o |
16 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o | 16 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o |
17 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o | 17 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o |
18 | obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o | ||
18 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o | 19 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o |
19 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o | 20 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o |
20 | obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o | 21 | obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index c9fd486c1c7d..2a8e537cb046 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -172,11 +172,6 @@ static void ark3116_set_termios(struct usb_serial_port *port, | |||
172 | 172 | ||
173 | dbg("%s - port %d", __FUNCTION__, port->number); | 173 | dbg("%s - port %d", __FUNCTION__, port->number); |
174 | 174 | ||
175 | if (!port->tty || !port->tty->termios) { | ||
176 | dbg("%s - no tty structures", __FUNCTION__); | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | spin_lock_irqsave(&priv->lock, flags); | 175 | spin_lock_irqsave(&priv->lock, flags); |
181 | if (!priv->termios_initialized) { | 176 | if (!priv->termios_initialized) { |
182 | *(port->tty->termios) = tty_std_termios; | 177 | *(port->tty->termios) = tty_std_termios; |
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index a47a24f8820d..0b14aea8ebd5 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
@@ -36,6 +36,16 @@ static int usb_serial_device_match (struct device *dev, struct device_driver *dr | |||
36 | return 0; | 36 | return 0; |
37 | } | 37 | } |
38 | 38 | ||
39 | static ssize_t show_port_number(struct device *dev, | ||
40 | struct device_attribute *attr, char *buf) | ||
41 | { | ||
42 | struct usb_serial_port *port = to_usb_serial_port(dev); | ||
43 | |||
44 | return sprintf(buf, "%d\n", port->number - port->serial->minor); | ||
45 | } | ||
46 | |||
47 | static DEVICE_ATTR(port_number, S_IRUGO, show_port_number, NULL); | ||
48 | |||
39 | static int usb_serial_device_probe (struct device *dev) | 49 | static int usb_serial_device_probe (struct device *dev) |
40 | { | 50 | { |
41 | struct usb_serial_driver *driver; | 51 | struct usb_serial_driver *driver; |
@@ -62,6 +72,10 @@ static int usb_serial_device_probe (struct device *dev) | |||
62 | goto exit; | 72 | goto exit; |
63 | } | 73 | } |
64 | 74 | ||
75 | retval = device_create_file(dev, &dev_attr_port_number); | ||
76 | if (retval) | ||
77 | goto exit; | ||
78 | |||
65 | minor = port->number; | 79 | minor = port->number; |
66 | tty_register_device (usb_serial_tty_driver, minor, dev); | 80 | tty_register_device (usb_serial_tty_driver, minor, dev); |
67 | dev_info(&port->serial->dev->dev, | 81 | dev_info(&port->serial->dev->dev, |
@@ -84,6 +98,8 @@ static int usb_serial_device_remove (struct device *dev) | |||
84 | return -ENODEV; | 98 | return -ENODEV; |
85 | } | 99 | } |
86 | 100 | ||
101 | device_remove_file(&port->dev, &dev_attr_port_number); | ||
102 | |||
87 | driver = port->serial->type; | 103 | driver = port->serial->type; |
88 | if (driver->port_remove) { | 104 | if (driver->port_remove) { |
89 | if (!try_module_get(driver->driver.owner)) { | 105 | if (!try_module_get(driver->driver.owner)) { |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c new file mode 100644 index 000000000000..6b252ceb39a8 --- /dev/null +++ b/drivers/usb/serial/ch341.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* | ||
2 | * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk> | ||
3 | * | ||
4 | * ch341.c implements a serial port driver for the Winchiphead CH341. | ||
5 | * | ||
6 | * The CH341 device can be used to implement an RS232 asynchronous | ||
7 | * serial port, an IEEE-1284 parallel printer port or a memory-like | ||
8 | * interface. In all cases the CH341 supports an I2C interface as well. | ||
9 | * This driver only supports the asynchronous serial interface. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License version | ||
13 | * 2 as published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/tty.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/usb.h> | ||
21 | #include <linux/usb/serial.h> | ||
22 | #include <linux/serial.h> | ||
23 | |||
24 | #define DEFAULT_BAUD_RATE 2400 | ||
25 | #define DEFAULT_TIMEOUT 1000 | ||
26 | |||
27 | static int debug; | ||
28 | |||
29 | static struct usb_device_id id_table [] = { | ||
30 | { USB_DEVICE(0x4348, 0x5523) }, | ||
31 | { }, | ||
32 | }; | ||
33 | MODULE_DEVICE_TABLE(usb, id_table); | ||
34 | |||
35 | struct ch341_private { | ||
36 | unsigned baud_rate; | ||
37 | u8 dtr; | ||
38 | u8 rts; | ||
39 | }; | ||
40 | |||
41 | static int ch341_control_out(struct usb_device *dev, u8 request, | ||
42 | u16 value, u16 index) | ||
43 | { | ||
44 | int r; | ||
45 | dbg("ch341_control_out(%02x,%02x,%04x,%04x)", USB_DIR_OUT|0x40, | ||
46 | (int)request, (int)value, (int)index); | ||
47 | |||
48 | r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, | ||
49 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
50 | value, index, NULL, 0, DEFAULT_TIMEOUT); | ||
51 | |||
52 | return r; | ||
53 | } | ||
54 | |||
55 | static int ch341_control_in(struct usb_device *dev, | ||
56 | u8 request, u16 value, u16 index, | ||
57 | char *buf, unsigned bufsize) | ||
58 | { | ||
59 | int r; | ||
60 | dbg("ch341_control_in(%02x,%02x,%04x,%04x,%p,%u)", USB_DIR_IN|0x40, | ||
61 | (int)request, (int)value, (int)index, buf, (int)bufsize); | ||
62 | |||
63 | r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, | ||
64 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | ||
65 | value, index, buf, bufsize, DEFAULT_TIMEOUT); | ||
66 | return r; | ||
67 | } | ||
68 | |||
69 | static int ch341_set_baudrate(struct usb_device *dev, | ||
70 | struct ch341_private *priv) | ||
71 | { | ||
72 | short a, b; | ||
73 | int r; | ||
74 | |||
75 | dbg("ch341_set_baudrate(%d)", priv->baud_rate); | ||
76 | switch (priv->baud_rate) { | ||
77 | case 2400: | ||
78 | a = 0xd901; | ||
79 | b = 0x0038; | ||
80 | break; | ||
81 | case 4800: | ||
82 | a = 0x6402; | ||
83 | b = 0x001f; | ||
84 | break; | ||
85 | case 9600: | ||
86 | a = 0xb202; | ||
87 | b = 0x0013; | ||
88 | break; | ||
89 | case 19200: | ||
90 | a = 0xd902; | ||
91 | b = 0x000d; | ||
92 | break; | ||
93 | case 38400: | ||
94 | a = 0x6403; | ||
95 | b = 0x000a; | ||
96 | break; | ||
97 | case 115200: | ||
98 | a = 0xcc03; | ||
99 | b = 0x0008; | ||
100 | break; | ||
101 | default: | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | |||
105 | r = ch341_control_out(dev, 0x9a, 0x1312, a); | ||
106 | if (!r) | ||
107 | r = ch341_control_out(dev, 0x9a, 0x0f2c, b); | ||
108 | |||
109 | return r; | ||
110 | } | ||
111 | |||
112 | static int ch341_set_handshake(struct usb_device *dev, | ||
113 | struct ch341_private *priv) | ||
114 | { | ||
115 | dbg("ch341_set_handshake(%d,%d)", priv->dtr, priv->rts); | ||
116 | return ch341_control_out(dev, 0xa4, | ||
117 | ~((priv->dtr?1<<5:0)|(priv->rts?1<<6:0)), 0); | ||
118 | } | ||
119 | |||
120 | static int ch341_get_status(struct usb_device *dev) | ||
121 | { | ||
122 | char *buffer; | ||
123 | int r; | ||
124 | const unsigned size = 8; | ||
125 | |||
126 | dbg("ch341_get_status()"); | ||
127 | |||
128 | buffer = kmalloc(size, GFP_KERNEL); | ||
129 | if (!buffer) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | r = ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size); | ||
133 | if ( r < 0) | ||
134 | goto out; | ||
135 | |||
136 | /* Not having the datasheet for the CH341, we ignore the bytes returned | ||
137 | * from the device. Return error if the device did not respond in time. | ||
138 | */ | ||
139 | r = 0; | ||
140 | |||
141 | out: kfree(buffer); | ||
142 | return r; | ||
143 | } | ||
144 | |||
145 | /* -------------------------------------------------------------------------- */ | ||
146 | |||
147 | static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) | ||
148 | { | ||
149 | char *buffer; | ||
150 | int r; | ||
151 | const unsigned size = 8; | ||
152 | |||
153 | dbg("ch341_configure()"); | ||
154 | |||
155 | buffer = kmalloc(size, GFP_KERNEL); | ||
156 | if (!buffer) | ||
157 | return -ENOMEM; | ||
158 | |||
159 | /* expect two bytes 0x27 0x00 */ | ||
160 | r = ch341_control_in(dev, 0x5f, 0, 0, buffer, size); | ||
161 | if (r < 0) | ||
162 | goto out; | ||
163 | |||
164 | r = ch341_control_out(dev, 0xa1, 0, 0); | ||
165 | if (r < 0) | ||
166 | goto out; | ||
167 | |||
168 | r = ch341_set_baudrate(dev, priv); | ||
169 | if (r < 0) | ||
170 | goto out; | ||
171 | |||
172 | /* expect two bytes 0x56 0x00 */ | ||
173 | r = ch341_control_in(dev, 0x95, 0x2518, 0, buffer, size); | ||
174 | if (r < 0) | ||
175 | goto out; | ||
176 | |||
177 | r = ch341_control_out(dev, 0x9a, 0x2518, 0x0050); | ||
178 | if (r < 0) | ||
179 | goto out; | ||
180 | |||
181 | /* expect 0xff 0xee */ | ||
182 | r = ch341_get_status(dev); | ||
183 | if (r < 0) | ||
184 | goto out; | ||
185 | |||
186 | r = ch341_control_out(dev, 0xa1, 0x501f, 0xd90a); | ||
187 | if (r < 0) | ||
188 | goto out; | ||
189 | |||
190 | r = ch341_set_baudrate(dev, priv); | ||
191 | if (r < 0) | ||
192 | goto out; | ||
193 | |||
194 | r = ch341_set_handshake(dev, priv); | ||
195 | if (r < 0) | ||
196 | goto out; | ||
197 | |||
198 | /* expect 0x9f 0xee */ | ||
199 | r = ch341_get_status(dev); | ||
200 | |||
201 | out: kfree(buffer); | ||
202 | return r; | ||
203 | } | ||
204 | |||
205 | /* allocate private data */ | ||
206 | static int ch341_attach(struct usb_serial *serial) | ||
207 | { | ||
208 | struct ch341_private *priv; | ||
209 | int r; | ||
210 | |||
211 | dbg("ch341_attach()"); | ||
212 | |||
213 | /* private data */ | ||
214 | priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); | ||
215 | if (!priv) | ||
216 | return -ENOMEM; | ||
217 | |||
218 | priv->baud_rate = DEFAULT_BAUD_RATE; | ||
219 | priv->dtr = 1; | ||
220 | priv->rts = 1; | ||
221 | |||
222 | r = ch341_configure(serial->dev, priv); | ||
223 | if (r < 0) | ||
224 | goto error; | ||
225 | |||
226 | usb_set_serial_port_data(serial->port[0], priv); | ||
227 | return 0; | ||
228 | |||
229 | error: kfree(priv); | ||
230 | return r; | ||
231 | } | ||
232 | |||
233 | /* open this device, set default parameters */ | ||
234 | static int ch341_open(struct usb_serial_port *port, struct file *filp) | ||
235 | { | ||
236 | struct usb_serial *serial = port->serial; | ||
237 | struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); | ||
238 | int r; | ||
239 | |||
240 | dbg("ch341_open()"); | ||
241 | |||
242 | priv->baud_rate = DEFAULT_BAUD_RATE; | ||
243 | priv->dtr = 1; | ||
244 | priv->rts = 1; | ||
245 | |||
246 | r = ch341_configure(serial->dev, priv); | ||
247 | if (r) | ||
248 | goto out; | ||
249 | |||
250 | r = ch341_set_handshake(serial->dev, priv); | ||
251 | if (r) | ||
252 | goto out; | ||
253 | |||
254 | r = ch341_set_baudrate(serial->dev, priv); | ||
255 | if (r) | ||
256 | goto out; | ||
257 | |||
258 | r = usb_serial_generic_open(port, filp); | ||
259 | |||
260 | out: return r; | ||
261 | } | ||
262 | |||
263 | /* Old_termios contains the original termios settings and | ||
264 | * tty->termios contains the new setting to be used. | ||
265 | */ | ||
266 | static void ch341_set_termios(struct usb_serial_port *port, | ||
267 | struct ktermios *old_termios) | ||
268 | { | ||
269 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
270 | struct tty_struct *tty = port->tty; | ||
271 | unsigned baud_rate; | ||
272 | |||
273 | dbg("ch341_set_termios()"); | ||
274 | |||
275 | if (!tty || !tty->termios) | ||
276 | return; | ||
277 | |||
278 | baud_rate = tty_get_baud_rate(tty); | ||
279 | |||
280 | switch (baud_rate) { | ||
281 | case 2400: | ||
282 | case 4800: | ||
283 | case 9600: | ||
284 | case 19200: | ||
285 | case 38400: | ||
286 | case 115200: | ||
287 | priv->baud_rate = baud_rate; | ||
288 | break; | ||
289 | default: | ||
290 | dbg("Rate %d not supported, using %d", | ||
291 | baud_rate, DEFAULT_BAUD_RATE); | ||
292 | priv->baud_rate = DEFAULT_BAUD_RATE; | ||
293 | } | ||
294 | |||
295 | ch341_set_baudrate(port->serial->dev, priv); | ||
296 | |||
297 | /* Unimplemented: | ||
298 | * (cflag & CSIZE) : data bits [5, 8] | ||
299 | * (cflag & PARENB) : parity {NONE, EVEN, ODD} | ||
300 | * (cflag & CSTOPB) : stop bits [1, 2] | ||
301 | */ | ||
302 | } | ||
303 | |||
304 | static struct usb_driver ch341_driver = { | ||
305 | .name = "ch341", | ||
306 | .probe = usb_serial_probe, | ||
307 | .disconnect = usb_serial_disconnect, | ||
308 | .id_table = id_table, | ||
309 | .no_dynamic_id = 1, | ||
310 | }; | ||
311 | |||
312 | static struct usb_serial_driver ch341_device = { | ||
313 | .driver = { | ||
314 | .owner = THIS_MODULE, | ||
315 | .name = "ch341-uart", | ||
316 | }, | ||
317 | .id_table = id_table, | ||
318 | .usb_driver = &ch341_driver, | ||
319 | .num_interrupt_in = NUM_DONT_CARE, | ||
320 | .num_bulk_in = 1, | ||
321 | .num_bulk_out = 1, | ||
322 | .num_ports = 1, | ||
323 | .open = ch341_open, | ||
324 | .set_termios = ch341_set_termios, | ||
325 | .attach = ch341_attach, | ||
326 | }; | ||
327 | |||
328 | static int __init ch341_init(void) | ||
329 | { | ||
330 | int retval; | ||
331 | |||
332 | retval = usb_serial_register(&ch341_device); | ||
333 | if (retval) | ||
334 | return retval; | ||
335 | retval = usb_register(&ch341_driver); | ||
336 | if (retval) | ||
337 | usb_serial_deregister(&ch341_device); | ||
338 | return retval; | ||
339 | } | ||
340 | |||
341 | static void __exit ch341_exit(void) | ||
342 | { | ||
343 | usb_deregister(&ch341_driver); | ||
344 | usb_serial_deregister(&ch341_device); | ||
345 | } | ||
346 | |||
347 | module_init(ch341_init); | ||
348 | module_exit(ch341_exit); | ||
349 | MODULE_LICENSE("GPL"); | ||
350 | |||
351 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
352 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
353 | |||
354 | /* EOF ch341.c */ | ||
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 33f6ee50b8d3..eb7df1835c11 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -53,6 +53,7 @@ static void cp2101_shutdown(struct usb_serial*); | |||
53 | static int debug; | 53 | static int debug; |
54 | 54 | ||
55 | static struct usb_device_id id_table [] = { | 55 | static struct usb_device_id id_table [] = { |
56 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ | ||
56 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ | 57 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ |
57 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ | 58 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ |
58 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 59 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
@@ -521,7 +522,7 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
521 | 522 | ||
522 | dbg("%s - port %d", __FUNCTION__, port->number); | 523 | dbg("%s - port %d", __FUNCTION__, port->number); |
523 | 524 | ||
524 | if ((!port->tty) || (!port->tty->termios)) { | 525 | if (!port->tty || !port->tty->termios) { |
525 | dbg("%s - no tty structures", __FUNCTION__); | 526 | dbg("%s - no tty structures", __FUNCTION__); |
526 | return; | 527 | return; |
527 | } | 528 | } |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 2d045857b181..e4c248c98e84 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1169,7 +1169,9 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) | |||
1169 | /* XXX see create_sysfs_attrs */ | 1169 | /* XXX see create_sysfs_attrs */ |
1170 | if (priv->chip_type != SIO) { | 1170 | if (priv->chip_type != SIO) { |
1171 | device_remove_file(&port->dev, &dev_attr_event_char); | 1171 | device_remove_file(&port->dev, &dev_attr_event_char); |
1172 | if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) { | 1172 | if (priv->chip_type == FT232BM || |
1173 | priv->chip_type == FT2232C || | ||
1174 | priv->chip_type == FT232RL) { | ||
1173 | device_remove_file(&port->dev, &dev_attr_latency_timer); | 1175 | device_remove_file(&port->dev, &dev_attr_latency_timer); |
1174 | } | 1176 | } |
1175 | } | 1177 | } |
@@ -2102,6 +2104,7 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) | |||
2102 | case FT8U232AM: | 2104 | case FT8U232AM: |
2103 | case FT232BM: | 2105 | case FT232BM: |
2104 | case FT2232C: | 2106 | case FT2232C: |
2107 | case FT232RL: | ||
2105 | /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same | 2108 | /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same |
2106 | format as the data returned from the in point */ | 2109 | format as the data returned from the in point */ |
2107 | if ((ret = usb_control_msg(port->serial->dev, | 2110 | if ((ret = usb_control_msg(port->serial->dev, |
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index 4092f6dc9efd..b5194dc7d3bb 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c | |||
@@ -24,26 +24,6 @@ static struct usb_device_id id_table [] = { | |||
24 | }; | 24 | }; |
25 | MODULE_DEVICE_TABLE(usb, id_table); | 25 | MODULE_DEVICE_TABLE(usb, id_table); |
26 | 26 | ||
27 | static int funsoft_ioctl(struct usb_serial_port *port, struct file *file, | ||
28 | unsigned int cmd, unsigned long arg) | ||
29 | { | ||
30 | struct ktermios t; | ||
31 | |||
32 | dbg("%s - port %d, cmd 0x%04x", __FUNCTION__, port->number, cmd); | ||
33 | |||
34 | if (cmd == TCSETSF) { | ||
35 | if (user_termios_to_kernel_termios(&t, (struct termios __user *)arg)) | ||
36 | return -EFAULT; | ||
37 | |||
38 | dbg("%s - iflag:%x oflag:%x cflag:%x lflag:%x", __FUNCTION__, | ||
39 | t.c_iflag, t.c_oflag, t.c_cflag, t.c_lflag); | ||
40 | |||
41 | if (!(t.c_lflag & ICANON)) | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | return -ENOIOCTLCMD; | ||
45 | } | ||
46 | |||
47 | static struct usb_driver funsoft_driver = { | 27 | static struct usb_driver funsoft_driver = { |
48 | .name = "funsoft", | 28 | .name = "funsoft", |
49 | .probe = usb_serial_probe, | 29 | .probe = usb_serial_probe, |
@@ -63,7 +43,6 @@ static struct usb_serial_driver funsoft_device = { | |||
63 | .num_bulk_in = NUM_DONT_CARE, | 43 | .num_bulk_in = NUM_DONT_CARE, |
64 | .num_bulk_out = NUM_DONT_CARE, | 44 | .num_bulk_out = NUM_DONT_CARE, |
65 | .num_ports = 1, | 45 | .num_ports = 1, |
66 | .ioctl = funsoft_ioctl, | ||
67 | }; | 46 | }; |
68 | 47 | ||
69 | static int __init funsoft_init(void) | 48 | static int __init funsoft_init(void) |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 6a3a704b5849..e836ad07fdb9 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -256,6 +256,7 @@ static struct usb_device_id ipaq_id_table [] = { | |||
256 | { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */ | 256 | { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */ |
257 | { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */ | 257 | { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */ |
258 | { USB_DEVICE(0x04DD, 0x9151) }, /* SHARP S01SH USB Modem */ | 258 | { USB_DEVICE(0x04DD, 0x9151) }, /* SHARP S01SH USB Modem */ |
259 | { USB_DEVICE(0x04DD, 0x91AC) }, /* SHARP WS011SH USB Modem */ | ||
259 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ | 260 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ |
260 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ | 261 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ |
261 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ | 262 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ |
@@ -646,11 +647,13 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) | |||
646 | kfree(port->bulk_out_buffer); | 647 | kfree(port->bulk_out_buffer); |
647 | port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); | 648 | port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); |
648 | if (port->bulk_in_buffer == NULL) { | 649 | if (port->bulk_in_buffer == NULL) { |
650 | port->bulk_out_buffer = NULL; /* prevent double free */ | ||
649 | goto enomem; | 651 | goto enomem; |
650 | } | 652 | } |
651 | port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); | 653 | port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); |
652 | if (port->bulk_out_buffer == NULL) { | 654 | if (port->bulk_out_buffer == NULL) { |
653 | kfree(port->bulk_in_buffer); | 655 | kfree(port->bulk_in_buffer); |
656 | port->bulk_in_buffer = NULL; | ||
654 | goto enomem; | 657 | goto enomem; |
655 | } | 658 | } |
656 | port->read_urb->transfer_buffer = port->bulk_in_buffer; | 659 | port->read_urb->transfer_buffer = port->bulk_in_buffer; |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 5a4127e62c4a..90e3216abd1f 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -728,24 +728,32 @@ static void klsi_105_set_termios (struct usb_serial_port *port, | |||
728 | #endif | 728 | #endif |
729 | } | 729 | } |
730 | 730 | ||
731 | switch(cflag & CBAUD) { | 731 | switch(tty_get_baud_rate(port->tty)) { |
732 | case B0: /* handled below */ | 732 | case 0: /* handled below */ |
733 | break; | 733 | break; |
734 | case B1200: priv->cfg.baudrate = kl5kusb105a_sio_b1200; | 734 | case 1200: |
735 | priv->cfg.baudrate = kl5kusb105a_sio_b1200; | ||
735 | break; | 736 | break; |
736 | case B2400: priv->cfg.baudrate = kl5kusb105a_sio_b2400; | 737 | case 2400: |
738 | priv->cfg.baudrate = kl5kusb105a_sio_b2400; | ||
737 | break; | 739 | break; |
738 | case B4800: priv->cfg.baudrate = kl5kusb105a_sio_b4800; | 740 | case 4800: |
741 | priv->cfg.baudrate = kl5kusb105a_sio_b4800; | ||
739 | break; | 742 | break; |
740 | case B9600: priv->cfg.baudrate = kl5kusb105a_sio_b9600; | 743 | case 9600: |
744 | priv->cfg.baudrate = kl5kusb105a_sio_b9600; | ||
741 | break; | 745 | break; |
742 | case B19200: priv->cfg.baudrate = kl5kusb105a_sio_b19200; | 746 | case 19200: |
747 | priv->cfg.baudrate = kl5kusb105a_sio_b19200; | ||
743 | break; | 748 | break; |
744 | case B38400: priv->cfg.baudrate = kl5kusb105a_sio_b38400; | 749 | case 38400: |
750 | priv->cfg.baudrate = kl5kusb105a_sio_b38400; | ||
745 | break; | 751 | break; |
746 | case B57600: priv->cfg.baudrate = kl5kusb105a_sio_b57600; | 752 | case 57600: |
753 | priv->cfg.baudrate = kl5kusb105a_sio_b57600; | ||
747 | break; | 754 | break; |
748 | case B115200: priv->cfg.baudrate = kl5kusb105a_sio_b115200; | 755 | case 115200: |
756 | priv->cfg.baudrate = kl5kusb105a_sio_b115200; | ||
749 | break; | 757 | break; |
750 | default: | 758 | default: |
751 | err("KLSI USB->Serial converter:" | 759 | err("KLSI USB->Serial converter:" |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 02a86dbc0e97..6f224195bd25 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -82,6 +82,7 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, | |||
82 | unsigned int set, unsigned int clear); | 82 | unsigned int set, unsigned int clear); |
83 | static void kobil_read_int_callback( struct urb *urb ); | 83 | static void kobil_read_int_callback( struct urb *urb ); |
84 | static void kobil_write_callback( struct urb *purb ); | 84 | static void kobil_write_callback( struct urb *purb ); |
85 | static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old); | ||
85 | 86 | ||
86 | 87 | ||
87 | static struct usb_device_id id_table [] = { | 88 | static struct usb_device_id id_table [] = { |
@@ -119,6 +120,7 @@ static struct usb_serial_driver kobil_device = { | |||
119 | .attach = kobil_startup, | 120 | .attach = kobil_startup, |
120 | .shutdown = kobil_shutdown, | 121 | .shutdown = kobil_shutdown, |
121 | .ioctl = kobil_ioctl, | 122 | .ioctl = kobil_ioctl, |
123 | .set_termios = kobil_set_termios, | ||
122 | .tiocmget = kobil_tiocmget, | 124 | .tiocmget = kobil_tiocmget, |
123 | .tiocmset = kobil_tiocmset, | 125 | .tiocmset = kobil_tiocmset, |
124 | .open = kobil_open, | 126 | .open = kobil_open, |
@@ -137,7 +139,6 @@ struct kobil_private { | |||
137 | int cur_pos; // index of the next char to send in buf | 139 | int cur_pos; // index of the next char to send in buf |
138 | __u16 device_type; | 140 | __u16 device_type; |
139 | int line_state; | 141 | int line_state; |
140 | struct ktermios internal_termios; | ||
141 | }; | 142 | }; |
142 | 143 | ||
143 | 144 | ||
@@ -216,7 +217,7 @@ static void kobil_shutdown (struct usb_serial *serial) | |||
216 | 217 | ||
217 | static int kobil_open (struct usb_serial_port *port, struct file *filp) | 218 | static int kobil_open (struct usb_serial_port *port, struct file *filp) |
218 | { | 219 | { |
219 | int i, result = 0; | 220 | int result = 0; |
220 | struct kobil_private *priv; | 221 | struct kobil_private *priv; |
221 | unsigned char *transfer_buffer; | 222 | unsigned char *transfer_buffer; |
222 | int transfer_buffer_length = 8; | 223 | int transfer_buffer_length = 8; |
@@ -242,16 +243,6 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) | |||
242 | port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; | 243 | port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; |
243 | port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) | 244 | port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) |
244 | 245 | ||
245 | // set up internal termios structure | ||
246 | priv->internal_termios.c_iflag = port->tty->termios->c_iflag; | ||
247 | priv->internal_termios.c_oflag = port->tty->termios->c_oflag; | ||
248 | priv->internal_termios.c_cflag = port->tty->termios->c_cflag; | ||
249 | priv->internal_termios.c_lflag = port->tty->termios->c_lflag; | ||
250 | |||
251 | for (i=0; i<NCCS; i++) { | ||
252 | priv->internal_termios.c_cc[i] = port->tty->termios->c_cc[i]; | ||
253 | } | ||
254 | |||
255 | // allocate memory for transfer buffer | 246 | // allocate memory for transfer buffer |
256 | transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); | 247 | transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); |
257 | if (! transfer_buffer) { | 248 | if (! transfer_buffer) { |
@@ -607,102 +598,79 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, | |||
607 | return (result < 0) ? result : 0; | 598 | return (result < 0) ? result : 0; |
608 | } | 599 | } |
609 | 600 | ||
610 | 601 | static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old) | |
611 | static int kobil_ioctl(struct usb_serial_port *port, struct file *file, | ||
612 | unsigned int cmd, unsigned long arg) | ||
613 | { | 602 | { |
614 | struct kobil_private * priv; | 603 | struct kobil_private * priv; |
615 | int result; | 604 | int result; |
616 | unsigned short urb_val = 0; | 605 | unsigned short urb_val = 0; |
617 | unsigned char *transfer_buffer; | 606 | int c_cflag = port->tty->termios->c_cflag; |
618 | int transfer_buffer_length = 8; | 607 | speed_t speed; |
619 | char *settings; | 608 | void * settings; |
620 | void __user *user_arg = (void __user *)arg; | ||
621 | 609 | ||
622 | priv = usb_get_serial_port_data(port); | 610 | priv = usb_get_serial_port_data(port); |
623 | if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { | 611 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) |
624 | // This device doesn't support ioctl calls | 612 | // This device doesn't support ioctl calls |
625 | return 0; | 613 | return; |
626 | } | ||
627 | |||
628 | switch (cmd) { | ||
629 | case TCGETS: // 0x5401 | ||
630 | if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct ktermios))) { | ||
631 | dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); | ||
632 | return -EFAULT; | ||
633 | } | ||
634 | if (kernel_termios_to_user_termios((struct ktermios __user *)arg, | ||
635 | &priv->internal_termios)) | ||
636 | return -EFAULT; | ||
637 | return 0; | ||
638 | |||
639 | case TCSETS: // 0x5402 | ||
640 | if (!(port->tty->termios)) { | ||
641 | dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number); | ||
642 | return -ENOTTY; | ||
643 | } | ||
644 | if (!access_ok(VERIFY_READ, user_arg, sizeof(struct ktermios))) { | ||
645 | dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); | ||
646 | return -EFAULT; | ||
647 | } | ||
648 | if (user_termios_to_kernel_termios(&priv->internal_termios, | ||
649 | (struct ktermios __user *)arg)) | ||
650 | return -EFAULT; | ||
651 | |||
652 | settings = kzalloc(50, GFP_KERNEL); | ||
653 | if (! settings) { | ||
654 | return -ENOBUFS; | ||
655 | } | ||
656 | 614 | ||
657 | switch (priv->internal_termios.c_cflag & CBAUD) { | 615 | switch (speed = tty_get_baud_rate(port->tty)) { |
658 | case B1200: | 616 | case 1200: |
659 | urb_val = SUSBCR_SBR_1200; | 617 | urb_val = SUSBCR_SBR_1200; |
660 | strcat(settings, "1200 "); | ||
661 | break; | 618 | break; |
662 | case B9600: | 619 | case 9600: |
663 | default: | 620 | default: |
664 | urb_val = SUSBCR_SBR_9600; | 621 | urb_val = SUSBCR_SBR_9600; |
665 | strcat(settings, "9600 "); | ||
666 | break; | 622 | break; |
667 | } | 623 | } |
624 | urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; | ||
625 | |||
626 | settings = kzalloc(50, GFP_KERNEL); | ||
627 | if (! settings) | ||
628 | return; | ||
668 | 629 | ||
669 | urb_val |= (priv->internal_termios.c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; | 630 | sprintf(settings, "%d ", speed); |
670 | strcat(settings, (priv->internal_termios.c_cflag & CSTOPB) ? "2 StopBits " : "1 StopBit "); | ||
671 | 631 | ||
672 | if (priv->internal_termios.c_cflag & PARENB) { | 632 | if (c_cflag & PARENB) { |
673 | if (priv->internal_termios.c_cflag & PARODD) { | 633 | if (c_cflag & PARODD) { |
674 | urb_val |= SUSBCR_SPASB_OddParity; | 634 | urb_val |= SUSBCR_SPASB_OddParity; |
675 | strcat(settings, "Odd Parity"); | 635 | strcat(settings, "Odd Parity"); |
676 | } else { | ||
677 | urb_val |= SUSBCR_SPASB_EvenParity; | ||
678 | strcat(settings, "Even Parity"); | ||
679 | } | ||
680 | } else { | 636 | } else { |
681 | urb_val |= SUSBCR_SPASB_NoParity; | 637 | urb_val |= SUSBCR_SPASB_EvenParity; |
682 | strcat(settings, "No Parity"); | 638 | strcat(settings, "Even Parity"); |
683 | } | 639 | } |
684 | dbg("%s - port %d setting port to: %s", __FUNCTION__, port->number, settings ); | 640 | } else { |
641 | urb_val |= SUSBCR_SPASB_NoParity; | ||
642 | strcat(settings, "No Parity"); | ||
643 | } | ||
685 | 644 | ||
686 | result = usb_control_msg( port->serial->dev, | 645 | result = usb_control_msg( port->serial->dev, |
687 | usb_rcvctrlpipe(port->serial->dev, 0 ), | 646 | usb_rcvctrlpipe(port->serial->dev, 0 ), |
688 | SUSBCRequest_SetBaudRateParityAndStopBits, | 647 | SUSBCRequest_SetBaudRateParityAndStopBits, |
689 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, | 648 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
690 | urb_val, | 649 | urb_val, |
691 | 0, | 650 | 0, |
692 | settings, | 651 | settings, |
693 | 0, | 652 | 0, |
694 | KOBIL_TIMEOUT | 653 | KOBIL_TIMEOUT |
695 | ); | 654 | ); |
655 | kfree(settings); | ||
656 | } | ||
696 | 657 | ||
697 | dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result); | 658 | static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) |
698 | kfree(settings); | 659 | { |
660 | struct kobil_private * priv = usb_get_serial_port_data(port); | ||
661 | unsigned char *transfer_buffer; | ||
662 | int transfer_buffer_length = 8; | ||
663 | int result; | ||
664 | |||
665 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) | ||
666 | // This device doesn't support ioctl calls | ||
699 | return 0; | 667 | return 0; |
700 | 668 | ||
669 | switch (cmd) { | ||
701 | case TCFLSH: // 0x540B | 670 | case TCFLSH: // 0x540B |
702 | transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); | 671 | transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); |
703 | if (! transfer_buffer) { | 672 | if (! transfer_buffer) |
704 | return -ENOBUFS; | 673 | return -ENOBUFS; |
705 | } | ||
706 | 674 | ||
707 | result = usb_control_msg( port->serial->dev, | 675 | result = usb_control_msg( port->serial->dev, |
708 | usb_rcvctrlpipe(port->serial->dev, 0 ), | 676 | usb_rcvctrlpipe(port->serial->dev, 0 ), |
@@ -716,15 +684,13 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file, | |||
716 | ); | 684 | ); |
717 | 685 | ||
718 | dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result); | 686 | dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result); |
719 | |||
720 | kfree(transfer_buffer); | 687 | kfree(transfer_buffer); |
721 | return ((result < 0) ? -EFAULT : 0); | 688 | return (result < 0) ? -EFAULT : 0; |
722 | 689 | default: | |
690 | return -ENOIOCTLCMD; | ||
723 | } | 691 | } |
724 | return -ENOIOCTLCMD; | ||
725 | } | 692 | } |
726 | 693 | ||
727 | |||
728 | static int __init kobil_init (void) | 694 | static int __init kobil_init (void) |
729 | { | 695 | { |
730 | int retval; | 696 | int retval; |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index e08c9bb403d8..0dc99f75bb09 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -206,20 +206,20 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
206 | } | 206 | } |
207 | } else { | 207 | } else { |
208 | switch (value) { | 208 | switch (value) { |
209 | case 300: break; | 209 | case 300: break; |
210 | case 600: break; | 210 | case 600: break; |
211 | case 1200: break; | 211 | case 1200: break; |
212 | case 2400: break; | 212 | case 2400: break; |
213 | case 4800: break; | 213 | case 4800: break; |
214 | case 9600: break; | 214 | case 9600: break; |
215 | case 19200: break; | 215 | case 19200: break; |
216 | case 38400: break; | 216 | case 38400: break; |
217 | case 57600: break; | 217 | case 57600: break; |
218 | case 115200: break; | 218 | case 115200: break; |
219 | default: | 219 | default: |
220 | err("MCT USB-RS232: unsupported baudrate request 0x%x," | 220 | err("MCT USB-RS232: unsupported baudrate request 0x%x," |
221 | " using default of B9600", value); | 221 | " using default of B9600", value); |
222 | value = 9600; | 222 | value = 9600; |
223 | } | 223 | } |
224 | return 115200/value; | 224 | return 115200/value; |
225 | } | 225 | } |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 64f3f66a7a35..d19861166b50 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -1144,7 +1144,7 @@ static struct pl2303_buf *pl2303_buf_alloc(unsigned int size) | |||
1144 | if (size == 0) | 1144 | if (size == 0) |
1145 | return NULL; | 1145 | return NULL; |
1146 | 1146 | ||
1147 | pb = (struct pl2303_buf *)kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL); | 1147 | pb = kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL); |
1148 | if (pb == NULL) | 1148 | if (pb == NULL) |
1149 | return NULL; | 1149 | return NULL; |
1150 | 1150 | ||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index f9f85f56f0db..1da57fd9ea23 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -73,6 +73,7 @@ static struct usb_device_id id_table [] = { | |||
73 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) }, | 73 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) }, |
74 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, | 74 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, |
75 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, | 75 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, |
76 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81) }, | ||
76 | { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, | 77 | { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, |
77 | { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) }, | 78 | { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) }, |
78 | { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) }, | 79 | { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) }, |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index f9a71d0c102e..c39bace5cbcc 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -59,6 +59,7 @@ | |||
59 | #define SIEMENS_PRODUCT_ID_SX1 0x0001 | 59 | #define SIEMENS_PRODUCT_ID_SX1 0x0001 |
60 | #define SIEMENS_PRODUCT_ID_X65 0x0003 | 60 | #define SIEMENS_PRODUCT_ID_X65 0x0003 |
61 | #define SIEMENS_PRODUCT_ID_X75 0x0004 | 61 | #define SIEMENS_PRODUCT_ID_X75 0x0004 |
62 | #define SIEMENS_PRODUCT_ID_EF81 0x0005 | ||
62 | 63 | ||
63 | #define SYNTECH_VENDOR_ID 0x0745 | 64 | #define SYNTECH_VENDOR_ID 0x0745 |
64 | #define SYNTECH_PRODUCT_ID 0x0001 | 65 | #define SYNTECH_PRODUCT_ID 0x0001 |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 51669b7622bb..4e6dcc199be9 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -90,18 +90,12 @@ MODULE_AUTHOR (DRIVER_AUTHOR); | |||
90 | MODULE_DESCRIPTION (DRIVER_DESC); | 90 | MODULE_DESCRIPTION (DRIVER_DESC); |
91 | MODULE_LICENSE("GPL"); | 91 | MODULE_LICENSE("GPL"); |
92 | 92 | ||
93 | #if defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) && !defined(CONFIG_USBD_SAFE_SERIAL_PRODUCT) | ||
94 | #error "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT" | ||
95 | #endif | ||
96 | |||
97 | #if ! defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) | ||
98 | static __u16 vendor; // no default | 93 | static __u16 vendor; // no default |
99 | static __u16 product; // no default | 94 | static __u16 product; // no default |
100 | module_param(vendor, ushort, 0); | 95 | module_param(vendor, ushort, 0); |
101 | MODULE_PARM_DESC(vendor, "User specified USB idVendor (required)"); | 96 | MODULE_PARM_DESC(vendor, "User specified USB idVendor (required)"); |
102 | module_param(product, ushort, 0); | 97 | module_param(product, ushort, 0); |
103 | MODULE_PARM_DESC(product, "User specified USB idProduct (required)"); | 98 | MODULE_PARM_DESC(product, "User specified USB idProduct (required)"); |
104 | #endif | ||
105 | 99 | ||
106 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 100 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
107 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | 101 | MODULE_PARM_DESC(debug, "Debug enabled or not"); |
@@ -145,11 +139,6 @@ static struct usb_device_id id_table[] = { | |||
145 | {MY_USB_DEVICE (0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie | 139 | {MY_USB_DEVICE (0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie |
146 | {MY_USB_DEVICE (0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie | 140 | {MY_USB_DEVICE (0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie |
147 | {MY_USB_DEVICE (0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Sharp tmp | 141 | {MY_USB_DEVICE (0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Sharp tmp |
148 | #if defined(CONFIG_USB_SAFE_SERIAL_VENDOR) | ||
149 | {MY_USB_DEVICE | ||
150 | (CONFIG_USB_SAFE_SERIAL_VENDOR, CONFIG_USB_SAFE_SERIAL_PRODUCT, CDC_DEVICE_CLASS, | ||
151 | LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, | ||
152 | #endif | ||
153 | // extra null entry for module | 142 | // extra null entry for module |
154 | // vendor/produc parameters | 143 | // vendor/produc parameters |
155 | {MY_USB_DEVICE (0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, | 144 | {MY_USB_DEVICE (0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 9bf01a5efc84..4b1bd7def4a5 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -578,6 +578,17 @@ static void kill_traffic(struct usb_serial_port *port) | |||
578 | { | 578 | { |
579 | usb_kill_urb(port->read_urb); | 579 | usb_kill_urb(port->read_urb); |
580 | usb_kill_urb(port->write_urb); | 580 | usb_kill_urb(port->write_urb); |
581 | /* | ||
582 | * This is tricky. | ||
583 | * Some drivers submit the read_urb in the | ||
584 | * handler for the write_urb or vice versa | ||
585 | * this order determines the order in which | ||
586 | * usb_kill_urb() must be used to reliably | ||
587 | * kill the URBs. As it is unknown here, | ||
588 | * both orders must be used in turn. | ||
589 | * The call below is not redundant. | ||
590 | */ | ||
591 | usb_kill_urb(port->read_urb); | ||
581 | usb_kill_urb(port->interrupt_in_urb); | 592 | usb_kill_urb(port->interrupt_in_urb); |
582 | usb_kill_urb(port->interrupt_out_urb); | 593 | usb_kill_urb(port->interrupt_out_urb); |
583 | } | 594 | } |
@@ -651,16 +662,14 @@ exit: | |||
651 | 662 | ||
652 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) | 663 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) |
653 | { | 664 | { |
654 | struct list_head *p; | ||
655 | const struct usb_device_id *id; | 665 | const struct usb_device_id *id; |
656 | struct usb_serial_driver *t; | 666 | struct usb_serial_driver *drv; |
657 | 667 | ||
658 | /* Check if the usb id matches a known device */ | 668 | /* Check if the usb id matches a known device */ |
659 | list_for_each(p, &usb_serial_driver_list) { | 669 | list_for_each_entry(drv, &usb_serial_driver_list, driver_list) { |
660 | t = list_entry(p, struct usb_serial_driver, driver_list); | 670 | id = get_iface_id(drv, iface); |
661 | id = get_iface_id(t, iface); | ||
662 | if (id) | 671 | if (id) |
663 | return t; | 672 | return drv; |
664 | } | 673 | } |
665 | 674 | ||
666 | return NULL; | 675 | return NULL; |
@@ -800,9 +809,6 @@ int usb_serial_probe(struct usb_interface *interface, | |||
800 | /* END HORRIBLE HACK FOR PL2303 */ | 809 | /* END HORRIBLE HACK FOR PL2303 */ |
801 | #endif | 810 | #endif |
802 | 811 | ||
803 | /* found all that we need */ | ||
804 | dev_info(&interface->dev, "%s converter detected\n", type->description); | ||
805 | |||
806 | #ifdef CONFIG_USB_SERIAL_GENERIC | 812 | #ifdef CONFIG_USB_SERIAL_GENERIC |
807 | if (type == &usb_serial_generic_device) { | 813 | if (type == &usb_serial_generic_device) { |
808 | num_ports = num_bulk_out; | 814 | num_ports = num_bulk_out; |
@@ -836,6 +842,24 @@ int usb_serial_probe(struct usb_interface *interface, | |||
836 | serial->num_interrupt_in = num_interrupt_in; | 842 | serial->num_interrupt_in = num_interrupt_in; |
837 | serial->num_interrupt_out = num_interrupt_out; | 843 | serial->num_interrupt_out = num_interrupt_out; |
838 | 844 | ||
845 | /* check that the device meets the driver's requirements */ | ||
846 | if ((type->num_interrupt_in != NUM_DONT_CARE && | ||
847 | type->num_interrupt_in != num_interrupt_in) | ||
848 | || (type->num_interrupt_out != NUM_DONT_CARE && | ||
849 | type->num_interrupt_out != num_interrupt_out) | ||
850 | || (type->num_bulk_in != NUM_DONT_CARE && | ||
851 | type->num_bulk_in != num_bulk_in) | ||
852 | || (type->num_bulk_out != NUM_DONT_CARE && | ||
853 | type->num_bulk_out != num_bulk_out)) { | ||
854 | dbg("wrong number of endpoints"); | ||
855 | kfree(serial); | ||
856 | return -EIO; | ||
857 | } | ||
858 | |||
859 | /* found all that we need */ | ||
860 | dev_info(&interface->dev, "%s converter detected\n", | ||
861 | type->description); | ||
862 | |||
839 | /* create our ports, we need as many as the max endpoints */ | 863 | /* create our ports, we need as many as the max endpoints */ |
840 | /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ | 864 | /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ |
841 | max_endpoints = max(num_bulk_in, num_bulk_out); | 865 | max_endpoints = max(num_bulk_in, num_bulk_out); |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 30e08c0bcdc2..7ee087fed913 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -46,7 +46,6 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id | |||
46 | static int visor_calc_num_ports(struct usb_serial *serial); | 46 | static int visor_calc_num_ports(struct usb_serial *serial); |
47 | static void visor_shutdown (struct usb_serial *serial); | 47 | static void visor_shutdown (struct usb_serial *serial); |
48 | static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); | 48 | static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); |
49 | static void visor_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); | ||
50 | static void visor_write_bulk_callback (struct urb *urb); | 49 | static void visor_write_bulk_callback (struct urb *urb); |
51 | static void visor_read_bulk_callback (struct urb *urb); | 50 | static void visor_read_bulk_callback (struct urb *urb); |
52 | static void visor_read_int_callback (struct urb *urb); | 51 | static void visor_read_int_callback (struct urb *urb); |
@@ -203,7 +202,6 @@ static struct usb_serial_driver handspring_device = { | |||
203 | .calc_num_ports = visor_calc_num_ports, | 202 | .calc_num_ports = visor_calc_num_ports, |
204 | .shutdown = visor_shutdown, | 203 | .shutdown = visor_shutdown, |
205 | .ioctl = visor_ioctl, | 204 | .ioctl = visor_ioctl, |
206 | .set_termios = visor_set_termios, | ||
207 | .write = visor_write, | 205 | .write = visor_write, |
208 | .write_room = visor_write_room, | 206 | .write_room = visor_write_room, |
209 | .chars_in_buffer = visor_chars_in_buffer, | 207 | .chars_in_buffer = visor_chars_in_buffer, |
@@ -234,7 +232,6 @@ static struct usb_serial_driver clie_5_device = { | |||
234 | .calc_num_ports = visor_calc_num_ports, | 232 | .calc_num_ports = visor_calc_num_ports, |
235 | .shutdown = visor_shutdown, | 233 | .shutdown = visor_shutdown, |
236 | .ioctl = visor_ioctl, | 234 | .ioctl = visor_ioctl, |
237 | .set_termios = visor_set_termios, | ||
238 | .write = visor_write, | 235 | .write = visor_write, |
239 | .write_room = visor_write_room, | 236 | .write_room = visor_write_room, |
240 | .chars_in_buffer = visor_chars_in_buffer, | 237 | .chars_in_buffer = visor_chars_in_buffer, |
@@ -262,7 +259,6 @@ static struct usb_serial_driver clie_3_5_device = { | |||
262 | .unthrottle = visor_unthrottle, | 259 | .unthrottle = visor_unthrottle, |
263 | .attach = clie_3_5_startup, | 260 | .attach = clie_3_5_startup, |
264 | .ioctl = visor_ioctl, | 261 | .ioctl = visor_ioctl, |
265 | .set_termios = visor_set_termios, | ||
266 | .write = visor_write, | 262 | .write = visor_write, |
267 | .write_room = visor_write_room, | 263 | .write_room = visor_write_room, |
268 | .chars_in_buffer = visor_chars_in_buffer, | 264 | .chars_in_buffer = visor_chars_in_buffer, |
@@ -936,66 +932,6 @@ static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsign | |||
936 | return -ENOIOCTLCMD; | 932 | return -ENOIOCTLCMD; |
937 | } | 933 | } |
938 | 934 | ||
939 | |||
940 | /* This function is all nice and good, but we don't change anything based on it :) */ | ||
941 | static void visor_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) | ||
942 | { | ||
943 | unsigned int cflag; | ||
944 | |||
945 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
946 | |||
947 | if ((!port->tty) || (!port->tty->termios)) { | ||
948 | dbg("%s - no tty structures", __FUNCTION__); | ||
949 | return; | ||
950 | } | ||
951 | |||
952 | cflag = port->tty->termios->c_cflag; | ||
953 | |||
954 | /* get the byte size */ | ||
955 | switch (cflag & CSIZE) { | ||
956 | case CS5: dbg("%s - data bits = 5", __FUNCTION__); break; | ||
957 | case CS6: dbg("%s - data bits = 6", __FUNCTION__); break; | ||
958 | case CS7: dbg("%s - data bits = 7", __FUNCTION__); break; | ||
959 | default: | ||
960 | case CS8: dbg("%s - data bits = 8", __FUNCTION__); break; | ||
961 | } | ||
962 | |||
963 | /* determine the parity */ | ||
964 | if (cflag & PARENB) | ||
965 | if (cflag & PARODD) | ||
966 | dbg("%s - parity = odd", __FUNCTION__); | ||
967 | else | ||
968 | dbg("%s - parity = even", __FUNCTION__); | ||
969 | else | ||
970 | dbg("%s - parity = none", __FUNCTION__); | ||
971 | |||
972 | /* figure out the stop bits requested */ | ||
973 | if (cflag & CSTOPB) | ||
974 | dbg("%s - stop bits = 2", __FUNCTION__); | ||
975 | else | ||
976 | dbg("%s - stop bits = 1", __FUNCTION__); | ||
977 | |||
978 | |||
979 | /* figure out the flow control settings */ | ||
980 | if (cflag & CRTSCTS) | ||
981 | dbg("%s - RTS/CTS is enabled", __FUNCTION__); | ||
982 | else | ||
983 | dbg("%s - RTS/CTS is disabled", __FUNCTION__); | ||
984 | |||
985 | /* determine software flow control */ | ||
986 | if (I_IXOFF(port->tty)) | ||
987 | dbg("%s - XON/XOFF is enabled, XON = %2x, XOFF = %2x", | ||
988 | __FUNCTION__, START_CHAR(port->tty), STOP_CHAR(port->tty)); | ||
989 | else | ||
990 | dbg("%s - XON/XOFF is disabled", __FUNCTION__); | ||
991 | |||
992 | /* get the baud rate wanted */ | ||
993 | dbg("%s - baud rate = %d", __FUNCTION__, tty_get_baud_rate(port->tty)); | ||
994 | |||
995 | return; | ||
996 | } | ||
997 | |||
998 | |||
999 | static int __init visor_init (void) | 935 | static int __init visor_init (void) |
1000 | { | 936 | { |
1001 | int i, retval; | 937 | int i, retval; |
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 3a41740cad97..ee5b42aa5363 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c | |||
@@ -90,3 +90,17 @@ int usb_stor_ucr61s2b_init(struct us_data *us) | |||
90 | 90 | ||
91 | return (res ? -1 : 0); | 91 | return (res ? -1 : 0); |
92 | } | 92 | } |
93 | |||
94 | /* This places the HUAWEI E220 devices in multi-port mode */ | ||
95 | int usb_stor_huawei_e220_init(struct us_data *us) | ||
96 | { | ||
97 | int result; | ||
98 | |||
99 | us->iobuf[0] = 0x1; | ||
100 | result = usb_stor_control_msg(us, us->send_ctrl_pipe, | ||
101 | USB_REQ_SET_FEATURE, | ||
102 | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | ||
103 | 0x01, 0x0, us->iobuf, 0x1, 1000); | ||
104 | US_DEBUGP("usb_control_msg performing result is %d\n", result); | ||
105 | return (result ? 0 : -1); | ||
106 | } | ||
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index e2967a4d48a2..ad3ffd4236c2 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h | |||
@@ -47,3 +47,6 @@ int usb_stor_euscsi_init(struct us_data *us); | |||
47 | /* This function is required to activate all four slots on the UCR-61S2B | 47 | /* This function is required to activate all four slots on the UCR-61S2B |
48 | * flash reader */ | 48 | * flash reader */ |
49 | int usb_stor_ucr61s2b_init(struct us_data *us); | 49 | int usb_stor_ucr61s2b_init(struct us_data *us); |
50 | |||
51 | /* This places the HUAWEI E220 devices in multi-port mode */ | ||
52 | int usb_stor_huawei_e220_init(struct us_data *us); | ||
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 5e27297c0175..17ca4d73577b 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -190,9 +190,6 @@ static int usbat_check_status(struct us_data *us) | |||
190 | unsigned char *reply = us->iobuf; | 190 | unsigned char *reply = us->iobuf; |
191 | int rc; | 191 | int rc; |
192 | 192 | ||
193 | if (!us) | ||
194 | return USB_STOR_TRANSPORT_ERROR; | ||
195 | |||
196 | rc = usbat_get_status(us, reply); | 193 | rc = usbat_get_status(us, reply); |
197 | if (rc != USB_STOR_XFER_GOOD) | 194 | if (rc != USB_STOR_XFER_GOOD) |
198 | return USB_STOR_TRANSPORT_FAILED; | 195 | return USB_STOR_TRANSPORT_FAILED; |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index c6b78ba815ea..9b656ec427d0 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -198,7 +198,7 @@ UNUSUAL_DEV( 0x0421, 0x044e, 0x0100, 0x0100, | |||
198 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), | 198 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), |
199 | 199 | ||
200 | /* Reported by Bardur Arantsson <bardur@scientician.net> */ | 200 | /* Reported by Bardur Arantsson <bardur@scientician.net> */ |
201 | UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0370, | 201 | UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0610, |
202 | "Nokia", | 202 | "Nokia", |
203 | "6131", | 203 | "6131", |
204 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 204 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
@@ -341,6 +341,13 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100, | |||
341 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 341 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
342 | US_FL_FIX_CAPACITY), | 342 | US_FL_FIX_CAPACITY), |
343 | 343 | ||
344 | /* Reported by Graber and Mike Pagano <mpagano-kernel@mpagano.com> */ | ||
345 | UNUSUAL_DEV( 0x04b0, 0x040f, 0x0200, 0x0200, | ||
346 | "NIKON", | ||
347 | "NIKON DSC D200", | ||
348 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
349 | US_FL_FIX_CAPACITY), | ||
350 | |||
344 | /* Reported by Emil Larsson <emil@swip.net> */ | 351 | /* Reported by Emil Larsson <emil@swip.net> */ |
345 | UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, | 352 | UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, |
346 | "NIKON", | 353 | "NIKON", |
@@ -355,6 +362,20 @@ UNUSUAL_DEV( 0x04b0, 0x0413, 0x0110, 0x0110, | |||
355 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 362 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
356 | US_FL_FIX_CAPACITY), | 363 | US_FL_FIX_CAPACITY), |
357 | 364 | ||
365 | /* Reported by Paul Check <paul@openstreet.com> */ | ||
366 | UNUSUAL_DEV( 0x04b0, 0x0415, 0x0100, 0x0100, | ||
367 | "NIKON", | ||
368 | "NIKON DSC D2Xs", | ||
369 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
370 | US_FL_FIX_CAPACITY), | ||
371 | |||
372 | /* Reported by Shan Destromp (shansan@gmail.com) */ | ||
373 | UNUSUAL_DEV( 0x04b0, 0x0417, 0x0100, 0x0100, | ||
374 | "NIKON", | ||
375 | "NIKON DSC D40X", | ||
376 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
377 | US_FL_FIX_CAPACITY), | ||
378 | |||
358 | /* BENQ DC5330 | 379 | /* BENQ DC5330 |
359 | * Reported by Manuel Fombuena <mfombuena@ya.com> and | 380 | * Reported by Manuel Fombuena <mfombuena@ya.com> and |
360 | * Frank Copeland <fjc@thingy.apana.org.au> */ | 381 | * Frank Copeland <fjc@thingy.apana.org.au> */ |
@@ -1463,6 +1484,17 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, | |||
1463 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1484 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1464 | US_FL_IGNORE_RESIDUE ), | 1485 | US_FL_IGNORE_RESIDUE ), |
1465 | 1486 | ||
1487 | /* Reported by fangxiaozhi <fangxiaozhi60675@huawei.com> | ||
1488 | * and by linlei <linlei83@huawei.com> | ||
1489 | * Patch reworked by Johann Wilhelm <johann.wilhelm@student.tugraz.at> | ||
1490 | * This brings the HUAWEI E220 devices into multi-port mode | ||
1491 | */ | ||
1492 | UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, | ||
1493 | "HUAWEI MOBILE", | ||
1494 | "Mass Storage", | ||
1495 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1496 | 0), | ||
1497 | |||
1466 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ | 1498 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ |
1467 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, | 1499 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, |
1468 | "Minolta", | 1500 | "Minolta", |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 59181667066c..3451e8d03ab0 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -960,6 +960,10 @@ static int storage_probe(struct usb_interface *intf, | |||
960 | return -ENOMEM; | 960 | return -ENOMEM; |
961 | } | 961 | } |
962 | 962 | ||
963 | /* | ||
964 | * Allow 16-byte CDBs and thus > 2TB | ||
965 | */ | ||
966 | host->max_cmd_len = 16; | ||
963 | us = host_to_us(host); | 967 | us = host_to_us(host); |
964 | memset(us, 0, sizeof(struct us_data)); | 968 | memset(us, 0, sizeof(struct us_data)); |
965 | mutex_init(&(us->dev_mutex)); | 969 | mutex_init(&(us->dev_mutex)); |
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 8de11deb5d14..c815a40e167f 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -125,6 +125,7 @@ static int skel_open(struct inode *inode, struct file *file) | |||
125 | 125 | ||
126 | /* save our object in the file's private structure */ | 126 | /* save our object in the file's private structure */ |
127 | file->private_data = dev; | 127 | file->private_data = dev; |
128 | mutex_unlock(&dev->io_mutex); | ||
128 | 129 | ||
129 | exit: | 130 | exit: |
130 | return retval; | 131 | return retval; |
diff --git a/drivers/video/output.c b/drivers/video/output.c index 1473f2c892d2..f2df5519c9c4 100644 --- a/drivers/video/output.c +++ b/drivers/video/output.c | |||
@@ -31,7 +31,8 @@ MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction"); | |||
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); | 32 | MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); |
33 | 33 | ||
34 | static ssize_t video_output_show_state(struct class_device *dev,char *buf) | 34 | static ssize_t video_output_show_state(struct device *dev, |
35 | struct device_attribute *attr, char *buf) | ||
35 | { | 36 | { |
36 | ssize_t ret_size = 0; | 37 | ssize_t ret_size = 0; |
37 | struct output_device *od = to_output_device(dev); | 38 | struct output_device *od = to_output_device(dev); |
@@ -40,8 +41,9 @@ static ssize_t video_output_show_state(struct class_device *dev,char *buf) | |||
40 | return ret_size; | 41 | return ret_size; |
41 | } | 42 | } |
42 | 43 | ||
43 | static ssize_t video_output_store_state(struct class_device *dev, | 44 | static ssize_t video_output_store_state(struct device *dev, |
44 | const char *buf,size_t count) | 45 | struct device_attribute *attr, |
46 | const char *buf,size_t count) | ||
45 | { | 47 | { |
46 | char *endp; | 48 | char *endp; |
47 | struct output_device *od = to_output_device(dev); | 49 | struct output_device *od = to_output_device(dev); |
@@ -60,21 +62,22 @@ static ssize_t video_output_store_state(struct class_device *dev, | |||
60 | return count; | 62 | return count; |
61 | } | 63 | } |
62 | 64 | ||
63 | static void video_output_class_release(struct class_device *dev) | 65 | static void video_output_release(struct device *dev) |
64 | { | 66 | { |
65 | struct output_device *od = to_output_device(dev); | 67 | struct output_device *od = to_output_device(dev); |
66 | kfree(od); | 68 | kfree(od); |
67 | } | 69 | } |
68 | 70 | ||
69 | static struct class_device_attribute video_output_attributes[] = { | 71 | static struct device_attribute video_output_attributes[] = { |
70 | __ATTR(state, 0644, video_output_show_state, video_output_store_state), | 72 | __ATTR(state, 0644, video_output_show_state, video_output_store_state), |
71 | __ATTR_NULL, | 73 | __ATTR_NULL, |
72 | }; | 74 | }; |
73 | 75 | ||
76 | |||
74 | static struct class video_output_class = { | 77 | static struct class video_output_class = { |
75 | .name = "video_output", | 78 | .name = "video_output", |
76 | .release = video_output_class_release, | 79 | .dev_release = video_output_release, |
77 | .class_dev_attrs = video_output_attributes, | 80 | .dev_attrs = video_output_attributes, |
78 | }; | 81 | }; |
79 | 82 | ||
80 | struct output_device *video_output_register(const char *name, | 83 | struct output_device *video_output_register(const char *name, |
@@ -91,11 +94,11 @@ struct output_device *video_output_register(const char *name, | |||
91 | goto error_return; | 94 | goto error_return; |
92 | } | 95 | } |
93 | new_dev->props = op; | 96 | new_dev->props = op; |
94 | new_dev->class_dev.class = &video_output_class; | 97 | new_dev->dev.class = &video_output_class; |
95 | new_dev->class_dev.dev = dev; | 98 | new_dev->dev.parent = dev; |
96 | strlcpy(new_dev->class_dev.class_id,name,KOBJ_NAME_LEN); | 99 | strlcpy(new_dev->dev.bus_id,name, BUS_ID_SIZE); |
97 | class_set_devdata(&new_dev->class_dev,devdata); | 100 | dev_set_drvdata(&new_dev->dev, devdata); |
98 | ret_code = class_device_register(&new_dev->class_dev); | 101 | ret_code = device_register(&new_dev->dev); |
99 | if (ret_code) { | 102 | if (ret_code) { |
100 | kfree(new_dev); | 103 | kfree(new_dev); |
101 | goto error_return; | 104 | goto error_return; |
@@ -111,7 +114,7 @@ void video_output_unregister(struct output_device *dev) | |||
111 | { | 114 | { |
112 | if (!dev) | 115 | if (!dev) |
113 | return; | 116 | return; |
114 | class_device_unregister(&dev->class_dev); | 117 | device_unregister(&dev->dev); |
115 | } | 118 | } |
116 | EXPORT_SYMBOL(video_output_unregister); | 119 | EXPORT_SYMBOL(video_output_unregister); |
117 | 120 | ||
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index a593f900eff4..070217322c9f 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -197,7 +197,7 @@ static struct w1_family w1_default_family = { | |||
197 | .fops = &w1_default_fops, | 197 | .fops = &w1_default_fops, |
198 | }; | 198 | }; |
199 | 199 | ||
200 | static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); | 200 | static int w1_uevent(struct device *dev, struct kobj_uevent_env *env); |
201 | 201 | ||
202 | static struct bus_type w1_bus_type = { | 202 | static struct bus_type w1_bus_type = { |
203 | .name = "w1", | 203 | .name = "w1", |
@@ -396,13 +396,12 @@ static void w1_destroy_master_attributes(struct w1_master *master) | |||
396 | } | 396 | } |
397 | 397 | ||
398 | #ifdef CONFIG_HOTPLUG | 398 | #ifdef CONFIG_HOTPLUG |
399 | static int w1_uevent(struct device *dev, char **envp, int num_envp, | 399 | static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) |
400 | char *buffer, int buffer_size) | ||
401 | { | 400 | { |
402 | struct w1_master *md = NULL; | 401 | struct w1_master *md = NULL; |
403 | struct w1_slave *sl = NULL; | 402 | struct w1_slave *sl = NULL; |
404 | char *event_owner, *name; | 403 | char *event_owner, *name; |
405 | int err, cur_index=0, cur_len=0; | 404 | int err; |
406 | 405 | ||
407 | if (dev->driver == &w1_master_driver) { | 406 | if (dev->driver == &w1_master_driver) { |
408 | md = container_of(dev, struct w1_master, dev); | 407 | md = container_of(dev, struct w1_master, dev); |
@@ -423,23 +422,19 @@ static int w1_uevent(struct device *dev, char **envp, int num_envp, | |||
423 | if (dev->driver != &w1_slave_driver || !sl) | 422 | if (dev->driver != &w1_slave_driver || !sl) |
424 | return 0; | 423 | return 0; |
425 | 424 | ||
426 | err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, | 425 | err = add_uevent_var(env, "W1_FID=%02X", sl->reg_num.family); |
427 | &cur_len, "W1_FID=%02X", sl->reg_num.family); | ||
428 | if (err) | 426 | if (err) |
429 | return err; | 427 | return err; |
430 | 428 | ||
431 | err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, | 429 | err = add_uevent_var(env, "W1_SLAVE_ID=%024LX", |
432 | &cur_len, "W1_SLAVE_ID=%024LX", | 430 | (unsigned long long)sl->reg_num.id); |
433 | (unsigned long long)sl->reg_num.id); | ||
434 | envp[cur_index] = NULL; | ||
435 | if (err) | 431 | if (err) |
436 | return err; | 432 | return err; |
437 | 433 | ||
438 | return 0; | 434 | return 0; |
439 | }; | 435 | }; |
440 | #else | 436 | #else |
441 | static int w1_uevent(struct device *dev, char **envp, int num_envp, | 437 | static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) |
442 | char *buffer, int buffer_size) | ||
443 | { | 438 | { |
444 | return 0; | 439 | return 0; |
445 | } | 440 | } |