diff options
112 files changed, 2702 insertions, 1111 deletions
diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 1af0f2d50220..2ffb0d62f0fe 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt | |||
@@ -33,7 +33,9 @@ pci_alloc_consistent(struct pci_dev *dev, size_t size, | |||
33 | 33 | ||
34 | Consistent memory is memory for which a write by either the device or | 34 | Consistent memory is memory for which a write by either the device or |
35 | the processor can immediately be read by the processor or device | 35 | the processor can immediately be read by the processor or device |
36 | without having to worry about caching effects. | 36 | without having to worry about caching effects. (You may however need |
37 | to make sure to flush the processor's write buffers before telling | ||
38 | devices to read that memory.) | ||
37 | 39 | ||
38 | This routine allocates a region of <size> bytes of consistent memory. | 40 | This routine allocates a region of <size> bytes of consistent memory. |
39 | it also returns a <dma_handle> which may be cast to an unsigned | 41 | it also returns a <dma_handle> which may be cast to an unsigned |
@@ -304,12 +306,12 @@ dma address with dma_mapping_error(). A non zero return value means the mapping | |||
304 | could not be created and the driver should take appropriate action (eg | 306 | could not be created and the driver should take appropriate action (eg |
305 | reduce current DMA mapping usage or delay and try again later). | 307 | reduce current DMA mapping usage or delay and try again later). |
306 | 308 | ||
307 | int | 309 | int |
308 | dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | 310 | dma_map_sg(struct device *dev, struct scatterlist *sg, |
309 | enum dma_data_direction direction) | 311 | int nents, enum dma_data_direction direction) |
310 | int | 312 | int |
311 | pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, | 313 | pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, |
312 | int nents, int direction) | 314 | int nents, int direction) |
313 | 315 | ||
314 | Maps a scatter gather list from the block layer. | 316 | Maps a scatter gather list from the block layer. |
315 | 317 | ||
@@ -327,12 +329,33 @@ critical that the driver do something, in the case of a block driver | |||
327 | aborting the request or even oopsing is better than doing nothing and | 329 | aborting the request or even oopsing is better than doing nothing and |
328 | corrupting the filesystem. | 330 | corrupting the filesystem. |
329 | 331 | ||
330 | void | 332 | With scatterlists, you use the resulting mapping like this: |
331 | dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | 333 | |
332 | enum dma_data_direction direction) | 334 | int i, count = dma_map_sg(dev, sglist, nents, direction); |
333 | void | 335 | struct scatterlist *sg; |
334 | pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, | 336 | |
335 | int nents, int direction) | 337 | for (i = 0, sg = sglist; i < count; i++, sg++) { |
338 | hw_address[i] = sg_dma_address(sg); | ||
339 | hw_len[i] = sg_dma_len(sg); | ||
340 | } | ||
341 | |||
342 | where nents is the number of entries in the sglist. | ||
343 | |||
344 | The implementation is free to merge several consecutive sglist entries | ||
345 | into one (e.g. with an IOMMU, or if several pages just happen to be | ||
346 | physically contiguous) and returns the actual number of sg entries it | ||
347 | mapped them to. On failure 0, is returned. | ||
348 | |||
349 | Then you should loop count times (note: this can be less than nents times) | ||
350 | and use sg_dma_address() and sg_dma_len() macros where you previously | ||
351 | accessed sg->address and sg->length as shown above. | ||
352 | |||
353 | void | ||
354 | dma_unmap_sg(struct device *dev, struct scatterlist *sg, | ||
355 | int nhwentries, enum dma_data_direction direction) | ||
356 | void | ||
357 | pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, | ||
358 | int nents, int direction) | ||
336 | 359 | ||
337 | unmap the previously mapped scatter/gather list. All the parameters | 360 | unmap the previously mapped scatter/gather list. All the parameters |
338 | must be the same as those and passed in to the scatter/gather mapping | 361 | must be the same as those and passed in to the scatter/gather mapping |
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt index 10bf4deb96aa..7c717699032c 100644 --- a/Documentation/DMA-mapping.txt +++ b/Documentation/DMA-mapping.txt | |||
@@ -58,11 +58,15 @@ translating each of those pages back to a kernel address using | |||
58 | something like __va(). [ EDIT: Update this when we integrate | 58 | something like __va(). [ EDIT: Update this when we integrate |
59 | Gerd Knorr's generic code which does this. ] | 59 | Gerd Knorr's generic code which does this. ] |
60 | 60 | ||
61 | This rule also means that you may not use kernel image addresses | 61 | This rule also means that you may use neither kernel image addresses |
62 | (ie. items in the kernel's data/text/bss segment, or your driver's) | 62 | (items in data/text/bss segments), nor module image addresses, nor |
63 | nor may you use kernel stack addresses for DMA. Both of these items | 63 | stack addresses for DMA. These could all be mapped somewhere entirely |
64 | might be mapped somewhere entirely different than the rest of physical | 64 | different than the rest of physical memory. Even if those classes of |
65 | memory. | 65 | memory could physically work with DMA, you'd need to ensure the I/O |
66 | buffers were cacheline-aligned. Without that, you'd see cacheline | ||
67 | sharing problems (data corruption) on CPUs with DMA-incoherent caches. | ||
68 | (The CPU could write to one word, DMA would write to a different one | ||
69 | in the same cache line, and one of them could be overwritten.) | ||
66 | 70 | ||
67 | Also, this means that you cannot take the return of a kmap() | 71 | Also, this means that you cannot take the return of a kmap() |
68 | call and DMA to/from that. This is similar to vmalloc(). | 72 | call and DMA to/from that. This is similar to vmalloc(). |
@@ -284,6 +288,11 @@ There are two types of DMA mappings: | |||
284 | 288 | ||
285 | in order to get correct behavior on all platforms. | 289 | in order to get correct behavior on all platforms. |
286 | 290 | ||
291 | Also, on some platforms your driver may need to flush CPU write | ||
292 | buffers in much the same way as it needs to flush write buffers | ||
293 | found in PCI bridges (such as by reading a register's value | ||
294 | after writing it). | ||
295 | |||
287 | - Streaming DMA mappings which are usually mapped for one DMA transfer, | 296 | - Streaming DMA mappings which are usually mapped for one DMA transfer, |
288 | unmapped right after it (unless you use pci_dma_sync_* below) and for which | 297 | unmapped right after it (unless you use pci_dma_sync_* below) and for which |
289 | hardware can optimize for sequential accesses. | 298 | hardware can optimize for sequential accesses. |
@@ -303,6 +312,9 @@ There are two types of DMA mappings: | |||
303 | 312 | ||
304 | Neither type of DMA mapping has alignment restrictions that come | 313 | Neither type of DMA mapping has alignment restrictions that come |
305 | from PCI, although some devices may have such restrictions. | 314 | from PCI, although some devices may have such restrictions. |
315 | Also, systems with caches that aren't DMA-coherent will work better | ||
316 | when the underlying buffers don't share cache lines with other data. | ||
317 | |||
306 | 318 | ||
307 | Using Consistent DMA mappings. | 319 | Using Consistent DMA mappings. |
308 | 320 | ||
diff --git a/Documentation/i2c/busses/i2c-parport b/Documentation/i2c/busses/i2c-parport index d9f23c0763f1..77b995dfca22 100644 --- a/Documentation/i2c/busses/i2c-parport +++ b/Documentation/i2c/busses/i2c-parport | |||
@@ -12,18 +12,22 @@ meant as a replacement for the older, individual drivers: | |||
12 | teletext adapters) | 12 | teletext adapters) |
13 | 13 | ||
14 | It currently supports the following devices: | 14 | It currently supports the following devices: |
15 | * Philips adapter | 15 | * (type=0) Philips adapter |
16 | * home brew teletext adapter | 16 | * (type=1) home brew teletext adapter |
17 | * Velleman K8000 adapter | 17 | * (type=2) Velleman K8000 adapter |
18 | * ELV adapter | 18 | * (type=3) ELV adapter |
19 | * Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032) | 19 | * (type=4) Analog Devices ADM1032 evaluation board |
20 | * Barco LPT->DVI (K5800236) adapter | 20 | * (type=5) Analog Devices evaluation boards: ADM1025, ADM1030, ADM1031 |
21 | * (type=6) Barco LPT->DVI (K5800236) adapter | ||
21 | 22 | ||
22 | These devices use different pinout configurations, so you have to tell | 23 | These devices use different pinout configurations, so you have to tell |
23 | the driver what you have, using the type module parameter. There is no | 24 | the driver what you have, using the type module parameter. There is no |
24 | way to autodetect the devices. Support for different pinout configurations | 25 | way to autodetect the devices. Support for different pinout configurations |
25 | can be easily added when needed. | 26 | can be easily added when needed. |
26 | 27 | ||
28 | Earlier kernels defaulted to type=0 (Philips). But now, if the type | ||
29 | parameter is missing, the driver will simply fail to initialize. | ||
30 | |||
27 | 31 | ||
28 | Building your own adapter | 32 | Building your own adapter |
29 | ------------------------- | 33 | ------------------------- |
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 5b9ed21216cf..96fb8a020af2 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
@@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds | |||
6 | 6 | ||
7 | obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ | 7 | obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ |
8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ | 8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ |
9 | pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ | 9 | pci-dma.o i386_ksyms.o i387.o bootflag.o \ |
10 | quirks.o i8237.o topology.o alternative.o | 10 | quirks.o i8237.o topology.o alternative.o |
11 | 11 | ||
12 | obj-y += cpu/ | 12 | obj-y += cpu/ |
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index 4f58b9c0efe3..f48bef15b4f0 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S | |||
@@ -314,3 +314,4 @@ ENTRY(sys_call_table) | |||
314 | .long sys_get_robust_list | 314 | .long sys_get_robust_list |
315 | .long sys_splice | 315 | .long sys_splice |
316 | .long sys_sync_file_range | 316 | .long sys_sync_file_range |
317 | .long sys_tee /* 315 */ | ||
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 3ca59cad05f3..73235443fda7 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -588,7 +588,10 @@ static __init int via_router_probe(struct irq_router *r, | |||
588 | case PCI_DEVICE_ID_VIA_82C596: | 588 | case PCI_DEVICE_ID_VIA_82C596: |
589 | case PCI_DEVICE_ID_VIA_82C686: | 589 | case PCI_DEVICE_ID_VIA_82C686: |
590 | case PCI_DEVICE_ID_VIA_8231: | 590 | case PCI_DEVICE_ID_VIA_8231: |
591 | case PCI_DEVICE_ID_VIA_8233A: | ||
591 | case PCI_DEVICE_ID_VIA_8235: | 592 | case PCI_DEVICE_ID_VIA_8235: |
593 | case PCI_DEVICE_ID_VIA_8237: | ||
594 | case PCI_DEVICE_ID_VIA_8237_SATA: | ||
592 | /* FIXME: add new ones for 8233/5 */ | 595 | /* FIXME: add new ones for 8233/5 */ |
593 | r->name = "VIA"; | 596 | r->name = "VIA"; |
594 | r->get = pirq_via_get; | 597 | r->get = pirq_via_get; |
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 59e871dae742..09a0dbc17fb6 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile | |||
@@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.lds | |||
7 | obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ | 7 | obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ |
8 | irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ | 8 | irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ |
9 | salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ | 9 | salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ |
10 | unwind.o mca.o mca_asm.o topology.o dmi_scan.o | 10 | unwind.o mca.o mca_asm.o topology.o |
11 | 11 | ||
12 | obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o | 12 | obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o |
13 | obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o | 13 | obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o |
@@ -30,7 +30,6 @@ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o | |||
30 | obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o | 30 | obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o |
31 | obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o | 31 | obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o |
32 | mca_recovery-y += mca_drv.o mca_drv_asm.o | 32 | mca_recovery-y += mca_drv.o mca_drv_asm.o |
33 | dmi_scan-y += ../../i386/kernel/dmi_scan.o | ||
34 | 33 | ||
35 | # The gate DSO image is built using a special linker script. | 34 | # The gate DSO image is built using a special linker script. |
36 | targets += gate.so gate-syms.o | 35 | targets += gate.so gate-syms.o |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 6e16f6b35bd3..e30798811216 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1609,5 +1609,6 @@ sys_call_table: | |||
1609 | data8 sys_set_robust_list | 1609 | data8 sys_set_robust_list |
1610 | data8 sys_get_robust_list | 1610 | data8 sys_get_robust_list |
1611 | data8 sys_sync_file_range // 1300 | 1611 | data8 sys_sync_file_range // 1300 |
1612 | data8 sys_tee | ||
1612 | 1613 | ||
1613 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 1614 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 5e6fdbe78bcd..6a0880639bc9 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -963,7 +963,7 @@ no_mod: | |||
963 | */ | 963 | */ |
964 | 964 | ||
965 | static void | 965 | static void |
966 | ia64_wait_for_slaves(int monarch) | 966 | ia64_wait_for_slaves(int monarch, const char *type) |
967 | { | 967 | { |
968 | int c, wait = 0, missing = 0; | 968 | int c, wait = 0, missing = 0; |
969 | for_each_online_cpu(c) { | 969 | for_each_online_cpu(c) { |
@@ -989,7 +989,7 @@ ia64_wait_for_slaves(int monarch) | |||
989 | } | 989 | } |
990 | if (!missing) | 990 | if (!missing) |
991 | goto all_in; | 991 | goto all_in; |
992 | printk(KERN_INFO "OS MCA slave did not rendezvous on cpu"); | 992 | printk(KERN_INFO "OS %s slave did not rendezvous on cpu", type); |
993 | for_each_online_cpu(c) { | 993 | for_each_online_cpu(c) { |
994 | if (c == monarch) | 994 | if (c == monarch) |
995 | continue; | 995 | continue; |
@@ -1000,7 +1000,7 @@ ia64_wait_for_slaves(int monarch) | |||
1000 | return; | 1000 | return; |
1001 | 1001 | ||
1002 | all_in: | 1002 | all_in: |
1003 | printk(KERN_INFO "All OS MCA slaves have reached rendezvous\n"); | 1003 | printk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type); |
1004 | return; | 1004 | return; |
1005 | } | 1005 | } |
1006 | 1006 | ||
@@ -1038,7 +1038,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1038 | if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0) | 1038 | if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0) |
1039 | == NOTIFY_STOP) | 1039 | == NOTIFY_STOP) |
1040 | ia64_mca_spin(__FUNCTION__); | 1040 | ia64_mca_spin(__FUNCTION__); |
1041 | ia64_wait_for_slaves(cpu); | 1041 | ia64_wait_for_slaves(cpu, "MCA"); |
1042 | 1042 | ||
1043 | /* Wakeup all the processors which are spinning in the rendezvous loop. | 1043 | /* Wakeup all the processors which are spinning in the rendezvous loop. |
1044 | * They will leave SAL, then spin in the OS with interrupts disabled | 1044 | * They will leave SAL, then spin in the OS with interrupts disabled |
@@ -1429,7 +1429,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1429 | */ | 1429 | */ |
1430 | printk("Delaying for 5 seconds...\n"); | 1430 | printk("Delaying for 5 seconds...\n"); |
1431 | udelay(5*1000000); | 1431 | udelay(5*1000000); |
1432 | ia64_wait_for_slaves(cpu); | 1432 | ia64_wait_for_slaves(cpu, "INIT"); |
1433 | /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through | 1433 | /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through |
1434 | * to default_monarch_init_process() above and just print all the | 1434 | * to default_monarch_init_process() above and just print all the |
1435 | * tasks. | 1435 | * tasks. |
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index ec9eeb89975d..b6bcc9fa3603 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c | |||
@@ -519,6 +519,68 @@ void __cpuinit *per_cpu_init(void) | |||
519 | } | 519 | } |
520 | #endif /* CONFIG_SMP */ | 520 | #endif /* CONFIG_SMP */ |
521 | 521 | ||
522 | #ifdef CONFIG_VIRTUAL_MEM_MAP | ||
523 | static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i) | ||
524 | { | ||
525 | unsigned long end_address, hole_next_pfn; | ||
526 | unsigned long stop_address; | ||
527 | |||
528 | end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i]; | ||
529 | end_address = PAGE_ALIGN(end_address); | ||
530 | |||
531 | stop_address = (unsigned long) &vmem_map[ | ||
532 | pgdat->node_start_pfn + pgdat->node_spanned_pages]; | ||
533 | |||
534 | do { | ||
535 | pgd_t *pgd; | ||
536 | pud_t *pud; | ||
537 | pmd_t *pmd; | ||
538 | pte_t *pte; | ||
539 | |||
540 | pgd = pgd_offset_k(end_address); | ||
541 | if (pgd_none(*pgd)) { | ||
542 | end_address += PGDIR_SIZE; | ||
543 | continue; | ||
544 | } | ||
545 | |||
546 | pud = pud_offset(pgd, end_address); | ||
547 | if (pud_none(*pud)) { | ||
548 | end_address += PUD_SIZE; | ||
549 | continue; | ||
550 | } | ||
551 | |||
552 | pmd = pmd_offset(pud, end_address); | ||
553 | if (pmd_none(*pmd)) { | ||
554 | end_address += PMD_SIZE; | ||
555 | continue; | ||
556 | } | ||
557 | |||
558 | pte = pte_offset_kernel(pmd, end_address); | ||
559 | retry_pte: | ||
560 | if (pte_none(*pte)) { | ||
561 | end_address += PAGE_SIZE; | ||
562 | pte++; | ||
563 | if ((end_address < stop_address) && | ||
564 | (end_address != ALIGN(end_address, 1UL << PMD_SHIFT))) | ||
565 | goto retry_pte; | ||
566 | continue; | ||
567 | } | ||
568 | /* Found next valid vmem_map page */ | ||
569 | break; | ||
570 | } while (end_address < stop_address); | ||
571 | |||
572 | end_address = min(end_address, stop_address); | ||
573 | end_address = end_address - (unsigned long) vmem_map + sizeof(struct page) - 1; | ||
574 | hole_next_pfn = end_address / sizeof(struct page); | ||
575 | return hole_next_pfn - pgdat->node_start_pfn; | ||
576 | } | ||
577 | #else | ||
578 | static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i) | ||
579 | { | ||
580 | return i + 1; | ||
581 | } | ||
582 | #endif | ||
583 | |||
522 | /** | 584 | /** |
523 | * show_mem - give short summary of memory stats | 585 | * show_mem - give short summary of memory stats |
524 | * | 586 | * |
@@ -547,8 +609,10 @@ void show_mem(void) | |||
547 | struct page *page; | 609 | struct page *page; |
548 | if (pfn_valid(pgdat->node_start_pfn + i)) | 610 | if (pfn_valid(pgdat->node_start_pfn + i)) |
549 | page = pfn_to_page(pgdat->node_start_pfn + i); | 611 | page = pfn_to_page(pgdat->node_start_pfn + i); |
550 | else | 612 | else { |
613 | i = find_next_valid_pfn_for_pgdat(pgdat, i) - 1; | ||
551 | continue; | 614 | continue; |
615 | } | ||
552 | if (PageReserved(page)) | 616 | if (PageReserved(page)) |
553 | reserved++; | 617 | reserved++; |
554 | else if (PageSwapCache(page)) | 618 | else if (PageSwapCache(page)) |
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 1424eab450ee..a14c96403840 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S | |||
@@ -323,3 +323,4 @@ COMPAT_SYS(pselect6) | |||
323 | COMPAT_SYS(ppoll) | 323 | COMPAT_SYS(ppoll) |
324 | SYSCALL(unshare) | 324 | SYSCALL(unshare) |
325 | SYSCALL(splice) | 325 | SYSCALL(splice) |
326 | SYSCALL(tee) | ||
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index a098a11e7755..059c88313f4e 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ | |||
8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ | 8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ |
9 | x8664_ksyms.o i387.o syscall.o vsyscall.o \ | 9 | x8664_ksyms.o i387.o syscall.o vsyscall.o \ |
10 | setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ | 10 | setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ |
11 | dmi_scan.o pci-dma.o pci-nommu.o | 11 | pci-dma.o pci-nommu.o |
12 | 12 | ||
13 | obj-$(CONFIG_X86_MCE) += mce.o | 13 | obj-$(CONFIG_X86_MCE) += mce.o |
14 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o | 14 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o |
@@ -49,5 +49,3 @@ intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o | |||
49 | quirks-y += ../../i386/kernel/quirks.o | 49 | quirks-y += ../../i386/kernel/quirks.o |
50 | i8237-y += ../../i386/kernel/i8237.o | 50 | i8237-y += ../../i386/kernel/i8237.o |
51 | msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o | 51 | msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o |
52 | dmi_scan-y += ../../i386/kernel/dmi_scan.o | ||
53 | |||
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/arch/i386/kernel/dmi_scan.c b/drivers/firmware/dmi_scan.c index 5efceebc48dc..948bd7e1445a 100644 --- a/arch/i386/kernel/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -27,7 +27,7 @@ static char * __init dmi_string(struct dmi_header *dm, u8 s) | |||
27 | else | 27 | else |
28 | printk(KERN_ERR "dmi_string: out of memory.\n"); | 28 | printk(KERN_ERR "dmi_string: out of memory.\n"); |
29 | } | 29 | } |
30 | } | 30 | } |
31 | 31 | ||
32 | return str; | 32 | return str; |
33 | } | 33 | } |
@@ -41,7 +41,7 @@ static int __init dmi_table(u32 base, int len, int num, | |||
41 | { | 41 | { |
42 | u8 *buf, *data; | 42 | u8 *buf, *data; |
43 | int i = 0; | 43 | int i = 0; |
44 | 44 | ||
45 | buf = dmi_ioremap(base, len); | 45 | buf = dmi_ioremap(base, len); |
46 | if (buf == NULL) | 46 | if (buf == NULL) |
47 | return -1; | 47 | return -1; |
@@ -49,9 +49,9 @@ static int __init dmi_table(u32 base, int len, int num, | |||
49 | data = buf; | 49 | data = buf; |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * Stop when we see all the items the table claimed to have | 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) | 53 | * OR we run off the end of the table (also happens) |
54 | */ | 54 | */ |
55 | while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { | 55 | while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { |
56 | struct dmi_header *dm = (struct dmi_header *)data; | 56 | struct dmi_header *dm = (struct dmi_header *)data; |
57 | /* | 57 | /* |
@@ -75,7 +75,7 @@ static int __init dmi_checksum(u8 *buf) | |||
75 | { | 75 | { |
76 | u8 sum = 0; | 76 | u8 sum = 0; |
77 | int a; | 77 | int a; |
78 | 78 | ||
79 | for (a = 0; a < 15; a++) | 79 | for (a = 0; a < 15; a++) |
80 | sum += buf[a]; | 80 | sum += buf[a]; |
81 | 81 | ||
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; |
@@ -665,9 +665,7 @@ static int de_thread(struct task_struct *tsk) | |||
665 | * and to assume its PID: | 665 | * and to assume its PID: |
666 | */ | 666 | */ |
667 | if (!thread_group_leader(current)) { | 667 | if (!thread_group_leader(current)) { |
668 | struct task_struct *parent; | ||
669 | struct dentry *proc_dentry1, *proc_dentry2; | 668 | struct dentry *proc_dentry1, *proc_dentry2; |
670 | unsigned long ptrace; | ||
671 | 669 | ||
672 | /* | 670 | /* |
673 | * Wait for the thread group leader to be a zombie. | 671 | * Wait for the thread group leader to be a zombie. |
@@ -704,22 +702,6 @@ static int de_thread(struct task_struct *tsk) | |||
704 | * two threads with a switched PID, and release | 702 | * two threads with a switched PID, and release |
705 | * the former thread group leader: | 703 | * the former thread group leader: |
706 | */ | 704 | */ |
707 | ptrace = leader->ptrace; | ||
708 | parent = leader->parent; | ||
709 | if (unlikely(ptrace) && unlikely(parent == current)) { | ||
710 | /* | ||
711 | * Joker was ptracing his own group leader, | ||
712 | * and now he wants to be his own parent! | ||
713 | * We can't have that. | ||
714 | */ | ||
715 | ptrace = 0; | ||
716 | } | ||
717 | |||
718 | ptrace_unlink(current); | ||
719 | ptrace_unlink(leader); | ||
720 | remove_parent(current); | ||
721 | remove_parent(leader); | ||
722 | |||
723 | 705 | ||
724 | /* Become a process group leader with the old leader's pid. | 706 | /* Become a process group leader with the old leader's pid. |
725 | * Note: The old leader also uses thispid until release_task | 707 | * Note: The old leader also uses thispid until release_task |
@@ -732,8 +714,6 @@ static int de_thread(struct task_struct *tsk) | |||
732 | attach_pid(current, PIDTYPE_SID, current->signal->session); | 714 | attach_pid(current, PIDTYPE_SID, current->signal->session); |
733 | list_add_tail(¤t->tasks, &init_task.tasks); | 715 | list_add_tail(¤t->tasks, &init_task.tasks); |
734 | 716 | ||
735 | current->parent = current->real_parent = leader->real_parent; | ||
736 | leader->parent = leader->real_parent = child_reaper; | ||
737 | current->group_leader = current; | 717 | current->group_leader = current; |
738 | leader->group_leader = current; | 718 | leader->group_leader = current; |
739 | 719 | ||
@@ -742,13 +722,6 @@ static int de_thread(struct task_struct *tsk) | |||
742 | detach_pid(leader, PIDTYPE_SID); | 722 | detach_pid(leader, PIDTYPE_SID); |
743 | list_del_init(&leader->tasks); | 723 | list_del_init(&leader->tasks); |
744 | 724 | ||
745 | add_parent(current); | ||
746 | add_parent(leader); | ||
747 | if (ptrace) { | ||
748 | current->ptrace = ptrace; | ||
749 | __ptrace_link(current, parent); | ||
750 | } | ||
751 | |||
752 | current->exit_signal = SIGCHLD; | 725 | current->exit_signal = SIGCHLD; |
753 | 726 | ||
754 | BUG_ON(leader->exit_state != EXIT_ZOMBIE); | 727 | BUG_ON(leader->exit_state != EXIT_ZOMBIE); |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 6c740f860665..cc750c68fe70 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -92,48 +92,50 @@ struct fuse_req *fuse_get_req(struct fuse_conn *fc) | |||
92 | { | 92 | { |
93 | struct fuse_req *req; | 93 | struct fuse_req *req; |
94 | sigset_t oldset; | 94 | sigset_t oldset; |
95 | int intr; | ||
95 | int err; | 96 | int err; |
96 | 97 | ||
98 | atomic_inc(&fc->num_waiting); | ||
97 | block_sigs(&oldset); | 99 | block_sigs(&oldset); |
98 | err = wait_event_interruptible(fc->blocked_waitq, !fc->blocked); | 100 | intr = wait_event_interruptible(fc->blocked_waitq, !fc->blocked); |
99 | restore_sigs(&oldset); | 101 | restore_sigs(&oldset); |
100 | if (err) | 102 | err = -EINTR; |
101 | return ERR_PTR(-EINTR); | 103 | if (intr) |
104 | goto out; | ||
102 | 105 | ||
103 | req = fuse_request_alloc(); | 106 | req = fuse_request_alloc(); |
107 | err = -ENOMEM; | ||
104 | if (!req) | 108 | if (!req) |
105 | return ERR_PTR(-ENOMEM); | 109 | goto out; |
106 | 110 | ||
107 | atomic_inc(&fc->num_waiting); | ||
108 | fuse_request_init(req); | ||
109 | req->in.h.uid = current->fsuid; | 111 | req->in.h.uid = current->fsuid; |
110 | req->in.h.gid = current->fsgid; | 112 | req->in.h.gid = current->fsgid; |
111 | req->in.h.pid = current->pid; | 113 | req->in.h.pid = current->pid; |
114 | req->waiting = 1; | ||
112 | return req; | 115 | return req; |
116 | |||
117 | out: | ||
118 | atomic_dec(&fc->num_waiting); | ||
119 | return ERR_PTR(err); | ||
113 | } | 120 | } |
114 | 121 | ||
115 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) | 122 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) |
116 | { | 123 | { |
117 | if (atomic_dec_and_test(&req->count)) { | 124 | if (atomic_dec_and_test(&req->count)) { |
118 | atomic_dec(&fc->num_waiting); | 125 | if (req->waiting) |
126 | atomic_dec(&fc->num_waiting); | ||
119 | fuse_request_free(req); | 127 | fuse_request_free(req); |
120 | } | 128 | } |
121 | } | 129 | } |
122 | 130 | ||
123 | void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req) | 131 | void fuse_remove_background(struct fuse_conn *fc, struct fuse_req *req) |
124 | { | 132 | { |
125 | iput(req->inode); | 133 | list_del_init(&req->bg_entry); |
126 | iput(req->inode2); | ||
127 | if (req->file) | ||
128 | fput(req->file); | ||
129 | spin_lock(&fc->lock); | ||
130 | list_del(&req->bg_entry); | ||
131 | if (fc->num_background == FUSE_MAX_BACKGROUND) { | 134 | if (fc->num_background == FUSE_MAX_BACKGROUND) { |
132 | fc->blocked = 0; | 135 | fc->blocked = 0; |
133 | wake_up_all(&fc->blocked_waitq); | 136 | wake_up_all(&fc->blocked_waitq); |
134 | } | 137 | } |
135 | fc->num_background--; | 138 | fc->num_background--; |
136 | spin_unlock(&fc->lock); | ||
137 | } | 139 | } |
138 | 140 | ||
139 | /* | 141 | /* |
@@ -163,17 +165,27 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) | |||
163 | wake_up(&req->waitq); | 165 | wake_up(&req->waitq); |
164 | fuse_put_request(fc, req); | 166 | fuse_put_request(fc, req); |
165 | } else { | 167 | } else { |
168 | struct inode *inode = req->inode; | ||
169 | struct inode *inode2 = req->inode2; | ||
170 | struct file *file = req->file; | ||
166 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; | 171 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; |
167 | req->end = NULL; | 172 | req->end = NULL; |
173 | req->inode = NULL; | ||
174 | req->inode2 = NULL; | ||
175 | req->file = NULL; | ||
176 | if (!list_empty(&req->bg_entry)) | ||
177 | fuse_remove_background(fc, req); | ||
168 | spin_unlock(&fc->lock); | 178 | spin_unlock(&fc->lock); |
169 | down_read(&fc->sbput_sem); | 179 | |
170 | if (fc->mounted) | ||
171 | fuse_release_background(fc, req); | ||
172 | up_read(&fc->sbput_sem); | ||
173 | if (end) | 180 | if (end) |
174 | end(fc, req); | 181 | end(fc, req); |
175 | else | 182 | else |
176 | fuse_put_request(fc, req); | 183 | fuse_put_request(fc, req); |
184 | |||
185 | if (file) | ||
186 | fput(file); | ||
187 | iput(inode); | ||
188 | iput(inode2); | ||
177 | } | 189 | } |
178 | } | 190 | } |
179 | 191 | ||
@@ -277,6 +289,10 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req) | |||
277 | len_args(req->in.numargs, (struct fuse_arg *) req->in.args); | 289 | len_args(req->in.numargs, (struct fuse_arg *) req->in.args); |
278 | list_add_tail(&req->list, &fc->pending); | 290 | list_add_tail(&req->list, &fc->pending); |
279 | req->state = FUSE_REQ_PENDING; | 291 | req->state = FUSE_REQ_PENDING; |
292 | if (!req->waiting) { | ||
293 | req->waiting = 1; | ||
294 | atomic_inc(&fc->num_waiting); | ||
295 | } | ||
280 | wake_up(&fc->waitq); | 296 | wake_up(&fc->waitq); |
281 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | 297 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); |
282 | } | 298 | } |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e4f041a11bb5..fc342cf7c2cc 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -565,8 +565,12 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, | |||
565 | buf += nres; | 565 | buf += nres; |
566 | if (nres != nbytes) | 566 | if (nres != nbytes) |
567 | break; | 567 | break; |
568 | if (count) | 568 | if (count) { |
569 | fuse_reset_request(req); | 569 | fuse_put_request(fc, req); |
570 | req = fuse_get_req(fc); | ||
571 | if (IS_ERR(req)) | ||
572 | break; | ||
573 | } | ||
570 | } | 574 | } |
571 | fuse_put_request(fc, req); | 575 | fuse_put_request(fc, req); |
572 | if (res > 0) { | 576 | if (res > 0) { |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 19c7185a7546..59661c481d9d 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -159,6 +159,9 @@ struct fuse_req { | |||
159 | /** Data is being copied to/from the request */ | 159 | /** Data is being copied to/from the request */ |
160 | unsigned locked:1; | 160 | unsigned locked:1; |
161 | 161 | ||
162 | /** Request is counted as "waiting" */ | ||
163 | unsigned waiting:1; | ||
164 | |||
162 | /** State of the request */ | 165 | /** State of the request */ |
163 | enum fuse_req_state state; | 166 | enum fuse_req_state state; |
164 | 167 | ||
@@ -255,15 +258,9 @@ struct fuse_conn { | |||
255 | /** waitq for blocked connection */ | 258 | /** waitq for blocked connection */ |
256 | wait_queue_head_t blocked_waitq; | 259 | wait_queue_head_t blocked_waitq; |
257 | 260 | ||
258 | /** RW semaphore for exclusion with fuse_put_super() */ | ||
259 | struct rw_semaphore sbput_sem; | ||
260 | |||
261 | /** The next unique request id */ | 261 | /** The next unique request id */ |
262 | u64 reqctr; | 262 | u64 reqctr; |
263 | 263 | ||
264 | /** Mount is active */ | ||
265 | unsigned mounted; | ||
266 | |||
267 | /** Connection established, cleared on umount, connection | 264 | /** Connection established, cleared on umount, connection |
268 | abort and device release */ | 265 | abort and device release */ |
269 | unsigned connected; | 266 | unsigned connected; |
@@ -474,11 +471,11 @@ void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); | |||
474 | void request_send_background(struct fuse_conn *fc, struct fuse_req *req); | 471 | void request_send_background(struct fuse_conn *fc, struct fuse_req *req); |
475 | 472 | ||
476 | /** | 473 | /** |
477 | * Release inodes and file associated with background request | 474 | * Remove request from the the background list |
478 | */ | 475 | */ |
479 | void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req); | 476 | void fuse_remove_background(struct fuse_conn *fc, struct fuse_req *req); |
480 | 477 | ||
481 | /* Abort all requests */ | 478 | /** Abort all requests */ |
482 | void fuse_abort_conn(struct fuse_conn *fc); | 479 | void fuse_abort_conn(struct fuse_conn *fc); |
483 | 480 | ||
484 | /** | 481 | /** |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index fd34037b0588..43a6fc0db8a7 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -204,17 +204,26 @@ static void fuse_put_super(struct super_block *sb) | |||
204 | { | 204 | { |
205 | struct fuse_conn *fc = get_fuse_conn_super(sb); | 205 | struct fuse_conn *fc = get_fuse_conn_super(sb); |
206 | 206 | ||
207 | down_write(&fc->sbput_sem); | ||
208 | while (!list_empty(&fc->background)) | ||
209 | fuse_release_background(fc, | ||
210 | list_entry(fc->background.next, | ||
211 | struct fuse_req, bg_entry)); | ||
212 | |||
213 | spin_lock(&fc->lock); | 207 | spin_lock(&fc->lock); |
214 | fc->mounted = 0; | ||
215 | fc->connected = 0; | 208 | fc->connected = 0; |
209 | while (!list_empty(&fc->background)) { | ||
210 | struct fuse_req *req = list_entry(fc->background.next, | ||
211 | struct fuse_req, bg_entry); | ||
212 | struct inode *inode = req->inode; | ||
213 | struct inode *inode2 = req->inode2; | ||
214 | |||
215 | /* File would hold a reference to vfsmount */ | ||
216 | BUG_ON(req->file); | ||
217 | req->inode = NULL; | ||
218 | req->inode2 = NULL; | ||
219 | fuse_remove_background(fc, req); | ||
220 | |||
221 | spin_unlock(&fc->lock); | ||
222 | iput(inode); | ||
223 | iput(inode2); | ||
224 | spin_lock(&fc->lock); | ||
225 | } | ||
216 | spin_unlock(&fc->lock); | 226 | spin_unlock(&fc->lock); |
217 | up_write(&fc->sbput_sem); | ||
218 | /* Flush all readers on this fs */ | 227 | /* Flush all readers on this fs */ |
219 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | 228 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); |
220 | wake_up_all(&fc->waitq); | 229 | wake_up_all(&fc->waitq); |
@@ -386,7 +395,6 @@ static struct fuse_conn *new_conn(void) | |||
386 | INIT_LIST_HEAD(&fc->processing); | 395 | INIT_LIST_HEAD(&fc->processing); |
387 | INIT_LIST_HEAD(&fc->io); | 396 | INIT_LIST_HEAD(&fc->io); |
388 | INIT_LIST_HEAD(&fc->background); | 397 | INIT_LIST_HEAD(&fc->background); |
389 | init_rwsem(&fc->sbput_sem); | ||
390 | kobj_set_kset_s(fc, connections_subsys); | 398 | kobj_set_kset_s(fc, connections_subsys); |
391 | kobject_init(&fc->kobj); | 399 | kobject_init(&fc->kobj); |
392 | atomic_set(&fc->num_waiting, 0); | 400 | atomic_set(&fc->num_waiting, 0); |
@@ -541,7 +549,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
541 | goto err_free_req; | 549 | goto err_free_req; |
542 | 550 | ||
543 | sb->s_root = root_dentry; | 551 | sb->s_root = root_dentry; |
544 | fc->mounted = 1; | ||
545 | fc->connected = 1; | 552 | fc->connected = 1; |
546 | kobject_get(&fc->kobj); | 553 | kobject_get(&fc->kobj); |
547 | file->private_data = fc; | 554 | file->private_data = fc; |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index af0cb4b9e784..f3b6af071722 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -331,7 +331,9 @@ void delete_partition(struct gendisk *disk, int part) | |||
331 | devfs_remove("%s/part%d", disk->devfs_name, part); | 331 | devfs_remove("%s/part%d", disk->devfs_name, part); |
332 | if (p->holder_dir) | 332 | if (p->holder_dir) |
333 | kobject_unregister(p->holder_dir); | 333 | kobject_unregister(p->holder_dir); |
334 | kobject_unregister(&p->kobj); | 334 | kobject_uevent(&p->kobj, KOBJ_REMOVE); |
335 | kobject_del(&p->kobj); | ||
336 | kobject_put(&p->kobj); | ||
335 | } | 337 | } |
336 | 338 | ||
337 | void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) | 339 | void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) |
@@ -357,7 +359,10 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) | |||
357 | snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part); | 359 | snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part); |
358 | p->kobj.parent = &disk->kobj; | 360 | p->kobj.parent = &disk->kobj; |
359 | p->kobj.ktype = &ktype_part; | 361 | p->kobj.ktype = &ktype_part; |
360 | kobject_register(&p->kobj); | 362 | kobject_init(&p->kobj); |
363 | kobject_add(&p->kobj); | ||
364 | if (!disk->part_uevent_suppress) | ||
365 | kobject_uevent(&p->kobj, KOBJ_ADD); | ||
361 | partition_sysfs_add_subdir(p); | 366 | partition_sysfs_add_subdir(p); |
362 | disk->part[part-1] = p; | 367 | disk->part[part-1] = p; |
363 | } | 368 | } |
@@ -395,6 +400,8 @@ void register_disk(struct gendisk *disk) | |||
395 | { | 400 | { |
396 | struct block_device *bdev; | 401 | struct block_device *bdev; |
397 | char *s; | 402 | char *s; |
403 | int i; | ||
404 | struct hd_struct *p; | ||
398 | int err; | 405 | int err; |
399 | 406 | ||
400 | strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN); | 407 | strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN); |
@@ -406,13 +413,12 @@ void register_disk(struct gendisk *disk) | |||
406 | return; | 413 | return; |
407 | disk_sysfs_symlinks(disk); | 414 | disk_sysfs_symlinks(disk); |
408 | disk_sysfs_add_subdirs(disk); | 415 | disk_sysfs_add_subdirs(disk); |
409 | kobject_uevent(&disk->kobj, KOBJ_ADD); | ||
410 | 416 | ||
411 | /* No minors to use for partitions */ | 417 | /* No minors to use for partitions */ |
412 | if (disk->minors == 1) { | 418 | if (disk->minors == 1) { |
413 | if (disk->devfs_name[0] != '\0') | 419 | if (disk->devfs_name[0] != '\0') |
414 | devfs_add_disk(disk); | 420 | devfs_add_disk(disk); |
415 | return; | 421 | goto exit; |
416 | } | 422 | } |
417 | 423 | ||
418 | /* always add handle for the whole disk */ | 424 | /* always add handle for the whole disk */ |
@@ -420,16 +426,32 @@ void register_disk(struct gendisk *disk) | |||
420 | 426 | ||
421 | /* No such device (e.g., media were just removed) */ | 427 | /* No such device (e.g., media were just removed) */ |
422 | if (!get_capacity(disk)) | 428 | if (!get_capacity(disk)) |
423 | return; | 429 | goto exit; |
424 | 430 | ||
425 | bdev = bdget_disk(disk, 0); | 431 | bdev = bdget_disk(disk, 0); |
426 | if (!bdev) | 432 | if (!bdev) |
427 | return; | 433 | goto exit; |
428 | 434 | ||
435 | /* scan partition table, but suppress uevents */ | ||
429 | bdev->bd_invalidated = 1; | 436 | bdev->bd_invalidated = 1; |
430 | if (blkdev_get(bdev, FMODE_READ, 0) < 0) | 437 | disk->part_uevent_suppress = 1; |
431 | return; | 438 | err = blkdev_get(bdev, FMODE_READ, 0); |
439 | disk->part_uevent_suppress = 0; | ||
440 | if (err < 0) | ||
441 | goto exit; | ||
432 | blkdev_put(bdev); | 442 | blkdev_put(bdev); |
443 | |||
444 | exit: | ||
445 | /* announce disk after possible partitions are already created */ | ||
446 | kobject_uevent(&disk->kobj, KOBJ_ADD); | ||
447 | |||
448 | /* announce possible partitions */ | ||
449 | for (i = 1; i < disk->minors; i++) { | ||
450 | p = disk->part[i-1]; | ||
451 | if (!p || !p->nr_sects) | ||
452 | continue; | ||
453 | kobject_uevent(&p->kobj, KOBJ_ADD); | ||
454 | } | ||
433 | } | 455 | } |
434 | 456 | ||
435 | int rescan_partitions(struct gendisk *disk, struct block_device *bdev) | 457 | int rescan_partitions(struct gendisk *disk, struct block_device *bdev) |
@@ -131,12 +131,19 @@ static int anon_pipe_buf_steal(struct pipe_inode_info *pipe, | |||
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
133 | 133 | ||
134 | static void anon_pipe_buf_get(struct pipe_inode_info *info, | ||
135 | struct pipe_buffer *buf) | ||
136 | { | ||
137 | page_cache_get(buf->page); | ||
138 | } | ||
139 | |||
134 | static struct pipe_buf_operations anon_pipe_buf_ops = { | 140 | static struct pipe_buf_operations anon_pipe_buf_ops = { |
135 | .can_merge = 1, | 141 | .can_merge = 1, |
136 | .map = anon_pipe_buf_map, | 142 | .map = anon_pipe_buf_map, |
137 | .unmap = anon_pipe_buf_unmap, | 143 | .unmap = anon_pipe_buf_unmap, |
138 | .release = anon_pipe_buf_release, | 144 | .release = anon_pipe_buf_release, |
139 | .steal = anon_pipe_buf_steal, | 145 | .steal = anon_pipe_buf_steal, |
146 | .get = anon_pipe_buf_get, | ||
140 | }; | 147 | }; |
141 | 148 | ||
142 | static ssize_t | 149 | static ssize_t |
diff --git a/fs/splice.c b/fs/splice.c index e50a460239dd..8d57e89924a6 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -125,12 +125,19 @@ static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info, | |||
125 | kunmap(buf->page); | 125 | kunmap(buf->page); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void page_cache_pipe_buf_get(struct pipe_inode_info *info, | ||
129 | struct pipe_buffer *buf) | ||
130 | { | ||
131 | page_cache_get(buf->page); | ||
132 | } | ||
133 | |||
128 | static struct pipe_buf_operations page_cache_pipe_buf_ops = { | 134 | static struct pipe_buf_operations page_cache_pipe_buf_ops = { |
129 | .can_merge = 0, | 135 | .can_merge = 0, |
130 | .map = page_cache_pipe_buf_map, | 136 | .map = page_cache_pipe_buf_map, |
131 | .unmap = page_cache_pipe_buf_unmap, | 137 | .unmap = page_cache_pipe_buf_unmap, |
132 | .release = page_cache_pipe_buf_release, | 138 | .release = page_cache_pipe_buf_release, |
133 | .steal = page_cache_pipe_buf_steal, | 139 | .steal = page_cache_pipe_buf_steal, |
140 | .get = page_cache_pipe_buf_get, | ||
134 | }; | 141 | }; |
135 | 142 | ||
136 | /* | 143 | /* |
@@ -231,8 +238,9 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, | |||
231 | } | 238 | } |
232 | 239 | ||
233 | static int | 240 | static int |
234 | __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, | 241 | __generic_file_splice_read(struct file *in, loff_t *ppos, |
235 | size_t len, unsigned int flags) | 242 | struct pipe_inode_info *pipe, size_t len, |
243 | unsigned int flags) | ||
236 | { | 244 | { |
237 | struct address_space *mapping = in->f_mapping; | 245 | struct address_space *mapping = in->f_mapping; |
238 | unsigned int offset, nr_pages; | 246 | unsigned int offset, nr_pages; |
@@ -241,8 +249,8 @@ __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, | |||
241 | pgoff_t index; | 249 | pgoff_t index; |
242 | int i, error; | 250 | int i, error; |
243 | 251 | ||
244 | index = in->f_pos >> PAGE_CACHE_SHIFT; | 252 | index = *ppos >> PAGE_CACHE_SHIFT; |
245 | offset = in->f_pos & ~PAGE_CACHE_MASK; | 253 | offset = *ppos & ~PAGE_CACHE_MASK; |
246 | nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 254 | nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
247 | 255 | ||
248 | if (nr_pages > PIPE_BUFFERS) | 256 | if (nr_pages > PIPE_BUFFERS) |
@@ -348,8 +356,9 @@ fill_it: | |||
348 | * | 356 | * |
349 | * Will read pages from given file and fill them into a pipe. | 357 | * Will read pages from given file and fill them into a pipe. |
350 | */ | 358 | */ |
351 | ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, | 359 | ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, |
352 | size_t len, unsigned int flags) | 360 | struct pipe_inode_info *pipe, size_t len, |
361 | unsigned int flags) | ||
353 | { | 362 | { |
354 | ssize_t spliced; | 363 | ssize_t spliced; |
355 | int ret; | 364 | int ret; |
@@ -358,12 +367,12 @@ ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, | |||
358 | spliced = 0; | 367 | spliced = 0; |
359 | 368 | ||
360 | while (len) { | 369 | while (len) { |
361 | ret = __generic_file_splice_read(in, pipe, len, flags); | 370 | ret = __generic_file_splice_read(in, ppos, pipe, len, flags); |
362 | 371 | ||
363 | if (ret <= 0) | 372 | if (ret <= 0) |
364 | break; | 373 | break; |
365 | 374 | ||
366 | in->f_pos += ret; | 375 | *ppos += ret; |
367 | len -= ret; | 376 | len -= ret; |
368 | spliced += ret; | 377 | spliced += ret; |
369 | 378 | ||
@@ -561,7 +570,7 @@ typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, | |||
561 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. | 570 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. |
562 | */ | 571 | */ |
563 | static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | 572 | static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, |
564 | size_t len, unsigned int flags, | 573 | loff_t *ppos, size_t len, unsigned int flags, |
565 | splice_actor *actor) | 574 | splice_actor *actor) |
566 | { | 575 | { |
567 | int ret, do_wakeup, err; | 576 | int ret, do_wakeup, err; |
@@ -573,7 +582,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
573 | sd.total_len = len; | 582 | sd.total_len = len; |
574 | sd.flags = flags; | 583 | sd.flags = flags; |
575 | sd.file = out; | 584 | sd.file = out; |
576 | sd.pos = out->f_pos; | 585 | sd.pos = *ppos; |
577 | 586 | ||
578 | if (pipe->inode) | 587 | if (pipe->inode) |
579 | mutex_lock(&pipe->inode->i_mutex); | 588 | mutex_lock(&pipe->inode->i_mutex); |
@@ -656,9 +665,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
656 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | 665 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
657 | } | 666 | } |
658 | 667 | ||
659 | out->f_pos = sd.pos; | ||
660 | return ret; | 668 | return ret; |
661 | |||
662 | } | 669 | } |
663 | 670 | ||
664 | /** | 671 | /** |
@@ -674,12 +681,12 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
674 | */ | 681 | */ |
675 | ssize_t | 682 | ssize_t |
676 | generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | 683 | generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, |
677 | size_t len, unsigned int flags) | 684 | loff_t *ppos, size_t len, unsigned int flags) |
678 | { | 685 | { |
679 | struct address_space *mapping = out->f_mapping; | 686 | struct address_space *mapping = out->f_mapping; |
680 | ssize_t ret; | 687 | ssize_t ret; |
681 | 688 | ||
682 | ret = move_from_pipe(pipe, out, len, flags, pipe_to_file); | 689 | ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); |
683 | 690 | ||
684 | /* | 691 | /* |
685 | * If file or inode is SYNC and we actually wrote some data, sync it. | 692 | * If file or inode is SYNC and we actually wrote some data, sync it. |
@@ -715,9 +722,9 @@ EXPORT_SYMBOL(generic_file_splice_write); | |||
715 | * | 722 | * |
716 | */ | 723 | */ |
717 | ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, | 724 | ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, |
718 | size_t len, unsigned int flags) | 725 | loff_t *ppos, size_t len, unsigned int flags) |
719 | { | 726 | { |
720 | return move_from_pipe(pipe, out, len, flags, pipe_to_sendpage); | 727 | return move_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage); |
721 | } | 728 | } |
722 | 729 | ||
723 | EXPORT_SYMBOL(generic_splice_sendpage); | 730 | EXPORT_SYMBOL(generic_splice_sendpage); |
@@ -726,9 +733,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); | |||
726 | * Attempt to initiate a splice from pipe to file. | 733 | * Attempt to initiate a splice from pipe to file. |
727 | */ | 734 | */ |
728 | static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, | 735 | static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, |
729 | size_t len, unsigned int flags) | 736 | loff_t *ppos, size_t len, unsigned int flags) |
730 | { | 737 | { |
731 | loff_t pos; | ||
732 | int ret; | 738 | int ret; |
733 | 739 | ||
734 | if (unlikely(!out->f_op || !out->f_op->splice_write)) | 740 | if (unlikely(!out->f_op || !out->f_op->splice_write)) |
@@ -737,22 +743,21 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, | |||
737 | if (unlikely(!(out->f_mode & FMODE_WRITE))) | 743 | if (unlikely(!(out->f_mode & FMODE_WRITE))) |
738 | return -EBADF; | 744 | return -EBADF; |
739 | 745 | ||
740 | pos = out->f_pos; | 746 | ret = rw_verify_area(WRITE, out, ppos, len); |
741 | |||
742 | ret = rw_verify_area(WRITE, out, &pos, len); | ||
743 | if (unlikely(ret < 0)) | 747 | if (unlikely(ret < 0)) |
744 | return ret; | 748 | return ret; |
745 | 749 | ||
746 | return out->f_op->splice_write(pipe, out, len, flags); | 750 | return out->f_op->splice_write(pipe, out, ppos, len, flags); |
747 | } | 751 | } |
748 | 752 | ||
749 | /* | 753 | /* |
750 | * Attempt to initiate a splice from a file to a pipe. | 754 | * Attempt to initiate a splice from a file to a pipe. |
751 | */ | 755 | */ |
752 | static long do_splice_to(struct file *in, struct pipe_inode_info *pipe, | 756 | static long do_splice_to(struct file *in, loff_t *ppos, |
753 | size_t len, unsigned int flags) | 757 | struct pipe_inode_info *pipe, size_t len, |
758 | unsigned int flags) | ||
754 | { | 759 | { |
755 | loff_t pos, isize, left; | 760 | loff_t isize, left; |
756 | int ret; | 761 | int ret; |
757 | 762 | ||
758 | if (unlikely(!in->f_op || !in->f_op->splice_read)) | 763 | if (unlikely(!in->f_op || !in->f_op->splice_read)) |
@@ -761,28 +766,27 @@ static long do_splice_to(struct file *in, struct pipe_inode_info *pipe, | |||
761 | if (unlikely(!(in->f_mode & FMODE_READ))) | 766 | if (unlikely(!(in->f_mode & FMODE_READ))) |
762 | return -EBADF; | 767 | return -EBADF; |
763 | 768 | ||
764 | pos = in->f_pos; | 769 | ret = rw_verify_area(READ, in, ppos, len); |
765 | |||
766 | ret = rw_verify_area(READ, in, &pos, len); | ||
767 | if (unlikely(ret < 0)) | 770 | if (unlikely(ret < 0)) |
768 | return ret; | 771 | return ret; |
769 | 772 | ||
770 | isize = i_size_read(in->f_mapping->host); | 773 | isize = i_size_read(in->f_mapping->host); |
771 | if (unlikely(in->f_pos >= isize)) | 774 | if (unlikely(*ppos >= isize)) |
772 | return 0; | 775 | return 0; |
773 | 776 | ||
774 | left = isize - in->f_pos; | 777 | left = isize - *ppos; |
775 | if (unlikely(left < len)) | 778 | if (unlikely(left < len)) |
776 | len = left; | 779 | len = left; |
777 | 780 | ||
778 | return in->f_op->splice_read(in, pipe, len, flags); | 781 | return in->f_op->splice_read(in, ppos, pipe, len, flags); |
779 | } | 782 | } |
780 | 783 | ||
781 | long do_splice_direct(struct file *in, struct file *out, size_t len, | 784 | long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, |
782 | unsigned int flags) | 785 | size_t len, unsigned int flags) |
783 | { | 786 | { |
784 | struct pipe_inode_info *pipe; | 787 | struct pipe_inode_info *pipe; |
785 | long ret, bytes; | 788 | long ret, bytes; |
789 | loff_t out_off; | ||
786 | umode_t i_mode; | 790 | umode_t i_mode; |
787 | int i; | 791 | int i; |
788 | 792 | ||
@@ -820,6 +824,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len, | |||
820 | */ | 824 | */ |
821 | ret = 0; | 825 | ret = 0; |
822 | bytes = 0; | 826 | bytes = 0; |
827 | out_off = 0; | ||
823 | 828 | ||
824 | while (len) { | 829 | while (len) { |
825 | size_t read_len, max_read_len; | 830 | size_t read_len, max_read_len; |
@@ -829,7 +834,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len, | |||
829 | */ | 834 | */ |
830 | max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); | 835 | max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); |
831 | 836 | ||
832 | ret = do_splice_to(in, pipe, max_read_len, flags); | 837 | ret = do_splice_to(in, ppos, pipe, max_read_len, flags); |
833 | if (unlikely(ret < 0)) | 838 | if (unlikely(ret < 0)) |
834 | goto out_release; | 839 | goto out_release; |
835 | 840 | ||
@@ -840,7 +845,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len, | |||
840 | * must not do the output in nonblocking mode as then we | 845 | * must not do the output in nonblocking mode as then we |
841 | * could get stuck data in the internal pipe: | 846 | * could get stuck data in the internal pipe: |
842 | */ | 847 | */ |
843 | ret = do_splice_from(pipe, out, read_len, | 848 | ret = do_splice_from(pipe, out, &out_off, read_len, |
844 | flags & ~SPLICE_F_NONBLOCK); | 849 | flags & ~SPLICE_F_NONBLOCK); |
845 | if (unlikely(ret < 0)) | 850 | if (unlikely(ret < 0)) |
846 | goto out_release; | 851 | goto out_release; |
@@ -898,6 +903,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
898 | size_t len, unsigned int flags) | 903 | size_t len, unsigned int flags) |
899 | { | 904 | { |
900 | struct pipe_inode_info *pipe; | 905 | struct pipe_inode_info *pipe; |
906 | loff_t offset, *off; | ||
901 | 907 | ||
902 | pipe = in->f_dentry->d_inode->i_pipe; | 908 | pipe = in->f_dentry->d_inode->i_pipe; |
903 | if (pipe) { | 909 | if (pipe) { |
@@ -906,12 +912,13 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
906 | if (off_out) { | 912 | if (off_out) { |
907 | if (out->f_op->llseek == no_llseek) | 913 | if (out->f_op->llseek == no_llseek) |
908 | return -EINVAL; | 914 | return -EINVAL; |
909 | if (copy_from_user(&out->f_pos, off_out, | 915 | if (copy_from_user(&offset, off_out, sizeof(loff_t))) |
910 | sizeof(loff_t))) | ||
911 | return -EFAULT; | 916 | return -EFAULT; |
912 | } | 917 | off = &offset; |
918 | } else | ||
919 | off = &out->f_pos; | ||
913 | 920 | ||
914 | return do_splice_from(pipe, out, len, flags); | 921 | return do_splice_from(pipe, out, off, len, flags); |
915 | } | 922 | } |
916 | 923 | ||
917 | pipe = out->f_dentry->d_inode->i_pipe; | 924 | pipe = out->f_dentry->d_inode->i_pipe; |
@@ -921,11 +928,13 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
921 | if (off_in) { | 928 | if (off_in) { |
922 | if (in->f_op->llseek == no_llseek) | 929 | if (in->f_op->llseek == no_llseek) |
923 | return -EINVAL; | 930 | return -EINVAL; |
924 | if (copy_from_user(&in->f_pos, off_in, sizeof(loff_t))) | 931 | if (copy_from_user(&offset, off_in, sizeof(loff_t))) |
925 | return -EFAULT; | 932 | return -EFAULT; |
926 | } | 933 | off = &offset; |
934 | } else | ||
935 | off = &in->f_pos; | ||
927 | 936 | ||
928 | return do_splice_to(in, pipe, len, flags); | 937 | return do_splice_to(in, off, pipe, len, flags); |
929 | } | 938 | } |
930 | 939 | ||
931 | return -EINVAL; | 940 | return -EINVAL; |
@@ -961,3 +970,182 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, | |||
961 | 970 | ||
962 | return error; | 971 | return error; |
963 | } | 972 | } |
973 | |||
974 | /* | ||
975 | * Link contents of ipipe to opipe. | ||
976 | */ | ||
977 | static int link_pipe(struct pipe_inode_info *ipipe, | ||
978 | struct pipe_inode_info *opipe, | ||
979 | size_t len, unsigned int flags) | ||
980 | { | ||
981 | struct pipe_buffer *ibuf, *obuf; | ||
982 | int ret = 0, do_wakeup = 0, i; | ||
983 | |||
984 | /* | ||
985 | * Potential ABBA deadlock, work around it by ordering lock | ||
986 | * grabbing by inode address. Otherwise two different processes | ||
987 | * could deadlock (one doing tee from A -> B, the other from B -> A). | ||
988 | */ | ||
989 | if (ipipe->inode < opipe->inode) { | ||
990 | mutex_lock(&ipipe->inode->i_mutex); | ||
991 | mutex_lock(&opipe->inode->i_mutex); | ||
992 | } else { | ||
993 | mutex_lock(&opipe->inode->i_mutex); | ||
994 | mutex_lock(&ipipe->inode->i_mutex); | ||
995 | } | ||
996 | |||
997 | for (i = 0;; i++) { | ||
998 | if (!opipe->readers) { | ||
999 | send_sig(SIGPIPE, current, 0); | ||
1000 | if (!ret) | ||
1001 | ret = -EPIPE; | ||
1002 | break; | ||
1003 | } | ||
1004 | if (ipipe->nrbufs - i) { | ||
1005 | ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1)); | ||
1006 | |||
1007 | /* | ||
1008 | * If we have room, fill this buffer | ||
1009 | */ | ||
1010 | if (opipe->nrbufs < PIPE_BUFFERS) { | ||
1011 | int nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1); | ||
1012 | |||
1013 | /* | ||
1014 | * Get a reference to this pipe buffer, | ||
1015 | * so we can copy the contents over. | ||
1016 | */ | ||
1017 | ibuf->ops->get(ipipe, ibuf); | ||
1018 | |||
1019 | obuf = opipe->bufs + nbuf; | ||
1020 | *obuf = *ibuf; | ||
1021 | |||
1022 | if (obuf->len > len) | ||
1023 | obuf->len = len; | ||
1024 | |||
1025 | opipe->nrbufs++; | ||
1026 | do_wakeup = 1; | ||
1027 | ret += obuf->len; | ||
1028 | len -= obuf->len; | ||
1029 | |||
1030 | if (!len) | ||
1031 | break; | ||
1032 | if (opipe->nrbufs < PIPE_BUFFERS) | ||
1033 | continue; | ||
1034 | } | ||
1035 | |||
1036 | /* | ||
1037 | * We have input available, but no output room. | ||
1038 | * If we already copied data, return that. | ||
1039 | */ | ||
1040 | if (flags & SPLICE_F_NONBLOCK) { | ||
1041 | if (!ret) | ||
1042 | ret = -EAGAIN; | ||
1043 | break; | ||
1044 | } | ||
1045 | if (signal_pending(current)) { | ||
1046 | if (!ret) | ||
1047 | ret = -ERESTARTSYS; | ||
1048 | break; | ||
1049 | } | ||
1050 | if (do_wakeup) { | ||
1051 | smp_mb(); | ||
1052 | if (waitqueue_active(&opipe->wait)) | ||
1053 | wake_up_interruptible(&opipe->wait); | ||
1054 | kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN); | ||
1055 | do_wakeup = 0; | ||
1056 | } | ||
1057 | |||
1058 | opipe->waiting_writers++; | ||
1059 | pipe_wait(opipe); | ||
1060 | opipe->waiting_writers--; | ||
1061 | continue; | ||
1062 | } | ||
1063 | |||
1064 | /* | ||
1065 | * No input buffers, do the usual checks for available | ||
1066 | * writers and blocking and wait if necessary | ||
1067 | */ | ||
1068 | if (!ipipe->writers) | ||
1069 | break; | ||
1070 | if (!ipipe->waiting_writers) { | ||
1071 | if (ret) | ||
1072 | break; | ||
1073 | } | ||
1074 | if (flags & SPLICE_F_NONBLOCK) { | ||
1075 | if (!ret) | ||
1076 | ret = -EAGAIN; | ||
1077 | break; | ||
1078 | } | ||
1079 | if (signal_pending(current)) { | ||
1080 | if (!ret) | ||
1081 | ret = -ERESTARTSYS; | ||
1082 | break; | ||
1083 | } | ||
1084 | |||
1085 | if (waitqueue_active(&ipipe->wait)) | ||
1086 | wake_up_interruptible_sync(&ipipe->wait); | ||
1087 | kill_fasync(&ipipe->fasync_writers, SIGIO, POLL_OUT); | ||
1088 | |||
1089 | pipe_wait(ipipe); | ||
1090 | } | ||
1091 | |||
1092 | mutex_unlock(&ipipe->inode->i_mutex); | ||
1093 | mutex_unlock(&opipe->inode->i_mutex); | ||
1094 | |||
1095 | if (do_wakeup) { | ||
1096 | smp_mb(); | ||
1097 | if (waitqueue_active(&opipe->wait)) | ||
1098 | wake_up_interruptible(&opipe->wait); | ||
1099 | kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN); | ||
1100 | } | ||
1101 | |||
1102 | return ret; | ||
1103 | } | ||
1104 | |||
1105 | /* | ||
1106 | * This is a tee(1) implementation that works on pipes. It doesn't copy | ||
1107 | * any data, it simply references the 'in' pages on the 'out' pipe. | ||
1108 | * The 'flags' used are the SPLICE_F_* variants, currently the only | ||
1109 | * applicable one is SPLICE_F_NONBLOCK. | ||
1110 | */ | ||
1111 | static long do_tee(struct file *in, struct file *out, size_t len, | ||
1112 | unsigned int flags) | ||
1113 | { | ||
1114 | struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe; | ||
1115 | struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe; | ||
1116 | |||
1117 | /* | ||
1118 | * Link ipipe to the two output pipes, consuming as we go along. | ||
1119 | */ | ||
1120 | if (ipipe && opipe) | ||
1121 | return link_pipe(ipipe, opipe, len, flags); | ||
1122 | |||
1123 | return -EINVAL; | ||
1124 | } | ||
1125 | |||
1126 | asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags) | ||
1127 | { | ||
1128 | struct file *in; | ||
1129 | int error, fput_in; | ||
1130 | |||
1131 | if (unlikely(!len)) | ||
1132 | return 0; | ||
1133 | |||
1134 | error = -EBADF; | ||
1135 | in = fget_light(fdin, &fput_in); | ||
1136 | if (in) { | ||
1137 | if (in->f_mode & FMODE_READ) { | ||
1138 | int fput_out; | ||
1139 | struct file *out = fget_light(fdout, &fput_out); | ||
1140 | |||
1141 | if (out) { | ||
1142 | if (out->f_mode & FMODE_WRITE) | ||
1143 | error = do_tee(in, out, len, flags); | ||
1144 | fput_light(out, fput_out); | ||
1145 | } | ||
1146 | } | ||
1147 | fput_light(in, fput_in); | ||
1148 | } | ||
1149 | |||
1150 | return error; | ||
1151 | } | ||
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 6cfdc9a87772..610b5bdbe75b 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -43,6 +43,7 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd, | |||
43 | 43 | ||
44 | memset(sd, 0, sizeof(*sd)); | 44 | memset(sd, 0, sizeof(*sd)); |
45 | atomic_set(&sd->s_count, 1); | 45 | atomic_set(&sd->s_count, 1); |
46 | atomic_set(&sd->s_event, 0); | ||
46 | INIT_LIST_HEAD(&sd->s_children); | 47 | INIT_LIST_HEAD(&sd->s_children); |
47 | list_add(&sd->s_sibling, &parent_sd->s_children); | 48 | list_add(&sd->s_sibling, &parent_sd->s_children); |
48 | sd->s_element = element; | 49 | sd->s_element = element; |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index f1cb1ddde511..cf3786625bfa 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/fsnotify.h> | 6 | #include <linux/fsnotify.h> |
7 | #include <linux/kobject.h> | 7 | #include <linux/kobject.h> |
8 | #include <linux/namei.h> | 8 | #include <linux/namei.h> |
9 | #include <linux/poll.h> | ||
9 | #include <asm/uaccess.h> | 10 | #include <asm/uaccess.h> |
10 | #include <asm/semaphore.h> | 11 | #include <asm/semaphore.h> |
11 | 12 | ||
@@ -57,6 +58,7 @@ struct sysfs_buffer { | |||
57 | struct sysfs_ops * ops; | 58 | struct sysfs_ops * ops; |
58 | struct semaphore sem; | 59 | struct semaphore sem; |
59 | int needs_read_fill; | 60 | int needs_read_fill; |
61 | int event; | ||
60 | }; | 62 | }; |
61 | 63 | ||
62 | 64 | ||
@@ -72,6 +74,7 @@ struct sysfs_buffer { | |||
72 | */ | 74 | */ |
73 | static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer) | 75 | static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer) |
74 | { | 76 | { |
77 | struct sysfs_dirent * sd = dentry->d_fsdata; | ||
75 | struct attribute * attr = to_attr(dentry); | 78 | struct attribute * attr = to_attr(dentry); |
76 | struct kobject * kobj = to_kobj(dentry->d_parent); | 79 | struct kobject * kobj = to_kobj(dentry->d_parent); |
77 | struct sysfs_ops * ops = buffer->ops; | 80 | struct sysfs_ops * ops = buffer->ops; |
@@ -83,6 +86,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer | |||
83 | if (!buffer->page) | 86 | if (!buffer->page) |
84 | return -ENOMEM; | 87 | return -ENOMEM; |
85 | 88 | ||
89 | buffer->event = atomic_read(&sd->s_event); | ||
86 | count = ops->show(kobj,attr,buffer->page); | 90 | count = ops->show(kobj,attr,buffer->page); |
87 | buffer->needs_read_fill = 0; | 91 | buffer->needs_read_fill = 0; |
88 | BUG_ON(count > (ssize_t)PAGE_SIZE); | 92 | BUG_ON(count > (ssize_t)PAGE_SIZE); |
@@ -348,12 +352,84 @@ static int sysfs_release(struct inode * inode, struct file * filp) | |||
348 | return 0; | 352 | return 0; |
349 | } | 353 | } |
350 | 354 | ||
355 | /* Sysfs attribute files are pollable. The idea is that you read | ||
356 | * the content and then you use 'poll' or 'select' to wait for | ||
357 | * the content to change. When the content changes (assuming the | ||
358 | * manager for the kobject supports notification), poll will | ||
359 | * return POLLERR|POLLPRI, and select will return the fd whether | ||
360 | * it is waiting for read, write, or exceptions. | ||
361 | * Once poll/select indicates that the value has changed, you | ||
362 | * need to close and re-open the file, as simply seeking and reading | ||
363 | * again will not get new data, or reset the state of 'poll'. | ||
364 | * Reminder: this only works for attributes which actively support | ||
365 | * it, and it is not possible to test an attribute from userspace | ||
366 | * to see if it supports poll (Nether 'poll' or 'select' return | ||
367 | * an appropriate error code). When in doubt, set a suitable timeout value. | ||
368 | */ | ||
369 | static unsigned int sysfs_poll(struct file *filp, poll_table *wait) | ||
370 | { | ||
371 | struct sysfs_buffer * buffer = filp->private_data; | ||
372 | struct kobject * kobj = to_kobj(filp->f_dentry->d_parent); | ||
373 | struct sysfs_dirent * sd = filp->f_dentry->d_fsdata; | ||
374 | int res = 0; | ||
375 | |||
376 | poll_wait(filp, &kobj->poll, wait); | ||
377 | |||
378 | if (buffer->event != atomic_read(&sd->s_event)) { | ||
379 | res = POLLERR|POLLPRI; | ||
380 | buffer->needs_read_fill = 1; | ||
381 | } | ||
382 | |||
383 | return res; | ||
384 | } | ||
385 | |||
386 | |||
387 | static struct dentry *step_down(struct dentry *dir, const char * name) | ||
388 | { | ||
389 | struct dentry * de; | ||
390 | |||
391 | if (dir == NULL || dir->d_inode == NULL) | ||
392 | return NULL; | ||
393 | |||
394 | mutex_lock(&dir->d_inode->i_mutex); | ||
395 | de = lookup_one_len(name, dir, strlen(name)); | ||
396 | mutex_unlock(&dir->d_inode->i_mutex); | ||
397 | dput(dir); | ||
398 | if (IS_ERR(de)) | ||
399 | return NULL; | ||
400 | if (de->d_inode == NULL) { | ||
401 | dput(de); | ||
402 | return NULL; | ||
403 | } | ||
404 | return de; | ||
405 | } | ||
406 | |||
407 | void sysfs_notify(struct kobject * k, char *dir, char *attr) | ||
408 | { | ||
409 | struct dentry *de = k->dentry; | ||
410 | if (de) | ||
411 | dget(de); | ||
412 | if (de && dir) | ||
413 | de = step_down(de, dir); | ||
414 | if (de && attr) | ||
415 | de = step_down(de, attr); | ||
416 | if (de) { | ||
417 | struct sysfs_dirent * sd = de->d_fsdata; | ||
418 | if (sd) | ||
419 | atomic_inc(&sd->s_event); | ||
420 | wake_up_interruptible(&k->poll); | ||
421 | dput(de); | ||
422 | } | ||
423 | } | ||
424 | EXPORT_SYMBOL_GPL(sysfs_notify); | ||
425 | |||
351 | const struct file_operations sysfs_file_operations = { | 426 | const struct file_operations sysfs_file_operations = { |
352 | .read = sysfs_read_file, | 427 | .read = sysfs_read_file, |
353 | .write = sysfs_write_file, | 428 | .write = sysfs_write_file, |
354 | .llseek = generic_file_llseek, | 429 | .llseek = generic_file_llseek, |
355 | .open = sysfs_open_file, | 430 | .open = sysfs_open_file, |
356 | .release = sysfs_release, | 431 | .release = sysfs_release, |
432 | .poll = sysfs_poll, | ||
357 | }; | 433 | }; |
358 | 434 | ||
359 | 435 | ||
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 32958a7c50e9..3651ffb5ec09 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -11,6 +11,7 @@ extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, | |||
11 | 11 | ||
12 | extern int sysfs_add_file(struct dentry *, const struct attribute *, int); | 12 | extern int sysfs_add_file(struct dentry *, const struct attribute *, int); |
13 | extern void sysfs_hash_and_remove(struct dentry * dir, const char * name); | 13 | extern void sysfs_hash_and_remove(struct dentry * dir, const char * name); |
14 | extern struct sysfs_dirent *sysfs_find(struct sysfs_dirent *dir, const char * name); | ||
14 | 15 | ||
15 | extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **); | 16 | extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **); |
16 | extern void sysfs_remove_subdir(struct dentry *); | 17 | extern void sysfs_remove_subdir(struct dentry *); |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 269721af02f3..c847416f6d10 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -252,6 +252,7 @@ xfs_file_sendfile_invis( | |||
252 | STATIC ssize_t | 252 | STATIC ssize_t |
253 | xfs_file_splice_read( | 253 | xfs_file_splice_read( |
254 | struct file *infilp, | 254 | struct file *infilp, |
255 | loff_t *ppos, | ||
255 | struct pipe_inode_info *pipe, | 256 | struct pipe_inode_info *pipe, |
256 | size_t len, | 257 | size_t len, |
257 | unsigned int flags) | 258 | unsigned int flags) |
@@ -259,13 +260,14 @@ xfs_file_splice_read( | |||
259 | vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); | 260 | vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); |
260 | ssize_t rval; | 261 | ssize_t rval; |
261 | 262 | ||
262 | VOP_SPLICE_READ(vp, infilp, pipe, len, flags, 0, NULL, rval); | 263 | VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, 0, NULL, rval); |
263 | return rval; | 264 | return rval; |
264 | } | 265 | } |
265 | 266 | ||
266 | STATIC ssize_t | 267 | STATIC ssize_t |
267 | xfs_file_splice_read_invis( | 268 | xfs_file_splice_read_invis( |
268 | struct file *infilp, | 269 | struct file *infilp, |
270 | loff_t *ppos, | ||
269 | struct pipe_inode_info *pipe, | 271 | struct pipe_inode_info *pipe, |
270 | size_t len, | 272 | size_t len, |
271 | unsigned int flags) | 273 | unsigned int flags) |
@@ -273,7 +275,7 @@ xfs_file_splice_read_invis( | |||
273 | vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); | 275 | vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); |
274 | ssize_t rval; | 276 | ssize_t rval; |
275 | 277 | ||
276 | VOP_SPLICE_READ(vp, infilp, pipe, len, flags, IO_INVIS, NULL, rval); | 278 | VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, IO_INVIS, NULL, rval); |
277 | return rval; | 279 | return rval; |
278 | } | 280 | } |
279 | 281 | ||
@@ -281,13 +283,14 @@ STATIC ssize_t | |||
281 | xfs_file_splice_write( | 283 | xfs_file_splice_write( |
282 | struct pipe_inode_info *pipe, | 284 | struct pipe_inode_info *pipe, |
283 | struct file *outfilp, | 285 | struct file *outfilp, |
286 | loff_t *ppos, | ||
284 | size_t len, | 287 | size_t len, |
285 | unsigned int flags) | 288 | unsigned int flags) |
286 | { | 289 | { |
287 | vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); | 290 | vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); |
288 | ssize_t rval; | 291 | ssize_t rval; |
289 | 292 | ||
290 | VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, 0, NULL, rval); | 293 | VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, 0, NULL, rval); |
291 | return rval; | 294 | return rval; |
292 | } | 295 | } |
293 | 296 | ||
@@ -295,13 +298,14 @@ STATIC ssize_t | |||
295 | xfs_file_splice_write_invis( | 298 | xfs_file_splice_write_invis( |
296 | struct pipe_inode_info *pipe, | 299 | struct pipe_inode_info *pipe, |
297 | struct file *outfilp, | 300 | struct file *outfilp, |
301 | loff_t *ppos, | ||
298 | size_t len, | 302 | size_t len, |
299 | unsigned int flags) | 303 | unsigned int flags) |
300 | { | 304 | { |
301 | vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); | 305 | vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); |
302 | ssize_t rval; | 306 | ssize_t rval; |
303 | 307 | ||
304 | VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, IO_INVIS, NULL, rval); | 308 | VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, IO_INVIS, NULL, rval); |
305 | return rval; | 309 | return rval; |
306 | } | 310 | } |
307 | 311 | ||
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 74a52937f208..67efe3308980 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -338,6 +338,7 @@ ssize_t | |||
338 | xfs_splice_read( | 338 | xfs_splice_read( |
339 | bhv_desc_t *bdp, | 339 | bhv_desc_t *bdp, |
340 | struct file *infilp, | 340 | struct file *infilp, |
341 | loff_t *ppos, | ||
341 | struct pipe_inode_info *pipe, | 342 | struct pipe_inode_info *pipe, |
342 | size_t count, | 343 | size_t count, |
343 | int flags, | 344 | int flags, |
@@ -360,7 +361,7 @@ xfs_splice_read( | |||
360 | int error; | 361 | int error; |
361 | 362 | ||
362 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), | 363 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), |
363 | infilp->f_pos, count, | 364 | *ppos, count, |
364 | FILP_DELAY_FLAG(infilp), &locktype); | 365 | FILP_DELAY_FLAG(infilp), &locktype); |
365 | if (error) { | 366 | if (error) { |
366 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 367 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
@@ -368,8 +369,8 @@ xfs_splice_read( | |||
368 | } | 369 | } |
369 | } | 370 | } |
370 | xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, &ip->i_iocore, | 371 | xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, &ip->i_iocore, |
371 | pipe, count, infilp->f_pos, ioflags); | 372 | pipe, count, *ppos, ioflags); |
372 | ret = generic_file_splice_read(infilp, pipe, count, flags); | 373 | ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); |
373 | if (ret > 0) | 374 | if (ret > 0) |
374 | XFS_STATS_ADD(xs_read_bytes, ret); | 375 | XFS_STATS_ADD(xs_read_bytes, ret); |
375 | 376 | ||
@@ -382,6 +383,7 @@ xfs_splice_write( | |||
382 | bhv_desc_t *bdp, | 383 | bhv_desc_t *bdp, |
383 | struct pipe_inode_info *pipe, | 384 | struct pipe_inode_info *pipe, |
384 | struct file *outfilp, | 385 | struct file *outfilp, |
386 | loff_t *ppos, | ||
385 | size_t count, | 387 | size_t count, |
386 | int flags, | 388 | int flags, |
387 | int ioflags, | 389 | int ioflags, |
@@ -403,7 +405,7 @@ xfs_splice_write( | |||
403 | int error; | 405 | int error; |
404 | 406 | ||
405 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), | 407 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), |
406 | outfilp->f_pos, count, | 408 | *ppos, count, |
407 | FILP_DELAY_FLAG(outfilp), &locktype); | 409 | FILP_DELAY_FLAG(outfilp), &locktype); |
408 | if (error) { | 410 | if (error) { |
409 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 411 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
@@ -411,8 +413,8 @@ xfs_splice_write( | |||
411 | } | 413 | } |
412 | } | 414 | } |
413 | xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore, | 415 | xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore, |
414 | pipe, count, outfilp->f_pos, ioflags); | 416 | pipe, count, *ppos, ioflags); |
415 | ret = generic_file_splice_write(pipe, outfilp, count, flags); | 417 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); |
416 | if (ret > 0) | 418 | if (ret > 0) |
417 | XFS_STATS_ADD(xs_write_bytes, ret); | 419 | XFS_STATS_ADD(xs_write_bytes, ret); |
418 | 420 | ||
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index 55c689a86ad2..8f4539952350 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h | |||
@@ -93,11 +93,11 @@ extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *, | |||
93 | extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *, | 93 | extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *, |
94 | loff_t *, int, size_t, read_actor_t, | 94 | loff_t *, int, size_t, read_actor_t, |
95 | void *, struct cred *); | 95 | void *, struct cred *); |
96 | extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, | 96 | extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *, |
97 | struct pipe_inode_info *, size_t, int, int, | 97 | struct pipe_inode_info *, size_t, int, int, |
98 | struct cred *); | 98 | struct cred *); |
99 | extern ssize_t xfs_splice_write(struct bhv_desc *, struct pipe_inode_info *, | 99 | extern ssize_t xfs_splice_write(struct bhv_desc *, struct pipe_inode_info *, |
100 | struct file *, size_t, int, int, | 100 | struct file *, loff_t *, size_t, int, int, |
101 | struct cred *); | 101 | struct cred *); |
102 | 102 | ||
103 | #endif /* __XFS_LRW_H__ */ | 103 | #endif /* __XFS_LRW_H__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 88b09f186289..2a8e16c22353 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -173,11 +173,11 @@ typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *, | |||
173 | typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *, | 173 | typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *, |
174 | loff_t *, int, size_t, read_actor_t, | 174 | loff_t *, int, size_t, read_actor_t, |
175 | void *, struct cred *); | 175 | void *, struct cred *); |
176 | typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, | 176 | typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *, |
177 | struct pipe_inode_info *, size_t, int, int, | 177 | struct pipe_inode_info *, size_t, int, int, |
178 | struct cred *); | 178 | struct cred *); |
179 | typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *, | 179 | typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *, |
180 | struct file *, size_t, int, int, | 180 | struct file *, loff_t *, size_t, int, int, |
181 | struct cred *); | 181 | struct cred *); |
182 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, | 182 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, |
183 | int, unsigned int, void __user *); | 183 | int, unsigned int, void __user *); |
@@ -284,10 +284,10 @@ typedef struct vnodeops { | |||
284 | rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr) | 284 | rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr) |
285 | #define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \ | 285 | #define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \ |
286 | rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr) | 286 | rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr) |
287 | #define VOP_SPLICE_READ(vp,f,pipe,cnt,fl,iofl,cr,rv) \ | 287 | #define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \ |
288 | rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,pipe,cnt,fl,iofl,cr) | 288 | rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr) |
289 | #define VOP_SPLICE_WRITE(vp,f,pipe,cnt,fl,iofl,cr,rv) \ | 289 | #define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \ |
290 | rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,pipe,cnt,fl,iofl,cr) | 290 | rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr) |
291 | #define VOP_BMAP(vp,of,sz,rw,b,n,rv) \ | 291 | #define VOP_BMAP(vp,of,sz,rw,b,n,rv) \ |
292 | rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n) | 292 | rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n) |
293 | #define VOP_OPEN(vp, cr, rv) \ | 293 | #define VOP_OPEN(vp, cr, rv) \ |
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index 6a8dd83c350f..d81d6cfc1bb4 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h | |||
@@ -320,8 +320,9 @@ | |||
320 | #define __NR_get_robust_list 312 | 320 | #define __NR_get_robust_list 312 |
321 | #define __NR_splice 313 | 321 | #define __NR_splice 313 |
322 | #define __NR_sync_file_range 314 | 322 | #define __NR_sync_file_range 314 |
323 | #define __NR_tee 315 | ||
323 | 324 | ||
324 | #define NR_syscalls 315 | 325 | #define NR_syscalls 316 |
325 | 326 | ||
326 | /* | 327 | /* |
327 | * user-visible error numbers are in the range -1 - -128: see | 328 | * user-visible error numbers are in the range -1 - -128: see |
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h index 1c749acca021..a40ebec6aeeb 100644 --- a/include/asm-ia64/unistd.h +++ b/include/asm-ia64/unistd.h | |||
@@ -289,12 +289,13 @@ | |||
289 | #define __NR_set_robust_list 1298 | 289 | #define __NR_set_robust_list 1298 |
290 | #define __NR_get_robust_list 1299 | 290 | #define __NR_get_robust_list 1299 |
291 | #define __NR_sync_file_range 1300 | 291 | #define __NR_sync_file_range 1300 |
292 | #define __NR_tee 1301 | ||
292 | 293 | ||
293 | #ifdef __KERNEL__ | 294 | #ifdef __KERNEL__ |
294 | 295 | ||
295 | #include <linux/config.h> | 296 | #include <linux/config.h> |
296 | 297 | ||
297 | #define NR_syscalls 277 /* length of syscall table */ | 298 | #define NR_syscalls 278 /* length of syscall table */ |
298 | 299 | ||
299 | #define __ARCH_WANT_SYS_RT_SIGACTION | 300 | #define __ARCH_WANT_SYS_RT_SIGACTION |
300 | 301 | ||
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index 536ba0873052..c612f1a62772 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h | |||
@@ -302,8 +302,9 @@ | |||
302 | #define __NR_ppoll 281 | 302 | #define __NR_ppoll 281 |
303 | #define __NR_unshare 282 | 303 | #define __NR_unshare 282 |
304 | #define __NR_splice 283 | 304 | #define __NR_splice 283 |
305 | #define __NR_tee 284 | ||
305 | 306 | ||
306 | #define __NR_syscalls 284 | 307 | #define __NR_syscalls 285 |
307 | 308 | ||
308 | #ifdef __KERNEL__ | 309 | #ifdef __KERNEL__ |
309 | #define __NR__exit __NR_exit | 310 | #define __NR__exit __NR_exit |
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index f21ff2c1e960..d86494e23b63 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h | |||
@@ -611,8 +611,10 @@ __SYSCALL(__NR_set_robust_list, sys_set_robust_list) | |||
611 | __SYSCALL(__NR_get_robust_list, sys_get_robust_list) | 611 | __SYSCALL(__NR_get_robust_list, sys_get_robust_list) |
612 | #define __NR_splice 275 | 612 | #define __NR_splice 275 |
613 | __SYSCALL(__NR_splice, sys_splice) | 613 | __SYSCALL(__NR_splice, sys_splice) |
614 | #define __NR_tee 276 | ||
615 | __SYSCALL(__NR_tee, sys_tee) | ||
614 | 616 | ||
615 | #define __NR_syscall_max __NR_splice | 617 | #define __NR_syscall_max __NR_tee |
616 | 618 | ||
617 | #ifndef __NO_STUBS | 619 | #ifndef __NO_STUBS |
618 | 620 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 162c6e57307a..3de2bfb2410f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1039,8 +1039,8 @@ struct file_operations { | |||
1039 | int (*check_flags)(int); | 1039 | int (*check_flags)(int); |
1040 | int (*dir_notify)(struct file *filp, unsigned long arg); | 1040 | int (*dir_notify)(struct file *filp, unsigned long arg); |
1041 | int (*flock) (struct file *, int, struct file_lock *); | 1041 | int (*flock) (struct file *, int, struct file_lock *); |
1042 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int); | 1042 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); |
1043 | ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); | 1043 | ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); |
1044 | }; | 1044 | }; |
1045 | 1045 | ||
1046 | struct inode_operations { | 1046 | struct inode_operations { |
@@ -1613,13 +1613,13 @@ extern void do_generic_mapping_read(struct address_space *mapping, | |||
1613 | loff_t *, read_descriptor_t *, read_actor_t); | 1613 | loff_t *, read_descriptor_t *, read_actor_t); |
1614 | 1614 | ||
1615 | /* fs/splice.c */ | 1615 | /* fs/splice.c */ |
1616 | extern ssize_t generic_file_splice_read(struct file *, | 1616 | extern ssize_t generic_file_splice_read(struct file *, loff_t *, |
1617 | struct pipe_inode_info *, size_t, unsigned int); | 1617 | struct pipe_inode_info *, size_t, unsigned int); |
1618 | extern ssize_t generic_file_splice_write(struct pipe_inode_info *, | 1618 | extern ssize_t generic_file_splice_write(struct pipe_inode_info *, |
1619 | struct file *, size_t, unsigned int); | 1619 | struct file *, loff_t *, size_t, unsigned int); |
1620 | extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, | 1620 | extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, |
1621 | struct file *out, size_t len, unsigned int flags); | 1621 | struct file *out, loff_t *, size_t len, unsigned int flags); |
1622 | extern long do_splice_direct(struct file *in, struct file *out, | 1622 | extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, |
1623 | size_t len, unsigned int flags); | 1623 | size_t len, unsigned int flags); |
1624 | 1624 | ||
1625 | extern void | 1625 | extern void |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 10a27f29d692..2ef845b35175 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -105,6 +105,7 @@ struct gendisk { | |||
105 | * disks that can't be partitioned. */ | 105 | * disks that can't be partitioned. */ |
106 | char disk_name[32]; /* name of major driver */ | 106 | char disk_name[32]; /* name of major driver */ |
107 | struct hd_struct **part; /* [indexed by minor] */ | 107 | struct hd_struct **part; /* [indexed by minor] */ |
108 | int part_uevent_suppress; | ||
108 | struct block_device_operations *fops; | 109 | struct block_device_operations *fops; |
109 | struct request_queue *queue; | 110 | struct request_queue *queue; |
110 | void *private_data; | 111 | void *private_data; |
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 4cb1214ec290..dcd0623be892 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/rwsem.h> | 24 | #include <linux/rwsem.h> |
25 | #include <linux/kref.h> | 25 | #include <linux/kref.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/wait.h> | ||
27 | #include <asm/atomic.h> | 28 | #include <asm/atomic.h> |
28 | 29 | ||
29 | #define KOBJ_NAME_LEN 20 | 30 | #define KOBJ_NAME_LEN 20 |
@@ -56,6 +57,7 @@ struct kobject { | |||
56 | struct kset * kset; | 57 | struct kset * kset; |
57 | struct kobj_type * ktype; | 58 | struct kobj_type * ktype; |
58 | struct dentry * dentry; | 59 | struct dentry * dentry; |
60 | wait_queue_head_t poll; | ||
59 | }; | 61 | }; |
60 | 62 | ||
61 | extern int kobject_set_name(struct kobject *, const char *, ...) | 63 | extern int kobject_set_name(struct kobject *, const char *, ...) |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 0aad5a378e95..3a6a4e37a482 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -97,7 +97,13 @@ enum pci_channel_state { | |||
97 | 97 | ||
98 | typedef unsigned short __bitwise pci_bus_flags_t; | 98 | typedef unsigned short __bitwise pci_bus_flags_t; |
99 | enum pci_bus_flags { | 99 | enum pci_bus_flags { |
100 | PCI_BUS_FLAGS_NO_MSI = (pci_bus_flags_t) 1, | 100 | PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, |
101 | }; | ||
102 | |||
103 | struct pci_cap_saved_state { | ||
104 | struct hlist_node next; | ||
105 | char cap_nr; | ||
106 | u32 data[0]; | ||
101 | }; | 107 | }; |
102 | 108 | ||
103 | /* | 109 | /* |
@@ -159,6 +165,7 @@ struct pci_dev { | |||
159 | unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ | 165 | unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ |
160 | 166 | ||
161 | u32 saved_config_space[16]; /* config space saved at suspend time */ | 167 | u32 saved_config_space[16]; /* config space saved at suspend time */ |
168 | struct hlist_head saved_cap_space; | ||
162 | struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ | 169 | struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ |
163 | int rom_attr_enabled; /* has display of the rom attribute been enabled? */ | 170 | int rom_attr_enabled; /* has display of the rom attribute been enabled? */ |
164 | struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ | 171 | struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ |
@@ -169,6 +176,30 @@ struct pci_dev { | |||
169 | #define to_pci_dev(n) container_of(n, struct pci_dev, dev) | 176 | #define to_pci_dev(n) container_of(n, struct pci_dev, dev) |
170 | #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) | 177 | #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) |
171 | 178 | ||
179 | static inline struct pci_cap_saved_state *pci_find_saved_cap( | ||
180 | struct pci_dev *pci_dev,char cap) | ||
181 | { | ||
182 | struct pci_cap_saved_state *tmp; | ||
183 | struct hlist_node *pos; | ||
184 | |||
185 | hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) { | ||
186 | if (tmp->cap_nr == cap) | ||
187 | return tmp; | ||
188 | } | ||
189 | return NULL; | ||
190 | } | ||
191 | |||
192 | static inline void pci_add_saved_cap(struct pci_dev *pci_dev, | ||
193 | struct pci_cap_saved_state *new_cap) | ||
194 | { | ||
195 | hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); | ||
196 | } | ||
197 | |||
198 | static inline void pci_remove_saved_cap(struct pci_cap_saved_state *cap) | ||
199 | { | ||
200 | hlist_del(&cap->next); | ||
201 | } | ||
202 | |||
172 | /* | 203 | /* |
173 | * For PCI devices, the region numbers are assigned this way: | 204 | * For PCI devices, the region numbers are assigned this way: |
174 | * | 205 | * |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 870fe38378b1..8d03e10212f5 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -497,7 +497,8 @@ | |||
497 | #define PCI_DEVICE_ID_AMD_8111_SMBUS 0x746b | 497 | #define PCI_DEVICE_ID_AMD_8111_SMBUS 0x746b |
498 | #define PCI_DEVICE_ID_AMD_8111_AUDIO 0x746d | 498 | #define PCI_DEVICE_ID_AMD_8111_AUDIO 0x746d |
499 | #define PCI_DEVICE_ID_AMD_8151_0 0x7454 | 499 | #define PCI_DEVICE_ID_AMD_8151_0 0x7454 |
500 | #define PCI_DEVICE_ID_AMD_8131_APIC 0x7450 | 500 | #define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450 |
501 | #define PCI_DEVICE_ID_AMD_8131_APIC 0x7451 | ||
501 | #define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090 | 502 | #define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090 |
502 | #define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091 | 503 | #define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091 |
503 | #define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093 | 504 | #define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093 |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 123a7c24bc72..ef7f33c0be19 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
@@ -21,6 +21,7 @@ struct pipe_buf_operations { | |||
21 | void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *); | 21 | void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *); |
22 | void (*release)(struct pipe_inode_info *, struct pipe_buffer *); | 22 | void (*release)(struct pipe_inode_info *, struct pipe_buffer *); |
23 | int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); | 23 | int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); |
24 | void (*get)(struct pipe_inode_info *, struct pipe_buffer *); | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | struct pipe_inode_info { | 27 | struct pipe_inode_info { |
diff --git a/include/linux/pm.h b/include/linux/pm.h index 6df2585c0169..66be58902b17 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -199,6 +199,12 @@ extern int device_suspend(pm_message_t state); | |||
199 | 199 | ||
200 | extern int dpm_runtime_suspend(struct device *, pm_message_t); | 200 | extern int dpm_runtime_suspend(struct device *, pm_message_t); |
201 | extern void dpm_runtime_resume(struct device *); | 201 | extern void dpm_runtime_resume(struct device *); |
202 | extern void __suspend_report_result(const char *function, void *fn, int ret); | ||
203 | |||
204 | #define suspend_report_result(fn, ret) \ | ||
205 | do { \ | ||
206 | __suspend_report_result(__FUNCTION__, fn, ret); \ | ||
207 | } while (0) | ||
202 | 208 | ||
203 | #else /* !CONFIG_PM */ | 209 | #else /* !CONFIG_PM */ |
204 | 210 | ||
@@ -219,6 +225,8 @@ static inline void dpm_runtime_resume(struct device * dev) | |||
219 | { | 225 | { |
220 | } | 226 | } |
221 | 227 | ||
228 | #define suspend_report_result(fn, ret) do { } while (0) | ||
229 | |||
222 | #endif | 230 | #endif |
223 | 231 | ||
224 | /* changes to device_may_wakeup take effect on the next pm state change. | 232 | /* changes to device_may_wakeup take effect on the next pm state change. |
diff --git a/include/linux/pm_legacy.h b/include/linux/pm_legacy.h index 1252b45face1..008932d73c35 100644 --- a/include/linux/pm_legacy.h +++ b/include/linux/pm_legacy.h | |||
@@ -16,11 +16,6 @@ struct pm_dev __deprecated * | |||
16 | pm_register(pm_dev_t type, unsigned long id, pm_callback callback); | 16 | pm_register(pm_dev_t type, unsigned long id, pm_callback callback); |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Unregister a device with power management | ||
20 | */ | ||
21 | void __deprecated pm_unregister(struct pm_dev *dev); | ||
22 | |||
23 | /* | ||
24 | * Unregister all devices with matching callback | 19 | * Unregister all devices with matching callback |
25 | */ | 20 | */ |
26 | void __deprecated pm_unregister_all(pm_callback callback); | 21 | void __deprecated pm_unregister_all(pm_callback callback); |
@@ -41,8 +36,6 @@ static inline struct pm_dev *pm_register(pm_dev_t type, | |||
41 | return NULL; | 36 | return NULL; |
42 | } | 37 | } |
43 | 38 | ||
44 | static inline void pm_unregister(struct pm_dev *dev) {} | ||
45 | |||
46 | static inline void pm_unregister_all(pm_callback callback) {} | 39 | static inline void pm_unregister_all(pm_callback callback) {} |
47 | 40 | ||
48 | static inline int pm_send_all(pm_request_t rqst, void *data) | 41 | static inline int pm_send_all(pm_request_t rqst, void *data) |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index f001bad28d9a..d3ebc0e68b2b 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -574,6 +574,8 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, | |||
574 | int fd_out, loff_t __user *off_out, | 574 | int fd_out, loff_t __user *off_out, |
575 | size_t len, unsigned int flags); | 575 | size_t len, unsigned int flags); |
576 | 576 | ||
577 | asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); | ||
578 | |||
577 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, | 579 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, |
578 | unsigned int flags); | 580 | unsigned int flags); |
579 | 581 | ||
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 392da5a6dacb..1ea5d3cda6ae 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -74,6 +74,7 @@ struct sysfs_dirent { | |||
74 | umode_t s_mode; | 74 | umode_t s_mode; |
75 | struct dentry * s_dentry; | 75 | struct dentry * s_dentry; |
76 | struct iattr * s_iattr; | 76 | struct iattr * s_iattr; |
77 | atomic_t s_event; | ||
77 | }; | 78 | }; |
78 | 79 | ||
79 | #define SYSFS_ROOT 0x0001 | 80 | #define SYSFS_ROOT 0x0001 |
@@ -117,6 +118,7 @@ int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr); | |||
117 | 118 | ||
118 | int sysfs_create_group(struct kobject *, const struct attribute_group *); | 119 | int sysfs_create_group(struct kobject *, const struct attribute_group *); |
119 | void sysfs_remove_group(struct kobject *, const struct attribute_group *); | 120 | void sysfs_remove_group(struct kobject *, const struct attribute_group *); |
121 | void sysfs_notify(struct kobject * k, char *dir, char *attr); | ||
120 | 122 | ||
121 | #else /* CONFIG_SYSFS */ | 123 | #else /* CONFIG_SYSFS */ |
122 | 124 | ||
@@ -185,6 +187,10 @@ static inline void sysfs_remove_group(struct kobject * k, const struct attribute | |||
185 | ; | 187 | ; |
186 | } | 188 | } |
187 | 189 | ||
190 | static inline void sysfs_notify(struct kobject * k, char *dir, char *attr) | ||
191 | { | ||
192 | } | ||
193 | |||
188 | #endif /* CONFIG_SYSFS */ | 194 | #endif /* CONFIG_SYSFS */ |
189 | 195 | ||
190 | #endif /* _SYSFS_H_ */ | 196 | #endif /* _SYSFS_H_ */ |
diff --git a/include/linux/usb/net2280.h b/include/linux/usb/net2280.h new file mode 100644 index 000000000000..c602f884f182 --- /dev/null +++ b/include/linux/usb/net2280.h | |||
@@ -0,0 +1,444 @@ | |||
1 | /* | ||
2 | * NetChip 2280 high/full speed USB device controller. | ||
3 | * Unlike many such controllers, this one talks PCI. | ||
4 | */ | ||
5 | #ifndef __LINUX_USB_NET2280_H | ||
6 | #define __LINUX_USB_NET2280_H | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) | ||
10 | * Copyright (C) 2003 David Brownell | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | */ | ||
26 | |||
27 | /*-------------------------------------------------------------------------*/ | ||
28 | |||
29 | /* NET2280 MEMORY MAPPED REGISTERS | ||
30 | * | ||
31 | * The register layout came from the chip documentation, and the bit | ||
32 | * number definitions were extracted from chip specification. | ||
33 | * | ||
34 | * Use the shift operator ('<<') to build bit masks, with readl/writel | ||
35 | * to access the registers through PCI. | ||
36 | */ | ||
37 | |||
38 | /* main registers, BAR0 + 0x0000 */ | ||
39 | struct net2280_regs { | ||
40 | // offset 0x0000 | ||
41 | u32 devinit; | ||
42 | #define LOCAL_CLOCK_FREQUENCY 8 | ||
43 | #define FORCE_PCI_RESET 7 | ||
44 | #define PCI_ID 6 | ||
45 | #define PCI_ENABLE 5 | ||
46 | #define FIFO_SOFT_RESET 4 | ||
47 | #define CFG_SOFT_RESET 3 | ||
48 | #define PCI_SOFT_RESET 2 | ||
49 | #define USB_SOFT_RESET 1 | ||
50 | #define M8051_RESET 0 | ||
51 | u32 eectl; | ||
52 | #define EEPROM_ADDRESS_WIDTH 23 | ||
53 | #define EEPROM_CHIP_SELECT_ACTIVE 22 | ||
54 | #define EEPROM_PRESENT 21 | ||
55 | #define EEPROM_VALID 20 | ||
56 | #define EEPROM_BUSY 19 | ||
57 | #define EEPROM_CHIP_SELECT_ENABLE 18 | ||
58 | #define EEPROM_BYTE_READ_START 17 | ||
59 | #define EEPROM_BYTE_WRITE_START 16 | ||
60 | #define EEPROM_READ_DATA 8 | ||
61 | #define EEPROM_WRITE_DATA 0 | ||
62 | u32 eeclkfreq; | ||
63 | u32 _unused0; | ||
64 | // offset 0x0010 | ||
65 | |||
66 | u32 pciirqenb0; /* interrupt PCI master ... */ | ||
67 | #define SETUP_PACKET_INTERRUPT_ENABLE 7 | ||
68 | #define ENDPOINT_F_INTERRUPT_ENABLE 6 | ||
69 | #define ENDPOINT_E_INTERRUPT_ENABLE 5 | ||
70 | #define ENDPOINT_D_INTERRUPT_ENABLE 4 | ||
71 | #define ENDPOINT_C_INTERRUPT_ENABLE 3 | ||
72 | #define ENDPOINT_B_INTERRUPT_ENABLE 2 | ||
73 | #define ENDPOINT_A_INTERRUPT_ENABLE 1 | ||
74 | #define ENDPOINT_0_INTERRUPT_ENABLE 0 | ||
75 | u32 pciirqenb1; | ||
76 | #define PCI_INTERRUPT_ENABLE 31 | ||
77 | #define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 | ||
78 | #define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 | ||
79 | #define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 | ||
80 | #define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 | ||
81 | #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 | ||
82 | #define PCI_TARGET_ABORT_ASSERTED_INTERRUPT_ENABLE 18 | ||
83 | #define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 | ||
84 | #define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 | ||
85 | #define GPIO_INTERRUPT_ENABLE 13 | ||
86 | #define DMA_D_INTERRUPT_ENABLE 12 | ||
87 | #define DMA_C_INTERRUPT_ENABLE 11 | ||
88 | #define DMA_B_INTERRUPT_ENABLE 10 | ||
89 | #define DMA_A_INTERRUPT_ENABLE 9 | ||
90 | #define EEPROM_DONE_INTERRUPT_ENABLE 8 | ||
91 | #define VBUS_INTERRUPT_ENABLE 7 | ||
92 | #define CONTROL_STATUS_INTERRUPT_ENABLE 6 | ||
93 | #define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 | ||
94 | #define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 | ||
95 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 | ||
96 | #define RESUME_INTERRUPT_ENABLE 1 | ||
97 | #define SOF_INTERRUPT_ENABLE 0 | ||
98 | u32 cpu_irqenb0; /* ... or onboard 8051 */ | ||
99 | #define SETUP_PACKET_INTERRUPT_ENABLE 7 | ||
100 | #define ENDPOINT_F_INTERRUPT_ENABLE 6 | ||
101 | #define ENDPOINT_E_INTERRUPT_ENABLE 5 | ||
102 | #define ENDPOINT_D_INTERRUPT_ENABLE 4 | ||
103 | #define ENDPOINT_C_INTERRUPT_ENABLE 3 | ||
104 | #define ENDPOINT_B_INTERRUPT_ENABLE 2 | ||
105 | #define ENDPOINT_A_INTERRUPT_ENABLE 1 | ||
106 | #define ENDPOINT_0_INTERRUPT_ENABLE 0 | ||
107 | u32 cpu_irqenb1; | ||
108 | #define CPU_INTERRUPT_ENABLE 31 | ||
109 | #define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 | ||
110 | #define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 | ||
111 | #define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 | ||
112 | #define PCI_INTA_INTERRUPT_ENABLE 24 | ||
113 | #define PCI_PME_INTERRUPT_ENABLE 23 | ||
114 | #define PCI_SERR_INTERRUPT_ENABLE 22 | ||
115 | #define PCI_PERR_INTERRUPT_ENABLE 21 | ||
116 | #define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 | ||
117 | #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 | ||
118 | #define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 | ||
119 | #define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 | ||
120 | #define GPIO_INTERRUPT_ENABLE 13 | ||
121 | #define DMA_D_INTERRUPT_ENABLE 12 | ||
122 | #define DMA_C_INTERRUPT_ENABLE 11 | ||
123 | #define DMA_B_INTERRUPT_ENABLE 10 | ||
124 | #define DMA_A_INTERRUPT_ENABLE 9 | ||
125 | #define EEPROM_DONE_INTERRUPT_ENABLE 8 | ||
126 | #define VBUS_INTERRUPT_ENABLE 7 | ||
127 | #define CONTROL_STATUS_INTERRUPT_ENABLE 6 | ||
128 | #define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 | ||
129 | #define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 | ||
130 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 | ||
131 | #define RESUME_INTERRUPT_ENABLE 1 | ||
132 | #define SOF_INTERRUPT_ENABLE 0 | ||
133 | |||
134 | // offset 0x0020 | ||
135 | u32 _unused1; | ||
136 | u32 usbirqenb1; | ||
137 | #define USB_INTERRUPT_ENABLE 31 | ||
138 | #define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 | ||
139 | #define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 | ||
140 | #define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 | ||
141 | #define PCI_INTA_INTERRUPT_ENABLE 24 | ||
142 | #define PCI_PME_INTERRUPT_ENABLE 23 | ||
143 | #define PCI_SERR_INTERRUPT_ENABLE 22 | ||
144 | #define PCI_PERR_INTERRUPT_ENABLE 21 | ||
145 | #define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 | ||
146 | #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 | ||
147 | #define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 | ||
148 | #define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 | ||
149 | #define GPIO_INTERRUPT_ENABLE 13 | ||
150 | #define DMA_D_INTERRUPT_ENABLE 12 | ||
151 | #define DMA_C_INTERRUPT_ENABLE 11 | ||
152 | #define DMA_B_INTERRUPT_ENABLE 10 | ||
153 | #define DMA_A_INTERRUPT_ENABLE 9 | ||
154 | #define EEPROM_DONE_INTERRUPT_ENABLE 8 | ||
155 | #define VBUS_INTERRUPT_ENABLE 7 | ||
156 | #define CONTROL_STATUS_INTERRUPT_ENABLE 6 | ||
157 | #define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 | ||
158 | #define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 | ||
159 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 | ||
160 | #define RESUME_INTERRUPT_ENABLE 1 | ||
161 | #define SOF_INTERRUPT_ENABLE 0 | ||
162 | u32 irqstat0; | ||
163 | #define INTA_ASSERTED 12 | ||
164 | #define SETUP_PACKET_INTERRUPT 7 | ||
165 | #define ENDPOINT_F_INTERRUPT 6 | ||
166 | #define ENDPOINT_E_INTERRUPT 5 | ||
167 | #define ENDPOINT_D_INTERRUPT 4 | ||
168 | #define ENDPOINT_C_INTERRUPT 3 | ||
169 | #define ENDPOINT_B_INTERRUPT 2 | ||
170 | #define ENDPOINT_A_INTERRUPT 1 | ||
171 | #define ENDPOINT_0_INTERRUPT 0 | ||
172 | u32 irqstat1; | ||
173 | #define POWER_STATE_CHANGE_INTERRUPT 27 | ||
174 | #define PCI_ARBITER_TIMEOUT_INTERRUPT 26 | ||
175 | #define PCI_PARITY_ERROR_INTERRUPT 25 | ||
176 | #define PCI_INTA_INTERRUPT 24 | ||
177 | #define PCI_PME_INTERRUPT 23 | ||
178 | #define PCI_SERR_INTERRUPT 22 | ||
179 | #define PCI_PERR_INTERRUPT 21 | ||
180 | #define PCI_MASTER_ABORT_RECEIVED_INTERRUPT 20 | ||
181 | #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19 | ||
182 | #define PCI_RETRY_ABORT_INTERRUPT 17 | ||
183 | #define PCI_MASTER_CYCLE_DONE_INTERRUPT 16 | ||
184 | #define SOF_DOWN_INTERRUPT 14 | ||
185 | #define GPIO_INTERRUPT 13 | ||
186 | #define DMA_D_INTERRUPT 12 | ||
187 | #define DMA_C_INTERRUPT 11 | ||
188 | #define DMA_B_INTERRUPT 10 | ||
189 | #define DMA_A_INTERRUPT 9 | ||
190 | #define EEPROM_DONE_INTERRUPT 8 | ||
191 | #define VBUS_INTERRUPT 7 | ||
192 | #define CONTROL_STATUS_INTERRUPT 6 | ||
193 | #define ROOT_PORT_RESET_INTERRUPT 4 | ||
194 | #define SUSPEND_REQUEST_INTERRUPT 3 | ||
195 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT 2 | ||
196 | #define RESUME_INTERRUPT 1 | ||
197 | #define SOF_INTERRUPT 0 | ||
198 | // offset 0x0030 | ||
199 | u32 idxaddr; | ||
200 | u32 idxdata; | ||
201 | u32 fifoctl; | ||
202 | #define PCI_BASE2_RANGE 16 | ||
203 | #define IGNORE_FIFO_AVAILABILITY 3 | ||
204 | #define PCI_BASE2_SELECT 2 | ||
205 | #define FIFO_CONFIGURATION_SELECT 0 | ||
206 | u32 _unused2; | ||
207 | // offset 0x0040 | ||
208 | u32 memaddr; | ||
209 | #define START 28 | ||
210 | #define DIRECTION 27 | ||
211 | #define FIFO_DIAGNOSTIC_SELECT 24 | ||
212 | #define MEMORY_ADDRESS 0 | ||
213 | u32 memdata0; | ||
214 | u32 memdata1; | ||
215 | u32 _unused3; | ||
216 | // offset 0x0050 | ||
217 | u32 gpioctl; | ||
218 | #define GPIO3_LED_SELECT 12 | ||
219 | #define GPIO3_INTERRUPT_ENABLE 11 | ||
220 | #define GPIO2_INTERRUPT_ENABLE 10 | ||
221 | #define GPIO1_INTERRUPT_ENABLE 9 | ||
222 | #define GPIO0_INTERRUPT_ENABLE 8 | ||
223 | #define GPIO3_OUTPUT_ENABLE 7 | ||
224 | #define GPIO2_OUTPUT_ENABLE 6 | ||
225 | #define GPIO1_OUTPUT_ENABLE 5 | ||
226 | #define GPIO0_OUTPUT_ENABLE 4 | ||
227 | #define GPIO3_DATA 3 | ||
228 | #define GPIO2_DATA 2 | ||
229 | #define GPIO1_DATA 1 | ||
230 | #define GPIO0_DATA 0 | ||
231 | u32 gpiostat; | ||
232 | #define GPIO3_INTERRUPT 3 | ||
233 | #define GPIO2_INTERRUPT 2 | ||
234 | #define GPIO1_INTERRUPT 1 | ||
235 | #define GPIO0_INTERRUPT 0 | ||
236 | } __attribute__ ((packed)); | ||
237 | |||
238 | /* usb control, BAR0 + 0x0080 */ | ||
239 | struct net2280_usb_regs { | ||
240 | // offset 0x0080 | ||
241 | u32 stdrsp; | ||
242 | #define STALL_UNSUPPORTED_REQUESTS 31 | ||
243 | #define SET_TEST_MODE 16 | ||
244 | #define GET_OTHER_SPEED_CONFIGURATION 15 | ||
245 | #define GET_DEVICE_QUALIFIER 14 | ||
246 | #define SET_ADDRESS 13 | ||
247 | #define ENDPOINT_SET_CLEAR_HALT 12 | ||
248 | #define DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP 11 | ||
249 | #define GET_STRING_DESCRIPTOR_2 10 | ||
250 | #define GET_STRING_DESCRIPTOR_1 9 | ||
251 | #define GET_STRING_DESCRIPTOR_0 8 | ||
252 | #define GET_SET_INTERFACE 6 | ||
253 | #define GET_SET_CONFIGURATION 5 | ||
254 | #define GET_CONFIGURATION_DESCRIPTOR 4 | ||
255 | #define GET_DEVICE_DESCRIPTOR 3 | ||
256 | #define GET_ENDPOINT_STATUS 2 | ||
257 | #define GET_INTERFACE_STATUS 1 | ||
258 | #define GET_DEVICE_STATUS 0 | ||
259 | u32 prodvendid; | ||
260 | #define PRODUCT_ID 16 | ||
261 | #define VENDOR_ID 0 | ||
262 | u32 relnum; | ||
263 | u32 usbctl; | ||
264 | #define SERIAL_NUMBER_INDEX 16 | ||
265 | #define PRODUCT_ID_STRING_ENABLE 13 | ||
266 | #define VENDOR_ID_STRING_ENABLE 12 | ||
267 | #define USB_ROOT_PORT_WAKEUP_ENABLE 11 | ||
268 | #define VBUS_PIN 10 | ||
269 | #define TIMED_DISCONNECT 9 | ||
270 | #define SUSPEND_IMMEDIATELY 7 | ||
271 | #define SELF_POWERED_USB_DEVICE 6 | ||
272 | #define REMOTE_WAKEUP_SUPPORT 5 | ||
273 | #define PME_POLARITY 4 | ||
274 | #define USB_DETECT_ENABLE 3 | ||
275 | #define PME_WAKEUP_ENABLE 2 | ||
276 | #define DEVICE_REMOTE_WAKEUP_ENABLE 1 | ||
277 | #define SELF_POWERED_STATUS 0 | ||
278 | // offset 0x0090 | ||
279 | u32 usbstat; | ||
280 | #define HIGH_SPEED 7 | ||
281 | #define FULL_SPEED 6 | ||
282 | #define GENERATE_RESUME 5 | ||
283 | #define GENERATE_DEVICE_REMOTE_WAKEUP 4 | ||
284 | u32 xcvrdiag; | ||
285 | #define FORCE_HIGH_SPEED_MODE 31 | ||
286 | #define FORCE_FULL_SPEED_MODE 30 | ||
287 | #define USB_TEST_MODE 24 | ||
288 | #define LINE_STATE 16 | ||
289 | #define TRANSCEIVER_OPERATION_MODE 2 | ||
290 | #define TRANSCEIVER_SELECT 1 | ||
291 | #define TERMINATION_SELECT 0 | ||
292 | u32 setup0123; | ||
293 | u32 setup4567; | ||
294 | // offset 0x0090 | ||
295 | u32 _unused0; | ||
296 | u32 ouraddr; | ||
297 | #define FORCE_IMMEDIATE 7 | ||
298 | #define OUR_USB_ADDRESS 0 | ||
299 | u32 ourconfig; | ||
300 | } __attribute__ ((packed)); | ||
301 | |||
302 | /* pci control, BAR0 + 0x0100 */ | ||
303 | struct net2280_pci_regs { | ||
304 | // offset 0x0100 | ||
305 | u32 pcimstctl; | ||
306 | #define PCI_ARBITER_PARK_SELECT 13 | ||
307 | #define PCI_MULTI LEVEL_ARBITER 12 | ||
308 | #define PCI_RETRY_ABORT_ENABLE 11 | ||
309 | #define DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE 10 | ||
310 | #define DMA_READ_MULTIPLE_ENABLE 9 | ||
311 | #define DMA_READ_LINE_ENABLE 8 | ||
312 | #define PCI_MASTER_COMMAND_SELECT 6 | ||
313 | #define MEM_READ_OR_WRITE 0 | ||
314 | #define IO_READ_OR_WRITE 1 | ||
315 | #define CFG_READ_OR_WRITE 2 | ||
316 | #define PCI_MASTER_START 5 | ||
317 | #define PCI_MASTER_READ_WRITE 4 | ||
318 | #define PCI_MASTER_WRITE 0 | ||
319 | #define PCI_MASTER_READ 1 | ||
320 | #define PCI_MASTER_BYTE_WRITE_ENABLES 0 | ||
321 | u32 pcimstaddr; | ||
322 | u32 pcimstdata; | ||
323 | u32 pcimststat; | ||
324 | #define PCI_ARBITER_CLEAR 2 | ||
325 | #define PCI_EXTERNAL_ARBITER 1 | ||
326 | #define PCI_HOST_MODE 0 | ||
327 | } __attribute__ ((packed)); | ||
328 | |||
329 | /* dma control, BAR0 + 0x0180 ... array of four structs like this, | ||
330 | * for channels 0..3. see also struct net2280_dma: descriptor | ||
331 | * that can be loaded into some of these registers. | ||
332 | */ | ||
333 | struct net2280_dma_regs { /* [11.7] */ | ||
334 | // offset 0x0180, 0x01a0, 0x01c0, 0x01e0, | ||
335 | u32 dmactl; | ||
336 | #define DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE 25 | ||
337 | #define DMA_CLEAR_COUNT_ENABLE 21 | ||
338 | #define DESCRIPTOR_POLLING_RATE 19 | ||
339 | #define POLL_CONTINUOUS 0 | ||
340 | #define POLL_1_USEC 1 | ||
341 | #define POLL_100_USEC 2 | ||
342 | #define POLL_1_MSEC 3 | ||
343 | #define DMA_VALID_BIT_POLLING_ENABLE 18 | ||
344 | #define DMA_VALID_BIT_ENABLE 17 | ||
345 | #define DMA_SCATTER_GATHER_ENABLE 16 | ||
346 | #define DMA_OUT_AUTO_START_ENABLE 4 | ||
347 | #define DMA_PREEMPT_ENABLE 3 | ||
348 | #define DMA_FIFO_VALIDATE 2 | ||
349 | #define DMA_ENABLE 1 | ||
350 | #define DMA_ADDRESS_HOLD 0 | ||
351 | u32 dmastat; | ||
352 | #define DMA_ABORT_DONE_INTERRUPT 27 | ||
353 | #define DMA_SCATTER_GATHER_DONE_INTERRUPT 25 | ||
354 | #define DMA_TRANSACTION_DONE_INTERRUPT 24 | ||
355 | #define DMA_ABORT 1 | ||
356 | #define DMA_START 0 | ||
357 | u32 _unused0 [2]; | ||
358 | // offset 0x0190, 0x01b0, 0x01d0, 0x01f0, | ||
359 | u32 dmacount; | ||
360 | #define VALID_BIT 31 | ||
361 | #define DMA_DIRECTION 30 | ||
362 | #define DMA_DONE_INTERRUPT_ENABLE 29 | ||
363 | #define END_OF_CHAIN 28 | ||
364 | #define DMA_BYTE_COUNT_MASK ((1<<24)-1) | ||
365 | #define DMA_BYTE_COUNT 0 | ||
366 | u32 dmaaddr; | ||
367 | u32 dmadesc; | ||
368 | u32 _unused1; | ||
369 | } __attribute__ ((packed)); | ||
370 | |||
371 | /* dedicated endpoint registers, BAR0 + 0x0200 */ | ||
372 | |||
373 | struct net2280_dep_regs { /* [11.8] */ | ||
374 | // offset 0x0200, 0x0210, 0x220, 0x230, 0x240 | ||
375 | u32 dep_cfg; | ||
376 | // offset 0x0204, 0x0214, 0x224, 0x234, 0x244 | ||
377 | u32 dep_rsp; | ||
378 | u32 _unused [2]; | ||
379 | } __attribute__ ((packed)); | ||
380 | |||
381 | /* configurable endpoint registers, BAR0 + 0x0300 ... array of seven structs | ||
382 | * like this, for ep0 then the configurable endpoints A..F | ||
383 | * ep0 reserved for control; E and F have only 64 bytes of fifo | ||
384 | */ | ||
385 | struct net2280_ep_regs { /* [11.9] */ | ||
386 | // offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0 | ||
387 | u32 ep_cfg; | ||
388 | #define ENDPOINT_BYTE_COUNT 16 | ||
389 | #define ENDPOINT_ENABLE 10 | ||
390 | #define ENDPOINT_TYPE 8 | ||
391 | #define ENDPOINT_DIRECTION 7 | ||
392 | #define ENDPOINT_NUMBER 0 | ||
393 | u32 ep_rsp; | ||
394 | #define SET_NAK_OUT_PACKETS 15 | ||
395 | #define SET_EP_HIDE_STATUS_PHASE 14 | ||
396 | #define SET_EP_FORCE_CRC_ERROR 13 | ||
397 | #define SET_INTERRUPT_MODE 12 | ||
398 | #define SET_CONTROL_STATUS_PHASE_HANDSHAKE 11 | ||
399 | #define SET_NAK_OUT_PACKETS_MODE 10 | ||
400 | #define SET_ENDPOINT_TOGGLE 9 | ||
401 | #define SET_ENDPOINT_HALT 8 | ||
402 | #define CLEAR_NAK_OUT_PACKETS 7 | ||
403 | #define CLEAR_EP_HIDE_STATUS_PHASE 6 | ||
404 | #define CLEAR_EP_FORCE_CRC_ERROR 5 | ||
405 | #define CLEAR_INTERRUPT_MODE 4 | ||
406 | #define CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE 3 | ||
407 | #define CLEAR_NAK_OUT_PACKETS_MODE 2 | ||
408 | #define CLEAR_ENDPOINT_TOGGLE 1 | ||
409 | #define CLEAR_ENDPOINT_HALT 0 | ||
410 | u32 ep_irqenb; | ||
411 | #define SHORT_PACKET_OUT_DONE_INTERRUPT_ENABLE 6 | ||
412 | #define SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE 5 | ||
413 | #define DATA_PACKET_RECEIVED_INTERRUPT_ENABLE 3 | ||
414 | #define DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE 2 | ||
415 | #define DATA_OUT_PING_TOKEN_INTERRUPT_ENABLE 1 | ||
416 | #define DATA_IN_TOKEN_INTERRUPT_ENABLE 0 | ||
417 | u32 ep_stat; | ||
418 | #define FIFO_VALID_COUNT 24 | ||
419 | #define HIGH_BANDWIDTH_OUT_TRANSACTION_PID 22 | ||
420 | #define TIMEOUT 21 | ||
421 | #define USB_STALL_SENT 20 | ||
422 | #define USB_IN_NAK_SENT 19 | ||
423 | #define USB_IN_ACK_RCVD 18 | ||
424 | #define USB_OUT_PING_NAK_SENT 17 | ||
425 | #define USB_OUT_ACK_SENT 16 | ||
426 | #define FIFO_OVERFLOW 13 | ||
427 | #define FIFO_UNDERFLOW 12 | ||
428 | #define FIFO_FULL 11 | ||
429 | #define FIFO_EMPTY 10 | ||
430 | #define FIFO_FLUSH 9 | ||
431 | #define SHORT_PACKET_OUT_DONE_INTERRUPT 6 | ||
432 | #define SHORT_PACKET_TRANSFERRED_INTERRUPT 5 | ||
433 | #define NAK_OUT_PACKETS 4 | ||
434 | #define DATA_PACKET_RECEIVED_INTERRUPT 3 | ||
435 | #define DATA_PACKET_TRANSMITTED_INTERRUPT 2 | ||
436 | #define DATA_OUT_PING_TOKEN_INTERRUPT 1 | ||
437 | #define DATA_IN_TOKEN_INTERRUPT 0 | ||
438 | // offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0 | ||
439 | u32 ep_avail; | ||
440 | u32 ep_data; | ||
441 | u32 _unused0 [2]; | ||
442 | } __attribute__ ((packed)); | ||
443 | |||
444 | #endif /* __LINUX_USB_NET2280_H */ | ||
diff --git a/kernel/power/pm.c b/kernel/power/pm.c index 0f6908cce1dd..84063ac8fcfc 100644 --- a/kernel/power/pm.c +++ b/kernel/power/pm.c | |||
@@ -75,25 +75,6 @@ struct pm_dev *pm_register(pm_dev_t type, | |||
75 | return dev; | 75 | return dev; |
76 | } | 76 | } |
77 | 77 | ||
78 | /** | ||
79 | * pm_unregister - unregister a device with power management | ||
80 | * @dev: device to unregister | ||
81 | * | ||
82 | * Remove a device from the power management notification lists. The | ||
83 | * dev passed must be a handle previously returned by pm_register. | ||
84 | */ | ||
85 | |||
86 | void pm_unregister(struct pm_dev *dev) | ||
87 | { | ||
88 | if (dev) { | ||
89 | mutex_lock(&pm_devs_lock); | ||
90 | list_del(&dev->entry); | ||
91 | mutex_unlock(&pm_devs_lock); | ||
92 | |||
93 | kfree(dev); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | static void __pm_unregister(struct pm_dev *dev) | 78 | static void __pm_unregister(struct pm_dev *dev) |
98 | { | 79 | { |
99 | if (dev) { | 80 | if (dev) { |
@@ -258,7 +239,6 @@ int pm_send_all(pm_request_t rqst, void *data) | |||
258 | } | 239 | } |
259 | 240 | ||
260 | EXPORT_SYMBOL(pm_register); | 241 | EXPORT_SYMBOL(pm_register); |
261 | EXPORT_SYMBOL(pm_unregister); | ||
262 | EXPORT_SYMBOL(pm_unregister_all); | 242 | EXPORT_SYMBOL(pm_unregister_all); |
263 | EXPORT_SYMBOL(pm_send_all); | 243 | EXPORT_SYMBOL(pm_send_all); |
264 | EXPORT_SYMBOL(pm_active); | 244 | EXPORT_SYMBOL(pm_active); |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 0eeb7e66722c..4e0f0ec003f7 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -56,10 +56,6 @@ void ptrace_untrace(task_t *child) | |||
56 | signal_wake_up(child, 1); | 56 | signal_wake_up(child, 1); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | if (child->signal->flags & SIGNAL_GROUP_EXIT) { | ||
60 | sigaddset(&child->pending.signal, SIGKILL); | ||
61 | signal_wake_up(child, 1); | ||
62 | } | ||
63 | spin_unlock(&child->sighand->siglock); | 59 | spin_unlock(&child->sighand->siglock); |
64 | } | 60 | } |
65 | 61 | ||
@@ -81,7 +77,8 @@ void __ptrace_unlink(task_t *child) | |||
81 | add_parent(child); | 77 | add_parent(child); |
82 | } | 78 | } |
83 | 79 | ||
84 | ptrace_untrace(child); | 80 | if (child->state == TASK_TRACED) |
81 | ptrace_untrace(child); | ||
85 | } | 82 | } |
86 | 83 | ||
87 | /* | 84 | /* |
diff --git a/kernel/signal.c b/kernel/signal.c index b14f895027c3..e5f8aea78ffe 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1754,9 +1754,9 @@ relock: | |||
1754 | /* Let the debugger run. */ | 1754 | /* Let the debugger run. */ |
1755 | ptrace_stop(signr, signr, info); | 1755 | ptrace_stop(signr, signr, info); |
1756 | 1756 | ||
1757 | /* We're back. Did the debugger cancel the sig or group_exit? */ | 1757 | /* We're back. Did the debugger cancel the sig? */ |
1758 | signr = current->exit_code; | 1758 | signr = current->exit_code; |
1759 | if (signr == 0 || current->signal->flags & SIGNAL_GROUP_EXIT) | 1759 | if (signr == 0) |
1760 | continue; | 1760 | continue; |
1761 | 1761 | ||
1762 | current->exit_code = 0; | 1762 | current->exit_code = 0; |
diff --git a/lib/kobject.c b/lib/kobject.c index 25204a41a9b0..01d957513940 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -128,6 +128,7 @@ void kobject_init(struct kobject * kobj) | |||
128 | { | 128 | { |
129 | kref_init(&kobj->kref); | 129 | kref_init(&kobj->kref); |
130 | INIT_LIST_HEAD(&kobj->entry); | 130 | INIT_LIST_HEAD(&kobj->entry); |
131 | init_waitqueue_head(&kobj->poll); | ||
131 | kobj->kset = kset_get(kobj->kset); | 132 | kobj->kset = kset_get(kobj->kset); |
132 | } | 133 | } |
133 | 134 | ||
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index db07ae73e051..be0200e9cdaf 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c | |||
@@ -196,8 +196,8 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
196 | 196 | ||
197 | print_buttons(dialog, height, width, 0); | 197 | print_buttons(dialog, height, width, 0); |
198 | 198 | ||
199 | wnoutrefresh(list); | ||
200 | wnoutrefresh(dialog); | 199 | wnoutrefresh(dialog); |
200 | wnoutrefresh(list); | ||
201 | doupdate(); | 201 | doupdate(); |
202 | 202 | ||
203 | while (key != ESC) { | 203 | while (key != ESC) { |
@@ -225,12 +225,11 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
225 | } | 225 | } |
226 | scroll--; | 226 | scroll--; |
227 | print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE); | 227 | print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE); |
228 | wnoutrefresh(list); | ||
229 | |||
230 | print_arrows(dialog, choice, item_no, | 228 | print_arrows(dialog, choice, item_no, |
231 | scroll, box_y, box_x + check_x + 5, list_height); | 229 | scroll, box_y, box_x + check_x + 5, list_height); |
232 | 230 | ||
233 | wrefresh(dialog); | 231 | wnoutrefresh(dialog); |
232 | wrefresh(list); | ||
234 | 233 | ||
235 | continue; /* wait for another key press */ | 234 | continue; /* wait for another key press */ |
236 | } else | 235 | } else |
@@ -252,12 +251,12 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
252 | scroll++; | 251 | scroll++; |
253 | print_item(list, items[(scroll + max_choice - 1) * 3 + 1], | 252 | print_item(list, items[(scroll + max_choice - 1) * 3 + 1], |
254 | status[scroll + max_choice - 1], max_choice - 1, TRUE); | 253 | status[scroll + max_choice - 1], max_choice - 1, TRUE); |
255 | wnoutrefresh(list); | ||
256 | 254 | ||
257 | print_arrows(dialog, choice, item_no, | 255 | print_arrows(dialog, choice, item_no, |
258 | scroll, box_y, box_x + check_x + 5, list_height); | 256 | scroll, box_y, box_x + check_x + 5, list_height); |
259 | 257 | ||
260 | wrefresh(dialog); | 258 | wnoutrefresh(dialog); |
259 | wrefresh(list); | ||
261 | 260 | ||
262 | continue; /* wait for another key press */ | 261 | continue; /* wait for another key press */ |
263 | } else | 262 | } else |
@@ -271,8 +270,8 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
271 | choice = i; | 270 | choice = i; |
272 | print_item(list, items[(scroll + choice) * 3 + 1], | 271 | print_item(list, items[(scroll + choice) * 3 + 1], |
273 | status[scroll + choice], choice, TRUE); | 272 | status[scroll + choice], choice, TRUE); |
274 | wnoutrefresh(list); | 273 | wnoutrefresh(dialog); |
275 | wrefresh(dialog); | 274 | wrefresh(list); |
276 | } | 275 | } |
277 | continue; /* wait for another key press */ | 276 | continue; /* wait for another key press */ |
278 | } | 277 | } |
@@ -306,8 +305,8 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
306 | print_item(list, items[(scroll + i) * 3 + 1], | 305 | print_item(list, items[(scroll + i) * 3 + 1], |
307 | status[scroll + i], i, i == choice); | 306 | status[scroll + i], i, i == choice); |
308 | } | 307 | } |
309 | wnoutrefresh(list); | 308 | wnoutrefresh(dialog); |
310 | wrefresh(dialog); | 309 | wrefresh(list); |
311 | 310 | ||
312 | for (i = 0; i < item_no; i++) | 311 | for (i = 0; i < item_no; i++) |
313 | if (status[i]) | 312 | if (status[i]) |