diff options
Diffstat (limited to 'drivers')
65 files changed, 1951 insertions, 877 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 48718b7f4fa0..76656acd00d4 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
188 | up(&dev->sem); | 188 | up(&dev->sem); |
189 | if (dev->parent) | 189 | if (dev->parent) |
190 | up(&dev->parent->sem); | 190 | up(&dev->parent->sem); |
191 | |||
192 | if (err > 0) /* success */ | ||
193 | err = count; | ||
194 | else if (err == 0) /* driver didn't accept device */ | ||
195 | err = -ENODEV; | ||
191 | } | 196 | } |
192 | put_device(dev); | 197 | put_device(dev); |
193 | put_bus(bus); | 198 | put_bus(bus); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index df7fdabd0730..0e71dff327cd 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -562,14 +562,13 @@ int class_device_add(struct class_device *class_dev) | |||
562 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); | 562 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); |
563 | 563 | ||
564 | /* notify any interfaces this device is now here */ | 564 | /* notify any interfaces this device is now here */ |
565 | if (parent_class) { | 565 | down(&parent_class->sem); |
566 | down(&parent_class->sem); | 566 | list_add_tail(&class_dev->node, &parent_class->children); |
567 | list_add_tail(&class_dev->node, &parent_class->children); | 567 | list_for_each_entry(class_intf, &parent_class->interfaces, node) { |
568 | list_for_each_entry(class_intf, &parent_class->interfaces, node) | 568 | if (class_intf->add) |
569 | if (class_intf->add) | 569 | class_intf->add(class_dev, class_intf); |
570 | class_intf->add(class_dev, class_intf); | ||
571 | up(&parent_class->sem); | ||
572 | } | 570 | } |
571 | up(&parent_class->sem); | ||
573 | 572 | ||
574 | register_done: | 573 | register_done: |
575 | if (error) { | 574 | if (error) { |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 730a9ce0a14a..889c71111239 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -209,7 +209,7 @@ static void __device_release_driver(struct device * dev) | |||
209 | sysfs_remove_link(&dev->kobj, "driver"); | 209 | sysfs_remove_link(&dev->kobj, "driver"); |
210 | klist_remove(&dev->knode_driver); | 210 | klist_remove(&dev->knode_driver); |
211 | 211 | ||
212 | if (dev->bus->remove) | 212 | if (dev->bus && dev->bus->remove) |
213 | dev->bus->remove(dev); | 213 | dev->bus->remove(dev); |
214 | else if (drv->remove) | 214 | else if (drv->remove) |
215 | drv->remove(dev); | 215 | drv->remove(dev); |
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index bdb60663f2ef..662209d3f42d 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
@@ -10,6 +10,8 @@ | |||
10 | 10 | ||
11 | #include <linux/vt_kern.h> | 11 | #include <linux/vt_kern.h> |
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <linux/kallsyms.h> | ||
14 | #include <linux/pm.h> | ||
13 | #include "../base.h" | 15 | #include "../base.h" |
14 | #include "power.h" | 16 | #include "power.h" |
15 | 17 | ||
@@ -58,6 +60,7 @@ int suspend_device(struct device * dev, pm_message_t state) | |||
58 | if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { | 60 | if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { |
59 | dev_dbg(dev, "suspending\n"); | 61 | dev_dbg(dev, "suspending\n"); |
60 | error = dev->bus->suspend(dev, state); | 62 | error = dev->bus->suspend(dev, state); |
63 | suspend_report_result(dev->bus->suspend, error); | ||
61 | } | 64 | } |
62 | up(&dev->sem); | 65 | up(&dev->sem); |
63 | return error; | 66 | return error; |
@@ -169,3 +172,12 @@ int device_power_down(pm_message_t state) | |||
169 | 172 | ||
170 | EXPORT_SYMBOL_GPL(device_power_down); | 173 | EXPORT_SYMBOL_GPL(device_power_down); |
171 | 174 | ||
175 | void __suspend_report_result(const char *function, void *fn, int ret) | ||
176 | { | ||
177 | if (ret) { | ||
178 | printk(KERN_ERR "%s(): ", function); | ||
179 | print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn); | ||
180 | printk("%d\n", ret); | ||
181 | } | ||
182 | } | ||
183 | EXPORT_SYMBOL_GPL(__suspend_report_result); | ||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index f70a47eadb52..841f0bd3eaaf 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -2734,7 +2734,7 @@ static void __do_SAK(void *arg) | |||
2734 | printk(KERN_NOTICE "SAK: killed process %d" | 2734 | printk(KERN_NOTICE "SAK: killed process %d" |
2735 | " (%s): fd#%d opened to the tty\n", | 2735 | " (%s): fd#%d opened to the tty\n", |
2736 | p->pid, p->comm, i); | 2736 | p->pid, p->comm, i); |
2737 | send_sig(SIGKILL, p, 1); | 2737 | force_sig(SIGKILL, p); |
2738 | break; | 2738 | break; |
2739 | } | 2739 | } |
2740 | } | 2740 | } |
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 85429979d0db..98e395f4bb29 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile | |||
@@ -1,7 +1,8 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | obj-$(CONFIG_EDD) += edd.o | 4 | obj-$(CONFIG_DMI) += dmi_scan.o |
5 | obj-$(CONFIG_EDD) += edd.o | ||
5 | obj-$(CONFIG_EFI_VARS) += efivars.o | 6 | obj-$(CONFIG_EFI_VARS) += efivars.o |
6 | obj-$(CONFIG_EFI_PCDP) += pcdp.o | 7 | obj-$(CONFIG_EFI_PCDP) += pcdp.o |
7 | obj-$(CONFIG_DELL_RBU) += dell_rbu.o | 8 | obj-$(CONFIG_DELL_RBU) += dell_rbu.o |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c new file mode 100644 index 000000000000..948bd7e1445a --- /dev/null +++ b/drivers/firmware/dmi_scan.c | |||
@@ -0,0 +1,358 @@ | |||
1 | #include <linux/types.h> | ||
2 | #include <linux/string.h> | ||
3 | #include <linux/init.h> | ||
4 | #include <linux/module.h> | ||
5 | #include <linux/dmi.h> | ||
6 | #include <linux/efi.h> | ||
7 | #include <linux/bootmem.h> | ||
8 | #include <linux/slab.h> | ||
9 | #include <asm/dmi.h> | ||
10 | |||
11 | static char * __init dmi_string(struct dmi_header *dm, u8 s) | ||
12 | { | ||
13 | u8 *bp = ((u8 *) dm) + dm->length; | ||
14 | char *str = ""; | ||
15 | |||
16 | if (s) { | ||
17 | s--; | ||
18 | while (s > 0 && *bp) { | ||
19 | bp += strlen(bp) + 1; | ||
20 | s--; | ||
21 | } | ||
22 | |||
23 | if (*bp != 0) { | ||
24 | str = dmi_alloc(strlen(bp) + 1); | ||
25 | if (str != NULL) | ||
26 | strcpy(str, bp); | ||
27 | else | ||
28 | printk(KERN_ERR "dmi_string: out of memory.\n"); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | return str; | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * We have to be cautious here. We have seen BIOSes with DMI pointers | ||
37 | * pointing to completely the wrong place for example | ||
38 | */ | ||
39 | static int __init dmi_table(u32 base, int len, int num, | ||
40 | void (*decode)(struct dmi_header *)) | ||
41 | { | ||
42 | u8 *buf, *data; | ||
43 | int i = 0; | ||
44 | |||
45 | buf = dmi_ioremap(base, len); | ||
46 | if (buf == NULL) | ||
47 | return -1; | ||
48 | |||
49 | data = buf; | ||
50 | |||
51 | /* | ||
52 | * Stop when we see all the items the table claimed to have | ||
53 | * OR we run off the end of the table (also happens) | ||
54 | */ | ||
55 | while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { | ||
56 | struct dmi_header *dm = (struct dmi_header *)data; | ||
57 | /* | ||
58 | * We want to know the total length (formated area and strings) | ||
59 | * before decoding to make sure we won't run off the table in | ||
60 | * dmi_decode or dmi_string | ||
61 | */ | ||
62 | data += dm->length; | ||
63 | while ((data - buf < len - 1) && (data[0] || data[1])) | ||
64 | data++; | ||
65 | if (data - buf < len - 1) | ||
66 | decode(dm); | ||
67 | data += 2; | ||
68 | i++; | ||
69 | } | ||
70 | dmi_iounmap(buf, len); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int __init dmi_checksum(u8 *buf) | ||
75 | { | ||
76 | u8 sum = 0; | ||
77 | int a; | ||
78 | |||
79 | for (a = 0; a < 15; a++) | ||
80 | sum += buf[a]; | ||
81 | |||
82 | return sum == 0; | ||
83 | } | ||
84 | |||
85 | static char *dmi_ident[DMI_STRING_MAX]; | ||
86 | static LIST_HEAD(dmi_devices); | ||
87 | |||
88 | /* | ||
89 | * Save a DMI string | ||
90 | */ | ||
91 | static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) | ||
92 | { | ||
93 | char *p, *d = (char*) dm; | ||
94 | |||
95 | if (dmi_ident[slot]) | ||
96 | return; | ||
97 | |||
98 | p = dmi_string(dm, d[string]); | ||
99 | if (p == NULL) | ||
100 | return; | ||
101 | |||
102 | dmi_ident[slot] = p; | ||
103 | } | ||
104 | |||
105 | static void __init dmi_save_devices(struct dmi_header *dm) | ||
106 | { | ||
107 | int i, count = (dm->length - sizeof(struct dmi_header)) / 2; | ||
108 | struct dmi_device *dev; | ||
109 | |||
110 | for (i = 0; i < count; i++) { | ||
111 | char *d = (char *)(dm + 1) + (i * 2); | ||
112 | |||
113 | /* Skip disabled device */ | ||
114 | if ((*d & 0x80) == 0) | ||
115 | continue; | ||
116 | |||
117 | dev = dmi_alloc(sizeof(*dev)); | ||
118 | if (!dev) { | ||
119 | printk(KERN_ERR "dmi_save_devices: out of memory.\n"); | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | dev->type = *d++ & 0x7f; | ||
124 | dev->name = dmi_string(dm, *d); | ||
125 | dev->device_data = NULL; | ||
126 | |||
127 | list_add(&dev->list, &dmi_devices); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static void __init dmi_save_ipmi_device(struct dmi_header *dm) | ||
132 | { | ||
133 | struct dmi_device *dev; | ||
134 | void * data; | ||
135 | |||
136 | data = dmi_alloc(dm->length); | ||
137 | if (data == NULL) { | ||
138 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | memcpy(data, dm, dm->length); | ||
143 | |||
144 | dev = dmi_alloc(sizeof(*dev)); | ||
145 | if (!dev) { | ||
146 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | dev->type = DMI_DEV_TYPE_IPMI; | ||
151 | dev->name = "IPMI controller"; | ||
152 | dev->device_data = data; | ||
153 | |||
154 | list_add(&dev->list, &dmi_devices); | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Process a DMI table entry. Right now all we care about are the BIOS | ||
159 | * and machine entries. For 2.5 we should pull the smbus controller info | ||
160 | * out of here. | ||
161 | */ | ||
162 | static void __init dmi_decode(struct dmi_header *dm) | ||
163 | { | ||
164 | switch(dm->type) { | ||
165 | case 0: /* BIOS Information */ | ||
166 | dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); | ||
167 | dmi_save_ident(dm, DMI_BIOS_VERSION, 5); | ||
168 | dmi_save_ident(dm, DMI_BIOS_DATE, 8); | ||
169 | break; | ||
170 | case 1: /* System Information */ | ||
171 | dmi_save_ident(dm, DMI_SYS_VENDOR, 4); | ||
172 | dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); | ||
173 | dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); | ||
174 | dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); | ||
175 | break; | ||
176 | case 2: /* Base Board Information */ | ||
177 | dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); | ||
178 | dmi_save_ident(dm, DMI_BOARD_NAME, 5); | ||
179 | dmi_save_ident(dm, DMI_BOARD_VERSION, 6); | ||
180 | break; | ||
181 | case 10: /* Onboard Devices Information */ | ||
182 | dmi_save_devices(dm); | ||
183 | break; | ||
184 | case 38: /* IPMI Device Information */ | ||
185 | dmi_save_ipmi_device(dm); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | static int __init dmi_present(char __iomem *p) | ||
190 | { | ||
191 | u8 buf[15]; | ||
192 | memcpy_fromio(buf, p, 15); | ||
193 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { | ||
194 | u16 num = (buf[13] << 8) | buf[12]; | ||
195 | u16 len = (buf[7] << 8) | buf[6]; | ||
196 | u32 base = (buf[11] << 24) | (buf[10] << 16) | | ||
197 | (buf[9] << 8) | buf[8]; | ||
198 | |||
199 | /* | ||
200 | * DMI version 0.0 means that the real version is taken from | ||
201 | * the SMBIOS version, which we don't know at this point. | ||
202 | */ | ||
203 | if (buf[14] != 0) | ||
204 | printk(KERN_INFO "DMI %d.%d present.\n", | ||
205 | buf[14] >> 4, buf[14] & 0xF); | ||
206 | else | ||
207 | printk(KERN_INFO "DMI present.\n"); | ||
208 | if (dmi_table(base,len, num, dmi_decode) == 0) | ||
209 | return 0; | ||
210 | } | ||
211 | return 1; | ||
212 | } | ||
213 | |||
214 | void __init dmi_scan_machine(void) | ||
215 | { | ||
216 | char __iomem *p, *q; | ||
217 | int rc; | ||
218 | |||
219 | if (efi_enabled) { | ||
220 | if (efi.smbios == EFI_INVALID_TABLE_ADDR) | ||
221 | goto out; | ||
222 | |||
223 | /* This is called as a core_initcall() because it isn't | ||
224 | * needed during early boot. This also means we can | ||
225 | * iounmap the space when we're done with it. | ||
226 | */ | ||
227 | p = dmi_ioremap(efi.smbios, 32); | ||
228 | if (p == NULL) | ||
229 | goto out; | ||
230 | |||
231 | rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ | ||
232 | dmi_iounmap(p, 32); | ||
233 | if (!rc) | ||
234 | return; | ||
235 | } | ||
236 | else { | ||
237 | /* | ||
238 | * no iounmap() for that ioremap(); it would be a no-op, but | ||
239 | * it's so early in setup that sucker gets confused into doing | ||
240 | * what it shouldn't if we actually call it. | ||
241 | */ | ||
242 | p = dmi_ioremap(0xF0000, 0x10000); | ||
243 | if (p == NULL) | ||
244 | goto out; | ||
245 | |||
246 | for (q = p; q < p + 0x10000; q += 16) { | ||
247 | rc = dmi_present(q); | ||
248 | if (!rc) | ||
249 | return; | ||
250 | } | ||
251 | } | ||
252 | out: printk(KERN_INFO "DMI not present or invalid.\n"); | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * dmi_check_system - check system DMI data | ||
257 | * @list: array of dmi_system_id structures to match against | ||
258 | * | ||
259 | * Walk the blacklist table running matching functions until someone | ||
260 | * returns non zero or we hit the end. Callback function is called for | ||
261 | * each successfull match. Returns the number of matches. | ||
262 | */ | ||
263 | int dmi_check_system(struct dmi_system_id *list) | ||
264 | { | ||
265 | int i, count = 0; | ||
266 | struct dmi_system_id *d = list; | ||
267 | |||
268 | while (d->ident) { | ||
269 | for (i = 0; i < ARRAY_SIZE(d->matches); i++) { | ||
270 | int s = d->matches[i].slot; | ||
271 | if (s == DMI_NONE) | ||
272 | continue; | ||
273 | if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr)) | ||
274 | continue; | ||
275 | /* No match */ | ||
276 | goto fail; | ||
277 | } | ||
278 | count++; | ||
279 | if (d->callback && d->callback(d)) | ||
280 | break; | ||
281 | fail: d++; | ||
282 | } | ||
283 | |||
284 | return count; | ||
285 | } | ||
286 | EXPORT_SYMBOL(dmi_check_system); | ||
287 | |||
288 | /** | ||
289 | * dmi_get_system_info - return DMI data value | ||
290 | * @field: data index (see enum dmi_filed) | ||
291 | * | ||
292 | * Returns one DMI data value, can be used to perform | ||
293 | * complex DMI data checks. | ||
294 | */ | ||
295 | char *dmi_get_system_info(int field) | ||
296 | { | ||
297 | return dmi_ident[field]; | ||
298 | } | ||
299 | EXPORT_SYMBOL(dmi_get_system_info); | ||
300 | |||
301 | /** | ||
302 | * dmi_find_device - find onboard device by type/name | ||
303 | * @type: device type or %DMI_DEV_TYPE_ANY to match all device types | ||
304 | * @desc: device name string or %NULL to match all | ||
305 | * @from: previous device found in search, or %NULL for new search. | ||
306 | * | ||
307 | * Iterates through the list of known onboard devices. If a device is | ||
308 | * found with a matching @vendor and @device, a pointer to its device | ||
309 | * structure is returned. Otherwise, %NULL is returned. | ||
310 | * A new search is initiated by passing %NULL to the @from argument. | ||
311 | * If @from is not %NULL, searches continue from next device. | ||
312 | */ | ||
313 | struct dmi_device * dmi_find_device(int type, const char *name, | ||
314 | struct dmi_device *from) | ||
315 | { | ||
316 | struct list_head *d, *head = from ? &from->list : &dmi_devices; | ||
317 | |||
318 | for(d = head->next; d != &dmi_devices; d = d->next) { | ||
319 | struct dmi_device *dev = list_entry(d, struct dmi_device, list); | ||
320 | |||
321 | if (((type == DMI_DEV_TYPE_ANY) || (dev->type == type)) && | ||
322 | ((name == NULL) || (strcmp(dev->name, name) == 0))) | ||
323 | return dev; | ||
324 | } | ||
325 | |||
326 | return NULL; | ||
327 | } | ||
328 | EXPORT_SYMBOL(dmi_find_device); | ||
329 | |||
330 | /** | ||
331 | * dmi_get_year - Return year of a DMI date | ||
332 | * @field: data index (like dmi_get_system_info) | ||
333 | * | ||
334 | * Returns -1 when the field doesn't exist. 0 when it is broken. | ||
335 | */ | ||
336 | int dmi_get_year(int field) | ||
337 | { | ||
338 | int year; | ||
339 | char *s = dmi_get_system_info(field); | ||
340 | |||
341 | if (!s) | ||
342 | return -1; | ||
343 | if (*s == '\0') | ||
344 | return 0; | ||
345 | s = strrchr(s, '/'); | ||
346 | if (!s) | ||
347 | return 0; | ||
348 | |||
349 | s += 1; | ||
350 | year = simple_strtoul(s, NULL, 0); | ||
351 | if (year && year < 100) { /* 2-digit year */ | ||
352 | year += 1900; | ||
353 | if (year < 1996) /* no dates < spec 1.0 */ | ||
354 | year += 100; | ||
355 | } | ||
356 | |||
357 | return year; | ||
358 | } | ||
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 6865c64d8a51..958602e28412 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -1161,7 +1161,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1161 | bank. */ | 1161 | bank. */ |
1162 | if (kind < 0) { | 1162 | if (kind < 0) { |
1163 | if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) { | 1163 | if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) { |
1164 | dev_warn(dev, "Detection failed at step 3\n"); | 1164 | dev_dbg(dev, "Detection failed at step 1\n"); |
1165 | goto ERROR1; | 1165 | goto ERROR1; |
1166 | } | 1166 | } |
1167 | val1 = w83792d_read_value(client, W83792D_REG_BANK); | 1167 | val1 = w83792d_read_value(client, W83792D_REG_BANK); |
@@ -1170,6 +1170,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1170 | if (!(val1 & 0x07)) { /* is Bank0 */ | 1170 | if (!(val1 & 0x07)) { /* is Bank0 */ |
1171 | if (((!(val1 & 0x80)) && (val2 != 0xa3)) || | 1171 | if (((!(val1 & 0x80)) && (val2 != 0xa3)) || |
1172 | ((val1 & 0x80) && (val2 != 0x5c))) { | 1172 | ((val1 & 0x80) && (val2 != 0x5c))) { |
1173 | dev_dbg(dev, "Detection failed at step 2\n"); | ||
1173 | goto ERROR1; | 1174 | goto ERROR1; |
1174 | } | 1175 | } |
1175 | } | 1176 | } |
@@ -1177,7 +1178,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1177 | should match */ | 1178 | should match */ |
1178 | if (w83792d_read_value(client, | 1179 | if (w83792d_read_value(client, |
1179 | W83792D_REG_I2C_ADDR) != address) { | 1180 | W83792D_REG_I2C_ADDR) != address) { |
1180 | dev_warn(dev, "Detection failed at step 5\n"); | 1181 | dev_dbg(dev, "Detection failed at step 3\n"); |
1181 | goto ERROR1; | 1182 | goto ERROR1; |
1182 | } | 1183 | } |
1183 | } | 1184 | } |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 089c6f5b24de..d6d44946a283 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -286,7 +286,10 @@ config I2C_PARPORT | |||
286 | This driver is a replacement for (and was inspired by) an older | 286 | This driver is a replacement for (and was inspired by) an older |
287 | driver named i2c-philips-par. The new driver supports more devices, | 287 | driver named i2c-philips-par. The new driver supports more devices, |
288 | and makes it easier to add support for new devices. | 288 | and makes it easier to add support for new devices. |
289 | 289 | ||
290 | An adapter type parameter is now mandatory. Please read the file | ||
291 | Documentation/i2c/busses/i2c-parport for details. | ||
292 | |||
290 | Another driver exists, named i2c-parport-light, which doesn't depend | 293 | Another driver exists, named i2c-parport-light, which doesn't depend |
291 | on the parport driver. This is meant for embedded systems. Don't say | 294 | on the parport driver. This is meant for embedded systems. Don't say |
292 | Y here if you intend to say Y or M there. | 295 | Y here if you intend to say Y or M there. |
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c index c63025a4c861..e09ebbb2f9f0 100644 --- a/drivers/i2c/busses/i2c-parport-light.c +++ b/drivers/i2c/busses/i2c-parport-light.c | |||
@@ -121,9 +121,14 @@ static struct i2c_adapter parport_adapter = { | |||
121 | 121 | ||
122 | static int __init i2c_parport_init(void) | 122 | static int __init i2c_parport_init(void) |
123 | { | 123 | { |
124 | if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { | 124 | if (type < 0) { |
125 | printk(KERN_WARNING "i2c-parport: adapter type unspecified\n"); | ||
126 | return -ENODEV; | ||
127 | } | ||
128 | |||
129 | if (type >= ARRAY_SIZE(adapter_parm)) { | ||
125 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); | 130 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); |
126 | type = 0; | 131 | return -ENODEV; |
127 | } | 132 | } |
128 | 133 | ||
129 | if (base == 0) { | 134 | if (base == 0) { |
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 7e2e8cd1c14a..934bd55bae15 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c | |||
@@ -241,9 +241,14 @@ static struct parport_driver i2c_parport_driver = { | |||
241 | 241 | ||
242 | static int __init i2c_parport_init(void) | 242 | static int __init i2c_parport_init(void) |
243 | { | 243 | { |
244 | if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { | 244 | if (type < 0) { |
245 | printk(KERN_WARNING "i2c-parport: adapter type unspecified\n"); | ||
246 | return -ENODEV; | ||
247 | } | ||
248 | |||
249 | if (type >= ARRAY_SIZE(adapter_parm)) { | ||
245 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); | 250 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); |
246 | type = 0; | 251 | return -ENODEV; |
247 | } | 252 | } |
248 | 253 | ||
249 | return parport_register_driver(&i2c_parport_driver); | 254 | return parport_register_driver(&i2c_parport_driver); |
diff --git a/drivers/i2c/busses/i2c-parport.h b/drivers/i2c/busses/i2c-parport.h index d702e5e0388d..9ddd816d5d0f 100644 --- a/drivers/i2c/busses/i2c-parport.h +++ b/drivers/i2c/busses/i2c-parport.h | |||
@@ -90,7 +90,7 @@ static struct adapter_parm adapter_parm[] = { | |||
90 | }, | 90 | }, |
91 | }; | 91 | }; |
92 | 92 | ||
93 | static int type; | 93 | static int type = -1; |
94 | module_param(type, int, 0); | 94 | module_param(type, int, 0); |
95 | MODULE_PARM_DESC(type, | 95 | MODULE_PARM_DESC(type, |
96 | "Type of adapter:\n" | 96 | "Type of adapter:\n" |
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 3024907cdafe..1a73c0532fc7 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c | |||
@@ -43,13 +43,6 @@ | |||
43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
44 | #include <asm/io.h> | 44 | #include <asm/io.h> |
45 | 45 | ||
46 | /* | ||
47 | HISTORY: | ||
48 | 2003-05-11 1.0.0 Updated from lm_sensors project for kernel 2.5 | ||
49 | (was i2c-sis645.c from lm_sensors 2.7.0) | ||
50 | */ | ||
51 | #define SIS96x_VERSION "1.0.0" | ||
52 | |||
53 | /* base address register in PCI config space */ | 46 | /* base address register in PCI config space */ |
54 | #define SIS96x_BAR 0x04 | 47 | #define SIS96x_BAR 0x04 |
55 | 48 | ||
@@ -337,7 +330,6 @@ static struct pci_driver sis96x_driver = { | |||
337 | 330 | ||
338 | static int __init i2c_sis96x_init(void) | 331 | static int __init i2c_sis96x_init(void) |
339 | { | 332 | { |
340 | printk(KERN_INFO "i2c-sis96x version %s\n", SIS96x_VERSION); | ||
341 | return pci_register_driver(&sis96x_driver); | 333 | return pci_register_driver(&sis96x_driver); |
342 | } | 334 | } |
343 | 335 | ||
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index 03d09ed5ec2c..4630f1969a09 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/rtc.h> | 27 | #include <linux/rtc.h> |
28 | #include <linux/bcd.h> | 28 | #include <linux/bcd.h> |
29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/workqueue.h> | ||
30 | 31 | ||
31 | #define DS1374_REG_TOD0 0x00 | 32 | #define DS1374_REG_TOD0 0x00 |
32 | #define DS1374_REG_TOD1 0x01 | 33 | #define DS1374_REG_TOD1 0x01 |
@@ -139,7 +140,7 @@ ulong ds1374_get_rtc_time(void) | |||
139 | return t1; | 140 | return t1; |
140 | } | 141 | } |
141 | 142 | ||
142 | static void ds1374_set_tlet(ulong arg) | 143 | static void ds1374_set_work(void *arg) |
143 | { | 144 | { |
144 | ulong t1, t2; | 145 | ulong t1, t2; |
145 | int limit = 10; /* arbitrary retry limit */ | 146 | int limit = 10; /* arbitrary retry limit */ |
@@ -168,17 +169,18 @@ static void ds1374_set_tlet(ulong arg) | |||
168 | 169 | ||
169 | static ulong new_time; | 170 | static ulong new_time; |
170 | 171 | ||
171 | static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, | 172 | static struct workqueue_struct *ds1374_workqueue; |
172 | (ulong) & new_time); | 173 | |
174 | static DECLARE_WORK(ds1374_work, ds1374_set_work, &new_time); | ||
173 | 175 | ||
174 | int ds1374_set_rtc_time(ulong nowtime) | 176 | int ds1374_set_rtc_time(ulong nowtime) |
175 | { | 177 | { |
176 | new_time = nowtime; | 178 | new_time = nowtime; |
177 | 179 | ||
178 | if (in_interrupt()) | 180 | if (in_interrupt()) |
179 | tasklet_schedule(&ds1374_tasklet); | 181 | queue_work(ds1374_workqueue, &ds1374_work); |
180 | else | 182 | else |
181 | ds1374_set_tlet((ulong) & new_time); | 183 | ds1374_set_work(&new_time); |
182 | 184 | ||
183 | return 0; | 185 | return 0; |
184 | } | 186 | } |
@@ -204,6 +206,8 @@ static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind) | |||
204 | client->adapter = adap; | 206 | client->adapter = adap; |
205 | client->driver = &ds1374_driver; | 207 | client->driver = &ds1374_driver; |
206 | 208 | ||
209 | ds1374_workqueue = create_singlethread_workqueue("ds1374"); | ||
210 | |||
207 | if ((rc = i2c_attach_client(client)) != 0) { | 211 | if ((rc = i2c_attach_client(client)) != 0) { |
208 | kfree(client); | 212 | kfree(client); |
209 | return rc; | 213 | return rc; |
@@ -227,7 +231,7 @@ static int ds1374_detach(struct i2c_client *client) | |||
227 | 231 | ||
228 | if ((rc = i2c_detach_client(client)) == 0) { | 232 | if ((rc = i2c_detach_client(client)) == 0) { |
229 | kfree(i2c_get_clientdata(client)); | 233 | kfree(i2c_get_clientdata(client)); |
230 | tasklet_kill(&ds1374_tasklet); | 234 | destroy_workqueue(ds1374_workqueue); |
231 | } | 235 | } |
232 | return rc; | 236 | return rc; |
233 | } | 237 | } |
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index b5aabe7cf792..27fc9ff2961a 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/rtc.h> | 25 | #include <linux/rtc.h> |
26 | #include <linux/bcd.h> | 26 | #include <linux/bcd.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/workqueue.h> | ||
28 | 29 | ||
29 | #include <asm/time.h> | 30 | #include <asm/time.h> |
30 | #include <asm/rtc.h> | 31 | #include <asm/rtc.h> |
@@ -111,7 +112,7 @@ m41t00_get_rtc_time(void) | |||
111 | } | 112 | } |
112 | 113 | ||
113 | static void | 114 | static void |
114 | m41t00_set_tlet(ulong arg) | 115 | m41t00_set(void *arg) |
115 | { | 116 | { |
116 | struct rtc_time tm; | 117 | struct rtc_time tm; |
117 | ulong nowtime = *(ulong *)arg; | 118 | ulong nowtime = *(ulong *)arg; |
@@ -145,9 +146,9 @@ m41t00_set_tlet(ulong arg) | |||
145 | return; | 146 | return; |
146 | } | 147 | } |
147 | 148 | ||
148 | static ulong new_time; | 149 | static ulong new_time; |
149 | 150 | static struct workqueue_struct *m41t00_wq; | |
150 | DECLARE_TASKLET_DISABLED(m41t00_tasklet, m41t00_set_tlet, (ulong)&new_time); | 151 | static DECLARE_WORK(m41t00_work, m41t00_set, &new_time); |
151 | 152 | ||
152 | int | 153 | int |
153 | m41t00_set_rtc_time(ulong nowtime) | 154 | m41t00_set_rtc_time(ulong nowtime) |
@@ -155,9 +156,9 @@ m41t00_set_rtc_time(ulong nowtime) | |||
155 | new_time = nowtime; | 156 | new_time = nowtime; |
156 | 157 | ||
157 | if (in_interrupt()) | 158 | if (in_interrupt()) |
158 | tasklet_schedule(&m41t00_tasklet); | 159 | queue_work(m41t00_wq, &m41t00_work); |
159 | else | 160 | else |
160 | m41t00_set_tlet((ulong)&new_time); | 161 | m41t00_set(&new_time); |
161 | 162 | ||
162 | return 0; | 163 | return 0; |
163 | } | 164 | } |
@@ -189,6 +190,7 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind) | |||
189 | return rc; | 190 | return rc; |
190 | } | 191 | } |
191 | 192 | ||
193 | m41t00_wq = create_singlethread_workqueue("m41t00"); | ||
192 | save_client = client; | 194 | save_client = client; |
193 | return 0; | 195 | return 0; |
194 | } | 196 | } |
@@ -206,7 +208,7 @@ m41t00_detach(struct i2c_client *client) | |||
206 | 208 | ||
207 | if ((rc = i2c_detach_client(client)) == 0) { | 209 | if ((rc = i2c_detach_client(client)) == 0) { |
208 | kfree(client); | 210 | kfree(client); |
209 | tasklet_kill(&m41t00_tasklet); | 211 | destroy_workqueue(m41t00_wq); |
210 | } | 212 | } |
211 | return rc; | 213 | return rc; |
212 | } | 214 | } |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 1ed5152db450..434ca39d19c1 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -163,6 +163,7 @@ void md_new_event(mddev_t *mddev) | |||
163 | { | 163 | { |
164 | atomic_inc(&md_event_count); | 164 | atomic_inc(&md_event_count); |
165 | wake_up(&md_event_waiters); | 165 | wake_up(&md_event_waiters); |
166 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | ||
166 | } | 167 | } |
167 | EXPORT_SYMBOL_GPL(md_new_event); | 168 | EXPORT_SYMBOL_GPL(md_new_event); |
168 | 169 | ||
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 6e79f5675b0d..638004546700 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -360,9 +360,6 @@ static int __init rpaphp_init(void) | |||
360 | while ((dn = of_find_node_by_type(dn, "pci"))) | 360 | while ((dn = of_find_node_by_type(dn, "pci"))) |
361 | rpaphp_add_slot(dn); | 361 | rpaphp_add_slot(dn); |
362 | 362 | ||
363 | if (!num_slots) | ||
364 | return -ENODEV; | ||
365 | |||
366 | return 0; | 363 | return 0; |
367 | } | 364 | } |
368 | 365 | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index a77e79c8c82e..2087a397ef16 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -504,6 +504,201 @@ void pci_scan_msi_device(struct pci_dev *dev) | |||
504 | nr_reserved_vectors++; | 504 | nr_reserved_vectors++; |
505 | } | 505 | } |
506 | 506 | ||
507 | #ifdef CONFIG_PM | ||
508 | int pci_save_msi_state(struct pci_dev *dev) | ||
509 | { | ||
510 | int pos, i = 0; | ||
511 | u16 control; | ||
512 | struct pci_cap_saved_state *save_state; | ||
513 | u32 *cap; | ||
514 | |||
515 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | ||
516 | if (pos <= 0 || dev->no_msi) | ||
517 | return 0; | ||
518 | |||
519 | pci_read_config_word(dev, msi_control_reg(pos), &control); | ||
520 | if (!(control & PCI_MSI_FLAGS_ENABLE)) | ||
521 | return 0; | ||
522 | |||
523 | save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u32) * 5, | ||
524 | GFP_KERNEL); | ||
525 | if (!save_state) { | ||
526 | printk(KERN_ERR "Out of memory in pci_save_msi_state\n"); | ||
527 | return -ENOMEM; | ||
528 | } | ||
529 | cap = &save_state->data[0]; | ||
530 | |||
531 | pci_read_config_dword(dev, pos, &cap[i++]); | ||
532 | control = cap[0] >> 16; | ||
533 | pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, &cap[i++]); | ||
534 | if (control & PCI_MSI_FLAGS_64BIT) { | ||
535 | pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, &cap[i++]); | ||
536 | pci_read_config_dword(dev, pos + PCI_MSI_DATA_64, &cap[i++]); | ||
537 | } else | ||
538 | pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]); | ||
539 | if (control & PCI_MSI_FLAGS_MASKBIT) | ||
540 | pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]); | ||
541 | disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); | ||
542 | save_state->cap_nr = PCI_CAP_ID_MSI; | ||
543 | pci_add_saved_cap(dev, save_state); | ||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | void pci_restore_msi_state(struct pci_dev *dev) | ||
548 | { | ||
549 | int i = 0, pos; | ||
550 | u16 control; | ||
551 | struct pci_cap_saved_state *save_state; | ||
552 | u32 *cap; | ||
553 | |||
554 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSI); | ||
555 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | ||
556 | if (!save_state || pos <= 0) | ||
557 | return; | ||
558 | cap = &save_state->data[0]; | ||
559 | |||
560 | control = cap[i++] >> 16; | ||
561 | pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, cap[i++]); | ||
562 | if (control & PCI_MSI_FLAGS_64BIT) { | ||
563 | pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, cap[i++]); | ||
564 | pci_write_config_dword(dev, pos + PCI_MSI_DATA_64, cap[i++]); | ||
565 | } else | ||
566 | pci_write_config_dword(dev, pos + PCI_MSI_DATA_32, cap[i++]); | ||
567 | if (control & PCI_MSI_FLAGS_MASKBIT) | ||
568 | pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT, cap[i++]); | ||
569 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | ||
570 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); | ||
571 | pci_remove_saved_cap(save_state); | ||
572 | kfree(save_state); | ||
573 | } | ||
574 | |||
575 | int pci_save_msix_state(struct pci_dev *dev) | ||
576 | { | ||
577 | int pos; | ||
578 | u16 control; | ||
579 | struct pci_cap_saved_state *save_state; | ||
580 | |||
581 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
582 | if (pos <= 0 || dev->no_msi) | ||
583 | return 0; | ||
584 | |||
585 | pci_read_config_word(dev, msi_control_reg(pos), &control); | ||
586 | if (!(control & PCI_MSIX_FLAGS_ENABLE)) | ||
587 | return 0; | ||
588 | save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16), | ||
589 | GFP_KERNEL); | ||
590 | if (!save_state) { | ||
591 | printk(KERN_ERR "Out of memory in pci_save_msix_state\n"); | ||
592 | return -ENOMEM; | ||
593 | } | ||
594 | *((u16 *)&save_state->data[0]) = control; | ||
595 | |||
596 | disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); | ||
597 | save_state->cap_nr = PCI_CAP_ID_MSIX; | ||
598 | pci_add_saved_cap(dev, save_state); | ||
599 | return 0; | ||
600 | } | ||
601 | |||
602 | void pci_restore_msix_state(struct pci_dev *dev) | ||
603 | { | ||
604 | u16 save; | ||
605 | int pos; | ||
606 | int vector, head, tail = 0; | ||
607 | void __iomem *base; | ||
608 | int j; | ||
609 | struct msg_address address; | ||
610 | struct msg_data data; | ||
611 | struct msi_desc *entry; | ||
612 | int temp; | ||
613 | struct pci_cap_saved_state *save_state; | ||
614 | |||
615 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX); | ||
616 | if (!save_state) | ||
617 | return; | ||
618 | save = *((u16 *)&save_state->data[0]); | ||
619 | pci_remove_saved_cap(save_state); | ||
620 | kfree(save_state); | ||
621 | |||
622 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
623 | if (pos <= 0) | ||
624 | return; | ||
625 | |||
626 | /* route the table */ | ||
627 | temp = dev->irq; | ||
628 | if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) | ||
629 | return; | ||
630 | vector = head = dev->irq; | ||
631 | while (head != tail) { | ||
632 | entry = msi_desc[vector]; | ||
633 | base = entry->mask_base; | ||
634 | j = entry->msi_attrib.entry_nr; | ||
635 | |||
636 | msi_address_init(&address); | ||
637 | msi_data_init(&data, vector); | ||
638 | |||
639 | address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; | ||
640 | address.lo_address.value |= entry->msi_attrib.current_cpu << | ||
641 | MSI_TARGET_CPU_SHIFT; | ||
642 | |||
643 | writel(address.lo_address.value, | ||
644 | base + j * PCI_MSIX_ENTRY_SIZE + | ||
645 | PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); | ||
646 | writel(address.hi_address, | ||
647 | base + j * PCI_MSIX_ENTRY_SIZE + | ||
648 | PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); | ||
649 | writel(*(u32*)&data, | ||
650 | base + j * PCI_MSIX_ENTRY_SIZE + | ||
651 | PCI_MSIX_ENTRY_DATA_OFFSET); | ||
652 | |||
653 | tail = msi_desc[vector]->link.tail; | ||
654 | vector = tail; | ||
655 | } | ||
656 | dev->irq = temp; | ||
657 | |||
658 | pci_write_config_word(dev, msi_control_reg(pos), save); | ||
659 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); | ||
660 | } | ||
661 | #endif | ||
662 | |||
663 | static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry) | ||
664 | { | ||
665 | struct msg_address address; | ||
666 | struct msg_data data; | ||
667 | int pos, vector = dev->irq; | ||
668 | u16 control; | ||
669 | |||
670 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | ||
671 | pci_read_config_word(dev, msi_control_reg(pos), &control); | ||
672 | /* Configure MSI capability structure */ | ||
673 | msi_address_init(&address); | ||
674 | msi_data_init(&data, vector); | ||
675 | entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> | ||
676 | MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); | ||
677 | pci_write_config_dword(dev, msi_lower_address_reg(pos), | ||
678 | address.lo_address.value); | ||
679 | if (is_64bit_address(control)) { | ||
680 | pci_write_config_dword(dev, | ||
681 | msi_upper_address_reg(pos), address.hi_address); | ||
682 | pci_write_config_word(dev, | ||
683 | msi_data_reg(pos, 1), *((u32*)&data)); | ||
684 | } else | ||
685 | pci_write_config_word(dev, | ||
686 | msi_data_reg(pos, 0), *((u32*)&data)); | ||
687 | if (entry->msi_attrib.maskbit) { | ||
688 | unsigned int maskbits, temp; | ||
689 | /* All MSIs are unmasked by default, Mask them all */ | ||
690 | pci_read_config_dword(dev, | ||
691 | msi_mask_bits_reg(pos, is_64bit_address(control)), | ||
692 | &maskbits); | ||
693 | temp = (1 << multi_msi_capable(control)); | ||
694 | temp = ((temp - 1) & ~temp); | ||
695 | maskbits |= temp; | ||
696 | pci_write_config_dword(dev, | ||
697 | msi_mask_bits_reg(pos, is_64bit_address(control)), | ||
698 | maskbits); | ||
699 | } | ||
700 | } | ||
701 | |||
507 | /** | 702 | /** |
508 | * msi_capability_init - configure device's MSI capability structure | 703 | * msi_capability_init - configure device's MSI capability structure |
509 | * @dev: pointer to the pci_dev data structure of MSI device function | 704 | * @dev: pointer to the pci_dev data structure of MSI device function |
@@ -516,8 +711,6 @@ void pci_scan_msi_device(struct pci_dev *dev) | |||
516 | static int msi_capability_init(struct pci_dev *dev) | 711 | static int msi_capability_init(struct pci_dev *dev) |
517 | { | 712 | { |
518 | struct msi_desc *entry; | 713 | struct msi_desc *entry; |
519 | struct msg_address address; | ||
520 | struct msg_data data; | ||
521 | int pos, vector; | 714 | int pos, vector; |
522 | u16 control; | 715 | u16 control; |
523 | 716 | ||
@@ -549,33 +742,8 @@ static int msi_capability_init(struct pci_dev *dev) | |||
549 | /* Replace with MSI handler */ | 742 | /* Replace with MSI handler */ |
550 | irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit); | 743 | irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit); |
551 | /* Configure MSI capability structure */ | 744 | /* Configure MSI capability structure */ |
552 | msi_address_init(&address); | 745 | msi_register_init(dev, entry); |
553 | msi_data_init(&data, vector); | 746 | |
554 | entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> | ||
555 | MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); | ||
556 | pci_write_config_dword(dev, msi_lower_address_reg(pos), | ||
557 | address.lo_address.value); | ||
558 | if (is_64bit_address(control)) { | ||
559 | pci_write_config_dword(dev, | ||
560 | msi_upper_address_reg(pos), address.hi_address); | ||
561 | pci_write_config_word(dev, | ||
562 | msi_data_reg(pos, 1), *((u32*)&data)); | ||
563 | } else | ||
564 | pci_write_config_word(dev, | ||
565 | msi_data_reg(pos, 0), *((u32*)&data)); | ||
566 | if (entry->msi_attrib.maskbit) { | ||
567 | unsigned int maskbits, temp; | ||
568 | /* All MSIs are unmasked by default, Mask them all */ | ||
569 | pci_read_config_dword(dev, | ||
570 | msi_mask_bits_reg(pos, is_64bit_address(control)), | ||
571 | &maskbits); | ||
572 | temp = (1 << multi_msi_capable(control)); | ||
573 | temp = ((temp - 1) & ~temp); | ||
574 | maskbits |= temp; | ||
575 | pci_write_config_dword(dev, | ||
576 | msi_mask_bits_reg(pos, is_64bit_address(control)), | ||
577 | maskbits); | ||
578 | } | ||
579 | attach_msi_entry(entry, vector); | 747 | attach_msi_entry(entry, vector); |
580 | /* Set MSI enabled bits */ | 748 | /* Set MSI enabled bits */ |
581 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); | 749 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); |
@@ -731,6 +899,7 @@ int pci_enable_msi(struct pci_dev* dev) | |||
731 | vector_irq[dev->irq] = -1; | 899 | vector_irq[dev->irq] = -1; |
732 | nr_released_vectors--; | 900 | nr_released_vectors--; |
733 | spin_unlock_irqrestore(&msi_lock, flags); | 901 | spin_unlock_irqrestore(&msi_lock, flags); |
902 | msi_register_init(dev, msi_desc[dev->irq]); | ||
734 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); | 903 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); |
735 | return 0; | 904 | return 0; |
736 | } | 905 | } |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index f22f69ac6445..1456759936c5 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -271,10 +271,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) | |||
271 | struct pci_driver * drv = pci_dev->driver; | 271 | struct pci_driver * drv = pci_dev->driver; |
272 | int i = 0; | 272 | int i = 0; |
273 | 273 | ||
274 | if (drv && drv->suspend) | 274 | if (drv && drv->suspend) { |
275 | i = drv->suspend(pci_dev, state); | 275 | i = drv->suspend(pci_dev, state); |
276 | else | 276 | suspend_report_result(drv->suspend, i); |
277 | } else { | ||
277 | pci_save_state(pci_dev); | 278 | pci_save_state(pci_dev); |
279 | } | ||
278 | return i; | 280 | return i; |
279 | } | 281 | } |
280 | 282 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index bea1ad1ad5ba..2329f941a0dc 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -307,9 +307,11 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
307 | * Can enter D0 from any state, but if we can only go deeper | 307 | * Can enter D0 from any state, but if we can only go deeper |
308 | * to sleep if we're already in a low power state | 308 | * to sleep if we're already in a low power state |
309 | */ | 309 | */ |
310 | if (state != PCI_D0 && dev->current_state > state) | 310 | if (state != PCI_D0 && dev->current_state > state) { |
311 | printk(KERN_ERR "%s(): %s: state=%d, current state=%d\n", | ||
312 | __FUNCTION__, pci_name(dev), state, dev->current_state); | ||
311 | return -EINVAL; | 313 | return -EINVAL; |
312 | else if (dev->current_state == state) | 314 | } else if (dev->current_state == state) |
313 | return 0; /* we're already there */ | 315 | return 0; /* we're already there */ |
314 | 316 | ||
315 | /* find PCI PM capability in list */ | 317 | /* find PCI PM capability in list */ |
@@ -444,6 +446,10 @@ pci_save_state(struct pci_dev *dev) | |||
444 | /* XXX: 100% dword access ok here? */ | 446 | /* XXX: 100% dword access ok here? */ |
445 | for (i = 0; i < 16; i++) | 447 | for (i = 0; i < 16; i++) |
446 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); | 448 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); |
449 | if ((i = pci_save_msi_state(dev)) != 0) | ||
450 | return i; | ||
451 | if ((i = pci_save_msix_state(dev)) != 0) | ||
452 | return i; | ||
447 | return 0; | 453 | return 0; |
448 | } | 454 | } |
449 | 455 | ||
@@ -458,6 +464,8 @@ pci_restore_state(struct pci_dev *dev) | |||
458 | 464 | ||
459 | for (i = 0; i < 16; i++) | 465 | for (i = 0; i < 16; i++) |
460 | pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]); | 466 | pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]); |
467 | pci_restore_msi_state(dev); | ||
468 | pci_restore_msix_state(dev); | ||
461 | return 0; | 469 | return 0; |
462 | } | 470 | } |
463 | 471 | ||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 8f3fb47ea671..30630cbe2fe3 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -55,6 +55,17 @@ void pci_no_msi(void); | |||
55 | static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { } | 55 | static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { } |
56 | static inline void pci_no_msi(void) { } | 56 | static inline void pci_no_msi(void) { } |
57 | #endif | 57 | #endif |
58 | #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) | ||
59 | int pci_save_msi_state(struct pci_dev *dev); | ||
60 | int pci_save_msix_state(struct pci_dev *dev); | ||
61 | void pci_restore_msi_state(struct pci_dev *dev); | ||
62 | void pci_restore_msix_state(struct pci_dev *dev); | ||
63 | #else | ||
64 | static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; } | ||
65 | static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; } | ||
66 | static inline void pci_restore_msi_state(struct pci_dev *dev) {} | ||
67 | static inline void pci_restore_msix_state(struct pci_dev *dev) {} | ||
68 | #endif | ||
58 | 69 | ||
59 | extern int pcie_mch_quirk; | 70 | extern int pcie_mch_quirk; |
60 | extern struct device_attribute pci_dev_attrs[]; | 71 | extern struct device_attribute pci_dev_attrs[]; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 4970f47be72c..827550d25c9e 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -592,7 +592,7 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) | |||
592 | pci_write_config_byte( dev, AMD8131_MISC, tmp); | 592 | pci_write_config_byte( dev, AMD8131_MISC, tmp); |
593 | } | 593 | } |
594 | } | 594 | } |
595 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, quirk_amd_8131_ioapic ); | 595 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); |
596 | 596 | ||
597 | static void __init quirk_svw_msi(struct pci_dev *dev) | 597 | static void __init quirk_svw_msi(struct pci_dev *dev) |
598 | { | 598 | { |
@@ -921,6 +921,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) | |||
921 | if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { | 921 | if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { |
922 | switch (dev->subsystem_device) { | 922 | switch (dev->subsystem_device) { |
923 | case 0x1882: /* M6V notebook */ | 923 | case 0x1882: /* M6V notebook */ |
924 | case 0x1977: /* A6VA notebook */ | ||
924 | asus_hides_smbus = 1; | 925 | asus_hides_smbus = 1; |
925 | } | 926 | } |
926 | } | 927 | } |
@@ -999,6 +1000,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asu | |||
999 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | 1000 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); |
1000 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | 1001 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); |
1001 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | 1002 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); |
1003 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc ); | ||
1002 | 1004 | ||
1003 | static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | 1005 | static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) |
1004 | { | 1006 | { |
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 830d2c982670..b38990adf1cd 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -68,7 +68,7 @@ | |||
68 | 68 | ||
69 | #include "usbatm.h" | 69 | #include "usbatm.h" |
70 | 70 | ||
71 | #define EAGLEUSBVERSION "ueagle 1.2" | 71 | #define EAGLEUSBVERSION "ueagle 1.3" |
72 | 72 | ||
73 | 73 | ||
74 | /* | 74 | /* |
@@ -243,7 +243,7 @@ enum { | |||
243 | #define BULK_TIMEOUT 300 | 243 | #define BULK_TIMEOUT 300 |
244 | #define CTRL_TIMEOUT 1000 | 244 | #define CTRL_TIMEOUT 1000 |
245 | 245 | ||
246 | #define ACK_TIMEOUT msecs_to_jiffies(1500) | 246 | #define ACK_TIMEOUT msecs_to_jiffies(3000) |
247 | 247 | ||
248 | #define UEA_INTR_IFACE_NO 0 | 248 | #define UEA_INTR_IFACE_NO 0 |
249 | #define UEA_US_IFACE_NO 1 | 249 | #define UEA_US_IFACE_NO 1 |
@@ -314,6 +314,10 @@ struct cmv { | |||
314 | ((d) & 0xff) << 16 | \ | 314 | ((d) & 0xff) << 16 | \ |
315 | ((a) & 0xff) << 8 | \ | 315 | ((a) & 0xff) << 8 | \ |
316 | ((b) & 0xff)) | 316 | ((b) & 0xff)) |
317 | #define GETSA1(a) ((a >> 8) & 0xff) | ||
318 | #define GETSA2(a) (a & 0xff) | ||
319 | #define GETSA3(a) ((a >> 24) & 0xff) | ||
320 | #define GETSA4(a) ((a >> 16) & 0xff) | ||
317 | 321 | ||
318 | #define SA_CNTL MAKESA('C', 'N', 'T', 'L') | 322 | #define SA_CNTL MAKESA('C', 'N', 'T', 'L') |
319 | #define SA_DIAG MAKESA('D', 'I', 'A', 'G') | 323 | #define SA_DIAG MAKESA('D', 'I', 'A', 'G') |
@@ -728,11 +732,12 @@ bad2: | |||
728 | uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i); | 732 | uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i); |
729 | return; | 733 | return; |
730 | bad1: | 734 | bad1: |
731 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno); | 735 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); |
732 | } | 736 | } |
733 | 737 | ||
734 | static inline void wake_up_cmv_ack(struct uea_softc *sc) | 738 | static inline void wake_up_cmv_ack(struct uea_softc *sc) |
735 | { | 739 | { |
740 | BUG_ON(sc->cmv_ack); | ||
736 | sc->cmv_ack = 1; | 741 | sc->cmv_ack = 1; |
737 | wake_up(&sc->cmv_ack_wait); | 742 | wake_up(&sc->cmv_ack_wait); |
738 | } | 743 | } |
@@ -743,6 +748,9 @@ static inline int wait_cmv_ack(struct uea_softc *sc) | |||
743 | sc->cmv_ack, ACK_TIMEOUT); | 748 | sc->cmv_ack, ACK_TIMEOUT); |
744 | sc->cmv_ack = 0; | 749 | sc->cmv_ack = 0; |
745 | 750 | ||
751 | uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n", | ||
752 | jiffies_to_msecs(ret)); | ||
753 | |||
746 | if (ret < 0) | 754 | if (ret < 0) |
747 | return ret; | 755 | return ret; |
748 | 756 | ||
@@ -791,6 +799,12 @@ static int uea_cmv(struct uea_softc *sc, | |||
791 | struct cmv cmv; | 799 | struct cmv cmv; |
792 | int ret; | 800 | int ret; |
793 | 801 | ||
802 | uea_enters(INS_TO_USBDEV(sc)); | ||
803 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, " | ||
804 | "offset : 0x%04x, data : 0x%08x\n", | ||
805 | FUNCTION_TYPE(function), FUNCTION_SUBTYPE(function), | ||
806 | GETSA1(address), GETSA2(address), GETSA3(address), | ||
807 | GETSA4(address), offset, data); | ||
794 | /* we send a request, but we expect a reply */ | 808 | /* we send a request, but we expect a reply */ |
795 | sc->cmv_function = function | 0x2; | 809 | sc->cmv_function = function | 0x2; |
796 | sc->cmv_idx++; | 810 | sc->cmv_idx++; |
@@ -808,7 +822,9 @@ static int uea_cmv(struct uea_softc *sc, | |||
808 | ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); | 822 | ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); |
809 | if (ret < 0) | 823 | if (ret < 0) |
810 | return ret; | 824 | return ret; |
811 | return wait_cmv_ack(sc); | 825 | ret = wait_cmv_ack(sc); |
826 | uea_leaves(INS_TO_USBDEV(sc)); | ||
827 | return ret; | ||
812 | } | 828 | } |
813 | 829 | ||
814 | static inline int uea_read_cmv(struct uea_softc *sc, | 830 | static inline int uea_read_cmv(struct uea_softc *sc, |
@@ -922,7 +938,7 @@ static int uea_stat(struct uea_softc *sc) | |||
922 | * we check the status again in order to detect the failure earlier | 938 | * we check the status again in order to detect the failure earlier |
923 | */ | 939 | */ |
924 | if (sc->stats.phy.flags) { | 940 | if (sc->stats.phy.flags) { |
925 | uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n", | 941 | uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n", |
926 | sc->stats.phy.flags); | 942 | sc->stats.phy.flags); |
927 | return 0; | 943 | return 0; |
928 | } | 944 | } |
@@ -1063,7 +1079,13 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1063 | uea_enters(INS_TO_USBDEV(sc)); | 1079 | uea_enters(INS_TO_USBDEV(sc)); |
1064 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); | 1080 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); |
1065 | 1081 | ||
1082 | /* mask interrupt */ | ||
1066 | sc->booting = 1; | 1083 | sc->booting = 1; |
1084 | /* We need to set this here because, a ack timeout could have occured, | ||
1085 | * but before we start the reboot, the ack occurs and set this to 1. | ||
1086 | * So we will failed to wait Ready CMV. | ||
1087 | */ | ||
1088 | sc->cmv_ack = 0; | ||
1067 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST); | 1089 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST); |
1068 | 1090 | ||
1069 | /* reset statistics */ | 1091 | /* reset statistics */ |
@@ -1089,6 +1111,7 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1089 | 1111 | ||
1090 | msleep(1000); | 1112 | msleep(1000); |
1091 | sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); | 1113 | sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); |
1114 | /* demask interrupt */ | ||
1092 | sc->booting = 0; | 1115 | sc->booting = 0; |
1093 | 1116 | ||
1094 | /* start loading DSP */ | 1117 | /* start loading DSP */ |
@@ -1101,6 +1124,8 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1101 | if (ret < 0) | 1124 | if (ret < 0) |
1102 | return ret; | 1125 | return ret; |
1103 | 1126 | ||
1127 | uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n"); | ||
1128 | |||
1104 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | 1129 | /* Enter in R-IDLE (cmv) until instructed otherwise */ |
1105 | ret = uea_write_cmv(sc, SA_CNTL, 0, 1); | 1130 | ret = uea_write_cmv(sc, SA_CNTL, 0, 1); |
1106 | if (ret < 0) | 1131 | if (ret < 0) |
@@ -1121,6 +1146,7 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1121 | } | 1146 | } |
1122 | /* Enter in R-ACT-REQ */ | 1147 | /* Enter in R-ACT-REQ */ |
1123 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); | 1148 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); |
1149 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1124 | out: | 1150 | out: |
1125 | release_firmware(cmvs_fw); | 1151 | release_firmware(cmvs_fw); |
1126 | sc->reset = 0; | 1152 | sc->reset = 0; |
@@ -1235,6 +1261,7 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | |||
1235 | 1261 | ||
1236 | if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { | 1262 | if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { |
1237 | wake_up_cmv_ack(sc); | 1263 | wake_up_cmv_ack(sc); |
1264 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1238 | return; | 1265 | return; |
1239 | } | 1266 | } |
1240 | 1267 | ||
@@ -1249,6 +1276,7 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | |||
1249 | sc->data = sc->data << 16 | sc->data >> 16; | 1276 | sc->data = sc->data << 16 | sc->data >> 16; |
1250 | 1277 | ||
1251 | wake_up_cmv_ack(sc); | 1278 | wake_up_cmv_ack(sc); |
1279 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1252 | return; | 1280 | return; |
1253 | 1281 | ||
1254 | bad2: | 1282 | bad2: |
@@ -1256,12 +1284,14 @@ bad2: | |||
1256 | "Function : %d, Subfunction : %d\n", | 1284 | "Function : %d, Subfunction : %d\n", |
1257 | FUNCTION_TYPE(cmv->bFunction), | 1285 | FUNCTION_TYPE(cmv->bFunction), |
1258 | FUNCTION_SUBTYPE(cmv->bFunction)); | 1286 | FUNCTION_SUBTYPE(cmv->bFunction)); |
1287 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1259 | return; | 1288 | return; |
1260 | 1289 | ||
1261 | bad1: | 1290 | bad1: |
1262 | uea_err(INS_TO_USBDEV(sc), "invalid cmv received, " | 1291 | uea_err(INS_TO_USBDEV(sc), "invalid cmv received, " |
1263 | "wPreamble %d, bDirection %d\n", | 1292 | "wPreamble %d, bDirection %d\n", |
1264 | le16_to_cpu(cmv->wPreamble), cmv->bDirection); | 1293 | le16_to_cpu(cmv->wPreamble), cmv->bDirection); |
1294 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1265 | } | 1295 | } |
1266 | 1296 | ||
1267 | /* | 1297 | /* |
@@ -1346,7 +1376,7 @@ static int uea_boot(struct uea_softc *sc) | |||
1346 | if (ret < 0) { | 1376 | if (ret < 0) { |
1347 | uea_err(INS_TO_USBDEV(sc), | 1377 | uea_err(INS_TO_USBDEV(sc), |
1348 | "urb submition failed with error %d\n", ret); | 1378 | "urb submition failed with error %d\n", ret); |
1349 | goto err1; | 1379 | goto err; |
1350 | } | 1380 | } |
1351 | 1381 | ||
1352 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); | 1382 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); |
@@ -1360,10 +1390,10 @@ static int uea_boot(struct uea_softc *sc) | |||
1360 | 1390 | ||
1361 | err2: | 1391 | err2: |
1362 | usb_kill_urb(sc->urb_int); | 1392 | usb_kill_urb(sc->urb_int); |
1363 | err1: | ||
1364 | kfree(intr); | ||
1365 | err: | 1393 | err: |
1366 | usb_free_urb(sc->urb_int); | 1394 | usb_free_urb(sc->urb_int); |
1395 | sc->urb_int = NULL; | ||
1396 | kfree(intr); | ||
1367 | uea_leaves(INS_TO_USBDEV(sc)); | 1397 | uea_leaves(INS_TO_USBDEV(sc)); |
1368 | return -ENOMEM; | 1398 | return -ENOMEM; |
1369 | } | 1399 | } |
@@ -1508,7 +1538,7 @@ static ssize_t read_##name(struct device *dev, \ | |||
1508 | int ret = -ENODEV; \ | 1538 | int ret = -ENODEV; \ |
1509 | struct uea_softc *sc; \ | 1539 | struct uea_softc *sc; \ |
1510 | \ | 1540 | \ |
1511 | mutex_lock(&uea_mutex); \ | 1541 | mutex_lock(&uea_mutex); \ |
1512 | sc = dev_to_uea(dev); \ | 1542 | sc = dev_to_uea(dev); \ |
1513 | if (!sc) \ | 1543 | if (!sc) \ |
1514 | goto out; \ | 1544 | goto out; \ |
@@ -1516,7 +1546,7 @@ static ssize_t read_##name(struct device *dev, \ | |||
1516 | if (reset) \ | 1546 | if (reset) \ |
1517 | sc->stats.phy.name = 0; \ | 1547 | sc->stats.phy.name = 0; \ |
1518 | out: \ | 1548 | out: \ |
1519 | mutex_unlock(&uea_mutex); \ | 1549 | mutex_unlock(&uea_mutex); \ |
1520 | return ret; \ | 1550 | return ret; \ |
1521 | } \ | 1551 | } \ |
1522 | \ | 1552 | \ |
@@ -1643,7 +1673,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1643 | 1673 | ||
1644 | sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); | 1674 | sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); |
1645 | if (!sc) { | 1675 | if (!sc) { |
1646 | uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n"); | 1676 | uea_err(usb, "uea_init: not enough memory !\n"); |
1647 | return -ENOMEM; | 1677 | return -ENOMEM; |
1648 | } | 1678 | } |
1649 | 1679 | ||
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index ff03184da403..a08787e253aa 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -99,4 +99,11 @@ config USB_OTG_WHITELIST | |||
99 | normal Linux-USB hosts do (other than the warning), and is | 99 | normal Linux-USB hosts do (other than the warning), and is |
100 | convenient for many stages of product development. | 100 | convenient for many stages of product development. |
101 | 101 | ||
102 | config USB_OTG_BLACKLIST_HUB | ||
103 | bool "Disable external hubs" | ||
104 | depends on USB_OTG | ||
105 | help | ||
106 | If you say Y here, then Linux will refuse to enumerate | ||
107 | external hubs. OTG hosts are allowed to reduce hardware | ||
108 | and software costs by not supporting external hubs. | ||
102 | 109 | ||
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 0d2193b69235..66b78404ab34 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -213,11 +213,9 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
213 | 213 | ||
214 | if (hcd->driver->suspend) { | 214 | if (hcd->driver->suspend) { |
215 | retval = hcd->driver->suspend(hcd, message); | 215 | retval = hcd->driver->suspend(hcd, message); |
216 | if (retval) { | 216 | suspend_report_result(hcd->driver->suspend, retval); |
217 | dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n", | 217 | if (retval) |
218 | retval); | ||
219 | goto done; | 218 | goto done; |
220 | } | ||
221 | } | 219 | } |
222 | synchronize_irq(dev->irq); | 220 | synchronize_irq(dev->irq); |
223 | 221 | ||
@@ -263,6 +261,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
263 | * some device state (e.g. as part of clock reinit). | 261 | * some device state (e.g. as part of clock reinit). |
264 | */ | 262 | */ |
265 | retval = pci_set_power_state (dev, PCI_D3hot); | 263 | retval = pci_set_power_state (dev, PCI_D3hot); |
264 | suspend_report_result(pci_set_power_state, retval); | ||
266 | if (retval == 0) { | 265 | if (retval == 0) { |
267 | int wake = device_can_wakeup(&hcd->self.root_hub->dev); | 266 | int wake = device_can_wakeup(&hcd->self.root_hub->dev); |
268 | 267 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8e65f7a237e4..0c87f73f2933 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -836,6 +836,13 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
836 | desc = intf->cur_altsetting; | 836 | desc = intf->cur_altsetting; |
837 | hdev = interface_to_usbdev(intf); | 837 | hdev = interface_to_usbdev(intf); |
838 | 838 | ||
839 | #ifdef CONFIG_USB_OTG_BLACKLIST_HUB | ||
840 | if (hdev->parent) { | ||
841 | dev_warn(&intf->dev, "ignoring external hub\n"); | ||
842 | return -ENODEV; | ||
843 | } | ||
844 | #endif | ||
845 | |||
839 | /* Some hubs have a subclass of 1, which AFAICT according to the */ | 846 | /* Some hubs have a subclass of 1, which AFAICT according to the */ |
840 | /* specs is not defined, but it works */ | 847 | /* specs is not defined, but it works */ |
841 | if ((desc->desc.bInterfaceSubClass != 0) && | 848 | if ((desc->desc.bInterfaceSubClass != 0) && |
@@ -1022,7 +1029,6 @@ void usb_set_device_state(struct usb_device *udev, | |||
1022 | recursively_mark_NOTATTACHED(udev); | 1029 | recursively_mark_NOTATTACHED(udev); |
1023 | spin_unlock_irqrestore(&device_state_lock, flags); | 1030 | spin_unlock_irqrestore(&device_state_lock, flags); |
1024 | } | 1031 | } |
1025 | EXPORT_SYMBOL(usb_set_device_state); | ||
1026 | 1032 | ||
1027 | 1033 | ||
1028 | #ifdef CONFIG_PM | 1034 | #ifdef CONFIG_PM |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index d7352aa73b5e..b7fdc1cd134a 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -1194,7 +1194,6 @@ EXPORT_SYMBOL(usb_disabled); | |||
1194 | EXPORT_SYMBOL_GPL(usb_get_intf); | 1194 | EXPORT_SYMBOL_GPL(usb_get_intf); |
1195 | EXPORT_SYMBOL_GPL(usb_put_intf); | 1195 | EXPORT_SYMBOL_GPL(usb_put_intf); |
1196 | 1196 | ||
1197 | EXPORT_SYMBOL(usb_alloc_dev); | ||
1198 | EXPORT_SYMBOL(usb_put_dev); | 1197 | EXPORT_SYMBOL(usb_put_dev); |
1199 | EXPORT_SYMBOL(usb_get_dev); | 1198 | EXPORT_SYMBOL(usb_get_dev); |
1200 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); | 1199 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); |
@@ -1208,7 +1207,6 @@ EXPORT_SYMBOL(usb_ifnum_to_if); | |||
1208 | EXPORT_SYMBOL(usb_altnum_to_altsetting); | 1207 | EXPORT_SYMBOL(usb_altnum_to_altsetting); |
1209 | 1208 | ||
1210 | EXPORT_SYMBOL(usb_reset_device); | 1209 | EXPORT_SYMBOL(usb_reset_device); |
1211 | EXPORT_SYMBOL(usb_disconnect); | ||
1212 | 1210 | ||
1213 | EXPORT_SYMBOL(__usb_get_extra_descriptor); | 1211 | EXPORT_SYMBOL(__usb_get_extra_descriptor); |
1214 | 1212 | ||
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index d80f71877d68..363b2ad74ae6 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -69,11 +69,11 @@ choice | |||
69 | often need board-specific hooks. | 69 | often need board-specific hooks. |
70 | 70 | ||
71 | config USB_GADGET_NET2280 | 71 | config USB_GADGET_NET2280 |
72 | boolean "NetChip 2280" | 72 | boolean "NetChip 228x" |
73 | depends on PCI | 73 | depends on PCI |
74 | select USB_GADGET_DUALSPEED | 74 | select USB_GADGET_DUALSPEED |
75 | help | 75 | help |
76 | NetChip 2280 is a PCI based USB peripheral controller which | 76 | NetChip 2280 / 2282 is a PCI based USB peripheral controller which |
77 | supports both full and high speed USB 2.0 data transfers. | 77 | supports both full and high speed USB 2.0 data transfers. |
78 | 78 | ||
79 | It has six configurable endpoints, as well as endpoint zero | 79 | It has six configurable endpoints, as well as endpoint zero |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 865858cfd1c2..b8d0b7825bf3 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1709,7 +1709,7 @@ static int __devexit at91udc_remove(struct platform_device *dev) | |||
1709 | } | 1709 | } |
1710 | 1710 | ||
1711 | #ifdef CONFIG_PM | 1711 | #ifdef CONFIG_PM |
1712 | static int at91udc_suspend(struct platform_device *dev, u32 state, u32 level) | 1712 | static int at91udc_suspend(struct platform_device *dev, pm_message_t mesg) |
1713 | { | 1713 | { |
1714 | struct at91_udc *udc = platform_get_drvdata(dev); | 1714 | struct at91_udc *udc = platform_get_drvdata(dev); |
1715 | 1715 | ||
@@ -1731,7 +1731,7 @@ static int at91udc_suspend(struct platform_device *dev, u32 state, u32 level) | |||
1731 | return 0; | 1731 | return 0; |
1732 | } | 1732 | } |
1733 | 1733 | ||
1734 | static int at91udc_resume(struct platform_device *dev, u32 level) | 1734 | static int at91udc_resume(struct platform_device *dev) |
1735 | { | 1735 | { |
1736 | struct at91_udc *udc = platform_get_drvdata(dev); | 1736 | struct at91_udc *udc = platform_get_drvdata(dev); |
1737 | 1737 | ||
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index c3d8e5c5bf28..9c4422ac9de4 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -2338,6 +2338,9 @@ autoconf_fail: | |||
2338 | hs_subset_descriptors(); | 2338 | hs_subset_descriptors(); |
2339 | } | 2339 | } |
2340 | 2340 | ||
2341 | device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
2342 | usb_gadget_set_selfpowered (gadget); | ||
2343 | |||
2341 | /* For now RNDIS is always a second config */ | 2344 | /* For now RNDIS is always a second config */ |
2342 | if (rndis) | 2345 | if (rndis) |
2343 | device_desc.bNumConfigurations = 2; | 2346 | device_desc.bNumConfigurations = 2; |
@@ -2361,9 +2364,6 @@ autoconf_fail: | |||
2361 | #endif | 2364 | #endif |
2362 | #endif /* DUALSPEED */ | 2365 | #endif /* DUALSPEED */ |
2363 | 2366 | ||
2364 | device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
2365 | usb_gadget_set_selfpowered (gadget); | ||
2366 | |||
2367 | if (gadget->is_otg) { | 2367 | if (gadget->is_otg) { |
2368 | otg_descriptor.bmAttributes |= USB_OTG_HNP, | 2368 | otg_descriptor.bmAttributes |= USB_OTG_HNP, |
2369 | eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 2369 | eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index cf3be299e353..6f887478b148 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -71,6 +71,12 @@ | |||
71 | * requirement amounts to two 16K buffers, size configurable by a parameter. | 71 | * requirement amounts to two 16K buffers, size configurable by a parameter. |
72 | * Support is included for both full-speed and high-speed operation. | 72 | * Support is included for both full-speed and high-speed operation. |
73 | * | 73 | * |
74 | * Note that the driver is slightly non-portable in that it assumes a | ||
75 | * single memory/DMA buffer will be useable for bulk-in, bulk-out, and | ||
76 | * interrupt-in endpoints. With most device controllers this isn't an | ||
77 | * issue, but there may be some with hardware restrictions that prevent | ||
78 | * a buffer from being used by more than one endpoint. | ||
79 | * | ||
74 | * Module options: | 80 | * Module options: |
75 | * | 81 | * |
76 | * file=filename[,filename...] | 82 | * file=filename[,filename...] |
@@ -108,6 +114,14 @@ | |||
108 | * setting are not allowed when the medium is loaded. | 114 | * setting are not allowed when the medium is loaded. |
109 | * | 115 | * |
110 | * This gadget driver is heavily based on "Gadget Zero" by David Brownell. | 116 | * This gadget driver is heavily based on "Gadget Zero" by David Brownell. |
117 | * The driver's SCSI command interface was based on the "Information | ||
118 | * technology - Small Computer System Interface - 2" document from | ||
119 | * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at | ||
120 | * <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>. The single exception | ||
121 | * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the | ||
122 | * "Universal Serial Bus Mass Storage Class UFI Command Specification" | ||
123 | * document, Revision 1.0, December 14, 1998, available at | ||
124 | * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>. | ||
111 | */ | 125 | */ |
112 | 126 | ||
113 | 127 | ||
@@ -334,11 +348,9 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
334 | 348 | ||
335 | #define MAX_LUNS 8 | 349 | #define MAX_LUNS 8 |
336 | 350 | ||
337 | /* Arggh! There should be a module_param_array_named macro! */ | ||
338 | static char *file[MAX_LUNS]; | ||
339 | static int ro[MAX_LUNS]; | ||
340 | |||
341 | static struct { | 351 | static struct { |
352 | char *file[MAX_LUNS]; | ||
353 | int ro[MAX_LUNS]; | ||
342 | int num_filenames; | 354 | int num_filenames; |
343 | int num_ros; | 355 | int num_ros; |
344 | unsigned int nluns; | 356 | unsigned int nluns; |
@@ -370,10 +382,11 @@ static struct { | |||
370 | }; | 382 | }; |
371 | 383 | ||
372 | 384 | ||
373 | module_param_array(file, charp, &mod_data.num_filenames, S_IRUGO); | 385 | module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames, |
386 | S_IRUGO); | ||
374 | MODULE_PARM_DESC(file, "names of backing files or devices"); | 387 | MODULE_PARM_DESC(file, "names of backing files or devices"); |
375 | 388 | ||
376 | module_param_array(ro, bool, &mod_data.num_ros, S_IRUGO); | 389 | module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); |
377 | MODULE_PARM_DESC(ro, "true to force read-only"); | 390 | MODULE_PARM_DESC(ro, "true to force read-only"); |
378 | 391 | ||
379 | module_param_named(luns, mod_data.nluns, uint, S_IRUGO); | 392 | module_param_named(luns, mod_data.nluns, uint, S_IRUGO); |
@@ -1795,6 +1808,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1795 | * the bulk-out maxpacket size */ | 1808 | * the bulk-out maxpacket size */ |
1796 | bh->outreq->length = bh->bulk_out_intended_length = | 1809 | bh->outreq->length = bh->bulk_out_intended_length = |
1797 | amount; | 1810 | amount; |
1811 | bh->outreq->short_not_ok = 1; | ||
1798 | start_transfer(fsg, fsg->bulk_out, bh->outreq, | 1812 | start_transfer(fsg, fsg->bulk_out, bh->outreq, |
1799 | &bh->outreq_busy, &bh->state); | 1813 | &bh->outreq_busy, &bh->state); |
1800 | fsg->next_buffhd_to_fill = bh->next; | 1814 | fsg->next_buffhd_to_fill = bh->next; |
@@ -2398,6 +2412,7 @@ static int throw_away_data(struct fsg_dev *fsg) | |||
2398 | * the bulk-out maxpacket size */ | 2412 | * the bulk-out maxpacket size */ |
2399 | bh->outreq->length = bh->bulk_out_intended_length = | 2413 | bh->outreq->length = bh->bulk_out_intended_length = |
2400 | amount; | 2414 | amount; |
2415 | bh->outreq->short_not_ok = 1; | ||
2401 | start_transfer(fsg, fsg->bulk_out, bh->outreq, | 2416 | start_transfer(fsg, fsg->bulk_out, bh->outreq, |
2402 | &bh->outreq_busy, &bh->state); | 2417 | &bh->outreq_busy, &bh->state); |
2403 | fsg->next_buffhd_to_fill = bh->next; | 2418 | fsg->next_buffhd_to_fill = bh->next; |
@@ -3029,6 +3044,7 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3029 | 3044 | ||
3030 | /* Queue a request to read a Bulk-only CBW */ | 3045 | /* Queue a request to read a Bulk-only CBW */ |
3031 | set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); | 3046 | set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); |
3047 | bh->outreq->short_not_ok = 1; | ||
3032 | start_transfer(fsg, fsg->bulk_out, bh->outreq, | 3048 | start_transfer(fsg, fsg->bulk_out, bh->outreq, |
3033 | &bh->outreq_busy, &bh->state); | 3049 | &bh->outreq_busy, &bh->state); |
3034 | 3050 | ||
@@ -3859,7 +3875,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3859 | 3875 | ||
3860 | for (i = 0; i < fsg->nluns; ++i) { | 3876 | for (i = 0; i < fsg->nluns; ++i) { |
3861 | curlun = &fsg->luns[i]; | 3877 | curlun = &fsg->luns[i]; |
3862 | curlun->ro = ro[i]; | 3878 | curlun->ro = mod_data.ro[i]; |
3863 | curlun->dev.parent = &gadget->dev; | 3879 | curlun->dev.parent = &gadget->dev; |
3864 | curlun->dev.driver = &fsg_driver.driver; | 3880 | curlun->dev.driver = &fsg_driver.driver; |
3865 | dev_set_drvdata(&curlun->dev, fsg); | 3881 | dev_set_drvdata(&curlun->dev, fsg); |
@@ -3876,8 +3892,9 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3876 | kref_get(&fsg->ref); | 3892 | kref_get(&fsg->ref); |
3877 | } | 3893 | } |
3878 | 3894 | ||
3879 | if (file[i] && *file[i]) { | 3895 | if (mod_data.file[i] && *mod_data.file[i]) { |
3880 | if ((rc = open_backing_file(curlun, file[i])) != 0) | 3896 | if ((rc = open_backing_file(curlun, |
3897 | mod_data.file[i])) != 0) | ||
3881 | goto out; | 3898 | goto out; |
3882 | } else if (!mod_data.removable) { | 3899 | } else if (!mod_data.removable) { |
3883 | ERROR(fsg, "no file given for LUN%d\n", i); | 3900 | ERROR(fsg, "no file given for LUN%d\n", i); |
@@ -3953,6 +3970,9 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3953 | for (i = 0; i < NUM_BUFFERS; ++i) { | 3970 | for (i = 0; i < NUM_BUFFERS; ++i) { |
3954 | struct fsg_buffhd *bh = &fsg->buffhds[i]; | 3971 | struct fsg_buffhd *bh = &fsg->buffhds[i]; |
3955 | 3972 | ||
3973 | /* Allocate for the bulk-in endpoint. We assume that | ||
3974 | * the buffer will also work with the bulk-out (and | ||
3975 | * interrupt-in) endpoint. */ | ||
3956 | bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen, | 3976 | bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen, |
3957 | &bh->dma, GFP_KERNEL); | 3977 | &bh->dma, GFP_KERNEL); |
3958 | if (!bh->buf) | 3978 | if (!bh->buf) |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index c4081407171f..aa80f0910720 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -100,9 +100,9 @@ | |||
100 | #define gadget_is_musbhsfc(g) 0 | 100 | #define gadget_is_musbhsfc(g) 0 |
101 | #endif | 101 | #endif |
102 | 102 | ||
103 | /* Mentor high speed "dual role" controller, peripheral mode */ | 103 | /* Mentor high speed "dual role" controller, in peripheral role */ |
104 | #ifdef CONFIG_USB_GADGET_MUSBHDRC | 104 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
105 | #define gadget_is_musbhdrc(g) !strcmp("musbhdrc_udc", (g)->name) | 105 | #define gadget_is_musbhdrc(g) !strcmp("musb_hdrc", (g)->name) |
106 | #else | 106 | #else |
107 | #define gadget_is_musbhdrc(g) 0 | 107 | #define gadget_is_musbhdrc(g) 0 |
108 | #endif | 108 | #endif |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 3f618ce6998d..42b457030b03 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -810,7 +810,7 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
810 | if (value == 0) | 810 | if (value == 0) |
811 | data->state = STATE_EP_ENABLED; | 811 | data->state = STATE_EP_ENABLED; |
812 | break; | 812 | break; |
813 | #ifdef HIGHSPEED | 813 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
814 | case USB_SPEED_HIGH: | 814 | case USB_SPEED_HIGH: |
815 | /* fails if caller didn't provide that descriptor... */ | 815 | /* fails if caller didn't provide that descriptor... */ |
816 | value = usb_ep_enable (ep, &data->hs_desc); | 816 | value = usb_ep_enable (ep, &data->hs_desc); |
@@ -982,7 +982,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
982 | /* assume that was SET_CONFIGURATION */ | 982 | /* assume that was SET_CONFIGURATION */ |
983 | if (dev->current_config) { | 983 | if (dev->current_config) { |
984 | unsigned power; | 984 | unsigned power; |
985 | #ifdef HIGHSPEED | 985 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
986 | if (dev->gadget->speed == USB_SPEED_HIGH) | 986 | if (dev->gadget->speed == USB_SPEED_HIGH) |
987 | power = dev->hs_config->bMaxPower; | 987 | power = dev->hs_config->bMaxPower; |
988 | else | 988 | else |
@@ -1262,7 +1262,7 @@ static struct file_operations ep0_io_operations = { | |||
1262 | * Unrecognized ep0 requests may be handled in user space. | 1262 | * Unrecognized ep0 requests may be handled in user space. |
1263 | */ | 1263 | */ |
1264 | 1264 | ||
1265 | #ifdef HIGHSPEED | 1265 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1266 | static void make_qualifier (struct dev_data *dev) | 1266 | static void make_qualifier (struct dev_data *dev) |
1267 | { | 1267 | { |
1268 | struct usb_qualifier_descriptor qual; | 1268 | struct usb_qualifier_descriptor qual; |
@@ -1291,7 +1291,7 @@ static int | |||
1291 | config_buf (struct dev_data *dev, u8 type, unsigned index) | 1291 | config_buf (struct dev_data *dev, u8 type, unsigned index) |
1292 | { | 1292 | { |
1293 | int len; | 1293 | int len; |
1294 | #ifdef HIGHSPEED | 1294 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1295 | int hs; | 1295 | int hs; |
1296 | #endif | 1296 | #endif |
1297 | 1297 | ||
@@ -1299,7 +1299,7 @@ config_buf (struct dev_data *dev, u8 type, unsigned index) | |||
1299 | if (index > 0) | 1299 | if (index > 0) |
1300 | return -EINVAL; | 1300 | return -EINVAL; |
1301 | 1301 | ||
1302 | #ifdef HIGHSPEED | 1302 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1303 | hs = (dev->gadget->speed == USB_SPEED_HIGH); | 1303 | hs = (dev->gadget->speed == USB_SPEED_HIGH); |
1304 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 1304 | if (type == USB_DT_OTHER_SPEED_CONFIG) |
1305 | hs = !hs; | 1305 | hs = !hs; |
@@ -1335,12 +1335,12 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1335 | dev->state = STATE_CONNECTED; | 1335 | dev->state = STATE_CONNECTED; |
1336 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; | 1336 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; |
1337 | 1337 | ||
1338 | #ifdef HIGHSPEED | 1338 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1339 | if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { | 1339 | if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { |
1340 | ERROR (dev, "no high speed config??\n"); | 1340 | ERROR (dev, "no high speed config??\n"); |
1341 | return -EINVAL; | 1341 | return -EINVAL; |
1342 | } | 1342 | } |
1343 | #endif /* HIGHSPEED */ | 1343 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ |
1344 | 1344 | ||
1345 | INFO (dev, "connected\n"); | 1345 | INFO (dev, "connected\n"); |
1346 | event = next_event (dev, GADGETFS_CONNECT); | 1346 | event = next_event (dev, GADGETFS_CONNECT); |
@@ -1352,11 +1352,11 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1352 | /* ... down_trylock (&data->lock) ... */ | 1352 | /* ... down_trylock (&data->lock) ... */ |
1353 | if (data->state != STATE_EP_DEFER_ENABLE) | 1353 | if (data->state != STATE_EP_DEFER_ENABLE) |
1354 | continue; | 1354 | continue; |
1355 | #ifdef HIGHSPEED | 1355 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1356 | if (gadget->speed == USB_SPEED_HIGH) | 1356 | if (gadget->speed == USB_SPEED_HIGH) |
1357 | value = usb_ep_enable (ep, &data->hs_desc); | 1357 | value = usb_ep_enable (ep, &data->hs_desc); |
1358 | else | 1358 | else |
1359 | #endif /* HIGHSPEED */ | 1359 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ |
1360 | value = usb_ep_enable (ep, &data->desc); | 1360 | value = usb_ep_enable (ep, &data->desc); |
1361 | if (value) { | 1361 | if (value) { |
1362 | ERROR (dev, "deferred %s enable --> %d\n", | 1362 | ERROR (dev, "deferred %s enable --> %d\n", |
@@ -1391,7 +1391,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1391 | value = min (w_length, (u16) sizeof *dev->dev); | 1391 | value = min (w_length, (u16) sizeof *dev->dev); |
1392 | req->buf = dev->dev; | 1392 | req->buf = dev->dev; |
1393 | break; | 1393 | break; |
1394 | #ifdef HIGHSPEED | 1394 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1395 | case USB_DT_DEVICE_QUALIFIER: | 1395 | case USB_DT_DEVICE_QUALIFIER: |
1396 | if (!dev->hs_config) | 1396 | if (!dev->hs_config) |
1397 | break; | 1397 | break; |
@@ -1428,7 +1428,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1428 | // user mode expected to disable endpoints | 1428 | // user mode expected to disable endpoints |
1429 | } else { | 1429 | } else { |
1430 | u8 config, power; | 1430 | u8 config, power; |
1431 | #ifdef HIGHSPEED | 1431 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1432 | if (gadget->speed == USB_SPEED_HIGH) { | 1432 | if (gadget->speed == USB_SPEED_HIGH) { |
1433 | config = dev->hs_config->bConfigurationValue; | 1433 | config = dev->hs_config->bConfigurationValue; |
1434 | power = dev->hs_config->bMaxPower; | 1434 | power = dev->hs_config->bMaxPower; |
@@ -1728,7 +1728,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) | |||
1728 | } | 1728 | } |
1729 | 1729 | ||
1730 | static struct usb_gadget_driver gadgetfs_driver = { | 1730 | static struct usb_gadget_driver gadgetfs_driver = { |
1731 | #ifdef HIGHSPEED | 1731 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1732 | .speed = USB_SPEED_HIGH, | 1732 | .speed = USB_SPEED_HIGH, |
1733 | #else | 1733 | #else |
1734 | .speed = USB_SPEED_FULL, | 1734 | .speed = USB_SPEED_FULL, |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index fb73dc100535..6a4b93ad1082 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * Copyright (C) 2003 David Brownell | 26 | * Copyright (C) 2003 David Brownell |
27 | * Copyright (C) 2003-2005 PLX Technology, Inc. | 27 | * Copyright (C) 2003-2005 PLX Technology, Inc. |
28 | * | 28 | * |
29 | * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility with 2282 chip | ||
30 | * | ||
29 | * This program is free software; you can redistribute it and/or modify | 31 | * This program is free software; you can redistribute it and/or modify |
30 | * it under the terms of the GNU General Public License as published by | 32 | * it under the terms of the GNU General Public License as published by |
31 | * the Free Software Foundation; either version 2 of the License, or | 33 | * the Free Software Foundation; either version 2 of the License, or |
@@ -71,8 +73,8 @@ | |||
71 | #include <asm/unaligned.h> | 73 | #include <asm/unaligned.h> |
72 | 74 | ||
73 | 75 | ||
74 | #define DRIVER_DESC "PLX NET2280 USB Peripheral Controller" | 76 | #define DRIVER_DESC "PLX NET228x USB Peripheral Controller" |
75 | #define DRIVER_VERSION "2005 Feb 03" | 77 | #define DRIVER_VERSION "2005 Sept 27" |
76 | 78 | ||
77 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | 79 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) |
78 | #define EP_DONTUSE 13 /* nonzero */ | 80 | #define EP_DONTUSE 13 /* nonzero */ |
@@ -118,7 +120,7 @@ module_param (fifo_mode, ushort, 0644); | |||
118 | /* enable_suspend -- When enabled, the driver will respond to | 120 | /* enable_suspend -- When enabled, the driver will respond to |
119 | * USB suspend requests by powering down the NET2280. Otherwise, | 121 | * USB suspend requests by powering down the NET2280. Otherwise, |
120 | * USB suspend requests will be ignored. This is acceptible for | 122 | * USB suspend requests will be ignored. This is acceptible for |
121 | * self-powered devices, and helps avoid some quirks. | 123 | * self-powered devices |
122 | */ | 124 | */ |
123 | static int enable_suspend = 0; | 125 | static int enable_suspend = 0; |
124 | 126 | ||
@@ -223,6 +225,11 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
223 | ep->is_in = (tmp & USB_DIR_IN) != 0; | 225 | ep->is_in = (tmp & USB_DIR_IN) != 0; |
224 | if (!ep->is_in) | 226 | if (!ep->is_in) |
225 | writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | 227 | writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); |
228 | else if (dev->pdev->device != 0x2280) { | ||
229 | /* Added for 2282, Don't use nak packets on an in endpoint, this was ignored on 2280 */ | ||
230 | writel ((1 << CLEAR_NAK_OUT_PACKETS) | ||
231 | | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); | ||
232 | } | ||
226 | 233 | ||
227 | writel (tmp, &ep->regs->ep_cfg); | 234 | writel (tmp, &ep->regs->ep_cfg); |
228 | 235 | ||
@@ -232,8 +239,9 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
232 | writel (tmp, &dev->regs->pciirqenb0); | 239 | writel (tmp, &dev->regs->pciirqenb0); |
233 | 240 | ||
234 | tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) | 241 | tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) |
235 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE) | 242 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); |
236 | | readl (&ep->regs->ep_irqenb); | 243 | if (dev->pdev->device == 0x2280) |
244 | tmp |= readl (&ep->regs->ep_irqenb); | ||
237 | writel (tmp, &ep->regs->ep_irqenb); | 245 | writel (tmp, &ep->regs->ep_irqenb); |
238 | } else { /* dma, per-request */ | 246 | } else { /* dma, per-request */ |
239 | tmp = (1 << (8 + ep->num)); /* completion */ | 247 | tmp = (1 << (8 + ep->num)); /* completion */ |
@@ -314,10 +322,18 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) | |||
314 | /* init to our chosen defaults, notably so that we NAK OUT | 322 | /* init to our chosen defaults, notably so that we NAK OUT |
315 | * packets until the driver queues a read (+note erratum 0112) | 323 | * packets until the driver queues a read (+note erratum 0112) |
316 | */ | 324 | */ |
317 | tmp = (1 << SET_NAK_OUT_PACKETS_MODE) | 325 | if (!ep->is_in || ep->dev->pdev->device == 0x2280) { |
326 | tmp = (1 << SET_NAK_OUT_PACKETS_MODE) | ||
318 | | (1 << SET_NAK_OUT_PACKETS) | 327 | | (1 << SET_NAK_OUT_PACKETS) |
319 | | (1 << CLEAR_EP_HIDE_STATUS_PHASE) | 328 | | (1 << CLEAR_EP_HIDE_STATUS_PHASE) |
320 | | (1 << CLEAR_INTERRUPT_MODE); | 329 | | (1 << CLEAR_INTERRUPT_MODE); |
330 | } else { | ||
331 | /* added for 2282 */ | ||
332 | tmp = (1 << CLEAR_NAK_OUT_PACKETS_MODE) | ||
333 | | (1 << CLEAR_NAK_OUT_PACKETS) | ||
334 | | (1 << CLEAR_EP_HIDE_STATUS_PHASE) | ||
335 | | (1 << CLEAR_INTERRUPT_MODE); | ||
336 | } | ||
321 | 337 | ||
322 | if (ep->num != 0) { | 338 | if (ep->num != 0) { |
323 | tmp |= (1 << CLEAR_ENDPOINT_TOGGLE) | 339 | tmp |= (1 << CLEAR_ENDPOINT_TOGGLE) |
@@ -326,14 +342,18 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) | |||
326 | writel (tmp, &ep->regs->ep_rsp); | 342 | writel (tmp, &ep->regs->ep_rsp); |
327 | 343 | ||
328 | /* scrub most status bits, and flush any fifo state */ | 344 | /* scrub most status bits, and flush any fifo state */ |
329 | writel ( (1 << TIMEOUT) | 345 | if (ep->dev->pdev->device == 0x2280) |
346 | tmp = (1 << FIFO_OVERFLOW) | ||
347 | | (1 << FIFO_UNDERFLOW); | ||
348 | else | ||
349 | tmp = 0; | ||
350 | |||
351 | writel (tmp | (1 << TIMEOUT) | ||
330 | | (1 << USB_STALL_SENT) | 352 | | (1 << USB_STALL_SENT) |
331 | | (1 << USB_IN_NAK_SENT) | 353 | | (1 << USB_IN_NAK_SENT) |
332 | | (1 << USB_IN_ACK_RCVD) | 354 | | (1 << USB_IN_ACK_RCVD) |
333 | | (1 << USB_OUT_PING_NAK_SENT) | 355 | | (1 << USB_OUT_PING_NAK_SENT) |
334 | | (1 << USB_OUT_ACK_SENT) | 356 | | (1 << USB_OUT_ACK_SENT) |
335 | | (1 << FIFO_OVERFLOW) | ||
336 | | (1 << FIFO_UNDERFLOW) | ||
337 | | (1 << FIFO_FLUSH) | 357 | | (1 << FIFO_FLUSH) |
338 | | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | 358 | | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) |
339 | | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | 359 | | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) |
@@ -718,7 +738,7 @@ fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid) | |||
718 | */ | 738 | */ |
719 | if (ep->is_in) | 739 | if (ep->is_in) |
720 | dmacount |= (1 << DMA_DIRECTION); | 740 | dmacount |= (1 << DMA_DIRECTION); |
721 | else if ((dmacount % ep->ep.maxpacket) != 0) | 741 | if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) || ep->dev->pdev->device != 0x2280) |
722 | dmacount |= (1 << END_OF_CHAIN); | 742 | dmacount |= (1 << END_OF_CHAIN); |
723 | 743 | ||
724 | req->valid = valid; | 744 | req->valid = valid; |
@@ -760,9 +780,12 @@ static inline void stop_dma (struct net2280_dma_regs __iomem *dma) | |||
760 | static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma) | 780 | static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma) |
761 | { | 781 | { |
762 | struct net2280_dma_regs __iomem *dma = ep->dma; | 782 | struct net2280_dma_regs __iomem *dma = ep->dma; |
783 | unsigned int tmp = (1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION); | ||
763 | 784 | ||
764 | writel ((1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION), | 785 | if (ep->dev->pdev->device != 0x2280) |
765 | &dma->dmacount); | 786 | tmp |= (1 << END_OF_CHAIN); |
787 | |||
788 | writel (tmp, &dma->dmacount); | ||
766 | writel (readl (&dma->dmastat), &dma->dmastat); | 789 | writel (readl (&dma->dmastat), &dma->dmastat); |
767 | 790 | ||
768 | writel (td_dma, &dma->dmadesc); | 791 | writel (td_dma, &dma->dmadesc); |
@@ -2110,7 +2133,11 @@ static void handle_ep_small (struct net2280_ep *ep) | |||
2110 | VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n", | 2133 | VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n", |
2111 | ep->ep.name, t, req ? &req->req : 0); | 2134 | ep->ep.name, t, req ? &req->req : 0); |
2112 | #endif | 2135 | #endif |
2113 | writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); | 2136 | if (!ep->is_in || ep->dev->pdev->device == 0x2280) |
2137 | writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); | ||
2138 | else | ||
2139 | /* Added for 2282 */ | ||
2140 | writel (t, &ep->regs->ep_stat); | ||
2114 | 2141 | ||
2115 | /* for ep0, monitor token irqs to catch data stage length errors | 2142 | /* for ep0, monitor token irqs to catch data stage length errors |
2116 | * and to synchronize on status. | 2143 | * and to synchronize on status. |
@@ -2214,7 +2241,8 @@ static void handle_ep_small (struct net2280_ep *ep) | |||
2214 | if (likely (req)) { | 2241 | if (likely (req)) { |
2215 | req->td->dmacount = 0; | 2242 | req->td->dmacount = 0; |
2216 | t = readl (&ep->regs->ep_avail); | 2243 | t = readl (&ep->regs->ep_avail); |
2217 | dma_done (ep, req, count, t); | 2244 | dma_done (ep, req, count, |
2245 | (ep->out_overflow || t) ? -EOVERFLOW : 0); | ||
2218 | } | 2246 | } |
2219 | 2247 | ||
2220 | /* also flush to prevent erratum 0106 trouble */ | 2248 | /* also flush to prevent erratum 0106 trouble */ |
@@ -2337,7 +2365,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2337 | u32 raw [2]; | 2365 | u32 raw [2]; |
2338 | struct usb_ctrlrequest r; | 2366 | struct usb_ctrlrequest r; |
2339 | } u; | 2367 | } u; |
2340 | int tmp = 0; | 2368 | int tmp; |
2341 | struct net2280_request *req; | 2369 | struct net2280_request *req; |
2342 | 2370 | ||
2343 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) { | 2371 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) { |
@@ -2364,14 +2392,19 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2364 | } | 2392 | } |
2365 | ep->stopped = 0; | 2393 | ep->stopped = 0; |
2366 | dev->protocol_stall = 0; | 2394 | dev->protocol_stall = 0; |
2367 | writel ( (1 << TIMEOUT) | 2395 | |
2396 | if (ep->dev->pdev->device == 0x2280) | ||
2397 | tmp = (1 << FIFO_OVERFLOW) | ||
2398 | | (1 << FIFO_UNDERFLOW); | ||
2399 | else | ||
2400 | tmp = 0; | ||
2401 | |||
2402 | writel (tmp | (1 << TIMEOUT) | ||
2368 | | (1 << USB_STALL_SENT) | 2403 | | (1 << USB_STALL_SENT) |
2369 | | (1 << USB_IN_NAK_SENT) | 2404 | | (1 << USB_IN_NAK_SENT) |
2370 | | (1 << USB_IN_ACK_RCVD) | 2405 | | (1 << USB_IN_ACK_RCVD) |
2371 | | (1 << USB_OUT_PING_NAK_SENT) | 2406 | | (1 << USB_OUT_PING_NAK_SENT) |
2372 | | (1 << USB_OUT_ACK_SENT) | 2407 | | (1 << USB_OUT_ACK_SENT) |
2373 | | (1 << FIFO_OVERFLOW) | ||
2374 | | (1 << FIFO_UNDERFLOW) | ||
2375 | | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | 2408 | | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) |
2376 | | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | 2409 | | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) |
2377 | | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | 2410 | | (1 << DATA_PACKET_RECEIVED_INTERRUPT) |
@@ -2385,6 +2418,8 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2385 | cpu_to_le32s (&u.raw [0]); | 2418 | cpu_to_le32s (&u.raw [0]); |
2386 | cpu_to_le32s (&u.raw [1]); | 2419 | cpu_to_le32s (&u.raw [1]); |
2387 | 2420 | ||
2421 | tmp = 0; | ||
2422 | |||
2388 | #define w_value le16_to_cpup (&u.r.wValue) | 2423 | #define w_value le16_to_cpup (&u.r.wValue) |
2389 | #define w_index le16_to_cpup (&u.r.wIndex) | 2424 | #define w_index le16_to_cpup (&u.r.wIndex) |
2390 | #define w_length le16_to_cpup (&u.r.wLength) | 2425 | #define w_length le16_to_cpup (&u.r.wLength) |
@@ -2594,10 +2629,17 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat) | |||
2594 | writel (stat, &dev->regs->irqstat1); | 2629 | writel (stat, &dev->regs->irqstat1); |
2595 | 2630 | ||
2596 | /* some status we can just ignore */ | 2631 | /* some status we can just ignore */ |
2597 | stat &= ~((1 << CONTROL_STATUS_INTERRUPT) | 2632 | if (dev->pdev->device == 0x2280) |
2598 | | (1 << SUSPEND_REQUEST_INTERRUPT) | 2633 | stat &= ~((1 << CONTROL_STATUS_INTERRUPT) |
2599 | | (1 << RESUME_INTERRUPT) | 2634 | | (1 << SUSPEND_REQUEST_INTERRUPT) |
2600 | | (1 << SOF_INTERRUPT)); | 2635 | | (1 << RESUME_INTERRUPT) |
2636 | | (1 << SOF_INTERRUPT)); | ||
2637 | else | ||
2638 | stat &= ~((1 << CONTROL_STATUS_INTERRUPT) | ||
2639 | | (1 << RESUME_INTERRUPT) | ||
2640 | | (1 << SOF_DOWN_INTERRUPT) | ||
2641 | | (1 << SOF_INTERRUPT)); | ||
2642 | |||
2601 | if (!stat) | 2643 | if (!stat) |
2602 | return; | 2644 | return; |
2603 | // DEBUG (dev, "irqstat1 %08x\n", stat); | 2645 | // DEBUG (dev, "irqstat1 %08x\n", stat); |
@@ -2939,6 +2981,13 @@ static struct pci_device_id pci_ids [] = { { | |||
2939 | .device = 0x2280, | 2981 | .device = 0x2280, |
2940 | .subvendor = PCI_ANY_ID, | 2982 | .subvendor = PCI_ANY_ID, |
2941 | .subdevice = PCI_ANY_ID, | 2983 | .subdevice = PCI_ANY_ID, |
2984 | }, { | ||
2985 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
2986 | .class_mask = ~0, | ||
2987 | .vendor = 0x17cc, | ||
2988 | .device = 0x2282, | ||
2989 | .subvendor = PCI_ANY_ID, | ||
2990 | .subdevice = PCI_ANY_ID, | ||
2942 | 2991 | ||
2943 | }, { /* end: all zeroes */ } | 2992 | }, { /* end: all zeroes */ } |
2944 | }; | 2993 | }; |
diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h index fff4509cf340..957d6df34015 100644 --- a/drivers/usb/gadget/net2280.h +++ b/drivers/usb/gadget/net2280.h | |||
@@ -22,420 +22,7 @@ | |||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | */ | 23 | */ |
24 | 24 | ||
25 | /*-------------------------------------------------------------------------*/ | 25 | #include <linux/usb/net2280.h> |
26 | |||
27 | /* NET2280 MEMORY MAPPED REGISTERS | ||
28 | * | ||
29 | * The register layout came from the chip documentation, and the bit | ||
30 | * number definitions were extracted from chip specification. | ||
31 | * | ||
32 | * Use the shift operator ('<<') to build bit masks, with readl/writel | ||
33 | * to access the registers through PCI. | ||
34 | */ | ||
35 | |||
36 | /* main registers, BAR0 + 0x0000 */ | ||
37 | struct net2280_regs { | ||
38 | // offset 0x0000 | ||
39 | u32 devinit; | ||
40 | #define LOCAL_CLOCK_FREQUENCY 8 | ||
41 | #define FORCE_PCI_RESET 7 | ||
42 | #define PCI_ID 6 | ||
43 | #define PCI_ENABLE 5 | ||
44 | #define FIFO_SOFT_RESET 4 | ||
45 | #define CFG_SOFT_RESET 3 | ||
46 | #define PCI_SOFT_RESET 2 | ||
47 | #define USB_SOFT_RESET 1 | ||
48 | #define M8051_RESET 0 | ||
49 | u32 eectl; | ||
50 | #define EEPROM_ADDRESS_WIDTH 23 | ||
51 | #define EEPROM_CHIP_SELECT_ACTIVE 22 | ||
52 | #define EEPROM_PRESENT 21 | ||
53 | #define EEPROM_VALID 20 | ||
54 | #define EEPROM_BUSY 19 | ||
55 | #define EEPROM_CHIP_SELECT_ENABLE 18 | ||
56 | #define EEPROM_BYTE_READ_START 17 | ||
57 | #define EEPROM_BYTE_WRITE_START 16 | ||
58 | #define EEPROM_READ_DATA 8 | ||
59 | #define EEPROM_WRITE_DATA 0 | ||
60 | u32 eeclkfreq; | ||
61 | u32 _unused0; | ||
62 | // offset 0x0010 | ||
63 | |||
64 | u32 pciirqenb0; /* interrupt PCI master ... */ | ||
65 | #define SETUP_PACKET_INTERRUPT_ENABLE 7 | ||
66 | #define ENDPOINT_F_INTERRUPT_ENABLE 6 | ||
67 | #define ENDPOINT_E_INTERRUPT_ENABLE 5 | ||
68 | #define ENDPOINT_D_INTERRUPT_ENABLE 4 | ||
69 | #define ENDPOINT_C_INTERRUPT_ENABLE 3 | ||
70 | #define ENDPOINT_B_INTERRUPT_ENABLE 2 | ||
71 | #define ENDPOINT_A_INTERRUPT_ENABLE 1 | ||
72 | #define ENDPOINT_0_INTERRUPT_ENABLE 0 | ||
73 | u32 pciirqenb1; | ||
74 | #define PCI_INTERRUPT_ENABLE 31 | ||
75 | #define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 | ||
76 | #define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 | ||
77 | #define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 | ||
78 | #define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 | ||
79 | #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 | ||
80 | #define PCI_TARGET_ABORT_ASSERTED_INTERRUPT_ENABLE 18 | ||
81 | #define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 | ||
82 | #define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 | ||
83 | #define GPIO_INTERRUPT_ENABLE 13 | ||
84 | #define DMA_D_INTERRUPT_ENABLE 12 | ||
85 | #define DMA_C_INTERRUPT_ENABLE 11 | ||
86 | #define DMA_B_INTERRUPT_ENABLE 10 | ||
87 | #define DMA_A_INTERRUPT_ENABLE 9 | ||
88 | #define EEPROM_DONE_INTERRUPT_ENABLE 8 | ||
89 | #define VBUS_INTERRUPT_ENABLE 7 | ||
90 | #define CONTROL_STATUS_INTERRUPT_ENABLE 6 | ||
91 | #define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 | ||
92 | #define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 | ||
93 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 | ||
94 | #define RESUME_INTERRUPT_ENABLE 1 | ||
95 | #define SOF_INTERRUPT_ENABLE 0 | ||
96 | u32 cpu_irqenb0; /* ... or onboard 8051 */ | ||
97 | #define SETUP_PACKET_INTERRUPT_ENABLE 7 | ||
98 | #define ENDPOINT_F_INTERRUPT_ENABLE 6 | ||
99 | #define ENDPOINT_E_INTERRUPT_ENABLE 5 | ||
100 | #define ENDPOINT_D_INTERRUPT_ENABLE 4 | ||
101 | #define ENDPOINT_C_INTERRUPT_ENABLE 3 | ||
102 | #define ENDPOINT_B_INTERRUPT_ENABLE 2 | ||
103 | #define ENDPOINT_A_INTERRUPT_ENABLE 1 | ||
104 | #define ENDPOINT_0_INTERRUPT_ENABLE 0 | ||
105 | u32 cpu_irqenb1; | ||
106 | #define CPU_INTERRUPT_ENABLE 31 | ||
107 | #define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 | ||
108 | #define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 | ||
109 | #define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 | ||
110 | #define PCI_INTA_INTERRUPT_ENABLE 24 | ||
111 | #define PCI_PME_INTERRUPT_ENABLE 23 | ||
112 | #define PCI_SERR_INTERRUPT_ENABLE 22 | ||
113 | #define PCI_PERR_INTERRUPT_ENABLE 21 | ||
114 | #define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 | ||
115 | #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 | ||
116 | #define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 | ||
117 | #define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 | ||
118 | #define GPIO_INTERRUPT_ENABLE 13 | ||
119 | #define DMA_D_INTERRUPT_ENABLE 12 | ||
120 | #define DMA_C_INTERRUPT_ENABLE 11 | ||
121 | #define DMA_B_INTERRUPT_ENABLE 10 | ||
122 | #define DMA_A_INTERRUPT_ENABLE 9 | ||
123 | #define EEPROM_DONE_INTERRUPT_ENABLE 8 | ||
124 | #define VBUS_INTERRUPT_ENABLE 7 | ||
125 | #define CONTROL_STATUS_INTERRUPT_ENABLE 6 | ||
126 | #define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 | ||
127 | #define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 | ||
128 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 | ||
129 | #define RESUME_INTERRUPT_ENABLE 1 | ||
130 | #define SOF_INTERRUPT_ENABLE 0 | ||
131 | |||
132 | // offset 0x0020 | ||
133 | u32 _unused1; | ||
134 | u32 usbirqenb1; | ||
135 | #define USB_INTERRUPT_ENABLE 31 | ||
136 | #define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 | ||
137 | #define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 | ||
138 | #define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 | ||
139 | #define PCI_INTA_INTERRUPT_ENABLE 24 | ||
140 | #define PCI_PME_INTERRUPT_ENABLE 23 | ||
141 | #define PCI_SERR_INTERRUPT_ENABLE 22 | ||
142 | #define PCI_PERR_INTERRUPT_ENABLE 21 | ||
143 | #define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 | ||
144 | #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 | ||
145 | #define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 | ||
146 | #define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 | ||
147 | #define GPIO_INTERRUPT_ENABLE 13 | ||
148 | #define DMA_D_INTERRUPT_ENABLE 12 | ||
149 | #define DMA_C_INTERRUPT_ENABLE 11 | ||
150 | #define DMA_B_INTERRUPT_ENABLE 10 | ||
151 | #define DMA_A_INTERRUPT_ENABLE 9 | ||
152 | #define EEPROM_DONE_INTERRUPT_ENABLE 8 | ||
153 | #define VBUS_INTERRUPT_ENABLE 7 | ||
154 | #define CONTROL_STATUS_INTERRUPT_ENABLE 6 | ||
155 | #define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 | ||
156 | #define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 | ||
157 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 | ||
158 | #define RESUME_INTERRUPT_ENABLE 1 | ||
159 | #define SOF_INTERRUPT_ENABLE 0 | ||
160 | u32 irqstat0; | ||
161 | #define INTA_ASSERTED 12 | ||
162 | #define SETUP_PACKET_INTERRUPT 7 | ||
163 | #define ENDPOINT_F_INTERRUPT 6 | ||
164 | #define ENDPOINT_E_INTERRUPT 5 | ||
165 | #define ENDPOINT_D_INTERRUPT 4 | ||
166 | #define ENDPOINT_C_INTERRUPT 3 | ||
167 | #define ENDPOINT_B_INTERRUPT 2 | ||
168 | #define ENDPOINT_A_INTERRUPT 1 | ||
169 | #define ENDPOINT_0_INTERRUPT 0 | ||
170 | u32 irqstat1; | ||
171 | #define POWER_STATE_CHANGE_INTERRUPT 27 | ||
172 | #define PCI_ARBITER_TIMEOUT_INTERRUPT 26 | ||
173 | #define PCI_PARITY_ERROR_INTERRUPT 25 | ||
174 | #define PCI_INTA_INTERRUPT 24 | ||
175 | #define PCI_PME_INTERRUPT 23 | ||
176 | #define PCI_SERR_INTERRUPT 22 | ||
177 | #define PCI_PERR_INTERRUPT 21 | ||
178 | #define PCI_MASTER_ABORT_RECEIVED_INTERRUPT 20 | ||
179 | #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19 | ||
180 | #define PCI_RETRY_ABORT_INTERRUPT 17 | ||
181 | #define PCI_MASTER_CYCLE_DONE_INTERRUPT 16 | ||
182 | #define GPIO_INTERRUPT 13 | ||
183 | #define DMA_D_INTERRUPT 12 | ||
184 | #define DMA_C_INTERRUPT 11 | ||
185 | #define DMA_B_INTERRUPT 10 | ||
186 | #define DMA_A_INTERRUPT 9 | ||
187 | #define EEPROM_DONE_INTERRUPT 8 | ||
188 | #define VBUS_INTERRUPT 7 | ||
189 | #define CONTROL_STATUS_INTERRUPT 6 | ||
190 | #define ROOT_PORT_RESET_INTERRUPT 4 | ||
191 | #define SUSPEND_REQUEST_INTERRUPT 3 | ||
192 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT 2 | ||
193 | #define RESUME_INTERRUPT 1 | ||
194 | #define SOF_INTERRUPT 0 | ||
195 | // offset 0x0030 | ||
196 | u32 idxaddr; | ||
197 | u32 idxdata; | ||
198 | u32 fifoctl; | ||
199 | #define PCI_BASE2_RANGE 16 | ||
200 | #define IGNORE_FIFO_AVAILABILITY 3 | ||
201 | #define PCI_BASE2_SELECT 2 | ||
202 | #define FIFO_CONFIGURATION_SELECT 0 | ||
203 | u32 _unused2; | ||
204 | // offset 0x0040 | ||
205 | u32 memaddr; | ||
206 | #define START 28 | ||
207 | #define DIRECTION 27 | ||
208 | #define FIFO_DIAGNOSTIC_SELECT 24 | ||
209 | #define MEMORY_ADDRESS 0 | ||
210 | u32 memdata0; | ||
211 | u32 memdata1; | ||
212 | u32 _unused3; | ||
213 | // offset 0x0050 | ||
214 | u32 gpioctl; | ||
215 | #define GPIO3_LED_SELECT 12 | ||
216 | #define GPIO3_INTERRUPT_ENABLE 11 | ||
217 | #define GPIO2_INTERRUPT_ENABLE 10 | ||
218 | #define GPIO1_INTERRUPT_ENABLE 9 | ||
219 | #define GPIO0_INTERRUPT_ENABLE 8 | ||
220 | #define GPIO3_OUTPUT_ENABLE 7 | ||
221 | #define GPIO2_OUTPUT_ENABLE 6 | ||
222 | #define GPIO1_OUTPUT_ENABLE 5 | ||
223 | #define GPIO0_OUTPUT_ENABLE 4 | ||
224 | #define GPIO3_DATA 3 | ||
225 | #define GPIO2_DATA 2 | ||
226 | #define GPIO1_DATA 1 | ||
227 | #define GPIO0_DATA 0 | ||
228 | u32 gpiostat; | ||
229 | #define GPIO3_INTERRUPT 3 | ||
230 | #define GPIO2_INTERRUPT 2 | ||
231 | #define GPIO1_INTERRUPT 1 | ||
232 | #define GPIO0_INTERRUPT 0 | ||
233 | } __attribute__ ((packed)); | ||
234 | |||
235 | /* usb control, BAR0 + 0x0080 */ | ||
236 | struct net2280_usb_regs { | ||
237 | // offset 0x0080 | ||
238 | u32 stdrsp; | ||
239 | #define STALL_UNSUPPORTED_REQUESTS 31 | ||
240 | #define SET_TEST_MODE 16 | ||
241 | #define GET_OTHER_SPEED_CONFIGURATION 15 | ||
242 | #define GET_DEVICE_QUALIFIER 14 | ||
243 | #define SET_ADDRESS 13 | ||
244 | #define ENDPOINT_SET_CLEAR_HALT 12 | ||
245 | #define DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP 11 | ||
246 | #define GET_STRING_DESCRIPTOR_2 10 | ||
247 | #define GET_STRING_DESCRIPTOR_1 9 | ||
248 | #define GET_STRING_DESCRIPTOR_0 8 | ||
249 | #define GET_SET_INTERFACE 6 | ||
250 | #define GET_SET_CONFIGURATION 5 | ||
251 | #define GET_CONFIGURATION_DESCRIPTOR 4 | ||
252 | #define GET_DEVICE_DESCRIPTOR 3 | ||
253 | #define GET_ENDPOINT_STATUS 2 | ||
254 | #define GET_INTERFACE_STATUS 1 | ||
255 | #define GET_DEVICE_STATUS 0 | ||
256 | u32 prodvendid; | ||
257 | #define PRODUCT_ID 16 | ||
258 | #define VENDOR_ID 0 | ||
259 | u32 relnum; | ||
260 | u32 usbctl; | ||
261 | #define SERIAL_NUMBER_INDEX 16 | ||
262 | #define PRODUCT_ID_STRING_ENABLE 13 | ||
263 | #define VENDOR_ID_STRING_ENABLE 12 | ||
264 | #define USB_ROOT_PORT_WAKEUP_ENABLE 11 | ||
265 | #define VBUS_PIN 10 | ||
266 | #define TIMED_DISCONNECT 9 | ||
267 | #define SUSPEND_IMMEDIATELY 7 | ||
268 | #define SELF_POWERED_USB_DEVICE 6 | ||
269 | #define REMOTE_WAKEUP_SUPPORT 5 | ||
270 | #define PME_POLARITY 4 | ||
271 | #define USB_DETECT_ENABLE 3 | ||
272 | #define PME_WAKEUP_ENABLE 2 | ||
273 | #define DEVICE_REMOTE_WAKEUP_ENABLE 1 | ||
274 | #define SELF_POWERED_STATUS 0 | ||
275 | // offset 0x0090 | ||
276 | u32 usbstat; | ||
277 | #define HIGH_SPEED 7 | ||
278 | #define FULL_SPEED 6 | ||
279 | #define GENERATE_RESUME 5 | ||
280 | #define GENERATE_DEVICE_REMOTE_WAKEUP 4 | ||
281 | u32 xcvrdiag; | ||
282 | #define FORCE_HIGH_SPEED_MODE 31 | ||
283 | #define FORCE_FULL_SPEED_MODE 30 | ||
284 | #define USB_TEST_MODE 24 | ||
285 | #define LINE_STATE 16 | ||
286 | #define TRANSCEIVER_OPERATION_MODE 2 | ||
287 | #define TRANSCEIVER_SELECT 1 | ||
288 | #define TERMINATION_SELECT 0 | ||
289 | u32 setup0123; | ||
290 | u32 setup4567; | ||
291 | // offset 0x0090 | ||
292 | u32 _unused0; | ||
293 | u32 ouraddr; | ||
294 | #define FORCE_IMMEDIATE 7 | ||
295 | #define OUR_USB_ADDRESS 0 | ||
296 | u32 ourconfig; | ||
297 | } __attribute__ ((packed)); | ||
298 | |||
299 | /* pci control, BAR0 + 0x0100 */ | ||
300 | struct net2280_pci_regs { | ||
301 | // offset 0x0100 | ||
302 | u32 pcimstctl; | ||
303 | #define PCI_ARBITER_PARK_SELECT 13 | ||
304 | #define PCI_MULTI LEVEL_ARBITER 12 | ||
305 | #define PCI_RETRY_ABORT_ENABLE 11 | ||
306 | #define DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE 10 | ||
307 | #define DMA_READ_MULTIPLE_ENABLE 9 | ||
308 | #define DMA_READ_LINE_ENABLE 8 | ||
309 | #define PCI_MASTER_COMMAND_SELECT 6 | ||
310 | #define MEM_READ_OR_WRITE 0 | ||
311 | #define IO_READ_OR_WRITE 1 | ||
312 | #define CFG_READ_OR_WRITE 2 | ||
313 | #define PCI_MASTER_START 5 | ||
314 | #define PCI_MASTER_READ_WRITE 4 | ||
315 | #define PCI_MASTER_WRITE 0 | ||
316 | #define PCI_MASTER_READ 1 | ||
317 | #define PCI_MASTER_BYTE_WRITE_ENABLES 0 | ||
318 | u32 pcimstaddr; | ||
319 | u32 pcimstdata; | ||
320 | u32 pcimststat; | ||
321 | #define PCI_ARBITER_CLEAR 2 | ||
322 | #define PCI_EXTERNAL_ARBITER 1 | ||
323 | #define PCI_HOST_MODE 0 | ||
324 | } __attribute__ ((packed)); | ||
325 | |||
326 | /* dma control, BAR0 + 0x0180 ... array of four structs like this, | ||
327 | * for channels 0..3. see also struct net2280_dma: descriptor | ||
328 | * that can be loaded into some of these registers. | ||
329 | */ | ||
330 | struct net2280_dma_regs { /* [11.7] */ | ||
331 | // offset 0x0180, 0x01a0, 0x01c0, 0x01e0, | ||
332 | u32 dmactl; | ||
333 | #define DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE 25 | ||
334 | #define DMA_CLEAR_COUNT_ENABLE 21 | ||
335 | #define DESCRIPTOR_POLLING_RATE 19 | ||
336 | #define POLL_CONTINUOUS 0 | ||
337 | #define POLL_1_USEC 1 | ||
338 | #define POLL_100_USEC 2 | ||
339 | #define POLL_1_MSEC 3 | ||
340 | #define DMA_VALID_BIT_POLLING_ENABLE 18 | ||
341 | #define DMA_VALID_BIT_ENABLE 17 | ||
342 | #define DMA_SCATTER_GATHER_ENABLE 16 | ||
343 | #define DMA_OUT_AUTO_START_ENABLE 4 | ||
344 | #define DMA_PREEMPT_ENABLE 3 | ||
345 | #define DMA_FIFO_VALIDATE 2 | ||
346 | #define DMA_ENABLE 1 | ||
347 | #define DMA_ADDRESS_HOLD 0 | ||
348 | u32 dmastat; | ||
349 | #define DMA_SCATTER_GATHER_DONE_INTERRUPT 25 | ||
350 | #define DMA_TRANSACTION_DONE_INTERRUPT 24 | ||
351 | #define DMA_ABORT 1 | ||
352 | #define DMA_START 0 | ||
353 | u32 _unused0 [2]; | ||
354 | // offset 0x0190, 0x01b0, 0x01d0, 0x01f0, | ||
355 | u32 dmacount; | ||
356 | #define VALID_BIT 31 | ||
357 | #define DMA_DIRECTION 30 | ||
358 | #define DMA_DONE_INTERRUPT_ENABLE 29 | ||
359 | #define END_OF_CHAIN 28 | ||
360 | #define DMA_BYTE_COUNT_MASK ((1<<24)-1) | ||
361 | #define DMA_BYTE_COUNT 0 | ||
362 | u32 dmaaddr; | ||
363 | u32 dmadesc; | ||
364 | u32 _unused1; | ||
365 | } __attribute__ ((packed)); | ||
366 | |||
367 | /* dedicated endpoint registers, BAR0 + 0x0200 */ | ||
368 | |||
369 | struct net2280_dep_regs { /* [11.8] */ | ||
370 | // offset 0x0200, 0x0210, 0x220, 0x230, 0x240 | ||
371 | u32 dep_cfg; | ||
372 | // offset 0x0204, 0x0214, 0x224, 0x234, 0x244 | ||
373 | u32 dep_rsp; | ||
374 | u32 _unused [2]; | ||
375 | } __attribute__ ((packed)); | ||
376 | |||
377 | /* configurable endpoint registers, BAR0 + 0x0300 ... array of seven structs | ||
378 | * like this, for ep0 then the configurable endpoints A..F | ||
379 | * ep0 reserved for control; E and F have only 64 bytes of fifo | ||
380 | */ | ||
381 | struct net2280_ep_regs { /* [11.9] */ | ||
382 | // offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0 | ||
383 | u32 ep_cfg; | ||
384 | #define ENDPOINT_BYTE_COUNT 16 | ||
385 | #define ENDPOINT_ENABLE 10 | ||
386 | #define ENDPOINT_TYPE 8 | ||
387 | #define ENDPOINT_DIRECTION 7 | ||
388 | #define ENDPOINT_NUMBER 0 | ||
389 | u32 ep_rsp; | ||
390 | #define SET_NAK_OUT_PACKETS 15 | ||
391 | #define SET_EP_HIDE_STATUS_PHASE 14 | ||
392 | #define SET_EP_FORCE_CRC_ERROR 13 | ||
393 | #define SET_INTERRUPT_MODE 12 | ||
394 | #define SET_CONTROL_STATUS_PHASE_HANDSHAKE 11 | ||
395 | #define SET_NAK_OUT_PACKETS_MODE 10 | ||
396 | #define SET_ENDPOINT_TOGGLE 9 | ||
397 | #define SET_ENDPOINT_HALT 8 | ||
398 | #define CLEAR_NAK_OUT_PACKETS 7 | ||
399 | #define CLEAR_EP_HIDE_STATUS_PHASE 6 | ||
400 | #define CLEAR_EP_FORCE_CRC_ERROR 5 | ||
401 | #define CLEAR_INTERRUPT_MODE 4 | ||
402 | #define CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE 3 | ||
403 | #define CLEAR_NAK_OUT_PACKETS_MODE 2 | ||
404 | #define CLEAR_ENDPOINT_TOGGLE 1 | ||
405 | #define CLEAR_ENDPOINT_HALT 0 | ||
406 | u32 ep_irqenb; | ||
407 | #define SHORT_PACKET_OUT_DONE_INTERRUPT_ENABLE 6 | ||
408 | #define SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE 5 | ||
409 | #define DATA_PACKET_RECEIVED_INTERRUPT_ENABLE 3 | ||
410 | #define DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE 2 | ||
411 | #define DATA_OUT_PING_TOKEN_INTERRUPT_ENABLE 1 | ||
412 | #define DATA_IN_TOKEN_INTERRUPT_ENABLE 0 | ||
413 | u32 ep_stat; | ||
414 | #define FIFO_VALID_COUNT 24 | ||
415 | #define HIGH_BANDWIDTH_OUT_TRANSACTION_PID 22 | ||
416 | #define TIMEOUT 21 | ||
417 | #define USB_STALL_SENT 20 | ||
418 | #define USB_IN_NAK_SENT 19 | ||
419 | #define USB_IN_ACK_RCVD 18 | ||
420 | #define USB_OUT_PING_NAK_SENT 17 | ||
421 | #define USB_OUT_ACK_SENT 16 | ||
422 | #define FIFO_OVERFLOW 13 | ||
423 | #define FIFO_UNDERFLOW 12 | ||
424 | #define FIFO_FULL 11 | ||
425 | #define FIFO_EMPTY 10 | ||
426 | #define FIFO_FLUSH 9 | ||
427 | #define SHORT_PACKET_OUT_DONE_INTERRUPT 6 | ||
428 | #define SHORT_PACKET_TRANSFERRED_INTERRUPT 5 | ||
429 | #define NAK_OUT_PACKETS 4 | ||
430 | #define DATA_PACKET_RECEIVED_INTERRUPT 3 | ||
431 | #define DATA_PACKET_TRANSMITTED_INTERRUPT 2 | ||
432 | #define DATA_OUT_PING_TOKEN_INTERRUPT 1 | ||
433 | #define DATA_IN_TOKEN_INTERRUPT 0 | ||
434 | // offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0 | ||
435 | u32 ep_avail; | ||
436 | u32 ep_data; | ||
437 | u32 _unused0 [2]; | ||
438 | } __attribute__ ((packed)); | ||
439 | 26 | ||
440 | /*-------------------------------------------------------------------------*/ | 27 | /*-------------------------------------------------------------------------*/ |
441 | 28 | ||
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 51424f66a765..68e3d8f5da89 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -572,9 +572,10 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | |||
572 | switch (status) { | 572 | switch (status) { |
573 | 573 | ||
574 | case 0: /* normal completion? */ | 574 | case 0: /* normal completion? */ |
575 | if (ep == dev->out_ep) | 575 | if (ep == dev->out_ep) { |
576 | check_read_data (dev, ep, req); | 576 | check_read_data (dev, ep, req); |
577 | else | 577 | memset (req->buf, 0x55, req->length); |
578 | } else | ||
578 | reinit_write_data (dev, ep, req); | 579 | reinit_write_data (dev, ep, req); |
579 | break; | 580 | break; |
580 | 581 | ||
@@ -626,6 +627,8 @@ source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) | |||
626 | 627 | ||
627 | if (strcmp (ep->name, EP_IN_NAME) == 0) | 628 | if (strcmp (ep->name, EP_IN_NAME) == 0) |
628 | reinit_write_data (ep->driver_data, ep, req); | 629 | reinit_write_data (ep->driver_data, ep, req); |
630 | else | ||
631 | memset (req->buf, 0x55, req->length); | ||
629 | 632 | ||
630 | status = usb_ep_queue (ep, req, gfp_flags); | 633 | status = usb_ep_queue (ep, req, gfp_flags); |
631 | if (status) { | 634 | if (status) { |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 980030d684d5..6b7350b52419 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <asm/arch/board.h> | 20 | #include <asm/arch/board.h> |
21 | 21 | ||
22 | #ifndef CONFIG_ARCH_AT91RM9200 | 22 | #ifndef CONFIG_ARCH_AT91RM9200 |
23 | #error "This file is AT91RM9200 bus glue. CONFIG_ARCH_AT91RM9200 must be defined." | 23 | #error "CONFIG_ARCH_AT91RM9200 must be defined." |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | /* interface and function clocks */ | 26 | /* interface and function clocks */ |
@@ -84,8 +84,6 @@ static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); | |||
84 | * Allocates basic resources for this USB host controller, and | 84 | * Allocates basic resources for this USB host controller, and |
85 | * then invokes the start() method for the HCD associated with it | 85 | * then invokes the start() method for the HCD associated with it |
86 | * through the hotplug entry's driver_data. | 86 | * through the hotplug entry's driver_data. |
87 | * | ||
88 | * Store this function in the HCD's struct pci_driver as probe(). | ||
89 | */ | 87 | */ |
90 | int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev) | 88 | int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev) |
91 | { | 89 | { |
@@ -148,7 +146,6 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device * | |||
148 | } | 146 | } |
149 | 147 | ||
150 | 148 | ||
151 | /* may be called without controller electrically present */ | ||
152 | /* may be called with controller, bus, and devices active */ | 149 | /* may be called with controller, bus, and devices active */ |
153 | 150 | ||
154 | /** | 151 | /** |
@@ -166,11 +163,11 @@ static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pde | |||
166 | usb_remove_hcd(hcd); | 163 | usb_remove_hcd(hcd); |
167 | at91_stop_hc(pdev); | 164 | at91_stop_hc(pdev); |
168 | iounmap(hcd->regs); | 165 | iounmap(hcd->regs); |
169 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 166 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
170 | 167 | ||
171 | clk_put(fclk); | 168 | clk_put(fclk); |
172 | clk_put(iclk); | 169 | clk_put(iclk); |
173 | fclk = iclk = NULL; | 170 | fclk = iclk = NULL; |
174 | 171 | ||
175 | dev_set_drvdata(&pdev->dev, NULL); | 172 | dev_set_drvdata(&pdev->dev, NULL); |
176 | return 0; | 173 | return 0; |
@@ -235,8 +232,8 @@ static const struct hc_driver ohci_at91_hc_driver = { | |||
235 | .hub_control = ohci_hub_control, | 232 | .hub_control = ohci_hub_control, |
236 | 233 | ||
237 | #ifdef CONFIG_PM | 234 | #ifdef CONFIG_PM |
238 | .hub_suspend = ohci_hub_suspend, | 235 | .bus_suspend = ohci_bus_suspend, |
239 | .hub_resume = ohci_hub_resume, | 236 | .bus_resume = ohci_bus_resume, |
240 | #endif | 237 | #endif |
241 | .start_port_reset = ohci_start_port_reset, | 238 | .start_port_reset = ohci_start_port_reset, |
242 | }; | 239 | }; |
@@ -254,21 +251,21 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *dev) | |||
254 | } | 251 | } |
255 | 252 | ||
256 | #ifdef CONFIG_PM | 253 | #ifdef CONFIG_PM |
257 | static int ohci_hcd_at91_drv_suspend(struct platform_device *dev, u32 state, u32 level) | ||
258 | { | ||
259 | printk("%s(%s:%d): not implemented yet\n", | ||
260 | __func__, __FILE__, __LINE__); | ||
261 | 254 | ||
255 | /* REVISIT suspend/resume look "too" simple here */ | ||
256 | |||
257 | static int | ||
258 | ohci_hcd_at91_drv_suspend(struct platform_device *dev, pm_message_t mesg) | ||
259 | { | ||
262 | clk_disable(fclk); | 260 | clk_disable(fclk); |
261 | clk_disable(iclk); | ||
263 | 262 | ||
264 | return 0; | 263 | return 0; |
265 | } | 264 | } |
266 | 265 | ||
267 | static int ohci_hcd_at91_drv_resume(struct platform_device *dev, u32 state) | 266 | static int ohci_hcd_at91_drv_resume(struct platform_device *dev) |
268 | { | 267 | { |
269 | printk("%s(%s:%d): not implemented yet\n", | 268 | clk_enable(iclk); |
270 | __func__, __FILE__, __LINE__); | ||
271 | |||
272 | clk_enable(fclk); | 269 | clk_enable(fclk); |
273 | 270 | ||
274 | return 0; | 271 | return 0; |
@@ -278,6 +275,8 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *dev, u32 state) | |||
278 | #define ohci_hcd_at91_drv_resume NULL | 275 | #define ohci_hcd_at91_drv_resume NULL |
279 | #endif | 276 | #endif |
280 | 277 | ||
278 | MODULE_ALIAS("at91rm9200-ohci"); | ||
279 | |||
281 | static struct platform_driver ohci_hcd_at91_driver = { | 280 | static struct platform_driver ohci_hcd_at91_driver = { |
282 | .probe = ohci_hcd_at91_drv_probe, | 281 | .probe = ohci_hcd_at91_drv_probe, |
283 | .remove = ohci_hcd_at91_drv_remove, | 282 | .remove = ohci_hcd_at91_drv_remove, |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 682bf2215660..1da5de573a6f 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -30,6 +30,7 @@ | |||
30 | /* clock device associated with the hcd */ | 30 | /* clock device associated with the hcd */ |
31 | 31 | ||
32 | static struct clk *clk; | 32 | static struct clk *clk; |
33 | static struct clk *usb_clk; | ||
33 | 34 | ||
34 | /* forward definitions */ | 35 | /* forward definitions */ |
35 | 36 | ||
@@ -37,7 +38,7 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc); | |||
37 | 38 | ||
38 | /* conversion functions */ | 39 | /* conversion functions */ |
39 | 40 | ||
40 | struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) | 41 | static struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) |
41 | { | 42 | { |
42 | return hcd->self.controller->platform_data; | 43 | return hcd->self.controller->platform_data; |
43 | } | 44 | } |
@@ -47,6 +48,10 @@ static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd) | |||
47 | struct s3c2410_hcd_info *info = dev->dev.platform_data; | 48 | struct s3c2410_hcd_info *info = dev->dev.platform_data; |
48 | 49 | ||
49 | dev_dbg(&dev->dev, "s3c2410_start_hc:\n"); | 50 | dev_dbg(&dev->dev, "s3c2410_start_hc:\n"); |
51 | |||
52 | clk_enable(usb_clk); | ||
53 | mdelay(2); /* let the bus clock stabilise */ | ||
54 | |||
50 | clk_enable(clk); | 55 | clk_enable(clk); |
51 | 56 | ||
52 | if (info != NULL) { | 57 | if (info != NULL) { |
@@ -75,6 +80,7 @@ static void s3c2410_stop_hc(struct platform_device *dev) | |||
75 | } | 80 | } |
76 | 81 | ||
77 | clk_disable(clk); | 82 | clk_disable(clk); |
83 | clk_disable(usb_clk); | ||
78 | } | 84 | } |
79 | 85 | ||
80 | /* ohci_s3c2410_hub_status_data | 86 | /* ohci_s3c2410_hub_status_data |
@@ -316,7 +322,8 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) | |||
316 | * | 322 | * |
317 | */ | 323 | */ |
318 | 324 | ||
319 | void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) | 325 | static void |
326 | usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) | ||
320 | { | 327 | { |
321 | usb_remove_hcd(hcd); | 328 | usb_remove_hcd(hcd); |
322 | s3c2410_stop_hc(dev); | 329 | s3c2410_stop_hc(dev); |
@@ -334,8 +341,8 @@ void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) | |||
334 | * through the hotplug entry's driver_data. | 341 | * through the hotplug entry's driver_data. |
335 | * | 342 | * |
336 | */ | 343 | */ |
337 | int usb_hcd_s3c2410_probe (const struct hc_driver *driver, | 344 | static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, |
338 | struct platform_device *dev) | 345 | struct platform_device *dev) |
339 | { | 346 | { |
340 | struct usb_hcd *hcd = NULL; | 347 | struct usb_hcd *hcd = NULL; |
341 | int retval; | 348 | int retval; |
@@ -353,14 +360,21 @@ int usb_hcd_s3c2410_probe (const struct hc_driver *driver, | |||
353 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 360 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
354 | dev_err(&dev->dev, "request_mem_region failed"); | 361 | dev_err(&dev->dev, "request_mem_region failed"); |
355 | retval = -EBUSY; | 362 | retval = -EBUSY; |
356 | goto err0; | 363 | goto err_put; |
357 | } | 364 | } |
358 | 365 | ||
359 | clk = clk_get(NULL, "usb-host"); | 366 | clk = clk_get(&dev->dev, "usb-host"); |
360 | if (IS_ERR(clk)) { | 367 | if (IS_ERR(clk)) { |
361 | dev_err(&dev->dev, "cannot get usb-host clock\n"); | 368 | dev_err(&dev->dev, "cannot get usb-host clock\n"); |
362 | retval = -ENOENT; | 369 | retval = -ENOENT; |
363 | goto err1; | 370 | goto err_mem; |
371 | } | ||
372 | |||
373 | usb_clk = clk_get(&dev->dev, "upll"); | ||
374 | if (IS_ERR(usb_clk)) { | ||
375 | dev_err(&dev->dev, "cannot get usb-host clock\n"); | ||
376 | retval = -ENOENT; | ||
377 | goto err_clk; | ||
364 | } | 378 | } |
365 | 379 | ||
366 | s3c2410_start_hc(dev, hcd); | 380 | s3c2410_start_hc(dev, hcd); |
@@ -369,26 +383,29 @@ int usb_hcd_s3c2410_probe (const struct hc_driver *driver, | |||
369 | if (!hcd->regs) { | 383 | if (!hcd->regs) { |
370 | dev_err(&dev->dev, "ioremap failed\n"); | 384 | dev_err(&dev->dev, "ioremap failed\n"); |
371 | retval = -ENOMEM; | 385 | retval = -ENOMEM; |
372 | goto err2; | 386 | goto err_ioremap; |
373 | } | 387 | } |
374 | 388 | ||
375 | ohci_hcd_init(hcd_to_ohci(hcd)); | 389 | ohci_hcd_init(hcd_to_ohci(hcd)); |
376 | 390 | ||
377 | retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); | 391 | retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); |
378 | if (retval != 0) | 392 | if (retval != 0) |
379 | goto err2; | 393 | goto err_ioremap; |
380 | 394 | ||
381 | return 0; | 395 | return 0; |
382 | 396 | ||
383 | err2: | 397 | err_ioremap: |
384 | s3c2410_stop_hc(dev); | 398 | s3c2410_stop_hc(dev); |
385 | iounmap(hcd->regs); | 399 | iounmap(hcd->regs); |
400 | clk_put(usb_clk); | ||
401 | |||
402 | err_clk: | ||
386 | clk_put(clk); | 403 | clk_put(clk); |
387 | 404 | ||
388 | err1: | 405 | err_mem: |
389 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 406 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
390 | 407 | ||
391 | err0: | 408 | err_put: |
392 | usb_put_hcd(hcd); | 409 | usb_put_hcd(hcd); |
393 | return retval; | 410 | return retval; |
394 | } | 411 | } |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 9e81c26313f9..1045f846fbe2 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/acpi.h> | 17 | #include <linux/acpi.h> |
18 | #include "pci-quirks.h" | ||
18 | 19 | ||
19 | 20 | ||
20 | #define UHCI_USBLEGSUP 0xc0 /* legacy support */ | 21 | #define UHCI_USBLEGSUP 0xc0 /* legacy support */ |
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h new file mode 100644 index 000000000000..1564edfff6fe --- /dev/null +++ b/drivers/usb/host/pci-quirks.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef __LINUX_USB_PCI_QUIRKS_H | ||
2 | #define __LINUX_USB_PCI_QUIRKS_H | ||
3 | |||
4 | void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
5 | int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
6 | |||
7 | #endif /* __LINUX_USB_PCI_QUIRKS_H */ | ||
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 4edb8330c440..c0c4db78b590 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -50,6 +50,7 @@ | |||
50 | 50 | ||
51 | #include "../core/hcd.h" | 51 | #include "../core/hcd.h" |
52 | #include "uhci-hcd.h" | 52 | #include "uhci-hcd.h" |
53 | #include "pci-quirks.h" | ||
53 | 54 | ||
54 | /* | 55 | /* |
55 | * Version Information | 56 | * Version Information |
@@ -100,9 +101,6 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | |||
100 | #include "uhci-q.c" | 101 | #include "uhci-q.c" |
101 | #include "uhci-hub.c" | 102 | #include "uhci-hub.c" |
102 | 103 | ||
103 | extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
104 | extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
105 | |||
106 | /* | 104 | /* |
107 | * Finish up a host controller reset and update the recorded state. | 105 | * Finish up a host controller reset and update the recorded state. |
108 | */ | 106 | */ |
@@ -117,8 +115,7 @@ static void finish_reset(struct uhci_hcd *uhci) | |||
117 | for (port = 0; port < uhci->rh_numports; ++port) | 115 | for (port = 0; port < uhci->rh_numports; ++port) |
118 | outw(0, uhci->io_addr + USBPORTSC1 + (port * 2)); | 116 | outw(0, uhci->io_addr + USBPORTSC1 + (port * 2)); |
119 | 117 | ||
120 | uhci->port_c_suspend = uhci->suspended_ports = | 118 | uhci->port_c_suspend = uhci->resuming_ports = 0; |
121 | uhci->resuming_ports = 0; | ||
122 | uhci->rh_state = UHCI_RH_RESET; | 119 | uhci->rh_state = UHCI_RH_RESET; |
123 | uhci->is_stopped = UHCI_IS_STOPPED; | 120 | uhci->is_stopped = UHCI_IS_STOPPED; |
124 | uhci_to_hcd(uhci)->state = HC_STATE_HALT; | 121 | uhci_to_hcd(uhci)->state = HC_STATE_HALT; |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 4a69c7eb09bd..d5c8f4d92823 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -415,7 +415,6 @@ struct uhci_hcd { | |||
415 | 415 | ||
416 | /* Support for port suspend/resume/reset */ | 416 | /* Support for port suspend/resume/reset */ |
417 | unsigned long port_c_suspend; /* Bit-arrays of ports */ | 417 | unsigned long port_c_suspend; /* Bit-arrays of ports */ |
418 | unsigned long suspended_ports; | ||
419 | unsigned long resuming_ports; | 418 | unsigned long resuming_ports; |
420 | unsigned long ports_timeout; /* Time to stop signalling */ | 419 | unsigned long ports_timeout; /* Time to stop signalling */ |
421 | 420 | ||
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 152971d16769..c8451d9578f1 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c | |||
@@ -85,11 +85,10 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, | |||
85 | { | 85 | { |
86 | int status; | 86 | int status; |
87 | 87 | ||
88 | if (test_bit(port, &uhci->suspended_ports)) { | 88 | if (inw(port_addr) & (USBPORTSC_SUSP | USBPORTSC_RD)) { |
89 | CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD); | 89 | CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD); |
90 | clear_bit(port, &uhci->suspended_ports); | 90 | if (test_bit(port, &uhci->resuming_ports)) |
91 | clear_bit(port, &uhci->resuming_ports); | 91 | set_bit(port, &uhci->port_c_suspend); |
92 | set_bit(port, &uhci->port_c_suspend); | ||
93 | 92 | ||
94 | /* The controller won't actually turn off the RD bit until | 93 | /* The controller won't actually turn off the RD bit until |
95 | * it has had a chance to send a low-speed EOP sequence, | 94 | * it has had a chance to send a low-speed EOP sequence, |
@@ -97,6 +96,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, | |||
97 | * slightly longer for good luck. */ | 96 | * slightly longer for good luck. */ |
98 | udelay(4); | 97 | udelay(4); |
99 | } | 98 | } |
99 | clear_bit(port, &uhci->resuming_ports); | ||
100 | } | 100 | } |
101 | 101 | ||
102 | /* Wait for the UHCI controller in HP's iLO2 server management chip. | 102 | /* Wait for the UHCI controller in HP's iLO2 server management chip. |
@@ -265,8 +265,6 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
265 | wPortChange |= USB_PORT_STAT_C_SUSPEND; | 265 | wPortChange |= USB_PORT_STAT_C_SUSPEND; |
266 | lstatus |= 1; | 266 | lstatus |= 1; |
267 | } | 267 | } |
268 | if (test_bit(port, &uhci->suspended_ports)) | ||
269 | lstatus |= 2; | ||
270 | if (test_bit(port, &uhci->resuming_ports)) | 268 | if (test_bit(port, &uhci->resuming_ports)) |
271 | lstatus |= 4; | 269 | lstatus |= 4; |
272 | 270 | ||
@@ -309,7 +307,6 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
309 | 307 | ||
310 | switch (wValue) { | 308 | switch (wValue) { |
311 | case USB_PORT_FEAT_SUSPEND: | 309 | case USB_PORT_FEAT_SUSPEND: |
312 | set_bit(port, &uhci->suspended_ports); | ||
313 | SET_RH_PORTSTAT(USBPORTSC_SUSP); | 310 | SET_RH_PORTSTAT(USBPORTSC_SUSP); |
314 | OK(0); | 311 | OK(0); |
315 | case USB_PORT_FEAT_RESET: | 312 | case USB_PORT_FEAT_RESET: |
@@ -343,8 +340,11 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
343 | CLR_RH_PORTSTAT(USBPORTSC_PEC); | 340 | CLR_RH_PORTSTAT(USBPORTSC_PEC); |
344 | OK(0); | 341 | OK(0); |
345 | case USB_PORT_FEAT_SUSPEND: | 342 | case USB_PORT_FEAT_SUSPEND: |
346 | if (test_bit(port, &uhci->suspended_ports) && | 343 | if (!(inw(port_addr) & USBPORTSC_SUSP)) { |
347 | !test_and_set_bit(port, | 344 | |
345 | /* Make certain the port isn't suspended */ | ||
346 | uhci_finish_suspend(uhci, port, port_addr); | ||
347 | } else if (!test_and_set_bit(port, | ||
348 | &uhci->resuming_ports)) { | 348 | &uhci->resuming_ports)) { |
349 | SET_RH_PORTSTAT(USBPORTSC_RD); | 349 | SET_RH_PORTSTAT(USBPORTSC_RD); |
350 | 350 | ||
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 5246b35301de..650103bc9618 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
@@ -200,45 +200,41 @@ config USB_POWERMATE | |||
200 | To compile this driver as a module, choose M here: the | 200 | To compile this driver as a module, choose M here: the |
201 | module will be called powermate. | 201 | module will be called powermate. |
202 | 202 | ||
203 | config USB_MTOUCH | 203 | config USB_TOUCHSCREEN |
204 | tristate "MicroTouch USB Touchscreen Driver" | 204 | tristate "USB Touchscreen Driver" |
205 | depends on USB && INPUT | 205 | depends on USB && INPUT |
206 | ---help--- | 206 | ---help--- |
207 | Say Y here if you want to use a MicroTouch (Now 3M) USB | 207 | USB Touchscreen driver for: |
208 | Touchscreen controller. | 208 | - eGalax Touchkit USB |
209 | - PanJit TouchSet USB | ||
210 | - 3M MicroTouch USB | ||
211 | - ITM | ||
209 | 212 | ||
210 | See <file:Documentation/usb/mtouch.txt> for additional information. | 213 | Have a look at <http://linux.chapter7.ch/touchkit/> for |
211 | 214 | a usage description and the required user-space stuff. | |
212 | To compile this driver as a module, choose M here: the | ||
213 | module will be called mtouchusb. | ||
214 | |||
215 | config USB_ITMTOUCH | ||
216 | tristate "ITM Touch USB Touchscreen Driver" | ||
217 | depends on USB && INPUT | ||
218 | ---help--- | ||
219 | Say Y here if you want to use a ITM Touch USB | ||
220 | Touchscreen controller. | ||
221 | |||
222 | This touchscreen is used in LG 1510SF monitors. | ||
223 | 215 | ||
224 | To compile this driver as a module, choose M here: the | 216 | To compile this driver as a module, choose M here: the |
225 | module will be called itmtouch. | 217 | module will be called usbtouchscreen. |
226 | 218 | ||
227 | config USB_EGALAX | 219 | config USB_TOUCHSCREEN_EGALAX |
228 | tristate "eGalax TouchKit USB Touchscreen Driver" | 220 | default y |
229 | depends on USB && INPUT | 221 | bool "eGalax device support" if EMBEDDED |
230 | ---help--- | 222 | depends on USB_TOUCHSCREEN |
231 | Say Y here if you want to use a eGalax TouchKit USB | ||
232 | Touchscreen controller. | ||
233 | 223 | ||
234 | The driver has been tested on a Xenarc 700TSV monitor | 224 | config USB_TOUCHSCREEN_PANJIT |
235 | with eGalax touchscreen. | 225 | default y |
226 | bool "PanJit device support" if EMBEDDED | ||
227 | depends on USB_TOUCHSCREEN | ||
236 | 228 | ||
237 | Have a look at <http://linux.chapter7.ch/touchkit/> for | 229 | config USB_TOUCHSCREEN_3M |
238 | a usage description and the required user-space stuff. | 230 | default y |
231 | bool "3M/Microtouch device support" if EMBEDDED | ||
232 | depends on USB_TOUCHSCREEN | ||
239 | 233 | ||
240 | To compile this driver as a module, choose M here: the | 234 | config USB_TOUCHSCREEN_ITM |
241 | module will be called touchkitusb. | 235 | default y |
236 | bool "ITM device support" if EMBEDDED | ||
237 | depends on USB_TOUCHSCREEN | ||
242 | 238 | ||
243 | config USB_YEALINK | 239 | config USB_YEALINK |
244 | tristate "Yealink usb-p1k voip phone" | 240 | tristate "Yealink usb-p1k voip phone" |
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index d512d9f488fe..764114529c56 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
@@ -37,6 +37,7 @@ obj-$(CONFIG_USB_MOUSE) += usbmouse.o | |||
37 | obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o | 37 | obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o |
38 | obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o | 38 | obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o |
39 | obj-$(CONFIG_USB_EGALAX) += touchkitusb.o | 39 | obj-$(CONFIG_USB_EGALAX) += touchkitusb.o |
40 | obj-$(CONFIG_USB_TOUCHSCREEN) += usbtouchscreen.o | ||
40 | obj-$(CONFIG_USB_POWERMATE) += powermate.o | 41 | obj-$(CONFIG_USB_POWERMATE) += powermate.o |
41 | obj-$(CONFIG_USB_WACOM) += wacom.o | 42 | obj-$(CONFIG_USB_WACOM) += wacom.o |
42 | obj-$(CONFIG_USB_ACECAD) += acecad.o | 43 | obj-$(CONFIG_USB_ACECAD) += acecad.o |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index d4bf1701046b..f419bd82ab7f 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1372,6 +1372,11 @@ void hid_close(struct hid_device *hid) | |||
1372 | usb_kill_urb(hid->urbin); | 1372 | usb_kill_urb(hid->urbin); |
1373 | } | 1373 | } |
1374 | 1374 | ||
1375 | #define USB_VENDOR_ID_PANJIT 0x134c | ||
1376 | |||
1377 | #define USB_VENDOR_ID_SILVERCREST 0x062a | ||
1378 | #define USB_DEVICE_ID_SILVERCREST_KB 0x0201 | ||
1379 | |||
1375 | /* | 1380 | /* |
1376 | * Initialize all reports | 1381 | * Initialize all reports |
1377 | */ | 1382 | */ |
@@ -1655,9 +1660,12 @@ static const struct hid_blacklist { | |||
1655 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, | 1660 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, |
1656 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, | 1661 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, |
1657 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, | 1662 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, |
1663 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 3, HID_QUIRK_IGNORE }, | ||
1664 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 4, HID_QUIRK_IGNORE }, | ||
1658 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 5, HID_QUIRK_IGNORE }, | 1665 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 5, HID_QUIRK_IGNORE }, |
1659 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, | 1666 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, |
1660 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF, HID_QUIRK_IGNORE }, | 1667 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF, HID_QUIRK_IGNORE }, |
1668 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF + 3, HID_QUIRK_IGNORE }, | ||
1661 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1669 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1662 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1670 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1663 | 1671 | ||
@@ -1675,6 +1683,7 @@ static const struct hid_blacklist { | |||
1675 | { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, | 1683 | { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, |
1676 | { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, | 1684 | { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, |
1677 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 1685 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
1686 | { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET }, | ||
1678 | 1687 | ||
1679 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, | 1688 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, |
1680 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, | 1689 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, |
@@ -1701,6 +1710,11 @@ static const struct hid_blacklist { | |||
1701 | { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, | 1710 | { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, |
1702 | { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, | 1711 | { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, |
1703 | 1712 | ||
1713 | { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, | ||
1714 | { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, | ||
1715 | { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE }, | ||
1716 | { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, | ||
1717 | |||
1704 | { 0, 0 } | 1718 | { 0, 0 } |
1705 | }; | 1719 | }; |
1706 | 1720 | ||
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c index 72e698658b53..d5c91ee67991 100644 --- a/drivers/usb/input/hid-ff.c +++ b/drivers/usb/input/hid-ff.c | |||
@@ -34,12 +34,6 @@ | |||
34 | 34 | ||
35 | #include "hid.h" | 35 | #include "hid.h" |
36 | 36 | ||
37 | /* Drivers' initializing functions */ | ||
38 | extern int hid_lgff_init(struct hid_device* hid); | ||
39 | extern int hid_lg3d_init(struct hid_device* hid); | ||
40 | extern int hid_pid_init(struct hid_device* hid); | ||
41 | extern int hid_tmff_init(struct hid_device* hid); | ||
42 | |||
43 | /* | 37 | /* |
44 | * This table contains pointers to initializers. To add support for new | 38 | * This table contains pointers to initializers. To add support for new |
45 | * devices, you need to add the USB vendor and product ids here. | 39 | * devices, you need to add the USB vendor and product ids here. |
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index 4e1b784fe527..9c62837b5b89 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h | |||
@@ -533,3 +533,8 @@ static inline int hid_ff_event(struct hid_device *hid, struct input_dev *input, | |||
533 | return hid->ff_event(hid, input, type, code, value); | 533 | return hid->ff_event(hid, input, type, code, value); |
534 | return -ENOSYS; | 534 | return -ENOSYS; |
535 | } | 535 | } |
536 | |||
537 | int hid_lgff_init(struct hid_device* hid); | ||
538 | int hid_tmff_init(struct hid_device* hid); | ||
539 | int hid_pid_init(struct hid_device* hid); | ||
540 | |||
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index b4a051b549d1..3d911976f378 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c | |||
@@ -297,6 +297,8 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs) | |||
297 | remote->data.bits_left -= 6; | 297 | remote->data.bits_left -= 6; |
298 | } else { | 298 | } else { |
299 | err("%s - Error in message, invalid toggle.\n", __FUNCTION__); | 299 | err("%s - Error in message, invalid toggle.\n", __FUNCTION__); |
300 | remote->stage = 0; | ||
301 | return; | ||
300 | } | 302 | } |
301 | 303 | ||
302 | keyspan_load_tester(remote, 5); | 304 | keyspan_load_tester(remote, 5); |
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c new file mode 100644 index 000000000000..e9a07c1e905b --- /dev/null +++ b/drivers/usb/input/usbtouchscreen.c | |||
@@ -0,0 +1,605 @@ | |||
1 | /****************************************************************************** | ||
2 | * usbtouchscreen.c | ||
3 | * Driver for USB Touchscreens, supporting those devices: | ||
4 | * - eGalax Touchkit | ||
5 | * - 3M/Microtouch | ||
6 | * - ITM | ||
7 | * - PanJit TouchSet | ||
8 | * | ||
9 | * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch> | ||
10 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License as | ||
14 | * published by the Free Software Foundation; either version 2 of the | ||
15 | * License, or (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, but | ||
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
20 | * General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | * | ||
26 | * Driver is based on touchkitusb.c | ||
27 | * - ITM parts are from itmtouch.c | ||
28 | * - 3M parts are from mtouchusb.c | ||
29 | * - PanJit parts are from an unmerged driver by Lanslott Gish | ||
30 | * | ||
31 | *****************************************************************************/ | ||
32 | |||
33 | //#define DEBUG | ||
34 | |||
35 | #include <linux/config.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/input.h> | ||
39 | #include <linux/module.h> | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/usb.h> | ||
42 | #include <linux/usb_input.h> | ||
43 | |||
44 | |||
45 | #define DRIVER_VERSION "v0.3" | ||
46 | #define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>" | ||
47 | #define DRIVER_DESC "USB Touchscreen Driver" | ||
48 | |||
49 | static int swap_xy; | ||
50 | module_param(swap_xy, bool, 0644); | ||
51 | MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); | ||
52 | |||
53 | /* device specifc data/functions */ | ||
54 | struct usbtouch_usb; | ||
55 | struct usbtouch_device_info { | ||
56 | int min_xc, max_xc; | ||
57 | int min_yc, max_yc; | ||
58 | int min_press, max_press; | ||
59 | int rept_size; | ||
60 | int flags; | ||
61 | |||
62 | void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, unsigned char *pkt, int len); | ||
63 | int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press); | ||
64 | int (*init) (struct usbtouch_usb *usbtouch); | ||
65 | }; | ||
66 | |||
67 | #define USBTOUCH_FLG_BUFFER 0x01 | ||
68 | |||
69 | |||
70 | /* a usbtouch device */ | ||
71 | struct usbtouch_usb { | ||
72 | unsigned char *data; | ||
73 | dma_addr_t data_dma; | ||
74 | unsigned char *buffer; | ||
75 | int buf_len; | ||
76 | struct urb *irq; | ||
77 | struct usb_device *udev; | ||
78 | struct input_dev *input; | ||
79 | struct usbtouch_device_info *type; | ||
80 | char name[128]; | ||
81 | char phys[64]; | ||
82 | }; | ||
83 | |||
84 | static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, | ||
85 | struct pt_regs *regs, unsigned char *pkt, int len); | ||
86 | |||
87 | /* device types */ | ||
88 | enum { | ||
89 | DEVTPYE_DUMMY = -1, | ||
90 | DEVTYPE_EGALAX, | ||
91 | DEVTYPE_PANJIT, | ||
92 | DEVTYPE_3M, | ||
93 | DEVTYPE_ITM, | ||
94 | }; | ||
95 | |||
96 | static struct usb_device_id usbtouch_devices[] = { | ||
97 | #ifdef CONFIG_USB_TOUCHSCREEN_EGALAX | ||
98 | {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX}, | ||
99 | {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX}, | ||
100 | {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX}, | ||
101 | {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX}, | ||
102 | #endif | ||
103 | |||
104 | #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT | ||
105 | {USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT}, | ||
106 | {USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT}, | ||
107 | {USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT}, | ||
108 | {USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT}, | ||
109 | #endif | ||
110 | |||
111 | #ifdef CONFIG_USB_TOUCHSCREEN_3M | ||
112 | {USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M}, | ||
113 | #endif | ||
114 | |||
115 | #ifdef CONFIG_USB_TOUCHSCREEN_ITM | ||
116 | {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, | ||
117 | #endif | ||
118 | |||
119 | {} | ||
120 | }; | ||
121 | |||
122 | |||
123 | /***************************************************************************** | ||
124 | * eGalax part | ||
125 | */ | ||
126 | |||
127 | #ifdef CONFIG_USB_TOUCHSCREEN_EGALAX | ||
128 | |||
129 | #define EGALAX_PKT_TYPE_MASK 0xFE | ||
130 | #define EGALAX_PKT_TYPE_REPT 0x80 | ||
131 | #define EGALAX_PKT_TYPE_DIAG 0x0A | ||
132 | |||
133 | static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | ||
134 | { | ||
135 | if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) | ||
136 | return 0; | ||
137 | |||
138 | *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); | ||
139 | *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); | ||
140 | *touch = pkt[0] & 0x01; | ||
141 | |||
142 | return 1; | ||
143 | |||
144 | } | ||
145 | |||
146 | static int egalax_get_pkt_len(unsigned char *buf) | ||
147 | { | ||
148 | switch (buf[0] & EGALAX_PKT_TYPE_MASK) { | ||
149 | case EGALAX_PKT_TYPE_REPT: | ||
150 | return 5; | ||
151 | |||
152 | case EGALAX_PKT_TYPE_DIAG: | ||
153 | return buf[1] + 2; | ||
154 | } | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static void egalax_process(struct usbtouch_usb *usbtouch, struct pt_regs *regs, | ||
160 | unsigned char *pkt, int len) | ||
161 | { | ||
162 | unsigned char *buffer; | ||
163 | int pkt_len, buf_len, pos; | ||
164 | |||
165 | /* if the buffer contains data, append */ | ||
166 | if (unlikely(usbtouch->buf_len)) { | ||
167 | int tmp; | ||
168 | |||
169 | /* if only 1 byte in buffer, add another one to get length */ | ||
170 | if (usbtouch->buf_len == 1) | ||
171 | usbtouch->buffer[1] = pkt[0]; | ||
172 | |||
173 | pkt_len = egalax_get_pkt_len(usbtouch->buffer); | ||
174 | |||
175 | /* unknown packet: drop everything */ | ||
176 | if (!pkt_len) | ||
177 | return; | ||
178 | |||
179 | /* append, process */ | ||
180 | tmp = pkt_len - usbtouch->buf_len; | ||
181 | memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp); | ||
182 | usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len); | ||
183 | |||
184 | buffer = pkt + tmp; | ||
185 | buf_len = len - tmp; | ||
186 | } else { | ||
187 | buffer = pkt; | ||
188 | buf_len = len; | ||
189 | } | ||
190 | |||
191 | /* only one byte left in buffer */ | ||
192 | if (unlikely(buf_len == 1)) { | ||
193 | usbtouch->buffer[0] = buffer[0]; | ||
194 | usbtouch->buf_len = 1; | ||
195 | return; | ||
196 | } | ||
197 | |||
198 | /* loop over the buffer */ | ||
199 | pos = 0; | ||
200 | while (pos < buf_len) { | ||
201 | /* get packet len */ | ||
202 | pkt_len = egalax_get_pkt_len(buffer + pos); | ||
203 | |||
204 | /* unknown packet: drop everything */ | ||
205 | if (unlikely(!pkt_len)) | ||
206 | return; | ||
207 | |||
208 | /* full packet: process */ | ||
209 | if (likely(pkt_len <= buf_len)) { | ||
210 | usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len); | ||
211 | } else { | ||
212 | /* incomplete packet: save in buffer */ | ||
213 | memcpy(usbtouch->buffer, buffer + pos, buf_len - pos); | ||
214 | usbtouch->buf_len = buf_len - pos; | ||
215 | } | ||
216 | pos += pkt_len; | ||
217 | } | ||
218 | } | ||
219 | #endif | ||
220 | |||
221 | |||
222 | /***************************************************************************** | ||
223 | * PanJit Part | ||
224 | */ | ||
225 | #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT | ||
226 | static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | ||
227 | { | ||
228 | *x = ((pkt[2] & 0x0F) << 8) | pkt[1]; | ||
229 | *y = ((pkt[4] & 0x0F) << 8) | pkt[3]; | ||
230 | *touch = pkt[0] & 0x01; | ||
231 | |||
232 | return 1; | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | |||
237 | /***************************************************************************** | ||
238 | * 3M/Microtouch Part | ||
239 | */ | ||
240 | #ifdef CONFIG_USB_TOUCHSCREEN_3M | ||
241 | |||
242 | #define MTOUCHUSB_ASYNC_REPORT 1 | ||
243 | #define MTOUCHUSB_RESET 7 | ||
244 | #define MTOUCHUSB_REQ_CTRLLR_ID 10 | ||
245 | |||
246 | static int mtouch_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | ||
247 | { | ||
248 | *x = (pkt[8] << 8) | pkt[7]; | ||
249 | *y = (pkt[10] << 8) | pkt[9]; | ||
250 | *touch = (pkt[2] & 0x40) ? 1 : 0; | ||
251 | |||
252 | return 1; | ||
253 | } | ||
254 | |||
255 | static int mtouch_init(struct usbtouch_usb *usbtouch) | ||
256 | { | ||
257 | int ret; | ||
258 | |||
259 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | ||
260 | MTOUCHUSB_RESET, | ||
261 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
262 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
263 | dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", | ||
264 | __FUNCTION__, ret); | ||
265 | if (ret < 0) | ||
266 | return ret; | ||
267 | |||
268 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | ||
269 | MTOUCHUSB_ASYNC_REPORT, | ||
270 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
271 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
272 | dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", | ||
273 | __FUNCTION__, ret); | ||
274 | if (ret < 0) | ||
275 | return ret; | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | #endif | ||
280 | |||
281 | |||
282 | /***************************************************************************** | ||
283 | * ITM Part | ||
284 | */ | ||
285 | #ifdef CONFIG_USB_TOUCHSCREEN_ITM | ||
286 | static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | ||
287 | { | ||
288 | *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); | ||
289 | *x = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); | ||
290 | *press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F); | ||
291 | *touch = ~pkt[7] & 0x20; | ||
292 | |||
293 | return 1; | ||
294 | } | ||
295 | #endif | ||
296 | |||
297 | |||
298 | /***************************************************************************** | ||
299 | * the different device descriptors | ||
300 | */ | ||
301 | static struct usbtouch_device_info usbtouch_dev_info[] = { | ||
302 | #ifdef CONFIG_USB_TOUCHSCREEN_EGALAX | ||
303 | [DEVTYPE_EGALAX] = { | ||
304 | .min_xc = 0x0, | ||
305 | .max_xc = 0x07ff, | ||
306 | .min_yc = 0x0, | ||
307 | .max_yc = 0x07ff, | ||
308 | .rept_size = 16, | ||
309 | .flags = USBTOUCH_FLG_BUFFER, | ||
310 | .process_pkt = egalax_process, | ||
311 | .read_data = egalax_read_data, | ||
312 | }, | ||
313 | #endif | ||
314 | |||
315 | #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT | ||
316 | [DEVTYPE_PANJIT] = { | ||
317 | .min_xc = 0x0, | ||
318 | .max_xc = 0x0fff, | ||
319 | .min_yc = 0x0, | ||
320 | .max_yc = 0x0fff, | ||
321 | .rept_size = 8, | ||
322 | .read_data = panjit_read_data, | ||
323 | }, | ||
324 | #endif | ||
325 | |||
326 | #ifdef CONFIG_USB_TOUCHSCREEN_3M | ||
327 | [DEVTYPE_3M] = { | ||
328 | .min_xc = 0x0, | ||
329 | .max_xc = 0x4000, | ||
330 | .min_yc = 0x0, | ||
331 | .max_yc = 0x4000, | ||
332 | .rept_size = 11, | ||
333 | .read_data = mtouch_read_data, | ||
334 | .init = mtouch_init, | ||
335 | }, | ||
336 | #endif | ||
337 | |||
338 | #ifdef CONFIG_USB_TOUCHSCREEN_ITM | ||
339 | [DEVTYPE_ITM] = { | ||
340 | .min_xc = 0x0, | ||
341 | .max_xc = 0x0fff, | ||
342 | .min_yc = 0x0, | ||
343 | .max_yc = 0x0fff, | ||
344 | .max_press = 0xff, | ||
345 | .rept_size = 8, | ||
346 | .read_data = itm_read_data, | ||
347 | }, | ||
348 | #endif | ||
349 | }; | ||
350 | |||
351 | |||
352 | /***************************************************************************** | ||
353 | * Generic Part | ||
354 | */ | ||
355 | static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, | ||
356 | struct pt_regs *regs, unsigned char *pkt, int len) | ||
357 | { | ||
358 | int x, y, touch, press; | ||
359 | struct usbtouch_device_info *type = usbtouch->type; | ||
360 | |||
361 | if (!type->read_data(pkt, &x, &y, &touch, &press)) | ||
362 | return; | ||
363 | |||
364 | input_regs(usbtouch->input, regs); | ||
365 | input_report_key(usbtouch->input, BTN_TOUCH, touch); | ||
366 | |||
367 | if (swap_xy) { | ||
368 | input_report_abs(usbtouch->input, ABS_X, y); | ||
369 | input_report_abs(usbtouch->input, ABS_Y, x); | ||
370 | } else { | ||
371 | input_report_abs(usbtouch->input, ABS_X, x); | ||
372 | input_report_abs(usbtouch->input, ABS_Y, y); | ||
373 | } | ||
374 | if (type->max_press) | ||
375 | input_report_abs(usbtouch->input, ABS_PRESSURE, press); | ||
376 | input_sync(usbtouch->input); | ||
377 | } | ||
378 | |||
379 | |||
380 | static void usbtouch_irq(struct urb *urb, struct pt_regs *regs) | ||
381 | { | ||
382 | struct usbtouch_usb *usbtouch = urb->context; | ||
383 | int retval; | ||
384 | |||
385 | switch (urb->status) { | ||
386 | case 0: | ||
387 | /* success */ | ||
388 | break; | ||
389 | case -ETIMEDOUT: | ||
390 | /* this urb is timing out */ | ||
391 | dbg("%s - urb timed out - was the device unplugged?", | ||
392 | __FUNCTION__); | ||
393 | return; | ||
394 | case -ECONNRESET: | ||
395 | case -ENOENT: | ||
396 | case -ESHUTDOWN: | ||
397 | /* this urb is terminated, clean up */ | ||
398 | dbg("%s - urb shutting down with status: %d", | ||
399 | __FUNCTION__, urb->status); | ||
400 | return; | ||
401 | default: | ||
402 | dbg("%s - nonzero urb status received: %d", | ||
403 | __FUNCTION__, urb->status); | ||
404 | goto exit; | ||
405 | } | ||
406 | |||
407 | usbtouch->type->process_pkt(usbtouch, regs, usbtouch->data, urb->actual_length); | ||
408 | |||
409 | exit: | ||
410 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
411 | if (retval) | ||
412 | err("%s - usb_submit_urb failed with result: %d", | ||
413 | __FUNCTION__, retval); | ||
414 | } | ||
415 | |||
416 | static int usbtouch_open(struct input_dev *input) | ||
417 | { | ||
418 | struct usbtouch_usb *usbtouch = input->private; | ||
419 | |||
420 | usbtouch->irq->dev = usbtouch->udev; | ||
421 | |||
422 | if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) | ||
423 | return -EIO; | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static void usbtouch_close(struct input_dev *input) | ||
429 | { | ||
430 | struct usbtouch_usb *usbtouch = input->private; | ||
431 | |||
432 | usb_kill_urb(usbtouch->irq); | ||
433 | } | ||
434 | |||
435 | |||
436 | static void usbtouch_free_buffers(struct usb_device *udev, | ||
437 | struct usbtouch_usb *usbtouch) | ||
438 | { | ||
439 | if (usbtouch->data) | ||
440 | usb_buffer_free(udev, usbtouch->type->rept_size, | ||
441 | usbtouch->data, usbtouch->data_dma); | ||
442 | kfree(usbtouch->buffer); | ||
443 | } | ||
444 | |||
445 | |||
446 | static int usbtouch_probe(struct usb_interface *intf, | ||
447 | const struct usb_device_id *id) | ||
448 | { | ||
449 | struct usbtouch_usb *usbtouch; | ||
450 | struct input_dev *input_dev; | ||
451 | struct usb_host_interface *interface; | ||
452 | struct usb_endpoint_descriptor *endpoint; | ||
453 | struct usb_device *udev = interface_to_usbdev(intf); | ||
454 | struct usbtouch_device_info *type; | ||
455 | int err; | ||
456 | |||
457 | interface = intf->cur_altsetting; | ||
458 | endpoint = &interface->endpoint[0].desc; | ||
459 | |||
460 | usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); | ||
461 | input_dev = input_allocate_device(); | ||
462 | if (!usbtouch || !input_dev) | ||
463 | goto out_free; | ||
464 | |||
465 | type = &usbtouch_dev_info[id->driver_info]; | ||
466 | usbtouch->type = type; | ||
467 | if (!type->process_pkt) | ||
468 | type->process_pkt = usbtouch_process_pkt; | ||
469 | |||
470 | usbtouch->data = usb_buffer_alloc(udev, type->rept_size, | ||
471 | SLAB_KERNEL, &usbtouch->data_dma); | ||
472 | if (!usbtouch->data) | ||
473 | goto out_free; | ||
474 | |||
475 | if (type->flags & USBTOUCH_FLG_BUFFER) { | ||
476 | usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL); | ||
477 | if (!usbtouch->buffer) | ||
478 | goto out_free_buffers; | ||
479 | } | ||
480 | |||
481 | usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
482 | if (!usbtouch->irq) { | ||
483 | dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__); | ||
484 | goto out_free_buffers; | ||
485 | } | ||
486 | |||
487 | usbtouch->udev = udev; | ||
488 | usbtouch->input = input_dev; | ||
489 | |||
490 | if (udev->manufacturer) | ||
491 | strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name)); | ||
492 | |||
493 | if (udev->product) { | ||
494 | if (udev->manufacturer) | ||
495 | strlcat(usbtouch->name, " ", sizeof(usbtouch->name)); | ||
496 | strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name)); | ||
497 | } | ||
498 | |||
499 | if (!strlen(usbtouch->name)) | ||
500 | snprintf(usbtouch->name, sizeof(usbtouch->name), | ||
501 | "USB Touchscreen %04x:%04x", | ||
502 | le16_to_cpu(udev->descriptor.idVendor), | ||
503 | le16_to_cpu(udev->descriptor.idProduct)); | ||
504 | |||
505 | usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys)); | ||
506 | strlcpy(usbtouch->phys, "/input0", sizeof(usbtouch->phys)); | ||
507 | |||
508 | input_dev->name = usbtouch->name; | ||
509 | input_dev->phys = usbtouch->phys; | ||
510 | usb_to_input_id(udev, &input_dev->id); | ||
511 | input_dev->cdev.dev = &intf->dev; | ||
512 | input_dev->private = usbtouch; | ||
513 | input_dev->open = usbtouch_open; | ||
514 | input_dev->close = usbtouch_close; | ||
515 | |||
516 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
517 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
518 | input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0); | ||
519 | input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0); | ||
520 | if (type->max_press) | ||
521 | input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, | ||
522 | type->max_press, 0, 0); | ||
523 | |||
524 | usb_fill_int_urb(usbtouch->irq, usbtouch->udev, | ||
525 | usb_rcvintpipe(usbtouch->udev, 0x81), | ||
526 | usbtouch->data, type->rept_size, | ||
527 | usbtouch_irq, usbtouch, endpoint->bInterval); | ||
528 | |||
529 | usbtouch->irq->transfer_dma = usbtouch->data_dma; | ||
530 | usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
531 | |||
532 | /* device specific init */ | ||
533 | if (type->init) { | ||
534 | err = type->init(usbtouch); | ||
535 | if (err) { | ||
536 | dbg("%s - type->init() failed, err: %d", __FUNCTION__, err); | ||
537 | goto out_free_buffers; | ||
538 | } | ||
539 | } | ||
540 | |||
541 | err = input_register_device(usbtouch->input); | ||
542 | if (err) { | ||
543 | dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err); | ||
544 | goto out_free_buffers; | ||
545 | } | ||
546 | |||
547 | usb_set_intfdata(intf, usbtouch); | ||
548 | |||
549 | return 0; | ||
550 | |||
551 | out_free_buffers: | ||
552 | usbtouch_free_buffers(udev, usbtouch); | ||
553 | out_free: | ||
554 | input_free_device(input_dev); | ||
555 | kfree(usbtouch); | ||
556 | return -ENOMEM; | ||
557 | } | ||
558 | |||
559 | static void usbtouch_disconnect(struct usb_interface *intf) | ||
560 | { | ||
561 | struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); | ||
562 | |||
563 | dbg("%s - called", __FUNCTION__); | ||
564 | |||
565 | if (!usbtouch) | ||
566 | return; | ||
567 | |||
568 | dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__); | ||
569 | usb_set_intfdata(intf, NULL); | ||
570 | usb_kill_urb(usbtouch->irq); | ||
571 | input_unregister_device(usbtouch->input); | ||
572 | usb_free_urb(usbtouch->irq); | ||
573 | usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); | ||
574 | kfree(usbtouch); | ||
575 | } | ||
576 | |||
577 | MODULE_DEVICE_TABLE(usb, usbtouch_devices); | ||
578 | |||
579 | static struct usb_driver usbtouch_driver = { | ||
580 | .name = "usbtouchscreen", | ||
581 | .probe = usbtouch_probe, | ||
582 | .disconnect = usbtouch_disconnect, | ||
583 | .id_table = usbtouch_devices, | ||
584 | }; | ||
585 | |||
586 | static int __init usbtouch_init(void) | ||
587 | { | ||
588 | return usb_register(&usbtouch_driver); | ||
589 | } | ||
590 | |||
591 | static void __exit usbtouch_cleanup(void) | ||
592 | { | ||
593 | usb_deregister(&usbtouch_driver); | ||
594 | } | ||
595 | |||
596 | module_init(usbtouch_init); | ||
597 | module_exit(usbtouch_cleanup); | ||
598 | |||
599 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
600 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
601 | MODULE_LICENSE("GPL"); | ||
602 | |||
603 | MODULE_ALIAS("touchkitusb"); | ||
604 | MODULE_ALIAS("itmtouch"); | ||
605 | MODULE_ALIAS("mtouchusb"); | ||
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index d3e15df9e815..cf84c6096f29 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * Copyright (c) 2000 Daniel Egger <egger@suse.de> | 9 | * Copyright (c) 2000 Daniel Egger <egger@suse.de> |
10 | * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> | 10 | * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> |
11 | * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> | 11 | * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> |
12 | * Copyright (c) 2002-2005 Ping Cheng <pingc@wacom.com> | 12 | * Copyright (c) 2002-2006 Ping Cheng <pingc@wacom.com> |
13 | * | 13 | * |
14 | * ChangeLog: | 14 | * ChangeLog: |
15 | * v0.1 (vp) - Initial release | 15 | * v0.1 (vp) - Initial release |
@@ -56,6 +56,8 @@ | |||
56 | * - Merged wacom_intuos3_irq into wacom_intuos_irq | 56 | * - Merged wacom_intuos3_irq into wacom_intuos_irq |
57 | * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. | 57 | * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. |
58 | * - Report Device IDs | 58 | * - Report Device IDs |
59 | * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 | ||
60 | * - Minor data report fix | ||
59 | */ | 61 | */ |
60 | 62 | ||
61 | /* | 63 | /* |
@@ -78,7 +80,7 @@ | |||
78 | /* | 80 | /* |
79 | * Version Information | 81 | * Version Information |
80 | */ | 82 | */ |
81 | #define DRIVER_VERSION "v1.44" | 83 | #define DRIVER_VERSION "v1.45" |
82 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" | 84 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" |
83 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" | 85 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" |
84 | #define DRIVER_LICENSE "GPL" | 86 | #define DRIVER_LICENSE "GPL" |
@@ -99,6 +101,8 @@ enum { | |||
99 | PL, | 101 | PL, |
100 | INTUOS, | 102 | INTUOS, |
101 | INTUOS3, | 103 | INTUOS3, |
104 | INTUOS312, | ||
105 | INTUOS319, | ||
102 | CINTIQ, | 106 | CINTIQ, |
103 | MAX_TYPE | 107 | MAX_TYPE |
104 | }; | 108 | }; |
@@ -127,7 +131,19 @@ struct wacom { | |||
127 | char phys[32]; | 131 | char phys[32]; |
128 | }; | 132 | }; |
129 | 133 | ||
134 | #define USB_REQ_GET_REPORT 0x01 | ||
130 | #define USB_REQ_SET_REPORT 0x09 | 135 | #define USB_REQ_SET_REPORT 0x09 |
136 | |||
137 | static int usb_get_report(struct usb_interface *intf, unsigned char type, | ||
138 | unsigned char id, void *buf, int size) | ||
139 | { | ||
140 | return usb_control_msg(interface_to_usbdev(intf), | ||
141 | usb_rcvctrlpipe(interface_to_usbdev(intf), 0), | ||
142 | USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
143 | (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, | ||
144 | buf, size, 100); | ||
145 | } | ||
146 | |||
131 | static int usb_set_report(struct usb_interface *intf, unsigned char type, | 147 | static int usb_set_report(struct usb_interface *intf, unsigned char type, |
132 | unsigned char id, void *buf, int size) | 148 | unsigned char id, void *buf, int size) |
133 | { | 149 | { |
@@ -206,7 +222,8 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) | |||
206 | wacom->tool[1] = BTN_TOOL_PEN; | 222 | wacom->tool[1] = BTN_TOOL_PEN; |
207 | id = STYLUS_DEVICE_ID; | 223 | id = STYLUS_DEVICE_ID; |
208 | } | 224 | } |
209 | input_report_key(dev, wacom->tool[1], id); /* report in proximity for tool */ | 225 | input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ |
226 | input_report_abs(dev, ABS_MISC, id); /* report tool id */ | ||
210 | input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); | 227 | input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); |
211 | input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); | 228 | input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); |
212 | input_report_abs(dev, ABS_PRESSURE, pressure); | 229 | input_report_abs(dev, ABS_PRESSURE, pressure); |
@@ -239,7 +256,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) | |||
239 | struct wacom *wacom = urb->context; | 256 | struct wacom *wacom = urb->context; |
240 | unsigned char *data = wacom->data; | 257 | unsigned char *data = wacom->data; |
241 | struct input_dev *dev = wacom->dev; | 258 | struct input_dev *dev = wacom->dev; |
242 | int retval; | 259 | int retval, id; |
243 | 260 | ||
244 | switch (urb->status) { | 261 | switch (urb->status) { |
245 | case 0: | 262 | case 0: |
@@ -263,12 +280,15 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) | |||
263 | 280 | ||
264 | input_regs(dev, regs); | 281 | input_regs(dev, regs); |
265 | if (data[1] & 0x04) { | 282 | if (data[1] & 0x04) { |
266 | input_report_key(dev, BTN_TOOL_RUBBER, (data[1] & 0x20) ? ERASER_DEVICE_ID : 0); | 283 | input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); |
267 | input_report_key(dev, BTN_TOUCH, data[1] & 0x08); | 284 | input_report_key(dev, BTN_TOUCH, data[1] & 0x08); |
285 | id = ERASER_DEVICE_ID; | ||
268 | } else { | 286 | } else { |
269 | input_report_key(dev, BTN_TOOL_PEN, (data[1] & 0x20) ? STYLUS_DEVICE_ID : 0); | 287 | input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); |
270 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); | 288 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); |
289 | id = STYLUS_DEVICE_ID; | ||
271 | } | 290 | } |
291 | input_report_abs(dev, ABS_MISC, id); /* report tool id */ | ||
272 | input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2])); | 292 | input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2])); |
273 | input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4])); | 293 | input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4])); |
274 | input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); | 294 | input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); |
@@ -312,7 +332,8 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) | |||
312 | } | 332 | } |
313 | 333 | ||
314 | input_regs(dev, regs); | 334 | input_regs(dev, regs); |
315 | input_report_key(dev, BTN_TOOL_PEN, STYLUS_DEVICE_ID); | 335 | input_report_key(dev, BTN_TOOL_PEN, 1); |
336 | input_report_abs(dev, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ | ||
316 | input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); | 337 | input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); |
317 | input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); | 338 | input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); |
318 | input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); | 339 | input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); |
@@ -350,6 +371,8 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
350 | goto exit; | 371 | goto exit; |
351 | } | 372 | } |
352 | 373 | ||
374 | if (data[0] == 99) return; /* for Volito tablets */ | ||
375 | |||
353 | if (data[0] != 2) { | 376 | if (data[0] != 2) { |
354 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); | 377 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); |
355 | goto exit; | 378 | goto exit; |
@@ -374,10 +397,10 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
374 | case 2: /* Mouse with wheel */ | 397 | case 2: /* Mouse with wheel */ |
375 | input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); | 398 | input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); |
376 | if (wacom->features->type == WACOM_G4) { | 399 | if (wacom->features->type == WACOM_G4) { |
377 | rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03); | 400 | rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); |
378 | input_report_rel(dev, REL_WHEEL, rw); | 401 | input_report_rel(dev, REL_WHEEL, -rw); |
379 | } else | 402 | } else |
380 | input_report_rel(dev, REL_WHEEL, (signed char) data[6]); | 403 | input_report_rel(dev, REL_WHEEL, -(signed char) data[6]); |
381 | /* fall through */ | 404 | /* fall through */ |
382 | 405 | ||
383 | case 3: /* Mouse without wheel */ | 406 | case 3: /* Mouse without wheel */ |
@@ -406,39 +429,27 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
406 | } | 429 | } |
407 | } | 430 | } |
408 | 431 | ||
409 | input_report_key(dev, wacom->tool[0], (data[1] & 0x10) ? id : 0); | 432 | if (data[1] & 0x10) |
433 | input_report_abs(dev, ABS_MISC, id); /* report tool id */ | ||
434 | else | ||
435 | input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ | ||
436 | input_report_key(dev, wacom->tool[0], data[1] & 0x10); | ||
410 | input_sync(dev); | 437 | input_sync(dev); |
411 | 438 | ||
412 | /* send pad data */ | 439 | /* send pad data */ |
413 | if (wacom->features->type == WACOM_G4) { | 440 | if (wacom->features->type == WACOM_G4) { |
414 | /* fist time sending pad data */ | 441 | if ((wacom->serial[1] & 0xc0) != (data[7] & 0xf8)) { |
415 | if (wacom->tool[1] != BTN_TOOL_FINGER) { | 442 | wacom->id[1] = 1; |
416 | wacom->id[1] = 0; | 443 | wacom->serial[1] = (data[7] & 0xf8); |
417 | wacom->serial[1] = (data[7] & 0x38) >> 2; | ||
418 | } | ||
419 | if (data[7] & 0xf8) { | ||
420 | input_report_key(dev, BTN_0, (data[7] & 0x40)); | 444 | input_report_key(dev, BTN_0, (data[7] & 0x40)); |
421 | input_report_key(dev, BTN_4, (data[7] & 0x80)); | 445 | input_report_key(dev, BTN_4, (data[7] & 0x80)); |
422 | if (((data[7] & 0x38) >> 2) == (wacom->serial[1] & 0x0e)) | 446 | rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); |
423 | /* alter REL_WHEEL value so X apps can get it */ | ||
424 | wacom->serial[1] += (wacom->serial[1] & 0x01) ? -1 : 1; | ||
425 | else | ||
426 | wacom->serial[1] = (data[7] & 0x38 ) >> 2; | ||
427 | |||
428 | /* don't alter the value when there is no wheel event */ | ||
429 | if (wacom->serial[1] == 1) | ||
430 | wacom->serial[1] = 0; | ||
431 | rw = wacom->serial[1]; | ||
432 | rw = (rw & 0x08) ? -(rw & 0x07) : (rw & 0x07); | ||
433 | input_report_rel(dev, REL_WHEEL, rw); | 447 | input_report_rel(dev, REL_WHEEL, rw); |
434 | wacom->tool[1] = BTN_TOOL_FINGER; | 448 | input_report_key(dev, BTN_TOOL_FINGER, 0xf0); |
435 | wacom->id[1] = data[7] & 0xf8; | ||
436 | input_report_key(dev, wacom->tool[1], 0xf0); | ||
437 | input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); | 449 | input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); |
438 | } else if (wacom->id[1]) { | 450 | } else if (wacom->id[1]) { |
439 | wacom->id[1] = 0; | 451 | wacom->id[1] = 0; |
440 | wacom->serial[1] = 0; | 452 | input_report_key(dev, BTN_TOOL_FINGER, 0); |
441 | input_report_key(dev, wacom->tool[1], 0); | ||
442 | input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); | 453 | input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); |
443 | } | 454 | } |
444 | input_sync(dev); | 455 | input_sync(dev); |
@@ -516,21 +527,31 @@ static int wacom_intuos_inout(struct urb *urb) | |||
516 | default: /* Unknown tool */ | 527 | default: /* Unknown tool */ |
517 | wacom->tool[idx] = BTN_TOOL_PEN; | 528 | wacom->tool[idx] = BTN_TOOL_PEN; |
518 | } | 529 | } |
519 | input_report_key(dev, wacom->tool[idx], wacom->id[idx]); | 530 | if(!((wacom->tool[idx] == BTN_TOOL_LENS) && |
520 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 531 | ((wacom->features->type == INTUOS312) |
521 | input_sync(dev); | 532 | || (wacom->features->type == INTUOS319)))) { |
533 | input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */ | ||
534 | input_report_key(dev, wacom->tool[idx], 1); | ||
535 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | ||
536 | input_sync(dev); | ||
537 | } | ||
522 | return 1; | 538 | return 1; |
523 | } | 539 | } |
524 | 540 | ||
525 | /* Exit report */ | 541 | /* Exit report */ |
526 | if ((data[1] & 0xfe) == 0x80) { | 542 | if ((data[1] & 0xfe) == 0x80) { |
527 | input_report_key(dev, wacom->tool[idx], 0); | 543 | input_report_key(dev, wacom->tool[idx], 0); |
544 | input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ | ||
528 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 545 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); |
529 | input_sync(dev); | 546 | input_sync(dev); |
530 | return 1; | 547 | return 1; |
531 | } | 548 | } |
532 | 549 | ||
533 | return 0; | 550 | if((wacom->tool[idx] == BTN_TOOL_LENS) && ((wacom->features->type == INTUOS312) |
551 | || (wacom->features->type == INTUOS319))) | ||
552 | return 1; | ||
553 | else | ||
554 | return 0; | ||
534 | } | 555 | } |
535 | 556 | ||
536 | static void wacom_intuos_general(struct urb *urb) | 557 | static void wacom_intuos_general(struct urb *urb) |
@@ -600,10 +621,9 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) | |||
600 | /* pad packets. Works as a second tool and is always in prox */ | 621 | /* pad packets. Works as a second tool and is always in prox */ |
601 | if (data[0] == 12) { | 622 | if (data[0] == 12) { |
602 | /* initiate the pad as a device */ | 623 | /* initiate the pad as a device */ |
603 | if (wacom->tool[1] != BTN_TOOL_FINGER) { | 624 | if (wacom->tool[1] != BTN_TOOL_FINGER) |
604 | wacom->tool[1] = BTN_TOOL_FINGER; | 625 | wacom->tool[1] = BTN_TOOL_FINGER; |
605 | input_report_key(dev, wacom->tool[1], 1); | 626 | |
606 | } | ||
607 | input_report_key(dev, BTN_0, (data[5] & 0x01)); | 627 | input_report_key(dev, BTN_0, (data[5] & 0x01)); |
608 | input_report_key(dev, BTN_1, (data[5] & 0x02)); | 628 | input_report_key(dev, BTN_1, (data[5] & 0x02)); |
609 | input_report_key(dev, BTN_2, (data[5] & 0x04)); | 629 | input_report_key(dev, BTN_2, (data[5] & 0x04)); |
@@ -614,6 +634,11 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) | |||
614 | input_report_key(dev, BTN_7, (data[6] & 0x08)); | 634 | input_report_key(dev, BTN_7, (data[6] & 0x08)); |
615 | input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); | 635 | input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); |
616 | input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); | 636 | input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); |
637 | |||
638 | if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | data[2]) | ||
639 | input_report_key(dev, wacom->tool[1], 1); | ||
640 | else | ||
641 | input_report_key(dev, wacom->tool[1], 0); | ||
617 | input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff); | 642 | input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff); |
618 | input_sync(dev); | 643 | input_sync(dev); |
619 | goto exit; | 644 | goto exit; |
@@ -676,8 +701,8 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) | |||
676 | input_report_key(dev, BTN_LEFT, data[8] & 0x04); | 701 | input_report_key(dev, BTN_LEFT, data[8] & 0x04); |
677 | input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); | 702 | input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); |
678 | input_report_key(dev, BTN_RIGHT, data[8] & 0x10); | 703 | input_report_key(dev, BTN_RIGHT, data[8] & 0x10); |
679 | input_report_rel(dev, REL_WHEEL, ((data[8] & 0x02) >> 1) | 704 | input_report_rel(dev, REL_WHEEL, (data[8] & 0x01) |
680 | - (data[8] & 0x01)); | 705 | - ((data[8] & 0x02) >> 1)); |
681 | 706 | ||
682 | /* I3 2D mouse side buttons */ | 707 | /* I3 2D mouse side buttons */ |
683 | if (wacom->features->type == INTUOS3) { | 708 | if (wacom->features->type == INTUOS3) { |
@@ -695,7 +720,8 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) | |||
695 | } | 720 | } |
696 | } | 721 | } |
697 | 722 | ||
698 | input_report_key(dev, wacom->tool[idx], wacom->id[idx]); | 723 | input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */ |
724 | input_report_key(dev, wacom->tool[idx], 1); | ||
699 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 725 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); |
700 | input_sync(dev); | 726 | input_sync(dev); |
701 | 727 | ||
@@ -733,7 +759,8 @@ static struct wacom_features wacom_features[] = { | |||
733 | { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq }, | 759 | { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq }, |
734 | { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_pl_irq }, | 760 | { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_pl_irq }, |
735 | { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq }, | 761 | { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq }, |
736 | { "Wacom PL710", 8, 34080, 27660, 511, 32, PL, wacom_pl_irq }, | 762 | { "Wacom DTU710", 8, 34080, 27660, 511, 32, PL, wacom_pl_irq }, |
763 | { "Wacom DTF521", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq }, | ||
737 | { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_pl_irq }, | 764 | { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_pl_irq }, |
738 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq }, | 765 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq }, |
739 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, | 766 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, |
@@ -744,6 +771,8 @@ static struct wacom_features wacom_features[] = { | |||
744 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq }, | 771 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq }, |
745 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq }, | 772 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq }, |
746 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq }, | 773 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq }, |
774 | { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 15, INTUOS312, wacom_intuos_irq }, | ||
775 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 15, INTUOS319, wacom_intuos_irq }, | ||
747 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_intuos_irq }, | 776 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_intuos_irq }, |
748 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq }, | 777 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq }, |
749 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, | 778 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, |
@@ -779,6 +808,7 @@ static struct usb_device_id wacom_ids[] = { | |||
779 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, | 808 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, |
780 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, | 809 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, |
781 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, | 810 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, |
811 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC3) }, | ||
782 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, | 812 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, |
783 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, | 813 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, |
784 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, | 814 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, |
@@ -788,6 +818,8 @@ static struct usb_device_id wacom_ids[] = { | |||
788 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, | 818 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, |
789 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, | 819 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, |
790 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, | 820 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, |
821 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, | ||
822 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, | ||
791 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, | 823 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, |
792 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, | 824 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, |
793 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | 825 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, |
@@ -820,7 +852,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
820 | struct usb_endpoint_descriptor *endpoint; | 852 | struct usb_endpoint_descriptor *endpoint; |
821 | struct wacom *wacom; | 853 | struct wacom *wacom; |
822 | struct input_dev *input_dev; | 854 | struct input_dev *input_dev; |
823 | char rep_data[2] = {0x02, 0x02}; | 855 | char rep_data[2], limit = 0; |
824 | 856 | ||
825 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 857 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
826 | input_dev = input_allocate_device(); | 858 | input_dev = input_allocate_device(); |
@@ -857,6 +889,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
857 | input_set_abs_params(input_dev, ABS_X, 0, wacom->features->x_max, 4, 0); | 889 | input_set_abs_params(input_dev, ABS_X, 0, wacom->features->x_max, 4, 0); |
858 | input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0); | 890 | input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0); |
859 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); | 891 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); |
892 | input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); | ||
860 | 893 | ||
861 | switch (wacom->features->type) { | 894 | switch (wacom->features->type) { |
862 | case WACOM_G4: | 895 | case WACOM_G4: |
@@ -875,6 +908,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
875 | break; | 908 | break; |
876 | 909 | ||
877 | case INTUOS3: | 910 | case INTUOS3: |
911 | case INTUOS312: | ||
912 | case INTUOS319: | ||
878 | case CINTIQ: | 913 | case CINTIQ: |
879 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); | 914 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); |
880 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); | 915 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); |
@@ -916,10 +951,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
916 | 951 | ||
917 | input_register_device(wacom->dev); | 952 | input_register_device(wacom->dev); |
918 | 953 | ||
919 | /* ask the tablet to report tablet data */ | 954 | /* Ask the tablet to report tablet data. Repeat until it succeeds */ |
920 | usb_set_report(intf, 3, 2, rep_data, 2); | 955 | do { |
921 | /* repeat once (not sure why the first call often fails) */ | 956 | rep_data[0] = 2; |
922 | usb_set_report(intf, 3, 2, rep_data, 2); | 957 | rep_data[1] = 2; |
958 | usb_set_report(intf, 3, 2, rep_data, 2); | ||
959 | usb_get_report(intf, 3, 2, rep_data, 2); | ||
960 | } while (rep_data[1] != 2 && limit++ < 5); | ||
923 | 961 | ||
924 | usb_set_intfdata(intf, wacom); | 962 | usb_set_intfdata(intf, wacom); |
925 | return 0; | 963 | return 0; |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 9d59b901841c..ccc5e8238bd8 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -381,6 +381,7 @@ alloc_sglist (int nents, int max, int vary) | |||
381 | 381 | ||
382 | for (i = 0; i < nents; i++) { | 382 | for (i = 0; i < nents; i++) { |
383 | char *buf; | 383 | char *buf; |
384 | unsigned j; | ||
384 | 385 | ||
385 | buf = kzalloc (size, SLAB_KERNEL); | 386 | buf = kzalloc (size, SLAB_KERNEL); |
386 | if (!buf) { | 387 | if (!buf) { |
@@ -391,6 +392,16 @@ alloc_sglist (int nents, int max, int vary) | |||
391 | /* kmalloc pages are always physically contiguous! */ | 392 | /* kmalloc pages are always physically contiguous! */ |
392 | sg_init_one(&sg[i], buf, size); | 393 | sg_init_one(&sg[i], buf, size); |
393 | 394 | ||
395 | switch (pattern) { | ||
396 | case 0: | ||
397 | /* already zeroed */ | ||
398 | break; | ||
399 | case 1: | ||
400 | for (j = 0; j < size; j++) | ||
401 | *buf++ = (u8) (j % 63); | ||
402 | break; | ||
403 | } | ||
404 | |||
394 | if (vary) { | 405 | if (vary) { |
395 | size += vary; | 406 | size += vary; |
396 | size %= max; | 407 | size %= max; |
@@ -425,6 +436,8 @@ static int perform_sglist ( | |||
425 | usb_sg_wait (req); | 436 | usb_sg_wait (req); |
426 | retval = req->status; | 437 | retval = req->status; |
427 | 438 | ||
439 | /* FIXME check resulting data pattern */ | ||
440 | |||
428 | /* FIXME if endpoint halted, clear halt (and log) */ | 441 | /* FIXME if endpoint halted, clear halt (and log) */ |
429 | } | 442 | } |
430 | 443 | ||
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 3094970615cb..12b599a0b539 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c | |||
@@ -37,7 +37,6 @@ | |||
37 | 37 | ||
38 | #include "usbnet.h" | 38 | #include "usbnet.h" |
39 | 39 | ||
40 | |||
41 | /* ASIX AX8817X based USB 2.0 Ethernet Devices */ | 40 | /* ASIX AX8817X based USB 2.0 Ethernet Devices */ |
42 | 41 | ||
43 | #define AX_CMD_SET_SW_MII 0x06 | 42 | #define AX_CMD_SET_SW_MII 0x06 |
@@ -109,7 +108,7 @@ | |||
109 | #define AX_EEPROM_MAGIC 0xdeadbeef | 108 | #define AX_EEPROM_MAGIC 0xdeadbeef |
110 | 109 | ||
111 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ | 110 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ |
112 | struct ax8817x_data { | 111 | struct asix_data { |
113 | u8 multi_filter[AX_MCAST_FILTER_SIZE]; | 112 | u8 multi_filter[AX_MCAST_FILTER_SIZE]; |
114 | }; | 113 | }; |
115 | 114 | ||
@@ -121,7 +120,7 @@ struct ax88172_int_data { | |||
121 | u16 res3; | 120 | u16 res3; |
122 | } __attribute__ ((packed)); | 121 | } __attribute__ ((packed)); |
123 | 122 | ||
124 | static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | 123 | static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, |
125 | u16 size, void *data) | 124 | u16 size, void *data) |
126 | { | 125 | { |
127 | return usb_control_msg( | 126 | return usb_control_msg( |
@@ -136,7 +135,7 @@ static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | |||
136 | USB_CTRL_GET_TIMEOUT); | 135 | USB_CTRL_GET_TIMEOUT); |
137 | } | 136 | } |
138 | 137 | ||
139 | static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | 138 | static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, |
140 | u16 size, void *data) | 139 | u16 size, void *data) |
141 | { | 140 | { |
142 | return usb_control_msg( | 141 | return usb_control_msg( |
@@ -151,19 +150,80 @@ static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | |||
151 | USB_CTRL_SET_TIMEOUT); | 150 | USB_CTRL_SET_TIMEOUT); |
152 | } | 151 | } |
153 | 152 | ||
154 | static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs) | 153 | static void asix_async_cmd_callback(struct urb *urb, struct pt_regs *regs) |
155 | { | 154 | { |
156 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; | 155 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; |
157 | 156 | ||
158 | if (urb->status < 0) | 157 | if (urb->status < 0) |
159 | printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d", | 158 | printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d", |
160 | urb->status); | 159 | urb->status); |
161 | 160 | ||
162 | kfree(req); | 161 | kfree(req); |
163 | usb_free_urb(urb); | 162 | usb_free_urb(urb); |
164 | } | 163 | } |
165 | 164 | ||
166 | static void ax8817x_status(struct usbnet *dev, struct urb *urb) | 165 | static inline int asix_set_sw_mii(struct usbnet *dev) |
166 | { | ||
167 | int ret; | ||
168 | ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); | ||
169 | if (ret < 0) | ||
170 | devdbg(dev, "Failed to enable software MII access"); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | static inline int asix_set_hw_mii(struct usbnet *dev) | ||
175 | { | ||
176 | int ret; | ||
177 | ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); | ||
178 | if (ret < 0) | ||
179 | devdbg(dev, "Failed to enable hardware MII access"); | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | static inline int asix_get_phyid(struct usbnet *dev) | ||
184 | { | ||
185 | int ret = 0; | ||
186 | void *buf; | ||
187 | |||
188 | buf = kmalloc(2, GFP_KERNEL); | ||
189 | if (!buf) | ||
190 | goto out1; | ||
191 | |||
192 | if ((ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, | ||
193 | 0, 0, 2, buf)) < 2) { | ||
194 | devdbg(dev, "Error reading PHYID register: %02x", ret); | ||
195 | goto out2; | ||
196 | } | ||
197 | ret = *((u8 *)buf + 1); | ||
198 | out2: | ||
199 | kfree(buf); | ||
200 | out1: | ||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | static int asix_sw_reset(struct usbnet *dev, u8 flags) | ||
205 | { | ||
206 | int ret; | ||
207 | |||
208 | ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); | ||
209 | if (ret < 0) | ||
210 | devdbg(dev,"Failed to send software reset: %02x", ret); | ||
211 | |||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | static int asix_write_rx_ctl(struct usbnet *dev, u16 mode) | ||
216 | { | ||
217 | int ret; | ||
218 | |||
219 | ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); | ||
220 | if (ret < 0) | ||
221 | devdbg(dev, "Failed to write RX_CTL mode: %02x", ret); | ||
222 | |||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | static void asix_status(struct usbnet *dev, struct urb *urb) | ||
167 | { | 227 | { |
168 | struct ax88172_int_data *event; | 228 | struct ax88172_int_data *event; |
169 | int link; | 229 | int link; |
@@ -179,12 +239,12 @@ static void ax8817x_status(struct usbnet *dev, struct urb *urb) | |||
179 | usbnet_defer_kevent (dev, EVENT_LINK_RESET ); | 239 | usbnet_defer_kevent (dev, EVENT_LINK_RESET ); |
180 | } else | 240 | } else |
181 | netif_carrier_off(dev->net); | 241 | netif_carrier_off(dev->net); |
182 | devdbg(dev, "ax8817x - Link Status is: %d", link); | 242 | devdbg(dev, "Link Status is: %d", link); |
183 | } | 243 | } |
184 | } | 244 | } |
185 | 245 | ||
186 | static void | 246 | static void |
187 | ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | 247 | asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, |
188 | u16 size, void *data) | 248 | u16 size, void *data) |
189 | { | 249 | { |
190 | struct usb_ctrlrequest *req; | 250 | struct usb_ctrlrequest *req; |
@@ -211,7 +271,7 @@ ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | |||
211 | usb_fill_control_urb(urb, dev->udev, | 271 | usb_fill_control_urb(urb, dev->udev, |
212 | usb_sndctrlpipe(dev->udev, 0), | 272 | usb_sndctrlpipe(dev->udev, 0), |
213 | (void *)req, data, size, | 273 | (void *)req, data, size, |
214 | ax8817x_async_cmd_callback, req); | 274 | asix_async_cmd_callback, req); |
215 | 275 | ||
216 | if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { | 276 | if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { |
217 | deverr(dev, "Error submitting the control message: status=%d", | 277 | deverr(dev, "Error submitting the control message: status=%d", |
@@ -221,10 +281,10 @@ ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | |||
221 | } | 281 | } |
222 | } | 282 | } |
223 | 283 | ||
224 | static void ax8817x_set_multicast(struct net_device *net) | 284 | static void asix_set_multicast(struct net_device *net) |
225 | { | 285 | { |
226 | struct usbnet *dev = netdev_priv(net); | 286 | struct usbnet *dev = netdev_priv(net); |
227 | struct ax8817x_data *data = (struct ax8817x_data *)&dev->data; | 287 | struct asix_data *data = (struct asix_data *)&dev->data; |
228 | u8 rx_ctl = 0x8c; | 288 | u8 rx_ctl = 0x8c; |
229 | 289 | ||
230 | if (net->flags & IFF_PROMISC) { | 290 | if (net->flags & IFF_PROMISC) { |
@@ -255,53 +315,51 @@ static void ax8817x_set_multicast(struct net_device *net) | |||
255 | mc_list = mc_list->next; | 315 | mc_list = mc_list->next; |
256 | } | 316 | } |
257 | 317 | ||
258 | ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, | 318 | asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, |
259 | AX_MCAST_FILTER_SIZE, data->multi_filter); | 319 | AX_MCAST_FILTER_SIZE, data->multi_filter); |
260 | 320 | ||
261 | rx_ctl |= 0x10; | 321 | rx_ctl |= 0x10; |
262 | } | 322 | } |
263 | 323 | ||
264 | ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); | 324 | asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); |
265 | } | 325 | } |
266 | 326 | ||
267 | static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc) | 327 | static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) |
268 | { | 328 | { |
269 | struct usbnet *dev = netdev_priv(netdev); | 329 | struct usbnet *dev = netdev_priv(netdev); |
270 | u16 res; | 330 | u16 res; |
271 | u8 buf[1]; | ||
272 | 331 | ||
273 | ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); | 332 | asix_set_sw_mii(dev); |
274 | ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, | 333 | asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, |
275 | (__u16)loc, 2, (u16 *)&res); | 334 | (__u16)loc, 2, (u16 *)&res); |
276 | ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); | 335 | asix_set_hw_mii(dev); |
277 | 336 | ||
278 | return res & 0xffff; | 337 | return res & 0xffff; |
279 | } | 338 | } |
280 | 339 | ||
281 | /* same as above, but converts resulting value to cpu byte order */ | 340 | /* same as above, but converts resulting value to cpu byte order */ |
282 | static int ax8817x_mdio_read_le(struct net_device *netdev, int phy_id, int loc) | 341 | static int asix_mdio_read_le(struct net_device *netdev, int phy_id, int loc) |
283 | { | 342 | { |
284 | return le16_to_cpu(ax8817x_mdio_read(netdev,phy_id, loc)); | 343 | return le16_to_cpu(asix_mdio_read(netdev,phy_id, loc)); |
285 | } | 344 | } |
286 | 345 | ||
287 | static void | 346 | static void |
288 | ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) | 347 | asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) |
289 | { | 348 | { |
290 | struct usbnet *dev = netdev_priv(netdev); | 349 | struct usbnet *dev = netdev_priv(netdev); |
291 | u16 res = val; | 350 | u16 res = val; |
292 | u8 buf[1]; | ||
293 | 351 | ||
294 | ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); | 352 | asix_set_sw_mii(dev); |
295 | ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, | 353 | asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, |
296 | (__u16)loc, 2, (u16 *)&res); | 354 | (__u16)loc, 2, (u16 *)&res); |
297 | ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); | 355 | asix_set_hw_mii(dev); |
298 | } | 356 | } |
299 | 357 | ||
300 | /* same as above, but converts new value to le16 byte order before writing */ | 358 | /* same as above, but converts new value to le16 byte order before writing */ |
301 | static void | 359 | static void |
302 | ax8817x_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val) | 360 | asix_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val) |
303 | { | 361 | { |
304 | ax8817x_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) ); | 362 | asix_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) ); |
305 | } | 363 | } |
306 | 364 | ||
307 | static int ax88172_link_reset(struct usbnet *dev) | 365 | static int ax88172_link_reset(struct usbnet *dev) |
@@ -312,23 +370,23 @@ static int ax88172_link_reset(struct usbnet *dev) | |||
312 | u8 mode; | 370 | u8 mode; |
313 | 371 | ||
314 | mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN; | 372 | mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN; |
315 | lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); | 373 | lpa = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); |
316 | adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); | 374 | adv = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); |
317 | res = mii_nway_result(lpa|adv); | 375 | res = mii_nway_result(lpa|adv); |
318 | if (res & LPA_DUPLEX) | 376 | if (res & LPA_DUPLEX) |
319 | mode |= AX_MEDIUM_FULL_DUPLEX; | 377 | mode |= AX_MEDIUM_FULL_DUPLEX; |
320 | ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); | 378 | asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); |
321 | 379 | ||
322 | return 0; | 380 | return 0; |
323 | } | 381 | } |
324 | 382 | ||
325 | static void | 383 | static void |
326 | ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | 384 | asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) |
327 | { | 385 | { |
328 | struct usbnet *dev = netdev_priv(net); | 386 | struct usbnet *dev = netdev_priv(net); |
329 | u8 opt; | 387 | u8 opt; |
330 | 388 | ||
331 | if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { | 389 | if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { |
332 | wolinfo->supported = 0; | 390 | wolinfo->supported = 0; |
333 | wolinfo->wolopts = 0; | 391 | wolinfo->wolopts = 0; |
334 | return; | 392 | return; |
@@ -344,7 +402,7 @@ ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | |||
344 | } | 402 | } |
345 | 403 | ||
346 | static int | 404 | static int |
347 | ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | 405 | asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) |
348 | { | 406 | { |
349 | struct usbnet *dev = netdev_priv(net); | 407 | struct usbnet *dev = netdev_priv(net); |
350 | u8 opt = 0; | 408 | u8 opt = 0; |
@@ -357,19 +415,19 @@ ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | |||
357 | if (opt != 0) | 415 | if (opt != 0) |
358 | opt |= AX_MONITOR_MODE; | 416 | opt |= AX_MONITOR_MODE; |
359 | 417 | ||
360 | if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, | 418 | if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, |
361 | opt, 0, 0, &buf) < 0) | 419 | opt, 0, 0, &buf) < 0) |
362 | return -EINVAL; | 420 | return -EINVAL; |
363 | 421 | ||
364 | return 0; | 422 | return 0; |
365 | } | 423 | } |
366 | 424 | ||
367 | static int ax8817x_get_eeprom_len(struct net_device *net) | 425 | static int asix_get_eeprom_len(struct net_device *net) |
368 | { | 426 | { |
369 | return AX_EEPROM_LEN; | 427 | return AX_EEPROM_LEN; |
370 | } | 428 | } |
371 | 429 | ||
372 | static int ax8817x_get_eeprom(struct net_device *net, | 430 | static int asix_get_eeprom(struct net_device *net, |
373 | struct ethtool_eeprom *eeprom, u8 *data) | 431 | struct ethtool_eeprom *eeprom, u8 *data) |
374 | { | 432 | { |
375 | struct usbnet *dev = netdev_priv(net); | 433 | struct usbnet *dev = netdev_priv(net); |
@@ -386,14 +444,14 @@ static int ax8817x_get_eeprom(struct net_device *net, | |||
386 | 444 | ||
387 | /* ax8817x returns 2 bytes from eeprom on read */ | 445 | /* ax8817x returns 2 bytes from eeprom on read */ |
388 | for (i=0; i < eeprom->len / 2; i++) { | 446 | for (i=0; i < eeprom->len / 2; i++) { |
389 | if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM, | 447 | if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, |
390 | eeprom->offset + i, 0, 2, &ebuf[i]) < 0) | 448 | eeprom->offset + i, 0, 2, &ebuf[i]) < 0) |
391 | return -EINVAL; | 449 | return -EINVAL; |
392 | } | 450 | } |
393 | return 0; | 451 | return 0; |
394 | } | 452 | } |
395 | 453 | ||
396 | static void ax8817x_get_drvinfo (struct net_device *net, | 454 | static void asix_get_drvinfo (struct net_device *net, |
397 | struct ethtool_drvinfo *info) | 455 | struct ethtool_drvinfo *info) |
398 | { | 456 | { |
399 | /* Inherit standard device info */ | 457 | /* Inherit standard device info */ |
@@ -401,14 +459,14 @@ static void ax8817x_get_drvinfo (struct net_device *net, | |||
401 | info->eedump_len = 0x3e; | 459 | info->eedump_len = 0x3e; |
402 | } | 460 | } |
403 | 461 | ||
404 | static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd) | 462 | static int asix_get_settings(struct net_device *net, struct ethtool_cmd *cmd) |
405 | { | 463 | { |
406 | struct usbnet *dev = netdev_priv(net); | 464 | struct usbnet *dev = netdev_priv(net); |
407 | 465 | ||
408 | return mii_ethtool_gset(&dev->mii,cmd); | 466 | return mii_ethtool_gset(&dev->mii,cmd); |
409 | } | 467 | } |
410 | 468 | ||
411 | static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd) | 469 | static int asix_set_settings(struct net_device *net, struct ethtool_cmd *cmd) |
412 | { | 470 | { |
413 | struct usbnet *dev = netdev_priv(net); | 471 | struct usbnet *dev = netdev_priv(net); |
414 | 472 | ||
@@ -418,27 +476,27 @@ static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd) | |||
418 | /* We need to override some ethtool_ops so we require our | 476 | /* We need to override some ethtool_ops so we require our |
419 | own structure so we don't interfere with other usbnet | 477 | own structure so we don't interfere with other usbnet |
420 | devices that may be connected at the same time. */ | 478 | devices that may be connected at the same time. */ |
421 | static struct ethtool_ops ax8817x_ethtool_ops = { | 479 | static struct ethtool_ops ax88172_ethtool_ops = { |
422 | .get_drvinfo = ax8817x_get_drvinfo, | 480 | .get_drvinfo = asix_get_drvinfo, |
423 | .get_link = ethtool_op_get_link, | 481 | .get_link = ethtool_op_get_link, |
424 | .get_msglevel = usbnet_get_msglevel, | 482 | .get_msglevel = usbnet_get_msglevel, |
425 | .set_msglevel = usbnet_set_msglevel, | 483 | .set_msglevel = usbnet_set_msglevel, |
426 | .get_wol = ax8817x_get_wol, | 484 | .get_wol = asix_get_wol, |
427 | .set_wol = ax8817x_set_wol, | 485 | .set_wol = asix_set_wol, |
428 | .get_eeprom_len = ax8817x_get_eeprom_len, | 486 | .get_eeprom_len = asix_get_eeprom_len, |
429 | .get_eeprom = ax8817x_get_eeprom, | 487 | .get_eeprom = asix_get_eeprom, |
430 | .get_settings = ax8817x_get_settings, | 488 | .get_settings = asix_get_settings, |
431 | .set_settings = ax8817x_set_settings, | 489 | .set_settings = asix_set_settings, |
432 | }; | 490 | }; |
433 | 491 | ||
434 | static int ax8817x_ioctl (struct net_device *net, struct ifreq *rq, int cmd) | 492 | static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) |
435 | { | 493 | { |
436 | struct usbnet *dev = netdev_priv(net); | 494 | struct usbnet *dev = netdev_priv(net); |
437 | 495 | ||
438 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | 496 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); |
439 | } | 497 | } |
440 | 498 | ||
441 | static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf) | 499 | static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) |
442 | { | 500 | { |
443 | int ret = 0; | 501 | int ret = 0; |
444 | void *buf; | 502 | void *buf; |
@@ -455,55 +513,39 @@ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf) | |||
455 | 513 | ||
456 | /* Toggle the GPIOs in a manufacturer/model specific way */ | 514 | /* Toggle the GPIOs in a manufacturer/model specific way */ |
457 | for (i = 2; i >= 0; i--) { | 515 | for (i = 2; i >= 0; i--) { |
458 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, | 516 | if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, |
459 | (gpio_bits >> (i * 8)) & 0xff, 0, 0, | 517 | (gpio_bits >> (i * 8)) & 0xff, 0, 0, |
460 | buf)) < 0) | 518 | buf)) < 0) |
461 | goto out2; | 519 | goto out2; |
462 | msleep(5); | 520 | msleep(5); |
463 | } | 521 | } |
464 | 522 | ||
465 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, | 523 | if ((ret = asix_write_rx_ctl(dev,0x80)) < 0) |
466 | 0x80, 0, 0, buf)) < 0) { | ||
467 | dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret); | ||
468 | goto out2; | 524 | goto out2; |
469 | } | ||
470 | 525 | ||
471 | /* Get the MAC address */ | 526 | /* Get the MAC address */ |
472 | memset(buf, 0, ETH_ALEN); | 527 | memset(buf, 0, ETH_ALEN); |
473 | if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, | 528 | if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, |
474 | 0, 0, 6, buf)) < 0) { | 529 | 0, 0, 6, buf)) < 0) { |
475 | dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); | 530 | dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); |
476 | goto out2; | 531 | goto out2; |
477 | } | 532 | } |
478 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); | 533 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); |
479 | 534 | ||
480 | /* Get the PHY id */ | ||
481 | if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, | ||
482 | 0, 0, 2, buf)) < 0) { | ||
483 | dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret); | ||
484 | goto out2; | ||
485 | } else if (ret < 2) { | ||
486 | /* this should always return 2 bytes */ | ||
487 | dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", | ||
488 | ret); | ||
489 | ret = -EIO; | ||
490 | goto out2; | ||
491 | } | ||
492 | |||
493 | /* Initialize MII structure */ | 535 | /* Initialize MII structure */ |
494 | dev->mii.dev = dev->net; | 536 | dev->mii.dev = dev->net; |
495 | dev->mii.mdio_read = ax8817x_mdio_read; | 537 | dev->mii.mdio_read = asix_mdio_read; |
496 | dev->mii.mdio_write = ax8817x_mdio_write; | 538 | dev->mii.mdio_write = asix_mdio_write; |
497 | dev->mii.phy_id_mask = 0x3f; | 539 | dev->mii.phy_id_mask = 0x3f; |
498 | dev->mii.reg_num_mask = 0x1f; | 540 | dev->mii.reg_num_mask = 0x1f; |
499 | dev->mii.phy_id = *((u8 *)buf + 1); | 541 | dev->mii.phy_id = asix_get_phyid(dev); |
500 | dev->net->do_ioctl = ax8817x_ioctl; | 542 | dev->net->do_ioctl = asix_ioctl; |
501 | 543 | ||
502 | dev->net->set_multicast_list = ax8817x_set_multicast; | 544 | dev->net->set_multicast_list = asix_set_multicast; |
503 | dev->net->ethtool_ops = &ax8817x_ethtool_ops; | 545 | dev->net->ethtool_ops = &ax88172_ethtool_ops; |
504 | 546 | ||
505 | ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); | 547 | asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); |
506 | ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, | 548 | asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, |
507 | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); | 549 | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); |
508 | mii_nway_restart(&dev->mii); | 550 | mii_nway_restart(&dev->mii); |
509 | 551 | ||
@@ -515,16 +557,16 @@ out1: | |||
515 | } | 557 | } |
516 | 558 | ||
517 | static struct ethtool_ops ax88772_ethtool_ops = { | 559 | static struct ethtool_ops ax88772_ethtool_ops = { |
518 | .get_drvinfo = ax8817x_get_drvinfo, | 560 | .get_drvinfo = asix_get_drvinfo, |
519 | .get_link = ethtool_op_get_link, | 561 | .get_link = ethtool_op_get_link, |
520 | .get_msglevel = usbnet_get_msglevel, | 562 | .get_msglevel = usbnet_get_msglevel, |
521 | .set_msglevel = usbnet_set_msglevel, | 563 | .set_msglevel = usbnet_set_msglevel, |
522 | .get_wol = ax8817x_get_wol, | 564 | .get_wol = asix_get_wol, |
523 | .set_wol = ax8817x_set_wol, | 565 | .set_wol = asix_set_wol, |
524 | .get_eeprom_len = ax8817x_get_eeprom_len, | 566 | .get_eeprom_len = asix_get_eeprom_len, |
525 | .get_eeprom = ax8817x_get_eeprom, | 567 | .get_eeprom = asix_get_eeprom, |
526 | .get_settings = ax8817x_get_settings, | 568 | .get_settings = asix_get_settings, |
527 | .set_settings = ax8817x_set_settings, | 569 | .set_settings = asix_set_settings, |
528 | }; | 570 | }; |
529 | 571 | ||
530 | static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) | 572 | static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) |
@@ -541,62 +583,45 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) | |||
541 | goto out1; | 583 | goto out1; |
542 | } | 584 | } |
543 | 585 | ||
544 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, | 586 | if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, |
545 | 0x00B0, 0, 0, buf)) < 0) | 587 | 0x00B0, 0, 0, buf)) < 0) |
546 | goto out2; | 588 | goto out2; |
547 | 589 | ||
548 | msleep(5); | 590 | msleep(5); |
549 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, | 591 | if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, |
550 | 0x0001, 0, 0, buf)) < 0) { | 592 | 0x0001, 0, 0, buf)) < 0) { |
551 | dbg("Select PHY #1 failed: %d", ret); | 593 | dbg("Select PHY #1 failed: %d", ret); |
552 | goto out2; | 594 | goto out2; |
553 | } | 595 | } |
554 | 596 | ||
555 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD, | 597 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD)) < 0) |
556 | 0, 0, buf)) < 0) { | ||
557 | dbg("Failed to power down internal PHY: %d", ret); | ||
558 | goto out2; | 598 | goto out2; |
559 | } | ||
560 | 599 | ||
561 | msleep(150); | 600 | msleep(150); |
562 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR, | 601 | if ((ret = asix_sw_reset(dev, AX_SWRESET_CLEAR)) < 0) |
563 | 0, 0, buf)) < 0) { | ||
564 | dbg("Failed to perform software reset: %d", ret); | ||
565 | goto out2; | 602 | goto out2; |
566 | } | ||
567 | 603 | ||
568 | msleep(150); | 604 | msleep(150); |
569 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, | 605 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) |
570 | AX_SWRESET_IPRL | AX_SWRESET_PRL, | ||
571 | 0, 0, buf)) < 0) { | ||
572 | dbg("Failed to set Internal/External PHY reset control: %d", | ||
573 | ret); | ||
574 | goto out2; | 606 | goto out2; |
575 | } | ||
576 | 607 | ||
577 | msleep(150); | 608 | msleep(150); |
578 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, | 609 | if ((ret = asix_write_rx_ctl(dev, 0x00)) < 0) |
579 | 0x0000, 0, 0, buf)) < 0) { | ||
580 | dbg("Failed to reset RX_CTL: %d", ret); | ||
581 | goto out2; | 610 | goto out2; |
582 | } | ||
583 | 611 | ||
584 | /* Get the MAC address */ | 612 | /* Get the MAC address */ |
585 | memset(buf, 0, ETH_ALEN); | 613 | memset(buf, 0, ETH_ALEN); |
586 | if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID, | 614 | if ((ret = asix_read_cmd(dev, AX88772_CMD_READ_NODE_ID, |
587 | 0, 0, ETH_ALEN, buf)) < 0) { | 615 | 0, 0, ETH_ALEN, buf)) < 0) { |
588 | dbg("Failed to read MAC address: %d", ret); | 616 | dbg("Failed to read MAC address: %d", ret); |
589 | goto out2; | 617 | goto out2; |
590 | } | 618 | } |
591 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); | 619 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); |
592 | 620 | ||
593 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, | 621 | if ((ret = asix_set_sw_mii(dev)) < 0) |
594 | 0, 0, 0, buf)) < 0) { | ||
595 | dbg("Enabling software MII failed: %d", ret); | ||
596 | goto out2; | 622 | goto out2; |
597 | } | ||
598 | 623 | ||
599 | if (((ret = ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, | 624 | if (((ret = asix_read_cmd(dev, AX_CMD_READ_MII_REG, |
600 | 0x0010, 2, 2, buf)) < 0) | 625 | 0x0010, 2, 2, buf)) < 0) |
601 | || (*((u16 *)buf) != 0x003b)) { | 626 | || (*((u16 *)buf) != 0x003b)) { |
602 | dbg("Read PHY register 2 must be 0x3b00: %d", ret); | 627 | dbg("Read PHY register 2 must be 0x3b00: %d", ret); |
@@ -605,74 +630,49 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) | |||
605 | 630 | ||
606 | /* Initialize MII structure */ | 631 | /* Initialize MII structure */ |
607 | dev->mii.dev = dev->net; | 632 | dev->mii.dev = dev->net; |
608 | dev->mii.mdio_read = ax8817x_mdio_read; | 633 | dev->mii.mdio_read = asix_mdio_read; |
609 | dev->mii.mdio_write = ax8817x_mdio_write; | 634 | dev->mii.mdio_write = asix_mdio_write; |
610 | dev->mii.phy_id_mask = 0xff; | 635 | dev->mii.phy_id_mask = 0xff; |
611 | dev->mii.reg_num_mask = 0xff; | 636 | dev->mii.reg_num_mask = 0xff; |
612 | dev->net->do_ioctl = ax8817x_ioctl; | 637 | dev->net->do_ioctl = asix_ioctl; |
638 | dev->mii.phy_id = asix_get_phyid(dev); | ||
613 | 639 | ||
614 | /* Get the PHY id */ | 640 | if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0) |
615 | if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, | ||
616 | 0, 0, 2, buf)) < 0) { | ||
617 | dbg("Error reading PHY ID: %02x", ret); | ||
618 | goto out2; | 641 | goto out2; |
619 | } else if (ret < 2) { | ||
620 | /* this should always return 2 bytes */ | ||
621 | dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", | ||
622 | ret); | ||
623 | ret = -EIO; | ||
624 | goto out2; | ||
625 | } | ||
626 | dev->mii.phy_id = *((u8 *)buf + 1); | ||
627 | 642 | ||
628 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL, | ||
629 | 0, 0, buf)) < 0) { | ||
630 | dbg("Set external PHY reset pin level: %d", ret); | ||
631 | goto out2; | ||
632 | } | ||
633 | msleep(150); | 643 | msleep(150); |
634 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, | 644 | |
635 | AX_SWRESET_IPRL | AX_SWRESET_PRL, | 645 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) |
636 | 0, 0, buf)) < 0) { | ||
637 | dbg("Set Internal/External PHY reset control: %d", ret); | ||
638 | goto out2; | 646 | goto out2; |
639 | } | ||
640 | msleep(150); | ||
641 | 647 | ||
648 | msleep(150); | ||
642 | 649 | ||
643 | dev->net->set_multicast_list = ax8817x_set_multicast; | 650 | dev->net->set_multicast_list = asix_set_multicast; |
644 | dev->net->ethtool_ops = &ax88772_ethtool_ops; | 651 | dev->net->ethtool_ops = &ax88772_ethtool_ops; |
645 | 652 | ||
646 | ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); | 653 | asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); |
647 | ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, | 654 | asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, |
648 | ADVERTISE_ALL | ADVERTISE_CSMA); | 655 | ADVERTISE_ALL | ADVERTISE_CSMA); |
649 | mii_nway_restart(&dev->mii); | 656 | mii_nway_restart(&dev->mii); |
650 | 657 | ||
651 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, | 658 | if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, |
652 | AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) { | 659 | AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) { |
653 | dbg("Write medium mode register: %d", ret); | 660 | dbg("Write medium mode register: %d", ret); |
654 | goto out2; | 661 | goto out2; |
655 | } | 662 | } |
656 | 663 | ||
657 | if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, | 664 | if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, |
658 | AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, | 665 | AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, |
659 | AX88772_IPG2_DEFAULT, 0, buf)) < 0) { | 666 | AX88772_IPG2_DEFAULT, 0, buf)) < 0) { |
660 | dbg("Write IPG,IPG1,IPG2 failed: %d", ret); | 667 | dbg("Write IPG,IPG1,IPG2 failed: %d", ret); |
661 | goto out2; | 668 | goto out2; |
662 | } | 669 | } |
663 | if ((ret = | 670 | if ((ret = asix_set_hw_mii(dev)) < 0) |
664 | ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) { | ||
665 | dbg("Failed to set hardware MII: %02x", ret); | ||
666 | goto out2; | 671 | goto out2; |
667 | } | ||
668 | 672 | ||
669 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ | 673 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ |
670 | if ((ret = | 674 | if ((ret = asix_write_rx_ctl(dev, 0x0088)) < 0) |
671 | ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0, | ||
672 | buf)) < 0) { | ||
673 | dbg("Reset RX_CTL failed: %d", ret); | ||
674 | goto out2; | 675 | goto out2; |
675 | } | ||
676 | 676 | ||
677 | kfree(buf); | 677 | kfree(buf); |
678 | 678 | ||
@@ -794,23 +794,23 @@ static int ax88772_link_reset(struct usbnet *dev) | |||
794 | u16 mode; | 794 | u16 mode; |
795 | 795 | ||
796 | mode = AX88772_MEDIUM_DEFAULT; | 796 | mode = AX88772_MEDIUM_DEFAULT; |
797 | lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); | 797 | lpa = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); |
798 | adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); | 798 | adv = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); |
799 | res = mii_nway_result(lpa|adv); | 799 | res = mii_nway_result(lpa|adv); |
800 | 800 | ||
801 | if ((res & LPA_DUPLEX) == 0) | 801 | if ((res & LPA_DUPLEX) == 0) |
802 | mode &= ~AX88772_MEDIUM_FULL_DUPLEX; | 802 | mode &= ~AX88772_MEDIUM_FULL_DUPLEX; |
803 | if ((res & LPA_100) == 0) | 803 | if ((res & LPA_100) == 0) |
804 | mode &= ~AX88772_MEDIUM_100MB; | 804 | mode &= ~AX88772_MEDIUM_100MB; |
805 | ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); | 805 | asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); |
806 | 806 | ||
807 | return 0; | 807 | return 0; |
808 | } | 808 | } |
809 | 809 | ||
810 | static const struct driver_info ax8817x_info = { | 810 | static const struct driver_info ax8817x_info = { |
811 | .description = "ASIX AX8817x USB 2.0 Ethernet", | 811 | .description = "ASIX AX8817x USB 2.0 Ethernet", |
812 | .bind = ax8817x_bind, | 812 | .bind = ax88172_bind, |
813 | .status = ax8817x_status, | 813 | .status = asix_status, |
814 | .link_reset = ax88172_link_reset, | 814 | .link_reset = ax88172_link_reset, |
815 | .reset = ax88172_link_reset, | 815 | .reset = ax88172_link_reset, |
816 | .flags = FLAG_ETHER, | 816 | .flags = FLAG_ETHER, |
@@ -819,8 +819,8 @@ static const struct driver_info ax8817x_info = { | |||
819 | 819 | ||
820 | static const struct driver_info dlink_dub_e100_info = { | 820 | static const struct driver_info dlink_dub_e100_info = { |
821 | .description = "DLink DUB-E100 USB Ethernet", | 821 | .description = "DLink DUB-E100 USB Ethernet", |
822 | .bind = ax8817x_bind, | 822 | .bind = ax88172_bind, |
823 | .status = ax8817x_status, | 823 | .status = asix_status, |
824 | .link_reset = ax88172_link_reset, | 824 | .link_reset = ax88172_link_reset, |
825 | .reset = ax88172_link_reset, | 825 | .reset = ax88172_link_reset, |
826 | .flags = FLAG_ETHER, | 826 | .flags = FLAG_ETHER, |
@@ -829,8 +829,8 @@ static const struct driver_info dlink_dub_e100_info = { | |||
829 | 829 | ||
830 | static const struct driver_info netgear_fa120_info = { | 830 | static const struct driver_info netgear_fa120_info = { |
831 | .description = "Netgear FA-120 USB Ethernet", | 831 | .description = "Netgear FA-120 USB Ethernet", |
832 | .bind = ax8817x_bind, | 832 | .bind = ax88172_bind, |
833 | .status = ax8817x_status, | 833 | .status = asix_status, |
834 | .link_reset = ax88172_link_reset, | 834 | .link_reset = ax88172_link_reset, |
835 | .reset = ax88172_link_reset, | 835 | .reset = ax88172_link_reset, |
836 | .flags = FLAG_ETHER, | 836 | .flags = FLAG_ETHER, |
@@ -839,8 +839,8 @@ static const struct driver_info netgear_fa120_info = { | |||
839 | 839 | ||
840 | static const struct driver_info hawking_uf200_info = { | 840 | static const struct driver_info hawking_uf200_info = { |
841 | .description = "Hawking UF200 USB Ethernet", | 841 | .description = "Hawking UF200 USB Ethernet", |
842 | .bind = ax8817x_bind, | 842 | .bind = ax88172_bind, |
843 | .status = ax8817x_status, | 843 | .status = asix_status, |
844 | .link_reset = ax88172_link_reset, | 844 | .link_reset = ax88172_link_reset, |
845 | .reset = ax88172_link_reset, | 845 | .reset = ax88172_link_reset, |
846 | .flags = FLAG_ETHER, | 846 | .flags = FLAG_ETHER, |
@@ -850,13 +850,12 @@ static const struct driver_info hawking_uf200_info = { | |||
850 | static const struct driver_info ax88772_info = { | 850 | static const struct driver_info ax88772_info = { |
851 | .description = "ASIX AX88772 USB 2.0 Ethernet", | 851 | .description = "ASIX AX88772 USB 2.0 Ethernet", |
852 | .bind = ax88772_bind, | 852 | .bind = ax88772_bind, |
853 | .status = ax8817x_status, | 853 | .status = asix_status, |
854 | .link_reset = ax88772_link_reset, | 854 | .link_reset = ax88772_link_reset, |
855 | .reset = ax88772_link_reset, | 855 | .reset = ax88772_link_reset, |
856 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 856 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, |
857 | .rx_fixup = ax88772_rx_fixup, | 857 | .rx_fixup = ax88772_rx_fixup, |
858 | .tx_fixup = ax88772_tx_fixup, | 858 | .tx_fixup = ax88772_tx_fixup, |
859 | .data = 0x00130103, | ||
860 | }; | 859 | }; |
861 | 860 | ||
862 | static const struct usb_device_id products [] = { | 861 | static const struct usb_device_id products [] = { |
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 5b6675684567..2deb4c01539e 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
@@ -262,7 +262,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) | |||
262 | usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, | 262 | usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, |
263 | usb_sndctrlpipe(pegasus->usb, 0), | 263 | usb_sndctrlpipe(pegasus->usb, 0), |
264 | (char *) &pegasus->dr, | 264 | (char *) &pegasus->dr, |
265 | &tmp, 1, ctrl_callback, pegasus); | 265 | tmp, 1, ctrl_callback, pegasus); |
266 | 266 | ||
267 | add_wait_queue(&pegasus->ctrl_wait, &wait); | 267 | add_wait_queue(&pegasus->ctrl_wait, &wait); |
268 | set_current_state(TASK_UNINTERRUPTIBLE); | 268 | set_current_state(TASK_UNINTERRUPTIBLE); |
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index 49991ac1bf3b..94ddfe16fdda 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c | |||
@@ -39,6 +39,20 @@ | |||
39 | * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of | 39 | * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of |
40 | * course ACM was intended for modems, not Ethernet links! USB's standard | 40 | * course ACM was intended for modems, not Ethernet links! USB's standard |
41 | * for Ethernet links is "CDC Ethernet", which is significantly simpler. | 41 | * for Ethernet links is "CDC Ethernet", which is significantly simpler. |
42 | * | ||
43 | * NOTE that Microsoft's "RNDIS 1.0" specification is incomplete. Issues | ||
44 | * include: | ||
45 | * - Power management in particular relies on information that's scattered | ||
46 | * through other documentation, and which is incomplete or incorrect even | ||
47 | * there. | ||
48 | * - There are various undocumented protocol requirements, such as the | ||
49 | * need to send unused garbage in control-OUT messages. | ||
50 | * - In some cases, MS-Windows will emit undocumented requests; this | ||
51 | * matters more to peripheral implementations than host ones. | ||
52 | * | ||
53 | * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in | ||
54 | * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and | ||
55 | * currently rare) "Ethernet Emulation Model" (EEM). | ||
42 | */ | 56 | */ |
43 | 57 | ||
44 | /* | 58 | /* |
@@ -72,17 +86,17 @@ struct rndis_msg_hdr { | |||
72 | */ | 86 | */ |
73 | #define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */ | 87 | #define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */ |
74 | #define RNDIS_MSG_INIT ccpu2(0x00000002) | 88 | #define RNDIS_MSG_INIT ccpu2(0x00000002) |
75 | #define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) | 89 | #define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) |
76 | #define RNDIS_MSG_HALT ccpu2(0x00000003) | 90 | #define RNDIS_MSG_HALT ccpu2(0x00000003) |
77 | #define RNDIS_MSG_QUERY ccpu2(0x00000004) | 91 | #define RNDIS_MSG_QUERY ccpu2(0x00000004) |
78 | #define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) | 92 | #define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) |
79 | #define RNDIS_MSG_SET ccpu2(0x00000005) | 93 | #define RNDIS_MSG_SET ccpu2(0x00000005) |
80 | #define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) | 94 | #define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) |
81 | #define RNDIS_MSG_RESET ccpu2(0x00000006) | 95 | #define RNDIS_MSG_RESET ccpu2(0x00000006) |
82 | #define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) | 96 | #define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) |
83 | #define RNDIS_MSG_INDICATE ccpu2(0x00000007) | 97 | #define RNDIS_MSG_INDICATE ccpu2(0x00000007) |
84 | #define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008) | 98 | #define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008) |
85 | #define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) | 99 | #define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) |
86 | 100 | ||
87 | /* codes for "status" field of completion messages */ | 101 | /* codes for "status" field of completion messages */ |
88 | #define RNDIS_STATUS_SUCCESS ccpu2(0x00000000) | 102 | #define RNDIS_STATUS_SUCCESS ccpu2(0x00000000) |
@@ -596,13 +610,13 @@ static struct usb_driver rndis_driver = { | |||
596 | 610 | ||
597 | static int __init rndis_init(void) | 611 | static int __init rndis_init(void) |
598 | { | 612 | { |
599 | return usb_register(&rndis_driver); | 613 | return usb_register(&rndis_driver); |
600 | } | 614 | } |
601 | module_init(rndis_init); | 615 | module_init(rndis_init); |
602 | 616 | ||
603 | static void __exit rndis_exit(void) | 617 | static void __exit rndis_exit(void) |
604 | { | 618 | { |
605 | usb_deregister(&rndis_driver); | 619 | usb_deregister(&rndis_driver); |
606 | } | 620 | } |
607 | module_exit(rndis_exit); | 621 | module_exit(rndis_exit); |
608 | 622 | ||
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 5a8a2c91c2b2..f96b73f54bf1 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -158,6 +158,15 @@ config USB_SERIAL_FTDI_SIO | |||
158 | To compile this driver as a module, choose M here: the | 158 | To compile this driver as a module, choose M here: the |
159 | module will be called ftdi_sio. | 159 | module will be called ftdi_sio. |
160 | 160 | ||
161 | config USB_SERIAL_FUNSOFT | ||
162 | tristate "USB Fundamental Software Dongle Driver" | ||
163 | depends on USB_SERIAL | ||
164 | ---help--- | ||
165 | Say Y here if you want to use the Fundamental Software dongle. | ||
166 | |||
167 | To compile this driver as a module, choose M here: the | ||
168 | module will be called funsoft. | ||
169 | |||
161 | config USB_SERIAL_VISOR | 170 | config USB_SERIAL_VISOR |
162 | tristate "USB Handspring Visor / Palm m50x / Sony Clie Driver" | 171 | tristate "USB Handspring Visor / Palm m50x / Sony Clie Driver" |
163 | depends on USB_SERIAL | 172 | depends on USB_SERIAL |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index f7fe4172efed..93c21245b1af 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_SERIAL_EDGEPORT) += io_edgeport.o | |||
22 | obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o | 22 | obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o |
23 | obj-$(CONFIG_USB_SERIAL_EMPEG) += empeg.o | 23 | obj-$(CONFIG_USB_SERIAL_EMPEG) += empeg.o |
24 | obj-$(CONFIG_USB_SERIAL_FTDI_SIO) += ftdi_sio.o | 24 | obj-$(CONFIG_USB_SERIAL_FTDI_SIO) += ftdi_sio.o |
25 | obj-$(CONFIG_USB_SERIAL_FUNSOFT) += funsoft.o | ||
25 | obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o | 26 | obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o |
26 | obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o | 27 | obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o |
27 | obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o | 28 | obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 167f8ec56131..8023bb7279b1 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -54,7 +54,7 @@ static struct console usbcons; | |||
54 | * serial.c code, except that the specifier is "ttyUSB" instead | 54 | * serial.c code, except that the specifier is "ttyUSB" instead |
55 | * of "ttyS". | 55 | * of "ttyS". |
56 | */ | 56 | */ |
57 | static int __init usb_console_setup(struct console *co, char *options) | 57 | static int usb_console_setup(struct console *co, char *options) |
58 | { | 58 | { |
59 | struct usbcons_info *info = &usbcons_info; | 59 | struct usbcons_info *info = &usbcons_info; |
60 | int baud = 9600; | 60 | int baud = 9600; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f3af81b4dd29..f5851db67f5b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -489,10 +489,12 @@ static struct usb_device_id id_table_combined [] = { | |||
489 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, | 489 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, |
490 | { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, | 490 | { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, |
491 | { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) }, | 491 | { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) }, |
492 | { USB_DEVICE(FTDI_VID, FTDI_ECLO_COM_1WIRE_PID) }, | ||
492 | { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) }, | 493 | { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) }, |
493 | { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, | 494 | { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, |
494 | { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, | 495 | { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, |
495 | { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, | 496 | { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, |
497 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, | ||
496 | { }, /* Optional parameter entry */ | 498 | { }, /* Optional parameter entry */ |
497 | { } /* Terminating entry */ | 499 | { } /* Terminating entry */ |
498 | }; | 500 | }; |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 8da773c2744d..2155f0e4a378 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -399,6 +399,21 @@ | |||
399 | #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ | 399 | #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ |
400 | #define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ | 400 | #define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ |
401 | 401 | ||
402 | /* | ||
403 | * Eclo (http://www.eclo.pt/) product IDs. | ||
404 | * PID 0xEA90 submitted by Martin Grill. | ||
405 | */ | ||
406 | #define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ | ||
407 | |||
408 | /* | ||
409 | * Papouch products (http://www.papouch.com/) | ||
410 | * Submitted by Folkert van Heusden | ||
411 | */ | ||
412 | |||
413 | #define PAPOUCH_VID 0x5050 /* Vendor ID */ | ||
414 | #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ | ||
415 | |||
416 | |||
402 | /* Commands */ | 417 | /* Commands */ |
403 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 418 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
404 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 419 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c new file mode 100644 index 000000000000..803721b97e2e --- /dev/null +++ b/drivers/usb/serial/funsoft.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Funsoft Serial USB driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Greg Kroah-Hartman <gregkh@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/tty.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/usb.h> | ||
16 | #include "usb-serial.h" | ||
17 | |||
18 | static struct usb_device_id id_table [] = { | ||
19 | { USB_DEVICE(0x1404, 0xcddc) }, | ||
20 | { }, | ||
21 | }; | ||
22 | MODULE_DEVICE_TABLE(usb, id_table); | ||
23 | |||
24 | static struct usb_driver funsoft_driver = { | ||
25 | .name = "funsoft", | ||
26 | .probe = usb_serial_probe, | ||
27 | .disconnect = usb_serial_disconnect, | ||
28 | .id_table = id_table, | ||
29 | .no_dynamic_id = 1, | ||
30 | }; | ||
31 | |||
32 | static struct usb_serial_driver funsoft_device = { | ||
33 | .driver = { | ||
34 | .owner = THIS_MODULE, | ||
35 | .name = "funsoft", | ||
36 | }, | ||
37 | .id_table = id_table, | ||
38 | .num_interrupt_in = NUM_DONT_CARE, | ||
39 | .num_bulk_in = NUM_DONT_CARE, | ||
40 | .num_bulk_out = NUM_DONT_CARE, | ||
41 | .num_ports = 1, | ||
42 | }; | ||
43 | |||
44 | static int __init funsoft_init(void) | ||
45 | { | ||
46 | int retval; | ||
47 | |||
48 | retval = usb_serial_register(&funsoft_device); | ||
49 | if (retval) | ||
50 | return retval; | ||
51 | retval = usb_register(&funsoft_driver); | ||
52 | if (retval) | ||
53 | usb_serial_deregister(&funsoft_device); | ||
54 | return retval; | ||
55 | } | ||
56 | |||
57 | static void __exit funsoft_exit(void) | ||
58 | { | ||
59 | usb_deregister(&funsoft_driver); | ||
60 | usb_serial_deregister(&funsoft_device); | ||
61 | } | ||
62 | |||
63 | module_init(funsoft_init); | ||
64 | module_exit(funsoft_exit); | ||
65 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index b3014fda645c..ccf746b27d4e 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -78,6 +78,7 @@ static struct usb_device_id id_table [] = { | |||
78 | { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, | 78 | { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, |
79 | { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) }, | 79 | { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) }, |
80 | { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, | 80 | { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, |
81 | { USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) }, | ||
81 | { } /* Terminating entry */ | 82 | { } /* Terminating entry */ |
82 | }; | 83 | }; |
83 | 84 | ||
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 77901d143979..09f379b19e98 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -79,3 +79,7 @@ | |||
79 | /* USB GSM cable from Speed Dragon Multimedia, Ltd */ | 79 | /* USB GSM cable from Speed Dragon Multimedia, Ltd */ |
80 | #define SPEEDDRAGON_VENDOR_ID 0x0e55 | 80 | #define SPEEDDRAGON_VENDOR_ID 0x0e55 |
81 | #define SPEEDDRAGON_PRODUCT_ID 0x110b | 81 | #define SPEEDDRAGON_PRODUCT_ID 0x110b |
82 | |||
83 | /* Ours Technology Inc DKU-5 clone, chipset: Prolific Technology Inc */ | ||
84 | #define OTI_VENDOR_ID 0x0ea0 | ||
85 | #define OTI_PRODUCT_ID 0x6858 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 097f4e8488fe..071f86a59c08 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -27,10 +27,10 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
30 | #include <linux/mutex.h> | ||
30 | #include <linux/list.h> | 31 | #include <linux/list.h> |
31 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
33 | #include <asm/semaphore.h> | ||
34 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
35 | #include "usb-serial.h" | 35 | #include "usb-serial.h" |
36 | #include "pl2303.h" | 36 | #include "pl2303.h" |
@@ -192,7 +192,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
192 | if (!port) | 192 | if (!port) |
193 | return -ENODEV; | 193 | return -ENODEV; |
194 | 194 | ||
195 | if (down_interruptible(&port->sem)) | 195 | if (mutex_lock_interruptible(&port->mutex)) |
196 | return -ERESTARTSYS; | 196 | return -ERESTARTSYS; |
197 | 197 | ||
198 | ++port->open_count; | 198 | ++port->open_count; |
@@ -219,7 +219,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
219 | goto bailout_module_put; | 219 | goto bailout_module_put; |
220 | } | 220 | } |
221 | 221 | ||
222 | up(&port->sem); | 222 | mutex_unlock(&port->mutex); |
223 | return 0; | 223 | return 0; |
224 | 224 | ||
225 | bailout_module_put: | 225 | bailout_module_put: |
@@ -227,7 +227,7 @@ bailout_module_put: | |||
227 | bailout_kref_put: | 227 | bailout_kref_put: |
228 | kref_put(&serial->kref, destroy_serial); | 228 | kref_put(&serial->kref, destroy_serial); |
229 | port->open_count = 0; | 229 | port->open_count = 0; |
230 | up(&port->sem); | 230 | mutex_unlock(&port->mutex); |
231 | return retval; | 231 | return retval; |
232 | } | 232 | } |
233 | 233 | ||
@@ -240,10 +240,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
240 | 240 | ||
241 | dbg("%s - port %d", __FUNCTION__, port->number); | 241 | dbg("%s - port %d", __FUNCTION__, port->number); |
242 | 242 | ||
243 | down(&port->sem); | 243 | mutex_lock(&port->mutex); |
244 | 244 | ||
245 | if (port->open_count == 0) { | 245 | if (port->open_count == 0) { |
246 | up(&port->sem); | 246 | mutex_unlock(&port->mutex); |
247 | return; | 247 | return; |
248 | } | 248 | } |
249 | 249 | ||
@@ -262,7 +262,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
262 | module_put(port->serial->type->driver.owner); | 262 | module_put(port->serial->type->driver.owner); |
263 | } | 263 | } |
264 | 264 | ||
265 | up(&port->sem); | 265 | mutex_unlock(&port->mutex); |
266 | kref_put(&port->serial->kref, destroy_serial); | 266 | kref_put(&port->serial->kref, destroy_serial); |
267 | } | 267 | } |
268 | 268 | ||
@@ -783,7 +783,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
783 | port->number = i + serial->minor; | 783 | port->number = i + serial->minor; |
784 | port->serial = serial; | 784 | port->serial = serial; |
785 | spin_lock_init(&port->lock); | 785 | spin_lock_init(&port->lock); |
786 | sema_init(&port->sem, 1); | 786 | mutex_init(&port->mutex); |
787 | INIT_WORK(&port->work, usb_serial_port_softint, port); | 787 | INIT_WORK(&port->work, usb_serial_port_softint, port); |
788 | serial->port[i] = port; | 788 | serial->port[i] = port; |
789 | } | 789 | } |
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index d7d27c3385b3..dc89d8710460 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/config.h> | 17 | #include <linux/config.h> |
18 | #include <linux/kref.h> | 18 | #include <linux/kref.h> |
19 | #include <asm/semaphore.h> | 19 | #include <linux/mutex.h> |
20 | 20 | ||
21 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ | 21 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ |
22 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ | 22 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ |
@@ -31,7 +31,7 @@ | |||
31 | * @serial: pointer back to the struct usb_serial owner of this port. | 31 | * @serial: pointer back to the struct usb_serial owner of this port. |
32 | * @tty: pointer to the corresponding tty for this port. | 32 | * @tty: pointer to the corresponding tty for this port. |
33 | * @lock: spinlock to grab when updating portions of this structure. | 33 | * @lock: spinlock to grab when updating portions of this structure. |
34 | * @sem: semaphore used to synchronize serial_open() and serial_close() | 34 | * @mutex: mutex used to synchronize serial_open() and serial_close() |
35 | * access for this port. | 35 | * access for this port. |
36 | * @number: the number of the port (the minor number). | 36 | * @number: the number of the port (the minor number). |
37 | * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. | 37 | * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. |
@@ -63,7 +63,7 @@ struct usb_serial_port { | |||
63 | struct usb_serial * serial; | 63 | struct usb_serial * serial; |
64 | struct tty_struct * tty; | 64 | struct tty_struct * tty; |
65 | spinlock_t lock; | 65 | spinlock_t lock; |
66 | struct semaphore sem; | 66 | struct mutex mutex; |
67 | unsigned char number; | 67 | unsigned char number; |
68 | 68 | ||
69 | unsigned char * interrupt_in_buffer; | 69 | unsigned char * interrupt_in_buffer; |