diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-11-18 11:44:17 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-11-18 11:44:17 -0500 |
commit | f333b3f111e9db76109e304df8ee777ace7fbf86 (patch) | |
tree | ce9a74a7327020c48c80d278e1db5f12552f0fb0 /drivers | |
parent | f4256e301d9800b1e0276404cb01b3ac85b51067 (diff) | |
parent | 79bfb0a98fdc73ed6a18469cef245cbf50a1d8bb (diff) |
Merge branch 'upstream'
Diffstat (limited to 'drivers')
199 files changed, 10444 insertions, 6006 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 6a4da417c16b..606f8733a776 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/list.h> | 28 | #include <linux/list.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/pm.h> | 30 | #include <linux/pm.h> |
31 | #include <linux/pm_legacy.h> | ||
31 | #include <linux/device.h> | 32 | #include <linux/device.h> |
32 | #include <linux/proc_fs.h> | 33 | #include <linux/proc_fs.h> |
33 | #ifdef CONFIG_X86 | 34 | #ifdef CONFIG_X86 |
@@ -754,7 +755,7 @@ static int __init acpi_init(void) | |||
754 | result = acpi_bus_init(); | 755 | result = acpi_bus_init(); |
755 | 756 | ||
756 | if (!result) { | 757 | if (!result) { |
757 | #ifdef CONFIG_PM | 758 | #ifdef CONFIG_PM_LEGACY |
758 | if (!PM_IS_ACTIVE()) | 759 | if (!PM_IS_ACTIVE()) |
759 | pm_active = 1; | 760 | pm_active = 1; |
760 | else { | 761 | else { |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 573b6a97bb1f..70d8a6ec0920 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -514,8 +514,6 @@ static int acpi_processor_set_power_policy(struct acpi_processor *pr) | |||
514 | 514 | ||
515 | static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | 515 | static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) |
516 | { | 516 | { |
517 | int i; | ||
518 | |||
519 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_fadt"); | 517 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_fadt"); |
520 | 518 | ||
521 | if (!pr) | 519 | if (!pr) |
@@ -524,8 +522,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | |||
524 | if (!pr->pblk) | 522 | if (!pr->pblk) |
525 | return_VALUE(-ENODEV); | 523 | return_VALUE(-ENODEV); |
526 | 524 | ||
527 | for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) | 525 | memset(pr->power.states, 0, sizeof(pr->power.states)); |
528 | memset(pr->power.states, 0, sizeof(struct acpi_processor_cx)); | ||
529 | 526 | ||
530 | /* if info is obtained from pblk/fadt, type equals state */ | 527 | /* if info is obtained from pblk/fadt, type equals state */ |
531 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | 528 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; |
@@ -555,13 +552,9 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | |||
555 | 552 | ||
556 | static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) | 553 | static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) |
557 | { | 554 | { |
558 | int i; | ||
559 | |||
560 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); | 555 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); |
561 | 556 | ||
562 | for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) | 557 | memset(pr->power.states, 0, sizeof(pr->power.states)); |
563 | memset(&(pr->power.states[i]), 0, | ||
564 | sizeof(struct acpi_processor_cx)); | ||
565 | 558 | ||
566 | /* if info is obtained from pblk/fadt, type equals state */ | 559 | /* if info is obtained from pblk/fadt, type equals state */ |
567 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | 560 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; |
@@ -873,7 +866,8 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
873 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { | 866 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { |
874 | if (pr->power.states[i].valid) { | 867 | if (pr->power.states[i].valid) { |
875 | pr->power.count = i; | 868 | pr->power.count = i; |
876 | pr->flags.power = 1; | 869 | if (pr->power.states[i].type >= ACPI_STATE_C2) |
870 | pr->flags.power = 1; | ||
877 | } | 871 | } |
878 | } | 872 | } |
879 | 873 | ||
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 98f6c02d6790..59dacb6552c0 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -526,18 +526,23 @@ request_firmware_work_func(void *arg) | |||
526 | { | 526 | { |
527 | struct firmware_work *fw_work = arg; | 527 | struct firmware_work *fw_work = arg; |
528 | const struct firmware *fw; | 528 | const struct firmware *fw; |
529 | int ret; | ||
529 | if (!arg) { | 530 | if (!arg) { |
530 | WARN_ON(1); | 531 | WARN_ON(1); |
531 | return 0; | 532 | return 0; |
532 | } | 533 | } |
533 | daemonize("%s/%s", "firmware", fw_work->name); | 534 | daemonize("%s/%s", "firmware", fw_work->name); |
534 | _request_firmware(&fw, fw_work->name, fw_work->device, | 535 | ret = _request_firmware(&fw, fw_work->name, fw_work->device, |
535 | fw_work->hotplug); | 536 | fw_work->hotplug); |
536 | fw_work->cont(fw, fw_work->context); | 537 | if (ret < 0) |
537 | release_firmware(fw); | 538 | fw_work->cont(NULL, fw_work->context); |
539 | else { | ||
540 | fw_work->cont(fw, fw_work->context); | ||
541 | release_firmware(fw); | ||
542 | } | ||
538 | module_put(fw_work->module); | 543 | module_put(fw_work->module); |
539 | kfree(fw_work); | 544 | kfree(fw_work); |
540 | return 0; | 545 | return ret; |
541 | } | 546 | } |
542 | 547 | ||
543 | /** | 548 | /** |
@@ -586,6 +591,8 @@ request_firmware_nowait( | |||
586 | 591 | ||
587 | if (ret < 0) { | 592 | if (ret < 0) { |
588 | fw_work->cont(NULL, fw_work->context); | 593 | fw_work->cont(NULL, fw_work->context); |
594 | module_put(fw_work->module); | ||
595 | kfree(fw_work); | ||
589 | return ret; | 596 | return ret; |
590 | } | 597 | } |
591 | return 0; | 598 | return 0; |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 3226aa11c6ef..2942d32280a5 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -255,7 +255,7 @@ scsi_cmd_stack_free(int ctlr) | |||
255 | #define DEVICETYPE(n) (n<0 || n>MAX_SCSI_DEVICE_CODE) ? \ | 255 | #define DEVICETYPE(n) (n<0 || n>MAX_SCSI_DEVICE_CODE) ? \ |
256 | "Unknown" : scsi_device_types[n] | 256 | "Unknown" : scsi_device_types[n] |
257 | 257 | ||
258 | #if 1 | 258 | #if 0 |
259 | static int xmargin=8; | 259 | static int xmargin=8; |
260 | static int amargin=60; | 260 | static int amargin=60; |
261 | 261 | ||
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 59e5982a5db3..c0233efabeba 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -1188,7 +1188,7 @@ static void pkt_count_states(struct pktcdvd_device *pd, int *states) | |||
1188 | struct packet_data *pkt; | 1188 | struct packet_data *pkt; |
1189 | int i; | 1189 | int i; |
1190 | 1190 | ||
1191 | for (i = 0; i <= PACKET_NUM_STATES; i++) | 1191 | for (i = 0; i < PACKET_NUM_STATES; i++) |
1192 | states[i] = 0; | 1192 | states[i] = 0; |
1193 | 1193 | ||
1194 | spin_lock(&pd->cdrw.active_list_lock); | 1194 | spin_lock(&pd->cdrw.active_list_lock); |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index fdf4370db994..970f70d498f4 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -735,7 +735,7 @@ config SGI_IP27_RTC | |||
735 | 735 | ||
736 | config GEN_RTC | 736 | config GEN_RTC |
737 | tristate "Generic /dev/rtc emulation" | 737 | tristate "Generic /dev/rtc emulation" |
738 | depends on RTC!=y && !IA64 && !ARM && !PPC64 && !M32R && !SPARC32 && !SPARC64 | 738 | depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC32 && !SPARC64 |
739 | ---help--- | 739 | ---help--- |
740 | If you say Y here and create a character special file /dev/rtc with | 740 | If you say Y here and create a character special file /dev/rtc with |
741 | major number 10 and minor number 135 using mknod ("man mknod"), you | 741 | major number 10 and minor number 135 using mknod ("man mknod"), you |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 78ce98a69f37..76589782adcb 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -57,9 +57,8 @@ static int nr_garts; | |||
57 | static struct pci_dev * hammers[MAX_HAMMER_GARTS]; | 57 | static struct pci_dev * hammers[MAX_HAMMER_GARTS]; |
58 | 58 | ||
59 | static struct resource *aperture_resource; | 59 | static struct resource *aperture_resource; |
60 | static int __initdata agp_try_unsupported; | 60 | static int __initdata agp_try_unsupported = 1; |
61 | 61 | ||
62 | static int gart_iterator; | ||
63 | #define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++) | 62 | #define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++) |
64 | 63 | ||
65 | static void flush_amd64_tlb(struct pci_dev *dev) | 64 | static void flush_amd64_tlb(struct pci_dev *dev) |
@@ -73,6 +72,7 @@ static void flush_amd64_tlb(struct pci_dev *dev) | |||
73 | 72 | ||
74 | static void amd64_tlbflush(struct agp_memory *temp) | 73 | static void amd64_tlbflush(struct agp_memory *temp) |
75 | { | 74 | { |
75 | int gart_iterator; | ||
76 | for_each_nb() | 76 | for_each_nb() |
77 | flush_amd64_tlb(hammers[gart_iterator]); | 77 | flush_amd64_tlb(hammers[gart_iterator]); |
78 | } | 78 | } |
@@ -222,6 +222,7 @@ static struct aper_size_info_32 amd_8151_sizes[7] = | |||
222 | static int amd_8151_configure(void) | 222 | static int amd_8151_configure(void) |
223 | { | 223 | { |
224 | unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); | 224 | unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); |
225 | int gart_iterator; | ||
225 | 226 | ||
226 | /* Configure AGP regs in each x86-64 host bridge. */ | 227 | /* Configure AGP regs in each x86-64 host bridge. */ |
227 | for_each_nb() { | 228 | for_each_nb() { |
@@ -235,7 +236,7 @@ static int amd_8151_configure(void) | |||
235 | static void amd64_cleanup(void) | 236 | static void amd64_cleanup(void) |
236 | { | 237 | { |
237 | u32 tmp; | 238 | u32 tmp; |
238 | 239 | int gart_iterator; | |
239 | for_each_nb() { | 240 | for_each_nb() { |
240 | /* disable gart translation */ | 241 | /* disable gart translation */ |
241 | pci_read_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, &tmp); | 242 | pci_read_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, &tmp); |
@@ -697,6 +698,16 @@ static struct pci_device_id agp_amd64_pci_table[] = { | |||
697 | .subvendor = PCI_ANY_ID, | 698 | .subvendor = PCI_ANY_ID, |
698 | .subdevice = PCI_ANY_ID, | 699 | .subdevice = PCI_ANY_ID, |
699 | }, | 700 | }, |
701 | /* ALI/ULI M1695 */ | ||
702 | { | ||
703 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
704 | .class_mask = ~0, | ||
705 | .vendor = PCI_VENDOR_ID_AL, | ||
706 | .device = 0x1689, | ||
707 | .subvendor = PCI_ANY_ID, | ||
708 | .subdevice = PCI_ANY_ID, | ||
709 | }, | ||
710 | |||
700 | { } | 711 | { } |
701 | }; | 712 | }; |
702 | 713 | ||
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index c8255312b8c1..50947e38501a 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
@@ -557,6 +557,10 @@ static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = { | |||
557 | .device_id = PCI_DEVICE_ID_APPLE_U3H_AGP, | 557 | .device_id = PCI_DEVICE_ID_APPLE_U3H_AGP, |
558 | .chipset_name = "U3H", | 558 | .chipset_name = "U3H", |
559 | }, | 559 | }, |
560 | { | ||
561 | .device_id = PCI_DEVICE_ID_APPLE_IPID2_AGP, | ||
562 | .chipset_name = "UniNorth/Intrepid2", | ||
563 | }, | ||
560 | }; | 564 | }; |
561 | 565 | ||
562 | static int __devinit agp_uninorth_probe(struct pci_dev *pdev, | 566 | static int __devinit agp_uninorth_probe(struct pci_dev *pdev, |
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 6c4b3f986d0c..f3c3aaf4560e 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -99,7 +99,9 @@ struct smm_regs { | |||
99 | 99 | ||
100 | static inline char *i8k_get_dmi_data(int field) | 100 | static inline char *i8k_get_dmi_data(int field) |
101 | { | 101 | { |
102 | return dmi_get_system_info(field) ? : "N/A"; | 102 | char *dmi_data = dmi_get_system_info(field); |
103 | |||
104 | return dmi_data && *dmi_data ? dmi_data : "?"; | ||
103 | } | 105 | } |
104 | 106 | ||
105 | /* | 107 | /* |
@@ -396,7 +398,7 @@ static int i8k_proc_show(struct seq_file *seq, void *offset) | |||
396 | return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n", | 398 | return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n", |
397 | I8K_PROC_FMT, | 399 | I8K_PROC_FMT, |
398 | bios_version, | 400 | bios_version, |
399 | dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A", | 401 | i8k_get_dmi_data(DMI_PRODUCT_SERIAL), |
400 | cpu_temp, | 402 | cpu_temp, |
401 | left_fan, right_fan, left_speed, right_speed, | 403 | left_fan, right_fan, left_speed, right_speed, |
402 | ac_power, fn_key); | 404 | ac_power, fn_key); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index d16bd4b5c117..6b302a930e5f 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define PFX "IPMI message handler: " | 49 | #define PFX "IPMI message handler: " |
50 | 50 | ||
51 | #define IPMI_DRIVER_VERSION "36.0" | 51 | #define IPMI_DRIVER_VERSION "38.0" |
52 | 52 | ||
53 | static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); | 53 | static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); |
54 | static int ipmi_init_msghandler(void); | 54 | static int ipmi_init_msghandler(void); |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index ea89dca3dbb5..01a1f6badb53 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -2203,7 +2203,7 @@ static void setup_xaction_handlers(struct smi_info *smi_info) | |||
2203 | 2203 | ||
2204 | static inline void wait_for_timer_and_thread(struct smi_info *smi_info) | 2204 | static inline void wait_for_timer_and_thread(struct smi_info *smi_info) |
2205 | { | 2205 | { |
2206 | if (smi_info->thread != ERR_PTR(-ENOMEM)) | 2206 | if (smi_info->thread != NULL && smi_info->thread != ERR_PTR(-ENOMEM)) |
2207 | kthread_stop(smi_info->thread); | 2207 | kthread_stop(smi_info->thread); |
2208 | del_timer_sync(&smi_info->si_timer); | 2208 | del_timer_sync(&smi_info->si_timer); |
2209 | } | 2209 | } |
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig index d22bfdc13563..27c1179ee527 100644 --- a/drivers/char/pcmcia/Kconfig +++ b/drivers/char/pcmcia/Kconfig | |||
@@ -18,5 +18,29 @@ config SYNCLINK_CS | |||
18 | The module will be called synclinkmp. If you want to do that, say M | 18 | The module will be called synclinkmp. If you want to do that, say M |
19 | here. | 19 | here. |
20 | 20 | ||
21 | config CARDMAN_4000 | ||
22 | tristate "Omnikey Cardman 4000 support" | ||
23 | depends on PCMCIA | ||
24 | help | ||
25 | Enable support for the Omnikey Cardman 4000 PCMCIA Smartcard | ||
26 | reader. | ||
27 | |||
28 | This kernel driver requires additional userspace support, either | ||
29 | by the vendor-provided PC/SC ifd_handler (http://www.omnikey.com/), | ||
30 | or via the cm4000 backend of OpenCT (http://www.opensc.com/). | ||
31 | |||
32 | config CARDMAN_4040 | ||
33 | tristate "Omnikey CardMan 4040 support" | ||
34 | depends on PCMCIA | ||
35 | help | ||
36 | Enable support for the Omnikey CardMan 4040 PCMCIA Smartcard | ||
37 | reader. | ||
38 | |||
39 | This card is basically a USB CCID device connected to a FIFO | ||
40 | in I/O space. To use the kernel driver, you will need either the | ||
41 | PC/SC ifdhandler provided from the Omnikey homepage | ||
42 | (http://www.omnikey.com/), or a current development version of OpenCT | ||
43 | (http://www.opensc.org/). | ||
44 | |||
21 | endmenu | 45 | endmenu |
22 | 46 | ||
diff --git a/drivers/char/pcmcia/Makefile b/drivers/char/pcmcia/Makefile index 1fcd4c591958..0aae20985d57 100644 --- a/drivers/char/pcmcia/Makefile +++ b/drivers/char/pcmcia/Makefile | |||
@@ -5,3 +5,5 @@ | |||
5 | # | 5 | # |
6 | 6 | ||
7 | obj-$(CONFIG_SYNCLINK_CS) += synclink_cs.o | 7 | obj-$(CONFIG_SYNCLINK_CS) += synclink_cs.o |
8 | obj-$(CONFIG_CARDMAN_4000) += cm4000_cs.o | ||
9 | obj-$(CONFIG_CARDMAN_4040) += cm4040_cs.o | ||
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c new file mode 100644 index 000000000000..ef011ef5dc46 --- /dev/null +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -0,0 +1,2078 @@ | |||
1 | /* | ||
2 | * A driver for the PCMCIA Smartcard Reader "Omnikey CardMan Mobile 4000" | ||
3 | * | ||
4 | * cm4000_cs.c support.linux@omnikey.com | ||
5 | * | ||
6 | * Tue Oct 23 11:32:43 GMT 2001 herp - cleaned up header files | ||
7 | * Sun Jan 20 10:11:15 MET 2002 herp - added modversion header files | ||
8 | * Thu Nov 14 16:34:11 GMT 2002 mh - added PPS functionality | ||
9 | * Tue Nov 19 16:36:27 GMT 2002 mh - added SUSPEND/RESUME functionailty | ||
10 | * Wed Jul 28 12:55:01 CEST 2004 mh - kernel 2.6 adjustments | ||
11 | * | ||
12 | * current version: 2.4.0gm4 | ||
13 | * | ||
14 | * (C) 2000,2001,2002,2003,2004 Omnikey AG | ||
15 | * | ||
16 | * (C) 2005 Harald Welte <laforge@gnumonks.org> | ||
17 | * - Adhere to Kernel CodingStyle | ||
18 | * - Port to 2.6.13 "new" style PCMCIA | ||
19 | * - Check for copy_{from,to}_user return values | ||
20 | * - Use nonseekable_open() | ||
21 | * | ||
22 | * All rights reserved. Licensed under dual BSD/GPL license. | ||
23 | */ | ||
24 | |||
25 | /* #define PCMCIA_DEBUG 6 */ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/fs.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <asm/uaccess.h> | ||
34 | #include <asm/io.h> | ||
35 | |||
36 | #include <pcmcia/cs_types.h> | ||
37 | #include <pcmcia/cs.h> | ||
38 | #include <pcmcia/cistpl.h> | ||
39 | #include <pcmcia/cisreg.h> | ||
40 | #include <pcmcia/ciscode.h> | ||
41 | #include <pcmcia/ds.h> | ||
42 | |||
43 | #include <linux/cm4000_cs.h> | ||
44 | |||
45 | /* #define ATR_CSUM */ | ||
46 | |||
47 | #ifdef PCMCIA_DEBUG | ||
48 | #define reader_to_dev(x) (&handle_to_dev(x->link.handle)) | ||
49 | static int pc_debug = PCMCIA_DEBUG; | ||
50 | module_param(pc_debug, int, 0600); | ||
51 | #define DEBUGP(n, rdr, x, args...) do { \ | ||
52 | if (pc_debug >= (n)) \ | ||
53 | dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ | ||
54 | __FUNCTION__ , ## args); \ | ||
55 | } while (0) | ||
56 | #else | ||
57 | #define DEBUGP(n, rdr, x, args...) | ||
58 | #endif | ||
59 | static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte"; | ||
60 | |||
61 | #define T_1SEC (HZ) | ||
62 | #define T_10MSEC msecs_to_jiffies(10) | ||
63 | #define T_20MSEC msecs_to_jiffies(20) | ||
64 | #define T_40MSEC msecs_to_jiffies(40) | ||
65 | #define T_50MSEC msecs_to_jiffies(50) | ||
66 | #define T_100MSEC msecs_to_jiffies(100) | ||
67 | #define T_500MSEC msecs_to_jiffies(500) | ||
68 | |||
69 | static void cm4000_detach(dev_link_t *link); | ||
70 | static void cm4000_release(dev_link_t *link); | ||
71 | |||
72 | static int major; /* major number we get from the kernel */ | ||
73 | |||
74 | /* note: the first state has to have number 0 always */ | ||
75 | |||
76 | #define M_FETCH_ATR 0 | ||
77 | #define M_TIMEOUT_WAIT 1 | ||
78 | #define M_READ_ATR_LEN 2 | ||
79 | #define M_READ_ATR 3 | ||
80 | #define M_ATR_PRESENT 4 | ||
81 | #define M_BAD_CARD 5 | ||
82 | #define M_CARDOFF 6 | ||
83 | |||
84 | #define LOCK_IO 0 | ||
85 | #define LOCK_MONITOR 1 | ||
86 | |||
87 | #define IS_AUTOPPS_ACT 6 | ||
88 | #define IS_PROCBYTE_PRESENT 7 | ||
89 | #define IS_INVREV 8 | ||
90 | #define IS_ANY_T0 9 | ||
91 | #define IS_ANY_T1 10 | ||
92 | #define IS_ATR_PRESENT 11 | ||
93 | #define IS_ATR_VALID 12 | ||
94 | #define IS_CMM_ABSENT 13 | ||
95 | #define IS_BAD_LENGTH 14 | ||
96 | #define IS_BAD_CSUM 15 | ||
97 | #define IS_BAD_CARD 16 | ||
98 | |||
99 | #define REG_FLAGS0(x) (x + 0) | ||
100 | #define REG_FLAGS1(x) (x + 1) | ||
101 | #define REG_NUM_BYTES(x) (x + 2) | ||
102 | #define REG_BUF_ADDR(x) (x + 3) | ||
103 | #define REG_BUF_DATA(x) (x + 4) | ||
104 | #define REG_NUM_SEND(x) (x + 5) | ||
105 | #define REG_BAUDRATE(x) (x + 6) | ||
106 | #define REG_STOPBITS(x) (x + 7) | ||
107 | |||
108 | struct cm4000_dev { | ||
109 | dev_link_t link; /* pcmcia link */ | ||
110 | dev_node_t node; /* OS node (major,minor) */ | ||
111 | |||
112 | unsigned char atr[MAX_ATR]; | ||
113 | unsigned char rbuf[512]; | ||
114 | unsigned char sbuf[512]; | ||
115 | |||
116 | wait_queue_head_t devq; /* when removing cardman must not be | ||
117 | zeroed! */ | ||
118 | |||
119 | wait_queue_head_t ioq; /* if IO is locked, wait on this Q */ | ||
120 | wait_queue_head_t atrq; /* wait for ATR valid */ | ||
121 | wait_queue_head_t readq; /* used by write to wake blk.read */ | ||
122 | |||
123 | /* warning: do not move this fields. | ||
124 | * initialising to zero depends on it - see ZERO_DEV below. */ | ||
125 | unsigned char atr_csum; | ||
126 | unsigned char atr_len_retry; | ||
127 | unsigned short atr_len; | ||
128 | unsigned short rlen; /* bytes avail. after write */ | ||
129 | unsigned short rpos; /* latest read pos. write zeroes */ | ||
130 | unsigned char procbyte; /* T=0 procedure byte */ | ||
131 | unsigned char mstate; /* state of card monitor */ | ||
132 | unsigned char cwarn; /* slow down warning */ | ||
133 | unsigned char flags0; /* cardman IO-flags 0 */ | ||
134 | unsigned char flags1; /* cardman IO-flags 1 */ | ||
135 | unsigned int mdelay; /* variable monitor speeds, in jiffies */ | ||
136 | |||
137 | unsigned int baudv; /* baud value for speed */ | ||
138 | unsigned char ta1; | ||
139 | unsigned char proto; /* T=0, T=1, ... */ | ||
140 | unsigned long flags; /* lock+flags (MONITOR,IO,ATR) * for concurrent | ||
141 | access */ | ||
142 | |||
143 | unsigned char pts[4]; | ||
144 | |||
145 | struct timer_list timer; /* used to keep monitor running */ | ||
146 | int monitor_running; | ||
147 | }; | ||
148 | |||
149 | #define ZERO_DEV(dev) \ | ||
150 | memset(&dev->atr_csum,0, \ | ||
151 | sizeof(struct cm4000_dev) - \ | ||
152 | /*link*/ sizeof(dev_link_t) - \ | ||
153 | /*node*/ sizeof(dev_node_t) - \ | ||
154 | /*atr*/ MAX_ATR*sizeof(char) - \ | ||
155 | /*rbuf*/ 512*sizeof(char) - \ | ||
156 | /*sbuf*/ 512*sizeof(char) - \ | ||
157 | /*queue*/ 4*sizeof(wait_queue_head_t)) | ||
158 | |||
159 | static dev_info_t dev_info = MODULE_NAME; | ||
160 | static dev_link_t *dev_table[CM4000_MAX_DEV]; | ||
161 | |||
162 | /* This table doesn't use spaces after the comma between fields and thus | ||
163 | * violates CodingStyle. However, I don't really think wrapping it around will | ||
164 | * make it any clearer to read -HW */ | ||
165 | static unsigned char fi_di_table[10][14] = { | ||
166 | /*FI 00 01 02 03 04 05 06 07 08 09 10 11 12 13 */ | ||
167 | /*DI */ | ||
168 | /* 0 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, | ||
169 | /* 1 */ {0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x91,0x11,0x11,0x11,0x11}, | ||
170 | /* 2 */ {0x02,0x12,0x22,0x32,0x11,0x11,0x11,0x11,0x11,0x92,0xA2,0xB2,0x11,0x11}, | ||
171 | /* 3 */ {0x03,0x13,0x23,0x33,0x43,0x53,0x63,0x11,0x11,0x93,0xA3,0xB3,0xC3,0xD3}, | ||
172 | /* 4 */ {0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x11,0x11,0x94,0xA4,0xB4,0xC4,0xD4}, | ||
173 | /* 5 */ {0x00,0x15,0x25,0x35,0x45,0x55,0x65,0x11,0x11,0x95,0xA5,0xB5,0xC5,0xD5}, | ||
174 | /* 6 */ {0x06,0x16,0x26,0x36,0x46,0x56,0x66,0x11,0x11,0x96,0xA6,0xB6,0xC6,0xD6}, | ||
175 | /* 7 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, | ||
176 | /* 8 */ {0x08,0x11,0x28,0x38,0x48,0x58,0x68,0x11,0x11,0x98,0xA8,0xB8,0xC8,0xD8}, | ||
177 | /* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9} | ||
178 | }; | ||
179 | |||
180 | #ifndef PCMCIA_DEBUG | ||
181 | #define xoutb outb | ||
182 | #define xinb inb | ||
183 | #else | ||
184 | static inline void xoutb(unsigned char val, unsigned short port) | ||
185 | { | ||
186 | if (pc_debug >= 7) | ||
187 | printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port); | ||
188 | outb(val, port); | ||
189 | } | ||
190 | static inline unsigned char xinb(unsigned short port) | ||
191 | { | ||
192 | unsigned char val; | ||
193 | |||
194 | val = inb(port); | ||
195 | if (pc_debug >= 7) | ||
196 | printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port); | ||
197 | |||
198 | return val; | ||
199 | } | ||
200 | #endif | ||
201 | |||
202 | #define b_0000 15 | ||
203 | #define b_0001 14 | ||
204 | #define b_0010 13 | ||
205 | #define b_0011 12 | ||
206 | #define b_0100 11 | ||
207 | #define b_0101 10 | ||
208 | #define b_0110 9 | ||
209 | #define b_0111 8 | ||
210 | #define b_1000 7 | ||
211 | #define b_1001 6 | ||
212 | #define b_1010 5 | ||
213 | #define b_1011 4 | ||
214 | #define b_1100 3 | ||
215 | #define b_1101 2 | ||
216 | #define b_1110 1 | ||
217 | #define b_1111 0 | ||
218 | |||
219 | static unsigned char irtab[16] = { | ||
220 | b_0000, b_1000, b_0100, b_1100, | ||
221 | b_0010, b_1010, b_0110, b_1110, | ||
222 | b_0001, b_1001, b_0101, b_1101, | ||
223 | b_0011, b_1011, b_0111, b_1111 | ||
224 | }; | ||
225 | |||
226 | static void str_invert_revert(unsigned char *b, int len) | ||
227 | { | ||
228 | int i; | ||
229 | |||
230 | for (i = 0; i < len; i++) | ||
231 | b[i] = (irtab[b[i] & 0x0f] << 4) | irtab[b[i] >> 4]; | ||
232 | } | ||
233 | |||
234 | static unsigned char invert_revert(unsigned char ch) | ||
235 | { | ||
236 | return (irtab[ch & 0x0f] << 4) | irtab[ch >> 4]; | ||
237 | } | ||
238 | |||
239 | #define ATRLENCK(dev,pos) \ | ||
240 | if (pos>=dev->atr_len || pos>=MAX_ATR) \ | ||
241 | goto return_0; | ||
242 | |||
243 | static unsigned int calc_baudv(unsigned char fidi) | ||
244 | { | ||
245 | unsigned int wcrcf, wbrcf, fi_rfu, di_rfu; | ||
246 | |||
247 | fi_rfu = 372; | ||
248 | di_rfu = 1; | ||
249 | |||
250 | /* FI */ | ||
251 | switch ((fidi >> 4) & 0x0F) { | ||
252 | case 0x00: | ||
253 | wcrcf = 372; | ||
254 | break; | ||
255 | case 0x01: | ||
256 | wcrcf = 372; | ||
257 | break; | ||
258 | case 0x02: | ||
259 | wcrcf = 558; | ||
260 | break; | ||
261 | case 0x03: | ||
262 | wcrcf = 744; | ||
263 | break; | ||
264 | case 0x04: | ||
265 | wcrcf = 1116; | ||
266 | break; | ||
267 | case 0x05: | ||
268 | wcrcf = 1488; | ||
269 | break; | ||
270 | case 0x06: | ||
271 | wcrcf = 1860; | ||
272 | break; | ||
273 | case 0x07: | ||
274 | wcrcf = fi_rfu; | ||
275 | break; | ||
276 | case 0x08: | ||
277 | wcrcf = fi_rfu; | ||
278 | break; | ||
279 | case 0x09: | ||
280 | wcrcf = 512; | ||
281 | break; | ||
282 | case 0x0A: | ||
283 | wcrcf = 768; | ||
284 | break; | ||
285 | case 0x0B: | ||
286 | wcrcf = 1024; | ||
287 | break; | ||
288 | case 0x0C: | ||
289 | wcrcf = 1536; | ||
290 | break; | ||
291 | case 0x0D: | ||
292 | wcrcf = 2048; | ||
293 | break; | ||
294 | default: | ||
295 | wcrcf = fi_rfu; | ||
296 | break; | ||
297 | } | ||
298 | |||
299 | /* DI */ | ||
300 | switch (fidi & 0x0F) { | ||
301 | case 0x00: | ||
302 | wbrcf = di_rfu; | ||
303 | break; | ||
304 | case 0x01: | ||
305 | wbrcf = 1; | ||
306 | break; | ||
307 | case 0x02: | ||
308 | wbrcf = 2; | ||
309 | break; | ||
310 | case 0x03: | ||
311 | wbrcf = 4; | ||
312 | break; | ||
313 | case 0x04: | ||
314 | wbrcf = 8; | ||
315 | break; | ||
316 | case 0x05: | ||
317 | wbrcf = 16; | ||
318 | break; | ||
319 | case 0x06: | ||
320 | wbrcf = 32; | ||
321 | break; | ||
322 | case 0x07: | ||
323 | wbrcf = di_rfu; | ||
324 | break; | ||
325 | case 0x08: | ||
326 | wbrcf = 12; | ||
327 | break; | ||
328 | case 0x09: | ||
329 | wbrcf = 20; | ||
330 | break; | ||
331 | default: | ||
332 | wbrcf = di_rfu; | ||
333 | break; | ||
334 | } | ||
335 | |||
336 | return (wcrcf / wbrcf); | ||
337 | } | ||
338 | |||
339 | static unsigned short io_read_num_rec_bytes(ioaddr_t iobase, unsigned short *s) | ||
340 | { | ||
341 | unsigned short tmp; | ||
342 | |||
343 | tmp = *s = 0; | ||
344 | do { | ||
345 | *s = tmp; | ||
346 | tmp = inb(REG_NUM_BYTES(iobase)) | | ||
347 | (inb(REG_FLAGS0(iobase)) & 4 ? 0x100 : 0); | ||
348 | } while (tmp != *s); | ||
349 | |||
350 | return *s; | ||
351 | } | ||
352 | |||
353 | static int parse_atr(struct cm4000_dev *dev) | ||
354 | { | ||
355 | unsigned char any_t1, any_t0; | ||
356 | unsigned char ch, ifno; | ||
357 | int ix, done; | ||
358 | |||
359 | DEBUGP(3, dev, "-> parse_atr: dev->atr_len = %i\n", dev->atr_len); | ||
360 | |||
361 | if (dev->atr_len < 3) { | ||
362 | DEBUGP(5, dev, "parse_atr: atr_len < 3\n"); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | if (dev->atr[0] == 0x3f) | ||
367 | set_bit(IS_INVREV, &dev->flags); | ||
368 | else | ||
369 | clear_bit(IS_INVREV, &dev->flags); | ||
370 | ix = 1; | ||
371 | ifno = 1; | ||
372 | ch = dev->atr[1]; | ||
373 | dev->proto = 0; /* XXX PROTO */ | ||
374 | any_t1 = any_t0 = done = 0; | ||
375 | dev->ta1 = 0x11; /* defaults to 9600 baud */ | ||
376 | do { | ||
377 | if (ifno == 1 && (ch & 0x10)) { | ||
378 | /* read first interface byte and TA1 is present */ | ||
379 | dev->ta1 = dev->atr[2]; | ||
380 | DEBUGP(5, dev, "Card says FiDi is 0x%.2x\n", dev->ta1); | ||
381 | ifno++; | ||
382 | } else if ((ifno == 2) && (ch & 0x10)) { /* TA(2) */ | ||
383 | dev->ta1 = 0x11; | ||
384 | ifno++; | ||
385 | } | ||
386 | |||
387 | DEBUGP(5, dev, "Yi=%.2x\n", ch & 0xf0); | ||
388 | ix += ((ch & 0x10) >> 4) /* no of int.face chars */ | ||
389 | +((ch & 0x20) >> 5) | ||
390 | + ((ch & 0x40) >> 6) | ||
391 | + ((ch & 0x80) >> 7); | ||
392 | /* ATRLENCK(dev,ix); */ | ||
393 | if (ch & 0x80) { /* TDi */ | ||
394 | ch = dev->atr[ix]; | ||
395 | if ((ch & 0x0f)) { | ||
396 | any_t1 = 1; | ||
397 | DEBUGP(5, dev, "card is capable of T=1\n"); | ||
398 | } else { | ||
399 | any_t0 = 1; | ||
400 | DEBUGP(5, dev, "card is capable of T=0\n"); | ||
401 | } | ||
402 | } else | ||
403 | done = 1; | ||
404 | } while (!done); | ||
405 | |||
406 | DEBUGP(5, dev, "ix=%d noHist=%d any_t1=%d\n", | ||
407 | ix, dev->atr[1] & 15, any_t1); | ||
408 | if (ix + 1 + (dev->atr[1] & 0x0f) + any_t1 != dev->atr_len) { | ||
409 | DEBUGP(5, dev, "length error\n"); | ||
410 | return 0; | ||
411 | } | ||
412 | if (any_t0) | ||
413 | set_bit(IS_ANY_T0, &dev->flags); | ||
414 | |||
415 | if (any_t1) { /* compute csum */ | ||
416 | dev->atr_csum = 0; | ||
417 | #ifdef ATR_CSUM | ||
418 | for (i = 1; i < dev->atr_len; i++) | ||
419 | dev->atr_csum ^= dev->atr[i]; | ||
420 | if (dev->atr_csum) { | ||
421 | set_bit(IS_BAD_CSUM, &dev->flags); | ||
422 | DEBUGP(5, dev, "bad checksum\n"); | ||
423 | goto return_0; | ||
424 | } | ||
425 | #endif | ||
426 | if (any_t0 == 0) | ||
427 | dev->proto = 1; /* XXX PROTO */ | ||
428 | set_bit(IS_ANY_T1, &dev->flags); | ||
429 | } | ||
430 | |||
431 | return 1; | ||
432 | } | ||
433 | |||
434 | struct card_fixup { | ||
435 | char atr[12]; | ||
436 | u_int8_t atr_len; | ||
437 | u_int8_t stopbits; | ||
438 | }; | ||
439 | |||
440 | static struct card_fixup card_fixups[] = { | ||
441 | { /* ACOS */ | ||
442 | .atr = { 0x3b, 0xb3, 0x11, 0x00, 0x00, 0x41, 0x01 }, | ||
443 | .atr_len = 7, | ||
444 | .stopbits = 0x03, | ||
445 | }, | ||
446 | { /* Motorola */ | ||
447 | .atr = {0x3b, 0x76, 0x13, 0x00, 0x00, 0x80, 0x62, 0x07, | ||
448 | 0x41, 0x81, 0x81 }, | ||
449 | .atr_len = 11, | ||
450 | .stopbits = 0x04, | ||
451 | }, | ||
452 | }; | ||
453 | |||
454 | static void set_cardparameter(struct cm4000_dev *dev) | ||
455 | { | ||
456 | int i; | ||
457 | ioaddr_t iobase = dev->link.io.BasePort1; | ||
458 | u_int8_t stopbits = 0x02; /* ISO default */ | ||
459 | |||
460 | DEBUGP(3, dev, "-> set_cardparameter\n"); | ||
461 | |||
462 | dev->flags1 = dev->flags1 | (((dev->baudv - 1) & 0x0100) >> 8); | ||
463 | xoutb(dev->flags1, REG_FLAGS1(iobase)); | ||
464 | DEBUGP(5, dev, "flags1 = 0x%02x\n", dev->flags1); | ||
465 | |||
466 | /* set baudrate */ | ||
467 | xoutb((unsigned char)((dev->baudv - 1) & 0xFF), REG_BAUDRATE(iobase)); | ||
468 | |||
469 | DEBUGP(5, dev, "baudv = %i -> write 0x%02x\n", dev->baudv, | ||
470 | ((dev->baudv - 1) & 0xFF)); | ||
471 | |||
472 | /* set stopbits */ | ||
473 | for (i = 0; i < ARRAY_SIZE(card_fixups); i++) { | ||
474 | if (!memcmp(dev->atr, card_fixups[i].atr, | ||
475 | card_fixups[i].atr_len)) | ||
476 | stopbits = card_fixups[i].stopbits; | ||
477 | } | ||
478 | xoutb(stopbits, REG_STOPBITS(iobase)); | ||
479 | |||
480 | DEBUGP(3, dev, "<- set_cardparameter\n"); | ||
481 | } | ||
482 | |||
483 | static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) | ||
484 | { | ||
485 | |||
486 | unsigned long tmp, i; | ||
487 | unsigned short num_bytes_read; | ||
488 | unsigned char pts_reply[4]; | ||
489 | ssize_t rc; | ||
490 | ioaddr_t iobase = dev->link.io.BasePort1; | ||
491 | |||
492 | rc = 0; | ||
493 | |||
494 | DEBUGP(3, dev, "-> set_protocol\n"); | ||
495 | DEBUGP(5, dev, "ptsreq->Protocol = 0x%.8x, ptsreq->Flags=0x%.8x, " | ||
496 | "ptsreq->pts1=0x%.2x, ptsreq->pts2=0x%.2x, " | ||
497 | "ptsreq->pts3=0x%.2x\n", (unsigned int)ptsreq->protocol, | ||
498 | (unsigned int)ptsreq->flags, ptsreq->pts1, ptsreq->pts2, | ||
499 | ptsreq->pts3); | ||
500 | |||
501 | /* Fill PTS structure */ | ||
502 | dev->pts[0] = 0xff; | ||
503 | dev->pts[1] = 0x00; | ||
504 | tmp = ptsreq->protocol; | ||
505 | while ((tmp = (tmp >> 1)) > 0) | ||
506 | dev->pts[1]++; | ||
507 | dev->proto = dev->pts[1]; /* Set new protocol */ | ||
508 | dev->pts[1] = (0x01 << 4) | (dev->pts[1]); | ||
509 | |||
510 | /* Correct Fi/Di according to CM4000 Fi/Di table */ | ||
511 | DEBUGP(5, dev, "Ta(1) from ATR is 0x%.2x\n", dev->ta1); | ||
512 | /* set Fi/Di according to ATR TA(1) */ | ||
513 | dev->pts[2] = fi_di_table[dev->ta1 & 0x0F][(dev->ta1 >> 4) & 0x0F]; | ||
514 | |||
515 | /* Calculate PCK character */ | ||
516 | dev->pts[3] = dev->pts[0] ^ dev->pts[1] ^ dev->pts[2]; | ||
517 | |||
518 | DEBUGP(5, dev, "pts0=%.2x, pts1=%.2x, pts2=%.2x, pts3=%.2x\n", | ||
519 | dev->pts[0], dev->pts[1], dev->pts[2], dev->pts[3]); | ||
520 | |||
521 | /* check card convention */ | ||
522 | if (test_bit(IS_INVREV, &dev->flags)) | ||
523 | str_invert_revert(dev->pts, 4); | ||
524 | |||
525 | /* reset SM */ | ||
526 | xoutb(0x80, REG_FLAGS0(iobase)); | ||
527 | |||
528 | /* Enable access to the message buffer */ | ||
529 | DEBUGP(5, dev, "Enable access to the messages buffer\n"); | ||
530 | dev->flags1 = 0x20 /* T_Active */ | ||
531 | | (test_bit(IS_INVREV, &dev->flags) ? 0x02 : 0x00) /* inv parity */ | ||
532 | | ((dev->baudv >> 8) & 0x01); /* MSB-baud */ | ||
533 | xoutb(dev->flags1, REG_FLAGS1(iobase)); | ||
534 | |||
535 | DEBUGP(5, dev, "Enable message buffer -> flags1 = 0x%.2x\n", | ||
536 | dev->flags1); | ||
537 | |||
538 | /* write challenge to the buffer */ | ||
539 | DEBUGP(5, dev, "Write challenge to buffer: "); | ||
540 | for (i = 0; i < 4; i++) { | ||
541 | xoutb(i, REG_BUF_ADDR(iobase)); | ||
542 | xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */ | ||
543 | #ifdef PCMCIA_DEBUG | ||
544 | if (pc_debug >= 5) | ||
545 | printk("0x%.2x ", dev->pts[i]); | ||
546 | } | ||
547 | if (pc_debug >= 5) | ||
548 | printk("\n"); | ||
549 | #else | ||
550 | } | ||
551 | #endif | ||
552 | |||
553 | /* set number of bytes to write */ | ||
554 | DEBUGP(5, dev, "Set number of bytes to write\n"); | ||
555 | xoutb(0x04, REG_NUM_SEND(iobase)); | ||
556 | |||
557 | /* Trigger CARDMAN CONTROLLER */ | ||
558 | xoutb(0x50, REG_FLAGS0(iobase)); | ||
559 | |||
560 | /* Monitor progress */ | ||
561 | /* wait for xmit done */ | ||
562 | DEBUGP(5, dev, "Waiting for NumRecBytes getting valid\n"); | ||
563 | |||
564 | for (i = 0; i < 100; i++) { | ||
565 | if (inb(REG_FLAGS0(iobase)) & 0x08) { | ||
566 | DEBUGP(5, dev, "NumRecBytes is valid\n"); | ||
567 | break; | ||
568 | } | ||
569 | mdelay(10); | ||
570 | } | ||
571 | if (i == 100) { | ||
572 | DEBUGP(5, dev, "Timeout waiting for NumRecBytes getting " | ||
573 | "valid\n"); | ||
574 | rc = -EIO; | ||
575 | goto exit_setprotocol; | ||
576 | } | ||
577 | |||
578 | DEBUGP(5, dev, "Reading NumRecBytes\n"); | ||
579 | for (i = 0; i < 100; i++) { | ||
580 | io_read_num_rec_bytes(iobase, &num_bytes_read); | ||
581 | if (num_bytes_read >= 4) { | ||
582 | DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read); | ||
583 | break; | ||
584 | } | ||
585 | mdelay(10); | ||
586 | } | ||
587 | |||
588 | /* check whether it is a short PTS reply? */ | ||
589 | if (num_bytes_read == 3) | ||
590 | i = 0; | ||
591 | |||
592 | if (i == 100) { | ||
593 | DEBUGP(5, dev, "Timeout reading num_bytes_read\n"); | ||
594 | rc = -EIO; | ||
595 | goto exit_setprotocol; | ||
596 | } | ||
597 | |||
598 | DEBUGP(5, dev, "Reset the CARDMAN CONTROLLER\n"); | ||
599 | xoutb(0x80, REG_FLAGS0(iobase)); | ||
600 | |||
601 | /* Read PPS reply */ | ||
602 | DEBUGP(5, dev, "Read PPS reply\n"); | ||
603 | for (i = 0; i < num_bytes_read; i++) { | ||
604 | xoutb(i, REG_BUF_ADDR(iobase)); | ||
605 | pts_reply[i] = inb(REG_BUF_DATA(iobase)); | ||
606 | } | ||
607 | |||
608 | #ifdef PCMCIA_DEBUG | ||
609 | DEBUGP(2, dev, "PTSreply: "); | ||
610 | for (i = 0; i < num_bytes_read; i++) { | ||
611 | if (pc_debug >= 5) | ||
612 | printk("0x%.2x ", pts_reply[i]); | ||
613 | } | ||
614 | printk("\n"); | ||
615 | #endif /* PCMCIA_DEBUG */ | ||
616 | |||
617 | DEBUGP(5, dev, "Clear Tactive in Flags1\n"); | ||
618 | xoutb(0x20, REG_FLAGS1(iobase)); | ||
619 | |||
620 | /* Compare ptsreq and ptsreply */ | ||
621 | if ((dev->pts[0] == pts_reply[0]) && | ||
622 | (dev->pts[1] == pts_reply[1]) && | ||
623 | (dev->pts[2] == pts_reply[2]) && (dev->pts[3] == pts_reply[3])) { | ||
624 | /* setcardparameter according to PPS */ | ||
625 | dev->baudv = calc_baudv(dev->pts[2]); | ||
626 | set_cardparameter(dev); | ||
627 | } else if ((dev->pts[0] == pts_reply[0]) && | ||
628 | ((dev->pts[1] & 0xef) == pts_reply[1]) && | ||
629 | ((pts_reply[0] ^ pts_reply[1]) == pts_reply[2])) { | ||
630 | /* short PTS reply, set card parameter to default values */ | ||
631 | dev->baudv = calc_baudv(0x11); | ||
632 | set_cardparameter(dev); | ||
633 | } else | ||
634 | rc = -EIO; | ||
635 | |||
636 | exit_setprotocol: | ||
637 | DEBUGP(3, dev, "<- set_protocol\n"); | ||
638 | return rc; | ||
639 | } | ||
640 | |||
641 | static int io_detect_cm4000(ioaddr_t iobase, struct cm4000_dev *dev) | ||
642 | { | ||
643 | |||
644 | /* note: statemachine is assumed to be reset */ | ||
645 | if (inb(REG_FLAGS0(iobase)) & 8) { | ||
646 | clear_bit(IS_ATR_VALID, &dev->flags); | ||
647 | set_bit(IS_CMM_ABSENT, &dev->flags); | ||
648 | return 0; /* detect CMM = 1 -> failure */ | ||
649 | } | ||
650 | /* xoutb(0x40, REG_FLAGS1(iobase)); detectCMM */ | ||
651 | xoutb(dev->flags1 | 0x40, REG_FLAGS1(iobase)); | ||
652 | if ((inb(REG_FLAGS0(iobase)) & 8) == 0) { | ||
653 | clear_bit(IS_ATR_VALID, &dev->flags); | ||
654 | set_bit(IS_CMM_ABSENT, &dev->flags); | ||
655 | return 0; /* detect CMM=0 -> failure */ | ||
656 | } | ||
657 | /* clear detectCMM again by restoring original flags1 */ | ||
658 | xoutb(dev->flags1, REG_FLAGS1(iobase)); | ||
659 | return 1; | ||
660 | } | ||
661 | |||
662 | static void terminate_monitor(struct cm4000_dev *dev) | ||
663 | { | ||
664 | |||
665 | /* tell the monitor to stop and wait until | ||
666 | * it terminates. | ||
667 | */ | ||
668 | DEBUGP(3, dev, "-> terminate_monitor\n"); | ||
669 | wait_event_interruptible(dev->devq, | ||
670 | test_and_set_bit(LOCK_MONITOR, | ||
671 | (void *)&dev->flags)); | ||
672 | |||
673 | /* now, LOCK_MONITOR has been set. | ||
674 | * allow a last cycle in the monitor. | ||
675 | * the monitor will indicate that it has | ||
676 | * finished by clearing this bit. | ||
677 | */ | ||
678 | DEBUGP(5, dev, "Now allow last cycle of monitor!\n"); | ||
679 | while (test_bit(LOCK_MONITOR, (void *)&dev->flags)) | ||
680 | msleep(25); | ||
681 | |||
682 | DEBUGP(5, dev, "Delete timer\n"); | ||
683 | del_timer_sync(&dev->timer); | ||
684 | #ifdef PCMCIA_DEBUG | ||
685 | dev->monitor_running = 0; | ||
686 | #endif | ||
687 | |||
688 | DEBUGP(3, dev, "<- terminate_monitor\n"); | ||
689 | } | ||
690 | |||
691 | /* | ||
692 | * monitor the card every 50msec. as a side-effect, retrieve the | ||
693 | * atr once a card is inserted. another side-effect of retrieving the | ||
694 | * atr is that the card will be powered on, so there is no need to | ||
695 | * power on the card explictely from the application: the driver | ||
696 | * is already doing that for you. | ||
697 | */ | ||
698 | |||
699 | static void monitor_card(unsigned long p) | ||
700 | { | ||
701 | struct cm4000_dev *dev = (struct cm4000_dev *) p; | ||
702 | ioaddr_t iobase = dev->link.io.BasePort1; | ||
703 | unsigned short s; | ||
704 | struct ptsreq ptsreq; | ||
705 | int i, atrc; | ||
706 | |||
707 | DEBUGP(7, dev, "-> monitor_card\n"); | ||
708 | |||
709 | /* if someone has set the lock for us: we're done! */ | ||
710 | if (test_and_set_bit(LOCK_MONITOR, &dev->flags)) { | ||
711 | DEBUGP(4, dev, "About to stop monitor\n"); | ||
712 | /* no */ | ||
713 | dev->rlen = | ||
714 | dev->rpos = | ||
715 | dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0; | ||
716 | dev->mstate = M_FETCH_ATR; | ||
717 | clear_bit(LOCK_MONITOR, &dev->flags); | ||
718 | /* close et al. are sleeping on devq, so wake it */ | ||
719 | wake_up_interruptible(&dev->devq); | ||
720 | DEBUGP(2, dev, "<- monitor_card (we are done now)\n"); | ||
721 | return; | ||
722 | } | ||
723 | |||
724 | /* try to lock io: if it is already locked, just add another timer */ | ||
725 | if (test_and_set_bit(LOCK_IO, (void *)&dev->flags)) { | ||
726 | DEBUGP(4, dev, "Couldn't get IO lock\n"); | ||
727 | goto return_with_timer; | ||
728 | } | ||
729 | |||
730 | /* is a card/a reader inserted at all ? */ | ||
731 | dev->flags0 = xinb(REG_FLAGS0(iobase)); | ||
732 | DEBUGP(7, dev, "dev->flags0 = 0x%2x\n", dev->flags0); | ||
733 | DEBUGP(7, dev, "smartcard present: %s\n", | ||
734 | dev->flags0 & 1 ? "yes" : "no"); | ||
735 | DEBUGP(7, dev, "cardman present: %s\n", | ||
736 | dev->flags0 == 0xff ? "no" : "yes"); | ||
737 | |||
738 | if ((dev->flags0 & 1) == 0 /* no smartcard inserted */ | ||
739 | || dev->flags0 == 0xff) { /* no cardman inserted */ | ||
740 | /* no */ | ||
741 | dev->rlen = | ||
742 | dev->rpos = | ||
743 | dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0; | ||
744 | dev->mstate = M_FETCH_ATR; | ||
745 | |||
746 | dev->flags &= 0x000000ff; /* only keep IO and MONITOR locks */ | ||
747 | |||
748 | if (dev->flags0 == 0xff) { | ||
749 | DEBUGP(4, dev, "set IS_CMM_ABSENT bit\n"); | ||
750 | set_bit(IS_CMM_ABSENT, &dev->flags); | ||
751 | } else if (test_bit(IS_CMM_ABSENT, &dev->flags)) { | ||
752 | DEBUGP(4, dev, "clear IS_CMM_ABSENT bit " | ||
753 | "(card is removed)\n"); | ||
754 | clear_bit(IS_CMM_ABSENT, &dev->flags); | ||
755 | } | ||
756 | |||
757 | goto release_io; | ||
758 | } else if ((dev->flags0 & 1) && test_bit(IS_CMM_ABSENT, &dev->flags)) { | ||
759 | /* cardman and card present but cardman was absent before | ||
760 | * (after suspend with inserted card) */ | ||
761 | DEBUGP(4, dev, "clear IS_CMM_ABSENT bit (card is inserted)\n"); | ||
762 | clear_bit(IS_CMM_ABSENT, &dev->flags); | ||
763 | } | ||
764 | |||
765 | if (test_bit(IS_ATR_VALID, &dev->flags) == 1) { | ||
766 | DEBUGP(7, dev, "believe ATR is already valid (do nothing)\n"); | ||
767 | goto release_io; | ||
768 | } | ||
769 | |||
770 | switch (dev->mstate) { | ||
771 | unsigned char flags0; | ||
772 | case M_CARDOFF: | ||
773 | DEBUGP(4, dev, "M_CARDOFF\n"); | ||
774 | flags0 = inb(REG_FLAGS0(iobase)); | ||
775 | if (flags0 & 0x02) { | ||
776 | /* wait until Flags0 indicate power is off */ | ||
777 | dev->mdelay = T_10MSEC; | ||
778 | } else { | ||
779 | /* Flags0 indicate power off and no card inserted now; | ||
780 | * Reset CARDMAN CONTROLLER */ | ||
781 | xoutb(0x80, REG_FLAGS0(iobase)); | ||
782 | |||
783 | /* prepare for fetching ATR again: after card off ATR | ||
784 | * is read again automatically */ | ||
785 | dev->rlen = | ||
786 | dev->rpos = | ||
787 | dev->atr_csum = | ||
788 | dev->atr_len_retry = dev->cwarn = 0; | ||
789 | dev->mstate = M_FETCH_ATR; | ||
790 | |||
791 | /* minimal gap between CARDOFF and read ATR is 50msec */ | ||
792 | dev->mdelay = T_50MSEC; | ||
793 | } | ||
794 | break; | ||
795 | case M_FETCH_ATR: | ||
796 | DEBUGP(4, dev, "M_FETCH_ATR\n"); | ||
797 | xoutb(0x80, REG_FLAGS0(iobase)); | ||
798 | DEBUGP(4, dev, "Reset BAUDV to 9600\n"); | ||
799 | dev->baudv = 0x173; /* 9600 */ | ||
800 | xoutb(0x02, REG_STOPBITS(iobase)); /* stopbits=2 */ | ||
801 | xoutb(0x73, REG_BAUDRATE(iobase)); /* baud value */ | ||
802 | xoutb(0x21, REG_FLAGS1(iobase)); /* T_Active=1, baud | ||
803 | value */ | ||
804 | /* warm start vs. power on: */ | ||
805 | xoutb(dev->flags0 & 2 ? 0x46 : 0x44, REG_FLAGS0(iobase)); | ||
806 | dev->mdelay = T_40MSEC; | ||
807 | dev->mstate = M_TIMEOUT_WAIT; | ||
808 | break; | ||
809 | case M_TIMEOUT_WAIT: | ||
810 | DEBUGP(4, dev, "M_TIMEOUT_WAIT\n"); | ||
811 | /* numRecBytes */ | ||
812 | io_read_num_rec_bytes(iobase, &dev->atr_len); | ||
813 | dev->mdelay = T_10MSEC; | ||
814 | dev->mstate = M_READ_ATR_LEN; | ||
815 | break; | ||
816 | case M_READ_ATR_LEN: | ||
817 | DEBUGP(4, dev, "M_READ_ATR_LEN\n"); | ||
818 | /* infinite loop possible, since there is no timeout */ | ||
819 | |||
820 | #define MAX_ATR_LEN_RETRY 100 | ||
821 | |||
822 | if (dev->atr_len == io_read_num_rec_bytes(iobase, &s)) { | ||
823 | if (dev->atr_len_retry++ >= MAX_ATR_LEN_RETRY) { /* + XX msec */ | ||
824 | dev->mdelay = T_10MSEC; | ||
825 | dev->mstate = M_READ_ATR; | ||
826 | } | ||
827 | } else { | ||
828 | dev->atr_len = s; | ||
829 | dev->atr_len_retry = 0; /* set new timeout */ | ||
830 | } | ||
831 | |||
832 | DEBUGP(4, dev, "Current ATR_LEN = %i\n", dev->atr_len); | ||
833 | break; | ||
834 | case M_READ_ATR: | ||
835 | DEBUGP(4, dev, "M_READ_ATR\n"); | ||
836 | xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */ | ||
837 | for (i = 0; i < dev->atr_len; i++) { | ||
838 | xoutb(i, REG_BUF_ADDR(iobase)); | ||
839 | dev->atr[i] = inb(REG_BUF_DATA(iobase)); | ||
840 | } | ||
841 | /* Deactivate T_Active flags */ | ||
842 | DEBUGP(4, dev, "Deactivate T_Active flags\n"); | ||
843 | dev->flags1 = 0x01; | ||
844 | xoutb(dev->flags1, REG_FLAGS1(iobase)); | ||
845 | |||
846 | /* atr is present (which doesnt mean it's valid) */ | ||
847 | set_bit(IS_ATR_PRESENT, &dev->flags); | ||
848 | if (dev->atr[0] == 0x03) | ||
849 | str_invert_revert(dev->atr, dev->atr_len); | ||
850 | atrc = parse_atr(dev); | ||
851 | if (atrc == 0) { /* atr invalid */ | ||
852 | dev->mdelay = 0; | ||
853 | dev->mstate = M_BAD_CARD; | ||
854 | } else { | ||
855 | dev->mdelay = T_50MSEC; | ||
856 | dev->mstate = M_ATR_PRESENT; | ||
857 | set_bit(IS_ATR_VALID, &dev->flags); | ||
858 | } | ||
859 | |||
860 | if (test_bit(IS_ATR_VALID, &dev->flags) == 1) { | ||
861 | DEBUGP(4, dev, "monitor_card: ATR valid\n"); | ||
862 | /* if ta1 == 0x11, no PPS necessary (default values) */ | ||
863 | /* do not do PPS with multi protocol cards */ | ||
864 | if ((test_bit(IS_AUTOPPS_ACT, &dev->flags) == 0) && | ||
865 | (dev->ta1 != 0x11) && | ||
866 | !(test_bit(IS_ANY_T0, &dev->flags) && | ||
867 | test_bit(IS_ANY_T1, &dev->flags))) { | ||
868 | DEBUGP(4, dev, "Perform AUTOPPS\n"); | ||
869 | set_bit(IS_AUTOPPS_ACT, &dev->flags); | ||
870 | ptsreq.protocol = ptsreq.protocol = | ||
871 | (0x01 << dev->proto); | ||
872 | ptsreq.flags = 0x01; | ||
873 | ptsreq.pts1 = 0x00; | ||
874 | ptsreq.pts2 = 0x00; | ||
875 | ptsreq.pts3 = 0x00; | ||
876 | if (set_protocol(dev, &ptsreq) == 0) { | ||
877 | DEBUGP(4, dev, "AUTOPPS ret SUCC\n"); | ||
878 | clear_bit(IS_AUTOPPS_ACT, &dev->flags); | ||
879 | wake_up_interruptible(&dev->atrq); | ||
880 | } else { | ||
881 | DEBUGP(4, dev, "AUTOPPS failed: " | ||
882 | "repower using defaults\n"); | ||
883 | /* prepare for repowering */ | ||
884 | clear_bit(IS_ATR_PRESENT, &dev->flags); | ||
885 | clear_bit(IS_ATR_VALID, &dev->flags); | ||
886 | dev->rlen = | ||
887 | dev->rpos = | ||
888 | dev->atr_csum = | ||
889 | dev->atr_len_retry = dev->cwarn = 0; | ||
890 | dev->mstate = M_FETCH_ATR; | ||
891 | |||
892 | dev->mdelay = T_50MSEC; | ||
893 | } | ||
894 | } else { | ||
895 | /* for cards which use slightly different | ||
896 | * params (extra guard time) */ | ||
897 | set_cardparameter(dev); | ||
898 | if (test_bit(IS_AUTOPPS_ACT, &dev->flags) == 1) | ||
899 | DEBUGP(4, dev, "AUTOPPS already active " | ||
900 | "2nd try:use default values\n"); | ||
901 | if (dev->ta1 == 0x11) | ||
902 | DEBUGP(4, dev, "No AUTOPPS necessary " | ||
903 | "TA(1)==0x11\n"); | ||
904 | if (test_bit(IS_ANY_T0, &dev->flags) | ||
905 | && test_bit(IS_ANY_T1, &dev->flags)) | ||
906 | DEBUGP(4, dev, "Do NOT perform AUTOPPS " | ||
907 | "with multiprotocol cards\n"); | ||
908 | clear_bit(IS_AUTOPPS_ACT, &dev->flags); | ||
909 | wake_up_interruptible(&dev->atrq); | ||
910 | } | ||
911 | } else { | ||
912 | DEBUGP(4, dev, "ATR invalid\n"); | ||
913 | wake_up_interruptible(&dev->atrq); | ||
914 | } | ||
915 | break; | ||
916 | case M_BAD_CARD: | ||
917 | DEBUGP(4, dev, "M_BAD_CARD\n"); | ||
918 | /* slow down warning, but prompt immediately after insertion */ | ||
919 | if (dev->cwarn == 0 || dev->cwarn == 10) { | ||
920 | set_bit(IS_BAD_CARD, &dev->flags); | ||
921 | printk(KERN_WARNING MODULE_NAME ": device %s: ", | ||
922 | dev->node.dev_name); | ||
923 | if (test_bit(IS_BAD_CSUM, &dev->flags)) { | ||
924 | DEBUGP(4, dev, "ATR checksum (0x%.2x, should " | ||
925 | "be zero) failed\n", dev->atr_csum); | ||
926 | } | ||
927 | #ifdef PCMCIA_DEBUG | ||
928 | else if (test_bit(IS_BAD_LENGTH, &dev->flags)) { | ||
929 | DEBUGP(4, dev, "ATR length error\n"); | ||
930 | } else { | ||
931 | DEBUGP(4, dev, "card damaged or wrong way " | ||
932 | "inserted\n"); | ||
933 | } | ||
934 | #endif | ||
935 | dev->cwarn = 0; | ||
936 | wake_up_interruptible(&dev->atrq); /* wake open */ | ||
937 | } | ||
938 | dev->cwarn++; | ||
939 | dev->mdelay = T_100MSEC; | ||
940 | dev->mstate = M_FETCH_ATR; | ||
941 | break; | ||
942 | default: | ||
943 | DEBUGP(7, dev, "Unknown action\n"); | ||
944 | break; /* nothing */ | ||
945 | } | ||
946 | |||
947 | release_io: | ||
948 | DEBUGP(7, dev, "release_io\n"); | ||
949 | clear_bit(LOCK_IO, &dev->flags); | ||
950 | wake_up_interruptible(&dev->ioq); /* whoever needs IO */ | ||
951 | |||
952 | return_with_timer: | ||
953 | DEBUGP(7, dev, "<- monitor_card (returns with timer)\n"); | ||
954 | dev->timer.expires = jiffies + dev->mdelay; | ||
955 | add_timer(&dev->timer); | ||
956 | clear_bit(LOCK_MONITOR, &dev->flags); | ||
957 | } | ||
958 | |||
959 | /* Interface to userland (file_operations) */ | ||
960 | |||
961 | static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, | ||
962 | loff_t *ppos) | ||
963 | { | ||
964 | struct cm4000_dev *dev = filp->private_data; | ||
965 | ioaddr_t iobase = dev->link.io.BasePort1; | ||
966 | ssize_t rc; | ||
967 | int i, j, k; | ||
968 | |||
969 | DEBUGP(2, dev, "-> cmm_read(%s,%d)\n", current->comm, current->pid); | ||
970 | |||
971 | if (count == 0) /* according to manpage */ | ||
972 | return 0; | ||
973 | |||
974 | if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */ | ||
975 | test_bit(IS_CMM_ABSENT, &dev->flags)) | ||
976 | return -ENODEV; | ||
977 | |||
978 | if (test_bit(IS_BAD_CSUM, &dev->flags)) | ||
979 | return -EIO; | ||
980 | |||
981 | /* also see the note about this in cmm_write */ | ||
982 | if (wait_event_interruptible | ||
983 | (dev->atrq, | ||
984 | ((filp->f_flags & O_NONBLOCK) | ||
985 | || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) { | ||
986 | if (filp->f_flags & O_NONBLOCK) | ||
987 | return -EAGAIN; | ||
988 | return -ERESTARTSYS; | ||
989 | } | ||
990 | |||
991 | if (test_bit(IS_ATR_VALID, &dev->flags) == 0) | ||
992 | return -EIO; | ||
993 | |||
994 | /* this one implements blocking IO */ | ||
995 | if (wait_event_interruptible | ||
996 | (dev->readq, | ||
997 | ((filp->f_flags & O_NONBLOCK) || (dev->rpos < dev->rlen)))) { | ||
998 | if (filp->f_flags & O_NONBLOCK) | ||
999 | return -EAGAIN; | ||
1000 | return -ERESTARTSYS; | ||
1001 | } | ||
1002 | |||
1003 | /* lock io */ | ||
1004 | if (wait_event_interruptible | ||
1005 | (dev->ioq, | ||
1006 | ((filp->f_flags & O_NONBLOCK) | ||
1007 | || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) { | ||
1008 | if (filp->f_flags & O_NONBLOCK) | ||
1009 | return -EAGAIN; | ||
1010 | return -ERESTARTSYS; | ||
1011 | } | ||
1012 | |||
1013 | rc = 0; | ||
1014 | dev->flags0 = inb(REG_FLAGS0(iobase)); | ||
1015 | if ((dev->flags0 & 1) == 0 /* no smartcard inserted */ | ||
1016 | || dev->flags0 == 0xff) { /* no cardman inserted */ | ||
1017 | clear_bit(IS_ATR_VALID, &dev->flags); | ||
1018 | if (dev->flags0 & 1) { | ||
1019 | set_bit(IS_CMM_ABSENT, &dev->flags); | ||
1020 | rc = -ENODEV; | ||
1021 | } | ||
1022 | rc = -EIO; | ||
1023 | goto release_io; | ||
1024 | } | ||
1025 | |||
1026 | DEBUGP(4, dev, "begin read answer\n"); | ||
1027 | j = min(count, (size_t)(dev->rlen - dev->rpos)); | ||
1028 | k = dev->rpos; | ||
1029 | if (k + j > 255) | ||
1030 | j = 256 - k; | ||
1031 | DEBUGP(4, dev, "read1 j=%d\n", j); | ||
1032 | for (i = 0; i < j; i++) { | ||
1033 | xoutb(k++, REG_BUF_ADDR(iobase)); | ||
1034 | dev->rbuf[i] = xinb(REG_BUF_DATA(iobase)); | ||
1035 | } | ||
1036 | j = min(count, (size_t)(dev->rlen - dev->rpos)); | ||
1037 | if (k + j > 255) { | ||
1038 | DEBUGP(4, dev, "read2 j=%d\n", j); | ||
1039 | dev->flags1 |= 0x10; /* MSB buf addr set */ | ||
1040 | xoutb(dev->flags1, REG_FLAGS1(iobase)); | ||
1041 | for (; i < j; i++) { | ||
1042 | xoutb(k++, REG_BUF_ADDR(iobase)); | ||
1043 | dev->rbuf[i] = xinb(REG_BUF_DATA(iobase)); | ||
1044 | } | ||
1045 | } | ||
1046 | |||
1047 | if (dev->proto == 0 && count > dev->rlen - dev->rpos) { | ||
1048 | DEBUGP(4, dev, "T=0 and count > buffer\n"); | ||
1049 | dev->rbuf[i] = dev->rbuf[i - 1]; | ||
1050 | dev->rbuf[i - 1] = dev->procbyte; | ||
1051 | j++; | ||
1052 | } | ||
1053 | count = j; | ||
1054 | |||
1055 | dev->rpos = dev->rlen + 1; | ||
1056 | |||
1057 | /* Clear T1Active */ | ||
1058 | DEBUGP(4, dev, "Clear T1Active\n"); | ||
1059 | dev->flags1 &= 0xdf; | ||
1060 | xoutb(dev->flags1, REG_FLAGS1(iobase)); | ||
1061 | |||
1062 | xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */ | ||
1063 | /* last check before exit */ | ||
1064 | if (!io_detect_cm4000(iobase, dev)) | ||
1065 | count = -ENODEV; | ||
1066 | |||
1067 | if (test_bit(IS_INVREV, &dev->flags) && count > 0) | ||
1068 | str_invert_revert(dev->rbuf, count); | ||
1069 | |||
1070 | if (copy_to_user(buf, dev->rbuf, count)) | ||
1071 | return -EFAULT; | ||
1072 | |||
1073 | release_io: | ||
1074 | clear_bit(LOCK_IO, &dev->flags); | ||
1075 | wake_up_interruptible(&dev->ioq); | ||
1076 | |||
1077 | DEBUGP(2, dev, "<- cmm_read returns: rc = %Zi\n", | ||
1078 | (rc < 0 ? rc : count)); | ||
1079 | return rc < 0 ? rc : count; | ||
1080 | } | ||
1081 | |||
1082 | static ssize_t cmm_write(struct file *filp, const char __user *buf, | ||
1083 | size_t count, loff_t *ppos) | ||
1084 | { | ||
1085 | struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data; | ||
1086 | ioaddr_t iobase = dev->link.io.BasePort1; | ||
1087 | unsigned short s; | ||
1088 | unsigned char tmp; | ||
1089 | unsigned char infolen; | ||
1090 | unsigned char sendT0; | ||
1091 | unsigned short nsend; | ||
1092 | unsigned short nr; | ||
1093 | ssize_t rc; | ||
1094 | int i; | ||
1095 | |||
1096 | DEBUGP(2, dev, "-> cmm_write(%s,%d)\n", current->comm, current->pid); | ||
1097 | |||
1098 | if (count == 0) /* according to manpage */ | ||
1099 | return 0; | ||
1100 | |||
1101 | if (dev->proto == 0 && count < 4) { | ||
1102 | /* T0 must have at least 4 bytes */ | ||
1103 | DEBUGP(4, dev, "T0 short write\n"); | ||
1104 | return -EIO; | ||
1105 | } | ||
1106 | |||
1107 | nr = count & 0x1ff; /* max bytes to write */ | ||
1108 | |||
1109 | sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0; | ||
1110 | |||
1111 | if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */ | ||
1112 | test_bit(IS_CMM_ABSENT, &dev->flags)) | ||
1113 | return -ENODEV; | ||
1114 | |||
1115 | if (test_bit(IS_BAD_CSUM, &dev->flags)) { | ||
1116 | DEBUGP(4, dev, "bad csum\n"); | ||
1117 | return -EIO; | ||
1118 | } | ||
1119 | |||
1120 | /* | ||
1121 | * wait for atr to become valid. | ||
1122 | * note: it is important to lock this code. if we dont, the monitor | ||
1123 | * could be run between test_bit and the the call the sleep on the | ||
1124 | * atr-queue. if *then* the monitor detects atr valid, it will wake up | ||
1125 | * any process on the atr-queue, *but* since we have been interrupted, | ||
1126 | * we do not yet sleep on this queue. this would result in a missed | ||
1127 | * wake_up and the calling process would sleep forever (until | ||
1128 | * interrupted). also, do *not* restore_flags before sleep_on, because | ||
1129 | * this could result in the same situation! | ||
1130 | */ | ||
1131 | if (wait_event_interruptible | ||
1132 | (dev->atrq, | ||
1133 | ((filp->f_flags & O_NONBLOCK) | ||
1134 | || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) { | ||
1135 | if (filp->f_flags & O_NONBLOCK) | ||
1136 | return -EAGAIN; | ||
1137 | return -ERESTARTSYS; | ||
1138 | } | ||
1139 | |||
1140 | if (test_bit(IS_ATR_VALID, &dev->flags) == 0) { /* invalid atr */ | ||
1141 | DEBUGP(4, dev, "invalid ATR\n"); | ||
1142 | return -EIO; | ||
1143 | } | ||
1144 | |||
1145 | /* lock io */ | ||
1146 | if (wait_event_interruptible | ||
1147 | (dev->ioq, | ||
1148 | ((filp->f_flags & O_NONBLOCK) | ||
1149 | || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) { | ||
1150 | if (filp->f_flags & O_NONBLOCK) | ||
1151 | return -EAGAIN; | ||
1152 | return -ERESTARTSYS; | ||
1153 | } | ||
1154 | |||
1155 | if (copy_from_user(dev->sbuf, buf, ((count > 512) ? 512 : count))) | ||
1156 | return -EFAULT; | ||
1157 | |||
1158 | rc = 0; | ||
1159 | dev->flags0 = inb(REG_FLAGS0(iobase)); | ||
1160 | if ((dev->flags0 & 1) == 0 /* no smartcard inserted */ | ||
1161 | || dev->flags0 == 0xff) { /* no cardman inserted */ | ||
1162 | clear_bit(IS_ATR_VALID, &dev->flags); | ||
1163 | if (dev->flags0 & 1) { | ||
1164 | set_bit(IS_CMM_ABSENT, &dev->flags); | ||
1165 | rc = -ENODEV; | ||
1166 | } else { | ||
1167 | DEBUGP(4, dev, "IO error\n"); | ||
1168 | rc = -EIO; | ||
1169 | } | ||
1170 | goto release_io; | ||
1171 | } | ||
1172 | |||
1173 | xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */ | ||
1174 | |||
1175 | if (!io_detect_cm4000(iobase, dev)) { | ||
1176 | rc = -ENODEV; | ||
1177 | goto release_io; | ||
1178 | } | ||
1179 | |||
1180 | /* reflect T=0 send/read mode in flags1 */ | ||
1181 | dev->flags1 |= (sendT0); | ||
1182 | |||
1183 | set_cardparameter(dev); | ||
1184 | |||
1185 | /* dummy read, reset flag procedure received */ | ||
1186 | tmp = inb(REG_FLAGS1(iobase)); | ||
1187 | |||
1188 | dev->flags1 = 0x20 /* T_Active */ | ||
1189 | | (sendT0) | ||
1190 | | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0)/* inverse parity */ | ||
1191 | | (((dev->baudv - 1) & 0x0100) >> 8); /* MSB-Baud */ | ||
1192 | DEBUGP(1, dev, "set dev->flags1 = 0x%.2x\n", dev->flags1); | ||
1193 | xoutb(dev->flags1, REG_FLAGS1(iobase)); | ||
1194 | |||
1195 | /* xmit data */ | ||
1196 | DEBUGP(4, dev, "Xmit data\n"); | ||
1197 | for (i = 0; i < nr; i++) { | ||
1198 | if (i >= 256) { | ||
1199 | dev->flags1 = 0x20 /* T_Active */ | ||
1200 | | (sendT0) /* SendT0 */ | ||
1201 | /* inverse parity: */ | ||
1202 | | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0) | ||
1203 | | (((dev->baudv - 1) & 0x0100) >> 8) /* MSB-Baud */ | ||
1204 | | 0x10; /* set address high */ | ||
1205 | DEBUGP(4, dev, "dev->flags = 0x%.2x - set address " | ||
1206 | "high\n", dev->flags1); | ||
1207 | xoutb(dev->flags1, REG_FLAGS1(iobase)); | ||
1208 | } | ||
1209 | if (test_bit(IS_INVREV, &dev->flags)) { | ||
1210 | DEBUGP(4, dev, "Apply inverse convention for 0x%.2x " | ||
1211 | "-> 0x%.2x\n", (unsigned char)dev->sbuf[i], | ||
1212 | invert_revert(dev->sbuf[i])); | ||
1213 | xoutb(i, REG_BUF_ADDR(iobase)); | ||
1214 | xoutb(invert_revert(dev->sbuf[i]), | ||
1215 | REG_BUF_DATA(iobase)); | ||
1216 | } else { | ||
1217 | xoutb(i, REG_BUF_ADDR(iobase)); | ||
1218 | xoutb(dev->sbuf[i], REG_BUF_DATA(iobase)); | ||
1219 | } | ||
1220 | } | ||
1221 | DEBUGP(4, dev, "Xmit done\n"); | ||
1222 | |||
1223 | if (dev->proto == 0) { | ||
1224 | /* T=0 proto: 0 byte reply */ | ||
1225 | if (nr == 4) { | ||
1226 | DEBUGP(4, dev, "T=0 assumes 0 byte reply\n"); | ||
1227 | xoutb(i, REG_BUF_ADDR(iobase)); | ||
1228 | if (test_bit(IS_INVREV, &dev->flags)) | ||
1229 | xoutb(0xff, REG_BUF_DATA(iobase)); | ||
1230 | else | ||
1231 | xoutb(0x00, REG_BUF_DATA(iobase)); | ||
1232 | } | ||
1233 | |||
1234 | /* numSendBytes */ | ||
1235 | if (sendT0) | ||
1236 | nsend = nr; | ||
1237 | else { | ||
1238 | if (nr == 4) | ||
1239 | nsend = 5; | ||
1240 | else { | ||
1241 | nsend = 5 + (unsigned char)dev->sbuf[4]; | ||
1242 | if (dev->sbuf[4] == 0) | ||
1243 | nsend += 0x100; | ||
1244 | } | ||
1245 | } | ||
1246 | } else | ||
1247 | nsend = nr; | ||
1248 | |||
1249 | /* T0: output procedure byte */ | ||
1250 | if (test_bit(IS_INVREV, &dev->flags)) { | ||
1251 | DEBUGP(4, dev, "T=0 set Procedure byte (inverse-reverse) " | ||
1252 | "0x%.2x\n", invert_revert(dev->sbuf[1])); | ||
1253 | xoutb(invert_revert(dev->sbuf[1]), REG_NUM_BYTES(iobase)); | ||
1254 | } else { | ||
1255 | DEBUGP(4, dev, "T=0 set Procedure byte 0x%.2x\n", dev->sbuf[1]); | ||
1256 | xoutb(dev->sbuf[1], REG_NUM_BYTES(iobase)); | ||
1257 | } | ||
1258 | |||
1259 | DEBUGP(1, dev, "set NumSendBytes = 0x%.2x\n", | ||
1260 | (unsigned char)(nsend & 0xff)); | ||
1261 | xoutb((unsigned char)(nsend & 0xff), REG_NUM_SEND(iobase)); | ||
1262 | |||
1263 | DEBUGP(1, dev, "Trigger CARDMAN CONTROLLER (0x%.2x)\n", | ||
1264 | 0x40 /* SM_Active */ | ||
1265 | | (dev->flags0 & 2 ? 0 : 4) /* power on if needed */ | ||
1266 | |(dev->proto ? 0x10 : 0x08) /* T=1/T=0 */ | ||
1267 | |(nsend & 0x100) >> 8 /* MSB numSendBytes */ ); | ||
1268 | xoutb(0x40 /* SM_Active */ | ||
1269 | | (dev->flags0 & 2 ? 0 : 4) /* power on if needed */ | ||
1270 | |(dev->proto ? 0x10 : 0x08) /* T=1/T=0 */ | ||
1271 | |(nsend & 0x100) >> 8, /* MSB numSendBytes */ | ||
1272 | REG_FLAGS0(iobase)); | ||
1273 | |||
1274 | /* wait for xmit done */ | ||
1275 | if (dev->proto == 1) { | ||
1276 | DEBUGP(4, dev, "Wait for xmit done\n"); | ||
1277 | for (i = 0; i < 1000; i++) { | ||
1278 | if (inb(REG_FLAGS0(iobase)) & 0x08) | ||
1279 | break; | ||
1280 | msleep_interruptible(10); | ||
1281 | } | ||
1282 | if (i == 1000) { | ||
1283 | DEBUGP(4, dev, "timeout waiting for xmit done\n"); | ||
1284 | rc = -EIO; | ||
1285 | goto release_io; | ||
1286 | } | ||
1287 | } | ||
1288 | |||
1289 | /* T=1: wait for infoLen */ | ||
1290 | |||
1291 | infolen = 0; | ||
1292 | if (dev->proto) { | ||
1293 | /* wait until infoLen is valid */ | ||
1294 | for (i = 0; i < 6000; i++) { /* max waiting time of 1 min */ | ||
1295 | io_read_num_rec_bytes(iobase, &s); | ||
1296 | if (s >= 3) { | ||
1297 | infolen = inb(REG_FLAGS1(iobase)); | ||
1298 | DEBUGP(4, dev, "infolen=%d\n", infolen); | ||
1299 | break; | ||
1300 | } | ||
1301 | msleep_interruptible(10); | ||
1302 | } | ||
1303 | if (i == 6000) { | ||
1304 | DEBUGP(4, dev, "timeout waiting for infoLen\n"); | ||
1305 | rc = -EIO; | ||
1306 | goto release_io; | ||
1307 | } | ||
1308 | } else | ||
1309 | clear_bit(IS_PROCBYTE_PRESENT, &dev->flags); | ||
1310 | |||
1311 | /* numRecBytes | bit9 of numRecytes */ | ||
1312 | io_read_num_rec_bytes(iobase, &dev->rlen); | ||
1313 | for (i = 0; i < 600; i++) { /* max waiting time of 2 sec */ | ||
1314 | if (dev->proto) { | ||
1315 | if (dev->rlen >= infolen + 4) | ||
1316 | break; | ||
1317 | } | ||
1318 | msleep_interruptible(10); | ||
1319 | /* numRecBytes | bit9 of numRecytes */ | ||
1320 | io_read_num_rec_bytes(iobase, &s); | ||
1321 | if (s > dev->rlen) { | ||
1322 | DEBUGP(1, dev, "NumRecBytes inc (reset timeout)\n"); | ||
1323 | i = 0; /* reset timeout */ | ||
1324 | dev->rlen = s; | ||
1325 | } | ||
1326 | /* T=0: we are done when numRecBytes doesn't | ||
1327 | * increment any more and NoProcedureByte | ||
1328 | * is set and numRecBytes == bytes sent + 6 | ||
1329 | * (header bytes + data + 1 for sw2) | ||
1330 | * except when the card replies an error | ||
1331 | * which means, no data will be sent back. | ||
1332 | */ | ||
1333 | else if (dev->proto == 0) { | ||
1334 | if ((inb(REG_BUF_ADDR(iobase)) & 0x80)) { | ||
1335 | /* no procedure byte received since last read */ | ||
1336 | DEBUGP(1, dev, "NoProcedure byte set\n"); | ||
1337 | /* i=0; */ | ||
1338 | } else { | ||
1339 | /* procedure byte received since last read */ | ||
1340 | DEBUGP(1, dev, "NoProcedure byte unset " | ||
1341 | "(reset timeout)\n"); | ||
1342 | dev->procbyte = inb(REG_FLAGS1(iobase)); | ||
1343 | DEBUGP(1, dev, "Read procedure byte 0x%.2x\n", | ||
1344 | dev->procbyte); | ||
1345 | i = 0; /* resettimeout */ | ||
1346 | } | ||
1347 | if (inb(REG_FLAGS0(iobase)) & 0x08) { | ||
1348 | DEBUGP(1, dev, "T0Done flag (read reply)\n"); | ||
1349 | break; | ||
1350 | } | ||
1351 | } | ||
1352 | if (dev->proto) | ||
1353 | infolen = inb(REG_FLAGS1(iobase)); | ||
1354 | } | ||
1355 | if (i == 600) { | ||
1356 | DEBUGP(1, dev, "timeout waiting for numRecBytes\n"); | ||
1357 | rc = -EIO; | ||
1358 | goto release_io; | ||
1359 | } else { | ||
1360 | if (dev->proto == 0) { | ||
1361 | DEBUGP(1, dev, "Wait for T0Done bit to be set\n"); | ||
1362 | for (i = 0; i < 1000; i++) { | ||
1363 | if (inb(REG_FLAGS0(iobase)) & 0x08) | ||
1364 | break; | ||
1365 | msleep_interruptible(10); | ||
1366 | } | ||
1367 | if (i == 1000) { | ||
1368 | DEBUGP(1, dev, "timeout waiting for T0Done\n"); | ||
1369 | rc = -EIO; | ||
1370 | goto release_io; | ||
1371 | } | ||
1372 | |||
1373 | dev->procbyte = inb(REG_FLAGS1(iobase)); | ||
1374 | DEBUGP(4, dev, "Read procedure byte 0x%.2x\n", | ||
1375 | dev->procbyte); | ||
1376 | |||
1377 | io_read_num_rec_bytes(iobase, &dev->rlen); | ||
1378 | DEBUGP(4, dev, "Read NumRecBytes = %i\n", dev->rlen); | ||
1379 | |||
1380 | } | ||
1381 | } | ||
1382 | /* T=1: read offset=zero, T=0: read offset=after challenge */ | ||
1383 | dev->rpos = dev->proto ? 0 : nr == 4 ? 5 : nr > dev->rlen ? 5 : nr; | ||
1384 | DEBUGP(4, dev, "dev->rlen = %i, dev->rpos = %i, nr = %i\n", | ||
1385 | dev->rlen, dev->rpos, nr); | ||
1386 | |||
1387 | release_io: | ||
1388 | DEBUGP(4, dev, "Reset SM\n"); | ||
1389 | xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */ | ||
1390 | |||
1391 | if (rc < 0) { | ||
1392 | DEBUGP(4, dev, "Write failed but clear T_Active\n"); | ||
1393 | dev->flags1 &= 0xdf; | ||
1394 | xoutb(dev->flags1, REG_FLAGS1(iobase)); | ||
1395 | } | ||
1396 | |||
1397 | clear_bit(LOCK_IO, &dev->flags); | ||
1398 | wake_up_interruptible(&dev->ioq); | ||
1399 | wake_up_interruptible(&dev->readq); /* tell read we have data */ | ||
1400 | |||
1401 | /* ITSEC E2: clear write buffer */ | ||
1402 | memset((char *)dev->sbuf, 0, 512); | ||
1403 | |||
1404 | /* return error or actually written bytes */ | ||
1405 | DEBUGP(2, dev, "<- cmm_write\n"); | ||
1406 | return rc < 0 ? rc : nr; | ||
1407 | } | ||
1408 | |||
1409 | static void start_monitor(struct cm4000_dev *dev) | ||
1410 | { | ||
1411 | DEBUGP(3, dev, "-> start_monitor\n"); | ||
1412 | if (!dev->monitor_running) { | ||
1413 | DEBUGP(5, dev, "create, init and add timer\n"); | ||
1414 | init_timer(&dev->timer); | ||
1415 | dev->monitor_running = 1; | ||
1416 | dev->timer.expires = jiffies; | ||
1417 | dev->timer.data = (unsigned long) dev; | ||
1418 | dev->timer.function = monitor_card; | ||
1419 | add_timer(&dev->timer); | ||
1420 | } else | ||
1421 | DEBUGP(5, dev, "monitor already running\n"); | ||
1422 | DEBUGP(3, dev, "<- start_monitor\n"); | ||
1423 | } | ||
1424 | |||
1425 | static void stop_monitor(struct cm4000_dev *dev) | ||
1426 | { | ||
1427 | DEBUGP(3, dev, "-> stop_monitor\n"); | ||
1428 | if (dev->monitor_running) { | ||
1429 | DEBUGP(5, dev, "stopping monitor\n"); | ||
1430 | terminate_monitor(dev); | ||
1431 | /* reset monitor SM */ | ||
1432 | clear_bit(IS_ATR_VALID, &dev->flags); | ||
1433 | clear_bit(IS_ATR_PRESENT, &dev->flags); | ||
1434 | } else | ||
1435 | DEBUGP(5, dev, "monitor already stopped\n"); | ||
1436 | DEBUGP(3, dev, "<- stop_monitor\n"); | ||
1437 | } | ||
1438 | |||
1439 | static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | ||
1440 | unsigned long arg) | ||
1441 | { | ||
1442 | struct cm4000_dev *dev = filp->private_data; | ||
1443 | ioaddr_t iobase = dev->link.io.BasePort1; | ||
1444 | dev_link_t *link; | ||
1445 | int size; | ||
1446 | int rc; | ||
1447 | #ifdef PCMCIA_DEBUG | ||
1448 | char *ioctl_names[CM_IOC_MAXNR + 1] = { | ||
1449 | [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS", | ||
1450 | [_IOC_NR(CM_IOCGATR)] "CM_IOCGATR", | ||
1451 | [_IOC_NR(CM_IOCARDOFF)] "CM_IOCARDOFF", | ||
1452 | [_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS", | ||
1453 | [_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL", | ||
1454 | }; | ||
1455 | #endif | ||
1456 | DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode), | ||
1457 | iminor(inode), ioctl_names[_IOC_NR(cmd)]); | ||
1458 | |||
1459 | link = dev_table[iminor(inode)]; | ||
1460 | if (!(DEV_OK(link))) { | ||
1461 | DEBUGP(4, dev, "DEV_OK false\n"); | ||
1462 | return -ENODEV; | ||
1463 | } | ||
1464 | |||
1465 | if (test_bit(IS_CMM_ABSENT, &dev->flags)) { | ||
1466 | DEBUGP(4, dev, "CMM_ABSENT flag set\n"); | ||
1467 | return -ENODEV; | ||
1468 | } | ||
1469 | |||
1470 | if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) { | ||
1471 | DEBUGP(4, dev, "ioctype mismatch\n"); | ||
1472 | return -EINVAL; | ||
1473 | } | ||
1474 | if (_IOC_NR(cmd) > CM_IOC_MAXNR) { | ||
1475 | DEBUGP(4, dev, "iocnr mismatch\n"); | ||
1476 | return -EINVAL; | ||
1477 | } | ||
1478 | size = _IOC_SIZE(cmd); | ||
1479 | rc = 0; | ||
1480 | DEBUGP(4, dev, "iocdir=%.4x iocr=%.4x iocw=%.4x iocsize=%d cmd=%.4x\n", | ||
1481 | _IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd); | ||
1482 | |||
1483 | if (_IOC_DIR(cmd) & _IOC_READ) { | ||
1484 | if (!access_ok(VERIFY_WRITE, (void *)arg, size)) | ||
1485 | return -EFAULT; | ||
1486 | } | ||
1487 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | ||
1488 | if (!access_ok(VERIFY_READ, (void *)arg, size)) | ||
1489 | return -EFAULT; | ||
1490 | } | ||
1491 | |||
1492 | switch (cmd) { | ||
1493 | case CM_IOCGSTATUS: | ||
1494 | DEBUGP(4, dev, " ... in CM_IOCGSTATUS\n"); | ||
1495 | { | ||
1496 | int status; | ||
1497 | |||
1498 | /* clear other bits, but leave inserted & powered as | ||
1499 | * they are */ | ||
1500 | status = dev->flags0 & 3; | ||
1501 | if (test_bit(IS_ATR_PRESENT, &dev->flags)) | ||
1502 | status |= CM_ATR_PRESENT; | ||
1503 | if (test_bit(IS_ATR_VALID, &dev->flags)) | ||
1504 | status |= CM_ATR_VALID; | ||
1505 | if (test_bit(IS_CMM_ABSENT, &dev->flags)) | ||
1506 | status |= CM_NO_READER; | ||
1507 | if (test_bit(IS_BAD_CARD, &dev->flags)) | ||
1508 | status |= CM_BAD_CARD; | ||
1509 | if (copy_to_user((int *)arg, &status, sizeof(int))) | ||
1510 | return -EFAULT; | ||
1511 | } | ||
1512 | return 0; | ||
1513 | case CM_IOCGATR: | ||
1514 | DEBUGP(4, dev, "... in CM_IOCGATR\n"); | ||
1515 | { | ||
1516 | struct atreq *atreq = (struct atreq *) arg; | ||
1517 | int tmp; | ||
1518 | /* allow nonblocking io and being interrupted */ | ||
1519 | if (wait_event_interruptible | ||
1520 | (dev->atrq, | ||
1521 | ((filp->f_flags & O_NONBLOCK) | ||
1522 | || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) | ||
1523 | != 0)))) { | ||
1524 | if (filp->f_flags & O_NONBLOCK) | ||
1525 | return -EAGAIN; | ||
1526 | return -ERESTARTSYS; | ||
1527 | } | ||
1528 | |||
1529 | if (test_bit(IS_ATR_VALID, &dev->flags) == 0) { | ||
1530 | tmp = -1; | ||
1531 | if (copy_to_user(&(atreq->atr_len), &tmp, | ||
1532 | sizeof(int))) | ||
1533 | return -EFAULT; | ||
1534 | } else { | ||
1535 | if (copy_to_user(atreq->atr, dev->atr, | ||
1536 | dev->atr_len)) | ||
1537 | return -EFAULT; | ||
1538 | |||
1539 | tmp = dev->atr_len; | ||
1540 | if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int))) | ||
1541 | return -EFAULT; | ||
1542 | } | ||
1543 | return 0; | ||
1544 | } | ||
1545 | case CM_IOCARDOFF: | ||
1546 | |||
1547 | #ifdef PCMCIA_DEBUG | ||
1548 | DEBUGP(4, dev, "... in CM_IOCARDOFF\n"); | ||
1549 | if (dev->flags0 & 0x01) { | ||
1550 | DEBUGP(4, dev, " Card inserted\n"); | ||
1551 | } else { | ||
1552 | DEBUGP(2, dev, " No card inserted\n"); | ||
1553 | } | ||
1554 | if (dev->flags0 & 0x02) { | ||
1555 | DEBUGP(4, dev, " Card powered\n"); | ||
1556 | } else { | ||
1557 | DEBUGP(2, dev, " Card not powered\n"); | ||
1558 | } | ||
1559 | #endif | ||
1560 | |||
1561 | /* is a card inserted and powered? */ | ||
1562 | if ((dev->flags0 & 0x01) && (dev->flags0 & 0x02)) { | ||
1563 | |||
1564 | /* get IO lock */ | ||
1565 | if (wait_event_interruptible | ||
1566 | (dev->ioq, | ||
1567 | ((filp->f_flags & O_NONBLOCK) | ||
1568 | || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) | ||
1569 | == 0)))) { | ||
1570 | if (filp->f_flags & O_NONBLOCK) | ||
1571 | return -EAGAIN; | ||
1572 | return -ERESTARTSYS; | ||
1573 | } | ||
1574 | /* Set Flags0 = 0x42 */ | ||
1575 | DEBUGP(4, dev, "Set Flags0=0x42 \n"); | ||
1576 | xoutb(0x42, REG_FLAGS0(iobase)); | ||
1577 | clear_bit(IS_ATR_PRESENT, &dev->flags); | ||
1578 | clear_bit(IS_ATR_VALID, &dev->flags); | ||
1579 | dev->mstate = M_CARDOFF; | ||
1580 | clear_bit(LOCK_IO, &dev->flags); | ||
1581 | if (wait_event_interruptible | ||
1582 | (dev->atrq, | ||
1583 | ((filp->f_flags & O_NONBLOCK) | ||
1584 | || (test_bit(IS_ATR_VALID, (void *)&dev->flags) != | ||
1585 | 0)))) { | ||
1586 | if (filp->f_flags & O_NONBLOCK) | ||
1587 | return -EAGAIN; | ||
1588 | return -ERESTARTSYS; | ||
1589 | } | ||
1590 | } | ||
1591 | /* release lock */ | ||
1592 | clear_bit(LOCK_IO, &dev->flags); | ||
1593 | wake_up_interruptible(&dev->ioq); | ||
1594 | |||
1595 | return 0; | ||
1596 | case CM_IOCSPTS: | ||
1597 | { | ||
1598 | struct ptsreq krnptsreq; | ||
1599 | |||
1600 | if (copy_from_user(&krnptsreq, (struct ptsreq *) arg, | ||
1601 | sizeof(struct ptsreq))) | ||
1602 | return -EFAULT; | ||
1603 | |||
1604 | rc = 0; | ||
1605 | DEBUGP(4, dev, "... in CM_IOCSPTS\n"); | ||
1606 | /* wait for ATR to get valid */ | ||
1607 | if (wait_event_interruptible | ||
1608 | (dev->atrq, | ||
1609 | ((filp->f_flags & O_NONBLOCK) | ||
1610 | || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) | ||
1611 | != 0)))) { | ||
1612 | if (filp->f_flags & O_NONBLOCK) | ||
1613 | return -EAGAIN; | ||
1614 | return -ERESTARTSYS; | ||
1615 | } | ||
1616 | /* get IO lock */ | ||
1617 | if (wait_event_interruptible | ||
1618 | (dev->ioq, | ||
1619 | ((filp->f_flags & O_NONBLOCK) | ||
1620 | || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) | ||
1621 | == 0)))) { | ||
1622 | if (filp->f_flags & O_NONBLOCK) | ||
1623 | return -EAGAIN; | ||
1624 | return -ERESTARTSYS; | ||
1625 | } | ||
1626 | |||
1627 | if ((rc = set_protocol(dev, &krnptsreq)) != 0) { | ||
1628 | /* auto power_on again */ | ||
1629 | dev->mstate = M_FETCH_ATR; | ||
1630 | clear_bit(IS_ATR_VALID, &dev->flags); | ||
1631 | } | ||
1632 | /* release lock */ | ||
1633 | clear_bit(LOCK_IO, &dev->flags); | ||
1634 | wake_up_interruptible(&dev->ioq); | ||
1635 | |||
1636 | } | ||
1637 | return rc; | ||
1638 | #ifdef PCMCIA_DEBUG | ||
1639 | case CM_IOSDBGLVL: /* set debug log level */ | ||
1640 | { | ||
1641 | int old_pc_debug = 0; | ||
1642 | |||
1643 | old_pc_debug = pc_debug; | ||
1644 | if (copy_from_user(&pc_debug, (int *)arg, sizeof(int))) | ||
1645 | return -EFAULT; | ||
1646 | |||
1647 | if (old_pc_debug != pc_debug) | ||
1648 | DEBUGP(0, dev, "Changed debug log level " | ||
1649 | "to %i\n", pc_debug); | ||
1650 | } | ||
1651 | return rc; | ||
1652 | #endif | ||
1653 | default: | ||
1654 | DEBUGP(4, dev, "... in default (unknown IOCTL code)\n"); | ||
1655 | return -EINVAL; | ||
1656 | } | ||
1657 | } | ||
1658 | |||
1659 | static int cmm_open(struct inode *inode, struct file *filp) | ||
1660 | { | ||
1661 | struct cm4000_dev *dev; | ||
1662 | dev_link_t *link; | ||
1663 | int rc, minor = iminor(inode); | ||
1664 | |||
1665 | if (minor >= CM4000_MAX_DEV) | ||
1666 | return -ENODEV; | ||
1667 | |||
1668 | link = dev_table[minor]; | ||
1669 | if (link == NULL || !(DEV_OK(link))) | ||
1670 | return -ENODEV; | ||
1671 | |||
1672 | if (link->open) | ||
1673 | return -EBUSY; | ||
1674 | |||
1675 | dev = link->priv; | ||
1676 | filp->private_data = dev; | ||
1677 | |||
1678 | DEBUGP(2, dev, "-> cmm_open(device=%d.%d process=%s,%d)\n", | ||
1679 | imajor(inode), minor, current->comm, current->pid); | ||
1680 | |||
1681 | /* init device variables, they may be "polluted" after close | ||
1682 | * or, the device may never have been closed (i.e. open failed) | ||
1683 | */ | ||
1684 | |||
1685 | ZERO_DEV(dev); | ||
1686 | |||
1687 | /* opening will always block since the | ||
1688 | * monitor will be started by open, which | ||
1689 | * means we have to wait for ATR becoming | ||
1690 | * vaild = block until valid (or card | ||
1691 | * inserted) | ||
1692 | */ | ||
1693 | if (filp->f_flags & O_NONBLOCK) | ||
1694 | return -EAGAIN; | ||
1695 | |||
1696 | dev->mdelay = T_50MSEC; | ||
1697 | |||
1698 | /* start monitoring the cardstatus */ | ||
1699 | start_monitor(dev); | ||
1700 | |||
1701 | link->open = 1; /* only one open per device */ | ||
1702 | rc = 0; | ||
1703 | |||
1704 | DEBUGP(2, dev, "<- cmm_open\n"); | ||
1705 | return nonseekable_open(inode, filp); | ||
1706 | } | ||
1707 | |||
1708 | static int cmm_close(struct inode *inode, struct file *filp) | ||
1709 | { | ||
1710 | struct cm4000_dev *dev; | ||
1711 | dev_link_t *link; | ||
1712 | int minor = iminor(inode); | ||
1713 | |||
1714 | if (minor >= CM4000_MAX_DEV) | ||
1715 | return -ENODEV; | ||
1716 | |||
1717 | link = dev_table[minor]; | ||
1718 | if (link == NULL) | ||
1719 | return -ENODEV; | ||
1720 | |||
1721 | dev = link->priv; | ||
1722 | |||
1723 | DEBUGP(2, dev, "-> cmm_close(maj/min=%d.%d)\n", | ||
1724 | imajor(inode), minor); | ||
1725 | |||
1726 | stop_monitor(dev); | ||
1727 | |||
1728 | ZERO_DEV(dev); | ||
1729 | |||
1730 | link->open = 0; /* only one open per device */ | ||
1731 | wake_up(&dev->devq); /* socket removed? */ | ||
1732 | |||
1733 | DEBUGP(2, dev, "cmm_close\n"); | ||
1734 | return 0; | ||
1735 | } | ||
1736 | |||
1737 | static void cmm_cm4000_release(dev_link_t * link) | ||
1738 | { | ||
1739 | struct cm4000_dev *dev = link->priv; | ||
1740 | |||
1741 | /* dont terminate the monitor, rather rely on | ||
1742 | * close doing that for us. | ||
1743 | */ | ||
1744 | DEBUGP(3, dev, "-> cmm_cm4000_release\n"); | ||
1745 | while (link->open) { | ||
1746 | printk(KERN_INFO MODULE_NAME ": delaying release until " | ||
1747 | "process has terminated\n"); | ||
1748 | /* note: don't interrupt us: | ||
1749 | * close the applications which own | ||
1750 | * the devices _first_ ! | ||
1751 | */ | ||
1752 | wait_event(dev->devq, (link->open == 0)); | ||
1753 | } | ||
1754 | /* dev->devq=NULL; this cannot be zeroed earlier */ | ||
1755 | DEBUGP(3, dev, "<- cmm_cm4000_release\n"); | ||
1756 | return; | ||
1757 | } | ||
1758 | |||
1759 | /*==== Interface to PCMCIA Layer =======================================*/ | ||
1760 | |||
1761 | static void cm4000_config(dev_link_t * link, int devno) | ||
1762 | { | ||
1763 | client_handle_t handle = link->handle; | ||
1764 | struct cm4000_dev *dev; | ||
1765 | tuple_t tuple; | ||
1766 | cisparse_t parse; | ||
1767 | config_info_t conf; | ||
1768 | u_char buf[64]; | ||
1769 | int fail_fn, fail_rc; | ||
1770 | int rc; | ||
1771 | |||
1772 | /* read the config-tuples */ | ||
1773 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
1774 | tuple.Attributes = 0; | ||
1775 | tuple.TupleData = buf; | ||
1776 | tuple.TupleDataMax = sizeof(buf); | ||
1777 | tuple.TupleOffset = 0; | ||
1778 | |||
1779 | if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) { | ||
1780 | fail_fn = GetFirstTuple; | ||
1781 | goto cs_failed; | ||
1782 | } | ||
1783 | if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) { | ||
1784 | fail_fn = GetTupleData; | ||
1785 | goto cs_failed; | ||
1786 | } | ||
1787 | if ((fail_rc = | ||
1788 | pcmcia_parse_tuple(handle, &tuple, &parse)) != CS_SUCCESS) { | ||
1789 | fail_fn = ParseTuple; | ||
1790 | goto cs_failed; | ||
1791 | } | ||
1792 | if ((fail_rc = | ||
1793 | pcmcia_get_configuration_info(handle, &conf)) != CS_SUCCESS) { | ||
1794 | fail_fn = GetConfigurationInfo; | ||
1795 | goto cs_failed; | ||
1796 | } | ||
1797 | |||
1798 | link->state |= DEV_CONFIG; | ||
1799 | link->conf.ConfigBase = parse.config.base; | ||
1800 | link->conf.Present = parse.config.rmask[0]; | ||
1801 | link->conf.Vcc = conf.Vcc; | ||
1802 | |||
1803 | link->io.BasePort2 = 0; | ||
1804 | link->io.NumPorts2 = 0; | ||
1805 | link->io.Attributes2 = 0; | ||
1806 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
1807 | for (rc = pcmcia_get_first_tuple(handle, &tuple); | ||
1808 | rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(handle, &tuple)) { | ||
1809 | |||
1810 | rc = pcmcia_get_tuple_data(handle, &tuple); | ||
1811 | if (rc != CS_SUCCESS) | ||
1812 | continue; | ||
1813 | rc = pcmcia_parse_tuple(handle, &tuple, &parse); | ||
1814 | if (rc != CS_SUCCESS) | ||
1815 | continue; | ||
1816 | |||
1817 | link->conf.ConfigIndex = parse.cftable_entry.index; | ||
1818 | |||
1819 | if (!parse.cftable_entry.io.nwin) | ||
1820 | continue; | ||
1821 | |||
1822 | /* Get the IOaddr */ | ||
1823 | link->io.BasePort1 = parse.cftable_entry.io.win[0].base; | ||
1824 | link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; | ||
1825 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
1826 | if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT)) | ||
1827 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
1828 | if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT)) | ||
1829 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
1830 | link->io.IOAddrLines = parse.cftable_entry.io.flags | ||
1831 | & CISTPL_IO_LINES_MASK; | ||
1832 | |||
1833 | rc = pcmcia_request_io(handle, &link->io); | ||
1834 | if (rc == CS_SUCCESS) | ||
1835 | break; /* we are done */ | ||
1836 | } | ||
1837 | if (rc != CS_SUCCESS) | ||
1838 | goto cs_release; | ||
1839 | |||
1840 | link->conf.IntType = 00000002; | ||
1841 | |||
1842 | if ((fail_rc = | ||
1843 | pcmcia_request_configuration(handle, &link->conf)) != CS_SUCCESS) { | ||
1844 | fail_fn = RequestConfiguration; | ||
1845 | goto cs_release; | ||
1846 | } | ||
1847 | |||
1848 | dev = link->priv; | ||
1849 | sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); | ||
1850 | dev->node.major = major; | ||
1851 | dev->node.minor = devno; | ||
1852 | dev->node.next = NULL; | ||
1853 | link->dev = &dev->node; | ||
1854 | link->state &= ~DEV_CONFIG_PENDING; | ||
1855 | |||
1856 | return; | ||
1857 | |||
1858 | cs_failed: | ||
1859 | cs_error(handle, fail_fn, fail_rc); | ||
1860 | cs_release: | ||
1861 | cm4000_release(link); | ||
1862 | |||
1863 | link->state &= ~DEV_CONFIG_PENDING; | ||
1864 | } | ||
1865 | |||
1866 | static int cm4000_event(event_t event, int priority, | ||
1867 | event_callback_args_t *args) | ||
1868 | { | ||
1869 | dev_link_t *link; | ||
1870 | struct cm4000_dev *dev; | ||
1871 | int devno; | ||
1872 | |||
1873 | link = args->client_data; | ||
1874 | dev = link->priv; | ||
1875 | |||
1876 | DEBUGP(3, dev, "-> cm4000_event\n"); | ||
1877 | for (devno = 0; devno < CM4000_MAX_DEV; devno++) | ||
1878 | if (dev_table[devno] == link) | ||
1879 | break; | ||
1880 | |||
1881 | if (devno == CM4000_MAX_DEV) | ||
1882 | return CS_BAD_ADAPTER; | ||
1883 | |||
1884 | switch (event) { | ||
1885 | case CS_EVENT_CARD_INSERTION: | ||
1886 | DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n"); | ||
1887 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
1888 | cm4000_config(link, devno); | ||
1889 | break; | ||
1890 | case CS_EVENT_CARD_REMOVAL: | ||
1891 | DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); | ||
1892 | link->state &= ~DEV_PRESENT; | ||
1893 | stop_monitor(dev); | ||
1894 | break; | ||
1895 | case CS_EVENT_PM_SUSPEND: | ||
1896 | DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND " | ||
1897 | "(fall-through to CS_EVENT_RESET_PHYSICAL)\n"); | ||
1898 | link->state |= DEV_SUSPEND; | ||
1899 | /* fall-through */ | ||
1900 | case CS_EVENT_RESET_PHYSICAL: | ||
1901 | DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n"); | ||
1902 | if (link->state & DEV_CONFIG) { | ||
1903 | DEBUGP(5, dev, "ReleaseConfiguration\n"); | ||
1904 | pcmcia_release_configuration(link->handle); | ||
1905 | } | ||
1906 | stop_monitor(dev); | ||
1907 | break; | ||
1908 | case CS_EVENT_PM_RESUME: | ||
1909 | DEBUGP(5, dev, "CS_EVENT_PM_RESUME " | ||
1910 | "(fall-through to CS_EVENT_CARD_RESET)\n"); | ||
1911 | link->state &= ~DEV_SUSPEND; | ||
1912 | /* fall-through */ | ||
1913 | case CS_EVENT_CARD_RESET: | ||
1914 | DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n"); | ||
1915 | if ((link->state & DEV_CONFIG)) { | ||
1916 | DEBUGP(5, dev, "RequestConfiguration\n"); | ||
1917 | pcmcia_request_configuration(link->handle, &link->conf); | ||
1918 | } | ||
1919 | if (link->open) | ||
1920 | start_monitor(dev); | ||
1921 | break; | ||
1922 | default: | ||
1923 | DEBUGP(5, dev, "unknown event %.2x\n", event); | ||
1924 | break; | ||
1925 | } | ||
1926 | DEBUGP(3, dev, "<- cm4000_event\n"); | ||
1927 | return CS_SUCCESS; | ||
1928 | } | ||
1929 | |||
1930 | static void cm4000_release(dev_link_t *link) | ||
1931 | { | ||
1932 | cmm_cm4000_release(link->priv); /* delay release until device closed */ | ||
1933 | pcmcia_release_configuration(link->handle); | ||
1934 | pcmcia_release_io(link->handle, &link->io); | ||
1935 | } | ||
1936 | |||
1937 | static dev_link_t *cm4000_attach(void) | ||
1938 | { | ||
1939 | struct cm4000_dev *dev; | ||
1940 | dev_link_t *link; | ||
1941 | client_reg_t client_reg; | ||
1942 | int i; | ||
1943 | |||
1944 | for (i = 0; i < CM4000_MAX_DEV; i++) | ||
1945 | if (dev_table[i] == NULL) | ||
1946 | break; | ||
1947 | |||
1948 | if (i == CM4000_MAX_DEV) { | ||
1949 | printk(KERN_NOTICE MODULE_NAME ": all devices in use\n"); | ||
1950 | return NULL; | ||
1951 | } | ||
1952 | |||
1953 | /* create a new cm4000_cs device */ | ||
1954 | dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL); | ||
1955 | if (dev == NULL) | ||
1956 | return NULL; | ||
1957 | |||
1958 | link = &dev->link; | ||
1959 | link->priv = dev; | ||
1960 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
1961 | dev_table[i] = link; | ||
1962 | |||
1963 | /* register with card services */ | ||
1964 | client_reg.dev_info = &dev_info; | ||
1965 | client_reg.EventMask = | ||
1966 | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | | ||
1967 | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | | ||
1968 | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; | ||
1969 | client_reg.Version = 0x0210; | ||
1970 | client_reg.event_callback_args.client_data = link; | ||
1971 | |||
1972 | i = pcmcia_register_client(&link->handle, &client_reg); | ||
1973 | if (i) { | ||
1974 | cs_error(link->handle, RegisterClient, i); | ||
1975 | cm4000_detach(link); | ||
1976 | return NULL; | ||
1977 | } | ||
1978 | |||
1979 | init_waitqueue_head(&dev->devq); | ||
1980 | init_waitqueue_head(&dev->ioq); | ||
1981 | init_waitqueue_head(&dev->atrq); | ||
1982 | init_waitqueue_head(&dev->readq); | ||
1983 | |||
1984 | return link; | ||
1985 | } | ||
1986 | |||
1987 | static void cm4000_detach_by_devno(int devno, dev_link_t * link) | ||
1988 | { | ||
1989 | struct cm4000_dev *dev = link->priv; | ||
1990 | |||
1991 | DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno); | ||
1992 | |||
1993 | if (link->state & DEV_CONFIG) { | ||
1994 | DEBUGP(5, dev, "device still configured (try to release it)\n"); | ||
1995 | cm4000_release(link); | ||
1996 | } | ||
1997 | |||
1998 | if (link->handle) { | ||
1999 | pcmcia_deregister_client(link->handle); | ||
2000 | } | ||
2001 | |||
2002 | dev_table[devno] = NULL; | ||
2003 | kfree(dev); | ||
2004 | return; | ||
2005 | } | ||
2006 | |||
2007 | static void cm4000_detach(dev_link_t * link) | ||
2008 | { | ||
2009 | int i; | ||
2010 | |||
2011 | /* find device */ | ||
2012 | for (i = 0; i < CM4000_MAX_DEV; i++) | ||
2013 | if (dev_table[i] == link) | ||
2014 | break; | ||
2015 | |||
2016 | if (i == CM4000_MAX_DEV) | ||
2017 | return; | ||
2018 | |||
2019 | cm4000_detach_by_devno(i, link); | ||
2020 | return; | ||
2021 | } | ||
2022 | |||
2023 | static struct file_operations cm4000_fops = { | ||
2024 | .owner = THIS_MODULE, | ||
2025 | .read = cmm_read, | ||
2026 | .write = cmm_write, | ||
2027 | .ioctl = cmm_ioctl, | ||
2028 | .open = cmm_open, | ||
2029 | .release= cmm_close, | ||
2030 | }; | ||
2031 | |||
2032 | static struct pcmcia_device_id cm4000_ids[] = { | ||
2033 | PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0002), | ||
2034 | PCMCIA_DEVICE_PROD_ID12("CardMan", "4000", 0x2FB368CA, 0xA2BD8C39), | ||
2035 | PCMCIA_DEVICE_NULL, | ||
2036 | }; | ||
2037 | MODULE_DEVICE_TABLE(pcmcia, cm4000_ids); | ||
2038 | |||
2039 | static struct pcmcia_driver cm4000_driver = { | ||
2040 | .owner = THIS_MODULE, | ||
2041 | .drv = { | ||
2042 | .name = "cm4000_cs", | ||
2043 | }, | ||
2044 | .attach = cm4000_attach, | ||
2045 | .detach = cm4000_detach, | ||
2046 | .event = cm4000_event, | ||
2047 | .id_table = cm4000_ids, | ||
2048 | }; | ||
2049 | |||
2050 | static int __init cmm_init(void) | ||
2051 | { | ||
2052 | printk(KERN_INFO "%s\n", version); | ||
2053 | pcmcia_register_driver(&cm4000_driver); | ||
2054 | major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); | ||
2055 | if (major < 0) { | ||
2056 | printk(KERN_WARNING MODULE_NAME | ||
2057 | ": could not get major number\n"); | ||
2058 | return -1; | ||
2059 | } | ||
2060 | |||
2061 | return 0; | ||
2062 | } | ||
2063 | |||
2064 | static void __exit cmm_exit(void) | ||
2065 | { | ||
2066 | int i; | ||
2067 | |||
2068 | printk(KERN_INFO MODULE_NAME ": unloading\n"); | ||
2069 | pcmcia_unregister_driver(&cm4000_driver); | ||
2070 | for (i = 0; i < CM4000_MAX_DEV; i++) | ||
2071 | if (dev_table[i]) | ||
2072 | cm4000_detach_by_devno(i, dev_table[i]); | ||
2073 | unregister_chrdev(major, DEVICE_NAME); | ||
2074 | }; | ||
2075 | |||
2076 | module_init(cmm_init); | ||
2077 | module_exit(cmm_exit); | ||
2078 | MODULE_LICENSE("Dual BSD/GPL"); | ||
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c new file mode 100644 index 000000000000..4c698d908ffa --- /dev/null +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -0,0 +1,841 @@ | |||
1 | /* | ||
2 | * A driver for the Omnikey PCMCIA smartcard reader CardMan 4040 | ||
3 | * | ||
4 | * (c) 2000-2004 Omnikey AG (http://www.omnikey.com/) | ||
5 | * | ||
6 | * (C) 2005 Harald Welte <laforge@gnumonks.org> | ||
7 | * - add support for poll() | ||
8 | * - driver cleanup | ||
9 | * - add waitqueues | ||
10 | * - adhere to linux kernel coding style and policies | ||
11 | * - support 2.6.13 "new style" pcmcia interface | ||
12 | * | ||
13 | * The device basically is a USB CCID compliant device that has been | ||
14 | * attached to an I/O-Mapped FIFO. | ||
15 | * | ||
16 | * All rights reserved, Dual BSD/GPL Licensed. | ||
17 | */ | ||
18 | |||
19 | /* #define PCMCIA_DEBUG 6 */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/fs.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/poll.h> | ||
28 | #include <linux/wait.h> | ||
29 | #include <asm/uaccess.h> | ||
30 | #include <asm/io.h> | ||
31 | |||
32 | #include <pcmcia/cs_types.h> | ||
33 | #include <pcmcia/cs.h> | ||
34 | #include <pcmcia/cistpl.h> | ||
35 | #include <pcmcia/cisreg.h> | ||
36 | #include <pcmcia/ciscode.h> | ||
37 | #include <pcmcia/ds.h> | ||
38 | |||
39 | #include "cm4040_cs.h" | ||
40 | |||
41 | |||
42 | #ifdef PCMCIA_DEBUG | ||
43 | #define reader_to_dev(x) (&handle_to_dev(x->link.handle)) | ||
44 | static int pc_debug = PCMCIA_DEBUG; | ||
45 | module_param(pc_debug, int, 0600); | ||
46 | #define DEBUGP(n, rdr, x, args...) do { \ | ||
47 | if (pc_debug >= (n)) \ | ||
48 | dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ | ||
49 | __FUNCTION__ , ##args); \ | ||
50 | } while (0) | ||
51 | #else | ||
52 | #define DEBUGP(n, rdr, x, args...) | ||
53 | #endif | ||
54 | |||
55 | static char *version = | ||
56 | "OMNIKEY CardMan 4040 v1.1.0gm4 - All bugs added by Harald Welte"; | ||
57 | |||
58 | #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ) | ||
59 | #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ) | ||
60 | #define CCID_DRIVER_MINIMUM_TIMEOUT (3*HZ) | ||
61 | #define READ_WRITE_BUFFER_SIZE 512 | ||
62 | #define POLL_LOOP_COUNT 1000 | ||
63 | |||
64 | /* how often to poll for fifo status change */ | ||
65 | #define POLL_PERIOD msecs_to_jiffies(10) | ||
66 | |||
67 | static void reader_release(dev_link_t *link); | ||
68 | static void reader_detach(dev_link_t *link); | ||
69 | |||
70 | static int major; | ||
71 | |||
72 | #define BS_READABLE 0x01 | ||
73 | #define BS_WRITABLE 0x02 | ||
74 | |||
75 | struct reader_dev { | ||
76 | dev_link_t link; | ||
77 | dev_node_t node; | ||
78 | wait_queue_head_t devq; | ||
79 | wait_queue_head_t poll_wait; | ||
80 | wait_queue_head_t read_wait; | ||
81 | wait_queue_head_t write_wait; | ||
82 | unsigned long buffer_status; | ||
83 | unsigned long timeout; | ||
84 | unsigned char s_buf[READ_WRITE_BUFFER_SIZE]; | ||
85 | unsigned char r_buf[READ_WRITE_BUFFER_SIZE]; | ||
86 | struct timer_list poll_timer; | ||
87 | }; | ||
88 | |||
89 | static dev_info_t dev_info = MODULE_NAME; | ||
90 | static dev_link_t *dev_table[CM_MAX_DEV]; | ||
91 | |||
92 | #ifndef PCMCIA_DEBUG | ||
93 | #define xoutb outb | ||
94 | #define xinb inb | ||
95 | #else | ||
96 | static inline void xoutb(unsigned char val, unsigned short port) | ||
97 | { | ||
98 | if (pc_debug >= 7) | ||
99 | printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port); | ||
100 | outb(val, port); | ||
101 | } | ||
102 | |||
103 | static inline unsigned char xinb(unsigned short port) | ||
104 | { | ||
105 | unsigned char val; | ||
106 | |||
107 | val = inb(port); | ||
108 | if (pc_debug >= 7) | ||
109 | printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port); | ||
110 | return val; | ||
111 | } | ||
112 | #endif | ||
113 | |||
114 | /* poll the device fifo status register. not to be confused with | ||
115 | * the poll syscall. */ | ||
116 | static void cm4040_do_poll(unsigned long dummy) | ||
117 | { | ||
118 | struct reader_dev *dev = (struct reader_dev *) dummy; | ||
119 | unsigned int obs = xinb(dev->link.io.BasePort1 | ||
120 | + REG_OFFSET_BUFFER_STATUS); | ||
121 | |||
122 | if ((obs & BSR_BULK_IN_FULL)) { | ||
123 | set_bit(BS_READABLE, &dev->buffer_status); | ||
124 | DEBUGP(4, dev, "waking up read_wait\n"); | ||
125 | wake_up_interruptible(&dev->read_wait); | ||
126 | } else | ||
127 | clear_bit(BS_READABLE, &dev->buffer_status); | ||
128 | |||
129 | if (!(obs & BSR_BULK_OUT_FULL)) { | ||
130 | set_bit(BS_WRITABLE, &dev->buffer_status); | ||
131 | DEBUGP(4, dev, "waking up write_wait\n"); | ||
132 | wake_up_interruptible(&dev->write_wait); | ||
133 | } else | ||
134 | clear_bit(BS_WRITABLE, &dev->buffer_status); | ||
135 | |||
136 | if (dev->buffer_status) | ||
137 | wake_up_interruptible(&dev->poll_wait); | ||
138 | |||
139 | mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD); | ||
140 | } | ||
141 | |||
142 | static void cm4040_stop_poll(struct reader_dev *dev) | ||
143 | { | ||
144 | del_timer_sync(&dev->poll_timer); | ||
145 | } | ||
146 | |||
147 | static int wait_for_bulk_out_ready(struct reader_dev *dev) | ||
148 | { | ||
149 | int i, rc; | ||
150 | int iobase = dev->link.io.BasePort1; | ||
151 | |||
152 | for (i = 0; i < POLL_LOOP_COUNT; i++) { | ||
153 | if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) | ||
154 | & BSR_BULK_OUT_FULL) == 0) { | ||
155 | DEBUGP(4, dev, "BulkOut empty (i=%d)\n", i); | ||
156 | return 1; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n", | ||
161 | dev->timeout); | ||
162 | rc = wait_event_interruptible_timeout(dev->write_wait, | ||
163 | test_and_clear_bit(BS_WRITABLE, | ||
164 | &dev->buffer_status), | ||
165 | dev->timeout); | ||
166 | |||
167 | if (rc > 0) | ||
168 | DEBUGP(4, dev, "woke up: BulkOut empty\n"); | ||
169 | else if (rc == 0) | ||
170 | DEBUGP(4, dev, "woke up: BulkOut full, returning 0 :(\n"); | ||
171 | else if (rc < 0) | ||
172 | DEBUGP(4, dev, "woke up: signal arrived\n"); | ||
173 | |||
174 | return rc; | ||
175 | } | ||
176 | |||
177 | /* Write to Sync Control Register */ | ||
178 | static int write_sync_reg(unsigned char val, struct reader_dev *dev) | ||
179 | { | ||
180 | int iobase = dev->link.io.BasePort1; | ||
181 | int rc; | ||
182 | |||
183 | rc = wait_for_bulk_out_ready(dev); | ||
184 | if (rc <= 0) | ||
185 | return rc; | ||
186 | |||
187 | xoutb(val, iobase + REG_OFFSET_SYNC_CONTROL); | ||
188 | rc = wait_for_bulk_out_ready(dev); | ||
189 | if (rc <= 0) | ||
190 | return rc; | ||
191 | |||
192 | return 1; | ||
193 | } | ||
194 | |||
195 | static int wait_for_bulk_in_ready(struct reader_dev *dev) | ||
196 | { | ||
197 | int i, rc; | ||
198 | int iobase = dev->link.io.BasePort1; | ||
199 | |||
200 | for (i = 0; i < POLL_LOOP_COUNT; i++) { | ||
201 | if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) | ||
202 | & BSR_BULK_IN_FULL) == BSR_BULK_IN_FULL) { | ||
203 | DEBUGP(3, dev, "BulkIn full (i=%d)\n", i); | ||
204 | return 1; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n", | ||
209 | dev->timeout); | ||
210 | rc = wait_event_interruptible_timeout(dev->read_wait, | ||
211 | test_and_clear_bit(BS_READABLE, | ||
212 | &dev->buffer_status), | ||
213 | dev->timeout); | ||
214 | if (rc > 0) | ||
215 | DEBUGP(4, dev, "woke up: BulkIn full\n"); | ||
216 | else if (rc == 0) | ||
217 | DEBUGP(4, dev, "woke up: BulkIn not full, returning 0 :(\n"); | ||
218 | else if (rc < 0) | ||
219 | DEBUGP(4, dev, "woke up: signal arrived\n"); | ||
220 | |||
221 | return rc; | ||
222 | } | ||
223 | |||
224 | static ssize_t cm4040_read(struct file *filp, char __user *buf, | ||
225 | size_t count, loff_t *ppos) | ||
226 | { | ||
227 | struct reader_dev *dev = filp->private_data; | ||
228 | int iobase = dev->link.io.BasePort1; | ||
229 | size_t bytes_to_read; | ||
230 | unsigned long i; | ||
231 | size_t min_bytes_to_read; | ||
232 | int rc; | ||
233 | unsigned char uc; | ||
234 | |||
235 | DEBUGP(2, dev, "-> cm4040_read(%s,%d)\n", current->comm, current->pid); | ||
236 | |||
237 | if (count == 0) | ||
238 | return 0; | ||
239 | |||
240 | if (count < 10) | ||
241 | return -EFAULT; | ||
242 | |||
243 | if (filp->f_flags & O_NONBLOCK) { | ||
244 | DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n"); | ||
245 | DEBUGP(2, dev, "<- cm4040_read (failure)\n"); | ||
246 | return -EAGAIN; | ||
247 | } | ||
248 | |||
249 | if ((dev->link.state & DEV_PRESENT)==0) | ||
250 | return -ENODEV; | ||
251 | |||
252 | for (i = 0; i < 5; i++) { | ||
253 | rc = wait_for_bulk_in_ready(dev); | ||
254 | if (rc <= 0) { | ||
255 | DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc); | ||
256 | DEBUGP(2, dev, "<- cm4040_read (failed)\n"); | ||
257 | if (rc == -ERESTARTSYS) | ||
258 | return rc; | ||
259 | return -EIO; | ||
260 | } | ||
261 | dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN); | ||
262 | #ifdef PCMCIA_DEBUG | ||
263 | if (pc_debug >= 6) | ||
264 | printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]); | ||
265 | } | ||
266 | printk("\n"); | ||
267 | #else | ||
268 | } | ||
269 | #endif | ||
270 | |||
271 | bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]); | ||
272 | |||
273 | DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read); | ||
274 | |||
275 | min_bytes_to_read = min(count, bytes_to_read + 5); | ||
276 | |||
277 | DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read); | ||
278 | |||
279 | for (i = 0; i < (min_bytes_to_read-5); i++) { | ||
280 | rc = wait_for_bulk_in_ready(dev); | ||
281 | if (rc <= 0) { | ||
282 | DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc); | ||
283 | DEBUGP(2, dev, "<- cm4040_read (failed)\n"); | ||
284 | if (rc == -ERESTARTSYS) | ||
285 | return rc; | ||
286 | return -EIO; | ||
287 | } | ||
288 | dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN); | ||
289 | #ifdef PCMCIA_DEBUG | ||
290 | if (pc_debug >= 6) | ||
291 | printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]); | ||
292 | } | ||
293 | printk("\n"); | ||
294 | #else | ||
295 | } | ||
296 | #endif | ||
297 | |||
298 | *ppos = min_bytes_to_read; | ||
299 | if (copy_to_user(buf, dev->r_buf, min_bytes_to_read)) | ||
300 | return -EFAULT; | ||
301 | |||
302 | rc = wait_for_bulk_in_ready(dev); | ||
303 | if (rc <= 0) { | ||
304 | DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc); | ||
305 | DEBUGP(2, dev, "<- cm4040_read (failed)\n"); | ||
306 | if (rc == -ERESTARTSYS) | ||
307 | return rc; | ||
308 | return -EIO; | ||
309 | } | ||
310 | |||
311 | rc = write_sync_reg(SCR_READER_TO_HOST_DONE, dev); | ||
312 | if (rc <= 0) { | ||
313 | DEBUGP(5, dev, "write_sync_reg c=%.2x\n", rc); | ||
314 | DEBUGP(2, dev, "<- cm4040_read (failed)\n"); | ||
315 | if (rc == -ERESTARTSYS) | ||
316 | return rc; | ||
317 | else | ||
318 | return -EIO; | ||
319 | } | ||
320 | |||
321 | uc = xinb(iobase + REG_OFFSET_BULK_IN); | ||
322 | |||
323 | DEBUGP(2, dev, "<- cm4040_read (successfully)\n"); | ||
324 | return min_bytes_to_read; | ||
325 | } | ||
326 | |||
327 | static ssize_t cm4040_write(struct file *filp, const char __user *buf, | ||
328 | size_t count, loff_t *ppos) | ||
329 | { | ||
330 | struct reader_dev *dev = filp->private_data; | ||
331 | int iobase = dev->link.io.BasePort1; | ||
332 | ssize_t rc; | ||
333 | int i; | ||
334 | unsigned int bytes_to_write; | ||
335 | |||
336 | DEBUGP(2, dev, "-> cm4040_write(%s,%d)\n", current->comm, current->pid); | ||
337 | |||
338 | if (count == 0) { | ||
339 | DEBUGP(2, dev, "<- cm4040_write empty read (successfully)\n"); | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | if (count < 5) { | ||
344 | DEBUGP(2, dev, "<- cm4040_write buffersize=%Zd < 5\n", count); | ||
345 | return -EIO; | ||
346 | } | ||
347 | |||
348 | if (filp->f_flags & O_NONBLOCK) { | ||
349 | DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n"); | ||
350 | DEBUGP(4, dev, "<- cm4040_write (failure)\n"); | ||
351 | return -EAGAIN; | ||
352 | } | ||
353 | |||
354 | if ((dev->link.state & DEV_PRESENT) == 0) | ||
355 | return -ENODEV; | ||
356 | |||
357 | bytes_to_write = count; | ||
358 | if (copy_from_user(dev->s_buf, buf, bytes_to_write)) | ||
359 | return -EFAULT; | ||
360 | |||
361 | switch (dev->s_buf[0]) { | ||
362 | case CMD_PC_TO_RDR_XFRBLOCK: | ||
363 | case CMD_PC_TO_RDR_SECURE: | ||
364 | case CMD_PC_TO_RDR_TEST_SECURE: | ||
365 | case CMD_PC_TO_RDR_OK_SECURE: | ||
366 | dev->timeout = CCID_DRIVER_BULK_DEFAULT_TIMEOUT; | ||
367 | break; | ||
368 | |||
369 | case CMD_PC_TO_RDR_ICCPOWERON: | ||
370 | dev->timeout = CCID_DRIVER_ASYNC_POWERUP_TIMEOUT; | ||
371 | break; | ||
372 | |||
373 | case CMD_PC_TO_RDR_GETSLOTSTATUS: | ||
374 | case CMD_PC_TO_RDR_ICCPOWEROFF: | ||
375 | case CMD_PC_TO_RDR_GETPARAMETERS: | ||
376 | case CMD_PC_TO_RDR_RESETPARAMETERS: | ||
377 | case CMD_PC_TO_RDR_SETPARAMETERS: | ||
378 | case CMD_PC_TO_RDR_ESCAPE: | ||
379 | case CMD_PC_TO_RDR_ICCCLOCK: | ||
380 | default: | ||
381 | dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT; | ||
382 | break; | ||
383 | } | ||
384 | |||
385 | rc = write_sync_reg(SCR_HOST_TO_READER_START, dev); | ||
386 | if (rc <= 0) { | ||
387 | DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc); | ||
388 | DEBUGP(2, dev, "<- cm4040_write (failed)\n"); | ||
389 | if (rc == -ERESTARTSYS) | ||
390 | return rc; | ||
391 | else | ||
392 | return -EIO; | ||
393 | } | ||
394 | |||
395 | DEBUGP(4, dev, "start \n"); | ||
396 | |||
397 | for (i = 0; i < bytes_to_write; i++) { | ||
398 | rc = wait_for_bulk_out_ready(dev); | ||
399 | if (rc <= 0) { | ||
400 | DEBUGP(5, dev, "wait_for_bulk_out_ready rc=%.2Zx\n", | ||
401 | rc); | ||
402 | DEBUGP(2, dev, "<- cm4040_write (failed)\n"); | ||
403 | if (rc == -ERESTARTSYS) | ||
404 | return rc; | ||
405 | else | ||
406 | return -EIO; | ||
407 | } | ||
408 | |||
409 | xoutb(dev->s_buf[i],iobase + REG_OFFSET_BULK_OUT); | ||
410 | } | ||
411 | DEBUGP(4, dev, "end\n"); | ||
412 | |||
413 | rc = write_sync_reg(SCR_HOST_TO_READER_DONE, dev); | ||
414 | |||
415 | if (rc <= 0) { | ||
416 | DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc); | ||
417 | DEBUGP(2, dev, "<- cm4040_write (failed)\n"); | ||
418 | if (rc == -ERESTARTSYS) | ||
419 | return rc; | ||
420 | else | ||
421 | return -EIO; | ||
422 | } | ||
423 | |||
424 | DEBUGP(2, dev, "<- cm4040_write (successfully)\n"); | ||
425 | return count; | ||
426 | } | ||
427 | |||
428 | static unsigned int cm4040_poll(struct file *filp, poll_table *wait) | ||
429 | { | ||
430 | struct reader_dev *dev = filp->private_data; | ||
431 | unsigned int mask = 0; | ||
432 | |||
433 | poll_wait(filp, &dev->poll_wait, wait); | ||
434 | |||
435 | if (test_and_clear_bit(BS_READABLE, &dev->buffer_status)) | ||
436 | mask |= POLLIN | POLLRDNORM; | ||
437 | if (test_and_clear_bit(BS_WRITABLE, &dev->buffer_status)) | ||
438 | mask |= POLLOUT | POLLWRNORM; | ||
439 | |||
440 | DEBUGP(2, dev, "<- cm4040_poll(%u)\n", mask); | ||
441 | |||
442 | return mask; | ||
443 | } | ||
444 | |||
445 | static int cm4040_open(struct inode *inode, struct file *filp) | ||
446 | { | ||
447 | struct reader_dev *dev; | ||
448 | dev_link_t *link; | ||
449 | int minor = iminor(inode); | ||
450 | |||
451 | if (minor >= CM_MAX_DEV) | ||
452 | return -ENODEV; | ||
453 | |||
454 | link = dev_table[minor]; | ||
455 | if (link == NULL || !(DEV_OK(link))) | ||
456 | return -ENODEV; | ||
457 | |||
458 | if (link->open) | ||
459 | return -EBUSY; | ||
460 | |||
461 | dev = link->priv; | ||
462 | filp->private_data = dev; | ||
463 | |||
464 | if (filp->f_flags & O_NONBLOCK) { | ||
465 | DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n"); | ||
466 | return -EAGAIN; | ||
467 | } | ||
468 | |||
469 | link->open = 1; | ||
470 | |||
471 | dev->poll_timer.data = (unsigned long) dev; | ||
472 | mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD); | ||
473 | |||
474 | DEBUGP(2, dev, "<- cm4040_open (successfully)\n"); | ||
475 | return nonseekable_open(inode, filp); | ||
476 | } | ||
477 | |||
478 | static int cm4040_close(struct inode *inode, struct file *filp) | ||
479 | { | ||
480 | struct reader_dev *dev = filp->private_data; | ||
481 | dev_link_t *link; | ||
482 | int minor = iminor(inode); | ||
483 | |||
484 | DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode), | ||
485 | iminor(inode)); | ||
486 | |||
487 | if (minor >= CM_MAX_DEV) | ||
488 | return -ENODEV; | ||
489 | |||
490 | link = dev_table[minor]; | ||
491 | if (link == NULL) | ||
492 | return -ENODEV; | ||
493 | |||
494 | cm4040_stop_poll(dev); | ||
495 | |||
496 | link->open = 0; | ||
497 | wake_up(&dev->devq); | ||
498 | |||
499 | DEBUGP(2, dev, "<- cm4040_close\n"); | ||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | static void cm4040_reader_release(dev_link_t *link) | ||
504 | { | ||
505 | struct reader_dev *dev = link->priv; | ||
506 | |||
507 | DEBUGP(3, dev, "-> cm4040_reader_release\n"); | ||
508 | while (link->open) { | ||
509 | DEBUGP(3, dev, KERN_INFO MODULE_NAME ": delaying release " | ||
510 | "until process has terminated\n"); | ||
511 | wait_event(dev->devq, (link->open == 0)); | ||
512 | } | ||
513 | DEBUGP(3, dev, "<- cm4040_reader_release\n"); | ||
514 | return; | ||
515 | } | ||
516 | |||
517 | static void reader_config(dev_link_t *link, int devno) | ||
518 | { | ||
519 | client_handle_t handle; | ||
520 | struct reader_dev *dev; | ||
521 | tuple_t tuple; | ||
522 | cisparse_t parse; | ||
523 | config_info_t conf; | ||
524 | u_char buf[64]; | ||
525 | int fail_fn, fail_rc; | ||
526 | int rc; | ||
527 | |||
528 | handle = link->handle; | ||
529 | |||
530 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
531 | tuple.Attributes = 0; | ||
532 | tuple.TupleData = buf; | ||
533 | tuple.TupleDataMax = sizeof(buf); | ||
534 | tuple.TupleOffset = 0; | ||
535 | |||
536 | if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) { | ||
537 | fail_fn = GetFirstTuple; | ||
538 | goto cs_failed; | ||
539 | } | ||
540 | if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) { | ||
541 | fail_fn = GetTupleData; | ||
542 | goto cs_failed; | ||
543 | } | ||
544 | if ((fail_rc = pcmcia_parse_tuple(handle, &tuple, &parse)) | ||
545 | != CS_SUCCESS) { | ||
546 | fail_fn = ParseTuple; | ||
547 | goto cs_failed; | ||
548 | } | ||
549 | if ((fail_rc = pcmcia_get_configuration_info(handle, &conf)) | ||
550 | != CS_SUCCESS) { | ||
551 | fail_fn = GetConfigurationInfo; | ||
552 | goto cs_failed; | ||
553 | } | ||
554 | |||
555 | link->state |= DEV_CONFIG; | ||
556 | link->conf.ConfigBase = parse.config.base; | ||
557 | link->conf.Present = parse.config.rmask[0]; | ||
558 | link->conf.Vcc = conf.Vcc; | ||
559 | |||
560 | link->io.BasePort2 = 0; | ||
561 | link->io.NumPorts2 = 0; | ||
562 | link->io.Attributes2 = 0; | ||
563 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
564 | for (rc = pcmcia_get_first_tuple(handle, &tuple); | ||
565 | rc == CS_SUCCESS; | ||
566 | rc = pcmcia_get_next_tuple(handle, &tuple)) { | ||
567 | rc = pcmcia_get_tuple_data(handle, &tuple); | ||
568 | if (rc != CS_SUCCESS) | ||
569 | continue; | ||
570 | rc = pcmcia_parse_tuple(handle, &tuple, &parse); | ||
571 | if (rc != CS_SUCCESS) | ||
572 | continue; | ||
573 | |||
574 | link->conf.ConfigIndex = parse.cftable_entry.index; | ||
575 | |||
576 | if (!parse.cftable_entry.io.nwin) | ||
577 | continue; | ||
578 | |||
579 | link->io.BasePort1 = parse.cftable_entry.io.win[0].base; | ||
580 | link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; | ||
581 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
582 | if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT)) | ||
583 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
584 | if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT)) | ||
585 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
586 | link->io.IOAddrLines = parse.cftable_entry.io.flags | ||
587 | & CISTPL_IO_LINES_MASK; | ||
588 | rc = pcmcia_request_io(handle, &link->io); | ||
589 | |||
590 | dev_printk(KERN_INFO, &handle_to_dev(handle), "foo"); | ||
591 | if (rc == CS_SUCCESS) | ||
592 | break; | ||
593 | else | ||
594 | dev_printk(KERN_INFO, &handle_to_dev(handle), | ||
595 | "pcmcia_request_io failed 0x%x\n", rc); | ||
596 | } | ||
597 | if (rc != CS_SUCCESS) | ||
598 | goto cs_release; | ||
599 | |||
600 | link->conf.IntType = 00000002; | ||
601 | |||
602 | if ((fail_rc = pcmcia_request_configuration(handle,&link->conf)) | ||
603 | !=CS_SUCCESS) { | ||
604 | fail_fn = RequestConfiguration; | ||
605 | dev_printk(KERN_INFO, &handle_to_dev(handle), | ||
606 | "pcmcia_request_configuration failed 0x%x\n", | ||
607 | fail_rc); | ||
608 | goto cs_release; | ||
609 | } | ||
610 | |||
611 | dev = link->priv; | ||
612 | sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); | ||
613 | dev->node.major = major; | ||
614 | dev->node.minor = devno; | ||
615 | dev->node.next = NULL; | ||
616 | link->dev = &dev->node; | ||
617 | link->state &= ~DEV_CONFIG_PENDING; | ||
618 | |||
619 | DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno, | ||
620 | link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1); | ||
621 | DEBUGP(2, dev, "<- reader_config (succ)\n"); | ||
622 | |||
623 | return; | ||
624 | |||
625 | cs_failed: | ||
626 | cs_error(handle, fail_fn, fail_rc); | ||
627 | cs_release: | ||
628 | reader_release(link); | ||
629 | link->state &= ~DEV_CONFIG_PENDING; | ||
630 | } | ||
631 | |||
632 | static int reader_event(event_t event, int priority, | ||
633 | event_callback_args_t *args) | ||
634 | { | ||
635 | dev_link_t *link; | ||
636 | struct reader_dev *dev; | ||
637 | int devno; | ||
638 | |||
639 | link = args->client_data; | ||
640 | dev = link->priv; | ||
641 | DEBUGP(3, dev, "-> reader_event\n"); | ||
642 | for (devno = 0; devno < CM_MAX_DEV; devno++) { | ||
643 | if (dev_table[devno] == link) | ||
644 | break; | ||
645 | } | ||
646 | if (devno == CM_MAX_DEV) | ||
647 | return CS_BAD_ADAPTER; | ||
648 | |||
649 | switch (event) { | ||
650 | case CS_EVENT_CARD_INSERTION: | ||
651 | DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n"); | ||
652 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
653 | reader_config(link, devno); | ||
654 | break; | ||
655 | case CS_EVENT_CARD_REMOVAL: | ||
656 | DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); | ||
657 | link->state &= ~DEV_PRESENT; | ||
658 | break; | ||
659 | case CS_EVENT_PM_SUSPEND: | ||
660 | DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND " | ||
661 | "(fall-through to CS_EVENT_RESET_PHYSICAL)\n"); | ||
662 | link->state |= DEV_SUSPEND; | ||
663 | |||
664 | case CS_EVENT_RESET_PHYSICAL: | ||
665 | DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n"); | ||
666 | if (link->state & DEV_CONFIG) { | ||
667 | DEBUGP(5, dev, "ReleaseConfiguration\n"); | ||
668 | pcmcia_release_configuration(link->handle); | ||
669 | } | ||
670 | break; | ||
671 | case CS_EVENT_PM_RESUME: | ||
672 | DEBUGP(5, dev, "CS_EVENT_PM_RESUME " | ||
673 | "(fall-through to CS_EVENT_CARD_RESET)\n"); | ||
674 | link->state &= ~DEV_SUSPEND; | ||
675 | |||
676 | case CS_EVENT_CARD_RESET: | ||
677 | DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n"); | ||
678 | if ((link->state & DEV_CONFIG)) { | ||
679 | DEBUGP(5, dev, "RequestConfiguration\n"); | ||
680 | pcmcia_request_configuration(link->handle, | ||
681 | &link->conf); | ||
682 | } | ||
683 | break; | ||
684 | default: | ||
685 | DEBUGP(5, dev, "reader_event: unknown event %.2x\n", | ||
686 | event); | ||
687 | break; | ||
688 | } | ||
689 | DEBUGP(3, dev, "<- reader_event\n"); | ||
690 | return CS_SUCCESS; | ||
691 | } | ||
692 | |||
693 | static void reader_release(dev_link_t *link) | ||
694 | { | ||
695 | cm4040_reader_release(link->priv); | ||
696 | pcmcia_release_configuration(link->handle); | ||
697 | pcmcia_release_io(link->handle, &link->io); | ||
698 | } | ||
699 | |||
700 | static dev_link_t *reader_attach(void) | ||
701 | { | ||
702 | struct reader_dev *dev; | ||
703 | dev_link_t *link; | ||
704 | client_reg_t client_reg; | ||
705 | int i; | ||
706 | |||
707 | for (i = 0; i < CM_MAX_DEV; i++) { | ||
708 | if (dev_table[i] == NULL) | ||
709 | break; | ||
710 | } | ||
711 | |||
712 | if (i == CM_MAX_DEV) | ||
713 | return NULL; | ||
714 | |||
715 | dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL); | ||
716 | if (dev == NULL) | ||
717 | return NULL; | ||
718 | |||
719 | dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT; | ||
720 | dev->buffer_status = 0; | ||
721 | |||
722 | link = &dev->link; | ||
723 | link->priv = dev; | ||
724 | |||
725 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
726 | dev_table[i] = link; | ||
727 | |||
728 | client_reg.dev_info = &dev_info; | ||
729 | client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; | ||
730 | client_reg.EventMask= | ||
731 | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | | ||
732 | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | | ||
733 | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; | ||
734 | client_reg.Version = 0x0210; | ||
735 | client_reg.event_callback_args.client_data = link; | ||
736 | i = pcmcia_register_client(&link->handle, &client_reg); | ||
737 | if (i) { | ||
738 | cs_error(link->handle, RegisterClient, i); | ||
739 | reader_detach(link); | ||
740 | return NULL; | ||
741 | } | ||
742 | init_waitqueue_head(&dev->devq); | ||
743 | init_waitqueue_head(&dev->poll_wait); | ||
744 | init_waitqueue_head(&dev->read_wait); | ||
745 | init_waitqueue_head(&dev->write_wait); | ||
746 | init_timer(&dev->poll_timer); | ||
747 | dev->poll_timer.function = &cm4040_do_poll; | ||
748 | |||
749 | return link; | ||
750 | } | ||
751 | |||
752 | static void reader_detach_by_devno(int devno, dev_link_t *link) | ||
753 | { | ||
754 | struct reader_dev *dev = link->priv; | ||
755 | |||
756 | if (link->state & DEV_CONFIG) { | ||
757 | DEBUGP(5, dev, "device still configured (try to release it)\n"); | ||
758 | reader_release(link); | ||
759 | } | ||
760 | |||
761 | pcmcia_deregister_client(link->handle); | ||
762 | dev_table[devno] = NULL; | ||
763 | DEBUGP(5, dev, "freeing dev=%p\n", dev); | ||
764 | cm4040_stop_poll(dev); | ||
765 | kfree(dev); | ||
766 | return; | ||
767 | } | ||
768 | |||
769 | static void reader_detach(dev_link_t *link) | ||
770 | { | ||
771 | int i; | ||
772 | |||
773 | /* find device */ | ||
774 | for (i = 0; i < CM_MAX_DEV; i++) { | ||
775 | if (dev_table[i] == link) | ||
776 | break; | ||
777 | } | ||
778 | if (i == CM_MAX_DEV) | ||
779 | return; | ||
780 | |||
781 | reader_detach_by_devno(i, link); | ||
782 | return; | ||
783 | } | ||
784 | |||
785 | static struct file_operations reader_fops = { | ||
786 | .owner = THIS_MODULE, | ||
787 | .read = cm4040_read, | ||
788 | .write = cm4040_write, | ||
789 | .open = cm4040_open, | ||
790 | .release = cm4040_close, | ||
791 | .poll = cm4040_poll, | ||
792 | }; | ||
793 | |||
794 | static struct pcmcia_device_id cm4040_ids[] = { | ||
795 | PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0200), | ||
796 | PCMCIA_DEVICE_PROD_ID12("OMNIKEY", "CardMan 4040", | ||
797 | 0xE32CDD8C, 0x8F23318B), | ||
798 | PCMCIA_DEVICE_NULL, | ||
799 | }; | ||
800 | MODULE_DEVICE_TABLE(pcmcia, cm4040_ids); | ||
801 | |||
802 | static struct pcmcia_driver reader_driver = { | ||
803 | .owner = THIS_MODULE, | ||
804 | .drv = { | ||
805 | .name = "cm4040_cs", | ||
806 | }, | ||
807 | .attach = reader_attach, | ||
808 | .detach = reader_detach, | ||
809 | .event = reader_event, | ||
810 | .id_table = cm4040_ids, | ||
811 | }; | ||
812 | |||
813 | static int __init cm4040_init(void) | ||
814 | { | ||
815 | printk(KERN_INFO "%s\n", version); | ||
816 | pcmcia_register_driver(&reader_driver); | ||
817 | major = register_chrdev(0, DEVICE_NAME, &reader_fops); | ||
818 | if (major < 0) { | ||
819 | printk(KERN_WARNING MODULE_NAME | ||
820 | ": could not get major number\n"); | ||
821 | return -1; | ||
822 | } | ||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | static void __exit cm4040_exit(void) | ||
827 | { | ||
828 | int i; | ||
829 | |||
830 | printk(KERN_INFO MODULE_NAME ": unloading\n"); | ||
831 | pcmcia_unregister_driver(&reader_driver); | ||
832 | for (i = 0; i < CM_MAX_DEV; i++) { | ||
833 | if (dev_table[i]) | ||
834 | reader_detach_by_devno(i, dev_table[i]); | ||
835 | } | ||
836 | unregister_chrdev(major, DEVICE_NAME); | ||
837 | } | ||
838 | |||
839 | module_init(cm4040_init); | ||
840 | module_exit(cm4040_exit); | ||
841 | MODULE_LICENSE("Dual BSD/GPL"); | ||
diff --git a/drivers/char/pcmcia/cm4040_cs.h b/drivers/char/pcmcia/cm4040_cs.h new file mode 100644 index 000000000000..9a8b805c5095 --- /dev/null +++ b/drivers/char/pcmcia/cm4040_cs.h | |||
@@ -0,0 +1,47 @@ | |||
1 | #ifndef _CM4040_H_ | ||
2 | #define _CM4040_H_ | ||
3 | |||
4 | #define CM_MAX_DEV 4 | ||
5 | |||
6 | #define DEVICE_NAME "cmx" | ||
7 | #define MODULE_NAME "cm4040_cs" | ||
8 | |||
9 | #define REG_OFFSET_BULK_OUT 0 | ||
10 | #define REG_OFFSET_BULK_IN 0 | ||
11 | #define REG_OFFSET_BUFFER_STATUS 1 | ||
12 | #define REG_OFFSET_SYNC_CONTROL 2 | ||
13 | |||
14 | #define BSR_BULK_IN_FULL 0x02 | ||
15 | #define BSR_BULK_OUT_FULL 0x01 | ||
16 | |||
17 | #define SCR_HOST_TO_READER_START 0x80 | ||
18 | #define SCR_ABORT 0x40 | ||
19 | #define SCR_EN_NOTIFY 0x20 | ||
20 | #define SCR_ACK_NOTIFY 0x10 | ||
21 | #define SCR_READER_TO_HOST_DONE 0x08 | ||
22 | #define SCR_HOST_TO_READER_DONE 0x04 | ||
23 | #define SCR_PULSE_INTERRUPT 0x02 | ||
24 | #define SCR_POWER_DOWN 0x01 | ||
25 | |||
26 | |||
27 | #define CMD_PC_TO_RDR_ICCPOWERON 0x62 | ||
28 | #define CMD_PC_TO_RDR_GETSLOTSTATUS 0x65 | ||
29 | #define CMD_PC_TO_RDR_ICCPOWEROFF 0x63 | ||
30 | #define CMD_PC_TO_RDR_SECURE 0x69 | ||
31 | #define CMD_PC_TO_RDR_GETPARAMETERS 0x6C | ||
32 | #define CMD_PC_TO_RDR_RESETPARAMETERS 0x6D | ||
33 | #define CMD_PC_TO_RDR_SETPARAMETERS 0x61 | ||
34 | #define CMD_PC_TO_RDR_XFRBLOCK 0x6F | ||
35 | #define CMD_PC_TO_RDR_ESCAPE 0x6B | ||
36 | #define CMD_PC_TO_RDR_ICCCLOCK 0x6E | ||
37 | #define CMD_PC_TO_RDR_TEST_SECURE 0x74 | ||
38 | #define CMD_PC_TO_RDR_OK_SECURE 0x89 | ||
39 | |||
40 | |||
41 | #define CMD_RDR_TO_PC_SLOTSTATUS 0x81 | ||
42 | #define CMD_RDR_TO_PC_DATABLOCK 0x80 | ||
43 | #define CMD_RDR_TO_PC_PARAMETERS 0x82 | ||
44 | #define CMD_RDR_TO_PC_ESCAPE 0x83 | ||
45 | #define CMD_RDR_TO_PC_OK_SECURE 0x89 | ||
46 | |||
47 | #endif /* _CM4040_H_ */ | ||
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 82c6abde68df..62aa0e534a6d 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/synclink.c | 2 | * linux/drivers/char/synclink.c |
3 | * | 3 | * |
4 | * $Id: synclink.c,v 4.37 2005/09/07 13:13:19 paulkf Exp $ | 4 | * $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $ |
5 | * | 5 | * |
6 | * Device driver for Microgate SyncLink ISA and PCI | 6 | * Device driver for Microgate SyncLink ISA and PCI |
7 | * high speed multiprotocol serial adapters. | 7 | * high speed multiprotocol serial adapters. |
@@ -101,6 +101,7 @@ | |||
101 | #include <linux/termios.h> | 101 | #include <linux/termios.h> |
102 | #include <linux/workqueue.h> | 102 | #include <linux/workqueue.h> |
103 | #include <linux/hdlc.h> | 103 | #include <linux/hdlc.h> |
104 | #include <linux/dma-mapping.h> | ||
104 | 105 | ||
105 | #ifdef CONFIG_HDLC_MODULE | 106 | #ifdef CONFIG_HDLC_MODULE |
106 | #define CONFIG_HDLC 1 | 107 | #define CONFIG_HDLC 1 |
@@ -148,6 +149,7 @@ typedef struct _DMABUFFERENTRY | |||
148 | u32 link; /* 32-bit flat link to next buffer entry */ | 149 | u32 link; /* 32-bit flat link to next buffer entry */ |
149 | char *virt_addr; /* virtual address of data buffer */ | 150 | char *virt_addr; /* virtual address of data buffer */ |
150 | u32 phys_entry; /* physical address of this buffer entry */ | 151 | u32 phys_entry; /* physical address of this buffer entry */ |
152 | dma_addr_t dma_addr; | ||
151 | } DMABUFFERENTRY, *DMAPBUFFERENTRY; | 153 | } DMABUFFERENTRY, *DMAPBUFFERENTRY; |
152 | 154 | ||
153 | /* The queue of BH actions to be performed */ | 155 | /* The queue of BH actions to be performed */ |
@@ -233,7 +235,8 @@ struct mgsl_struct { | |||
233 | int ri_chkcount; | 235 | int ri_chkcount; |
234 | 236 | ||
235 | char *buffer_list; /* virtual address of Rx & Tx buffer lists */ | 237 | char *buffer_list; /* virtual address of Rx & Tx buffer lists */ |
236 | unsigned long buffer_list_phys; | 238 | u32 buffer_list_phys; |
239 | dma_addr_t buffer_list_dma_addr; | ||
237 | 240 | ||
238 | unsigned int rx_buffer_count; /* count of total allocated Rx buffers */ | 241 | unsigned int rx_buffer_count; /* count of total allocated Rx buffers */ |
239 | DMABUFFERENTRY *rx_buffer_list; /* list of receive buffer entries */ | 242 | DMABUFFERENTRY *rx_buffer_list; /* list of receive buffer entries */ |
@@ -896,7 +899,7 @@ module_param_array(txdmabufs, int, NULL, 0); | |||
896 | module_param_array(txholdbufs, int, NULL, 0); | 899 | module_param_array(txholdbufs, int, NULL, 0); |
897 | 900 | ||
898 | static char *driver_name = "SyncLink serial driver"; | 901 | static char *driver_name = "SyncLink serial driver"; |
899 | static char *driver_version = "$Revision: 4.37 $"; | 902 | static char *driver_version = "$Revision: 4.38 $"; |
900 | 903 | ||
901 | static int synclink_init_one (struct pci_dev *dev, | 904 | static int synclink_init_one (struct pci_dev *dev, |
902 | const struct pci_device_id *ent); | 905 | const struct pci_device_id *ent); |
@@ -3811,11 +3814,10 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info ) | |||
3811 | /* inspect portions of the buffer while other portions are being */ | 3814 | /* inspect portions of the buffer while other portions are being */ |
3812 | /* updated by the adapter using Bus Master DMA. */ | 3815 | /* updated by the adapter using Bus Master DMA. */ |
3813 | 3816 | ||
3814 | info->buffer_list = kmalloc(BUFFERLISTSIZE, GFP_KERNEL | GFP_DMA); | 3817 | info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL); |
3815 | if ( info->buffer_list == NULL ) | 3818 | if (info->buffer_list == NULL) |
3816 | return -ENOMEM; | 3819 | return -ENOMEM; |
3817 | 3820 | info->buffer_list_phys = (u32)(info->buffer_list_dma_addr); | |
3818 | info->buffer_list_phys = isa_virt_to_bus(info->buffer_list); | ||
3819 | } | 3821 | } |
3820 | 3822 | ||
3821 | /* We got the memory for the buffer entry lists. */ | 3823 | /* We got the memory for the buffer entry lists. */ |
@@ -3882,8 +3884,8 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info ) | |||
3882 | */ | 3884 | */ |
3883 | static void mgsl_free_buffer_list_memory( struct mgsl_struct *info ) | 3885 | static void mgsl_free_buffer_list_memory( struct mgsl_struct *info ) |
3884 | { | 3886 | { |
3885 | if ( info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI ) | 3887 | if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI) |
3886 | kfree(info->buffer_list); | 3888 | dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr); |
3887 | 3889 | ||
3888 | info->buffer_list = NULL; | 3890 | info->buffer_list = NULL; |
3889 | info->rx_buffer_list = NULL; | 3891 | info->rx_buffer_list = NULL; |
@@ -3910,7 +3912,7 @@ static void mgsl_free_buffer_list_memory( struct mgsl_struct *info ) | |||
3910 | static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount) | 3912 | static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount) |
3911 | { | 3913 | { |
3912 | int i; | 3914 | int i; |
3913 | unsigned long phys_addr; | 3915 | u32 phys_addr; |
3914 | 3916 | ||
3915 | /* Allocate page sized buffers for the receive buffer list */ | 3917 | /* Allocate page sized buffers for the receive buffer list */ |
3916 | 3918 | ||
@@ -3922,11 +3924,10 @@ static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *Buff | |||
3922 | info->last_mem_alloc += DMABUFFERSIZE; | 3924 | info->last_mem_alloc += DMABUFFERSIZE; |
3923 | } else { | 3925 | } else { |
3924 | /* ISA adapter uses system memory. */ | 3926 | /* ISA adapter uses system memory. */ |
3925 | BufferList[i].virt_addr = | 3927 | BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL); |
3926 | kmalloc(DMABUFFERSIZE, GFP_KERNEL | GFP_DMA); | 3928 | if (BufferList[i].virt_addr == NULL) |
3927 | if ( BufferList[i].virt_addr == NULL ) | ||
3928 | return -ENOMEM; | 3929 | return -ENOMEM; |
3929 | phys_addr = isa_virt_to_bus(BufferList[i].virt_addr); | 3930 | phys_addr = (u32)(BufferList[i].dma_addr); |
3930 | } | 3931 | } |
3931 | BufferList[i].phys_addr = phys_addr; | 3932 | BufferList[i].phys_addr = phys_addr; |
3932 | } | 3933 | } |
@@ -3957,7 +3958,7 @@ static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *Buf | |||
3957 | for ( i = 0 ; i < Buffercount ; i++ ) { | 3958 | for ( i = 0 ; i < Buffercount ; i++ ) { |
3958 | if ( BufferList[i].virt_addr ) { | 3959 | if ( BufferList[i].virt_addr ) { |
3959 | if ( info->bus_type != MGSL_BUS_TYPE_PCI ) | 3960 | if ( info->bus_type != MGSL_BUS_TYPE_PCI ) |
3960 | kfree(BufferList[i].virt_addr); | 3961 | dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr); |
3961 | BufferList[i].virt_addr = NULL; | 3962 | BufferList[i].virt_addr = NULL; |
3962 | } | 3963 | } |
3963 | } | 3964 | } |
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index b58adfe3ed19..a6873bf89ffa 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig | |||
@@ -6,7 +6,7 @@ menu "TPM devices" | |||
6 | 6 | ||
7 | config TCG_TPM | 7 | config TCG_TPM |
8 | tristate "TPM Hardware Support" | 8 | tristate "TPM Hardware Support" |
9 | depends on EXPERIMENTAL && PCI | 9 | depends on EXPERIMENTAL |
10 | ---help--- | 10 | ---help--- |
11 | If you have a TPM security chip in your system, which | 11 | If you have a TPM security chip in your system, which |
12 | implements the Trusted Computing Group's specification, | 12 | implements the Trusted Computing Group's specification, |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 303f15880466..a9be0e8eaea5 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -43,6 +43,13 @@ static void user_reader_timeout(unsigned long ptr) | |||
43 | { | 43 | { |
44 | struct tpm_chip *chip = (struct tpm_chip *) ptr; | 44 | struct tpm_chip *chip = (struct tpm_chip *) ptr; |
45 | 45 | ||
46 | schedule_work(&chip->work); | ||
47 | } | ||
48 | |||
49 | static void timeout_work(void * ptr) | ||
50 | { | ||
51 | struct tpm_chip *chip = ptr; | ||
52 | |||
46 | down(&chip->buffer_mutex); | 53 | down(&chip->buffer_mutex); |
47 | atomic_set(&chip->data_pending, 0); | 54 | atomic_set(&chip->data_pending, 0); |
48 | memset(chip->data_buffer, 0, TPM_BUFSIZE); | 55 | memset(chip->data_buffer, 0, TPM_BUFSIZE); |
@@ -370,6 +377,7 @@ int tpm_release(struct inode *inode, struct file *file) | |||
370 | file->private_data = NULL; | 377 | file->private_data = NULL; |
371 | chip->num_opens--; | 378 | chip->num_opens--; |
372 | del_singleshot_timer_sync(&chip->user_read_timer); | 379 | del_singleshot_timer_sync(&chip->user_read_timer); |
380 | flush_scheduled_work(); | ||
373 | atomic_set(&chip->data_pending, 0); | 381 | atomic_set(&chip->data_pending, 0); |
374 | put_device(chip->dev); | 382 | put_device(chip->dev); |
375 | kfree(chip->data_buffer); | 383 | kfree(chip->data_buffer); |
@@ -421,6 +429,7 @@ ssize_t tpm_read(struct file * file, char __user *buf, | |||
421 | int ret_size; | 429 | int ret_size; |
422 | 430 | ||
423 | del_singleshot_timer_sync(&chip->user_read_timer); | 431 | del_singleshot_timer_sync(&chip->user_read_timer); |
432 | flush_scheduled_work(); | ||
424 | ret_size = atomic_read(&chip->data_pending); | 433 | ret_size = atomic_read(&chip->data_pending); |
425 | atomic_set(&chip->data_pending, 0); | 434 | atomic_set(&chip->data_pending, 0); |
426 | if (ret_size > 0) { /* relay data */ | 435 | if (ret_size > 0) { /* relay data */ |
@@ -428,8 +437,7 @@ ssize_t tpm_read(struct file * file, char __user *buf, | |||
428 | ret_size = size; | 437 | ret_size = size; |
429 | 438 | ||
430 | down(&chip->buffer_mutex); | 439 | down(&chip->buffer_mutex); |
431 | if (copy_to_user | 440 | if (copy_to_user(buf, chip->data_buffer, ret_size)) |
432 | ((void __user *) buf, chip->data_buffer, ret_size)) | ||
433 | ret_size = -EFAULT; | 441 | ret_size = -EFAULT; |
434 | up(&chip->buffer_mutex); | 442 | up(&chip->buffer_mutex); |
435 | } | 443 | } |
@@ -460,7 +468,7 @@ void tpm_remove_hardware(struct device *dev) | |||
460 | sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); | 468 | sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); |
461 | 469 | ||
462 | dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= | 470 | dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= |
463 | !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); | 471 | ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); |
464 | 472 | ||
465 | kfree(chip); | 473 | kfree(chip); |
466 | 474 | ||
@@ -528,6 +536,8 @@ int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry) | |||
528 | init_MUTEX(&chip->tpm_mutex); | 536 | init_MUTEX(&chip->tpm_mutex); |
529 | INIT_LIST_HEAD(&chip->list); | 537 | INIT_LIST_HEAD(&chip->list); |
530 | 538 | ||
539 | INIT_WORK(&chip->work, timeout_work, chip); | ||
540 | |||
531 | init_timer(&chip->user_read_timer); | 541 | init_timer(&chip->user_read_timer); |
532 | chip->user_read_timer.function = user_reader_timeout; | 542 | chip->user_read_timer.function = user_reader_timeout; |
533 | chip->user_read_timer.data = (unsigned long) chip; | 543 | chip->user_read_timer.data = (unsigned long) chip; |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 9293bcc4dc62..159882ca69dd 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -50,7 +50,11 @@ struct tpm_vendor_specific { | |||
50 | u8 req_complete_mask; | 50 | u8 req_complete_mask; |
51 | u8 req_complete_val; | 51 | u8 req_complete_val; |
52 | u8 req_canceled; | 52 | u8 req_canceled; |
53 | u16 base; /* TPM base address */ | 53 | void __iomem *iobase; /* ioremapped address */ |
54 | unsigned long base; /* TPM base address */ | ||
55 | |||
56 | int region_size; | ||
57 | int have_region; | ||
54 | 58 | ||
55 | int (*recv) (struct tpm_chip *, u8 *, size_t); | 59 | int (*recv) (struct tpm_chip *, u8 *, size_t); |
56 | int (*send) (struct tpm_chip *, u8 *, size_t); | 60 | int (*send) (struct tpm_chip *, u8 *, size_t); |
@@ -73,6 +77,7 @@ struct tpm_chip { | |||
73 | struct semaphore buffer_mutex; | 77 | struct semaphore buffer_mutex; |
74 | 78 | ||
75 | struct timer_list user_read_timer; /* user needs to claim result */ | 79 | struct timer_list user_read_timer; /* user needs to claim result */ |
80 | struct work_struct work; | ||
76 | struct semaphore tpm_mutex; /* tpm is processing */ | 81 | struct semaphore tpm_mutex; /* tpm is processing */ |
77 | 82 | ||
78 | struct tpm_vendor_specific *vendor; | 83 | struct tpm_vendor_specific *vendor; |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 32e01450c425..ff3654964fe3 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -19,14 +19,8 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/platform_device.h> | ||
23 | #include "tpm.h" | 22 | #include "tpm.h" |
24 | 23 | #include "tpm_atmel.h" | |
25 | /* Atmel definitions */ | ||
26 | enum tpm_atmel_addr { | ||
27 | TPM_ATMEL_BASE_ADDR_LO = 0x08, | ||
28 | TPM_ATMEL_BASE_ADDR_HI = 0x09 | ||
29 | }; | ||
30 | 24 | ||
31 | /* write status bits */ | 25 | /* write status bits */ |
32 | enum tpm_atmel_write_status { | 26 | enum tpm_atmel_write_status { |
@@ -53,13 +47,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
53 | return -EIO; | 47 | return -EIO; |
54 | 48 | ||
55 | for (i = 0; i < 6; i++) { | 49 | for (i = 0; i < 6; i++) { |
56 | status = inb(chip->vendor->base + 1); | 50 | status = ioread8(chip->vendor->iobase + 1); |
57 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 51 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
58 | dev_err(chip->dev, | 52 | dev_err(chip->dev, "error reading header\n"); |
59 | "error reading header\n"); | ||
60 | return -EIO; | 53 | return -EIO; |
61 | } | 54 | } |
62 | *buf++ = inb(chip->vendor->base); | 55 | *buf++ = ioread8(chip->vendor->iobase); |
63 | } | 56 | } |
64 | 57 | ||
65 | /* size of the data received */ | 58 | /* size of the data received */ |
@@ -70,10 +63,9 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
70 | dev_err(chip->dev, | 63 | dev_err(chip->dev, |
71 | "Recv size(%d) less than available space\n", size); | 64 | "Recv size(%d) less than available space\n", size); |
72 | for (; i < size; i++) { /* clear the waiting data anyway */ | 65 | for (; i < size; i++) { /* clear the waiting data anyway */ |
73 | status = inb(chip->vendor->base + 1); | 66 | status = ioread8(chip->vendor->iobase + 1); |
74 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 67 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
75 | dev_err(chip->dev, | 68 | dev_err(chip->dev, "error reading data\n"); |
76 | "error reading data\n"); | ||
77 | return -EIO; | 69 | return -EIO; |
78 | } | 70 | } |
79 | } | 71 | } |
@@ -82,17 +74,17 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
82 | 74 | ||
83 | /* read all the data available */ | 75 | /* read all the data available */ |
84 | for (; i < size; i++) { | 76 | for (; i < size; i++) { |
85 | status = inb(chip->vendor->base + 1); | 77 | status = ioread8(chip->vendor->iobase + 1); |
86 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 78 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
87 | dev_err(chip->dev, | 79 | dev_err(chip->dev, "error reading data\n"); |
88 | "error reading data\n"); | ||
89 | return -EIO; | 80 | return -EIO; |
90 | } | 81 | } |
91 | *buf++ = inb(chip->vendor->base); | 82 | *buf++ = ioread8(chip->vendor->iobase); |
92 | } | 83 | } |
93 | 84 | ||
94 | /* make sure data available is gone */ | 85 | /* make sure data available is gone */ |
95 | status = inb(chip->vendor->base + 1); | 86 | status = ioread8(chip->vendor->iobase + 1); |
87 | |||
96 | if (status & ATML_STATUS_DATA_AVAIL) { | 88 | if (status & ATML_STATUS_DATA_AVAIL) { |
97 | dev_err(chip->dev, "data available is stuck\n"); | 89 | dev_err(chip->dev, "data available is stuck\n"); |
98 | return -EIO; | 90 | return -EIO; |
@@ -108,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count) | |||
108 | dev_dbg(chip->dev, "tpm_atml_send:\n"); | 100 | dev_dbg(chip->dev, "tpm_atml_send:\n"); |
109 | for (i = 0; i < count; i++) { | 101 | for (i = 0; i < count; i++) { |
110 | dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]); | 102 | dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]); |
111 | outb(buf[i], chip->vendor->base); | 103 | iowrite8(buf[i], chip->vendor->iobase); |
112 | } | 104 | } |
113 | 105 | ||
114 | return count; | 106 | return count; |
@@ -116,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count) | |||
116 | 108 | ||
117 | static void tpm_atml_cancel(struct tpm_chip *chip) | 109 | static void tpm_atml_cancel(struct tpm_chip *chip) |
118 | { | 110 | { |
119 | outb(ATML_STATUS_ABORT, chip->vendor->base + 1); | 111 | iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1); |
120 | } | 112 | } |
121 | 113 | ||
122 | static u8 tpm_atml_status(struct tpm_chip *chip) | 114 | static u8 tpm_atml_status(struct tpm_chip *chip) |
123 | { | 115 | { |
124 | return inb(chip->vendor->base + 1); | 116 | return ioread8(chip->vendor->iobase + 1); |
125 | } | 117 | } |
126 | 118 | ||
127 | static struct file_operations atmel_ops = { | 119 | static struct file_operations atmel_ops = { |
@@ -162,12 +154,17 @@ static struct tpm_vendor_specific tpm_atmel = { | |||
162 | 154 | ||
163 | static struct platform_device *pdev; | 155 | static struct platform_device *pdev; |
164 | 156 | ||
165 | static void __devexit tpm_atml_remove(struct device *dev) | 157 | static void atml_plat_remove(void) |
166 | { | 158 | { |
167 | struct tpm_chip *chip = dev_get_drvdata(dev); | 159 | struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); |
160 | |||
168 | if (chip) { | 161 | if (chip) { |
169 | release_region(chip->vendor->base, 2); | 162 | if (chip->vendor->have_region) |
163 | atmel_release_region(chip->vendor->base, | ||
164 | chip->vendor->region_size); | ||
165 | atmel_put_base_addr(chip->vendor); | ||
170 | tpm_remove_hardware(chip->dev); | 166 | tpm_remove_hardware(chip->dev); |
167 | platform_device_unregister(pdev); | ||
171 | } | 168 | } |
172 | } | 169 | } |
173 | 170 | ||
@@ -182,72 +179,46 @@ static struct device_driver atml_drv = { | |||
182 | static int __init init_atmel(void) | 179 | static int __init init_atmel(void) |
183 | { | 180 | { |
184 | int rc = 0; | 181 | int rc = 0; |
185 | int lo, hi; | ||
186 | 182 | ||
187 | driver_register(&atml_drv); | 183 | driver_register(&atml_drv); |
188 | 184 | ||
189 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); | 185 | if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) { |
190 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); | 186 | rc = -ENODEV; |
191 | 187 | goto err_unreg_drv; | |
192 | tpm_atmel.base = (hi<<8)|lo; | ||
193 | |||
194 | /* verify that it is an Atmel part */ | ||
195 | if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T' | ||
196 | || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') { | ||
197 | return -ENODEV; | ||
198 | } | 188 | } |
199 | 189 | ||
200 | /* verify chip version number is 1.1 */ | 190 | tpm_atmel.have_region = |
201 | if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) || | 191 | (atmel_request_region |
202 | (tpm_read_index(TPM_ADDR, 0x01) != 0x01 )) | 192 | (tpm_atmel.base, tpm_atmel.region_size, |
203 | return -ENODEV; | 193 | "tpm_atmel0") == NULL) ? 0 : 1; |
204 | |||
205 | pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); | ||
206 | if ( !pdev ) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | pdev->name = "tpm_atmel0"; | ||
210 | pdev->id = -1; | ||
211 | pdev->num_resources = 0; | ||
212 | pdev->dev.release = tpm_atml_remove; | ||
213 | pdev->dev.driver = &atml_drv; | ||
214 | |||
215 | if ((rc = platform_device_register(pdev)) < 0) { | ||
216 | kfree(pdev); | ||
217 | pdev = NULL; | ||
218 | return rc; | ||
219 | } | ||
220 | 194 | ||
221 | if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) { | 195 | if (IS_ERR |
222 | platform_device_unregister(pdev); | 196 | (pdev = |
223 | kfree(pdev); | 197 | platform_device_register_simple("tpm_atmel", -1, NULL, 0))) { |
224 | pdev = NULL; | 198 | rc = PTR_ERR(pdev); |
225 | return -EBUSY; | 199 | goto err_rel_reg; |
226 | } | 200 | } |
227 | 201 | ||
228 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) { | 202 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) |
229 | release_region(tpm_atmel.base, 2); | 203 | goto err_unreg_dev; |
230 | platform_device_unregister(pdev); | ||
231 | kfree(pdev); | ||
232 | pdev = NULL; | ||
233 | return rc; | ||
234 | } | ||
235 | |||
236 | dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n", | ||
237 | tpm_atmel.base); | ||
238 | return 0; | 204 | return 0; |
205 | |||
206 | err_unreg_dev: | ||
207 | platform_device_unregister(pdev); | ||
208 | err_rel_reg: | ||
209 | atmel_put_base_addr(&tpm_atmel); | ||
210 | if (tpm_atmel.have_region) | ||
211 | atmel_release_region(tpm_atmel.base, | ||
212 | tpm_atmel.region_size); | ||
213 | err_unreg_drv: | ||
214 | driver_unregister(&atml_drv); | ||
215 | return rc; | ||
239 | } | 216 | } |
240 | 217 | ||
241 | static void __exit cleanup_atmel(void) | 218 | static void __exit cleanup_atmel(void) |
242 | { | 219 | { |
243 | if (pdev) { | ||
244 | tpm_atml_remove(&pdev->dev); | ||
245 | platform_device_unregister(pdev); | ||
246 | kfree(pdev); | ||
247 | pdev = NULL; | ||
248 | } | ||
249 | |||
250 | driver_unregister(&atml_drv); | 220 | driver_unregister(&atml_drv); |
221 | atml_plat_remove(); | ||
251 | } | 222 | } |
252 | 223 | ||
253 | module_init(init_atmel); | 224 | module_init(init_atmel); |
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h new file mode 100644 index 000000000000..d3478aaadd77 --- /dev/null +++ b/drivers/char/tpm/tpm_atmel.h | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 IBM Corporation | ||
3 | * | ||
4 | * Authors: | ||
5 | * Kylene Hall <kjhall@us.ibm.com> | ||
6 | * | ||
7 | * Maintained by: <tpmdd_devel@lists.sourceforge.net> | ||
8 | * | ||
9 | * Device driver for TCG/TCPA TPM (trusted platform module). | ||
10 | * Specifications at www.trustedcomputinggroup.org | ||
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, version 2 of the | ||
15 | * License. | ||
16 | * | ||
17 | * These difference are required on power because the device must be | ||
18 | * discovered through the device tree and iomap must be used to get | ||
19 | * around the need for holes in the io_page_mask. This does not happen | ||
20 | * automatically because the tpm is not a normal pci device and lives | ||
21 | * under the root node. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifdef CONFIG_PPC64 | ||
26 | #define atmel_getb(chip, offset) readb(chip->vendor->iobase + offset); | ||
27 | #define atmel_putb(val, chip, offset) writeb(val, chip->vendor->iobase + offset) | ||
28 | #define atmel_request_region request_mem_region | ||
29 | #define atmel_release_region release_mem_region | ||
30 | |||
31 | static inline void atmel_put_base_addr(struct tpm_vendor_specific | ||
32 | *vendor) | ||
33 | { | ||
34 | iounmap(vendor->iobase); | ||
35 | } | ||
36 | |||
37 | static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor) | ||
38 | { | ||
39 | struct device_node *dn; | ||
40 | unsigned long address, size; | ||
41 | unsigned int *reg; | ||
42 | int reglen; | ||
43 | int naddrc; | ||
44 | int nsizec; | ||
45 | |||
46 | dn = of_find_node_by_name(NULL, "tpm"); | ||
47 | |||
48 | if (!dn) | ||
49 | return NULL; | ||
50 | |||
51 | if (!device_is_compatible(dn, "AT97SC3201")) { | ||
52 | of_node_put(dn); | ||
53 | return NULL; | ||
54 | } | ||
55 | |||
56 | reg = (unsigned int *) get_property(dn, "reg", ®len); | ||
57 | naddrc = prom_n_addr_cells(dn); | ||
58 | nsizec = prom_n_size_cells(dn); | ||
59 | |||
60 | of_node_put(dn); | ||
61 | |||
62 | |||
63 | if (naddrc == 2) | ||
64 | address = ((unsigned long) reg[0] << 32) | reg[1]; | ||
65 | else | ||
66 | address = reg[0]; | ||
67 | |||
68 | if (nsizec == 2) | ||
69 | size = | ||
70 | ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1]; | ||
71 | else | ||
72 | size = reg[naddrc]; | ||
73 | |||
74 | vendor->base = address; | ||
75 | vendor->region_size = size; | ||
76 | return ioremap(vendor->base, vendor->region_size); | ||
77 | } | ||
78 | #else | ||
79 | #define atmel_getb(chip, offset) inb(chip->vendor->base + offset) | ||
80 | #define atmel_putb(val, chip, offset) outb(val, chip->vendor->base + offset) | ||
81 | #define atmel_request_region request_region | ||
82 | #define atmel_release_region release_region | ||
83 | /* Atmel definitions */ | ||
84 | enum tpm_atmel_addr { | ||
85 | TPM_ATMEL_BASE_ADDR_LO = 0x08, | ||
86 | TPM_ATMEL_BASE_ADDR_HI = 0x09 | ||
87 | }; | ||
88 | |||
89 | /* Verify this is a 1.1 Atmel TPM */ | ||
90 | static int atmel_verify_tpm11(void) | ||
91 | { | ||
92 | |||
93 | /* verify that it is an Atmel part */ | ||
94 | if (tpm_read_index(TPM_ADDR, 4) != 'A' || | ||
95 | tpm_read_index(TPM_ADDR, 5) != 'T' || | ||
96 | tpm_read_index(TPM_ADDR, 6) != 'M' || | ||
97 | tpm_read_index(TPM_ADDR, 7) != 'L') | ||
98 | return 1; | ||
99 | |||
100 | /* query chip for its version number */ | ||
101 | if (tpm_read_index(TPM_ADDR, 0x00) != 1 || | ||
102 | tpm_read_index(TPM_ADDR, 0x01) != 1) | ||
103 | return 1; | ||
104 | |||
105 | /* This is an atmel supported part */ | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static inline void atmel_put_base_addr(struct tpm_vendor_specific | ||
110 | *vendor) | ||
111 | { | ||
112 | } | ||
113 | |||
114 | /* Determine where to talk to device */ | ||
115 | static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific | ||
116 | *vendor) | ||
117 | { | ||
118 | int lo, hi; | ||
119 | |||
120 | if (atmel_verify_tpm11() != 0) | ||
121 | return NULL; | ||
122 | |||
123 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); | ||
124 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); | ||
125 | |||
126 | vendor->base = (hi << 8) | lo; | ||
127 | vendor->region_size = 2; | ||
128 | |||
129 | return ioport_map(vendor->base, vendor->region_size); | ||
130 | } | ||
131 | #endif | ||
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c index abc30cca6645..65830ec71042 100644 --- a/drivers/char/watchdog/booke_wdt.c +++ b/drivers/char/watchdog/booke_wdt.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Watchdog timer for PowerPC Book-E systems | 4 | * Watchdog timer for PowerPC Book-E systems |
5 | * | 5 | * |
6 | * Author: Matthew McClintock | 6 | * Author: Matthew McClintock |
7 | * Maintainer: Kumar Gala <kumar.gala@freescale.com> | 7 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> |
8 | * | 8 | * |
9 | * Copyright 2005 Freescale Semiconductor Inc. | 9 | * Copyright 2005 Freescale Semiconductor Inc. |
10 | * | 10 | * |
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c index aa36855fa995..f87220be3c87 100644 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ b/drivers/i2c/busses/i2c-ixp4xx.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #include <asm/hardware.h> /* Pick up IXP4xx-specific bits */ | 36 | #include <asm/hardware.h> /* Pick up IXP4xx-specific bits */ |
37 | 37 | ||
38 | static struct device_driver ixp4xx_i2c_driver; | 38 | static struct platform_driver ixp4xx_i2c_driver; |
39 | 39 | ||
40 | static inline int ixp4xx_scl_pin(void *data) | 40 | static inline int ixp4xx_scl_pin(void *data) |
41 | { | 41 | { |
@@ -128,7 +128,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev) | |||
128 | drv_data->algo_data.timeout = 100; | 128 | drv_data->algo_data.timeout = 100; |
129 | 129 | ||
130 | drv_data->adapter.id = I2C_HW_B_IXP4XX; | 130 | drv_data->adapter.id = I2C_HW_B_IXP4XX; |
131 | strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.name, | 131 | strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.driver.name, |
132 | I2C_NAME_SIZE); | 132 | I2C_NAME_SIZE); |
133 | drv_data->adapter.algo_data = &drv_data->algo_data; | 133 | drv_data->adapter.algo_data = &drv_data->algo_data; |
134 | 134 | ||
@@ -140,7 +140,8 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev) | |||
140 | gpio_line_set(gpio->sda_pin, 0); | 140 | gpio_line_set(gpio->sda_pin, 0); |
141 | 141 | ||
142 | if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) { | 142 | if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) { |
143 | printk(KERN_ERR "ERROR: Could not install %s\n", dev->bus_id); | 143 | printk(KERN_ERR "ERROR: Could not install %s\n", |
144 | plat_dev->dev.bus_id); | ||
144 | 145 | ||
145 | kfree(drv_data); | 146 | kfree(drv_data); |
146 | return err; | 147 | return err; |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 42e5b8175cbf..ed2bc87f475b 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -787,6 +787,10 @@ config BLK_DEV_IDE_PMAC_BLINK | |||
787 | This option enables the use of the sleep LED as a hard drive | 787 | This option enables the use of the sleep LED as a hard drive |
788 | activity LED. | 788 | activity LED. |
789 | 789 | ||
790 | config BLK_DEV_IDE_SWARM | ||
791 | tristate "IDE for Sibyte evaluation boards" | ||
792 | depends on SIBYTE_SB1xxx_SOC | ||
793 | |||
790 | config BLK_DEV_IDE_AU1XXX | 794 | config BLK_DEV_IDE_AU1XXX |
791 | bool "IDE for AMD Alchemy Au1200" | 795 | bool "IDE for AMD Alchemy Au1200" |
792 | depends on SOC_AU1200 | 796 | depends on SOC_AU1200 |
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index cca9c075966d..569fae717503 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile | |||
@@ -48,6 +48,6 @@ obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o | |||
48 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o | 48 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o |
49 | obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o | 49 | obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o |
50 | 50 | ||
51 | obj-$(CONFIG_BLK_DEV_IDE) += legacy/ arm/ | 51 | obj-$(CONFIG_BLK_DEV_IDE) += legacy/ arm/ mips/ |
52 | obj-$(CONFIG_BLK_DEV_HD) += legacy/ | 52 | obj-$(CONFIG_BLK_DEV_HD) += legacy/ |
53 | obj-$(CONFIG_ETRAX_IDE) += cris/ | 53 | obj-$(CONFIG_ETRAX_IDE) += cris/ |
diff --git a/drivers/ide/mips/Makefile b/drivers/ide/mips/Makefile new file mode 100644 index 000000000000..578e52a59588 --- /dev/null +++ b/drivers/ide/mips/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o | |||
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c new file mode 100644 index 000000000000..66f6064f4640 --- /dev/null +++ b/drivers/ide/mips/swarm.c | |||
@@ -0,0 +1,201 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2001, 2002, 2003 Broadcom Corporation | ||
3 | * Copyright (C) 2004 MontaVista Software Inc. | ||
4 | * Author: Manish Lachwani, mlachwani@mvista.com | ||
5 | * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved. | ||
6 | * Author: Maciej W. Rozycki <macro@mips.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version 2 | ||
11 | * of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * Derived loosely from ide-pmac.c, so: | ||
25 | * Copyright (C) 1998 Paul Mackerras. | ||
26 | * Copyright (C) 1995-1998 Mark Lord | ||
27 | */ | ||
28 | |||
29 | /* | ||
30 | * Boards with SiByte processors so far have supported IDE devices via | ||
31 | * the Generic Bus, PCI bus, and built-in PCMCIA interface. In all | ||
32 | * cases, byte-swapping must be avoided for these devices (whereas | ||
33 | * other PCI devices, for example, will require swapping). Any | ||
34 | * SiByte-targetted kernel including IDE support will include this | ||
35 | * file. Probing of a Generic Bus for an IDE device is controlled by | ||
36 | * the definition of "SIBYTE_HAVE_IDE", which is provided by | ||
37 | * <asm/sibyte/board.h> for Broadcom boards. | ||
38 | */ | ||
39 | |||
40 | #include <linux/ide.h> | ||
41 | #include <linux/ioport.h> | ||
42 | #include <linux/kernel.h> | ||
43 | #include <linux/types.h> | ||
44 | #include <linux/platform_device.h> | ||
45 | |||
46 | #include <asm/io.h> | ||
47 | |||
48 | #include <asm/sibyte/board.h> | ||
49 | #include <asm/sibyte/sb1250_genbus.h> | ||
50 | #include <asm/sibyte/sb1250_regs.h> | ||
51 | |||
52 | #define DRV_NAME "ide-swarm" | ||
53 | |||
54 | static char swarm_ide_string[] = DRV_NAME; | ||
55 | |||
56 | static struct resource swarm_ide_resource = { | ||
57 | .name = "SWARM GenBus IDE", | ||
58 | .flags = IORESOURCE_MEM, | ||
59 | }; | ||
60 | |||
61 | static struct platform_device *swarm_ide_dev; | ||
62 | |||
63 | /* | ||
64 | * swarm_ide_probe - if the board header indicates the existence of | ||
65 | * Generic Bus IDE, allocate a HWIF for it. | ||
66 | */ | ||
67 | static int __devinit swarm_ide_probe(struct device *dev) | ||
68 | { | ||
69 | ide_hwif_t *hwif; | ||
70 | u8 __iomem *base; | ||
71 | phys_t offset, size; | ||
72 | int i; | ||
73 | |||
74 | if (!SIBYTE_HAVE_IDE) | ||
75 | return -ENODEV; | ||
76 | |||
77 | /* Find an empty slot. */ | ||
78 | for (i = 0; i < MAX_HWIFS; i++) | ||
79 | if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET]) | ||
80 | break; | ||
81 | if (i >= MAX_HWIFS) { | ||
82 | printk(KERN_ERR DRV_NAME ": no free slot for interface\n"); | ||
83 | return -ENOMEM; | ||
84 | } | ||
85 | |||
86 | hwif = ide_hwifs + i; | ||
87 | |||
88 | base = ioremap(A_IO_EXT_BASE, 0x800); | ||
89 | offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)); | ||
90 | size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS)); | ||
91 | iounmap(base); | ||
92 | |||
93 | offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE; | ||
94 | size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE; | ||
95 | if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) { | ||
96 | printk(KERN_INFO DRV_NAME | ||
97 | ": IDE interface at GenBus disabled\n"); | ||
98 | return -EBUSY; | ||
99 | } | ||
100 | |||
101 | printk(KERN_INFO DRV_NAME ": IDE interface at GenBus slot %i\n", | ||
102 | IDE_CS); | ||
103 | |||
104 | swarm_ide_resource.start = offset; | ||
105 | swarm_ide_resource.end = offset + size - 1; | ||
106 | if (request_resource(&iomem_resource, &swarm_ide_resource)) { | ||
107 | printk(KERN_ERR DRV_NAME | ||
108 | ": can't request I/O memory resource\n"); | ||
109 | return -EBUSY; | ||
110 | } | ||
111 | |||
112 | base = ioremap(offset, size); | ||
113 | |||
114 | /* Setup MMIO ops. */ | ||
115 | default_hwif_mmiops(hwif); | ||
116 | /* Prevent resource map manipulation. */ | ||
117 | hwif->mmio = 2; | ||
118 | hwif->noprobe = 0; | ||
119 | |||
120 | for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) | ||
121 | hwif->hw.io_ports[i] = | ||
122 | (unsigned long)(base + ((0x1f0 + i) << 5)); | ||
123 | hwif->hw.io_ports[IDE_CONTROL_OFFSET] = | ||
124 | (unsigned long)(base + (0x3f6 << 5)); | ||
125 | hwif->hw.irq = K_INT_GB_IDE; | ||
126 | |||
127 | memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); | ||
128 | hwif->irq = hwif->hw.irq; | ||
129 | |||
130 | dev_set_drvdata(dev, hwif); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static struct device_driver swarm_ide_driver = { | ||
136 | .name = swarm_ide_string, | ||
137 | .bus = &platform_bus_type, | ||
138 | .probe = swarm_ide_probe, | ||
139 | }; | ||
140 | |||
141 | static void swarm_ide_platform_release(struct device *device) | ||
142 | { | ||
143 | struct platform_device *pldev; | ||
144 | |||
145 | /* free device */ | ||
146 | pldev = to_platform_device(device); | ||
147 | kfree(pldev); | ||
148 | } | ||
149 | |||
150 | static int __devinit swarm_ide_init_module(void) | ||
151 | { | ||
152 | struct platform_device *pldev; | ||
153 | int err; | ||
154 | |||
155 | printk(KERN_INFO "SWARM IDE driver\n"); | ||
156 | |||
157 | if (driver_register(&swarm_ide_driver)) { | ||
158 | printk(KERN_ERR "Driver registration failed\n"); | ||
159 | err = -ENODEV; | ||
160 | goto out; | ||
161 | } | ||
162 | |||
163 | if (!(pldev = kmalloc(sizeof (*pldev), GFP_KERNEL))) { | ||
164 | err = -ENOMEM; | ||
165 | goto out_unregister_driver; | ||
166 | } | ||
167 | |||
168 | memset (pldev, 0, sizeof (*pldev)); | ||
169 | pldev->name = swarm_ide_string; | ||
170 | pldev->id = 0; | ||
171 | pldev->dev.release = swarm_ide_platform_release; | ||
172 | |||
173 | if (platform_device_register(pldev)) { | ||
174 | err = -ENODEV; | ||
175 | goto out_free_pldev; | ||
176 | } | ||
177 | |||
178 | if (!pldev->dev.driver) { | ||
179 | /* | ||
180 | * The driver was not bound to this device, there was | ||
181 | * no hardware at this address. Unregister it, as the | ||
182 | * release fuction will take care of freeing the | ||
183 | * allocated structure | ||
184 | */ | ||
185 | platform_device_unregister (pldev); | ||
186 | } | ||
187 | |||
188 | swarm_ide_dev = pldev; | ||
189 | |||
190 | return 0; | ||
191 | |||
192 | out_free_pldev: | ||
193 | kfree(pldev); | ||
194 | |||
195 | out_unregister_driver: | ||
196 | driver_unregister(&swarm_ide_driver); | ||
197 | out: | ||
198 | return err; | ||
199 | } | ||
200 | |||
201 | module_init(swarm_ide_init_module); | ||
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index ea0806c82be0..8a5c7b286b2b 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c | |||
@@ -399,34 +399,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c | |||
399 | return dev->irq; | 399 | return dev->irq; |
400 | } | 400 | } |
401 | 401 | ||
402 | static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base) | ||
403 | { | ||
404 | unsigned int rev; | ||
405 | u8 dma_state; | ||
406 | |||
407 | DBG(("init_dma_sl82c105(hwif: ide%d, dma_base: 0x%08x)\n", hwif->index, dma_base)); | ||
408 | |||
409 | hwif->autodma = 0; | ||
410 | |||
411 | if (!dma_base) | ||
412 | return; | ||
413 | |||
414 | dma_state = hwif->INB(dma_base + 2); | ||
415 | rev = sl82c105_bridge_revision(hwif->pci_dev); | ||
416 | if (rev <= 5) { | ||
417 | printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", | ||
418 | hwif->name, rev); | ||
419 | dma_state &= ~0x60; | ||
420 | } else { | ||
421 | dma_state |= 0x60; | ||
422 | if (!noautodma) | ||
423 | hwif->autodma = 1; | ||
424 | } | ||
425 | hwif->OUTB(dma_state, dma_base + 2); | ||
426 | |||
427 | ide_setup_dma(hwif, dma_base, 8); | ||
428 | } | ||
429 | |||
430 | /* | 402 | /* |
431 | * Initialise the chip | 403 | * Initialise the chip |
432 | */ | 404 | */ |
@@ -434,6 +406,8 @@ static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base | |||
434 | static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | 406 | static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) |
435 | { | 407 | { |
436 | struct pci_dev *dev = hwif->pci_dev; | 408 | struct pci_dev *dev = hwif->pci_dev; |
409 | unsigned int rev; | ||
410 | u8 dma_state; | ||
437 | u32 val; | 411 | u32 val; |
438 | 412 | ||
439 | DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); | 413 | DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); |
@@ -455,33 +429,54 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
455 | pci_read_config_dword(dev, 0x40, &val); | 429 | pci_read_config_dword(dev, 0x40, &val); |
456 | *((u32 *)&hwif->hwif_data) = val; | 430 | *((u32 *)&hwif->hwif_data) = val; |
457 | 431 | ||
432 | hwif->atapi_dma = 0; | ||
433 | hwif->mwdma_mask = 0; | ||
434 | hwif->swdma_mask = 0; | ||
435 | hwif->autodma = 0; | ||
436 | |||
458 | if (!hwif->dma_base) | 437 | if (!hwif->dma_base) |
459 | return; | 438 | return; |
460 | 439 | ||
461 | hwif->atapi_dma = 1; | 440 | dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60; |
462 | hwif->mwdma_mask = 0x07; | 441 | rev = sl82c105_bridge_revision(hwif->pci_dev); |
463 | hwif->swdma_mask = 0x07; | 442 | if (rev <= 5) { |
464 | 443 | /* | |
444 | * Never ever EVER under any circumstances enable | ||
445 | * DMA when the bridge is this old. | ||
446 | */ | ||
447 | printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", | ||
448 | hwif->name, rev); | ||
449 | } else { | ||
465 | #ifdef CONFIG_BLK_DEV_IDEDMA | 450 | #ifdef CONFIG_BLK_DEV_IDEDMA |
466 | hwif->ide_dma_check = &sl82c105_check_drive; | 451 | dma_state |= 0x60; |
467 | hwif->ide_dma_on = &sl82c105_ide_dma_on; | 452 | |
468 | hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; | 453 | hwif->atapi_dma = 1; |
469 | hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; | 454 | hwif->mwdma_mask = 0x07; |
470 | hwif->dma_start = &sl82c105_ide_dma_start; | 455 | hwif->swdma_mask = 0x07; |
471 | hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; | 456 | |
472 | 457 | hwif->ide_dma_check = &sl82c105_check_drive; | |
473 | if (!noautodma) | 458 | hwif->ide_dma_on = &sl82c105_ide_dma_on; |
474 | hwif->autodma = 1; | 459 | hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; |
475 | hwif->drives[0].autodma = hwif->autodma; | 460 | hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; |
476 | hwif->drives[1].autodma = hwif->autodma; | 461 | hwif->dma_start = &sl82c105_ide_dma_start; |
462 | hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; | ||
463 | |||
464 | if (!noautodma) | ||
465 | hwif->autodma = 1; | ||
466 | hwif->drives[0].autodma = hwif->autodma; | ||
467 | hwif->drives[1].autodma = hwif->autodma; | ||
468 | |||
469 | if (hwif->mate) | ||
470 | hwif->serialized = hwif->mate->serialized = 1; | ||
477 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | 471 | #endif /* CONFIG_BLK_DEV_IDEDMA */ |
472 | } | ||
473 | hwif->OUTB(dma_state, hwif->dma_base + 2); | ||
478 | } | 474 | } |
479 | 475 | ||
480 | static ide_pci_device_t sl82c105_chipset __devinitdata = { | 476 | static ide_pci_device_t sl82c105_chipset __devinitdata = { |
481 | .name = "W82C105", | 477 | .name = "W82C105", |
482 | .init_chipset = init_chipset_sl82c105, | 478 | .init_chipset = init_chipset_sl82c105, |
483 | .init_hwif = init_hwif_sl82c105, | 479 | .init_hwif = init_hwif_sl82c105, |
484 | .init_dma = init_dma_sl82c105, | ||
485 | .channels = 2, | 480 | .channels = 2, |
486 | .autodma = NOAUTODMA, | 481 | .autodma = NOAUTODMA, |
487 | .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, | 482 | .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, |
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index b3e65a65d202..136911a86e84 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -1667,11 +1667,16 @@ static struct macio_driver pmac_ide_macio_driver = | |||
1667 | }; | 1667 | }; |
1668 | 1668 | ||
1669 | static struct pci_device_id pmac_ide_pci_match[] = { | 1669 | static struct pci_device_id pmac_ide_pci_match[] = { |
1670 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 1670 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA, |
1671 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 1671 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
1672 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 1672 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, |
1673 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
1674 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, | ||
1675 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
1673 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA, | 1676 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA, |
1674 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 1677 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
1678 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA, | ||
1679 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
1675 | }; | 1680 | }; |
1676 | 1681 | ||
1677 | static struct pci_driver pmac_ide_pci_driver = { | 1682 | static struct pci_driver pmac_ide_pci_driver = { |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index 32bf0d5d0f9a..f8457ef48826 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
@@ -71,78 +71,68 @@ typedef struct { | |||
71 | /****************************************/ | 71 | /****************************************/ |
72 | static struct usb_device_id hfcusb_idtab[] = { | 72 | static struct usb_device_id hfcusb_idtab[] = { |
73 | { | 73 | { |
74 | .idVendor = 0x0959, | 74 | USB_DEVICE(0x0959, 0x2bd0), |
75 | .idProduct = 0x2bd0, | ||
76 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 75 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
77 | {LED_OFF, {4, 0, 2, 1}, | 76 | {LED_OFF, {4, 0, 2, 1}, |
78 | "ISDN USB TA (Cologne Chip HFC-S USB based)"}), | 77 | "ISDN USB TA (Cologne Chip HFC-S USB based)"}), |
79 | }, | 78 | }, |
80 | { | 79 | { |
81 | .idVendor = 0x0675, | 80 | USB_DEVICE(0x0675, 0x1688), |
82 | .idProduct = 0x1688, | ||
83 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 81 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
84 | {LED_SCHEME1, {1, 2, 0, 0}, | 82 | {LED_SCHEME1, {1, 2, 0, 0}, |
85 | "DrayTek miniVigor 128 USB ISDN TA"}), | 83 | "DrayTek miniVigor 128 USB ISDN TA"}), |
86 | }, | 84 | }, |
87 | { | 85 | { |
88 | .idVendor = 0x07b0, | 86 | USB_DEVICE(0x07b0, 0x0007), |
89 | .idProduct = 0x0007, | ||
90 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 87 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
91 | {LED_SCHEME1, {0x80, -64, -32, -16}, | 88 | {LED_SCHEME1, {0x80, -64, -32, -16}, |
92 | "Billion tiny USB ISDN TA 128"}), | 89 | "Billion tiny USB ISDN TA 128"}), |
93 | }, | 90 | }, |
94 | { | 91 | { |
95 | .idVendor = 0x0742, | 92 | USB_DEVICE(0x0742, 0x2008), |
96 | .idProduct = 0x2008, | ||
97 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 93 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
98 | {LED_SCHEME1, {4, 0, 2, 1}, | 94 | {LED_SCHEME1, {4, 0, 2, 1}, |
99 | "Stollmann USB TA"}), | 95 | "Stollmann USB TA"}), |
100 | }, | 96 | }, |
101 | { | 97 | { |
102 | .idVendor = 0x0742, | 98 | USB_DEVICE(0x0742, 0x2009), |
103 | .idProduct = 0x2009, | ||
104 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 99 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
105 | {LED_SCHEME1, {4, 0, 2, 1}, | 100 | {LED_SCHEME1, {4, 0, 2, 1}, |
106 | "Aceex USB ISDN TA"}), | 101 | "Aceex USB ISDN TA"}), |
107 | }, | 102 | }, |
108 | { | 103 | { |
109 | .idVendor = 0x0742, | 104 | USB_DEVICE(0x0742, 0x200A), |
110 | .idProduct = 0x200A, | ||
111 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 105 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
112 | {LED_SCHEME1, {4, 0, 2, 1}, | 106 | {LED_SCHEME1, {4, 0, 2, 1}, |
113 | "OEM USB ISDN TA"}), | 107 | "OEM USB ISDN TA"}), |
114 | }, | 108 | }, |
115 | { | 109 | { |
116 | .idVendor = 0x08e3, | 110 | USB_DEVICE(0x08e3, 0x0301), |
117 | .idProduct = 0x0301, | ||
118 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 111 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
119 | {LED_SCHEME1, {2, 0, 1, 4}, | 112 | {LED_SCHEME1, {2, 0, 1, 4}, |
120 | "Olitec USB RNIS"}), | 113 | "Olitec USB RNIS"}), |
121 | }, | 114 | }, |
122 | { | 115 | { |
123 | .idVendor = 0x07fa, | 116 | USB_DEVICE(0x07fa, 0x0846), |
124 | .idProduct = 0x0846, | ||
125 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 117 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
126 | {LED_SCHEME1, {0x80, -64, -32, -16}, | 118 | {LED_SCHEME1, {0x80, -64, -32, -16}, |
127 | "Bewan Modem RNIS USB"}), | 119 | "Bewan Modem RNIS USB"}), |
128 | }, | 120 | }, |
129 | { | 121 | { |
130 | .idVendor = 0x07fa, | 122 | USB_DEVICE(0x07fa, 0x0847), |
131 | .idProduct = 0x0847, | ||
132 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 123 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
133 | {LED_SCHEME1, {0x80, -64, -32, -16}, | 124 | {LED_SCHEME1, {0x80, -64, -32, -16}, |
134 | "Djinn Numeris USB"}), | 125 | "Djinn Numeris USB"}), |
135 | }, | 126 | }, |
136 | { | 127 | { |
137 | .idVendor = 0x07b0, | 128 | USB_DEVICE(0x07b0, 0x0006), |
138 | .idProduct = 0x0006, | ||
139 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 129 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
140 | {LED_SCHEME1, {0x80, -64, -32, -16}, | 130 | {LED_SCHEME1, {0x80, -64, -32, -16}, |
141 | "Twister ISDN TA"}), | 131 | "Twister ISDN TA"}), |
142 | }, | 132 | }, |
133 | { } | ||
143 | }; | 134 | }; |
144 | 135 | ||
145 | |||
146 | /***************************************************************/ | 136 | /***************************************************************/ |
147 | /* structure defining input+output fifos (interrupt/bulk mode) */ | 137 | /* structure defining input+output fifos (interrupt/bulk mode) */ |
148 | /***************************************************************/ | 138 | /***************************************************************/ |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 51315302a85e..252d55df9642 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -326,9 +326,9 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait) | |||
326 | } | 326 | } |
327 | } | 327 | } |
328 | 328 | ||
329 | ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); | 329 | ret = page->mapping->a_ops->prepare_write(bitmap->file, page, 0, PAGE_SIZE); |
330 | if (!ret) | 330 | if (!ret) |
331 | ret = page->mapping->a_ops->commit_write(NULL, page, 0, | 331 | ret = page->mapping->a_ops->commit_write(bitmap->file, page, 0, |
332 | PAGE_SIZE); | 332 | PAGE_SIZE); |
333 | if (ret) { | 333 | if (ret) { |
334 | unlock_page(page); | 334 | unlock_page(page); |
diff --git a/drivers/md/md.c b/drivers/md/md.c index adf960d8a7c9..78c7418478d6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -3156,7 +3156,7 @@ static int md_ioctl(struct inode *inode, struct file *file, | |||
3156 | if (cnt > 0 ) { | 3156 | if (cnt > 0 ) { |
3157 | printk(KERN_WARNING | 3157 | printk(KERN_WARNING |
3158 | "md: %s(pid %d) used deprecated START_ARRAY ioctl. " | 3158 | "md: %s(pid %d) used deprecated START_ARRAY ioctl. " |
3159 | "This will not be supported beyond 2.6\n", | 3159 | "This will not be supported beyond July 2006\n", |
3160 | current->comm, current->pid); | 3160 | current->comm, current->pid); |
3161 | cnt--; | 3161 | cnt--; |
3162 | } | 3162 | } |
@@ -3437,10 +3437,19 @@ static int md_thread(void * arg) | |||
3437 | allow_signal(SIGKILL); | 3437 | allow_signal(SIGKILL); |
3438 | while (!kthread_should_stop()) { | 3438 | while (!kthread_should_stop()) { |
3439 | 3439 | ||
3440 | wait_event_timeout(thread->wqueue, | 3440 | /* We need to wait INTERRUPTIBLE so that |
3441 | test_bit(THREAD_WAKEUP, &thread->flags) | 3441 | * we don't add to the load-average. |
3442 | || kthread_should_stop(), | 3442 | * That means we need to be sure no signals are |
3443 | thread->timeout); | 3443 | * pending |
3444 | */ | ||
3445 | if (signal_pending(current)) | ||
3446 | flush_signals(current); | ||
3447 | |||
3448 | wait_event_interruptible_timeout | ||
3449 | (thread->wqueue, | ||
3450 | test_bit(THREAD_WAKEUP, &thread->flags) | ||
3451 | || kthread_should_stop(), | ||
3452 | thread->timeout); | ||
3444 | try_to_freeze(); | 3453 | try_to_freeze(); |
3445 | 3454 | ||
3446 | clear_bit(THREAD_WAKEUP, &thread->flags); | 3455 | clear_bit(THREAD_WAKEUP, &thread->flags); |
@@ -3837,11 +3846,20 @@ static int is_mddev_idle(mddev_t *mddev) | |||
3837 | curr_events = disk_stat_read(disk, sectors[0]) + | 3846 | curr_events = disk_stat_read(disk, sectors[0]) + |
3838 | disk_stat_read(disk, sectors[1]) - | 3847 | disk_stat_read(disk, sectors[1]) - |
3839 | atomic_read(&disk->sync_io); | 3848 | atomic_read(&disk->sync_io); |
3840 | /* Allow some slack between valud of curr_events and last_events, | 3849 | /* The difference between curr_events and last_events |
3841 | * as there are some uninteresting races. | 3850 | * will be affected by any new non-sync IO (making |
3851 | * curr_events bigger) and any difference in the amount of | ||
3852 | * in-flight syncio (making current_events bigger or smaller) | ||
3853 | * The amount in-flight is currently limited to | ||
3854 | * 32*64K in raid1/10 and 256*PAGE_SIZE in raid5/6 | ||
3855 | * which is at most 4096 sectors. | ||
3856 | * These numbers are fairly fragile and should be made | ||
3857 | * more robust, probably by enforcing the | ||
3858 | * 'window size' that md_do_sync sort-of uses. | ||
3859 | * | ||
3842 | * Note: the following is an unsigned comparison. | 3860 | * Note: the following is an unsigned comparison. |
3843 | */ | 3861 | */ |
3844 | if ((curr_events - rdev->last_events + 32) > 64) { | 3862 | if ((curr_events - rdev->last_events + 4096) > 8192) { |
3845 | rdev->last_events = curr_events; | 3863 | rdev->last_events = curr_events; |
3846 | idle = 0; | 3864 | idle = 0; |
3847 | } | 3865 | } |
@@ -4100,7 +4118,7 @@ static void md_do_sync(mddev_t *mddev) | |||
4100 | if (currspeed > sysctl_speed_limit_min) { | 4118 | if (currspeed > sysctl_speed_limit_min) { |
4101 | if ((currspeed > sysctl_speed_limit_max) || | 4119 | if ((currspeed > sysctl_speed_limit_max) || |
4102 | !is_mddev_idle(mddev)) { | 4120 | !is_mddev_idle(mddev)) { |
4103 | msleep(250); | 4121 | msleep(500); |
4104 | goto repeat; | 4122 | goto repeat; |
4105 | } | 4123 | } |
4106 | } | 4124 | } |
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c index 4b71fd6f7aed..7972c73bc14e 100644 --- a/drivers/media/common/ir-common.c +++ b/drivers/media/common/ir-common.c | |||
@@ -126,6 +126,66 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
126 | }; | 126 | }; |
127 | EXPORT_SYMBOL_GPL(ir_codes_winfast); | 127 | EXPORT_SYMBOL_GPL(ir_codes_winfast); |
128 | 128 | ||
129 | IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | ||
130 | [ 0x59 ] = KEY_MUTE, | ||
131 | [ 0x4a ] = KEY_POWER, | ||
132 | |||
133 | [ 0x18 ] = KEY_TEXT, | ||
134 | [ 0x26 ] = KEY_TV, | ||
135 | [ 0x3d ] = KEY_PRINT, | ||
136 | |||
137 | [ 0x48 ] = KEY_RED, | ||
138 | [ 0x04 ] = KEY_GREEN, | ||
139 | [ 0x11 ] = KEY_YELLOW, | ||
140 | [ 0x00 ] = KEY_BLUE, | ||
141 | |||
142 | [ 0x2d ] = KEY_VOLUMEUP, | ||
143 | [ 0x1e ] = KEY_VOLUMEDOWN, | ||
144 | |||
145 | [ 0x49 ] = KEY_MENU, | ||
146 | |||
147 | [ 0x16 ] = KEY_CHANNELUP, | ||
148 | [ 0x17 ] = KEY_CHANNELDOWN, | ||
149 | |||
150 | [ 0x20 ] = KEY_UP, | ||
151 | [ 0x21 ] = KEY_DOWN, | ||
152 | [ 0x22 ] = KEY_LEFT, | ||
153 | [ 0x23 ] = KEY_RIGHT, | ||
154 | [ 0x0d ] = KEY_SELECT, | ||
155 | |||
156 | |||
157 | |||
158 | [ 0x08 ] = KEY_BACK, | ||
159 | [ 0x07 ] = KEY_REFRESH, | ||
160 | |||
161 | [ 0x2f ] = KEY_ZOOM, | ||
162 | [ 0x29 ] = KEY_RECORD, | ||
163 | |||
164 | [ 0x4b ] = KEY_PAUSE, | ||
165 | [ 0x4d ] = KEY_REWIND, | ||
166 | [ 0x2e ] = KEY_PLAY, | ||
167 | [ 0x4e ] = KEY_FORWARD, | ||
168 | [ 0x53 ] = KEY_PREVIOUS, | ||
169 | [ 0x4c ] = KEY_STOP, | ||
170 | [ 0x54 ] = KEY_NEXT, | ||
171 | |||
172 | [ 0x69 ] = KEY_KP0, | ||
173 | [ 0x6a ] = KEY_KP1, | ||
174 | [ 0x6b ] = KEY_KP2, | ||
175 | [ 0x6c ] = KEY_KP3, | ||
176 | [ 0x6d ] = KEY_KP4, | ||
177 | [ 0x6e ] = KEY_KP5, | ||
178 | [ 0x6f ] = KEY_KP6, | ||
179 | [ 0x70 ] = KEY_KP7, | ||
180 | [ 0x71 ] = KEY_KP8, | ||
181 | [ 0x72 ] = KEY_KP9, | ||
182 | |||
183 | [ 0x74 ] = KEY_CHANNEL, | ||
184 | [ 0x0a ] = KEY_BACKSPACE, | ||
185 | }; | ||
186 | |||
187 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle); | ||
188 | |||
129 | /* empty keytable, can be used as placeholder for not-yet created keytables */ | 189 | /* empty keytable, can be used as placeholder for not-yet created keytables */ |
130 | IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { | 190 | IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { |
131 | [ 42 ] = KEY_COFFEE, | 191 | [ 42 ] = KEY_COFFEE, |
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig index d7417eac2aba..2583a865a58e 100644 --- a/drivers/media/dvb/b2c2/Kconfig +++ b/drivers/media/dvb/b2c2/Kconfig | |||
@@ -7,6 +7,7 @@ config DVB_B2C2_FLEXCOP | |||
7 | select DVB_NXT2002 | 7 | select DVB_NXT2002 |
8 | select DVB_STV0297 | 8 | select DVB_STV0297 |
9 | select DVB_BCM3510 | 9 | select DVB_BCM3510 |
10 | select DVB_LGDT330X | ||
10 | help | 11 | help |
11 | Support for the digital TV receiver chip made by B2C2 Inc. included in | 12 | Support for the digital TV receiver chip made by B2C2 Inc. included in |
12 | Technisats PCI cards and USB boxes. | 13 | Technisats PCI cards and USB boxes. |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index a1607e7d6d6b..fb394a0d838c 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -276,7 +276,7 @@ static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2) | |||
276 | if (cinergyt2->stream_urb[i]) | 276 | if (cinergyt2->stream_urb[i]) |
277 | usb_free_urb(cinergyt2->stream_urb[i]); | 277 | usb_free_urb(cinergyt2->stream_urb[i]); |
278 | 278 | ||
279 | pci_free_consistent(NULL, STREAM_URB_COUNT*STREAM_BUF_SIZE, | 279 | usb_buffer_free(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE, |
280 | cinergyt2->streambuf, cinergyt2->streambuf_dmahandle); | 280 | cinergyt2->streambuf, cinergyt2->streambuf_dmahandle); |
281 | } | 281 | } |
282 | 282 | ||
@@ -284,9 +284,8 @@ static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2) | |||
284 | { | 284 | { |
285 | int i; | 285 | int i; |
286 | 286 | ||
287 | cinergyt2->streambuf = pci_alloc_consistent(NULL, | 287 | cinergyt2->streambuf = usb_buffer_alloc(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE, |
288 | STREAM_URB_COUNT*STREAM_BUF_SIZE, | 288 | SLAB_KERNEL, &cinergyt2->streambuf_dmahandle); |
289 | &cinergyt2->streambuf_dmahandle); | ||
290 | if (!cinergyt2->streambuf) { | 289 | if (!cinergyt2->streambuf) { |
291 | dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n"); | 290 | dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n"); |
292 | return -ENOMEM; | 291 | return -ENOMEM; |
@@ -780,6 +779,8 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) | |||
780 | 779 | ||
781 | input_register_device(cinergyt2->rc_input_dev); | 780 | input_register_device(cinergyt2->rc_input_dev); |
782 | schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); | 781 | schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); |
782 | |||
783 | return 0; | ||
783 | } | 784 | } |
784 | 785 | ||
785 | static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) | 786 | static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 199b01188858..1a3b3c7e5e99 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -333,4 +333,18 @@ config VIDEO_M32R_AR_M64278 | |||
333 | Say Y here to use the Renesas M64278E-800 camera module, | 333 | Say Y here to use the Renesas M64278E-800 camera module, |
334 | which supports VGA(640x480 pixcels) size of images. | 334 | which supports VGA(640x480 pixcels) size of images. |
335 | 335 | ||
336 | config VIDEO_AUDIO_DECODER | ||
337 | tristate "Add support for additional audio chipsets" | ||
338 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | ||
339 | ---help--- | ||
340 | Say Y here to compile drivers for WM8775 and CS53L32A audio | ||
341 | decoders. | ||
342 | |||
343 | config VIDEO_DECODER | ||
344 | tristate "Add support for additional video chipsets" | ||
345 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | ||
346 | ---help--- | ||
347 | Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 | ||
348 | video decoders. | ||
349 | |||
336 | endmenu | 350 | endmenu |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 3ac465992400..82060f9909d8 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -36,10 +36,11 @@ obj-$(CONFIG_VIDEO_CPIA) += cpia.o | |||
36 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o | 36 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o |
37 | obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o | 37 | obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o |
38 | obj-$(CONFIG_VIDEO_MEYE) += meye.o | 38 | obj-$(CONFIG_VIDEO_MEYE) += meye.o |
39 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ | 39 | obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ |
40 | obj-$(CONFIG_VIDEO_CX88) += cx88/ | 40 | obj-$(CONFIG_VIDEO_CX88) += cx88/ |
41 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ | 41 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ |
42 | obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o | 42 | obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o |
43 | obj-$(CONFIG_VIDEO_AUDIO_DECODER) += wm8775.o cs53l32a.o | ||
43 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ | 44 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ |
44 | obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o | 45 | obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o |
45 | obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o | 46 | obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o |
@@ -55,4 +56,6 @@ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o | |||
55 | 56 | ||
56 | obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o | 57 | obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o |
57 | 58 | ||
59 | obj-$(CONFIG_VIDEO_DECODER) += saa7115.o cx25840/ saa7127.o | ||
60 | |||
58 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 61 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core |
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 3413bace443a..e31ebb11c468 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c | |||
@@ -2133,7 +2133,10 @@ struct tvcard bttv_tvcards[] = { | |||
2133 | .tuner_addr = ADDR_UNSET, | 2133 | .tuner_addr = ADDR_UNSET, |
2134 | .radio_addr = ADDR_UNSET, | 2134 | .radio_addr = ADDR_UNSET, |
2135 | .has_dvb = 1, | 2135 | .has_dvb = 1, |
2136 | .has_remote = 1, | ||
2137 | .gpiomask = 0x1b, | ||
2136 | .no_gpioirq = 1, | 2138 | .no_gpioirq = 1, |
2139 | .any_irq = 1, | ||
2137 | }, | 2140 | }, |
2138 | [BTTV_BOARD_PV143] = { | 2141 | [BTTV_BOARD_PV143] = { |
2139 | /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ | 2142 | /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ |
@@ -2796,7 +2799,24 @@ struct tvcard bttv_tvcards[] = { | |||
2796 | .tuner_addr = ADDR_UNSET, | 2799 | .tuner_addr = ADDR_UNSET, |
2797 | .radio_addr = ADDR_UNSET, | 2800 | .radio_addr = ADDR_UNSET, |
2798 | }, | 2801 | }, |
2799 | 2802 | /* ---- card 0x8e ---------------------------------- */ | |
2803 | [BTTV_BOARD_SABRENT_TVFM] = { | ||
2804 | .name = "Sabrent TV-FM (bttv version)", | ||
2805 | .video_inputs = 3, | ||
2806 | .audio_inputs = 1, | ||
2807 | .tuner = 0, | ||
2808 | .svhs = 2, | ||
2809 | .gpiomask = 0x108007, | ||
2810 | .muxsel = { 2, 3, 1, 1}, | ||
2811 | .audiomux = { 100000, 100002, 100002, 100000}, | ||
2812 | .no_msp34xx = 1, | ||
2813 | .no_tda9875 = 1, | ||
2814 | .no_tda7432 = 1, | ||
2815 | .pll = PLL_28, | ||
2816 | .tuner_type = TUNER_TNF_5335MF, | ||
2817 | .tuner_addr = ADDR_UNSET, | ||
2818 | .has_radio = 1, | ||
2819 | }, | ||
2800 | }; | 2820 | }; |
2801 | 2821 | ||
2802 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); | 2822 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); |
@@ -3367,6 +3387,8 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3367 | btv->has_remote=1; | 3387 | btv->has_remote=1; |
3368 | if (!bttv_tvcards[btv->c.type].no_gpioirq) | 3388 | if (!bttv_tvcards[btv->c.type].no_gpioirq) |
3369 | btv->gpioirq=1; | 3389 | btv->gpioirq=1; |
3390 | if (bttv_tvcards[btv->c.type].any_irq) | ||
3391 | btv->any_irq = 1; | ||
3370 | if (bttv_tvcards[btv->c.type].audio_hook) | 3392 | if (bttv_tvcards[btv->c.type].audio_hook) |
3371 | btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; | 3393 | btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; |
3372 | 3394 | ||
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 0005741d5514..709099f03bd2 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
@@ -3667,6 +3667,10 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) | |||
3667 | int handled = 0; | 3667 | int handled = 0; |
3668 | 3668 | ||
3669 | btv=(struct bttv *)dev_id; | 3669 | btv=(struct bttv *)dev_id; |
3670 | |||
3671 | if (btv->any_irq) | ||
3672 | handled = bttv_any_irq(&btv->c); | ||
3673 | |||
3670 | count=0; | 3674 | count=0; |
3671 | while (1) { | 3675 | while (1) { |
3672 | /* get/clear interrupt status bits */ | 3676 | /* get/clear interrupt status bits */ |
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c index 575ce8b8e714..616a5b7e510c 100644 --- a/drivers/media/video/bttv-gpio.c +++ b/drivers/media/video/bttv-gpio.c | |||
@@ -113,6 +113,24 @@ void bttv_gpio_irq(struct bttv_core *core) | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | int bttv_any_irq(struct bttv_core *core) | ||
117 | { | ||
118 | struct bttv_sub_driver *drv; | ||
119 | struct bttv_sub_device *dev; | ||
120 | struct list_head *item; | ||
121 | int handled = 0; | ||
122 | |||
123 | list_for_each(item,&core->subs) { | ||
124 | dev = list_entry(item,struct bttv_sub_device,list); | ||
125 | drv = to_bttv_sub_drv(dev->dev.driver); | ||
126 | if (drv && drv->any_irq) { | ||
127 | if (drv->any_irq(dev)) | ||
128 | handled = 1; | ||
129 | } | ||
130 | } | ||
131 | return handled; | ||
132 | } | ||
133 | |||
116 | /* ----------------------------------------------------------------------- */ | 134 | /* ----------------------------------------------------------------------- */ |
117 | /* external: sub-driver register/unregister */ | 135 | /* external: sub-driver register/unregister */ |
118 | 136 | ||
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h index 124ea41dada4..93298f06e019 100644 --- a/drivers/media/video/bttv.h +++ b/drivers/media/video/bttv.h | |||
@@ -162,6 +162,7 @@ | |||
162 | #define BTTV_BOARD_PV_M4900 0x8b | 162 | #define BTTV_BOARD_PV_M4900 0x8b |
163 | #define BTTV_BOARD_OSPREY440 0x8c | 163 | #define BTTV_BOARD_OSPREY440 0x8c |
164 | #define BTTV_BOARD_ASOUND_SKYEYE 0x8d | 164 | #define BTTV_BOARD_ASOUND_SKYEYE 0x8d |
165 | #define BTTV_BOARD_SABRENT_TVFM 0x8e | ||
165 | 166 | ||
166 | /* i2c address list */ | 167 | /* i2c address list */ |
167 | #define I2C_TSA5522 0xc2 | 168 | #define I2C_TSA5522 0xc2 |
@@ -234,6 +235,7 @@ struct tvcard | |||
234 | unsigned int has_dvb:1; | 235 | unsigned int has_dvb:1; |
235 | unsigned int has_remote:1; | 236 | unsigned int has_remote:1; |
236 | unsigned int no_gpioirq:1; | 237 | unsigned int no_gpioirq:1; |
238 | unsigned int any_irq:1; | ||
237 | 239 | ||
238 | /* other settings */ | 240 | /* other settings */ |
239 | unsigned int pll; | 241 | unsigned int pll; |
@@ -333,6 +335,7 @@ struct bttv_sub_driver { | |||
333 | struct device_driver drv; | 335 | struct device_driver drv; |
334 | char wanted[BUS_ID_SIZE]; | 336 | char wanted[BUS_ID_SIZE]; |
335 | void (*gpio_irq)(struct bttv_sub_device *sub); | 337 | void (*gpio_irq)(struct bttv_sub_device *sub); |
338 | int (*any_irq)(struct bttv_sub_device *sub); | ||
336 | }; | 339 | }; |
337 | #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) | 340 | #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) |
338 | 341 | ||
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index 386f546f7d11..3aa9c6e4fc33 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h | |||
@@ -208,6 +208,7 @@ extern struct bus_type bttv_sub_bus_type; | |||
208 | int bttv_sub_add_device(struct bttv_core *core, char *name); | 208 | int bttv_sub_add_device(struct bttv_core *core, char *name); |
209 | int bttv_sub_del_devices(struct bttv_core *core); | 209 | int bttv_sub_del_devices(struct bttv_core *core); |
210 | void bttv_gpio_irq(struct bttv_core *core); | 210 | void bttv_gpio_irq(struct bttv_core *core); |
211 | int bttv_any_irq(struct bttv_core *core); | ||
211 | 212 | ||
212 | 213 | ||
213 | /* ---------------------------------------------------------- */ | 214 | /* ---------------------------------------------------------- */ |
@@ -273,6 +274,7 @@ struct bttv { | |||
273 | struct bttv_pll_info pll; | 274 | struct bttv_pll_info pll; |
274 | int triton1; | 275 | int triton1; |
275 | int gpioirq; | 276 | int gpioirq; |
277 | int any_irq; | ||
276 | int use_i2c_hw; | 278 | int use_i2c_hw; |
277 | 279 | ||
278 | /* old gpio interface */ | 280 | /* old gpio interface */ |
diff --git a/drivers/media/video/cx25840/Makefile b/drivers/media/video/cx25840/Makefile new file mode 100644 index 000000000000..543ebacdc9d7 --- /dev/null +++ b/drivers/media/video/cx25840/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \ | ||
2 | cx25840-vbi.o | ||
3 | |||
4 | obj-$(CONFIG_VIDEO_DECODER) += cx25840.o | ||
5 | |||
6 | EXTRA_CFLAGS += -I$(src)/.. | ||
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c new file mode 100644 index 000000000000..740908f8027d --- /dev/null +++ b/drivers/media/video/cx25840/cx25840-audio.c | |||
@@ -0,0 +1,368 @@ | |||
1 | /* cx25840 audio functions | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or | ||
4 | * modify it under the terms of the GNU General Public License | ||
5 | * as published by the Free Software Foundation; either version 2 | ||
6 | * of the License, or (at your option) any later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
16 | */ | ||
17 | |||
18 | |||
19 | #include <linux/videodev2.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <media/audiochip.h> | ||
22 | #include <media/v4l2-common.h> | ||
23 | |||
24 | #include "cx25840.h" | ||
25 | |||
26 | inline static int set_audclk_freq(struct i2c_client *client, | ||
27 | enum v4l2_audio_clock_freq freq) | ||
28 | { | ||
29 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
30 | |||
31 | /* assert soft reset */ | ||
32 | cx25840_and_or(client, 0x810, ~0x1, 0x01); | ||
33 | |||
34 | /* common for all inputs and rates */ | ||
35 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ | ||
36 | cx25840_write(client, 0x127, 0x50); | ||
37 | |||
38 | switch (state->audio_input) { | ||
39 | case AUDIO_TUNER: | ||
40 | switch (freq) { | ||
41 | case V4L2_AUDCLK_32_KHZ: | ||
42 | /* VID_PLL and AUX_PLL */ | ||
43 | cx25840_write4(client, 0x108, 0x0f040610); | ||
44 | |||
45 | /* AUX_PLL_FRAC */ | ||
46 | cx25840_write4(client, 0x110, 0xee39bb01); | ||
47 | |||
48 | /* src3/4/6_ctl = 0x0801f77f */ | ||
49 | cx25840_write4(client, 0x900, 0x7ff70108); | ||
50 | cx25840_write4(client, 0x904, 0x7ff70108); | ||
51 | cx25840_write4(client, 0x90c, 0x7ff70108); | ||
52 | break; | ||
53 | |||
54 | case V4L2_AUDCLK_441_KHZ: | ||
55 | /* VID_PLL and AUX_PLL */ | ||
56 | cx25840_write4(client, 0x108, 0x0f040910); | ||
57 | |||
58 | /* AUX_PLL_FRAC */ | ||
59 | cx25840_write4(client, 0x110, 0xd66bec00); | ||
60 | |||
61 | /* src3/4/6_ctl = 0x08016d59 */ | ||
62 | cx25840_write4(client, 0x900, 0x596d0108); | ||
63 | cx25840_write4(client, 0x904, 0x596d0108); | ||
64 | cx25840_write4(client, 0x90c, 0x596d0108); | ||
65 | break; | ||
66 | |||
67 | case V4L2_AUDCLK_48_KHZ: | ||
68 | /* VID_PLL and AUX_PLL */ | ||
69 | cx25840_write4(client, 0x108, 0x0f040a10); | ||
70 | |||
71 | /* AUX_PLL_FRAC */ | ||
72 | cx25840_write4(client, 0x110, 0xe5d69800); | ||
73 | |||
74 | /* src3/4/6_ctl = 0x08014faa */ | ||
75 | cx25840_write4(client, 0x900, 0xaa4f0108); | ||
76 | cx25840_write4(client, 0x904, 0xaa4f0108); | ||
77 | cx25840_write4(client, 0x90c, 0xaa4f0108); | ||
78 | break; | ||
79 | } | ||
80 | break; | ||
81 | |||
82 | case AUDIO_EXTERN_1: | ||
83 | case AUDIO_EXTERN_2: | ||
84 | case AUDIO_INTERN: | ||
85 | case AUDIO_RADIO: | ||
86 | switch (freq) { | ||
87 | case V4L2_AUDCLK_32_KHZ: | ||
88 | /* VID_PLL and AUX_PLL */ | ||
89 | cx25840_write4(client, 0x108, 0x0f04081e); | ||
90 | |||
91 | /* AUX_PLL_FRAC */ | ||
92 | cx25840_write4(client, 0x110, 0x69082a01); | ||
93 | |||
94 | /* src1_ctl = 0x08010000 */ | ||
95 | cx25840_write4(client, 0x8f8, 0x00000108); | ||
96 | |||
97 | /* src3/4/6_ctl = 0x08020000 */ | ||
98 | cx25840_write4(client, 0x900, 0x00000208); | ||
99 | cx25840_write4(client, 0x904, 0x00000208); | ||
100 | cx25840_write4(client, 0x90c, 0x00000208); | ||
101 | |||
102 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ | ||
103 | cx25840_write(client, 0x127, 0x54); | ||
104 | break; | ||
105 | |||
106 | case V4L2_AUDCLK_441_KHZ: | ||
107 | /* VID_PLL and AUX_PLL */ | ||
108 | cx25840_write4(client, 0x108, 0x0f040918); | ||
109 | |||
110 | /* AUX_PLL_FRAC */ | ||
111 | cx25840_write4(client, 0x110, 0xd66bec00); | ||
112 | |||
113 | /* src1_ctl = 0x08010000 */ | ||
114 | cx25840_write4(client, 0x8f8, 0xcd600108); | ||
115 | |||
116 | /* src3/4/6_ctl = 0x08020000 */ | ||
117 | cx25840_write4(client, 0x900, 0x85730108); | ||
118 | cx25840_write4(client, 0x904, 0x85730108); | ||
119 | cx25840_write4(client, 0x90c, 0x85730108); | ||
120 | break; | ||
121 | |||
122 | case V4L2_AUDCLK_48_KHZ: | ||
123 | /* VID_PLL and AUX_PLL */ | ||
124 | cx25840_write4(client, 0x108, 0x0f040a18); | ||
125 | |||
126 | /* AUX_PLL_FRAC */ | ||
127 | cx25840_write4(client, 0x110, 0xe5d69800); | ||
128 | |||
129 | /* src1_ctl = 0x08010000 */ | ||
130 | cx25840_write4(client, 0x8f8, 0x00800108); | ||
131 | |||
132 | /* src3/4/6_ctl = 0x08020000 */ | ||
133 | cx25840_write4(client, 0x900, 0x55550108); | ||
134 | cx25840_write4(client, 0x904, 0x55550108); | ||
135 | cx25840_write4(client, 0x90c, 0x55550108); | ||
136 | break; | ||
137 | } | ||
138 | break; | ||
139 | } | ||
140 | |||
141 | /* deassert soft reset */ | ||
142 | cx25840_and_or(client, 0x810, ~0x1, 0x00); | ||
143 | |||
144 | state->audclk_freq = freq; | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int set_input(struct i2c_client *client, int audio_input) | ||
150 | { | ||
151 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
152 | |||
153 | cx25840_dbg("set audio input (%d)\n", audio_input); | ||
154 | |||
155 | /* stop microcontroller */ | ||
156 | cx25840_and_or(client, 0x803, ~0x10, 0); | ||
157 | |||
158 | /* Mute everything to prevent the PFFT! */ | ||
159 | cx25840_write(client, 0x8d3, 0x1f); | ||
160 | |||
161 | switch (audio_input) { | ||
162 | case AUDIO_TUNER: | ||
163 | /* Set Path1 to Analog Demod Main Channel */ | ||
164 | cx25840_write4(client, 0x8d0, 0x7038061f); | ||
165 | |||
166 | /* When the microcontroller detects the | ||
167 | * audio format, it will unmute the lines */ | ||
168 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | ||
169 | break; | ||
170 | |||
171 | case AUDIO_EXTERN_1: | ||
172 | case AUDIO_EXTERN_2: | ||
173 | case AUDIO_INTERN: | ||
174 | case AUDIO_RADIO: | ||
175 | /* Set Path1 to Serial Audio Input */ | ||
176 | cx25840_write4(client, 0x8d0, 0x12100101); | ||
177 | |||
178 | /* The microcontroller should not be started for the | ||
179 | * non-tuner inputs: autodetection is specific for | ||
180 | * TV audio. */ | ||
181 | break; | ||
182 | |||
183 | default: | ||
184 | cx25840_dbg("Invalid audio input selection %d\n", audio_input); | ||
185 | return -EINVAL; | ||
186 | } | ||
187 | |||
188 | state->audio_input = audio_input; | ||
189 | |||
190 | return set_audclk_freq(client, state->audclk_freq); | ||
191 | } | ||
192 | |||
193 | inline static int get_volume(struct i2c_client *client) | ||
194 | { | ||
195 | /* Volume runs +18dB to -96dB in 1/2dB steps | ||
196 | * change to fit the msp3400 -114dB to +12dB range */ | ||
197 | |||
198 | /* check PATH1_VOLUME */ | ||
199 | int vol = 228 - cx25840_read(client, 0x8d4); | ||
200 | vol = (vol / 2) + 23; | ||
201 | return vol << 9; | ||
202 | } | ||
203 | |||
204 | inline static void set_volume(struct i2c_client *client, int volume) | ||
205 | { | ||
206 | /* First convert the volume to msp3400 values (0-127) */ | ||
207 | int vol = volume >> 9; | ||
208 | /* now scale it up to cx25840 values | ||
209 | * -114dB to -96dB maps to 0 | ||
210 | * this should be 19, but in my testing that was 4dB too loud */ | ||
211 | if (vol <= 23) { | ||
212 | vol = 0; | ||
213 | } else { | ||
214 | vol -= 23; | ||
215 | } | ||
216 | |||
217 | /* PATH1_VOLUME */ | ||
218 | cx25840_write(client, 0x8d4, 228 - (vol * 2)); | ||
219 | } | ||
220 | |||
221 | inline static int get_bass(struct i2c_client *client) | ||
222 | { | ||
223 | /* bass is 49 steps +12dB to -12dB */ | ||
224 | |||
225 | /* check PATH1_EQ_BASS_VOL */ | ||
226 | int bass = cx25840_read(client, 0x8d9) & 0x3f; | ||
227 | bass = (((48 - bass) * 0xffff) + 47) / 48; | ||
228 | return bass; | ||
229 | } | ||
230 | |||
231 | inline static void set_bass(struct i2c_client *client, int bass) | ||
232 | { | ||
233 | /* PATH1_EQ_BASS_VOL */ | ||
234 | cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff)); | ||
235 | } | ||
236 | |||
237 | inline static int get_treble(struct i2c_client *client) | ||
238 | { | ||
239 | /* treble is 49 steps +12dB to -12dB */ | ||
240 | |||
241 | /* check PATH1_EQ_TREBLE_VOL */ | ||
242 | int treble = cx25840_read(client, 0x8db) & 0x3f; | ||
243 | treble = (((48 - treble) * 0xffff) + 47) / 48; | ||
244 | return treble; | ||
245 | } | ||
246 | |||
247 | inline static void set_treble(struct i2c_client *client, int treble) | ||
248 | { | ||
249 | /* PATH1_EQ_TREBLE_VOL */ | ||
250 | cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff)); | ||
251 | } | ||
252 | |||
253 | inline static int get_balance(struct i2c_client *client) | ||
254 | { | ||
255 | /* balance is 7 bit, 0 to -96dB */ | ||
256 | |||
257 | /* check PATH1_BAL_LEVEL */ | ||
258 | int balance = cx25840_read(client, 0x8d5) & 0x7f; | ||
259 | /* check PATH1_BAL_LEFT */ | ||
260 | if ((cx25840_read(client, 0x8d5) & 0x80) == 0) | ||
261 | balance = 0x80 - balance; | ||
262 | else | ||
263 | balance = 0x80 + balance; | ||
264 | return balance << 8; | ||
265 | } | ||
266 | |||
267 | inline static void set_balance(struct i2c_client *client, int balance) | ||
268 | { | ||
269 | int bal = balance >> 8; | ||
270 | if (bal > 0x80) { | ||
271 | /* PATH1_BAL_LEFT */ | ||
272 | cx25840_and_or(client, 0x8d5, 0x7f, 0x80); | ||
273 | /* PATH1_BAL_LEVEL */ | ||
274 | cx25840_and_or(client, 0x8d5, ~0x7f, bal & 0x7f); | ||
275 | } else { | ||
276 | /* PATH1_BAL_LEFT */ | ||
277 | cx25840_and_or(client, 0x8d5, 0x7f, 0x00); | ||
278 | /* PATH1_BAL_LEVEL */ | ||
279 | cx25840_and_or(client, 0x8d5, ~0x7f, 0x80 - bal); | ||
280 | } | ||
281 | } | ||
282 | |||
283 | inline static int get_mute(struct i2c_client *client) | ||
284 | { | ||
285 | /* check SRC1_MUTE_EN */ | ||
286 | return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0; | ||
287 | } | ||
288 | |||
289 | inline static void set_mute(struct i2c_client *client, int mute) | ||
290 | { | ||
291 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
292 | |||
293 | if (state->audio_input == AUDIO_TUNER) { | ||
294 | /* Must turn off microcontroller in order to mute sound. | ||
295 | * Not sure if this is the best method, but it does work. | ||
296 | * If the microcontroller is running, then it will undo any | ||
297 | * changes to the mute register. */ | ||
298 | if (mute) { | ||
299 | /* disable microcontroller */ | ||
300 | cx25840_and_or(client, 0x803, ~0x10, 0x00); | ||
301 | cx25840_write(client, 0x8d3, 0x1f); | ||
302 | } else { | ||
303 | /* enable microcontroller */ | ||
304 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | ||
305 | } | ||
306 | } else { | ||
307 | /* SRC1_MUTE_EN */ | ||
308 | cx25840_and_or(client, 0x8d3, ~0x2, mute ? 0x02 : 0x00); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | ||
313 | { | ||
314 | struct v4l2_control *ctrl = arg; | ||
315 | |||
316 | switch (cmd) { | ||
317 | case AUDC_SET_INPUT: | ||
318 | return set_input(client, *(int *)arg); | ||
319 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | ||
320 | return set_audclk_freq(client, *(enum v4l2_audio_clock_freq *)arg); | ||
321 | case VIDIOC_G_CTRL: | ||
322 | switch (ctrl->id) { | ||
323 | case V4L2_CID_AUDIO_VOLUME: | ||
324 | ctrl->value = get_volume(client); | ||
325 | break; | ||
326 | case V4L2_CID_AUDIO_BASS: | ||
327 | ctrl->value = get_bass(client); | ||
328 | break; | ||
329 | case V4L2_CID_AUDIO_TREBLE: | ||
330 | ctrl->value = get_treble(client); | ||
331 | break; | ||
332 | case V4L2_CID_AUDIO_BALANCE: | ||
333 | ctrl->value = get_balance(client); | ||
334 | break; | ||
335 | case V4L2_CID_AUDIO_MUTE: | ||
336 | ctrl->value = get_mute(client); | ||
337 | break; | ||
338 | default: | ||
339 | return -EINVAL; | ||
340 | } | ||
341 | break; | ||
342 | case VIDIOC_S_CTRL: | ||
343 | switch (ctrl->id) { | ||
344 | case V4L2_CID_AUDIO_VOLUME: | ||
345 | set_volume(client, ctrl->value); | ||
346 | break; | ||
347 | case V4L2_CID_AUDIO_BASS: | ||
348 | set_bass(client, ctrl->value); | ||
349 | break; | ||
350 | case V4L2_CID_AUDIO_TREBLE: | ||
351 | set_treble(client, ctrl->value); | ||
352 | break; | ||
353 | case V4L2_CID_AUDIO_BALANCE: | ||
354 | set_balance(client, ctrl->value); | ||
355 | break; | ||
356 | case V4L2_CID_AUDIO_MUTE: | ||
357 | set_mute(client, ctrl->value); | ||
358 | break; | ||
359 | default: | ||
360 | return -EINVAL; | ||
361 | } | ||
362 | break; | ||
363 | default: | ||
364 | return -EINVAL; | ||
365 | } | ||
366 | |||
367 | return 0; | ||
368 | } | ||
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c new file mode 100644 index 000000000000..f6afeec499c5 --- /dev/null +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -0,0 +1,1020 @@ | |||
1 | /* cx25840 - Conexant CX25840 audio/video decoder driver | ||
2 | * | ||
3 | * Copyright (C) 2004 Ulf Eklund | ||
4 | * | ||
5 | * Based on the saa7115 driver and on the first verison of Chris Kennedy's | ||
6 | * cx25840 driver. | ||
7 | * | ||
8 | * Changes by Tyler Trafford <tatrafford@comcast.net> | ||
9 | * - cleanup/rewrite for V4L2 API (2005) | ||
10 | * | ||
11 | * VBI support by Hans Verkuil <hverkuil@xs4all.nl>. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
26 | */ | ||
27 | |||
28 | |||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/videodev2.h> | ||
33 | #include <linux/i2c.h> | ||
34 | #include <media/audiochip.h> | ||
35 | #include <media/v4l2-common.h> | ||
36 | |||
37 | #include "cx25840.h" | ||
38 | |||
39 | MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver"); | ||
40 | MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford"); | ||
41 | MODULE_LICENSE("GPL"); | ||
42 | |||
43 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | ||
44 | |||
45 | |||
46 | int cx25840_debug = 0; | ||
47 | |||
48 | module_param(cx25840_debug, bool, 0644); | ||
49 | |||
50 | MODULE_PARM_DESC(cx25840_debug, "Debugging messages [0=Off (default) 1=On]"); | ||
51 | |||
52 | I2C_CLIENT_INSMOD; | ||
53 | |||
54 | /* ----------------------------------------------------------------------- */ | ||
55 | |||
56 | int cx25840_write(struct i2c_client *client, u16 addr, u8 value) | ||
57 | { | ||
58 | u8 buffer[3]; | ||
59 | buffer[0] = addr >> 8; | ||
60 | buffer[1] = addr & 0xff; | ||
61 | buffer[2] = value; | ||
62 | return i2c_master_send(client, buffer, 3); | ||
63 | } | ||
64 | |||
65 | int cx25840_write4(struct i2c_client *client, u16 addr, u32 value) | ||
66 | { | ||
67 | u8 buffer[6]; | ||
68 | buffer[0] = addr >> 8; | ||
69 | buffer[1] = addr & 0xff; | ||
70 | buffer[2] = value >> 24; | ||
71 | buffer[3] = (value >> 16) & 0xff; | ||
72 | buffer[4] = (value >> 8) & 0xff; | ||
73 | buffer[5] = value & 0xff; | ||
74 | return i2c_master_send(client, buffer, 6); | ||
75 | } | ||
76 | |||
77 | u8 cx25840_read(struct i2c_client * client, u16 addr) | ||
78 | { | ||
79 | u8 buffer[2]; | ||
80 | buffer[0] = addr >> 8; | ||
81 | buffer[1] = addr & 0xff; | ||
82 | |||
83 | if (i2c_master_send(client, buffer, 2) < 2) | ||
84 | return 0; | ||
85 | |||
86 | if (i2c_master_recv(client, buffer, 1) < 1) | ||
87 | return 0; | ||
88 | |||
89 | return buffer[0]; | ||
90 | } | ||
91 | |||
92 | u32 cx25840_read4(struct i2c_client * client, u16 addr) | ||
93 | { | ||
94 | u8 buffer[4]; | ||
95 | buffer[0] = addr >> 8; | ||
96 | buffer[1] = addr & 0xff; | ||
97 | |||
98 | if (i2c_master_send(client, buffer, 2) < 2) | ||
99 | return 0; | ||
100 | |||
101 | if (i2c_master_recv(client, buffer, 4) < 4) | ||
102 | return 0; | ||
103 | |||
104 | return (buffer[0] << 24) | (buffer[1] << 16) | | ||
105 | (buffer[2] << 8) | buffer[3]; | ||
106 | } | ||
107 | |||
108 | int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, | ||
109 | u8 or_value) | ||
110 | { | ||
111 | return cx25840_write(client, addr, | ||
112 | (cx25840_read(client, addr) & and_mask) | | ||
113 | or_value); | ||
114 | } | ||
115 | |||
116 | /* ----------------------------------------------------------------------- */ | ||
117 | |||
118 | static int set_input(struct i2c_client *, enum cx25840_input); | ||
119 | static void input_change(struct i2c_client *); | ||
120 | static void log_status(struct i2c_client *client); | ||
121 | |||
122 | /* ----------------------------------------------------------------------- */ | ||
123 | |||
124 | static inline void init_dll1(struct i2c_client *client) | ||
125 | { | ||
126 | /* This is the Hauppauge sequence used to | ||
127 | * initialize the Delay Lock Loop 1 (ADC DLL). */ | ||
128 | cx25840_write(client, 0x159, 0x23); | ||
129 | cx25840_write(client, 0x15a, 0x87); | ||
130 | cx25840_write(client, 0x15b, 0x06); | ||
131 | cx25840_write(client, 0x159, 0xe1); | ||
132 | cx25840_write(client, 0x15a, 0x86); | ||
133 | cx25840_write(client, 0x159, 0xe0); | ||
134 | cx25840_write(client, 0x159, 0xe1); | ||
135 | cx25840_write(client, 0x15b, 0x10); | ||
136 | } | ||
137 | |||
138 | static inline void init_dll2(struct i2c_client *client) | ||
139 | { | ||
140 | /* This is the Hauppauge sequence used to | ||
141 | * initialize the Delay Lock Loop 2 (ADC DLL). */ | ||
142 | cx25840_write(client, 0x15d, 0xe3); | ||
143 | cx25840_write(client, 0x15e, 0x86); | ||
144 | cx25840_write(client, 0x15f, 0x06); | ||
145 | cx25840_write(client, 0x15d, 0xe1); | ||
146 | cx25840_write(client, 0x15d, 0xe0); | ||
147 | cx25840_write(client, 0x15d, 0xe1); | ||
148 | } | ||
149 | |||
150 | static void cx25840_initialize(struct i2c_client *client, int loadfw) | ||
151 | { | ||
152 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
153 | |||
154 | /* datasheet startup in numbered steps, refer to page 3-77 */ | ||
155 | /* 2. */ | ||
156 | cx25840_and_or(client, 0x803, ~0x10, 0x00); | ||
157 | /* The default of this register should be 4, but I get 0 instead. | ||
158 | * Set this register to 4 manually. */ | ||
159 | cx25840_write(client, 0x000, 0x04); | ||
160 | /* 3. */ | ||
161 | init_dll1(client); | ||
162 | init_dll2(client); | ||
163 | cx25840_write(client, 0x136, 0x0a); | ||
164 | /* 4. */ | ||
165 | cx25840_write(client, 0x13c, 0x01); | ||
166 | cx25840_write(client, 0x13c, 0x00); | ||
167 | /* 5. */ | ||
168 | if (loadfw) | ||
169 | cx25840_loadfw(client); | ||
170 | /* 6. */ | ||
171 | cx25840_write(client, 0x115, 0x8c); | ||
172 | cx25840_write(client, 0x116, 0x07); | ||
173 | cx25840_write(client, 0x118, 0x02); | ||
174 | /* 7. */ | ||
175 | cx25840_write(client, 0x4a5, 0x80); | ||
176 | cx25840_write(client, 0x4a5, 0x00); | ||
177 | cx25840_write(client, 0x402, 0x00); | ||
178 | /* 8. */ | ||
179 | cx25840_write(client, 0x401, 0x18); | ||
180 | cx25840_write(client, 0x4a2, 0x10); | ||
181 | cx25840_write(client, 0x402, 0x04); | ||
182 | /* 10. */ | ||
183 | cx25840_write(client, 0x8d3, 0x1f); | ||
184 | cx25840_write(client, 0x8e3, 0x03); | ||
185 | |||
186 | cx25840_vbi_setup(client); | ||
187 | |||
188 | /* trial and error says these are needed to get audio */ | ||
189 | cx25840_write(client, 0x914, 0xa0); | ||
190 | cx25840_write(client, 0x918, 0xa0); | ||
191 | cx25840_write(client, 0x919, 0x01); | ||
192 | |||
193 | /* stereo prefered */ | ||
194 | cx25840_write(client, 0x809, 0x04); | ||
195 | /* AC97 shift */ | ||
196 | cx25840_write(client, 0x8cf, 0x0f); | ||
197 | |||
198 | /* (re)set video input */ | ||
199 | set_input(client, state->input); | ||
200 | /* (re)set audio input */ | ||
201 | cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input); | ||
202 | |||
203 | /* start microcontroller */ | ||
204 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | ||
205 | } | ||
206 | |||
207 | /* ----------------------------------------------------------------------- */ | ||
208 | |||
209 | static void input_change(struct i2c_client *client) | ||
210 | { | ||
211 | v4l2_std_id std = cx25840_get_v4lstd(client); | ||
212 | |||
213 | if (std & V4L2_STD_PAL) { | ||
214 | /* Follow tuner change procedure for PAL */ | ||
215 | cx25840_write(client, 0x808, 0xff); | ||
216 | cx25840_write(client, 0x80b, 0x10); | ||
217 | } else if (std & V4L2_STD_SECAM) { | ||
218 | /* Select autodetect for SECAM */ | ||
219 | cx25840_write(client, 0x808, 0xff); | ||
220 | cx25840_write(client, 0x80b, 0x10); | ||
221 | } else if (std & V4L2_STD_NTSC) { | ||
222 | /* NTSC */ | ||
223 | cx25840_write(client, 0x808, 0xf6); | ||
224 | cx25840_write(client, 0x80b, 0x00); | ||
225 | } | ||
226 | |||
227 | if (cx25840_read(client, 0x803) & 0x10) { | ||
228 | /* restart audio decoder microcontroller */ | ||
229 | cx25840_and_or(client, 0x803, ~0x10, 0x00); | ||
230 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | static int set_input(struct i2c_client *client, enum cx25840_input input) | ||
235 | { | ||
236 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
237 | |||
238 | cx25840_dbg("decoder set input (%d)\n", input); | ||
239 | |||
240 | switch (input) { | ||
241 | case CX25840_TUNER: | ||
242 | cx25840_dbg("now setting Tuner input\n"); | ||
243 | |||
244 | if (state->cardtype == CARDTYPE_PVR150) { | ||
245 | /* CH_SEL_ADC2=1 */ | ||
246 | cx25840_and_or(client, 0x102, ~0x2, 0x02); | ||
247 | } | ||
248 | |||
249 | /* Video Input Control */ | ||
250 | if (state->cardtype == CARDTYPE_PG600) { | ||
251 | cx25840_write(client, 0x103, 0x11); | ||
252 | } else { | ||
253 | cx25840_write(client, 0x103, 0x46); | ||
254 | } | ||
255 | |||
256 | /* INPUT_MODE=0 */ | ||
257 | cx25840_and_or(client, 0x401, ~0x6, 0x00); | ||
258 | break; | ||
259 | |||
260 | case CX25840_COMPOSITE0: | ||
261 | case CX25840_COMPOSITE1: | ||
262 | cx25840_dbg("now setting Composite input\n"); | ||
263 | |||
264 | /* Video Input Control */ | ||
265 | if (state->cardtype == CARDTYPE_PG600) { | ||
266 | cx25840_write(client, 0x103, 0x00); | ||
267 | } else { | ||
268 | cx25840_write(client, 0x103, 0x02); | ||
269 | } | ||
270 | |||
271 | /* INPUT_MODE=0 */ | ||
272 | cx25840_and_or(client, 0x401, ~0x6, 0x00); | ||
273 | break; | ||
274 | |||
275 | case CX25840_SVIDEO0: | ||
276 | case CX25840_SVIDEO1: | ||
277 | cx25840_dbg("now setting S-Video input\n"); | ||
278 | |||
279 | /* CH_SEL_ADC2=0 */ | ||
280 | cx25840_and_or(client, 0x102, ~0x2, 0x00); | ||
281 | |||
282 | /* Video Input Control */ | ||
283 | if (state->cardtype == CARDTYPE_PG600) { | ||
284 | cx25840_write(client, 0x103, 0x02); | ||
285 | } else { | ||
286 | cx25840_write(client, 0x103, 0x10); | ||
287 | } | ||
288 | |||
289 | /* INPUT_MODE=1 */ | ||
290 | cx25840_and_or(client, 0x401, ~0x6, 0x02); | ||
291 | break; | ||
292 | |||
293 | default: | ||
294 | cx25840_err("%d is not a valid input!\n", input); | ||
295 | return -EINVAL; | ||
296 | } | ||
297 | |||
298 | state->input = input; | ||
299 | input_change(client); | ||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | /* ----------------------------------------------------------------------- */ | ||
304 | |||
305 | static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | ||
306 | { | ||
307 | u8 fmt; | ||
308 | |||
309 | switch (std) { | ||
310 | /* zero is autodetect */ | ||
311 | case 0: fmt = 0x0; break; | ||
312 | /* default ntsc to ntsc-m */ | ||
313 | case V4L2_STD_NTSC: | ||
314 | case V4L2_STD_NTSC_M: fmt = 0x1; break; | ||
315 | case V4L2_STD_NTSC_M_JP: fmt = 0x2; break; | ||
316 | case V4L2_STD_NTSC_443: fmt = 0x3; break; | ||
317 | case V4L2_STD_PAL: fmt = 0x4; break; | ||
318 | case V4L2_STD_PAL_M: fmt = 0x5; break; | ||
319 | case V4L2_STD_PAL_N: fmt = 0x6; break; | ||
320 | case V4L2_STD_PAL_Nc: fmt = 0x7; break; | ||
321 | case V4L2_STD_PAL_60: fmt = 0x8; break; | ||
322 | case V4L2_STD_SECAM: fmt = 0xc; break; | ||
323 | default: | ||
324 | return -ERANGE; | ||
325 | } | ||
326 | |||
327 | cx25840_and_or(client, 0x400, ~0xf, fmt); | ||
328 | cx25840_vbi_setup(client); | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) | ||
333 | { | ||
334 | /* check VID_FMT_SEL first */ | ||
335 | u8 fmt = cx25840_read(client, 0x400) & 0xf; | ||
336 | |||
337 | if (!fmt) { | ||
338 | /* check AFD_FMT_STAT if set to autodetect */ | ||
339 | fmt = cx25840_read(client, 0x40d) & 0xf; | ||
340 | } | ||
341 | |||
342 | switch (fmt) { | ||
343 | case 0x1: return V4L2_STD_NTSC_M; | ||
344 | case 0x2: return V4L2_STD_NTSC_M_JP; | ||
345 | case 0x3: return V4L2_STD_NTSC_443; | ||
346 | case 0x4: return V4L2_STD_PAL; | ||
347 | case 0x5: return V4L2_STD_PAL_M; | ||
348 | case 0x6: return V4L2_STD_PAL_N; | ||
349 | case 0x7: return V4L2_STD_PAL_Nc; | ||
350 | case 0x8: return V4L2_STD_PAL_60; | ||
351 | case 0xc: return V4L2_STD_SECAM; | ||
352 | default: return V4L2_STD_UNKNOWN; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | /* ----------------------------------------------------------------------- */ | ||
357 | |||
358 | static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
359 | { | ||
360 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
361 | |||
362 | switch (ctrl->id) { | ||
363 | case CX25840_CID_CARDTYPE: | ||
364 | switch (ctrl->value) { | ||
365 | case CARDTYPE_PVR150: | ||
366 | case CARDTYPE_PG600: | ||
367 | state->cardtype = ctrl->value; | ||
368 | break; | ||
369 | default: | ||
370 | return -ERANGE; | ||
371 | } | ||
372 | |||
373 | set_input(client, state->input); | ||
374 | break; | ||
375 | |||
376 | case V4L2_CID_BRIGHTNESS: | ||
377 | if (ctrl->value < 0 || ctrl->value > 255) { | ||
378 | cx25840_err("invalid brightness setting %d\n", | ||
379 | ctrl->value); | ||
380 | return -ERANGE; | ||
381 | } | ||
382 | |||
383 | cx25840_write(client, 0x414, ctrl->value - 128); | ||
384 | break; | ||
385 | |||
386 | case V4L2_CID_CONTRAST: | ||
387 | if (ctrl->value < 0 || ctrl->value > 127) { | ||
388 | cx25840_err("invalid contrast setting %d\n", | ||
389 | ctrl->value); | ||
390 | return -ERANGE; | ||
391 | } | ||
392 | |||
393 | cx25840_write(client, 0x415, ctrl->value << 1); | ||
394 | break; | ||
395 | |||
396 | case V4L2_CID_SATURATION: | ||
397 | if (ctrl->value < 0 || ctrl->value > 127) { | ||
398 | cx25840_err("invalid saturation setting %d\n", | ||
399 | ctrl->value); | ||
400 | return -ERANGE; | ||
401 | } | ||
402 | |||
403 | cx25840_write(client, 0x420, ctrl->value << 1); | ||
404 | cx25840_write(client, 0x421, ctrl->value << 1); | ||
405 | break; | ||
406 | |||
407 | case V4L2_CID_HUE: | ||
408 | if (ctrl->value < -127 || ctrl->value > 127) { | ||
409 | cx25840_err("invalid hue setting %d\n", ctrl->value); | ||
410 | return -ERANGE; | ||
411 | } | ||
412 | |||
413 | cx25840_write(client, 0x422, ctrl->value); | ||
414 | break; | ||
415 | |||
416 | case V4L2_CID_AUDIO_VOLUME: | ||
417 | case V4L2_CID_AUDIO_BASS: | ||
418 | case V4L2_CID_AUDIO_TREBLE: | ||
419 | case V4L2_CID_AUDIO_BALANCE: | ||
420 | case V4L2_CID_AUDIO_MUTE: | ||
421 | return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); | ||
422 | } | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
428 | { | ||
429 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
430 | |||
431 | switch (ctrl->id) { | ||
432 | case CX25840_CID_CARDTYPE: | ||
433 | ctrl->value = state->cardtype; | ||
434 | break; | ||
435 | case V4L2_CID_BRIGHTNESS: | ||
436 | ctrl->value = cx25840_read(client, 0x414) + 128; | ||
437 | break; | ||
438 | case V4L2_CID_CONTRAST: | ||
439 | ctrl->value = cx25840_read(client, 0x415) >> 1; | ||
440 | break; | ||
441 | case V4L2_CID_SATURATION: | ||
442 | ctrl->value = cx25840_read(client, 0x420) >> 1; | ||
443 | break; | ||
444 | case V4L2_CID_HUE: | ||
445 | ctrl->value = cx25840_read(client, 0x422); | ||
446 | break; | ||
447 | case V4L2_CID_AUDIO_VOLUME: | ||
448 | case V4L2_CID_AUDIO_BASS: | ||
449 | case V4L2_CID_AUDIO_TREBLE: | ||
450 | case V4L2_CID_AUDIO_BALANCE: | ||
451 | case V4L2_CID_AUDIO_MUTE: | ||
452 | return cx25840_audio(client, VIDIOC_G_CTRL, ctrl); | ||
453 | default: | ||
454 | return -EINVAL; | ||
455 | } | ||
456 | |||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | /* ----------------------------------------------------------------------- */ | ||
461 | |||
462 | static int get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | ||
463 | { | ||
464 | switch (fmt->type) { | ||
465 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
466 | return cx25840_vbi(client, VIDIOC_G_FMT, fmt); | ||
467 | default: | ||
468 | return -EINVAL; | ||
469 | } | ||
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | ||
475 | { | ||
476 | struct v4l2_pix_format *pix; | ||
477 | int HSC, VSC, Vsrc, Hsrc, filter, Vlines; | ||
478 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); | ||
479 | |||
480 | switch (fmt->type) { | ||
481 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
482 | pix = &(fmt->fmt.pix); | ||
483 | |||
484 | Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; | ||
485 | Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; | ||
486 | |||
487 | Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; | ||
488 | Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; | ||
489 | |||
490 | Vlines = pix->height + (is_pal ? 4 : 7); | ||
491 | |||
492 | if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || | ||
493 | (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { | ||
494 | cx25840_err("%dx%d is not a valid size!\n", | ||
495 | pix->width, pix->height); | ||
496 | return -ERANGE; | ||
497 | } | ||
498 | |||
499 | HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20); | ||
500 | VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); | ||
501 | VSC &= 0x1fff; | ||
502 | |||
503 | if (pix->width >= 385) | ||
504 | filter = 0; | ||
505 | else if (pix->width > 192) | ||
506 | filter = 1; | ||
507 | else if (pix->width > 96) | ||
508 | filter = 2; | ||
509 | else | ||
510 | filter = 3; | ||
511 | |||
512 | cx25840_dbg("decoder set size %dx%d -> scale %ux%u\n", | ||
513 | pix->width, pix->height, HSC, VSC); | ||
514 | |||
515 | /* HSCALE=HSC */ | ||
516 | cx25840_write(client, 0x418, HSC & 0xff); | ||
517 | cx25840_write(client, 0x419, (HSC >> 8) & 0xff); | ||
518 | cx25840_write(client, 0x41a, HSC >> 16); | ||
519 | /* VSCALE=VSC */ | ||
520 | cx25840_write(client, 0x41c, VSC & 0xff); | ||
521 | cx25840_write(client, 0x41d, VSC >> 8); | ||
522 | /* VS_INTRLACE=1 VFILT=filter */ | ||
523 | cx25840_write(client, 0x41e, 0x8 | filter); | ||
524 | break; | ||
525 | |||
526 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
527 | return cx25840_vbi(client, VIDIOC_S_FMT, fmt); | ||
528 | |||
529 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
530 | return cx25840_vbi(client, VIDIOC_S_FMT, fmt); | ||
531 | |||
532 | default: | ||
533 | return -EINVAL; | ||
534 | } | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | /* ----------------------------------------------------------------------- */ | ||
540 | |||
541 | static int cx25840_command(struct i2c_client *client, unsigned int cmd, | ||
542 | void *arg) | ||
543 | { | ||
544 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
545 | struct v4l2_tuner *vt = arg; | ||
546 | int result = 0; | ||
547 | |||
548 | switch (cmd) { | ||
549 | case 0: | ||
550 | break; | ||
551 | |||
552 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
553 | /* ioctls to allow direct access to the | ||
554 | * cx25840 registers for testing */ | ||
555 | case VIDIOC_INT_G_REGISTER: | ||
556 | { | ||
557 | struct v4l2_register *reg = arg; | ||
558 | |||
559 | if (reg->i2c_id != I2C_DRIVERID_CX25840) | ||
560 | return -EINVAL; | ||
561 | reg->val = cx25840_read(client, reg->reg & 0x0fff); | ||
562 | break; | ||
563 | } | ||
564 | |||
565 | case VIDIOC_INT_S_REGISTER: | ||
566 | { | ||
567 | struct v4l2_register *reg = arg; | ||
568 | |||
569 | if (reg->i2c_id != I2C_DRIVERID_CX25840) | ||
570 | return -EINVAL; | ||
571 | if (!capable(CAP_SYS_ADMIN)) | ||
572 | return -EPERM; | ||
573 | cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff); | ||
574 | break; | ||
575 | } | ||
576 | #endif | ||
577 | |||
578 | case VIDIOC_INT_DECODE_VBI_LINE: | ||
579 | return cx25840_vbi(client, cmd, arg); | ||
580 | |||
581 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | ||
582 | case AUDC_SET_INPUT: | ||
583 | result = cx25840_audio(client, cmd, arg); | ||
584 | break; | ||
585 | |||
586 | case VIDIOC_STREAMON: | ||
587 | cx25840_dbg("enable output\n"); | ||
588 | cx25840_write(client, 0x115, 0x8c); | ||
589 | cx25840_write(client, 0x116, 0x07); | ||
590 | break; | ||
591 | |||
592 | case VIDIOC_STREAMOFF: | ||
593 | cx25840_dbg("disable output\n"); | ||
594 | cx25840_write(client, 0x115, 0x00); | ||
595 | cx25840_write(client, 0x116, 0x00); | ||
596 | break; | ||
597 | |||
598 | case VIDIOC_LOG_STATUS: | ||
599 | log_status(client); | ||
600 | break; | ||
601 | |||
602 | case VIDIOC_G_CTRL: | ||
603 | result = get_v4lctrl(client, (struct v4l2_control *)arg); | ||
604 | break; | ||
605 | |||
606 | case VIDIOC_S_CTRL: | ||
607 | result = set_v4lctrl(client, (struct v4l2_control *)arg); | ||
608 | break; | ||
609 | |||
610 | case VIDIOC_G_STD: | ||
611 | *(v4l2_std_id *)arg = cx25840_get_v4lstd(client); | ||
612 | break; | ||
613 | |||
614 | case VIDIOC_S_STD: | ||
615 | result = set_v4lstd(client, *(v4l2_std_id *)arg); | ||
616 | break; | ||
617 | |||
618 | case VIDIOC_G_INPUT: | ||
619 | *(int *)arg = state->input; | ||
620 | break; | ||
621 | |||
622 | case VIDIOC_S_INPUT: | ||
623 | result = set_input(client, *(int *)arg); | ||
624 | break; | ||
625 | |||
626 | case VIDIOC_S_FREQUENCY: | ||
627 | input_change(client); | ||
628 | break; | ||
629 | |||
630 | case VIDIOC_G_TUNER: | ||
631 | { | ||
632 | u8 mode = cx25840_read(client, 0x804); | ||
633 | u8 pref = cx25840_read(client, 0x809) & 0xf; | ||
634 | u8 vpres = cx25840_read(client, 0x80a) & 0x10; | ||
635 | int val = 0; | ||
636 | |||
637 | vt->capability |= | ||
638 | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | | ||
639 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; | ||
640 | |||
641 | vt->signal = vpres ? 0xffff : 0x0; | ||
642 | |||
643 | /* get rxsubchans and audmode */ | ||
644 | if ((mode & 0xf) == 1) | ||
645 | val |= V4L2_TUNER_SUB_STEREO; | ||
646 | else | ||
647 | val |= V4L2_TUNER_SUB_MONO; | ||
648 | |||
649 | if (mode == 2 || mode == 4) | ||
650 | val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | ||
651 | |||
652 | if (mode & 0x10) | ||
653 | val |= V4L2_TUNER_SUB_SAP; | ||
654 | |||
655 | vt->rxsubchans = val; | ||
656 | |||
657 | switch (pref) { | ||
658 | case 0: | ||
659 | vt->audmode = V4L2_TUNER_MODE_MONO; | ||
660 | break; | ||
661 | case 1: | ||
662 | case 2: | ||
663 | vt->audmode = V4L2_TUNER_MODE_LANG2; | ||
664 | break; | ||
665 | case 4: | ||
666 | default: | ||
667 | vt->audmode = V4L2_TUNER_MODE_STEREO; | ||
668 | } | ||
669 | break; | ||
670 | } | ||
671 | |||
672 | case VIDIOC_S_TUNER: | ||
673 | switch (vt->audmode) { | ||
674 | case V4L2_TUNER_MODE_MONO: | ||
675 | case V4L2_TUNER_MODE_LANG1: | ||
676 | /* Force PREF_MODE to MONO */ | ||
677 | cx25840_and_or(client, 0x809, ~0xf, 0x00); | ||
678 | break; | ||
679 | case V4L2_TUNER_MODE_STEREO: | ||
680 | /* Force PREF_MODE to STEREO */ | ||
681 | cx25840_and_or(client, 0x809, ~0xf, 0x04); | ||
682 | break; | ||
683 | case V4L2_TUNER_MODE_LANG2: | ||
684 | /* Force PREF_MODE to LANG2 */ | ||
685 | cx25840_and_or(client, 0x809, ~0xf, 0x01); | ||
686 | break; | ||
687 | } | ||
688 | break; | ||
689 | |||
690 | case VIDIOC_G_FMT: | ||
691 | result = get_v4lfmt(client, (struct v4l2_format *)arg); | ||
692 | break; | ||
693 | |||
694 | case VIDIOC_S_FMT: | ||
695 | result = set_v4lfmt(client, (struct v4l2_format *)arg); | ||
696 | break; | ||
697 | |||
698 | case VIDIOC_INT_RESET: | ||
699 | cx25840_initialize(client, 0); | ||
700 | break; | ||
701 | |||
702 | case VIDIOC_INT_G_CHIP_IDENT: | ||
703 | *(enum v4l2_chip_ident *)arg = | ||
704 | V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf); | ||
705 | break; | ||
706 | |||
707 | default: | ||
708 | cx25840_err("invalid ioctl %x\n", cmd); | ||
709 | return -EINVAL; | ||
710 | } | ||
711 | |||
712 | return result; | ||
713 | } | ||
714 | |||
715 | /* ----------------------------------------------------------------------- */ | ||
716 | |||
717 | struct i2c_driver i2c_driver_cx25840; | ||
718 | |||
719 | static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | ||
720 | int kind) | ||
721 | { | ||
722 | struct i2c_client *client; | ||
723 | struct cx25840_state *state; | ||
724 | u16 device_id; | ||
725 | |||
726 | /* Check if the adapter supports the needed features | ||
727 | * Not until kernel version 2.6.11 did the bit-algo | ||
728 | * correctly report that it would do an I2C-level xfer */ | ||
729 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) | ||
730 | return 0; | ||
731 | |||
732 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
733 | if (client == 0) | ||
734 | return -ENOMEM; | ||
735 | |||
736 | memset(client, 0, sizeof(struct i2c_client)); | ||
737 | client->addr = address; | ||
738 | client->adapter = adapter; | ||
739 | client->driver = &i2c_driver_cx25840; | ||
740 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
741 | snprintf(client->name, sizeof(client->name) - 1, "cx25840"); | ||
742 | |||
743 | cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1); | ||
744 | |||
745 | device_id = cx25840_read(client, 0x101) << 8; | ||
746 | device_id |= cx25840_read(client, 0x100); | ||
747 | |||
748 | /* The high byte of the device ID should be | ||
749 | * 0x84 if chip is present */ | ||
750 | if ((device_id & 0xff00) != 0x8400) { | ||
751 | cx25840_dbg("cx25840 not found\n"); | ||
752 | kfree(client); | ||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | cx25840_info("cx25%3x-2%x found @ 0x%x (%s)\n", | ||
757 | (device_id & 0xfff0) >> 4, | ||
758 | (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, | ||
759 | address << 1, adapter->name); | ||
760 | |||
761 | state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL); | ||
762 | if (state == NULL) { | ||
763 | kfree(client); | ||
764 | return -ENOMEM; | ||
765 | } | ||
766 | |||
767 | i2c_set_clientdata(client, state); | ||
768 | memset(state, 0, sizeof(struct cx25840_state)); | ||
769 | state->input = CX25840_TUNER; | ||
770 | state->audclk_freq = V4L2_AUDCLK_48_KHZ; | ||
771 | state->audio_input = AUDIO_TUNER; | ||
772 | state->cardtype = CARDTYPE_PVR150; | ||
773 | |||
774 | cx25840_initialize(client, 1); | ||
775 | |||
776 | i2c_attach_client(client); | ||
777 | |||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | static int cx25840_attach_adapter(struct i2c_adapter *adapter) | ||
782 | { | ||
783 | #ifdef I2C_CLASS_TV_ANALOG | ||
784 | if (adapter->class & I2C_CLASS_TV_ANALOG) | ||
785 | #else | ||
786 | if (adapter->id == I2C_HW_B_BT848) | ||
787 | #endif | ||
788 | return i2c_probe(adapter, &addr_data, &cx25840_detect_client); | ||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | static int cx25840_detach_client(struct i2c_client *client) | ||
793 | { | ||
794 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
795 | int err; | ||
796 | |||
797 | err = i2c_detach_client(client); | ||
798 | if (err) { | ||
799 | return err; | ||
800 | } | ||
801 | |||
802 | kfree(state); | ||
803 | kfree(client); | ||
804 | |||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | /* ----------------------------------------------------------------------- */ | ||
809 | |||
810 | struct i2c_driver i2c_driver_cx25840 = { | ||
811 | .name = "cx25840", | ||
812 | |||
813 | .id = I2C_DRIVERID_CX25840, | ||
814 | .flags = I2C_DF_NOTIFY, | ||
815 | |||
816 | .attach_adapter = cx25840_attach_adapter, | ||
817 | .detach_client = cx25840_detach_client, | ||
818 | .command = cx25840_command, | ||
819 | .owner = THIS_MODULE, | ||
820 | }; | ||
821 | |||
822 | |||
823 | static int __init m__init(void) | ||
824 | { | ||
825 | return i2c_add_driver(&i2c_driver_cx25840); | ||
826 | } | ||
827 | |||
828 | static void __exit m__exit(void) | ||
829 | { | ||
830 | i2c_del_driver(&i2c_driver_cx25840); | ||
831 | } | ||
832 | |||
833 | module_init(m__init); | ||
834 | module_exit(m__exit); | ||
835 | |||
836 | /* ----------------------------------------------------------------------- */ | ||
837 | |||
838 | static void log_status(struct i2c_client *client) | ||
839 | { | ||
840 | static const char *const fmt_strs[] = { | ||
841 | "0x0", | ||
842 | "NTSC-M", "NTSC-J", "NTSC-4.43", | ||
843 | "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60", | ||
844 | "0x9", "0xA", "0xB", | ||
845 | "SECAM", | ||
846 | "0xD", "0xE", "0xF" | ||
847 | }; | ||
848 | |||
849 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
850 | u8 microctrl_vidfmt = cx25840_read(client, 0x80a); | ||
851 | u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf; | ||
852 | u8 gen_stat1 = cx25840_read(client, 0x40d); | ||
853 | u8 download_ctl = cx25840_read(client, 0x803); | ||
854 | u8 mod_det_stat0 = cx25840_read(client, 0x804); | ||
855 | u8 mod_det_stat1 = cx25840_read(client, 0x805); | ||
856 | u8 audio_config = cx25840_read(client, 0x808); | ||
857 | u8 pref_mode = cx25840_read(client, 0x809); | ||
858 | u8 afc0 = cx25840_read(client, 0x80b); | ||
859 | u8 mute_ctl = cx25840_read(client, 0x8d3); | ||
860 | char *p; | ||
861 | |||
862 | cx25840_info("Video signal: %spresent\n", | ||
863 | (microctrl_vidfmt & 0x10) ? "" : "not "); | ||
864 | cx25840_info("Detected format: %s\n", | ||
865 | fmt_strs[gen_stat1 & 0xf]); | ||
866 | |||
867 | switch (mod_det_stat0) { | ||
868 | case 0x00: p = "mono"; break; | ||
869 | case 0x01: p = "stereo"; break; | ||
870 | case 0x02: p = "dual"; break; | ||
871 | case 0x04: p = "tri"; break; | ||
872 | case 0x10: p = "mono with SAP"; break; | ||
873 | case 0x11: p = "stereo with SAP"; break; | ||
874 | case 0x12: p = "dual with SAP"; break; | ||
875 | case 0x14: p = "tri with SAP"; break; | ||
876 | case 0xfe: p = "forced mode"; break; | ||
877 | default: p = "not defined"; | ||
878 | } | ||
879 | cx25840_info("Detected audio mode: %s\n", p); | ||
880 | |||
881 | switch (mod_det_stat1) { | ||
882 | case 0x00: p = "not defined"; break; | ||
883 | case 0x01: p = "EIAJ"; break; | ||
884 | case 0x02: p = "A2-M"; break; | ||
885 | case 0x03: p = "A2-BG"; break; | ||
886 | case 0x04: p = "A2-DK1"; break; | ||
887 | case 0x05: p = "A2-DK2"; break; | ||
888 | case 0x06: p = "A2-DK3"; break; | ||
889 | case 0x07: p = "A1 (6.0 MHz FM Mono)"; break; | ||
890 | case 0x08: p = "AM-L"; break; | ||
891 | case 0x09: p = "NICAM-BG"; break; | ||
892 | case 0x0a: p = "NICAM-DK"; break; | ||
893 | case 0x0b: p = "NICAM-I"; break; | ||
894 | case 0x0c: p = "NICAM-L"; break; | ||
895 | case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break; | ||
896 | case 0x0e: p = "IF FM Radio"; break; | ||
897 | case 0x0f: p = "BTSC"; break; | ||
898 | case 0x10: p = "high-deviation FM"; break; | ||
899 | case 0x11: p = "very high-deviation FM"; break; | ||
900 | case 0xfd: p = "unknown audio standard"; break; | ||
901 | case 0xfe: p = "forced audio standard"; break; | ||
902 | case 0xff: p = "no detected audio standard"; break; | ||
903 | default: p = "not defined"; | ||
904 | } | ||
905 | cx25840_info("Detected audio standard: %s\n", p); | ||
906 | cx25840_info("Audio muted: %s\n", | ||
907 | (mute_ctl & 0x2) ? "yes" : "no"); | ||
908 | cx25840_info("Audio microcontroller: %s\n", | ||
909 | (download_ctl & 0x10) ? "running" : "stopped"); | ||
910 | |||
911 | switch (audio_config >> 4) { | ||
912 | case 0x00: p = "undefined"; break; | ||
913 | case 0x01: p = "BTSC"; break; | ||
914 | case 0x02: p = "EIAJ"; break; | ||
915 | case 0x03: p = "A2-M"; break; | ||
916 | case 0x04: p = "A2-BG"; break; | ||
917 | case 0x05: p = "A2-DK1"; break; | ||
918 | case 0x06: p = "A2-DK2"; break; | ||
919 | case 0x07: p = "A2-DK3"; break; | ||
920 | case 0x08: p = "A1 (6.0 MHz FM Mono)"; break; | ||
921 | case 0x09: p = "AM-L"; break; | ||
922 | case 0x0a: p = "NICAM-BG"; break; | ||
923 | case 0x0b: p = "NICAM-DK"; break; | ||
924 | case 0x0c: p = "NICAM-I"; break; | ||
925 | case 0x0d: p = "NICAM-L"; break; | ||
926 | case 0x0e: p = "FM radio"; break; | ||
927 | case 0x0f: p = "automatic detection"; break; | ||
928 | default: p = "undefined"; | ||
929 | } | ||
930 | cx25840_info("Configured audio standard: %s\n", p); | ||
931 | |||
932 | if ((audio_config >> 4) < 0xF) { | ||
933 | switch (audio_config & 0xF) { | ||
934 | case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break; | ||
935 | case 0x01: p = "MONO2 (LANGUAGE B)"; break; | ||
936 | case 0x02: p = "MONO3 (STEREO forced MONO)"; break; | ||
937 | case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break; | ||
938 | case 0x04: p = "STEREO"; break; | ||
939 | case 0x05: p = "DUAL1 (AB)"; break; | ||
940 | case 0x06: p = "DUAL2 (AC) (FM)"; break; | ||
941 | case 0x07: p = "DUAL3 (BC) (FM)"; break; | ||
942 | case 0x08: p = "DUAL4 (AC) (AM)"; break; | ||
943 | case 0x09: p = "DUAL5 (BC) (AM)"; break; | ||
944 | case 0x0a: p = "SAP"; break; | ||
945 | default: p = "undefined"; | ||
946 | } | ||
947 | cx25840_info("Configured audio mode: %s\n", p); | ||
948 | } else { | ||
949 | switch (audio_config & 0xF) { | ||
950 | case 0x00: p = "BG"; break; | ||
951 | case 0x01: p = "DK1"; break; | ||
952 | case 0x02: p = "DK2"; break; | ||
953 | case 0x03: p = "DK3"; break; | ||
954 | case 0x04: p = "I"; break; | ||
955 | case 0x05: p = "L"; break; | ||
956 | case 0x06: p = "BTSC"; break; | ||
957 | case 0x07: p = "EIAJ"; break; | ||
958 | case 0x08: p = "A2-M"; break; | ||
959 | case 0x09: p = "FM Radio"; break; | ||
960 | case 0x0f: p = "automatic standard and mode detection"; break; | ||
961 | default: p = "undefined"; | ||
962 | } | ||
963 | cx25840_info("Configured audio system: %s\n", p); | ||
964 | } | ||
965 | |||
966 | cx25840_info("Specified standard: %s\n", | ||
967 | vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); | ||
968 | |||
969 | switch (state->input) { | ||
970 | case CX25840_COMPOSITE0: p = "Composite 0"; break; | ||
971 | case CX25840_COMPOSITE1: p = "Composite 1"; break; | ||
972 | case CX25840_SVIDEO0: p = "S-Video 0"; break; | ||
973 | case CX25840_SVIDEO1: p = "S-Video 1"; break; | ||
974 | case CX25840_TUNER: p = "Tuner"; break; | ||
975 | } | ||
976 | cx25840_info("Specified input: %s\n", p); | ||
977 | cx25840_info("Specified audio input: %s\n", | ||
978 | state->audio_input == 0 ? "Tuner" : "External"); | ||
979 | |||
980 | switch (state->audclk_freq) { | ||
981 | case V4L2_AUDCLK_441_KHZ: p = "44.1 kHz"; break; | ||
982 | case V4L2_AUDCLK_48_KHZ: p = "48 kHz"; break; | ||
983 | case V4L2_AUDCLK_32_KHZ: p = "32 kHz"; break; | ||
984 | default: p = "undefined"; | ||
985 | } | ||
986 | cx25840_info("Specified audioclock freq: %s\n", p); | ||
987 | |||
988 | switch (pref_mode & 0xf) { | ||
989 | case 0: p = "mono/language A"; break; | ||
990 | case 1: p = "language B"; break; | ||
991 | case 2: p = "language C"; break; | ||
992 | case 3: p = "analog fallback"; break; | ||
993 | case 4: p = "stereo"; break; | ||
994 | case 5: p = "language AC"; break; | ||
995 | case 6: p = "language BC"; break; | ||
996 | case 7: p = "language AB"; break; | ||
997 | default: p = "undefined"; | ||
998 | } | ||
999 | cx25840_info("Preferred audio mode: %s\n", p); | ||
1000 | |||
1001 | if ((audio_config & 0xf) == 0xf) { | ||
1002 | switch ((afc0 >> 3) & 0x3) { | ||
1003 | case 0: p = "system DK"; break; | ||
1004 | case 1: p = "system L"; break; | ||
1005 | case 2: p = "autodetect"; break; | ||
1006 | default: p = "undefined"; | ||
1007 | } | ||
1008 | cx25840_info("Selected 65 MHz format: %s\n", p); | ||
1009 | |||
1010 | switch (afc0 & 0x7) { | ||
1011 | case 0: p = "chroma"; break; | ||
1012 | case 1: p = "BTSC"; break; | ||
1013 | case 2: p = "EIAJ"; break; | ||
1014 | case 3: p = "A2-M"; break; | ||
1015 | case 4: p = "autodetect"; break; | ||
1016 | default: p = "undefined"; | ||
1017 | } | ||
1018 | cx25840_info("Selected 45 MHz format: %s\n", p); | ||
1019 | } | ||
1020 | } | ||
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c new file mode 100644 index 000000000000..df9d50a75542 --- /dev/null +++ b/drivers/media/video/cx25840/cx25840-firmware.c | |||
@@ -0,0 +1,167 @@ | |||
1 | /* cx25840 firmware functions | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or | ||
4 | * modify it under the terms of the GNU General Public License | ||
5 | * as published by the Free Software Foundation; either version 2 | ||
6 | * of the License, or (at your option) any later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
16 | */ | ||
17 | |||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/i2c-algo-bit.h> | ||
22 | #include <linux/firmware.h> | ||
23 | #include <media/v4l2-common.h> | ||
24 | |||
25 | #include "cx25840.h" | ||
26 | |||
27 | #define FWFILE "v4l-cx25840.fw" | ||
28 | #define FWSEND 1024 | ||
29 | |||
30 | #define FWDEV(x) &((x)->adapter->dev) | ||
31 | |||
32 | static int fastfw = 1; | ||
33 | static char *firmware = FWFILE; | ||
34 | |||
35 | module_param(fastfw, bool, 0444); | ||
36 | module_param(firmware, charp, 0444); | ||
37 | |||
38 | MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]"); | ||
39 | MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); | ||
40 | |||
41 | static inline void set_i2c_delay(struct i2c_client *client, int delay) | ||
42 | { | ||
43 | struct i2c_algo_bit_data *algod = client->adapter->algo_data; | ||
44 | |||
45 | /* We aren't guaranteed to be using algo_bit, | ||
46 | * so avoid the null pointer dereference | ||
47 | * and disable the 'fast firmware load' */ | ||
48 | if (algod) { | ||
49 | algod->udelay = delay; | ||
50 | } else { | ||
51 | fastfw = 0; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | static inline void start_fw_load(struct i2c_client *client) | ||
56 | { | ||
57 | /* DL_ADDR_LB=0 DL_ADDR_HB=0 */ | ||
58 | cx25840_write(client, 0x800, 0x00); | ||
59 | cx25840_write(client, 0x801, 0x00); | ||
60 | // DL_MAP=3 DL_AUTO_INC=0 DL_ENABLE=1 | ||
61 | cx25840_write(client, 0x803, 0x0b); | ||
62 | /* AUTO_INC_DIS=1 */ | ||
63 | cx25840_write(client, 0x000, 0x20); | ||
64 | |||
65 | if (fastfw) | ||
66 | set_i2c_delay(client, 3); | ||
67 | } | ||
68 | |||
69 | static inline void end_fw_load(struct i2c_client *client) | ||
70 | { | ||
71 | if (fastfw) | ||
72 | set_i2c_delay(client, 10); | ||
73 | |||
74 | /* AUTO_INC_DIS=0 */ | ||
75 | cx25840_write(client, 0x000, 0x00); | ||
76 | /* DL_ENABLE=0 */ | ||
77 | cx25840_write(client, 0x803, 0x03); | ||
78 | } | ||
79 | |||
80 | static inline int check_fw_load(struct i2c_client *client, int size) | ||
81 | { | ||
82 | /* DL_ADDR_HB DL_ADDR_LB */ | ||
83 | int s = cx25840_read(client, 0x801) << 8; | ||
84 | s |= cx25840_read(client, 0x800); | ||
85 | |||
86 | if (size != s) { | ||
87 | cx25840_err("firmware %s load failed\n", firmware); | ||
88 | return -EINVAL; | ||
89 | } | ||
90 | |||
91 | cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static inline int fw_write(struct i2c_client *client, u8 * data, int size) | ||
96 | { | ||
97 | if (i2c_master_send(client, data, size) < size) { | ||
98 | |||
99 | if (fastfw) { | ||
100 | cx25840_err("333MHz i2c firmware load failed\n"); | ||
101 | fastfw = 0; | ||
102 | set_i2c_delay(client, 10); | ||
103 | |||
104 | if (i2c_master_send(client, data, size) < size) { | ||
105 | cx25840_err | ||
106 | ("100MHz i2c firmware load failed\n"); | ||
107 | return -ENOSYS; | ||
108 | } | ||
109 | |||
110 | } else { | ||
111 | cx25840_err("firmware load i2c failure\n"); | ||
112 | return -ENOSYS; | ||
113 | } | ||
114 | |||
115 | } | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | int cx25840_loadfw(struct i2c_client *client) | ||
121 | { | ||
122 | const struct firmware *fw = NULL; | ||
123 | u8 buffer[4], *ptr; | ||
124 | int size, send, retval; | ||
125 | |||
126 | if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { | ||
127 | cx25840_err("unable to open firmware %s\n", firmware); | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | |||
131 | start_fw_load(client); | ||
132 | |||
133 | buffer[0] = 0x08; | ||
134 | buffer[1] = 0x02; | ||
135 | buffer[2] = fw->data[0]; | ||
136 | buffer[3] = fw->data[1]; | ||
137 | retval = fw_write(client, buffer, 4); | ||
138 | |||
139 | if (retval < 0) { | ||
140 | release_firmware(fw); | ||
141 | return retval; | ||
142 | } | ||
143 | |||
144 | size = fw->size - 2; | ||
145 | ptr = fw->data; | ||
146 | while (size > 0) { | ||
147 | ptr[0] = 0x08; | ||
148 | ptr[1] = 0x02; | ||
149 | send = size > (FWSEND - 2) ? FWSEND : size + 2; | ||
150 | retval = fw_write(client, ptr, send); | ||
151 | |||
152 | if (retval < 0) { | ||
153 | release_firmware(fw); | ||
154 | return retval; | ||
155 | } | ||
156 | |||
157 | size -= FWSEND - 2; | ||
158 | ptr += FWSEND - 2; | ||
159 | } | ||
160 | |||
161 | end_fw_load(client); | ||
162 | |||
163 | size = fw->size; | ||
164 | release_firmware(fw); | ||
165 | |||
166 | return check_fw_load(client, size); | ||
167 | } | ||
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c new file mode 100644 index 000000000000..13ba4e15ddea --- /dev/null +++ b/drivers/media/video/cx25840/cx25840-vbi.c | |||
@@ -0,0 +1,315 @@ | |||
1 | /* cx25840 VBI functions | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or | ||
4 | * modify it under the terms of the GNU General Public License | ||
5 | * as published by the Free Software Foundation; either version 2 | ||
6 | * of the License, or (at your option) any later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
16 | */ | ||
17 | |||
18 | |||
19 | #include <linux/videodev2.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <media/v4l2-common.h> | ||
22 | |||
23 | #include "cx25840.h" | ||
24 | |||
25 | static inline int odd_parity(u8 c) | ||
26 | { | ||
27 | c ^= (c >> 4); | ||
28 | c ^= (c >> 2); | ||
29 | c ^= (c >> 1); | ||
30 | |||
31 | return c & 1; | ||
32 | } | ||
33 | |||
34 | static inline int decode_vps(u8 * dst, u8 * p) | ||
35 | { | ||
36 | static const u8 biphase_tbl[] = { | ||
37 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, | ||
38 | 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, | ||
39 | 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96, | ||
40 | 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2, | ||
41 | 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94, | ||
42 | 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0, | ||
43 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, | ||
44 | 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, | ||
45 | 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5, | ||
46 | 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1, | ||
47 | 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87, | ||
48 | 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3, | ||
49 | 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85, | ||
50 | 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1, | ||
51 | 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5, | ||
52 | 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1, | ||
53 | 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4, | ||
54 | 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0, | ||
55 | 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86, | ||
56 | 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2, | ||
57 | 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84, | ||
58 | 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0, | ||
59 | 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4, | ||
60 | 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0, | ||
61 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, | ||
62 | 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, | ||
63 | 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96, | ||
64 | 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2, | ||
65 | 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94, | ||
66 | 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0, | ||
67 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, | ||
68 | 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, | ||
69 | }; | ||
70 | |||
71 | u8 c, err = 0; | ||
72 | int i; | ||
73 | |||
74 | for (i = 0; i < 2 * 13; i += 2) { | ||
75 | err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]]; | ||
76 | c = (biphase_tbl[p[i + 1]] & 0xf) | | ||
77 | ((biphase_tbl[p[i]] & 0xf) << 4); | ||
78 | dst[i / 2] = c; | ||
79 | } | ||
80 | |||
81 | return err & 0xf0; | ||
82 | } | ||
83 | |||
84 | void cx25840_vbi_setup(struct i2c_client *client) | ||
85 | { | ||
86 | v4l2_std_id std = cx25840_get_v4lstd(client); | ||
87 | |||
88 | if (std & ~V4L2_STD_NTSC) { | ||
89 | /* datasheet startup, step 8d */ | ||
90 | cx25840_write(client, 0x49f, 0x11); | ||
91 | |||
92 | cx25840_write(client, 0x470, 0x84); | ||
93 | cx25840_write(client, 0x471, 0x00); | ||
94 | cx25840_write(client, 0x472, 0x2d); | ||
95 | cx25840_write(client, 0x473, 0x5d); | ||
96 | |||
97 | cx25840_write(client, 0x474, 0x24); | ||
98 | cx25840_write(client, 0x475, 0x40); | ||
99 | cx25840_write(client, 0x476, 0x24); | ||
100 | cx25840_write(client, 0x477, 0x28); | ||
101 | |||
102 | cx25840_write(client, 0x478, 0x1f); | ||
103 | cx25840_write(client, 0x479, 0x02); | ||
104 | |||
105 | if (std & V4L2_STD_SECAM) { | ||
106 | cx25840_write(client, 0x47a, 0x80); | ||
107 | cx25840_write(client, 0x47b, 0x00); | ||
108 | cx25840_write(client, 0x47c, 0x5f); | ||
109 | cx25840_write(client, 0x47d, 0x42); | ||
110 | } else { | ||
111 | cx25840_write(client, 0x47a, 0x90); | ||
112 | cx25840_write(client, 0x47b, 0x20); | ||
113 | cx25840_write(client, 0x47c, 0x63); | ||
114 | cx25840_write(client, 0x47d, 0x82); | ||
115 | } | ||
116 | |||
117 | cx25840_write(client, 0x47e, 0x0a); | ||
118 | cx25840_write(client, 0x47f, 0x01); | ||
119 | } else { | ||
120 | /* datasheet startup, step 8d */ | ||
121 | cx25840_write(client, 0x49f, 0x14); | ||
122 | |||
123 | cx25840_write(client, 0x470, 0x7a); | ||
124 | cx25840_write(client, 0x471, 0x00); | ||
125 | cx25840_write(client, 0x472, 0x2d); | ||
126 | cx25840_write(client, 0x473, 0x5b); | ||
127 | |||
128 | cx25840_write(client, 0x474, 0x1a); | ||
129 | cx25840_write(client, 0x475, 0x70); | ||
130 | cx25840_write(client, 0x476, 0x1e); | ||
131 | cx25840_write(client, 0x477, 0x1e); | ||
132 | |||
133 | cx25840_write(client, 0x478, 0x1f); | ||
134 | cx25840_write(client, 0x479, 0x02); | ||
135 | cx25840_write(client, 0x47a, 0x50); | ||
136 | cx25840_write(client, 0x47b, 0x66); | ||
137 | |||
138 | cx25840_write(client, 0x47c, 0x1f); | ||
139 | cx25840_write(client, 0x47d, 0x7c); | ||
140 | cx25840_write(client, 0x47e, 0x08); | ||
141 | cx25840_write(client, 0x47f, 0x00); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | ||
146 | { | ||
147 | struct v4l2_format *fmt; | ||
148 | struct v4l2_sliced_vbi_format *svbi; | ||
149 | |||
150 | switch (cmd) { | ||
151 | case VIDIOC_G_FMT: | ||
152 | { | ||
153 | static u16 lcr2vbi[] = { | ||
154 | 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ | ||
155 | 0, V4L2_SLICED_WSS_625, 0, /* 4 */ | ||
156 | V4L2_SLICED_CAPTION_525, /* 6 */ | ||
157 | 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ | ||
158 | 0, 0, 0, 0 | ||
159 | }; | ||
160 | int i; | ||
161 | |||
162 | fmt = arg; | ||
163 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | ||
164 | return -EINVAL; | ||
165 | svbi = &fmt->fmt.sliced; | ||
166 | memset(svbi, 0, sizeof(*svbi)); | ||
167 | /* we're done if raw VBI is active */ | ||
168 | if ((cx25840_read(client, 0x404) & 0x10) == 0) | ||
169 | break; | ||
170 | |||
171 | for (i = 7; i <= 23; i++) { | ||
172 | u8 v = cx25840_read(client, 0x424 + i - 7); | ||
173 | |||
174 | svbi->service_lines[0][i] = lcr2vbi[v >> 4]; | ||
175 | svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; | ||
176 | svbi->service_set |= | ||
177 | svbi->service_lines[0][i] | svbi->service_lines[1][i]; | ||
178 | } | ||
179 | break; | ||
180 | } | ||
181 | |||
182 | case VIDIOC_S_FMT: | ||
183 | { | ||
184 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); | ||
185 | int vbi_offset = is_pal ? 1 : 0; | ||
186 | int i, x; | ||
187 | u8 lcr[24]; | ||
188 | |||
189 | fmt = arg; | ||
190 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | ||
191 | return -EINVAL; | ||
192 | svbi = &fmt->fmt.sliced; | ||
193 | if (svbi->service_set == 0) { | ||
194 | /* raw VBI */ | ||
195 | memset(svbi, 0, sizeof(*svbi)); | ||
196 | |||
197 | /* Setup VBI */ | ||
198 | cx25840_vbi_setup(client); | ||
199 | |||
200 | /* VBI Offset */ | ||
201 | cx25840_write(client, 0x47f, vbi_offset); | ||
202 | cx25840_write(client, 0x404, 0x2e); | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | for (x = 0; x <= 23; x++) | ||
207 | lcr[x] = 0x00; | ||
208 | |||
209 | /* Setup VBI */ | ||
210 | cx25840_vbi_setup(client); | ||
211 | |||
212 | /* Sliced VBI */ | ||
213 | cx25840_write(client, 0x404, 0x36); /* Ancillery data */ | ||
214 | cx25840_write(client, 0x406, 0x13); | ||
215 | cx25840_write(client, 0x47f, vbi_offset); | ||
216 | |||
217 | if (is_pal) { | ||
218 | for (i = 0; i <= 6; i++) | ||
219 | svbi->service_lines[0][i] = | ||
220 | svbi->service_lines[1][i] = 0; | ||
221 | } else { | ||
222 | for (i = 0; i <= 9; i++) | ||
223 | svbi->service_lines[0][i] = | ||
224 | svbi->service_lines[1][i] = 0; | ||
225 | |||
226 | for (i = 22; i <= 23; i++) | ||
227 | svbi->service_lines[0][i] = | ||
228 | svbi->service_lines[1][i] = 0; | ||
229 | } | ||
230 | |||
231 | for (i = 7; i <= 23; i++) { | ||
232 | for (x = 0; x <= 1; x++) { | ||
233 | switch (svbi->service_lines[1-x][i]) { | ||
234 | case V4L2_SLICED_TELETEXT_B: | ||
235 | lcr[i] |= 1 << (4 * x); | ||
236 | break; | ||
237 | case V4L2_SLICED_WSS_625: | ||
238 | lcr[i] |= 4 << (4 * x); | ||
239 | break; | ||
240 | case V4L2_SLICED_CAPTION_525: | ||
241 | lcr[i] |= 6 << (4 * x); | ||
242 | break; | ||
243 | case V4L2_SLICED_VPS: | ||
244 | lcr[i] |= 9 << (4 * x); | ||
245 | break; | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | |||
250 | for (x = 1, i = 0x424; i <= 0x434; i++, x++) { | ||
251 | cx25840_write(client, i, lcr[6 + x]); | ||
252 | } | ||
253 | |||
254 | cx25840_write(client, 0x43c, 0x16); | ||
255 | |||
256 | if (is_pal) { | ||
257 | cx25840_write(client, 0x474, 0x2a); | ||
258 | } else { | ||
259 | cx25840_write(client, 0x474, 0x1a + 6); | ||
260 | } | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | case VIDIOC_INT_DECODE_VBI_LINE: | ||
265 | { | ||
266 | struct v4l2_decode_vbi_line *vbi = arg; | ||
267 | u8 *p = vbi->p; | ||
268 | int id1, id2, l, err = 0; | ||
269 | |||
270 | if (p[0] || p[1] != 0xff || p[2] != 0xff || | ||
271 | (p[3] != 0x55 && p[3] != 0x91)) { | ||
272 | vbi->line = vbi->type = 0; | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | p += 4; | ||
277 | id1 = p[-1]; | ||
278 | id2 = p[0] & 0xf; | ||
279 | l = p[2] & 0x3f; | ||
280 | l += 5; | ||
281 | p += 4; | ||
282 | |||
283 | switch (id2) { | ||
284 | case 1: | ||
285 | id2 = V4L2_SLICED_TELETEXT_B; | ||
286 | break; | ||
287 | case 4: | ||
288 | id2 = V4L2_SLICED_WSS_625; | ||
289 | break; | ||
290 | case 6: | ||
291 | id2 = V4L2_SLICED_CAPTION_525; | ||
292 | err = !odd_parity(p[0]) || !odd_parity(p[1]); | ||
293 | break; | ||
294 | case 9: | ||
295 | id2 = V4L2_SLICED_VPS; | ||
296 | if (decode_vps(p, p) != 0) { | ||
297 | err = 1; | ||
298 | } | ||
299 | break; | ||
300 | default: | ||
301 | id2 = 0; | ||
302 | err = 1; | ||
303 | break; | ||
304 | } | ||
305 | |||
306 | vbi->type = err ? 0 : id2; | ||
307 | vbi->line = err ? 0 : l; | ||
308 | vbi->is_second_field = err ? 0 : (id1 == 0x55); | ||
309 | vbi->p = p; | ||
310 | break; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | return 0; | ||
315 | } | ||
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h new file mode 100644 index 000000000000..5c3f0639fb77 --- /dev/null +++ b/drivers/media/video/cx25840/cx25840.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /* cx25840 API header | ||
2 | * | ||
3 | * Copyright (C) 2003-2004 Chris Kennedy | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef _CX25840_H_ | ||
21 | #define _CX25840_H_ | ||
22 | |||
23 | |||
24 | #include <linux/videodev2.h> | ||
25 | #include <linux/i2c.h> | ||
26 | |||
27 | extern int cx25840_debug; | ||
28 | |||
29 | #define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \ | ||
30 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
31 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
32 | |||
33 | #define cx25840_err(fmt, arg...) do { \ | ||
34 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | ||
35 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
36 | |||
37 | #define cx25840_info(fmt, arg...) do { \ | ||
38 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | ||
39 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
40 | |||
41 | #define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) | ||
42 | |||
43 | enum cx25840_cardtype { | ||
44 | CARDTYPE_PVR150, | ||
45 | CARDTYPE_PG600 | ||
46 | }; | ||
47 | |||
48 | enum cx25840_input { | ||
49 | CX25840_TUNER, | ||
50 | CX25840_COMPOSITE0, | ||
51 | CX25840_COMPOSITE1, | ||
52 | CX25840_SVIDEO0, | ||
53 | CX25840_SVIDEO1 | ||
54 | }; | ||
55 | |||
56 | struct cx25840_state { | ||
57 | enum cx25840_cardtype cardtype; | ||
58 | enum cx25840_input input; | ||
59 | int audio_input; | ||
60 | enum v4l2_audio_clock_freq audclk_freq; | ||
61 | }; | ||
62 | |||
63 | /* ----------------------------------------------------------------------- */ | ||
64 | /* cx25850-core.c */ | ||
65 | int cx25840_write(struct i2c_client *client, u16 addr, u8 value); | ||
66 | int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); | ||
67 | u8 cx25840_read(struct i2c_client *client, u16 addr); | ||
68 | u32 cx25840_read4(struct i2c_client *client, u16 addr); | ||
69 | int cx25840_and_or(struct i2c_client *client, u16 addr, u8 mask, u8 value); | ||
70 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client); | ||
71 | |||
72 | /* ----------------------------------------------------------------------- */ | ||
73 | /* cx25850-firmware.c */ | ||
74 | int cx25840_loadfw(struct i2c_client *client); | ||
75 | |||
76 | /* ----------------------------------------------------------------------- */ | ||
77 | /* cx25850-audio.c */ | ||
78 | int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); | ||
79 | |||
80 | /* ----------------------------------------------------------------------- */ | ||
81 | /* cx25850-vbi.c */ | ||
82 | void cx25840_vbi_setup(struct i2c_client *client); | ||
83 | int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg); | ||
84 | |||
85 | #endif | ||
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 9cce91ec334b..99ea955f5987 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -439,9 +439,6 @@ static int dvb_register(struct cx8802_dev *dev) | |||
439 | /* Put the analog decoder in standby to keep it quiet */ | 439 | /* Put the analog decoder in standby to keep it quiet */ |
440 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | 440 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); |
441 | 441 | ||
442 | /* Put the analog decoder in standby to keep it quiet */ | ||
443 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | ||
444 | |||
445 | /* register everything */ | 442 | /* register everything */ |
446 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); | 443 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); |
447 | } | 444 | } |
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 32c49df58adc..9b94f77d6fd7 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -120,9 +120,6 @@ static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
120 | if (buf[1]==0xff) | 120 | if (buf[1]==0xff) |
121 | return 0; | 121 | return 0; |
122 | 122 | ||
123 | /* avoid fast reapeating */ | ||
124 | if (buf[1]==ir->old) | ||
125 | return 0; | ||
126 | ir->old=buf[1]; | 123 | ir->old=buf[1]; |
127 | 124 | ||
128 | /* Rearranges bits to the right order */ | 125 | /* Rearranges bits to the right order */ |
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c index ed81934ef3cd..5abfc0fbf6de 100644 --- a/drivers/media/video/ir-kbd-gpio.c +++ b/drivers/media/video/ir-kbd-gpio.c | |||
@@ -221,24 +221,99 @@ static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = { | |||
221 | [ 24 ] = KEY_MUTE // mute/unmute | 221 | [ 24 ] = KEY_MUTE // mute/unmute |
222 | }; | 222 | }; |
223 | 223 | ||
224 | static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = { | ||
225 | [0x00] = KEY_KP0, | ||
226 | [0x01] = KEY_KP1, | ||
227 | [0x02] = KEY_KP2, | ||
228 | [0x03] = KEY_KP3, | ||
229 | [0x04] = KEY_KP4, | ||
230 | [0x05] = KEY_KP5, | ||
231 | [0x06] = KEY_KP6, | ||
232 | [0x07] = KEY_KP7, | ||
233 | [0x08] = KEY_KP8, | ||
234 | [0x09] = KEY_KP9, | ||
235 | [0x0a] = KEY_TV, | ||
236 | [0x0b] = KEY_AUX, | ||
237 | [0x0c] = KEY_DVD, | ||
238 | [0x0d] = KEY_POWER, | ||
239 | [0x0e] = KEY_MHP, /* labelled 'Picture' */ | ||
240 | [0x0f] = KEY_AUDIO, | ||
241 | [0x10] = KEY_INFO, | ||
242 | [0x11] = KEY_F13, /* 16:9 */ | ||
243 | [0x12] = KEY_F14, /* 14:9 */ | ||
244 | [0x13] = KEY_EPG, | ||
245 | [0x14] = KEY_EXIT, | ||
246 | [0x15] = KEY_MENU, | ||
247 | [0x16] = KEY_UP, | ||
248 | [0x17] = KEY_DOWN, | ||
249 | [0x18] = KEY_LEFT, | ||
250 | [0x19] = KEY_RIGHT, | ||
251 | [0x1a] = KEY_ENTER, | ||
252 | [0x1b] = KEY_CHANNELUP, | ||
253 | [0x1c] = KEY_CHANNELDOWN, | ||
254 | [0x1d] = KEY_VOLUMEUP, | ||
255 | [0x1e] = KEY_VOLUMEDOWN, | ||
256 | [0x1f] = KEY_RED, | ||
257 | [0x20] = KEY_GREEN, | ||
258 | [0x21] = KEY_YELLOW, | ||
259 | [0x22] = KEY_BLUE, | ||
260 | [0x23] = KEY_SUBTITLE, | ||
261 | [0x24] = KEY_F15, /* AD */ | ||
262 | [0x25] = KEY_TEXT, | ||
263 | [0x26] = KEY_MUTE, | ||
264 | [0x27] = KEY_REWIND, | ||
265 | [0x28] = KEY_STOP, | ||
266 | [0x29] = KEY_PLAY, | ||
267 | [0x2a] = KEY_FASTFORWARD, | ||
268 | [0x2b] = KEY_F16, /* chapter */ | ||
269 | [0x2c] = KEY_PAUSE, | ||
270 | [0x2d] = KEY_PLAY, | ||
271 | [0x2e] = KEY_RECORD, | ||
272 | [0x2f] = KEY_F17, /* picture in picture */ | ||
273 | [0x30] = KEY_KPPLUS, /* zoom in */ | ||
274 | [0x31] = KEY_KPMINUS, /* zoom out */ | ||
275 | [0x32] = KEY_F18, /* capture */ | ||
276 | [0x33] = KEY_F19, /* web */ | ||
277 | [0x34] = KEY_EMAIL, | ||
278 | [0x35] = KEY_PHONE, | ||
279 | [0x36] = KEY_PC | ||
280 | }; | ||
281 | |||
224 | struct IR { | 282 | struct IR { |
225 | struct bttv_sub_device *sub; | 283 | struct bttv_sub_device *sub; |
226 | struct input_dev *input; | 284 | struct input_dev *input; |
227 | struct ir_input_state ir; | 285 | struct ir_input_state ir; |
228 | char name[32]; | 286 | char name[32]; |
229 | char phys[32]; | 287 | char phys[32]; |
288 | |||
289 | /* Usual gpio signalling */ | ||
290 | |||
230 | u32 mask_keycode; | 291 | u32 mask_keycode; |
231 | u32 mask_keydown; | 292 | u32 mask_keydown; |
232 | u32 mask_keyup; | 293 | u32 mask_keyup; |
233 | 294 | u32 polling; | |
234 | int polling; | ||
235 | u32 last_gpio; | 295 | u32 last_gpio; |
236 | struct work_struct work; | 296 | struct work_struct work; |
237 | struct timer_list timer; | 297 | struct timer_list timer; |
298 | |||
299 | /* RC5 gpio */ | ||
300 | |||
301 | u32 rc5_gpio; | ||
302 | struct timer_list timer_end; /* timer_end for code completion */ | ||
303 | struct timer_list timer_keyup; /* timer_end for key release */ | ||
304 | u32 last_rc5; /* last good rc5 code */ | ||
305 | u32 last_bit; /* last raw bit seen */ | ||
306 | u32 code; /* raw code under construction */ | ||
307 | struct timeval base_time; /* time of last seen code */ | ||
308 | int active; /* building raw code */ | ||
238 | }; | 309 | }; |
239 | 310 | ||
240 | static int debug; | 311 | static int debug; |
241 | module_param(debug, int, 0644); /* debug level (0,1,2) */ | 312 | module_param(debug, int, 0644); /* debug level (0,1,2) */ |
313 | static int repeat_delay = 500; | ||
314 | module_param(repeat_delay, int, 0644); | ||
315 | static int repeat_period = 33; | ||
316 | module_param(repeat_period, int, 0644); | ||
242 | 317 | ||
243 | #define DEVNAME "ir-kbd-gpio" | 318 | #define DEVNAME "ir-kbd-gpio" |
244 | #define dprintk(fmt, arg...) if (debug) \ | 319 | #define dprintk(fmt, arg...) if (debug) \ |
@@ -254,7 +329,7 @@ static struct bttv_sub_driver driver = { | |||
254 | .probe = ir_probe, | 329 | .probe = ir_probe, |
255 | .remove = ir_remove, | 330 | .remove = ir_remove, |
256 | }, | 331 | }, |
257 | .gpio_irq = ir_irq, | 332 | .gpio_irq = ir_irq, |
258 | }; | 333 | }; |
259 | 334 | ||
260 | /* ---------------------------------------------------------------------- */ | 335 | /* ---------------------------------------------------------------------- */ |
@@ -327,6 +402,173 @@ static void ir_work(void *data) | |||
327 | mod_timer(&ir->timer, timeout); | 402 | mod_timer(&ir->timer, timeout); |
328 | } | 403 | } |
329 | 404 | ||
405 | /* ---------------------------------------------------------------*/ | ||
406 | |||
407 | static int rc5_remote_gap = 885; | ||
408 | module_param(rc5_remote_gap, int, 0644); | ||
409 | static int rc5_key_timeout = 200; | ||
410 | module_param(rc5_key_timeout, int, 0644); | ||
411 | |||
412 | #define RC5_START(x) (((x)>>12)&3) | ||
413 | #define RC5_TOGGLE(x) (((x)>>11)&1) | ||
414 | #define RC5_ADDR(x) (((x)>>6)&31) | ||
415 | #define RC5_INSTR(x) ((x)&63) | ||
416 | |||
417 | /* decode raw bit pattern to RC5 code */ | ||
418 | static u32 rc5_decode(unsigned int code) | ||
419 | { | ||
420 | unsigned int org_code = code; | ||
421 | unsigned int pair; | ||
422 | unsigned int rc5 = 0; | ||
423 | int i; | ||
424 | |||
425 | code = (code << 1) | 1; | ||
426 | for (i = 0; i < 14; ++i) { | ||
427 | pair = code & 0x3; | ||
428 | code >>= 2; | ||
429 | |||
430 | rc5 <<= 1; | ||
431 | switch (pair) { | ||
432 | case 0: | ||
433 | case 2: | ||
434 | break; | ||
435 | case 1: | ||
436 | rc5 |= 1; | ||
437 | break; | ||
438 | case 3: | ||
439 | dprintk("bad code: %x\n", org_code); | ||
440 | return 0; | ||
441 | } | ||
442 | } | ||
443 | dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " | ||
444 | "instr=%x\n", rc5, org_code, RC5_START(rc5), | ||
445 | RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); | ||
446 | return rc5; | ||
447 | } | ||
448 | |||
449 | static int ir_rc5_irq(struct bttv_sub_device *sub) | ||
450 | { | ||
451 | struct IR *ir = dev_get_drvdata(&sub->dev); | ||
452 | struct timeval tv; | ||
453 | u32 gpio; | ||
454 | u32 gap; | ||
455 | unsigned long current_jiffies, timeout; | ||
456 | |||
457 | /* read gpio port */ | ||
458 | gpio = bttv_gpio_read(ir->sub->core); | ||
459 | |||
460 | /* remote IRQ? */ | ||
461 | if (!(gpio & 0x20)) | ||
462 | return 0; | ||
463 | |||
464 | /* get time of bit */ | ||
465 | current_jiffies = jiffies; | ||
466 | do_gettimeofday(&tv); | ||
467 | |||
468 | /* avoid overflow with gap >1s */ | ||
469 | if (tv.tv_sec - ir->base_time.tv_sec > 1) { | ||
470 | gap = 200000; | ||
471 | } else { | ||
472 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
473 | tv.tv_usec - ir->base_time.tv_usec; | ||
474 | } | ||
475 | |||
476 | /* active code => add bit */ | ||
477 | if (ir->active) { | ||
478 | /* only if in the code (otherwise spurious IRQ or timer | ||
479 | late) */ | ||
480 | if (ir->last_bit < 28) { | ||
481 | ir->last_bit = (gap - rc5_remote_gap / 2) / | ||
482 | rc5_remote_gap; | ||
483 | ir->code |= 1 << ir->last_bit; | ||
484 | } | ||
485 | /* starting new code */ | ||
486 | } else { | ||
487 | ir->active = 1; | ||
488 | ir->code = 0; | ||
489 | ir->base_time = tv; | ||
490 | ir->last_bit = 0; | ||
491 | |||
492 | timeout = current_jiffies + (500 + 30 * HZ) / 1000; | ||
493 | mod_timer(&ir->timer_end, timeout); | ||
494 | } | ||
495 | |||
496 | /* toggle GPIO pin 4 to reset the irq */ | ||
497 | bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4)); | ||
498 | bttv_gpio_write(ir->sub->core, gpio | (1 << 4)); | ||
499 | return 1; | ||
500 | } | ||
501 | |||
502 | static void ir_rc5_timer_end(unsigned long data) | ||
503 | { | ||
504 | struct IR *ir = (struct IR *)data; | ||
505 | struct timeval tv; | ||
506 | unsigned long current_jiffies, timeout; | ||
507 | u32 gap; | ||
508 | |||
509 | /* get time */ | ||
510 | current_jiffies = jiffies; | ||
511 | do_gettimeofday(&tv); | ||
512 | |||
513 | /* avoid overflow with gap >1s */ | ||
514 | if (tv.tv_sec - ir->base_time.tv_sec > 1) { | ||
515 | gap = 200000; | ||
516 | } else { | ||
517 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
518 | tv.tv_usec - ir->base_time.tv_usec; | ||
519 | } | ||
520 | |||
521 | /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ | ||
522 | if (gap < 28000) { | ||
523 | dprintk("spurious timer_end\n"); | ||
524 | return; | ||
525 | } | ||
526 | |||
527 | ir->active = 0; | ||
528 | if (ir->last_bit < 20) { | ||
529 | /* ignore spurious codes (caused by light/other remotes) */ | ||
530 | dprintk("short code: %x\n", ir->code); | ||
531 | } else { | ||
532 | u32 rc5 = rc5_decode(ir->code); | ||
533 | |||
534 | /* two start bits? */ | ||
535 | if (RC5_START(rc5) != 3) { | ||
536 | dprintk("rc5 start bits invalid: %u\n", RC5_START(rc5)); | ||
537 | |||
538 | /* right address? */ | ||
539 | } else if (RC5_ADDR(rc5) == 0x0) { | ||
540 | u32 toggle = RC5_TOGGLE(rc5); | ||
541 | u32 instr = RC5_INSTR(rc5); | ||
542 | |||
543 | /* Good code, decide if repeat/repress */ | ||
544 | if (toggle != RC5_TOGGLE(ir->last_rc5) || | ||
545 | instr != RC5_INSTR(ir->last_rc5)) { | ||
546 | dprintk("instruction %x, toggle %x\n", instr, | ||
547 | toggle); | ||
548 | ir_input_nokey(ir->input, &ir->ir); | ||
549 | ir_input_keydown(ir->input, &ir->ir, instr, | ||
550 | instr); | ||
551 | } | ||
552 | |||
553 | /* Set/reset key-up timer */ | ||
554 | timeout = current_jiffies + (500 + rc5_key_timeout | ||
555 | * HZ) / 1000; | ||
556 | mod_timer(&ir->timer_keyup, timeout); | ||
557 | |||
558 | /* Save code for repeat test */ | ||
559 | ir->last_rc5 = rc5; | ||
560 | } | ||
561 | } | ||
562 | } | ||
563 | |||
564 | static void ir_rc5_timer_keyup(unsigned long data) | ||
565 | { | ||
566 | struct IR *ir = (struct IR *)data; | ||
567 | |||
568 | dprintk("key released\n"); | ||
569 | ir_input_nokey(ir->input, &ir->ir); | ||
570 | } | ||
571 | |||
330 | /* ---------------------------------------------------------------------- */ | 572 | /* ---------------------------------------------------------------------- */ |
331 | 573 | ||
332 | static int ir_probe(struct device *dev) | 574 | static int ir_probe(struct device *dev) |
@@ -400,6 +642,12 @@ static int ir_probe(struct device *dev) | |||
400 | ir->mask_keyup = 0x006000; | 642 | ir->mask_keyup = 0x006000; |
401 | ir->polling = 50; // ms | 643 | ir->polling = 50; // ms |
402 | break; | 644 | break; |
645 | case BTTV_BOARD_NEBULA_DIGITV: | ||
646 | ir_codes = ir_codes_nebula; | ||
647 | driver.any_irq = ir_rc5_irq; | ||
648 | driver.gpio_irq = NULL; | ||
649 | ir->rc5_gpio = 1; | ||
650 | break; | ||
403 | } | 651 | } |
404 | if (NULL == ir_codes) { | 652 | if (NULL == ir_codes) { |
405 | kfree(ir); | 653 | kfree(ir); |
@@ -407,9 +655,17 @@ static int ir_probe(struct device *dev) | |||
407 | return -ENODEV; | 655 | return -ENODEV; |
408 | } | 656 | } |
409 | 657 | ||
410 | /* init hardware-specific stuff */ | 658 | if (ir->rc5_gpio) { |
411 | bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0); | 659 | u32 gpio; |
412 | ir->sub = sub; | 660 | /* enable remote irq */ |
661 | bttv_gpio_inout(sub->core, (1 << 4), 1 << 4); | ||
662 | gpio = bttv_gpio_read(sub->core); | ||
663 | bttv_gpio_write(sub->core, gpio & ~(1 << 4)); | ||
664 | bttv_gpio_write(sub->core, gpio | (1 << 4)); | ||
665 | } else { | ||
666 | /* init hardware-specific stuff */ | ||
667 | bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0); | ||
668 | } | ||
413 | 669 | ||
414 | /* init input device */ | 670 | /* init input device */ |
415 | snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", | 671 | snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", |
@@ -417,6 +673,7 @@ static int ir_probe(struct device *dev) | |||
417 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", | 673 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", |
418 | pci_name(sub->core->pci)); | 674 | pci_name(sub->core->pci)); |
419 | 675 | ||
676 | ir->sub = sub; | ||
420 | ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); | 677 | ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); |
421 | input_dev->name = ir->name; | 678 | input_dev->name = ir->name; |
422 | input_dev->phys = ir->phys; | 679 | input_dev->phys = ir->phys; |
@@ -437,11 +694,25 @@ static int ir_probe(struct device *dev) | |||
437 | ir->timer.function = ir_timer; | 694 | ir->timer.function = ir_timer; |
438 | ir->timer.data = (unsigned long)ir; | 695 | ir->timer.data = (unsigned long)ir; |
439 | schedule_work(&ir->work); | 696 | schedule_work(&ir->work); |
697 | } else if (ir->rc5_gpio) { | ||
698 | /* set timer_end for code completion */ | ||
699 | init_timer(&ir->timer_end); | ||
700 | ir->timer_end.function = ir_rc5_timer_end; | ||
701 | ir->timer_end.data = (unsigned long)ir; | ||
702 | |||
703 | init_timer(&ir->timer_keyup); | ||
704 | ir->timer_keyup.function = ir_rc5_timer_keyup; | ||
705 | ir->timer_keyup.data = (unsigned long)ir; | ||
440 | } | 706 | } |
441 | 707 | ||
442 | /* all done */ | 708 | /* all done */ |
443 | dev_set_drvdata(dev, ir); | 709 | dev_set_drvdata(dev, ir); |
444 | input_register_device(ir->input); | 710 | input_register_device(ir->input); |
711 | printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys); | ||
712 | |||
713 | /* the remote isn't as bouncy as a keyboard */ | ||
714 | ir->input->rep[REP_DELAY] = repeat_delay; | ||
715 | ir->input->rep[REP_PERIOD] = repeat_period; | ||
445 | 716 | ||
446 | return 0; | 717 | return 0; |
447 | } | 718 | } |
@@ -454,6 +725,15 @@ static int ir_remove(struct device *dev) | |||
454 | del_timer(&ir->timer); | 725 | del_timer(&ir->timer); |
455 | flush_scheduled_work(); | 726 | flush_scheduled_work(); |
456 | } | 727 | } |
728 | if (ir->rc5_gpio) { | ||
729 | u32 gpio; | ||
730 | |||
731 | del_timer(&ir->timer_end); | ||
732 | flush_scheduled_work(); | ||
733 | |||
734 | gpio = bttv_gpio_read(ir->sub->core); | ||
735 | bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4)); | ||
736 | } | ||
457 | 737 | ||
458 | input_unregister_device(ir->input); | 738 | input_unregister_device(ir->input); |
459 | kfree(ir); | 739 | kfree(ir); |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 0085567a1421..801c736e9328 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -183,6 +183,58 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
183 | return 1; | 183 | return 1; |
184 | } | 184 | } |
185 | 185 | ||
186 | /* The new pinnacle PCTV remote (with the colored buttons) | ||
187 | * | ||
188 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
189 | */ | ||
190 | |||
191 | int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
192 | { | ||
193 | unsigned char b[4]; | ||
194 | unsigned int start = 0,parity = 0,code = 0; | ||
195 | |||
196 | /* poll IR chip */ | ||
197 | if (4 != i2c_master_recv(&ir->c,b,4)) { | ||
198 | dprintk(2,"read error\n"); | ||
199 | return -EIO; | ||
200 | } | ||
201 | |||
202 | for (start = 0; start<4; start++) { | ||
203 | if (b[start] == 0x80) { | ||
204 | code=b[(start+3)%4]; | ||
205 | parity=b[(start+2)%4]; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | /* Empty Request */ | ||
210 | if (parity==0) | ||
211 | return 0; | ||
212 | |||
213 | /* Repeating... */ | ||
214 | if (ir->old == parity) | ||
215 | return 0; | ||
216 | |||
217 | |||
218 | ir->old = parity; | ||
219 | |||
220 | /* Reduce code value to fit inside IR_KEYTAB_SIZE | ||
221 | * | ||
222 | * this is the only value that results in 42 unique | ||
223 | * codes < 128 | ||
224 | */ | ||
225 | |||
226 | code %= 0x88; | ||
227 | |||
228 | *ir_raw = code; | ||
229 | *ir_key = code; | ||
230 | |||
231 | dprintk(1,"Pinnacle PCTV key %02x\n", code); | ||
232 | |||
233 | return 1; | ||
234 | } | ||
235 | |||
236 | EXPORT_SYMBOL_GPL(get_key_pinnacle); | ||
237 | |||
186 | /* ----------------------------------------------------------------------- */ | 238 | /* ----------------------------------------------------------------------- */ |
187 | 239 | ||
188 | static void ir_key_poll(struct IR_i2c *ir) | 240 | static void ir_key_poll(struct IR_i2c *ir) |
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c new file mode 100644 index 000000000000..0235cef07b31 --- /dev/null +++ b/drivers/media/video/saa7115.c | |||
@@ -0,0 +1,1376 @@ | |||
1 | /* saa7115 - Philips SAA7114/SAA7115 video decoder driver | ||
2 | * | ||
3 | * Based on saa7114 driver by Maxim Yevtyushkin, which is based on | ||
4 | * the saa7111 driver by Dave Perks. | ||
5 | * | ||
6 | * Copyright (C) 1998 Dave Perks <dperks@ibm.net> | ||
7 | * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com> | ||
8 | * | ||
9 | * Slight changes for video timing and attachment output by | ||
10 | * Wolfgang Scherr <scherr@net4you.net> | ||
11 | * | ||
12 | * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003) | ||
13 | * by Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
14 | * | ||
15 | * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com> | ||
16 | * (2/17/2003) | ||
17 | * | ||
18 | * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl> | ||
19 | * | ||
20 | * This program is free software; you can redistribute it and/or | ||
21 | * modify it under the terms of the GNU General Public License | ||
22 | * as published by the Free Software Foundation; either version 2 | ||
23 | * of the License, or (at your option) any later version. | ||
24 | * | ||
25 | * This program is distributed in the hope that it will be useful, | ||
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
28 | * GNU General Public License for more details. | ||
29 | * | ||
30 | * You should have received a copy of the GNU General Public License | ||
31 | * along with this program; if not, write to the Free Software | ||
32 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
33 | */ | ||
34 | |||
35 | |||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/module.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/i2c.h> | ||
40 | #include <linux/videodev2.h> | ||
41 | #include <media/v4l2-common.h> | ||
42 | |||
43 | MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver"); | ||
44 | MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil"); | ||
45 | MODULE_LICENSE("GPL"); | ||
46 | |||
47 | static int debug = 0; | ||
48 | module_param(debug, int, 0644); | ||
49 | |||
50 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | ||
51 | |||
52 | #define saa7115_dbg(fmt,arg...) \ | ||
53 | do { \ | ||
54 | if (debug) \ | ||
55 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
56 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
57 | } while (0) | ||
58 | |||
59 | #define saa7115_err(fmt, arg...) do { \ | ||
60 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | ||
61 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
62 | #define saa7115_info(fmt, arg...) do { \ | ||
63 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | ||
64 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
65 | |||
66 | static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; | ||
67 | |||
68 | |||
69 | I2C_CLIENT_INSMOD; | ||
70 | |||
71 | struct saa7115_state { | ||
72 | v4l2_std_id std; | ||
73 | int input; | ||
74 | int enable; | ||
75 | int bright; | ||
76 | int contrast; | ||
77 | int hue; | ||
78 | int sat; | ||
79 | enum v4l2_chip_ident ident; | ||
80 | enum v4l2_audio_clock_freq audclk_freq; | ||
81 | }; | ||
82 | |||
83 | /* ----------------------------------------------------------------------- */ | ||
84 | |||
85 | static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value) | ||
86 | { | ||
87 | return i2c_smbus_write_byte_data(client, reg, value); | ||
88 | } | ||
89 | |||
90 | static int saa7115_writeregs(struct i2c_client *client, const unsigned char *regs) | ||
91 | { | ||
92 | unsigned char reg, data; | ||
93 | |||
94 | while (*regs != 0x00) { | ||
95 | reg = *(regs++); | ||
96 | data = *(regs++); | ||
97 | if (saa7115_write(client, reg, data) < 0) | ||
98 | return -1; | ||
99 | } | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static inline int saa7115_read(struct i2c_client *client, u8 reg) | ||
104 | { | ||
105 | return i2c_smbus_read_byte_data(client, reg); | ||
106 | } | ||
107 | |||
108 | /* ----------------------------------------------------------------------- */ | ||
109 | |||
110 | /* If a value differs from the Hauppauge driver values, then the comment starts with | ||
111 | 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the | ||
112 | Hauppauge driver sets. */ | ||
113 | |||
114 | static const unsigned char saa7115_init_auto_input[] = { | ||
115 | 0x01, 0x48, /* white peak control disabled */ | ||
116 | 0x03, 0x20, /* was 0x30. 0x20: long vertical blanking */ | ||
117 | 0x04, 0x90, /* analog gain set to 0 */ | ||
118 | 0x05, 0x90, /* analog gain set to 0 */ | ||
119 | 0x06, 0xeb, /* horiz sync begin = -21 */ | ||
120 | 0x07, 0xe0, /* horiz sync stop = -17 */ | ||
121 | 0x0a, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */ | ||
122 | 0x0b, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */ | ||
123 | 0x0c, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */ | ||
124 | 0x0d, 0x00, /* chrominance hue control */ | ||
125 | 0x0f, 0x00, /* chrominance gain control: use automicatic mode */ | ||
126 | 0x10, 0x06, /* chrominance/luminance control: active adaptive combfilter */ | ||
127 | 0x11, 0x00, /* delay control */ | ||
128 | 0x12, 0x9d, /* RTS0 output control: VGATE */ | ||
129 | 0x13, 0x80, /* X-port output control: ITU656 standard mode, RTCO output enable RTCE */ | ||
130 | 0x14, 0x00, /* analog/ADC/auto compatibility control */ | ||
131 | 0x18, 0x40, /* raw data gain 0x00 = nominal */ | ||
132 | 0x19, 0x80, /* raw data offset 0x80 = 0 LSB */ | ||
133 | 0x1a, 0x77, /* color killer level control 0x77 = recommended */ | ||
134 | 0x1b, 0x42, /* misc chroma control 0x42 = recommended */ | ||
135 | 0x1c, 0xa9, /* combfilter control 0xA9 = recommended */ | ||
136 | 0x1d, 0x01, /* combfilter control 0x01 = recommended */ | ||
137 | 0x88, 0xd0, /* reset device */ | ||
138 | 0x88, 0xf0, /* set device programmed, all in operational mode */ | ||
139 | 0x00, 0x00 | ||
140 | }; | ||
141 | |||
142 | static const unsigned char saa7115_cfg_reset_scaler[] = { | ||
143 | 0x87, 0x00, /* disable I-port output */ | ||
144 | 0x88, 0xd0, /* reset scaler */ | ||
145 | 0x88, 0xf0, /* activate scaler */ | ||
146 | 0x87, 0x01, /* enable I-port output */ | ||
147 | 0x00, 0x00 | ||
148 | }; | ||
149 | |||
150 | /* ============== SAA7715 VIDEO templates ============= */ | ||
151 | |||
152 | static const unsigned char saa7115_cfg_60hz_fullres_x[] = { | ||
153 | 0xcc, 0xd0, /* hsize low (output), hor. output window size = 0x2d0 = 720 */ | ||
154 | 0xcd, 0x02, /* hsize hi (output) */ | ||
155 | |||
156 | /* Why not in 60hz-Land, too? */ | ||
157 | 0xd0, 0x01, /* downscale = 1 */ | ||
158 | 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */ | ||
159 | 0xd9, 0x04, | ||
160 | 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */ | ||
161 | 0xdd, 0x02, /* H-scaling incr chroma */ | ||
162 | |||
163 | 0x00, 0x00 | ||
164 | }; | ||
165 | static const unsigned char saa7115_cfg_60hz_fullres_y[] = { | ||
166 | 0xce, 0xf8, /* vsize low (output), ver. output window size = 248 (but 60hz is 240?) */ | ||
167 | 0xcf, 0x00, /* vsize hi (output) */ | ||
168 | |||
169 | /* Why not in 60hz-Land, too? */ | ||
170 | 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */ | ||
171 | 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */ | ||
172 | |||
173 | 0xe0, 0x00, /* V-scaling incr luma low */ | ||
174 | 0xe1, 0x04, /* " hi */ | ||
175 | 0xe2, 0x00, /* V-scaling incr chroma low */ | ||
176 | 0xe3, 0x04, /* " hi */ | ||
177 | |||
178 | 0x00, 0x00 | ||
179 | }; | ||
180 | |||
181 | static const unsigned char saa7115_cfg_60hz_video[] = { | ||
182 | 0x80, 0x00, /* reset tasks */ | ||
183 | 0x88, 0xd0, /* reset scaler */ | ||
184 | |||
185 | 0x15, 0x03, /* VGATE pulse start */ | ||
186 | 0x16, 0x11, /* VGATE pulse stop */ | ||
187 | 0x17, 0x9c, /* VGATE MSB and other values */ | ||
188 | |||
189 | 0x08, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */ | ||
190 | 0x0e, 0x07, /* lots of different stuff... video autodetection is on */ | ||
191 | |||
192 | 0x5a, 0x06, /* Vertical offset, standard 60hz value for ITU656 line counting */ | ||
193 | |||
194 | /* Task A */ | ||
195 | 0x90, 0x80, /* Task Handling Control */ | ||
196 | 0x91, 0x48, /* X-port formats/config */ | ||
197 | 0x92, 0x40, /* Input Ref. signal Def. */ | ||
198 | 0x93, 0x84, /* I-port config */ | ||
199 | 0x94, 0x01, /* hoffset low (input), 0x0002 is minimum */ | ||
200 | 0x95, 0x00, /* hoffset hi (input) */ | ||
201 | 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */ | ||
202 | 0x97, 0x02, /* hsize hi (input) */ | ||
203 | 0x98, 0x05, /* voffset low (input) */ | ||
204 | 0x99, 0x00, /* voffset hi (input) */ | ||
205 | 0x9a, 0x0c, /* vsize low (input), 0x0c = 12 */ | ||
206 | 0x9b, 0x00, /* vsize hi (input) */ | ||
207 | 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */ | ||
208 | 0x9d, 0x05, /* hsize hi (output) */ | ||
209 | 0x9e, 0x0c, /* vsize low (output), 0x0c = 12 */ | ||
210 | 0x9f, 0x00, /* vsize hi (output) */ | ||
211 | |||
212 | /* Task B */ | ||
213 | 0xc0, 0x00, /* Task Handling Control */ | ||
214 | 0xc1, 0x08, /* X-port formats/config */ | ||
215 | 0xc2, 0x00, /* Input Ref. signal Def. */ | ||
216 | 0xc3, 0x80, /* I-port config */ | ||
217 | 0xc4, 0x02, /* hoffset low (input), 0x0002 is minimum */ | ||
218 | 0xc5, 0x00, /* hoffset hi (input) */ | ||
219 | 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */ | ||
220 | 0xc7, 0x02, /* hsize hi (input) */ | ||
221 | 0xc8, 0x12, /* voffset low (input), 0x12 = 18 */ | ||
222 | 0xc9, 0x00, /* voffset hi (input) */ | ||
223 | 0xca, 0xf8, /* vsize low (input), 0xf8 = 248 */ | ||
224 | 0xcb, 0x00, /* vsize hi (input) */ | ||
225 | 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */ | ||
226 | 0xcd, 0x02, /* hsize hi (output) */ | ||
227 | |||
228 | 0xf0, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */ | ||
229 | 0xf1, 0x05, /* low bit with 0xF0 */ | ||
230 | 0xf5, 0xad, /* Set pulse generator register */ | ||
231 | 0xf6, 0x01, | ||
232 | |||
233 | 0x87, 0x00, /* Disable I-port output */ | ||
234 | 0x88, 0xd0, /* reset scaler */ | ||
235 | 0x80, 0x20, /* Activate only task "B", continuous mode (was 0xA0) */ | ||
236 | 0x88, 0xf0, /* activate scaler */ | ||
237 | 0x87, 0x01, /* Enable I-port output */ | ||
238 | 0x00, 0x00 | ||
239 | }; | ||
240 | |||
241 | static const unsigned char saa7115_cfg_50hz_fullres_x[] = { | ||
242 | 0xcc, 0xd0, /* hsize low (output), 720 same as 60hz */ | ||
243 | 0xcd, 0x02, /* hsize hi (output) */ | ||
244 | |||
245 | 0xd0, 0x01, /* down scale = 1 */ | ||
246 | 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */ | ||
247 | 0xd9, 0x04, | ||
248 | 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */ | ||
249 | 0xdd, 0x02, /* H-scaling incr chroma */ | ||
250 | |||
251 | 0x00, 0x00 | ||
252 | }; | ||
253 | static const unsigned char saa7115_cfg_50hz_fullres_y[] = { | ||
254 | 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */ | ||
255 | 0xcf, 0x01, /* vsize hi (output) */ | ||
256 | |||
257 | 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */ | ||
258 | 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */ | ||
259 | |||
260 | 0xe0, 0x00, /* V-scaling incr luma low */ | ||
261 | 0xe1, 0x04, /* " hi */ | ||
262 | 0xe2, 0x00, /* V-scaling incr chroma low */ | ||
263 | 0xe3, 0x04, /* " hi */ | ||
264 | |||
265 | 0x00, 0x00 | ||
266 | }; | ||
267 | |||
268 | static const unsigned char saa7115_cfg_50hz_video[] = { | ||
269 | 0x80, 0x00, /* reset tasks */ | ||
270 | 0x88, 0xd0, /* reset scaler */ | ||
271 | |||
272 | 0x15, 0x37, /* VGATE start */ | ||
273 | 0x16, 0x16, /* VGATE stop */ | ||
274 | 0x17, 0x99, /* VGATE MSB and other values */ | ||
275 | |||
276 | 0x08, 0x28, /* 0x28 = PAL */ | ||
277 | 0x0e, 0x07, /* chrominance control 1 */ | ||
278 | |||
279 | 0x5a, 0x03, /* Vertical offset, standard 50hz value */ | ||
280 | |||
281 | /* Task A */ | ||
282 | 0x90, 0x81, /* Task Handling Control */ | ||
283 | 0x91, 0x48, /* X-port formats/config */ | ||
284 | 0x92, 0x40, /* Input Ref. signal Def. */ | ||
285 | 0x93, 0x84, /* I-port config */ | ||
286 | /* This is weird: the datasheet says that you should use 2 as the minimum value, */ | ||
287 | /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */ | ||
288 | 0x94, 0x00, /* hoffset low (input), 0x0002 is minimum */ | ||
289 | 0x95, 0x00, /* hoffset hi (input) */ | ||
290 | 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */ | ||
291 | 0x97, 0x02, /* hsize hi (input) */ | ||
292 | 0x98, 0x03, /* voffset low (input) */ | ||
293 | 0x99, 0x00, /* voffset hi (input) */ | ||
294 | 0x9a, 0x12, /* vsize low (input), 0x12 = 18 */ | ||
295 | 0x9b, 0x00, /* vsize hi (input) */ | ||
296 | 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */ | ||
297 | 0x9d, 0x05, /* hsize hi (output) */ | ||
298 | 0x9e, 0x12, /* vsize low (output), 0x12 = 18 */ | ||
299 | 0x9f, 0x00, /* vsize hi (output) */ | ||
300 | |||
301 | /* Task B */ | ||
302 | 0xc0, 0x00, /* Task Handling Control */ | ||
303 | 0xc1, 0x08, /* X-port formats/config */ | ||
304 | 0xc2, 0x00, /* Input Ref. signal Def. */ | ||
305 | 0xc3, 0x80, /* I-port config */ | ||
306 | 0xc4, 0x00, /* hoffset low (input), 0x0002 is minimum. See comment at 0x94 above. */ | ||
307 | 0xc5, 0x00, /* hoffset hi (input) */ | ||
308 | 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */ | ||
309 | 0xc7, 0x02, /* hsize hi (input) */ | ||
310 | 0xc8, 0x16, /* voffset low (input), 0x16 = 22 */ | ||
311 | 0xc9, 0x00, /* voffset hi (input) */ | ||
312 | 0xca, 0x20, /* vsize low (input), 0x0120 = 288 */ | ||
313 | 0xcb, 0x01, /* vsize hi (input) */ | ||
314 | 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */ | ||
315 | 0xcd, 0x02, /* hsize hi (output) */ | ||
316 | 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */ | ||
317 | 0xcf, 0x01, /* vsize hi (output) */ | ||
318 | |||
319 | 0xf0, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */ | ||
320 | 0xf1, 0x05, /* low bit with 0xF0, (was 0x05) */ | ||
321 | 0xf5, 0xb0, /* Set pulse generator register */ | ||
322 | 0xf6, 0x01, | ||
323 | |||
324 | 0x87, 0x00, /* Disable I-port output */ | ||
325 | 0x88, 0xd0, /* reset scaler (was 0xD0) */ | ||
326 | 0x80, 0x20, /* Activate only task "B" */ | ||
327 | 0x88, 0xf0, /* activate scaler */ | ||
328 | 0x87, 0x01, /* Enable I-port output */ | ||
329 | 0x00, 0x00 | ||
330 | }; | ||
331 | |||
332 | /* ============== SAA7715 VIDEO templates (end) ======= */ | ||
333 | |||
334 | static const unsigned char saa7115_cfg_vbi_on[] = { | ||
335 | 0x80, 0x00, /* reset tasks */ | ||
336 | 0x88, 0xd0, /* reset scaler */ | ||
337 | 0x80, 0x30, /* Activate both tasks */ | ||
338 | 0x88, 0xf0, /* activate scaler */ | ||
339 | 0x87, 0x01, /* Enable I-port output */ | ||
340 | 0x00, 0x00 | ||
341 | }; | ||
342 | |||
343 | static const unsigned char saa7115_cfg_vbi_off[] = { | ||
344 | 0x80, 0x00, /* reset tasks */ | ||
345 | 0x88, 0xd0, /* reset scaler */ | ||
346 | 0x80, 0x20, /* Activate only task "B" */ | ||
347 | 0x88, 0xf0, /* activate scaler */ | ||
348 | 0x87, 0x01, /* Enable I-port output */ | ||
349 | 0x00, 0x00 | ||
350 | }; | ||
351 | |||
352 | static const unsigned char saa7115_init_misc[] = { | ||
353 | 0x38, 0x03, /* audio stuff */ | ||
354 | 0x39, 0x10, | ||
355 | 0x3a, 0x08, | ||
356 | |||
357 | 0x81, 0x01, /* reg 0x15,0x16 define blanking window */ | ||
358 | 0x82, 0x00, | ||
359 | 0x83, 0x01, /* I port settings */ | ||
360 | 0x84, 0x20, | ||
361 | 0x85, 0x21, | ||
362 | 0x86, 0xc5, | ||
363 | 0x87, 0x01, | ||
364 | |||
365 | /* Task A */ | ||
366 | 0xa0, 0x01, /* down scale = 1 */ | ||
367 | 0xa1, 0x00, /* prescale accumulation length = 1 */ | ||
368 | 0xa2, 0x00, /* dc gain and fir prefilter control */ | ||
369 | 0xa4, 0x80, /* Lum Brightness, nominal value = 0x80 */ | ||
370 | 0xa5, 0x40, /* Lum contrast, nominal value = 0x40 */ | ||
371 | 0xa6, 0x40, /* Chroma satur. nominal value = 0x80 */ | ||
372 | 0xa8, 0x00, /* hor lum scaling 0x0200 = 2 zoom */ | ||
373 | 0xa9, 0x02, /* note: 2 x zoom ensures that VBI lines have same length as video lines. */ | ||
374 | 0xaa, 0x00, /* H-phase offset Luma = 0 */ | ||
375 | 0xac, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */ | ||
376 | 0xad, 0x01, /* H-scaling incr chroma */ | ||
377 | 0xae, 0x00, /* H-phase offset chroma. must be offset luma / 2 */ | ||
378 | |||
379 | 0xb0, 0x00, /* V-scaling incr luma low */ | ||
380 | 0xb1, 0x04, /* " hi */ | ||
381 | 0xb2, 0x00, /* V-scaling incr chroma low */ | ||
382 | 0xb3, 0x04, /* " hi */ | ||
383 | 0xb4, 0x01, /* V-scaling mode control */ | ||
384 | 0xb8, 0x00, /* V-phase offset chroma 00 */ | ||
385 | 0xb9, 0x00, /* V-phase offset chroma 01 */ | ||
386 | 0xba, 0x00, /* V-phase offset chroma 10 */ | ||
387 | 0xbb, 0x00, /* V-phase offset chroma 11 */ | ||
388 | 0xbc, 0x00, /* V-phase offset luma 00 */ | ||
389 | 0xbd, 0x00, /* V-phase offset luma 01 */ | ||
390 | 0xbe, 0x00, /* V-phase offset luma 10 */ | ||
391 | 0xbf, 0x00, /* V-phase offset luma 11 */ | ||
392 | |||
393 | /* Task B */ | ||
394 | 0xd0, 0x01, /* down scale = 1 */ | ||
395 | 0xd1, 0x00, /* prescale accumulation length = 1 */ | ||
396 | 0xd2, 0x00, /* dc gain and fir prefilter control */ | ||
397 | 0xd4, 0x80, /* Lum Brightness, nominal value = 0x80 */ | ||
398 | 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */ | ||
399 | 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */ | ||
400 | 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */ | ||
401 | 0xd9, 0x04, | ||
402 | 0xda, 0x00, /* H-phase offset Luma = 0 */ | ||
403 | 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */ | ||
404 | 0xdd, 0x02, /* H-scaling incr chroma */ | ||
405 | 0xde, 0x00, /* H-phase offset chroma. must be offset luma / 2 */ | ||
406 | |||
407 | 0xe0, 0x00, /* V-scaling incr luma low */ | ||
408 | 0xe1, 0x04, /* " hi */ | ||
409 | 0xe2, 0x00, /* V-scaling incr chroma low */ | ||
410 | 0xe3, 0x04, /* " hi */ | ||
411 | 0xe4, 0x01, /* V-scaling mode control */ | ||
412 | 0xe8, 0x00, /* V-phase offset chroma 00 */ | ||
413 | 0xe9, 0x00, /* V-phase offset chroma 01 */ | ||
414 | 0xea, 0x00, /* V-phase offset chroma 10 */ | ||
415 | 0xeb, 0x00, /* V-phase offset chroma 11 */ | ||
416 | 0xec, 0x00, /* V-phase offset luma 00 */ | ||
417 | 0xed, 0x00, /* V-phase offset luma 01 */ | ||
418 | 0xee, 0x00, /* V-phase offset luma 10 */ | ||
419 | 0xef, 0x00, /* V-phase offset luma 11 */ | ||
420 | |||
421 | 0xf2, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */ | ||
422 | 0xf3, 0x46, | ||
423 | 0xf4, 0x00, | ||
424 | 0xf7, 0x4b, /* not the recommended settings! */ | ||
425 | 0xf8, 0x00, | ||
426 | 0xf9, 0x4b, | ||
427 | 0xfa, 0x00, | ||
428 | 0xfb, 0x4b, | ||
429 | 0xff, 0x88, /* PLL2 lock detection settings: 71 lines 50% phase error */ | ||
430 | |||
431 | /* Turn off VBI */ | ||
432 | 0x40, 0x20, /* No framing code errors allowed. */ | ||
433 | 0x41, 0xff, | ||
434 | 0x42, 0xff, | ||
435 | 0x43, 0xff, | ||
436 | 0x44, 0xff, | ||
437 | 0x45, 0xff, | ||
438 | 0x46, 0xff, | ||
439 | 0x47, 0xff, | ||
440 | 0x48, 0xff, | ||
441 | 0x49, 0xff, | ||
442 | 0x4a, 0xff, | ||
443 | 0x4b, 0xff, | ||
444 | 0x4c, 0xff, | ||
445 | 0x4d, 0xff, | ||
446 | 0x4e, 0xff, | ||
447 | 0x4f, 0xff, | ||
448 | 0x50, 0xff, | ||
449 | 0x51, 0xff, | ||
450 | 0x52, 0xff, | ||
451 | 0x53, 0xff, | ||
452 | 0x54, 0xff, | ||
453 | 0x55, 0xff, | ||
454 | 0x56, 0xff, | ||
455 | 0x57, 0xff, | ||
456 | 0x58, 0x40, | ||
457 | 0x59, 0x47, | ||
458 | 0x5b, 0x83, | ||
459 | 0x5d, 0xbd, | ||
460 | 0x5e, 0x35, | ||
461 | |||
462 | 0x02, 0x84, /* input tuner -> input 4, amplifier active */ | ||
463 | 0x09, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */ | ||
464 | |||
465 | 0x80, 0x20, /* enable task B */ | ||
466 | 0x88, 0xd0, | ||
467 | 0x88, 0xf0, | ||
468 | 0x00, 0x00 | ||
469 | }; | ||
470 | |||
471 | /* ============== SAA7715 AUDIO settings ============= */ | ||
472 | |||
473 | /* 48.0 kHz */ | ||
474 | static const unsigned char saa7115_cfg_48_audio[] = { | ||
475 | 0x34, 0xce, | ||
476 | 0x35, 0xfb, | ||
477 | 0x36, 0x30, | ||
478 | 0x00, 0x00 | ||
479 | }; | ||
480 | |||
481 | /* 44.1 kHz */ | ||
482 | static const unsigned char saa7115_cfg_441_audio[] = { | ||
483 | 0x34, 0xf2, | ||
484 | 0x35, 0x00, | ||
485 | 0x36, 0x2d, | ||
486 | 0x00, 0x00 | ||
487 | }; | ||
488 | |||
489 | /* 32.0 kHz */ | ||
490 | static const unsigned char saa7115_cfg_32_audio[] = { | ||
491 | 0x34, 0xdf, | ||
492 | 0x35, 0xa7, | ||
493 | 0x36, 0x20, | ||
494 | 0x00, 0x00 | ||
495 | }; | ||
496 | |||
497 | /* 48.0 kHz 60hz */ | ||
498 | static const unsigned char saa7115_cfg_60hz_48_audio[] = { | ||
499 | 0x30, 0xcd, | ||
500 | 0x31, 0x20, | ||
501 | 0x32, 0x03, | ||
502 | 0x00, 0x00 | ||
503 | }; | ||
504 | |||
505 | /* 48.0 kHz 50hz */ | ||
506 | static const unsigned char saa7115_cfg_50hz_48_audio[] = { | ||
507 | 0x30, 0x00, | ||
508 | 0x31, 0xc0, | ||
509 | 0x32, 0x03, | ||
510 | 0x00, 0x00 | ||
511 | }; | ||
512 | |||
513 | /* 44.1 kHz 60hz */ | ||
514 | static const unsigned char saa7115_cfg_60hz_441_audio[] = { | ||
515 | 0x30, 0xbc, | ||
516 | 0x31, 0xdf, | ||
517 | 0x32, 0x02, | ||
518 | 0x00, 0x00 | ||
519 | }; | ||
520 | |||
521 | /* 44.1 kHz 50hz */ | ||
522 | static const unsigned char saa7115_cfg_50hz_441_audio[] = { | ||
523 | 0x30, 0x00, | ||
524 | 0x31, 0x72, | ||
525 | 0x32, 0x03, | ||
526 | 0x00, 0x00 | ||
527 | }; | ||
528 | |||
529 | /* 32.0 kHz 60hz */ | ||
530 | static const unsigned char saa7115_cfg_60hz_32_audio[] = { | ||
531 | 0x30, 0xde, | ||
532 | 0x31, 0x15, | ||
533 | 0x32, 0x02, | ||
534 | 0x00, 0x00 | ||
535 | }; | ||
536 | |||
537 | /* 32.0 kHz 50hz */ | ||
538 | static const unsigned char saa7115_cfg_50hz_32_audio[] = { | ||
539 | 0x30, 0x00, | ||
540 | 0x31, 0x80, | ||
541 | 0x32, 0x02, | ||
542 | 0x00, 0x00 | ||
543 | }; | ||
544 | |||
545 | static int saa7115_odd_parity(u8 c) | ||
546 | { | ||
547 | c ^= (c >> 4); | ||
548 | c ^= (c >> 2); | ||
549 | c ^= (c >> 1); | ||
550 | |||
551 | return c & 1; | ||
552 | } | ||
553 | |||
554 | static int saa7115_decode_vps(u8 * dst, u8 * p) | ||
555 | { | ||
556 | static const u8 biphase_tbl[] = { | ||
557 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, | ||
558 | 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, | ||
559 | 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96, | ||
560 | 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2, | ||
561 | 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94, | ||
562 | 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0, | ||
563 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, | ||
564 | 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, | ||
565 | 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5, | ||
566 | 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1, | ||
567 | 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87, | ||
568 | 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3, | ||
569 | 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85, | ||
570 | 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1, | ||
571 | 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5, | ||
572 | 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1, | ||
573 | 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4, | ||
574 | 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0, | ||
575 | 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86, | ||
576 | 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2, | ||
577 | 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84, | ||
578 | 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0, | ||
579 | 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4, | ||
580 | 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0, | ||
581 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, | ||
582 | 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, | ||
583 | 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96, | ||
584 | 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2, | ||
585 | 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94, | ||
586 | 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0, | ||
587 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, | ||
588 | 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, | ||
589 | }; | ||
590 | int i; | ||
591 | u8 c, err = 0; | ||
592 | |||
593 | for (i = 0; i < 2 * 13; i += 2) { | ||
594 | err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]]; | ||
595 | c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4); | ||
596 | dst[i / 2] = c; | ||
597 | } | ||
598 | return err & 0xf0; | ||
599 | } | ||
600 | |||
601 | static int saa7115_decode_wss(u8 * p) | ||
602 | { | ||
603 | static const int wss_bits[8] = { | ||
604 | 0, 0, 0, 1, 0, 1, 1, 1 | ||
605 | }; | ||
606 | unsigned char parity; | ||
607 | int wss = 0; | ||
608 | int i; | ||
609 | |||
610 | for (i = 0; i < 16; i++) { | ||
611 | int b1 = wss_bits[p[i] & 7]; | ||
612 | int b2 = wss_bits[(p[i] >> 3) & 7]; | ||
613 | |||
614 | if (b1 == b2) | ||
615 | return -1; | ||
616 | wss |= b2 << i; | ||
617 | } | ||
618 | parity = wss & 15; | ||
619 | parity ^= parity >> 2; | ||
620 | parity ^= parity >> 1; | ||
621 | |||
622 | if (!(parity & 1)) | ||
623 | return -1; | ||
624 | |||
625 | return wss; | ||
626 | } | ||
627 | |||
628 | |||
629 | static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq) | ||
630 | { | ||
631 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
632 | |||
633 | saa7115_dbg("set audio clock freq: %d\n", freq); | ||
634 | switch (freq) { | ||
635 | case V4L2_AUDCLK_32_KHZ: | ||
636 | saa7115_writeregs(client, saa7115_cfg_32_audio); | ||
637 | if (state->std & V4L2_STD_525_60) { | ||
638 | saa7115_writeregs(client, saa7115_cfg_60hz_32_audio); | ||
639 | } else { | ||
640 | saa7115_writeregs(client, saa7115_cfg_50hz_32_audio); | ||
641 | } | ||
642 | break; | ||
643 | case V4L2_AUDCLK_441_KHZ: | ||
644 | saa7115_writeregs(client, saa7115_cfg_441_audio); | ||
645 | if (state->std & V4L2_STD_525_60) { | ||
646 | saa7115_writeregs(client, saa7115_cfg_60hz_441_audio); | ||
647 | } else { | ||
648 | saa7115_writeregs(client, saa7115_cfg_50hz_441_audio); | ||
649 | } | ||
650 | break; | ||
651 | case V4L2_AUDCLK_48_KHZ: | ||
652 | saa7115_writeregs(client, saa7115_cfg_48_audio); | ||
653 | if (state->std & V4L2_STD_525_60) { | ||
654 | saa7115_writeregs(client, saa7115_cfg_60hz_48_audio); | ||
655 | } else { | ||
656 | saa7115_writeregs(client, saa7115_cfg_50hz_48_audio); | ||
657 | } | ||
658 | break; | ||
659 | default: | ||
660 | saa7115_dbg("invalid audio setting %d\n", freq); | ||
661 | return -EINVAL; | ||
662 | } | ||
663 | state->audclk_freq = freq; | ||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
668 | { | ||
669 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
670 | |||
671 | switch (ctrl->id) { | ||
672 | case V4L2_CID_BRIGHTNESS: | ||
673 | if (ctrl->value < 0 || ctrl->value > 255) { | ||
674 | saa7115_err("invalid brightness setting %d\n", ctrl->value); | ||
675 | return -ERANGE; | ||
676 | } | ||
677 | |||
678 | state->bright = ctrl->value; | ||
679 | saa7115_write(client, 0x0a, state->bright); | ||
680 | break; | ||
681 | |||
682 | case V4L2_CID_CONTRAST: | ||
683 | if (ctrl->value < 0 || ctrl->value > 127) { | ||
684 | saa7115_err("invalid contrast setting %d\n", ctrl->value); | ||
685 | return -ERANGE; | ||
686 | } | ||
687 | |||
688 | state->contrast = ctrl->value; | ||
689 | saa7115_write(client, 0x0b, state->contrast); | ||
690 | break; | ||
691 | |||
692 | case V4L2_CID_SATURATION: | ||
693 | if (ctrl->value < 0 || ctrl->value > 127) { | ||
694 | saa7115_err("invalid saturation setting %d\n", ctrl->value); | ||
695 | return -ERANGE; | ||
696 | } | ||
697 | |||
698 | state->sat = ctrl->value; | ||
699 | saa7115_write(client, 0x0c, state->sat); | ||
700 | break; | ||
701 | |||
702 | case V4L2_CID_HUE: | ||
703 | if (ctrl->value < -127 || ctrl->value > 127) { | ||
704 | saa7115_err("invalid hue setting %d\n", ctrl->value); | ||
705 | return -ERANGE; | ||
706 | } | ||
707 | |||
708 | state->hue = ctrl->value; | ||
709 | saa7115_write(client, 0x0d, state->hue); | ||
710 | break; | ||
711 | } | ||
712 | |||
713 | return 0; | ||
714 | } | ||
715 | |||
716 | static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
717 | { | ||
718 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
719 | |||
720 | switch (ctrl->id) { | ||
721 | case V4L2_CID_BRIGHTNESS: | ||
722 | ctrl->value = state->bright; | ||
723 | break; | ||
724 | case V4L2_CID_CONTRAST: | ||
725 | ctrl->value = state->contrast; | ||
726 | break; | ||
727 | case V4L2_CID_SATURATION: | ||
728 | ctrl->value = state->sat; | ||
729 | break; | ||
730 | case V4L2_CID_HUE: | ||
731 | ctrl->value = state->hue; | ||
732 | break; | ||
733 | default: | ||
734 | return -EINVAL; | ||
735 | } | ||
736 | |||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std) | ||
741 | { | ||
742 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
743 | int taskb = saa7115_read(client, 0x80) & 0x10; | ||
744 | |||
745 | // This works for NTSC-M, SECAM-L and the 50Hz PAL variants. | ||
746 | if (std & V4L2_STD_525_60) { | ||
747 | saa7115_dbg("decoder set standard 60 Hz\n"); | ||
748 | saa7115_writeregs(client, saa7115_cfg_60hz_video); | ||
749 | } else { | ||
750 | saa7115_dbg("decoder set standard 50 Hz\n"); | ||
751 | saa7115_writeregs(client, saa7115_cfg_50hz_video); | ||
752 | } | ||
753 | |||
754 | state->std = std; | ||
755 | |||
756 | /* restart task B if needed */ | ||
757 | if (taskb && state->ident == V4L2_IDENT_SAA7114) { | ||
758 | saa7115_writeregs(client, saa7115_cfg_vbi_on); | ||
759 | } | ||
760 | |||
761 | /* switch audio mode too! */ | ||
762 | saa7115_set_audio_clock_freq(client, state->audclk_freq); | ||
763 | } | ||
764 | |||
765 | static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client) | ||
766 | { | ||
767 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
768 | |||
769 | return state->std; | ||
770 | } | ||
771 | |||
772 | static void saa7115_log_status(struct i2c_client *client) | ||
773 | { | ||
774 | static const char * const audclk_freq_strs[] = { | ||
775 | "44.1 kHz", | ||
776 | "48 kHz", | ||
777 | "32 kHz" | ||
778 | }; | ||
779 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
780 | int reg1e, reg1f; | ||
781 | int signalOk; | ||
782 | int vcr; | ||
783 | |||
784 | saa7115_info("Audio frequency: %s\n", audclk_freq_strs[state->audclk_freq]); | ||
785 | if (client->name[6] == '4') { | ||
786 | /* status for the saa7114 */ | ||
787 | reg1f = saa7115_read(client, 0x1f); | ||
788 | signalOk = (reg1f & 0xc1) == 0x81; | ||
789 | saa7115_info("Video signal: %s\n", signalOk ? "ok" : "bad"); | ||
790 | saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); | ||
791 | return; | ||
792 | } | ||
793 | |||
794 | /* status for the saa7115 */ | ||
795 | reg1e = saa7115_read(client, 0x1e); | ||
796 | reg1f = saa7115_read(client, 0x1f); | ||
797 | |||
798 | signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80; | ||
799 | vcr = !(reg1f & 0x10); | ||
800 | |||
801 | saa7115_info("Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad"); | ||
802 | saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); | ||
803 | |||
804 | switch (reg1e & 0x03) { | ||
805 | case 1: | ||
806 | saa7115_info("Detected format: NTSC\n"); | ||
807 | break; | ||
808 | case 2: | ||
809 | saa7115_info("Detected format: PAL\n"); | ||
810 | break; | ||
811 | case 3: | ||
812 | saa7115_info("Detected format: SECAM\n"); | ||
813 | break; | ||
814 | default: | ||
815 | saa7115_info("Detected format: BW/No color\n"); | ||
816 | break; | ||
817 | } | ||
818 | } | ||
819 | |||
820 | /* setup the sliced VBI lcr registers according to the sliced VBI format */ | ||
821 | static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt) | ||
822 | { | ||
823 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
824 | int is_50hz = (state->std & V4L2_STD_625_50); | ||
825 | u8 lcr[24]; | ||
826 | int i, x; | ||
827 | |||
828 | /* saa7114 doesn't yet support VBI */ | ||
829 | if (state->ident == V4L2_IDENT_SAA7114) | ||
830 | return; | ||
831 | |||
832 | for (i = 0; i <= 23; i++) | ||
833 | lcr[i] = 0xff; | ||
834 | |||
835 | if (fmt->service_set == 0) { | ||
836 | /* raw VBI */ | ||
837 | if (is_50hz) | ||
838 | for (i = 6; i <= 23; i++) | ||
839 | lcr[i] = 0xdd; | ||
840 | else | ||
841 | for (i = 10; i <= 21; i++) | ||
842 | lcr[i] = 0xdd; | ||
843 | } else { | ||
844 | /* sliced VBI */ | ||
845 | /* first clear lines that cannot be captured */ | ||
846 | if (is_50hz) { | ||
847 | for (i = 0; i <= 5; i++) | ||
848 | fmt->service_lines[0][i] = | ||
849 | fmt->service_lines[1][i] = 0; | ||
850 | } | ||
851 | else { | ||
852 | for (i = 0; i <= 9; i++) | ||
853 | fmt->service_lines[0][i] = | ||
854 | fmt->service_lines[1][i] = 0; | ||
855 | for (i = 22; i <= 23; i++) | ||
856 | fmt->service_lines[0][i] = | ||
857 | fmt->service_lines[1][i] = 0; | ||
858 | } | ||
859 | |||
860 | /* Now set the lcr values according to the specified service */ | ||
861 | for (i = 6; i <= 23; i++) { | ||
862 | lcr[i] = 0; | ||
863 | for (x = 0; x <= 1; x++) { | ||
864 | switch (fmt->service_lines[1-x][i]) { | ||
865 | case 0: | ||
866 | lcr[i] |= 0xf << (4 * x); | ||
867 | break; | ||
868 | case V4L2_SLICED_TELETEXT_B: | ||
869 | lcr[i] |= 1 << (4 * x); | ||
870 | break; | ||
871 | case V4L2_SLICED_CAPTION_525: | ||
872 | lcr[i] |= 4 << (4 * x); | ||
873 | break; | ||
874 | case V4L2_SLICED_WSS_625: | ||
875 | lcr[i] |= 5 << (4 * x); | ||
876 | break; | ||
877 | case V4L2_SLICED_VPS: | ||
878 | lcr[i] |= 7 << (4 * x); | ||
879 | break; | ||
880 | } | ||
881 | } | ||
882 | } | ||
883 | } | ||
884 | |||
885 | /* write the lcr registers */ | ||
886 | for (i = 2; i <= 23; i++) { | ||
887 | saa7115_write(client, i - 2 + 0x41, lcr[i]); | ||
888 | } | ||
889 | |||
890 | /* enable/disable raw VBI capturing */ | ||
891 | saa7115_writeregs(client, fmt->service_set == 0 ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off); | ||
892 | } | ||
893 | |||
894 | static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | ||
895 | { | ||
896 | static u16 lcr2vbi[] = { | ||
897 | 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ | ||
898 | 0, V4L2_SLICED_CAPTION_525, /* 4 */ | ||
899 | V4L2_SLICED_WSS_625, 0, /* 5 */ | ||
900 | V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */ | ||
901 | 0, 0, 0, 0 | ||
902 | }; | ||
903 | struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced; | ||
904 | int i; | ||
905 | |||
906 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | ||
907 | return -EINVAL; | ||
908 | memset(sliced, 0, sizeof(*sliced)); | ||
909 | /* done if using raw VBI */ | ||
910 | if (saa7115_read(client, 0x80) & 0x10) | ||
911 | return 0; | ||
912 | for (i = 2; i <= 23; i++) { | ||
913 | u8 v = saa7115_read(client, i - 2 + 0x41); | ||
914 | |||
915 | sliced->service_lines[0][i] = lcr2vbi[v >> 4]; | ||
916 | sliced->service_lines[1][i] = lcr2vbi[v & 0xf]; | ||
917 | sliced->service_set |= | ||
918 | sliced->service_lines[0][i] | sliced->service_lines[1][i]; | ||
919 | } | ||
920 | return 0; | ||
921 | } | ||
922 | |||
923 | static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | ||
924 | { | ||
925 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
926 | struct v4l2_pix_format *pix; | ||
927 | int HPSC, HFSC; | ||
928 | int VSCY, Vsrc; | ||
929 | int is_50hz = state->std & V4L2_STD_625_50; | ||
930 | |||
931 | if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { | ||
932 | saa7115_set_lcr(client, &fmt->fmt.sliced); | ||
933 | return 0; | ||
934 | } | ||
935 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
936 | return -EINVAL; | ||
937 | |||
938 | pix = &(fmt->fmt.pix); | ||
939 | |||
940 | saa7115_dbg("decoder set size\n"); | ||
941 | |||
942 | /* FIXME need better bounds checking here */ | ||
943 | if ((pix->width < 1) || (pix->width > 1440)) | ||
944 | return -EINVAL; | ||
945 | if ((pix->height < 1) || (pix->height > 960)) | ||
946 | return -EINVAL; | ||
947 | |||
948 | /* probably have a valid size, let's set it */ | ||
949 | /* Set output width/height */ | ||
950 | /* width */ | ||
951 | saa7115_write(client, 0xcc, (u8) (pix->width & 0xff)); | ||
952 | saa7115_write(client, 0xcd, (u8) ((pix->width >> 8) & 0xff)); | ||
953 | /* height */ | ||
954 | saa7115_write(client, 0xce, (u8) (pix->height & 0xff)); | ||
955 | saa7115_write(client, 0xcf, (u8) ((pix->height >> 8) & 0xff)); | ||
956 | |||
957 | /* Scaling settings */ | ||
958 | /* Hprescaler is floor(inres/outres) */ | ||
959 | /* FIXME hardcoding input res */ | ||
960 | if (pix->width != 720) { | ||
961 | HPSC = (int)(720 / pix->width); | ||
962 | /* 0 is not allowed (div. by zero) */ | ||
963 | HPSC = HPSC ? HPSC : 1; | ||
964 | HFSC = (int)((1024 * 720) / (HPSC * pix->width)); | ||
965 | |||
966 | saa7115_dbg("Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); | ||
967 | /* FIXME hardcodes to "Task B" | ||
968 | * write H prescaler integer */ | ||
969 | saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f)); | ||
970 | |||
971 | /* write H fine-scaling (luminance) */ | ||
972 | saa7115_write(client, 0xd8, (u8) (HFSC & 0xff)); | ||
973 | saa7115_write(client, 0xd9, (u8) ((HFSC >> 8) & 0xff)); | ||
974 | /* write H fine-scaling (chrominance) | ||
975 | * must be lum/2, so i'll just bitshift :) */ | ||
976 | saa7115_write(client, 0xDC, (u8) ((HFSC >> 1) & 0xff)); | ||
977 | saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff)); | ||
978 | } else { | ||
979 | if (is_50hz) { | ||
980 | saa7115_dbg("Setting full 50hz width\n"); | ||
981 | saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x); | ||
982 | } else { | ||
983 | saa7115_dbg("Setting full 60hz width\n"); | ||
984 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); | ||
985 | } | ||
986 | } | ||
987 | |||
988 | Vsrc = is_50hz ? 576 : 480; | ||
989 | |||
990 | if (pix->height != Vsrc) { | ||
991 | VSCY = (int)((1024 * Vsrc) / pix->height); | ||
992 | saa7115_dbg("Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY); | ||
993 | |||
994 | /* Correct Contrast and Luminance */ | ||
995 | saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY)); | ||
996 | saa7115_write(client, 0xd6, (u8) (64 * 1024 / VSCY)); | ||
997 | |||
998 | /* write V fine-scaling (luminance) */ | ||
999 | saa7115_write(client, 0xe0, (u8) (VSCY & 0xff)); | ||
1000 | saa7115_write(client, 0xe1, (u8) ((VSCY >> 8) & 0xff)); | ||
1001 | /* write V fine-scaling (chrominance) */ | ||
1002 | saa7115_write(client, 0xe2, (u8) (VSCY & 0xff)); | ||
1003 | saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff)); | ||
1004 | } else { | ||
1005 | if (is_50hz) { | ||
1006 | saa7115_dbg("Setting full 50Hz height\n"); | ||
1007 | saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y); | ||
1008 | } else { | ||
1009 | saa7115_dbg("Setting full 60hz height\n"); | ||
1010 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); | ||
1011 | } | ||
1012 | } | ||
1013 | |||
1014 | saa7115_writeregs(client, saa7115_cfg_reset_scaler); | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | /* Decode the sliced VBI data stream as created by the saa7115. | ||
1019 | The format is described in the saa7115 datasheet in Tables 25 and 26 | ||
1020 | and in Figure 33. | ||
1021 | The current implementation uses SAV/EAV codes and not the ancillary data | ||
1022 | headers. The vbi->p pointer points to the SDID byte right after the SAV | ||
1023 | code. */ | ||
1024 | static void saa7115_decode_vbi_line(struct i2c_client *client, | ||
1025 | struct v4l2_decode_vbi_line *vbi) | ||
1026 | { | ||
1027 | static const char vbi_no_data_pattern[] = { | ||
1028 | 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0 | ||
1029 | }; | ||
1030 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
1031 | u8 *p = vbi->p; | ||
1032 | u32 wss; | ||
1033 | int id1, id2; /* the ID1 and ID2 bytes from the internal header */ | ||
1034 | |||
1035 | vbi->type = 0; /* mark result as a failure */ | ||
1036 | id1 = p[2]; | ||
1037 | id2 = p[3]; | ||
1038 | /* Note: the field bit is inverted for 60 Hz video */ | ||
1039 | if (state->std & V4L2_STD_525_60) | ||
1040 | id1 ^= 0x40; | ||
1041 | |||
1042 | /* Skip internal header, p now points to the start of the payload */ | ||
1043 | p += 4; | ||
1044 | vbi->p = p; | ||
1045 | |||
1046 | /* calculate field and line number of the VBI packet (1-23) */ | ||
1047 | vbi->is_second_field = ((id1 & 0x40) != 0); | ||
1048 | vbi->line = (id1 & 0x3f) << 3; | ||
1049 | vbi->line |= (id2 & 0x70) >> 4; | ||
1050 | |||
1051 | /* Obtain data type */ | ||
1052 | id2 &= 0xf; | ||
1053 | |||
1054 | /* If the VBI slicer does not detect any signal it will fill up | ||
1055 | the payload buffer with 0xa0 bytes. */ | ||
1056 | if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern))) | ||
1057 | return; | ||
1058 | |||
1059 | /* decode payloads */ | ||
1060 | switch (id2) { | ||
1061 | case 1: | ||
1062 | vbi->type = V4L2_SLICED_TELETEXT_B; | ||
1063 | break; | ||
1064 | case 4: | ||
1065 | if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1])) | ||
1066 | return; | ||
1067 | vbi->type = V4L2_SLICED_CAPTION_525; | ||
1068 | break; | ||
1069 | case 5: | ||
1070 | wss = saa7115_decode_wss(p); | ||
1071 | if (wss == -1) | ||
1072 | return; | ||
1073 | p[0] = wss & 0xff; | ||
1074 | p[1] = wss >> 8; | ||
1075 | vbi->type = V4L2_SLICED_WSS_625; | ||
1076 | break; | ||
1077 | case 7: | ||
1078 | if (saa7115_decode_vps(p, p) != 0) | ||
1079 | return; | ||
1080 | vbi->type = V4L2_SLICED_VPS; | ||
1081 | break; | ||
1082 | default: | ||
1083 | return; | ||
1084 | } | ||
1085 | } | ||
1086 | |||
1087 | /* ============ SAA7115 AUDIO settings (end) ============= */ | ||
1088 | |||
1089 | static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) | ||
1090 | { | ||
1091 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
1092 | int *iarg = arg; | ||
1093 | |||
1094 | /* ioctls to allow direct access to the saa7115 registers for testing */ | ||
1095 | switch (cmd) { | ||
1096 | case VIDIOC_S_FMT: | ||
1097 | return saa7115_set_v4lfmt(client, (struct v4l2_format *)arg); | ||
1098 | |||
1099 | case VIDIOC_G_FMT: | ||
1100 | return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg); | ||
1101 | |||
1102 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | ||
1103 | return saa7115_set_audio_clock_freq(client, *(enum v4l2_audio_clock_freq *)arg); | ||
1104 | |||
1105 | case VIDIOC_G_TUNER: | ||
1106 | { | ||
1107 | struct v4l2_tuner *vt = arg; | ||
1108 | int status; | ||
1109 | |||
1110 | status = saa7115_read(client, 0x1f); | ||
1111 | |||
1112 | saa7115_dbg("status: 0x%02x\n", status); | ||
1113 | vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0; | ||
1114 | break; | ||
1115 | } | ||
1116 | |||
1117 | case VIDIOC_LOG_STATUS: | ||
1118 | saa7115_log_status(client); | ||
1119 | break; | ||
1120 | |||
1121 | case VIDIOC_G_CTRL: | ||
1122 | return saa7115_get_v4lctrl(client, (struct v4l2_control *)arg); | ||
1123 | |||
1124 | case VIDIOC_S_CTRL: | ||
1125 | return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg); | ||
1126 | |||
1127 | case VIDIOC_G_STD: | ||
1128 | *(v4l2_std_id *)arg = saa7115_get_v4lstd(client); | ||
1129 | break; | ||
1130 | |||
1131 | case VIDIOC_S_STD: | ||
1132 | saa7115_set_v4lstd(client, *(v4l2_std_id *)arg); | ||
1133 | break; | ||
1134 | |||
1135 | case VIDIOC_G_INPUT: | ||
1136 | *(int *)arg = state->input; | ||
1137 | break; | ||
1138 | |||
1139 | case VIDIOC_S_INPUT: | ||
1140 | saa7115_dbg("decoder set input %d\n", *iarg); | ||
1141 | /* inputs from 0-9 are available */ | ||
1142 | if (*iarg < 0 || *iarg > 9) { | ||
1143 | return -EINVAL; | ||
1144 | } | ||
1145 | |||
1146 | if (state->input == *iarg) | ||
1147 | break; | ||
1148 | saa7115_dbg("now setting %s input\n", | ||
1149 | *iarg >= 6 ? "S-Video" : "Composite"); | ||
1150 | state->input = *iarg; | ||
1151 | |||
1152 | /* select mode */ | ||
1153 | saa7115_write(client, 0x02, | ||
1154 | (saa7115_read(client, 0x02) & 0xf0) | | ||
1155 | state->input); | ||
1156 | |||
1157 | /* bypass chrominance trap for modes 6..9 */ | ||
1158 | saa7115_write(client, 0x09, | ||
1159 | (saa7115_read(client, 0x09) & 0x7f) | | ||
1160 | (state->input < 6 ? 0x0 : 0x80)); | ||
1161 | break; | ||
1162 | |||
1163 | case VIDIOC_STREAMON: | ||
1164 | case VIDIOC_STREAMOFF: | ||
1165 | saa7115_dbg("%s output\n", | ||
1166 | (cmd == VIDIOC_STREAMON) ? "enable" : "disable"); | ||
1167 | |||
1168 | if (state->enable != (cmd == VIDIOC_STREAMON)) { | ||
1169 | state->enable = (cmd == VIDIOC_STREAMON); | ||
1170 | saa7115_write(client, 0x87, state->enable); | ||
1171 | } | ||
1172 | break; | ||
1173 | |||
1174 | case VIDIOC_INT_DECODE_VBI_LINE: | ||
1175 | saa7115_decode_vbi_line(client, arg); | ||
1176 | break; | ||
1177 | |||
1178 | case VIDIOC_INT_RESET: | ||
1179 | saa7115_dbg("decoder RESET\n"); | ||
1180 | saa7115_writeregs(client, saa7115_cfg_reset_scaler); | ||
1181 | break; | ||
1182 | |||
1183 | case VIDIOC_INT_G_VBI_DATA: | ||
1184 | { | ||
1185 | struct v4l2_sliced_vbi_data *data = arg; | ||
1186 | |||
1187 | switch (data->id) { | ||
1188 | case V4L2_SLICED_WSS_625: | ||
1189 | if (saa7115_read(client, 0x6b) & 0xc0) | ||
1190 | return -EIO; | ||
1191 | data->data[0] = saa7115_read(client, 0x6c); | ||
1192 | data->data[1] = saa7115_read(client, 0x6d); | ||
1193 | return 0; | ||
1194 | case V4L2_SLICED_CAPTION_525: | ||
1195 | if (data->field == 0) { | ||
1196 | /* CC */ | ||
1197 | if (saa7115_read(client, 0x66) & 0xc0) | ||
1198 | return -EIO; | ||
1199 | data->data[0] = saa7115_read(client, 0x67); | ||
1200 | data->data[1] = saa7115_read(client, 0x68); | ||
1201 | return 0; | ||
1202 | } | ||
1203 | /* XDS */ | ||
1204 | if (saa7115_read(client, 0x66) & 0x30) | ||
1205 | return -EIO; | ||
1206 | data->data[0] = saa7115_read(client, 0x69); | ||
1207 | data->data[1] = saa7115_read(client, 0x6a); | ||
1208 | return 0; | ||
1209 | default: | ||
1210 | return -EINVAL; | ||
1211 | } | ||
1212 | break; | ||
1213 | } | ||
1214 | |||
1215 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1216 | case VIDIOC_INT_G_REGISTER: | ||
1217 | { | ||
1218 | struct v4l2_register *reg = arg; | ||
1219 | |||
1220 | if (reg->i2c_id != I2C_DRIVERID_SAA711X) | ||
1221 | return -EINVAL; | ||
1222 | reg->val = saa7115_read(client, reg->reg & 0xff); | ||
1223 | break; | ||
1224 | } | ||
1225 | |||
1226 | case VIDIOC_INT_S_REGISTER: | ||
1227 | { | ||
1228 | struct v4l2_register *reg = arg; | ||
1229 | |||
1230 | if (reg->i2c_id != I2C_DRIVERID_SAA711X) | ||
1231 | return -EINVAL; | ||
1232 | if (!capable(CAP_SYS_ADMIN)) | ||
1233 | return -EPERM; | ||
1234 | saa7115_write(client, reg->reg & 0xff, reg->val & 0xff); | ||
1235 | break; | ||
1236 | } | ||
1237 | #endif | ||
1238 | |||
1239 | case VIDIOC_INT_G_CHIP_IDENT: | ||
1240 | *iarg = state->ident; | ||
1241 | break; | ||
1242 | |||
1243 | default: | ||
1244 | return -EINVAL; | ||
1245 | } | ||
1246 | |||
1247 | return 0; | ||
1248 | } | ||
1249 | |||
1250 | /* ----------------------------------------------------------------------- */ | ||
1251 | |||
1252 | static struct i2c_driver i2c_driver_saa7115; | ||
1253 | |||
1254 | static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | ||
1255 | { | ||
1256 | struct i2c_client *client; | ||
1257 | struct saa7115_state *state; | ||
1258 | u8 chip_id; | ||
1259 | |||
1260 | /* Check if the adapter supports the needed features */ | ||
1261 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
1262 | return 0; | ||
1263 | |||
1264 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
1265 | if (client == 0) | ||
1266 | return -ENOMEM; | ||
1267 | memset(client, 0, sizeof(struct i2c_client)); | ||
1268 | client->addr = address; | ||
1269 | client->adapter = adapter; | ||
1270 | client->driver = &i2c_driver_saa7115; | ||
1271 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
1272 | snprintf(client->name, sizeof(client->name) - 1, "saa7115"); | ||
1273 | |||
1274 | saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1); | ||
1275 | |||
1276 | saa7115_write(client, 0, 5); | ||
1277 | chip_id = saa7115_read(client, 0) & 0x0f; | ||
1278 | if (chip_id != 4 && chip_id != 5) { | ||
1279 | saa7115_dbg("saa7115 not found\n"); | ||
1280 | kfree(client); | ||
1281 | return 0; | ||
1282 | } | ||
1283 | if (chip_id == 4) { | ||
1284 | snprintf(client->name, sizeof(client->name) - 1, "saa7114"); | ||
1285 | } | ||
1286 | saa7115_info("saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); | ||
1287 | |||
1288 | state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL); | ||
1289 | i2c_set_clientdata(client, state); | ||
1290 | if (state == NULL) { | ||
1291 | kfree(client); | ||
1292 | return -ENOMEM; | ||
1293 | } | ||
1294 | memset(state, 0, sizeof(struct saa7115_state)); | ||
1295 | state->std = V4L2_STD_NTSC; | ||
1296 | state->input = -1; | ||
1297 | state->enable = 1; | ||
1298 | state->bright = 128; | ||
1299 | state->contrast = 64; | ||
1300 | state->hue = 0; | ||
1301 | state->sat = 64; | ||
1302 | state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115; | ||
1303 | state->audclk_freq = V4L2_AUDCLK_48_KHZ; | ||
1304 | |||
1305 | saa7115_dbg("writing init values\n"); | ||
1306 | |||
1307 | /* init to 60hz/48khz */ | ||
1308 | saa7115_writeregs(client, saa7115_init_auto_input); | ||
1309 | saa7115_writeregs(client, saa7115_init_misc); | ||
1310 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); | ||
1311 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); | ||
1312 | saa7115_writeregs(client, saa7115_cfg_60hz_video); | ||
1313 | saa7115_writeregs(client, saa7115_cfg_48_audio); | ||
1314 | saa7115_writeregs(client, saa7115_cfg_60hz_48_audio); | ||
1315 | saa7115_writeregs(client, saa7115_cfg_reset_scaler); | ||
1316 | |||
1317 | i2c_attach_client(client); | ||
1318 | |||
1319 | saa7115_dbg("status: (1E) 0x%02x, (1F) 0x%02x\n", | ||
1320 | saa7115_read(client, 0x1e), saa7115_read(client, 0x1f)); | ||
1321 | |||
1322 | return 0; | ||
1323 | } | ||
1324 | |||
1325 | static int saa7115_probe(struct i2c_adapter *adapter) | ||
1326 | { | ||
1327 | #ifdef I2C_CLASS_TV_ANALOG | ||
1328 | if (adapter->class & I2C_CLASS_TV_ANALOG) | ||
1329 | #else | ||
1330 | if (adapter->id == I2C_HW_B_BT848) | ||
1331 | #endif | ||
1332 | return i2c_probe(adapter, &addr_data, &saa7115_attach); | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | static int saa7115_detach(struct i2c_client *client) | ||
1337 | { | ||
1338 | struct saa7115_state *state = i2c_get_clientdata(client); | ||
1339 | int err; | ||
1340 | |||
1341 | err = i2c_detach_client(client); | ||
1342 | if (err) { | ||
1343 | return err; | ||
1344 | } | ||
1345 | |||
1346 | kfree(state); | ||
1347 | kfree(client); | ||
1348 | return 0; | ||
1349 | } | ||
1350 | |||
1351 | /* ----------------------------------------------------------------------- */ | ||
1352 | |||
1353 | /* i2c implementation */ | ||
1354 | static struct i2c_driver i2c_driver_saa7115 = { | ||
1355 | .name = "saa7115", | ||
1356 | .id = I2C_DRIVERID_SAA711X, | ||
1357 | .flags = I2C_DF_NOTIFY, | ||
1358 | .attach_adapter = saa7115_probe, | ||
1359 | .detach_client = saa7115_detach, | ||
1360 | .command = saa7115_command, | ||
1361 | .owner = THIS_MODULE, | ||
1362 | }; | ||
1363 | |||
1364 | |||
1365 | static int __init saa7115_init_module(void) | ||
1366 | { | ||
1367 | return i2c_add_driver(&i2c_driver_saa7115); | ||
1368 | } | ||
1369 | |||
1370 | static void __exit saa7115_cleanup_module(void) | ||
1371 | { | ||
1372 | i2c_del_driver(&i2c_driver_saa7115); | ||
1373 | } | ||
1374 | |||
1375 | module_init(saa7115_init_module); | ||
1376 | module_exit(saa7115_cleanup_module); | ||
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c index 9aa8827de2c3..25b30f352d84 100644 --- a/drivers/media/video/saa711x.c +++ b/drivers/media/video/saa711x.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
37 | #include <asm/page.h> | 37 | #include <asm/page.h> |
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <asm/segment.h> | ||
40 | #include <linux/types.h> | 39 | #include <linux/types.h> |
41 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
42 | #include <linux/videodev.h> | 41 | #include <linux/videodev.h> |
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c new file mode 100644 index 000000000000..843431f10e3b --- /dev/null +++ b/drivers/media/video/saa7127.c | |||
@@ -0,0 +1,849 @@ | |||
1 | /* | ||
2 | * saa7127 - Philips SAA7127/SAA7129 video encoder driver | ||
3 | * | ||
4 | * Copyright (C) 2003 Roy Bulter <rbulter@hetnet.nl> | ||
5 | * | ||
6 | * Based on SAA7126 video encoder driver by Gillem & Andreas Oberritter | ||
7 | * | ||
8 | * Copyright (C) 2000-2001 Gillem <htoa@gmx.net> | ||
9 | * Copyright (C) 2002 Andreas Oberritter <obi@saftware.de> | ||
10 | * | ||
11 | * Based on Stadis 4:2:2 MPEG-2 Decoder Driver by Nathan Laredo | ||
12 | * | ||
13 | * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org> | ||
14 | * | ||
15 | * This driver is designed for the Hauppauge 250/350 Linux driver | ||
16 | * from the ivtv Project | ||
17 | * | ||
18 | * Copyright (C) 2003 Kevin Thayer <nufan_wfk@yahoo.com> | ||
19 | * | ||
20 | * Dual output support: | ||
21 | * Copyright (C) 2004 Eric Varsanyi | ||
22 | * | ||
23 | * NTSC Tuning and 7.5 IRE Setup | ||
24 | * Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
25 | * | ||
26 | * VBI additions & cleanup: | ||
27 | * Copyright (C) 2004, 2005 Hans Verkuil <hverkuil@xs4all.nl> | ||
28 | * | ||
29 | * Note: the saa7126 is identical to the saa7127, and the saa7128 is | ||
30 | * identical to the saa7129, except that the saa7126 and saa7128 have | ||
31 | * macrovision anti-taping support. This driver will almost certainly | ||
32 | * work find for those chips, except of course for the missing anti-taping | ||
33 | * support. | ||
34 | * | ||
35 | * This program is free software; you can redistribute it and/or modify | ||
36 | * it under the terms of the GNU General Public License as published by | ||
37 | * the Free Software Foundation; either version 2 of the License, or | ||
38 | * (at your option) any later version. | ||
39 | * | ||
40 | * This program is distributed in the hope that it will be useful, | ||
41 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
42 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
43 | * GNU General Public License for more details. | ||
44 | * | ||
45 | * You should have received a copy of the GNU General Public License | ||
46 | * along with this program; if not, write to the Free Software | ||
47 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
48 | */ | ||
49 | |||
50 | |||
51 | #include <linux/kernel.h> | ||
52 | #include <linux/module.h> | ||
53 | #include <linux/slab.h> | ||
54 | #include <linux/i2c.h> | ||
55 | #include <linux/videodev2.h> | ||
56 | #include <media/v4l2-common.h> | ||
57 | |||
58 | static int debug = 0; | ||
59 | static int test_image = 0; | ||
60 | |||
61 | MODULE_DESCRIPTION("Philips SAA7127/9 video encoder driver"); | ||
62 | MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); | ||
63 | MODULE_LICENSE("GPL"); | ||
64 | module_param(debug, int, 0644); | ||
65 | module_param(test_image, int, 0644); | ||
66 | MODULE_PARM_DESC(debug, "debug level (0-2)"); | ||
67 | MODULE_PARM_DESC(test_image, "test_image (0-1)"); | ||
68 | |||
69 | #define saa7127_dbg(fmt, arg...) \ | ||
70 | do { \ | ||
71 | if (debug >= 1) \ | ||
72 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
73 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
74 | } while (0) | ||
75 | |||
76 | /* High volume debug. Use with care. */ | ||
77 | #define saa7127_dbg_highvol(fmt, arg...) \ | ||
78 | do { \ | ||
79 | if (debug == 2) \ | ||
80 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
81 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
82 | } while (0) | ||
83 | |||
84 | #define saa7127_err(fmt, arg...) do { \ | ||
85 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | ||
86 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
87 | #define saa7127_info(fmt, arg...) do { \ | ||
88 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | ||
89 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
90 | |||
91 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | ||
92 | |||
93 | |||
94 | I2C_CLIENT_INSMOD; | ||
95 | |||
96 | /* | ||
97 | * SAA7127 registers | ||
98 | */ | ||
99 | |||
100 | #define SAA7127_REG_STATUS 0x00 | ||
101 | #define SAA7127_REG_WIDESCREEN_CONFIG 0x26 | ||
102 | #define SAA7127_REG_WIDESCREEN_ENABLE 0x27 | ||
103 | #define SAA7127_REG_BURST_START 0x28 | ||
104 | #define SAA7127_REG_BURST_END 0x29 | ||
105 | #define SAA7127_REG_COPYGEN_0 0x2a | ||
106 | #define SAA7127_REG_COPYGEN_1 0x2b | ||
107 | #define SAA7127_REG_COPYGEN_2 0x2c | ||
108 | #define SAA7127_REG_OUTPUT_PORT_CONTROL 0x2d | ||
109 | #define SAA7127_REG_GAIN_LUMINANCE_RGB 0x38 | ||
110 | #define SAA7127_REG_GAIN_COLORDIFF_RGB 0x39 | ||
111 | #define SAA7127_REG_INPUT_PORT_CONTROL_1 0x3a | ||
112 | #define SAA7129_REG_FADE_KEY_COL2 0x4f | ||
113 | #define SAA7127_REG_CHROMA_PHASE 0x5a | ||
114 | #define SAA7127_REG_GAINU 0x5b | ||
115 | #define SAA7127_REG_GAINV 0x5c | ||
116 | #define SAA7127_REG_BLACK_LEVEL 0x5d | ||
117 | #define SAA7127_REG_BLANKING_LEVEL 0x5e | ||
118 | #define SAA7127_REG_VBI_BLANKING 0x5f | ||
119 | #define SAA7127_REG_DAC_CONTROL 0x61 | ||
120 | #define SAA7127_REG_BURST_AMP 0x62 | ||
121 | #define SAA7127_REG_SUBC3 0x63 | ||
122 | #define SAA7127_REG_SUBC2 0x64 | ||
123 | #define SAA7127_REG_SUBC1 0x65 | ||
124 | #define SAA7127_REG_SUBC0 0x66 | ||
125 | #define SAA7127_REG_LINE_21_ODD_0 0x67 | ||
126 | #define SAA7127_REG_LINE_21_ODD_1 0x68 | ||
127 | #define SAA7127_REG_LINE_21_EVEN_0 0x69 | ||
128 | #define SAA7127_REG_LINE_21_EVEN_1 0x6a | ||
129 | #define SAA7127_REG_RCV_PORT_CONTROL 0x6b | ||
130 | #define SAA7127_REG_VTRIG 0x6c | ||
131 | #define SAA7127_REG_HTRIG_HI 0x6d | ||
132 | #define SAA7127_REG_MULTI 0x6e | ||
133 | #define SAA7127_REG_CLOSED_CAPTION 0x6f | ||
134 | #define SAA7127_REG_RCV2_OUTPUT_START 0x70 | ||
135 | #define SAA7127_REG_RCV2_OUTPUT_END 0x71 | ||
136 | #define SAA7127_REG_RCV2_OUTPUT_MSBS 0x72 | ||
137 | #define SAA7127_REG_TTX_REQUEST_H_START 0x73 | ||
138 | #define SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH 0x74 | ||
139 | #define SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT 0x75 | ||
140 | #define SAA7127_REG_TTX_ODD_REQ_VERT_START 0x76 | ||
141 | #define SAA7127_REG_TTX_ODD_REQ_VERT_END 0x77 | ||
142 | #define SAA7127_REG_TTX_EVEN_REQ_VERT_START 0x78 | ||
143 | #define SAA7127_REG_TTX_EVEN_REQ_VERT_END 0x79 | ||
144 | #define SAA7127_REG_FIRST_ACTIVE 0x7a | ||
145 | #define SAA7127_REG_LAST_ACTIVE 0x7b | ||
146 | #define SAA7127_REG_MSB_VERTICAL 0x7c | ||
147 | #define SAA7127_REG_DISABLE_TTX_LINE_LO_0 0x7e | ||
148 | #define SAA7127_REG_DISABLE_TTX_LINE_LO_1 0x7f | ||
149 | |||
150 | /* | ||
151 | ********************************************************************** | ||
152 | * | ||
153 | * Arrays with configuration parameters for the SAA7127 | ||
154 | * | ||
155 | ********************************************************************** | ||
156 | */ | ||
157 | |||
158 | struct i2c_reg_value { | ||
159 | unsigned char reg; | ||
160 | unsigned char value; | ||
161 | }; | ||
162 | |||
163 | static const struct i2c_reg_value saa7129_init_config_extra[] = { | ||
164 | { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 }, | ||
165 | { SAA7127_REG_VTRIG, 0xfa }, | ||
166 | }; | ||
167 | |||
168 | static const struct i2c_reg_value saa7127_init_config_common[] = { | ||
169 | { SAA7127_REG_WIDESCREEN_CONFIG, 0x0d }, | ||
170 | { SAA7127_REG_WIDESCREEN_ENABLE, 0x00 }, | ||
171 | { SAA7127_REG_COPYGEN_0, 0x77 }, | ||
172 | { SAA7127_REG_COPYGEN_1, 0x41 }, | ||
173 | { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */ | ||
174 | { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e }, | ||
175 | { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 }, | ||
176 | { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 }, | ||
177 | { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */ | ||
178 | { SAA7127_REG_LINE_21_ODD_0, 0x77 }, | ||
179 | { SAA7127_REG_LINE_21_ODD_1, 0x41 }, | ||
180 | { SAA7127_REG_LINE_21_EVEN_0, 0x88 }, | ||
181 | { SAA7127_REG_LINE_21_EVEN_1, 0x41 }, | ||
182 | { SAA7127_REG_RCV_PORT_CONTROL, 0x12 }, | ||
183 | { SAA7127_REG_VTRIG, 0xf9 }, | ||
184 | { SAA7127_REG_HTRIG_HI, 0x00 }, | ||
185 | { SAA7127_REG_RCV2_OUTPUT_START, 0x41 }, | ||
186 | { SAA7127_REG_RCV2_OUTPUT_END, 0xc3 }, | ||
187 | { SAA7127_REG_RCV2_OUTPUT_MSBS, 0x00 }, | ||
188 | { SAA7127_REG_TTX_REQUEST_H_START, 0x3e }, | ||
189 | { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 0xb8 }, | ||
190 | { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT, 0x03 }, | ||
191 | { SAA7127_REG_TTX_ODD_REQ_VERT_START, 0x15 }, | ||
192 | { SAA7127_REG_TTX_ODD_REQ_VERT_END, 0x16 }, | ||
193 | { SAA7127_REG_TTX_EVEN_REQ_VERT_START, 0x15 }, | ||
194 | { SAA7127_REG_TTX_EVEN_REQ_VERT_END, 0x16 }, | ||
195 | { SAA7127_REG_FIRST_ACTIVE, 0x1a }, | ||
196 | { SAA7127_REG_LAST_ACTIVE, 0x01 }, | ||
197 | { SAA7127_REG_MSB_VERTICAL, 0xc0 }, | ||
198 | { SAA7127_REG_DISABLE_TTX_LINE_LO_0, 0x00 }, | ||
199 | { SAA7127_REG_DISABLE_TTX_LINE_LO_1, 0x00 }, | ||
200 | { 0, 0 } | ||
201 | }; | ||
202 | |||
203 | #define SAA7127_60HZ_DAC_CONTROL 0x15 | ||
204 | static const struct i2c_reg_value saa7127_init_config_60hz[] = { | ||
205 | { SAA7127_REG_BURST_START, 0x19 }, | ||
206 | /* BURST_END is also used as a chip ID in saa7127_detect_client */ | ||
207 | { SAA7127_REG_BURST_END, 0x1d }, | ||
208 | { SAA7127_REG_CHROMA_PHASE, 0xa3 }, | ||
209 | { SAA7127_REG_GAINU, 0x98 }, | ||
210 | { SAA7127_REG_GAINV, 0xd3 }, | ||
211 | { SAA7127_REG_BLACK_LEVEL, 0x39 }, | ||
212 | { SAA7127_REG_BLANKING_LEVEL, 0x2e }, | ||
213 | { SAA7127_REG_VBI_BLANKING, 0x2e }, | ||
214 | { SAA7127_REG_DAC_CONTROL, 0x15 }, | ||
215 | { SAA7127_REG_BURST_AMP, 0x4d }, | ||
216 | { SAA7127_REG_SUBC3, 0x1f }, | ||
217 | { SAA7127_REG_SUBC2, 0x7c }, | ||
218 | { SAA7127_REG_SUBC1, 0xf0 }, | ||
219 | { SAA7127_REG_SUBC0, 0x21 }, | ||
220 | { SAA7127_REG_MULTI, 0x90 }, | ||
221 | { SAA7127_REG_CLOSED_CAPTION, 0x11 }, | ||
222 | { 0, 0 } | ||
223 | }; | ||
224 | |||
225 | #define SAA7127_50HZ_DAC_CONTROL 0x02 | ||
226 | struct i2c_reg_value saa7127_init_config_50hz[] = { | ||
227 | { SAA7127_REG_BURST_START, 0x21 }, | ||
228 | /* BURST_END is also used as a chip ID in saa7127_detect_client */ | ||
229 | { SAA7127_REG_BURST_END, 0x1d }, | ||
230 | { SAA7127_REG_CHROMA_PHASE, 0x3f }, | ||
231 | { SAA7127_REG_GAINU, 0x7d }, | ||
232 | { SAA7127_REG_GAINV, 0xaf }, | ||
233 | { SAA7127_REG_BLACK_LEVEL, 0x33 }, | ||
234 | { SAA7127_REG_BLANKING_LEVEL, 0x35 }, | ||
235 | { SAA7127_REG_VBI_BLANKING, 0x35 }, | ||
236 | { SAA7127_REG_DAC_CONTROL, 0x02 }, | ||
237 | { SAA7127_REG_BURST_AMP, 0x2f }, | ||
238 | { SAA7127_REG_SUBC3, 0xcb }, | ||
239 | { SAA7127_REG_SUBC2, 0x8a }, | ||
240 | { SAA7127_REG_SUBC1, 0x09 }, | ||
241 | { SAA7127_REG_SUBC0, 0x2a }, | ||
242 | { SAA7127_REG_MULTI, 0xa0 }, | ||
243 | { SAA7127_REG_CLOSED_CAPTION, 0x00 }, | ||
244 | { 0, 0 } | ||
245 | }; | ||
246 | |||
247 | /* Enumeration for the Supported input types */ | ||
248 | enum saa7127_input_type { | ||
249 | SAA7127_INPUT_TYPE_NORMAL, | ||
250 | SAA7127_INPUT_TYPE_TEST_IMAGE | ||
251 | }; | ||
252 | |||
253 | /* Enumeration for the Supported Output signal types */ | ||
254 | enum saa7127_output_type { | ||
255 | SAA7127_OUTPUT_TYPE_BOTH, | ||
256 | SAA7127_OUTPUT_TYPE_COMPOSITE, | ||
257 | SAA7127_OUTPUT_TYPE_SVIDEO, | ||
258 | SAA7127_OUTPUT_TYPE_RGB, | ||
259 | SAA7127_OUTPUT_TYPE_YUV_C, | ||
260 | SAA7127_OUTPUT_TYPE_YUV_V | ||
261 | }; | ||
262 | |||
263 | /* | ||
264 | ********************************************************************** | ||
265 | * | ||
266 | * Encoder Struct, holds the configuration state of the encoder | ||
267 | * | ||
268 | ********************************************************************** | ||
269 | */ | ||
270 | |||
271 | struct saa7127_state { | ||
272 | v4l2_std_id std; | ||
273 | enum v4l2_chip_ident ident; | ||
274 | enum saa7127_input_type input_type; | ||
275 | enum saa7127_output_type output_type; | ||
276 | int video_enable; | ||
277 | int wss_enable; | ||
278 | u16 wss_mode; | ||
279 | int cc_enable; | ||
280 | u16 cc_data; | ||
281 | int xds_enable; | ||
282 | u16 xds_data; | ||
283 | int vps_enable; | ||
284 | u8 vps_data[5]; | ||
285 | u8 reg_2d; | ||
286 | u8 reg_3a; | ||
287 | u8 reg_3a_cb; /* colorbar bit */ | ||
288 | u8 reg_61; | ||
289 | }; | ||
290 | |||
291 | static const char * const output_strs[] = | ||
292 | { | ||
293 | "S-Video + Composite", | ||
294 | "Composite", | ||
295 | "S-Video", | ||
296 | "RGB", | ||
297 | "YUV C", | ||
298 | "YUV V" | ||
299 | }; | ||
300 | |||
301 | static const char * const wss_strs[] = { | ||
302 | "invalid", | ||
303 | "letterbox 14:9 center", | ||
304 | "letterbox 14:9 top", | ||
305 | "invalid", | ||
306 | "letterbox 16:9 top", | ||
307 | "invalid", | ||
308 | "invalid", | ||
309 | "16:9 full format anamorphic" | ||
310 | "4:3 full format", | ||
311 | "invalid", | ||
312 | "invalid", | ||
313 | "letterbox 16:9 center", | ||
314 | "invalid", | ||
315 | "letterbox >16:9 center", | ||
316 | "14:9 full format center", | ||
317 | "invalid", | ||
318 | }; | ||
319 | |||
320 | /* ----------------------------------------------------------------------- */ | ||
321 | |||
322 | static int saa7127_read(struct i2c_client *client, u8 reg) | ||
323 | { | ||
324 | return i2c_smbus_read_byte_data(client, reg); | ||
325 | } | ||
326 | |||
327 | /* ----------------------------------------------------------------------- */ | ||
328 | |||
329 | static int saa7127_write(struct i2c_client *client, u8 reg, u8 val) | ||
330 | { | ||
331 | int i; | ||
332 | |||
333 | for (i = 0; i < 3; i++) { | ||
334 | if (i2c_smbus_write_byte_data(client, reg, val) == 0) | ||
335 | return 0; | ||
336 | } | ||
337 | saa7127_err("I2C Write Problem\n"); | ||
338 | return -1; | ||
339 | } | ||
340 | |||
341 | /* ----------------------------------------------------------------------- */ | ||
342 | |||
343 | static int saa7127_write_inittab(struct i2c_client *client, | ||
344 | const struct i2c_reg_value *regs) | ||
345 | { | ||
346 | while (regs->reg != 0) { | ||
347 | saa7127_write(client, regs->reg, regs->value); | ||
348 | regs++; | ||
349 | } | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | /* ----------------------------------------------------------------------- */ | ||
354 | |||
355 | static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) | ||
356 | { | ||
357 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
358 | int enable = (data->line != 0); | ||
359 | |||
360 | if (enable && (data->field != 0 || data->line != 16)) | ||
361 | return -EINVAL; | ||
362 | if (state->vps_enable != enable) { | ||
363 | saa7127_dbg("Turn VPS Signal %s\n", enable ? "on" : "off"); | ||
364 | saa7127_write(client, 0x54, enable << 7); | ||
365 | state->vps_enable = enable; | ||
366 | } | ||
367 | if (!enable) | ||
368 | return 0; | ||
369 | |||
370 | state->vps_data[0] = data->data[4]; | ||
371 | state->vps_data[1] = data->data[10]; | ||
372 | state->vps_data[2] = data->data[11]; | ||
373 | state->vps_data[3] = data->data[12]; | ||
374 | state->vps_data[4] = data->data[13]; | ||
375 | saa7127_dbg("Set VPS data %02x %02x %02x %02x %02x\n", | ||
376 | state->vps_data[0], state->vps_data[1], | ||
377 | state->vps_data[2], state->vps_data[3], | ||
378 | state->vps_data[4]); | ||
379 | saa7127_write(client, 0x55, state->vps_data[0]); | ||
380 | saa7127_write(client, 0x56, state->vps_data[1]); | ||
381 | saa7127_write(client, 0x57, state->vps_data[2]); | ||
382 | saa7127_write(client, 0x58, state->vps_data[3]); | ||
383 | saa7127_write(client, 0x59, state->vps_data[4]); | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | /* ----------------------------------------------------------------------- */ | ||
388 | |||
389 | static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) | ||
390 | { | ||
391 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
392 | u16 cc = data->data[0] << 8 | data->data[1]; | ||
393 | int enable = (data->line != 0); | ||
394 | |||
395 | if (enable && (data->field != 0 || data->line != 21)) | ||
396 | return -EINVAL; | ||
397 | if (state->cc_enable != enable) { | ||
398 | saa7127_dbg("Turn CC %s\n", enable ? "on" : "off"); | ||
399 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, | ||
400 | (enable << 6) | 0x11); | ||
401 | state->cc_enable = enable; | ||
402 | } | ||
403 | if (!enable) | ||
404 | return 0; | ||
405 | |||
406 | saa7127_dbg_highvol("CC data: %04x\n", cc); | ||
407 | saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff); | ||
408 | saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8); | ||
409 | state->cc_data = cc; | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | /* ----------------------------------------------------------------------- */ | ||
414 | |||
415 | static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) | ||
416 | { | ||
417 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
418 | u16 xds = data->data[1] << 8 | data->data[0]; | ||
419 | int enable = (data->line != 0); | ||
420 | |||
421 | if (enable && (data->field != 1 || data->line != 21)) | ||
422 | return -EINVAL; | ||
423 | if (state->xds_enable != enable) { | ||
424 | saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off"); | ||
425 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, | ||
426 | (enable << 7) | 0x11); | ||
427 | state->xds_enable = enable; | ||
428 | } | ||
429 | if (!enable) | ||
430 | return 0; | ||
431 | |||
432 | saa7127_dbg_highvol("XDS data: %04x\n", xds); | ||
433 | saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff); | ||
434 | saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8); | ||
435 | state->xds_data = xds; | ||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | /* ----------------------------------------------------------------------- */ | ||
440 | |||
441 | static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) | ||
442 | { | ||
443 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
444 | int enable = (data->line != 0); | ||
445 | |||
446 | if (enable && (data->field != 0 || data->line != 23)) | ||
447 | return -EINVAL; | ||
448 | if (state->wss_enable != enable) { | ||
449 | saa7127_dbg("Turn WSS %s\n", enable ? "on" : "off"); | ||
450 | saa7127_write(client, 0x27, enable << 7); | ||
451 | state->wss_enable = enable; | ||
452 | } | ||
453 | if (!enable) | ||
454 | return 0; | ||
455 | |||
456 | saa7127_write(client, 0x26, data->data[0]); | ||
457 | saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f)); | ||
458 | saa7127_dbg("WSS mode: %s\n", wss_strs[data->data[0] & 0xf]); | ||
459 | state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0]; | ||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | /* ----------------------------------------------------------------------- */ | ||
464 | |||
465 | static int saa7127_set_video_enable(struct i2c_client *client, int enable) | ||
466 | { | ||
467 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
468 | |||
469 | if (enable) { | ||
470 | saa7127_dbg("Enable Video Output\n"); | ||
471 | saa7127_write(client, 0x2d, state->reg_2d); | ||
472 | saa7127_write(client, 0x61, state->reg_61); | ||
473 | } else { | ||
474 | saa7127_dbg("Disable Video Output\n"); | ||
475 | saa7127_write(client, 0x2d, (state->reg_2d & 0xf0)); | ||
476 | saa7127_write(client, 0x61, (state->reg_61 | 0xc0)); | ||
477 | } | ||
478 | state->video_enable = enable; | ||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | /* ----------------------------------------------------------------------- */ | ||
483 | |||
484 | static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std) | ||
485 | { | ||
486 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
487 | const struct i2c_reg_value *inittab; | ||
488 | |||
489 | if (std & V4L2_STD_525_60) { | ||
490 | saa7127_dbg("Selecting 60 Hz video Standard\n"); | ||
491 | inittab = saa7127_init_config_60hz; | ||
492 | state->reg_61 = SAA7127_60HZ_DAC_CONTROL; | ||
493 | } else { | ||
494 | saa7127_dbg("Selecting 50 Hz video Standard\n"); | ||
495 | inittab = saa7127_init_config_50hz; | ||
496 | state->reg_61 = SAA7127_50HZ_DAC_CONTROL; | ||
497 | } | ||
498 | |||
499 | /* Write Table */ | ||
500 | saa7127_write_inittab(client, inittab); | ||
501 | state->std = std; | ||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | /* ----------------------------------------------------------------------- */ | ||
506 | |||
507 | static int saa7127_set_output_type(struct i2c_client *client, int output) | ||
508 | { | ||
509 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
510 | |||
511 | switch (output) { | ||
512 | case SAA7127_OUTPUT_TYPE_RGB: | ||
513 | state->reg_2d = 0x0f; /* RGB + CVBS (for sync) */ | ||
514 | state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ | ||
515 | break; | ||
516 | |||
517 | case SAA7127_OUTPUT_TYPE_COMPOSITE: | ||
518 | state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */ | ||
519 | state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ | ||
520 | break; | ||
521 | |||
522 | case SAA7127_OUTPUT_TYPE_SVIDEO: | ||
523 | state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */ | ||
524 | state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ | ||
525 | break; | ||
526 | |||
527 | case SAA7127_OUTPUT_TYPE_YUV_V: | ||
528 | state->reg_2d = 0x4f; /* reg 2D = 01001111, all DAC's on, RGB + VBS */ | ||
529 | state->reg_3a = 0x0b; /* reg 3A = 00001011, bypass RGB-matrix */ | ||
530 | break; | ||
531 | |||
532 | case SAA7127_OUTPUT_TYPE_YUV_C: | ||
533 | state->reg_2d = 0x0f; /* reg 2D = 00001111, all DAC's on, RGB + CVBS */ | ||
534 | state->reg_3a = 0x0b; /* reg 3A = 00001011, bypass RGB-matrix */ | ||
535 | break; | ||
536 | |||
537 | case SAA7127_OUTPUT_TYPE_BOTH: | ||
538 | state->reg_2d = 0xbf; | ||
539 | state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ | ||
540 | break; | ||
541 | |||
542 | default: | ||
543 | return -EINVAL; | ||
544 | } | ||
545 | saa7127_dbg("Selecting %s output type\n", output_strs[output]); | ||
546 | |||
547 | /* Configure Encoder */ | ||
548 | saa7127_write(client, 0x2d, state->reg_2d); | ||
549 | saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb); | ||
550 | state->output_type = output; | ||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | /* ----------------------------------------------------------------------- */ | ||
555 | |||
556 | static int saa7127_set_input_type(struct i2c_client *client, int input) | ||
557 | { | ||
558 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
559 | |||
560 | switch (input) { | ||
561 | case SAA7127_INPUT_TYPE_NORMAL: /* avia */ | ||
562 | saa7127_dbg("Selecting Normal Encoder Input\n"); | ||
563 | state->reg_3a_cb = 0; | ||
564 | break; | ||
565 | |||
566 | case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */ | ||
567 | saa7127_dbg("Selecting Color Bar generator\n"); | ||
568 | state->reg_3a_cb = 0x80; | ||
569 | break; | ||
570 | |||
571 | default: | ||
572 | return -EINVAL; | ||
573 | } | ||
574 | saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb); | ||
575 | state->input_type = input; | ||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | /* ----------------------------------------------------------------------- */ | ||
580 | |||
581 | static int saa7127_command(struct i2c_client *client, | ||
582 | unsigned int cmd, void *arg) | ||
583 | { | ||
584 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
585 | struct v4l2_format *fmt = arg; | ||
586 | int *iarg = arg; | ||
587 | |||
588 | switch (cmd) { | ||
589 | case VIDIOC_S_STD: | ||
590 | if (state->std == *(v4l2_std_id *)arg) | ||
591 | break; | ||
592 | return saa7127_set_std(client, *(v4l2_std_id *)arg); | ||
593 | |||
594 | case VIDIOC_G_STD: | ||
595 | *(v4l2_std_id *)arg = state->std; | ||
596 | break; | ||
597 | |||
598 | case VIDIOC_S_INPUT: | ||
599 | if (state->input_type == *iarg) | ||
600 | break; | ||
601 | return saa7127_set_input_type(client, *iarg); | ||
602 | |||
603 | case VIDIOC_S_OUTPUT: | ||
604 | if (state->output_type == *iarg) | ||
605 | break; | ||
606 | return saa7127_set_output_type(client, *iarg); | ||
607 | |||
608 | case VIDIOC_STREAMON: | ||
609 | case VIDIOC_STREAMOFF: | ||
610 | if (state->video_enable == (cmd == VIDIOC_STREAMON)) | ||
611 | break; | ||
612 | return saa7127_set_video_enable(client, cmd == VIDIOC_STREAMON); | ||
613 | |||
614 | case VIDIOC_G_FMT: | ||
615 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | ||
616 | return -EINVAL; | ||
617 | |||
618 | memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced)); | ||
619 | if (state->vps_enable) | ||
620 | fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS; | ||
621 | if (state->wss_enable) | ||
622 | fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
623 | if (state->cc_enable) { | ||
624 | fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525; | ||
625 | fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525; | ||
626 | } | ||
627 | fmt->fmt.sliced.service_set = | ||
628 | (state->vps_enable ? V4L2_SLICED_VPS : 0) | | ||
629 | (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) | | ||
630 | (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0); | ||
631 | break; | ||
632 | |||
633 | case VIDIOC_LOG_STATUS: | ||
634 | saa7127_info("Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz"); | ||
635 | saa7127_info("Input: %s\n", state->input_type ? "color bars" : "normal"); | ||
636 | saa7127_info("Output: %s\n", state->video_enable ? | ||
637 | output_strs[state->output_type] : "disabled"); | ||
638 | saa7127_info("WSS: %s\n", state->wss_enable ? | ||
639 | wss_strs[state->wss_mode] : "disabled"); | ||
640 | saa7127_info("VPS: %s\n", state->vps_enable ? "enabled" : "disabled"); | ||
641 | saa7127_info("CC: %s\n", state->cc_enable ? "enabled" : "disabled"); | ||
642 | break; | ||
643 | |||
644 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
645 | case VIDIOC_INT_G_REGISTER: | ||
646 | { | ||
647 | struct v4l2_register *reg = arg; | ||
648 | |||
649 | if (reg->i2c_id != I2C_DRIVERID_SAA7127) | ||
650 | return -EINVAL; | ||
651 | reg->val = saa7127_read(client, reg->reg & 0xff); | ||
652 | break; | ||
653 | } | ||
654 | |||
655 | case VIDIOC_INT_S_REGISTER: | ||
656 | { | ||
657 | struct v4l2_register *reg = arg; | ||
658 | |||
659 | if (reg->i2c_id != I2C_DRIVERID_SAA7127) | ||
660 | return -EINVAL; | ||
661 | if (!capable(CAP_SYS_ADMIN)) | ||
662 | return -EPERM; | ||
663 | saa7127_write(client, reg->reg & 0xff, reg->val & 0xff); | ||
664 | break; | ||
665 | } | ||
666 | #endif | ||
667 | |||
668 | case VIDIOC_INT_S_VBI_DATA: | ||
669 | { | ||
670 | struct v4l2_sliced_vbi_data *data = arg; | ||
671 | |||
672 | switch (data->id) { | ||
673 | case V4L2_SLICED_WSS_625: | ||
674 | return saa7127_set_wss(client, data); | ||
675 | case V4L2_SLICED_VPS: | ||
676 | return saa7127_set_vps(client, data); | ||
677 | case V4L2_SLICED_CAPTION_525: | ||
678 | if (data->field == 0) | ||
679 | return saa7127_set_cc(client, data); | ||
680 | return saa7127_set_xds(client, data); | ||
681 | default: | ||
682 | return -EINVAL; | ||
683 | } | ||
684 | break; | ||
685 | } | ||
686 | |||
687 | case VIDIOC_INT_G_CHIP_IDENT: | ||
688 | *(enum v4l2_chip_ident *)arg = state->ident; | ||
689 | break; | ||
690 | |||
691 | default: | ||
692 | return -EINVAL; | ||
693 | } | ||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | /* ----------------------------------------------------------------------- */ | ||
698 | |||
699 | struct i2c_driver i2c_driver_saa7127; | ||
700 | |||
701 | /* ----------------------------------------------------------------------- */ | ||
702 | |||
703 | static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) | ||
704 | { | ||
705 | struct i2c_client *client; | ||
706 | struct saa7127_state *state; | ||
707 | struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */ | ||
708 | int read_result = 0; | ||
709 | |||
710 | /* Check if the adapter supports the needed features */ | ||
711 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
712 | return 0; | ||
713 | |||
714 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
715 | if (client == 0) | ||
716 | return -ENOMEM; | ||
717 | |||
718 | memset(client, 0, sizeof(struct i2c_client)); | ||
719 | client->addr = address; | ||
720 | client->adapter = adapter; | ||
721 | client->driver = &i2c_driver_saa7127; | ||
722 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
723 | snprintf(client->name, sizeof(client->name) - 1, "saa7127"); | ||
724 | |||
725 | saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1); | ||
726 | |||
727 | /* First test register 0: Bits 5-7 are a version ID (should be 0), | ||
728 | and bit 2 should also be 0. | ||
729 | This is rather general, so the second test is more specific and | ||
730 | looks at the 'ending point of burst in clock cycles' which is | ||
731 | 0x1d after a reset and not expected to ever change. */ | ||
732 | if ((saa7127_read(client, 0) & 0xe4) != 0 || | ||
733 | (saa7127_read(client, 0x29) & 0x3f) != 0x1d) { | ||
734 | saa7127_dbg("saa7127 not found\n"); | ||
735 | kfree(client); | ||
736 | return 0; | ||
737 | } | ||
738 | state = kmalloc(sizeof(struct saa7127_state), GFP_KERNEL); | ||
739 | |||
740 | if (state == NULL) { | ||
741 | kfree(client); | ||
742 | return (-ENOMEM); | ||
743 | } | ||
744 | |||
745 | i2c_set_clientdata(client, state); | ||
746 | memset(state, 0, sizeof(struct saa7127_state)); | ||
747 | |||
748 | /* Configure Encoder */ | ||
749 | |||
750 | saa7127_dbg("Configuring encoder\n"); | ||
751 | saa7127_write_inittab(client, saa7127_init_config_common); | ||
752 | saa7127_set_std(client, V4L2_STD_NTSC); | ||
753 | saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH); | ||
754 | saa7127_set_vps(client, &vbi); | ||
755 | saa7127_set_wss(client, &vbi); | ||
756 | saa7127_set_cc(client, &vbi); | ||
757 | saa7127_set_xds(client, &vbi); | ||
758 | if (test_image == 1) { | ||
759 | /* The Encoder has an internal Colorbar generator */ | ||
760 | /* This can be used for debugging */ | ||
761 | saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE); | ||
762 | } else { | ||
763 | saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL); | ||
764 | } | ||
765 | saa7127_set_video_enable(client, 1); | ||
766 | |||
767 | /* Detect if it's an saa7129 */ | ||
768 | read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2); | ||
769 | saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa); | ||
770 | if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) { | ||
771 | saa7127_info("saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name); | ||
772 | saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result); | ||
773 | saa7127_write_inittab(client, saa7129_init_config_extra); | ||
774 | state->ident = V4L2_IDENT_SAA7129; | ||
775 | } else { | ||
776 | saa7127_info("saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name); | ||
777 | state->ident = V4L2_IDENT_SAA7127; | ||
778 | } | ||
779 | |||
780 | i2c_attach_client(client); | ||
781 | |||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | /* ----------------------------------------------------------------------- */ | ||
786 | |||
787 | static int saa7127_probe(struct i2c_adapter *adapter) | ||
788 | { | ||
789 | #ifdef I2C_CLASS_TV_ANALOG | ||
790 | if (adapter->class & I2C_CLASS_TV_ANALOG) | ||
791 | #else | ||
792 | if (adapter->id == I2C_HW_B_BT848) | ||
793 | #endif | ||
794 | return i2c_probe(adapter, &addr_data, saa7127_attach); | ||
795 | return 0; | ||
796 | } | ||
797 | |||
798 | /* ----------------------------------------------------------------------- */ | ||
799 | |||
800 | static int saa7127_detach(struct i2c_client *client) | ||
801 | { | ||
802 | struct saa7127_state *state = i2c_get_clientdata(client); | ||
803 | int err; | ||
804 | |||
805 | /* Turn off TV output */ | ||
806 | saa7127_set_video_enable(client, 0); | ||
807 | |||
808 | err = i2c_detach_client(client); | ||
809 | |||
810 | if (err) { | ||
811 | return err; | ||
812 | } | ||
813 | |||
814 | kfree(state); | ||
815 | kfree(client); | ||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | /* ----------------------------------------------------------------------- */ | ||
820 | |||
821 | struct i2c_driver i2c_driver_saa7127 = { | ||
822 | .name = "saa7127", | ||
823 | .id = I2C_DRIVERID_SAA7127, | ||
824 | .flags = I2C_DF_NOTIFY, | ||
825 | .attach_adapter = saa7127_probe, | ||
826 | .detach_client = saa7127_detach, | ||
827 | .command = saa7127_command, | ||
828 | .owner = THIS_MODULE, | ||
829 | }; | ||
830 | |||
831 | |||
832 | /* ----------------------------------------------------------------------- */ | ||
833 | |||
834 | static int __init saa7127_init_module(void) | ||
835 | { | ||
836 | return i2c_add_driver(&i2c_driver_saa7127); | ||
837 | } | ||
838 | |||
839 | /* ----------------------------------------------------------------------- */ | ||
840 | |||
841 | static void __exit saa7127_cleanup_module(void) | ||
842 | { | ||
843 | i2c_del_driver(&i2c_driver_saa7127); | ||
844 | } | ||
845 | |||
846 | /* ----------------------------------------------------------------------- */ | ||
847 | |||
848 | module_init(saa7127_init_module); | ||
849 | module_exit(saa7127_cleanup_module); | ||
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 624e8808a517..7bdeabe638ca 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -1,10 +1,11 @@ | |||
1 | config VIDEO_SAA7134 | 1 | config VIDEO_SAA7134 |
2 | tristate "Philips SAA7134 support" | 2 | tristate "Philips SAA7134 support" |
3 | depends on VIDEO_DEV && PCI && I2C && SOUND | 3 | depends on VIDEO_DEV && PCI && I2C && SOUND && SND |
4 | select VIDEO_BUF | 4 | select VIDEO_BUF |
5 | select VIDEO_IR | 5 | select VIDEO_IR |
6 | select VIDEO_TUNER | 6 | select VIDEO_TUNER |
7 | select CRC32 | 7 | select CRC32 |
8 | select SND_PCM_OSS | ||
8 | ---help--- | 9 | ---help--- |
9 | This is a video4linux driver for Philips SAA713x based | 10 | This is a video4linux driver for Philips SAA713x based |
10 | TV cards. | 11 | TV cards. |
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index e0b28f0533af..4226b61cc613 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile | |||
@@ -1,10 +1,11 @@ | |||
1 | 1 | ||
2 | saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \ | 2 | saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \ |
3 | saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \ | 3 | saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \ |
4 | saa7134-vbi.o saa7134-video.o saa7134-input.o | 4 | saa7134-video.o saa7134-input.o |
5 | 5 | ||
6 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \ | 6 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \ |
7 | saa6752hs.o saa7134-alsa.o | 7 | saa6752hs.o saa7134-alsa.o \ |
8 | saa7134-oss.o | ||
8 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o | 9 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o |
9 | 10 | ||
10 | EXTRA_CFLAGS += -I$(src)/.. | 11 | EXTRA_CFLAGS += -I$(src)/.. |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index 4f3c42354329..5707c666660b 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -30,7 +30,9 @@ | |||
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
31 | #include <sound/control.h> | 31 | #include <sound/control.h> |
32 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
33 | #include <sound/pcm_params.h> | ||
33 | #include <sound/initval.h> | 34 | #include <sound/initval.h> |
35 | #include <linux/interrupt.h> | ||
34 | 36 | ||
35 | #include "saa7134.h" | 37 | #include "saa7134.h" |
36 | #include "saa7134-reg.h" | 38 | #include "saa7134-reg.h" |
@@ -56,6 +58,8 @@ static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; | |||
56 | module_param_array(index, int, NULL, 0444); | 58 | module_param_array(index, int, NULL, 0444); |
57 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); | 59 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); |
58 | 60 | ||
61 | int position; | ||
62 | |||
59 | #define dprintk(fmt, arg...) if (debug) \ | 63 | #define dprintk(fmt, arg...) if (debug) \ |
60 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg) | 64 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg) |
61 | 65 | ||
@@ -68,7 +72,7 @@ typedef struct snd_card_saa7134 { | |||
68 | int mixer_volume[MIXER_ADDR_LAST+1][2]; | 72 | int mixer_volume[MIXER_ADDR_LAST+1][2]; |
69 | int capture_source[MIXER_ADDR_LAST+1][2]; | 73 | int capture_source[MIXER_ADDR_LAST+1][2]; |
70 | struct pci_dev *pci; | 74 | struct pci_dev *pci; |
71 | struct saa7134_dev *saadev; | 75 | struct saa7134_dev *dev; |
72 | 76 | ||
73 | unsigned long iobase; | 77 | unsigned long iobase; |
74 | int irq; | 78 | int irq; |
@@ -83,12 +87,10 @@ typedef struct snd_card_saa7134 { | |||
83 | */ | 87 | */ |
84 | 88 | ||
85 | typedef struct snd_card_saa7134_pcm { | 89 | typedef struct snd_card_saa7134_pcm { |
86 | struct saa7134_dev *saadev; | 90 | struct saa7134_dev *dev; |
87 | 91 | ||
88 | spinlock_t lock; | 92 | spinlock_t lock; |
89 | unsigned int pcm_size; /* buffer size */ | 93 | |
90 | unsigned int pcm_count; /* bytes per period */ | ||
91 | unsigned int pcm_bps; /* bytes per second */ | ||
92 | snd_pcm_substream_t *substream; | 94 | snd_pcm_substream_t *substream; |
93 | } snd_card_saa7134_pcm_t; | 95 | } snd_card_saa7134_pcm_t; |
94 | 96 | ||
@@ -100,13 +102,11 @@ static snd_card_t *snd_saa7134_cards[SNDRV_CARDS]; | |||
100 | * | 102 | * |
101 | * Called when the capture device is released or the buffer overflows | 103 | * Called when the capture device is released or the buffer overflows |
102 | * | 104 | * |
103 | * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped | 105 | * - Copied verbatim from saa7134-oss's dsp_dma_stop. |
104 | * if we just share dsp_dma_stop and use it here | ||
105 | * | 106 | * |
106 | */ | 107 | */ |
107 | 108 | ||
108 | static void saa7134_dma_stop(struct saa7134_dev *dev) | 109 | static void saa7134_dma_stop(struct saa7134_dev *dev) |
109 | |||
110 | { | 110 | { |
111 | dev->dmasound.dma_blk = -1; | 111 | dev->dmasound.dma_blk = -1; |
112 | dev->dmasound.dma_running = 0; | 112 | dev->dmasound.dma_running = 0; |
@@ -118,8 +118,7 @@ static void saa7134_dma_stop(struct saa7134_dev *dev) | |||
118 | * | 118 | * |
119 | * Called when preparing the capture device for use | 119 | * Called when preparing the capture device for use |
120 | * | 120 | * |
121 | * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped | 121 | * - Copied verbatim from saa7134-oss's dsp_dma_start. |
122 | * if we just share dsp_dma_start and use it here | ||
123 | * | 122 | * |
124 | */ | 123 | */ |
125 | 124 | ||
@@ -170,9 +169,9 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) | |||
170 | if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) { | 169 | if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) { |
171 | dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, | 170 | dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, |
172 | dev->dmasound.bufsize, dev->dmasound.blocks); | 171 | dev->dmasound.bufsize, dev->dmasound.blocks); |
172 | spin_unlock(&dev->slock); | ||
173 | snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); | 173 | snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); |
174 | saa7134_dma_stop(dev); | 174 | return; |
175 | goto done; | ||
176 | } | 175 | } |
177 | 176 | ||
178 | /* next block addr */ | 177 | /* next block addr */ |
@@ -194,6 +193,7 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) | |||
194 | snd_pcm_period_elapsed(dev->dmasound.substream); | 193 | snd_pcm_period_elapsed(dev->dmasound.substream); |
195 | spin_lock(&dev->slock); | 194 | spin_lock(&dev->slock); |
196 | } | 195 | } |
196 | |||
197 | done: | 197 | done: |
198 | spin_unlock(&dev->slock); | 198 | spin_unlock(&dev->slock); |
199 | 199 | ||
@@ -209,7 +209,9 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) | |||
209 | 209 | ||
210 | static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs) | 210 | static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs) |
211 | { | 211 | { |
212 | struct saa7134_dev *dev = (struct saa7134_dev*) dev_id; | 212 | struct saa7134_dmasound *dmasound = dev_id; |
213 | struct saa7134_dev *dev = dmasound->priv_data; | ||
214 | |||
213 | unsigned long report, status; | 215 | unsigned long report, status; |
214 | int loop, handled = 0; | 216 | int loop, handled = 0; |
215 | 217 | ||
@@ -248,56 +250,23 @@ static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream, | |||
248 | int cmd) | 250 | int cmd) |
249 | { | 251 | { |
250 | snd_pcm_runtime_t *runtime = substream->runtime; | 252 | snd_pcm_runtime_t *runtime = substream->runtime; |
251 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | 253 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
252 | struct saa7134_dev *dev=saapcm->saadev; | 254 | struct saa7134_dev *dev=pcm->dev; |
253 | int err = 0; | 255 | int err = 0; |
254 | 256 | ||
255 | spin_lock_irq(&dev->slock); | 257 | spin_lock(&dev->slock); |
256 | if (cmd == SNDRV_PCM_TRIGGER_START) { | 258 | if (cmd == SNDRV_PCM_TRIGGER_START) { |
257 | /* start dma */ | 259 | /* start dma */ |
258 | saa7134_dma_start(dev); | 260 | saa7134_dma_start(dev); |
259 | } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { | 261 | } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { |
260 | /* stop dma */ | 262 | /* stop dma */ |
261 | saa7134_dma_stop(dev); | 263 | saa7134_dma_stop(dev); |
262 | } else { | 264 | } else { |
263 | err = -EINVAL; | 265 | err = -EINVAL; |
264 | } | 266 | } |
265 | spin_unlock_irq(&dev->slock); | 267 | spin_unlock(&dev->slock); |
266 | |||
267 | return err; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * DMA buffer config | ||
272 | * | ||
273 | * Sets the values that will later be used as the size of the buffer, | ||
274 | * size of the fragments, and total number of fragments. | ||
275 | * Must be called during the preparation stage, before memory is | ||
276 | * allocated | ||
277 | * | ||
278 | * - Copied verbatim from saa7134-oss. Can be dropped | ||
279 | * if we just share dsp_buffer_conf from OSS. | ||
280 | */ | ||
281 | 268 | ||
282 | static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) | 269 | return err; |
283 | { | ||
284 | if (blksize < 0x100) | ||
285 | blksize = 0x100; | ||
286 | if (blksize > 0x10000) | ||
287 | blksize = 0x10000; | ||
288 | |||
289 | if (blocks < 2) | ||
290 | blocks = 2; | ||
291 | if ((blksize * blocks) > 1024*1024) | ||
292 | blocks = 1024*1024 / blksize; | ||
293 | |||
294 | dev->dmasound.blocks = blocks; | ||
295 | dev->dmasound.blksize = blksize; | ||
296 | dev->dmasound.bufsize = blksize * blocks; | ||
297 | |||
298 | dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", | ||
299 | blocks,blksize,blksize * blocks / 1024); | ||
300 | return 0; | ||
301 | } | 270 | } |
302 | 271 | ||
303 | /* | 272 | /* |
@@ -307,16 +276,16 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) | |||
307 | * ALSA, but I was unable to use ALSA's own DMA, and had to force the | 276 | * ALSA, but I was unable to use ALSA's own DMA, and had to force the |
308 | * usage of V4L's | 277 | * usage of V4L's |
309 | * | 278 | * |
310 | * - Copied verbatim from saa7134-oss. Can be dropped | 279 | * - Copied verbatim from saa7134-oss. |
311 | * if we just share dsp_buffer_init from OSS. | 280 | * |
312 | */ | 281 | */ |
313 | 282 | ||
314 | static int dsp_buffer_init(struct saa7134_dev *dev) | 283 | static int dsp_buffer_init(struct saa7134_dev *dev) |
315 | { | 284 | { |
316 | int err; | 285 | int err; |
317 | 286 | ||
318 | if (!dev->dmasound.bufsize) | 287 | BUG_ON(!dev->dmasound.bufsize); |
319 | BUG(); | 288 | |
320 | videobuf_dma_init(&dev->dmasound.dma); | 289 | videobuf_dma_init(&dev->dmasound.dma); |
321 | err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, | 290 | err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, |
322 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); | 291 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); |
@@ -326,6 +295,28 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
326 | } | 295 | } |
327 | 296 | ||
328 | /* | 297 | /* |
298 | * DMA buffer release | ||
299 | * | ||
300 | * Called after closing the device, during snd_card_saa7134_capture_close | ||
301 | * | ||
302 | */ | ||
303 | |||
304 | static int dsp_buffer_free(struct saa7134_dev *dev) | ||
305 | { | ||
306 | if (!dev->dmasound.blksize) | ||
307 | BUG(); | ||
308 | |||
309 | videobuf_dma_free(&dev->dmasound.dma); | ||
310 | |||
311 | dev->dmasound.blocks = 0; | ||
312 | dev->dmasound.blksize = 0; | ||
313 | dev->dmasound.bufsize = 0; | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | |||
319 | /* | ||
329 | * ALSA PCM preparation | 320 | * ALSA PCM preparation |
330 | * | 321 | * |
331 | * - One of the ALSA capture callbacks. | 322 | * - One of the ALSA capture callbacks. |
@@ -340,84 +331,30 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
340 | static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | 331 | static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) |
341 | { | 332 | { |
342 | snd_pcm_runtime_t *runtime = substream->runtime; | 333 | snd_pcm_runtime_t *runtime = substream->runtime; |
343 | int err, bswap, sign; | 334 | int bswap, sign; |
344 | u32 fmt, control; | 335 | u32 fmt, control; |
345 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | 336 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
346 | struct saa7134_dev *dev; | 337 | struct saa7134_dev *dev; |
347 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | 338 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
348 | unsigned int bps; | ||
349 | unsigned long size; | ||
350 | unsigned count; | ||
351 | |||
352 | size = snd_pcm_lib_buffer_bytes(substream); | ||
353 | count = snd_pcm_lib_period_bytes(substream); | ||
354 | |||
355 | saapcm->saadev->dmasound.substream = substream; | ||
356 | bps = runtime->rate * runtime->channels; | ||
357 | bps *= snd_pcm_format_width(runtime->format); | ||
358 | bps /= 8; | ||
359 | if (bps <= 0) | ||
360 | return -EINVAL; | ||
361 | saapcm->pcm_bps = bps; | ||
362 | saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream); | ||
363 | saapcm->pcm_count = snd_pcm_lib_period_bytes(substream); | ||
364 | |||
365 | 339 | ||
366 | dev=saa7134->saadev; | 340 | pcm->dev->dmasound.substream = substream; |
367 | 341 | ||
368 | dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count)); | 342 | dev = saa7134->dev; |
369 | 343 | ||
370 | err = dsp_buffer_init(dev); | 344 | if (snd_pcm_format_width(runtime->format) == 8) |
371 | if (0 != err) | ||
372 | goto fail2; | ||
373 | |||
374 | /* prepare buffer */ | ||
375 | if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma))) | ||
376 | return err; | ||
377 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) | ||
378 | goto fail1; | ||
379 | if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt, | ||
380 | dev->dmasound.dma.sglist, | ||
381 | dev->dmasound.dma.sglen, | ||
382 | 0))) | ||
383 | goto fail2; | ||
384 | |||
385 | |||
386 | |||
387 | switch (runtime->format) { | ||
388 | case SNDRV_PCM_FORMAT_U8: | ||
389 | case SNDRV_PCM_FORMAT_S8: | ||
390 | fmt = 0x00; | 345 | fmt = 0x00; |
391 | break; | 346 | else |
392 | case SNDRV_PCM_FORMAT_U16_LE: | ||
393 | case SNDRV_PCM_FORMAT_U16_BE: | ||
394 | case SNDRV_PCM_FORMAT_S16_LE: | ||
395 | case SNDRV_PCM_FORMAT_S16_BE: | ||
396 | fmt = 0x01; | 347 | fmt = 0x01; |
397 | break; | ||
398 | default: | ||
399 | err = -EINVAL; | ||
400 | return 1; | ||
401 | } | ||
402 | 348 | ||
403 | switch (runtime->format) { | 349 | if (snd_pcm_format_signed(runtime->format)) |
404 | case SNDRV_PCM_FORMAT_S8: | ||
405 | case SNDRV_PCM_FORMAT_S16_LE: | ||
406 | case SNDRV_PCM_FORMAT_S16_BE: | ||
407 | sign = 1; | 350 | sign = 1; |
408 | break; | 351 | else |
409 | default: | ||
410 | sign = 0; | 352 | sign = 0; |
411 | break; | ||
412 | } | ||
413 | 353 | ||
414 | switch (runtime->format) { | 354 | if (snd_pcm_format_big_endian(runtime->format)) |
415 | case SNDRV_PCM_FORMAT_U16_BE: | 355 | bswap = 1; |
416 | case SNDRV_PCM_FORMAT_S16_BE: | 356 | else |
417 | bswap = 1; break; | 357 | bswap = 0; |
418 | default: | ||
419 | bswap = 0; break; | ||
420 | } | ||
421 | 358 | ||
422 | switch (dev->pci->device) { | 359 | switch (dev->pci->device) { |
423 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | 360 | case PCI_DEVICE_ID_PHILIPS_SAA7134: |
@@ -445,7 +382,6 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | |||
445 | fmt |= 0x04; | 382 | fmt |= 0x04; |
446 | saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1); | 383 | saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1); |
447 | saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24)); | 384 | saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24)); |
448 | //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210); | ||
449 | break; | 385 | break; |
450 | } | 386 | } |
451 | 387 | ||
@@ -459,12 +395,6 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | |||
459 | if (bswap) | 395 | if (bswap) |
460 | control |= SAA7134_RS_CONTROL_BSWAP; | 396 | control |= SAA7134_RS_CONTROL_BSWAP; |
461 | 397 | ||
462 | /* I should be able to use runtime->dma_addr in the control | ||
463 | byte, but it doesn't work. So I allocate the DMA using the | ||
464 | V4L functions, and force ALSA to use that as the DMA area */ | ||
465 | |||
466 | runtime->dma_area = dev->dmasound.dma.vmalloc; | ||
467 | |||
468 | saa_writel(SAA7134_RS_BA1(6),0); | 398 | saa_writel(SAA7134_RS_BA1(6),0); |
469 | saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize); | 399 | saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize); |
470 | saa_writel(SAA7134_RS_PITCH(6),0); | 400 | saa_writel(SAA7134_RS_PITCH(6),0); |
@@ -473,12 +403,6 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | |||
473 | dev->dmasound.rate = runtime->rate; | 403 | dev->dmasound.rate = runtime->rate; |
474 | 404 | ||
475 | return 0; | 405 | return 0; |
476 | fail2: | ||
477 | saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); | ||
478 | fail1: | ||
479 | videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); | ||
480 | return err; | ||
481 | |||
482 | 406 | ||
483 | } | 407 | } |
484 | 408 | ||
@@ -496,10 +420,8 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | |||
496 | static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream) | 420 | static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream) |
497 | { | 421 | { |
498 | snd_pcm_runtime_t *runtime = substream->runtime; | 422 | snd_pcm_runtime_t *runtime = substream->runtime; |
499 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | 423 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
500 | struct saa7134_dev *dev=saapcm->saadev; | 424 | struct saa7134_dev *dev=pcm->dev; |
501 | |||
502 | |||
503 | 425 | ||
504 | if (dev->dmasound.read_count) { | 426 | if (dev->dmasound.read_count) { |
505 | dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream); | 427 | dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream); |
@@ -540,9 +462,9 @@ static snd_pcm_hardware_t snd_card_saa7134_capture = | |||
540 | 462 | ||
541 | static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) | 463 | static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) |
542 | { | 464 | { |
543 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | 465 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
544 | 466 | ||
545 | kfree(saapcm); | 467 | kfree(pcm); |
546 | } | 468 | } |
547 | 469 | ||
548 | 470 | ||
@@ -552,17 +474,76 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) | |||
552 | * - One of the ALSA capture callbacks. | 474 | * - One of the ALSA capture callbacks. |
553 | * | 475 | * |
554 | * Called on initialization, right before the PCM preparation | 476 | * Called on initialization, right before the PCM preparation |
555 | * Usually used in ALSA to allocate the DMA, but since we don't use the | ||
556 | * ALSA DMA it does nothing | ||
557 | * | 477 | * |
558 | */ | 478 | */ |
559 | 479 | ||
560 | static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, | 480 | static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, |
561 | snd_pcm_hw_params_t * hw_params) | 481 | snd_pcm_hw_params_t * hw_params) |
562 | { | 482 | { |
483 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | ||
484 | struct saa7134_dev *dev; | ||
485 | unsigned int period_size, periods; | ||
486 | int err; | ||
563 | 487 | ||
564 | return 0; | 488 | period_size = params_period_bytes(hw_params); |
489 | periods = params_periods(hw_params); | ||
490 | |||
491 | snd_assert(period_size >= 0x100 && period_size <= 0x10000, | ||
492 | return -EINVAL); | ||
493 | snd_assert(periods >= 2, return -EINVAL); | ||
494 | snd_assert(period_size * periods <= 1024 * 1024, return -EINVAL); | ||
565 | 495 | ||
496 | dev = saa7134->dev; | ||
497 | |||
498 | if (dev->dmasound.blocks == periods && | ||
499 | dev->dmasound.blksize == period_size) | ||
500 | return 0; | ||
501 | |||
502 | /* release the old buffer */ | ||
503 | if (substream->runtime->dma_area) { | ||
504 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | ||
505 | videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); | ||
506 | dsp_buffer_free(dev); | ||
507 | substream->runtime->dma_area = NULL; | ||
508 | } | ||
509 | dev->dmasound.blocks = periods; | ||
510 | dev->dmasound.blksize = period_size; | ||
511 | dev->dmasound.bufsize = period_size * periods; | ||
512 | |||
513 | err = dsp_buffer_init(dev); | ||
514 | if (0 != err) { | ||
515 | dev->dmasound.blocks = 0; | ||
516 | dev->dmasound.blksize = 0; | ||
517 | dev->dmasound.bufsize = 0; | ||
518 | return err; | ||
519 | } | ||
520 | |||
521 | if (0 != (err = videobuf_dma_pci_map(dev->pci, &dev->dmasound.dma))) { | ||
522 | dsp_buffer_free(dev); | ||
523 | return err; | ||
524 | } | ||
525 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) { | ||
526 | videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); | ||
527 | dsp_buffer_free(dev); | ||
528 | return err; | ||
529 | } | ||
530 | if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt, | ||
531 | dev->dmasound.dma.sglist, | ||
532 | dev->dmasound.dma.sglen, | ||
533 | 0))) { | ||
534 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | ||
535 | videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); | ||
536 | dsp_buffer_free(dev); | ||
537 | return err; | ||
538 | } | ||
539 | |||
540 | /* I should be able to use runtime->dma_addr in the control | ||
541 | byte, but it doesn't work. So I allocate the DMA using the | ||
542 | V4L functions, and force ALSA to use that as the DMA area */ | ||
543 | |||
544 | substream->runtime->dma_area = dev->dmasound.dma.vmalloc; | ||
545 | |||
546 | return 1; | ||
566 | 547 | ||
567 | } | 548 | } |
568 | 549 | ||
@@ -572,33 +553,23 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, | |||
572 | * - One of the ALSA capture callbacks. | 553 | * - One of the ALSA capture callbacks. |
573 | * | 554 | * |
574 | * Called after closing the device, but before snd_card_saa7134_capture_close | 555 | * Called after closing the device, but before snd_card_saa7134_capture_close |
575 | * Usually used in ALSA to free the DMA, but since we don't use the | 556 | * It stops the DMA audio and releases the buffers. |
576 | * ALSA DMA I'm almost sure this isn't necessary. | ||
577 | * | 557 | * |
578 | */ | 558 | */ |
579 | 559 | ||
580 | static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream) | 560 | static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream) |
581 | { | 561 | { |
582 | return 0; | 562 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
583 | } | 563 | struct saa7134_dev *dev; |
584 | |||
585 | /* | ||
586 | * DMA buffer release | ||
587 | * | ||
588 | * Called after closing the device, during snd_card_saa7134_capture_close | ||
589 | * | ||
590 | */ | ||
591 | |||
592 | static int dsp_buffer_free(struct saa7134_dev *dev) | ||
593 | { | ||
594 | if (!dev->dmasound.blksize) | ||
595 | BUG(); | ||
596 | 564 | ||
597 | videobuf_dma_free(&dev->dmasound.dma); | 565 | dev = saa7134->dev; |
598 | 566 | ||
599 | dev->dmasound.blocks = 0; | 567 | if (substream->runtime->dma_area) { |
600 | dev->dmasound.blksize = 0; | 568 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); |
601 | dev->dmasound.bufsize = 0; | 569 | videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); |
570 | dsp_buffer_free(dev); | ||
571 | substream->runtime->dma_area = NULL; | ||
572 | } | ||
602 | 573 | ||
603 | return 0; | 574 | return 0; |
604 | } | 575 | } |
@@ -608,21 +579,12 @@ static int dsp_buffer_free(struct saa7134_dev *dev) | |||
608 | * | 579 | * |
609 | * - One of the ALSA capture callbacks. | 580 | * - One of the ALSA capture callbacks. |
610 | * | 581 | * |
611 | * Called after closing the device. It stops the DMA audio and releases | 582 | * Called after closing the device. |
612 | * the buffers | ||
613 | * | 583 | * |
614 | */ | 584 | */ |
615 | 585 | ||
616 | static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) | 586 | static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) |
617 | { | 587 | { |
618 | snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream); | ||
619 | struct saa7134_dev *dev = chip->saadev; | ||
620 | |||
621 | /* unlock buffer */ | ||
622 | saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); | ||
623 | videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); | ||
624 | |||
625 | dsp_buffer_free(dev); | ||
626 | return 0; | 588 | return 0; |
627 | } | 589 | } |
628 | 590 | ||
@@ -639,29 +601,28 @@ static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) | |||
639 | static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream) | 601 | static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream) |
640 | { | 602 | { |
641 | snd_pcm_runtime_t *runtime = substream->runtime; | 603 | snd_pcm_runtime_t *runtime = substream->runtime; |
642 | snd_card_saa7134_pcm_t *saapcm; | 604 | snd_card_saa7134_pcm_t *pcm; |
643 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | 605 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
644 | struct saa7134_dev *dev = saa7134->saadev; | 606 | struct saa7134_dev *dev = saa7134->dev; |
645 | int err; | 607 | int err; |
646 | 608 | ||
647 | down(&dev->dmasound.lock); | 609 | down(&dev->dmasound.lock); |
648 | 610 | ||
649 | dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8; | ||
650 | dev->dmasound.channels = 2; | ||
651 | dev->dmasound.read_count = 0; | 611 | dev->dmasound.read_count = 0; |
652 | dev->dmasound.read_offset = 0; | 612 | dev->dmasound.read_offset = 0; |
653 | 613 | ||
654 | up(&dev->dmasound.lock); | 614 | up(&dev->dmasound.lock); |
655 | 615 | ||
656 | saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL); | 616 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); |
657 | if (saapcm == NULL) | 617 | if (pcm == NULL) |
658 | return -ENOMEM; | 618 | return -ENOMEM; |
659 | saapcm->saadev=saa7134->saadev; | ||
660 | 619 | ||
661 | spin_lock_init(&saapcm->lock); | 620 | pcm->dev=saa7134->dev; |
662 | 621 | ||
663 | saapcm->substream = substream; | 622 | spin_lock_init(&pcm->lock); |
664 | runtime->private_data = saapcm; | 623 | |
624 | pcm->substream = substream; | ||
625 | runtime->private_data = pcm; | ||
665 | runtime->private_free = snd_card_saa7134_runtime_free; | 626 | runtime->private_free = snd_card_saa7134_runtime_free; |
666 | runtime->hw = snd_card_saa7134_capture; | 627 | runtime->hw = snd_card_saa7134_capture; |
667 | 628 | ||
@@ -736,7 +697,6 @@ static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ | |||
736 | static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 697 | static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) |
737 | { | 698 | { |
738 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 699 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
739 | unsigned long flags; | ||
740 | int change, addr = kcontrol->private_value; | 700 | int change, addr = kcontrol->private_value; |
741 | int left, right; | 701 | int left, right; |
742 | 702 | ||
@@ -750,12 +710,12 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ | |||
750 | right = 0; | 710 | right = 0; |
751 | if (right > 20) | 711 | if (right > 20) |
752 | right = 20; | 712 | right = 20; |
753 | spin_lock_irqsave(&chip->mixer_lock, flags); | 713 | spin_lock_irq(&chip->mixer_lock); |
754 | change = chip->mixer_volume[addr][0] != left || | 714 | change = chip->mixer_volume[addr][0] != left || |
755 | chip->mixer_volume[addr][1] != right; | 715 | chip->mixer_volume[addr][1] != right; |
756 | chip->mixer_volume[addr][0] = left; | 716 | chip->mixer_volume[addr][0] = left; |
757 | chip->mixer_volume[addr][1] = right; | 717 | chip->mixer_volume[addr][1] = right; |
758 | spin_unlock_irqrestore(&chip->mixer_lock, flags); | 718 | spin_unlock_irq(&chip->mixer_lock); |
759 | return change; | 719 | return change; |
760 | } | 720 | } |
761 | 721 | ||
@@ -777,38 +737,37 @@ static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_ | |||
777 | static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 737 | static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) |
778 | { | 738 | { |
779 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 739 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
780 | unsigned long flags; | ||
781 | int addr = kcontrol->private_value; | 740 | int addr = kcontrol->private_value; |
782 | 741 | ||
783 | spin_lock_irqsave(&chip->mixer_lock, flags); | 742 | spin_lock_irq(&chip->mixer_lock); |
784 | ucontrol->value.integer.value[0] = chip->capture_source[addr][0]; | 743 | ucontrol->value.integer.value[0] = chip->capture_source[addr][0]; |
785 | ucontrol->value.integer.value[1] = chip->capture_source[addr][1]; | 744 | ucontrol->value.integer.value[1] = chip->capture_source[addr][1]; |
786 | spin_unlock_irqrestore(&chip->mixer_lock, flags); | 745 | spin_unlock_irq(&chip->mixer_lock); |
746 | |||
787 | return 0; | 747 | return 0; |
788 | } | 748 | } |
789 | 749 | ||
790 | static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 750 | static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) |
791 | { | 751 | { |
792 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 752 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
793 | unsigned long flags; | ||
794 | int change, addr = kcontrol->private_value; | 753 | int change, addr = kcontrol->private_value; |
795 | int left, right; | 754 | int left, right; |
796 | u32 anabar, xbarin; | 755 | u32 anabar, xbarin; |
797 | int analog_io, rate; | 756 | int analog_io, rate; |
798 | struct saa7134_dev *dev; | 757 | struct saa7134_dev *dev; |
799 | 758 | ||
800 | dev = chip->saadev; | 759 | dev = chip->dev; |
801 | 760 | ||
802 | left = ucontrol->value.integer.value[0] & 1; | 761 | left = ucontrol->value.integer.value[0] & 1; |
803 | right = ucontrol->value.integer.value[1] & 1; | 762 | right = ucontrol->value.integer.value[1] & 1; |
804 | spin_lock_irqsave(&chip->mixer_lock, flags); | 763 | spin_lock_irq(&chip->mixer_lock); |
805 | 764 | ||
806 | change = chip->capture_source[addr][0] != left || | 765 | change = chip->capture_source[addr][0] != left || |
807 | chip->capture_source[addr][1] != right; | 766 | chip->capture_source[addr][1] != right; |
808 | chip->capture_source[addr][0] = left; | 767 | chip->capture_source[addr][0] = left; |
809 | chip->capture_source[addr][1] = right; | 768 | chip->capture_source[addr][1] = right; |
810 | dev->dmasound.input=addr; | 769 | dev->dmasound.input=addr; |
811 | spin_unlock_irqrestore(&chip->mixer_lock, flags); | 770 | spin_unlock_irq(&chip->mixer_lock); |
812 | 771 | ||
813 | 772 | ||
814 | if (change) { | 773 | if (change) { |
@@ -898,43 +857,44 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) | |||
898 | return 0; | 857 | return 0; |
899 | } | 858 | } |
900 | 859 | ||
901 | static int snd_saa7134_free(snd_card_saa7134_t *chip) | 860 | static void snd_saa7134_free(snd_card_t * card) |
902 | { | 861 | { |
903 | return 0; | 862 | snd_card_saa7134_t *chip = card->private_data; |
904 | } | 863 | |
864 | if (chip->dev->dmasound.priv_data == NULL) | ||
865 | return; | ||
866 | |||
867 | if (chip->irq >= 0) { | ||
868 | synchronize_irq(chip->irq); | ||
869 | free_irq(chip->irq, &chip->dev->dmasound); | ||
870 | } | ||
871 | |||
872 | chip->dev->dmasound.priv_data = NULL; | ||
905 | 873 | ||
906 | static int snd_saa7134_dev_free(snd_device_t *device) | ||
907 | { | ||
908 | snd_card_saa7134_t *chip = device->device_data; | ||
909 | return snd_saa7134_free(chip); | ||
910 | } | 874 | } |
911 | 875 | ||
912 | /* | 876 | /* |
913 | * ALSA initialization | 877 | * ALSA initialization |
914 | * | 878 | * |
915 | * Called by saa7134-core, it creates the basic structures and registers | 879 | * Called by the init routine, once for each saa7134 device present, |
916 | * the ALSA devices | 880 | * it creates the basic structures and registers the ALSA devices |
917 | * | 881 | * |
918 | */ | 882 | */ |
919 | 883 | ||
920 | int alsa_card_saa7134_create (struct saa7134_dev *saadev) | 884 | int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) |
921 | { | 885 | { |
922 | static int dev; | ||
923 | 886 | ||
924 | snd_card_t *card; | 887 | snd_card_t *card; |
925 | snd_card_saa7134_t *chip; | 888 | snd_card_saa7134_t *chip; |
926 | int err; | 889 | int err; |
927 | static snd_device_ops_t ops = { | ||
928 | .dev_free = snd_saa7134_dev_free, | ||
929 | }; | ||
930 | 890 | ||
931 | 891 | ||
932 | if (dev >= SNDRV_CARDS) | 892 | if (devnum >= SNDRV_CARDS) |
933 | return -ENODEV; | 893 | return -ENODEV; |
934 | if (!enable[dev]) | 894 | if (!enable[devnum]) |
935 | return -ENODEV; | 895 | return -ENODEV; |
936 | 896 | ||
937 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 897 | card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t)); |
938 | 898 | ||
939 | if (card == NULL) | 899 | if (card == NULL) |
940 | return -ENOMEM; | 900 | return -ENOMEM; |
@@ -943,34 +903,33 @@ int alsa_card_saa7134_create (struct saa7134_dev *saadev) | |||
943 | 903 | ||
944 | /* Card "creation" */ | 904 | /* Card "creation" */ |
945 | 905 | ||
946 | chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); | 906 | card->private_free = snd_saa7134_free; |
947 | if (chip == NULL) { | 907 | chip = (snd_card_saa7134_t *) card->private_data; |
948 | return -ENOMEM; | ||
949 | } | ||
950 | 908 | ||
951 | spin_lock_init(&chip->lock); | 909 | spin_lock_init(&chip->lock); |
952 | spin_lock_init(&chip->mixer_lock); | 910 | spin_lock_init(&chip->mixer_lock); |
953 | 911 | ||
954 | chip->saadev = saadev; | 912 | chip->dev = dev; |
955 | 913 | ||
956 | chip->card = card; | 914 | chip->card = card; |
957 | 915 | ||
958 | chip->pci = saadev->pci; | 916 | chip->pci = dev->pci; |
959 | chip->irq = saadev->pci->irq; | 917 | chip->iobase = pci_resource_start(dev->pci, 0); |
960 | chip->iobase = pci_resource_start(saadev->pci, 0); | ||
961 | 918 | ||
962 | err = request_irq(saadev->pci->irq, saa7134_alsa_irq, | 919 | |
963 | SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev); | 920 | err = request_irq(dev->pci->irq, saa7134_alsa_irq, |
921 | SA_SHIRQ | SA_INTERRUPT, dev->name, | ||
922 | (void*) &dev->dmasound); | ||
964 | 923 | ||
965 | if (err < 0) { | 924 | if (err < 0) { |
966 | printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n", | 925 | printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n", |
967 | saadev->name, saadev->pci->irq); | 926 | dev->name, dev->pci->irq); |
968 | goto __nodev; | 927 | goto __nodev; |
969 | } | 928 | } |
970 | 929 | ||
971 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | 930 | chip->irq = dev->pci->irq; |
972 | goto __nodev; | 931 | |
973 | } | 932 | init_MUTEX(&dev->dmasound.lock); |
974 | 933 | ||
975 | if ((err = snd_card_saa7134_new_mixer(chip)) < 0) | 934 | if ((err = snd_card_saa7134_new_mixer(chip)) < 0) |
976 | goto __nodev; | 935 | goto __nodev; |
@@ -984,16 +943,15 @@ int alsa_card_saa7134_create (struct saa7134_dev *saadev) | |||
984 | 943 | ||
985 | strcpy(card->shortname, "SAA7134"); | 944 | strcpy(card->shortname, "SAA7134"); |
986 | sprintf(card->longname, "%s at 0x%lx irq %d", | 945 | sprintf(card->longname, "%s at 0x%lx irq %d", |
987 | chip->saadev->name, chip->iobase, chip->irq); | 946 | chip->dev->name, chip->iobase, chip->irq); |
988 | 947 | ||
989 | if ((err = snd_card_register(card)) == 0) { | 948 | if ((err = snd_card_register(card)) == 0) { |
990 | snd_saa7134_cards[dev] = card; | 949 | snd_saa7134_cards[devnum] = card; |
991 | return 0; | 950 | return 0; |
992 | } | 951 | } |
993 | 952 | ||
994 | __nodev: | 953 | __nodev: |
995 | snd_card_free(card); | 954 | snd_card_free(card); |
996 | kfree(chip); | ||
997 | return err; | 955 | return err; |
998 | } | 956 | } |
999 | 957 | ||
@@ -1007,21 +965,29 @@ __nodev: | |||
1007 | 965 | ||
1008 | static int saa7134_alsa_init(void) | 966 | static int saa7134_alsa_init(void) |
1009 | { | 967 | { |
1010 | struct saa7134_dev *saadev = NULL; | 968 | struct saa7134_dev *dev = NULL; |
1011 | struct list_head *list; | 969 | struct list_head *list; |
1012 | 970 | ||
1013 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); | 971 | position = 0; |
1014 | 972 | ||
1015 | list_for_each(list,&saa7134_devlist) { | 973 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); |
1016 | saadev = list_entry(list, struct saa7134_dev, devlist); | ||
1017 | alsa_card_saa7134_create(saadev); | ||
1018 | } | ||
1019 | 974 | ||
1020 | if (saadev == NULL) | 975 | list_for_each(list,&saa7134_devlist) { |
976 | dev = list_entry(list, struct saa7134_dev, devlist); | ||
977 | if (dev->dmasound.priv_data == NULL) { | ||
978 | dev->dmasound.priv_data = dev; | ||
979 | alsa_card_saa7134_create(dev,position); | ||
980 | position++; | ||
981 | } else { | ||
982 | printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name); | ||
983 | return -EBUSY; | ||
984 | } | ||
985 | } | ||
986 | |||
987 | if (dev == NULL) | ||
1021 | printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); | 988 | printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); |
1022 | 989 | ||
1023 | return 0; | 990 | return 0; |
1024 | |||
1025 | } | 991 | } |
1026 | 992 | ||
1027 | /* | 993 | /* |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 663d03e5bc67..75abc20b0ccd 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -2529,6 +2529,32 @@ struct saa7134_board saa7134_boards[] = { | |||
2529 | .amux = LINE1, | 2529 | .amux = LINE1, |
2530 | }}, | 2530 | }}, |
2531 | }, | 2531 | }, |
2532 | [SAA7134_BOARD_MSI_TVATANYWHERE_PLUS] = { | ||
2533 | .name = "MSI TV@Anywhere plus", | ||
2534 | .audio_clock = 0x00187de7, | ||
2535 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
2536 | .radio_type = UNSET, | ||
2537 | .tuner_addr = ADDR_UNSET, | ||
2538 | .radio_addr = ADDR_UNSET, | ||
2539 | .inputs = {{ | ||
2540 | .name = name_tv, | ||
2541 | .vmux = 1, | ||
2542 | .amux = TV, | ||
2543 | .tv = 1, | ||
2544 | },{ | ||
2545 | .name = name_comp1, | ||
2546 | .vmux = 3, | ||
2547 | .amux = LINE1, | ||
2548 | },{ | ||
2549 | .name = name_svideo, | ||
2550 | .vmux = 0, | ||
2551 | .amux = LINE1, | ||
2552 | }}, | ||
2553 | .radio = { | ||
2554 | .name = name_radio, | ||
2555 | .amux = LINE1, | ||
2556 | }, | ||
2557 | }, | ||
2532 | }; | 2558 | }; |
2533 | 2559 | ||
2534 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 2560 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
@@ -2970,6 +2996,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2970 | .subdevice = 0x2018, | 2996 | .subdevice = 0x2018, |
2971 | .driver_data = SAA7134_BOARD_PHILIPS_TIGER, | 2997 | .driver_data = SAA7134_BOARD_PHILIPS_TIGER, |
2972 | },{ | 2998 | },{ |
2999 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
3000 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
3001 | .subvendor = 0x1462, | ||
3002 | .subdevice = 0x6231, | ||
3003 | .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS, | ||
3004 | },{ | ||
2973 | /* --- boards without eeprom + subsystem ID --- */ | 3005 | /* --- boards without eeprom + subsystem ID --- */ |
2974 | .vendor = PCI_VENDOR_ID_PHILIPS, | 3006 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2975 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 3007 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 19b88744fb31..4275d2ddb864 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -53,13 +53,13 @@ static unsigned int gpio_tracking = 0; | |||
53 | module_param(gpio_tracking, int, 0644); | 53 | module_param(gpio_tracking, int, 0644); |
54 | MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]"); | 54 | MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]"); |
55 | 55 | ||
56 | static unsigned int oss = 0; | ||
57 | module_param(oss, int, 0444); | ||
58 | MODULE_PARM_DESC(oss,"register oss devices (default: no)"); | ||
59 | |||
60 | static unsigned int alsa = 0; | 56 | static unsigned int alsa = 0; |
61 | module_param(alsa, int, 0444); | 57 | module_param(alsa, int, 0644); |
62 | MODULE_PARM_DESC(alsa,"register alsa devices (default: no)"); | 58 | MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]"); |
59 | |||
60 | static unsigned int oss = 0; | ||
61 | module_param(oss, int, 0644); | ||
62 | MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]"); | ||
63 | 63 | ||
64 | static unsigned int latency = UNSET; | 64 | static unsigned int latency = UNSET; |
65 | module_param(latency, int, 0444); | 65 | module_param(latency, int, 0444); |
@@ -68,24 +68,18 @@ MODULE_PARM_DESC(latency,"pci latency timer"); | |||
68 | static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 68 | static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
69 | static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 69 | static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
70 | static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 70 | static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
71 | static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | ||
72 | static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | ||
73 | static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 71 | static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
74 | static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 72 | static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
75 | 73 | ||
76 | module_param_array(video_nr, int, NULL, 0444); | 74 | module_param_array(video_nr, int, NULL, 0444); |
77 | module_param_array(vbi_nr, int, NULL, 0444); | 75 | module_param_array(vbi_nr, int, NULL, 0444); |
78 | module_param_array(radio_nr, int, NULL, 0444); | 76 | module_param_array(radio_nr, int, NULL, 0444); |
79 | module_param_array(dsp_nr, int, NULL, 0444); | ||
80 | module_param_array(mixer_nr, int, NULL, 0444); | ||
81 | module_param_array(tuner, int, NULL, 0444); | 77 | module_param_array(tuner, int, NULL, 0444); |
82 | module_param_array(card, int, NULL, 0444); | 78 | module_param_array(card, int, NULL, 0444); |
83 | 79 | ||
84 | MODULE_PARM_DESC(video_nr, "video device number"); | 80 | MODULE_PARM_DESC(video_nr, "video device number"); |
85 | MODULE_PARM_DESC(vbi_nr, "vbi device number"); | 81 | MODULE_PARM_DESC(vbi_nr, "vbi device number"); |
86 | MODULE_PARM_DESC(radio_nr, "radio device number"); | 82 | MODULE_PARM_DESC(radio_nr, "radio device number"); |
87 | MODULE_PARM_DESC(dsp_nr, "oss dsp device number"); | ||
88 | MODULE_PARM_DESC(mixer_nr, "oss mixer device number"); | ||
89 | MODULE_PARM_DESC(tuner, "tuner type"); | 83 | MODULE_PARM_DESC(tuner, "tuner type"); |
90 | MODULE_PARM_DESC(card, "card type"); | 84 | MODULE_PARM_DESC(card, "card type"); |
91 | 85 | ||
@@ -195,6 +189,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg) | |||
195 | static int need_empress; | 189 | static int need_empress; |
196 | static int need_dvb; | 190 | static int need_dvb; |
197 | static int need_alsa; | 191 | static int need_alsa; |
192 | static int need_oss; | ||
198 | 193 | ||
199 | static int pending_call(struct notifier_block *self, unsigned long state, | 194 | static int pending_call(struct notifier_block *self, unsigned long state, |
200 | void *module) | 195 | void *module) |
@@ -208,6 +203,8 @@ static int pending_call(struct notifier_block *self, unsigned long state, | |||
208 | request_module("saa7134-dvb"); | 203 | request_module("saa7134-dvb"); |
209 | if (need_alsa) | 204 | if (need_alsa) |
210 | request_module("saa7134-alsa"); | 205 | request_module("saa7134-alsa"); |
206 | if (need_oss) | ||
207 | request_module("saa7134-oss"); | ||
211 | return NOTIFY_DONE; | 208 | return NOTIFY_DONE; |
212 | } | 209 | } |
213 | 210 | ||
@@ -218,10 +215,11 @@ static struct notifier_block pending_notifier = { | |||
218 | 215 | ||
219 | static void request_module_depend(char *name, int *flag) | 216 | static void request_module_depend(char *name, int *flag) |
220 | { | 217 | { |
218 | int err; | ||
221 | switch (THIS_MODULE->state) { | 219 | switch (THIS_MODULE->state) { |
222 | case MODULE_STATE_COMING: | 220 | case MODULE_STATE_COMING: |
223 | if (!pending_registered) { | 221 | if (!pending_registered) { |
224 | register_module_notifier(&pending_notifier); | 222 | err = register_module_notifier(&pending_notifier); |
225 | pending_registered = 1; | 223 | pending_registered = 1; |
226 | } | 224 | } |
227 | *flag = 1; | 225 | *flag = 1; |
@@ -578,12 +576,14 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
578 | goto out; | 576 | goto out; |
579 | } | 577 | } |
580 | 578 | ||
581 | /* If alsa support is active and we get a sound report, exit | 579 | /* If dmasound support is active and we get a sound report, exit |
582 | and let the saa7134-alsa module deal with it */ | 580 | and let the saa7134-alsa/oss module deal with it */ |
583 | 581 | ||
584 | if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) { | 582 | if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && |
583 | (dev->dmasound.priv_data != NULL) ) | ||
584 | { | ||
585 | if (irq_debug > 1) | 585 | if (irq_debug > 1) |
586 | printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n", | 586 | printk(KERN_DEBUG "%s/irq: ignoring interrupt for DMA sound\n", |
587 | dev->name); | 587 | dev->name); |
588 | goto out; | 588 | goto out; |
589 | } | 589 | } |
@@ -609,12 +609,6 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
609 | card_has_mpeg(dev)) | 609 | card_has_mpeg(dev)) |
610 | saa7134_irq_ts_done(dev,status); | 610 | saa7134_irq_ts_done(dev,status); |
611 | 611 | ||
612 | if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) { | ||
613 | if (oss) { | ||
614 | saa7134_irq_oss_done(dev,status); | ||
615 | } | ||
616 | } | ||
617 | |||
618 | if ((report & (SAA7134_IRQ_REPORT_GPIO16 | | 612 | if ((report & (SAA7134_IRQ_REPORT_GPIO16 | |
619 | SAA7134_IRQ_REPORT_GPIO18)) && | 613 | SAA7134_IRQ_REPORT_GPIO18)) && |
620 | dev->remote) | 614 | dev->remote) |
@@ -689,14 +683,6 @@ static int saa7134_hwinit1(struct saa7134_dev *dev) | |||
689 | * audio will not work. | 683 | * audio will not work. |
690 | */ | 684 | */ |
691 | 685 | ||
692 | switch (dev->pci->device) { | ||
693 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | ||
694 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | ||
695 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | ||
696 | saa7134_oss_init1(dev); | ||
697 | break; | ||
698 | } | ||
699 | |||
700 | /* enable peripheral devices */ | 686 | /* enable peripheral devices */ |
701 | saa_writeb(SAA7134_SPECIAL_MODE, 0x01); | 687 | saa_writeb(SAA7134_SPECIAL_MODE, 0x01); |
702 | 688 | ||
@@ -728,8 +714,6 @@ static int saa7134_hwinit2(struct saa7134_dev *dev) | |||
728 | irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | | 714 | irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | |
729 | SAA7134_IRQ2_INTE_GPIO18A | | 715 | SAA7134_IRQ2_INTE_GPIO18A | |
730 | SAA7134_IRQ2_INTE_GPIO16 ); | 716 | SAA7134_IRQ2_INTE_GPIO16 ); |
731 | else if (dev->has_remote == SAA7134_REMOTE_I2C) | ||
732 | request_module("ir-kbd-i2c"); | ||
733 | 717 | ||
734 | saa_writel(SAA7134_IRQ1, 0); | 718 | saa_writel(SAA7134_IRQ1, 0); |
735 | saa_writel(SAA7134_IRQ2, irq2_mask); | 719 | saa_writel(SAA7134_IRQ2, irq2_mask); |
@@ -742,13 +726,6 @@ static int saa7134_hwfini(struct saa7134_dev *dev) | |||
742 | { | 726 | { |
743 | dprintk("hwfini\n"); | 727 | dprintk("hwfini\n"); |
744 | 728 | ||
745 | switch (dev->pci->device) { | ||
746 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | ||
747 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | ||
748 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | ||
749 | saa7134_oss_fini(dev); | ||
750 | break; | ||
751 | } | ||
752 | if (card_has_mpeg(dev)) | 729 | if (card_has_mpeg(dev)) |
753 | saa7134_ts_fini(dev); | 730 | saa7134_ts_fini(dev); |
754 | saa7134_input_fini(dev); | 731 | saa7134_input_fini(dev); |
@@ -986,11 +963,12 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
986 | if (card_is_dvb(dev)) | 963 | if (card_is_dvb(dev)) |
987 | request_module_depend("saa7134-dvb",&need_dvb); | 964 | request_module_depend("saa7134-dvb",&need_dvb); |
988 | 965 | ||
989 | if (!oss && alsa) { | 966 | |
990 | dprintk("Requesting ALSA module\n"); | 967 | if (alsa) |
991 | request_module_depend("saa7134-alsa",&need_alsa); | 968 | request_module_depend("saa7134-alsa",&need_alsa); |
992 | } | ||
993 | 969 | ||
970 | if (oss) | ||
971 | request_module_depend("saa7134-oss",&need_oss); | ||
994 | 972 | ||
995 | v4l2_prio_init(&dev->prio); | 973 | v4l2_prio_init(&dev->prio); |
996 | 974 | ||
@@ -1024,32 +1002,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1024 | dev->name,dev->radio_dev->minor & 0x1f); | 1002 | dev->name,dev->radio_dev->minor & 0x1f); |
1025 | } | 1003 | } |
1026 | 1004 | ||
1027 | /* register oss devices */ | ||
1028 | switch (dev->pci->device) { | ||
1029 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | ||
1030 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | ||
1031 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | ||
1032 | if (oss) { | ||
1033 | err = dev->dmasound.minor_dsp = | ||
1034 | register_sound_dsp(&saa7134_dsp_fops, | ||
1035 | dsp_nr[dev->nr]); | ||
1036 | if (err < 0) { | ||
1037 | goto fail4; | ||
1038 | } | ||
1039 | printk(KERN_INFO "%s: registered device dsp%d\n", | ||
1040 | dev->name,dev->dmasound.minor_dsp >> 4); | ||
1041 | |||
1042 | err = dev->dmasound.minor_mixer = | ||
1043 | register_sound_mixer(&saa7134_mixer_fops, | ||
1044 | mixer_nr[dev->nr]); | ||
1045 | if (err < 0) | ||
1046 | goto fail5; | ||
1047 | printk(KERN_INFO "%s: registered device mixer%d\n", | ||
1048 | dev->name,dev->dmasound.minor_mixer >> 4); | ||
1049 | } | ||
1050 | break; | ||
1051 | } | ||
1052 | |||
1053 | /* everything worked */ | 1005 | /* everything worked */ |
1054 | pci_set_drvdata(pci_dev,dev); | 1006 | pci_set_drvdata(pci_dev,dev); |
1055 | saa7134_devcount++; | 1007 | saa7134_devcount++; |
@@ -1064,17 +1016,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1064 | 1016 | ||
1065 | /* check for signal */ | 1017 | /* check for signal */ |
1066 | saa7134_irq_video_intl(dev); | 1018 | saa7134_irq_video_intl(dev); |
1019 | |||
1067 | return 0; | 1020 | return 0; |
1068 | 1021 | ||
1069 | fail5: | ||
1070 | switch (dev->pci->device) { | ||
1071 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | ||
1072 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | ||
1073 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | ||
1074 | if (oss) | ||
1075 | unregister_sound_dsp(dev->dmasound.minor_dsp); | ||
1076 | break; | ||
1077 | } | ||
1078 | fail4: | 1022 | fail4: |
1079 | saa7134_unregister_video(dev); | 1023 | saa7134_unregister_video(dev); |
1080 | saa7134_i2c_unregister(dev); | 1024 | saa7134_i2c_unregister(dev); |
@@ -1125,19 +1069,16 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) | |||
1125 | saa7134_devcount--; | 1069 | saa7134_devcount--; |
1126 | 1070 | ||
1127 | saa7134_i2c_unregister(dev); | 1071 | saa7134_i2c_unregister(dev); |
1128 | switch (dev->pci->device) { | ||
1129 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | ||
1130 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | ||
1131 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | ||
1132 | if (oss) { | ||
1133 | unregister_sound_mixer(dev->dmasound.minor_mixer); | ||
1134 | unregister_sound_dsp(dev->dmasound.minor_dsp); | ||
1135 | } | ||
1136 | break; | ||
1137 | } | ||
1138 | saa7134_unregister_video(dev); | 1072 | saa7134_unregister_video(dev); |
1139 | 1073 | ||
1140 | /* release ressources */ | 1074 | /* the DMA sound modules should be unloaded before reaching |
1075 | this, but just in case they are still present... */ | ||
1076 | if (dev->dmasound.priv_data != NULL) { | ||
1077 | free_irq(pci_dev->irq, &dev->dmasound); | ||
1078 | dev->dmasound.priv_data = NULL; | ||
1079 | } | ||
1080 | |||
1081 | /* release resources */ | ||
1141 | free_irq(pci_dev->irq, dev); | 1082 | free_irq(pci_dev->irq, dev); |
1142 | iounmap(dev->lmmio); | 1083 | iounmap(dev->lmmio); |
1143 | release_mem_region(pci_resource_start(pci_dev,0), | 1084 | release_mem_region(pci_resource_start(pci_dev,0), |
@@ -1225,7 +1166,7 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients); | |||
1225 | EXPORT_SYMBOL(saa7134_devlist); | 1166 | EXPORT_SYMBOL(saa7134_devlist); |
1226 | EXPORT_SYMBOL(saa7134_boards); | 1167 | EXPORT_SYMBOL(saa7134_boards); |
1227 | 1168 | ||
1228 | /* ----------------- For ALSA -------------------------------- */ | 1169 | /* ----------------- for the DMA sound modules --------------- */ |
1229 | 1170 | ||
1230 | EXPORT_SYMBOL(saa7134_pgtable_free); | 1171 | EXPORT_SYMBOL(saa7134_pgtable_free); |
1231 | EXPORT_SYMBOL(saa7134_pgtable_build); | 1172 | EXPORT_SYMBOL(saa7134_pgtable_build); |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 329accda6d45..e648cc3bc96d 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -485,64 +485,6 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { | |||
485 | 485 | ||
486 | }; | 486 | }; |
487 | 487 | ||
488 | static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | ||
489 | [ 0x59 ] = KEY_MUTE, | ||
490 | [ 0x4a ] = KEY_POWER, | ||
491 | |||
492 | [ 0x18 ] = KEY_TEXT, | ||
493 | [ 0x26 ] = KEY_TV, | ||
494 | [ 0x3d ] = KEY_PRINT, | ||
495 | |||
496 | [ 0x48 ] = KEY_RED, | ||
497 | [ 0x04 ] = KEY_GREEN, | ||
498 | [ 0x11 ] = KEY_YELLOW, | ||
499 | [ 0x00 ] = KEY_BLUE, | ||
500 | |||
501 | [ 0x2d ] = KEY_VOLUMEUP, | ||
502 | [ 0x1e ] = KEY_VOLUMEDOWN, | ||
503 | |||
504 | [ 0x49 ] = KEY_MENU, | ||
505 | |||
506 | [ 0x16 ] = KEY_CHANNELUP, | ||
507 | [ 0x17 ] = KEY_CHANNELDOWN, | ||
508 | |||
509 | [ 0x20 ] = KEY_UP, | ||
510 | [ 0x21 ] = KEY_DOWN, | ||
511 | [ 0x22 ] = KEY_LEFT, | ||
512 | [ 0x23 ] = KEY_RIGHT, | ||
513 | [ 0x0d ] = KEY_SELECT, | ||
514 | |||
515 | |||
516 | |||
517 | [ 0x08 ] = KEY_BACK, | ||
518 | [ 0x07 ] = KEY_REFRESH, | ||
519 | |||
520 | [ 0x2f ] = KEY_ZOOM, | ||
521 | [ 0x29 ] = KEY_RECORD, | ||
522 | |||
523 | [ 0x4b ] = KEY_PAUSE, | ||
524 | [ 0x4d ] = KEY_REWIND, | ||
525 | [ 0x2e ] = KEY_PLAY, | ||
526 | [ 0x4e ] = KEY_FORWARD, | ||
527 | [ 0x53 ] = KEY_PREVIOUS, | ||
528 | [ 0x4c ] = KEY_STOP, | ||
529 | [ 0x54 ] = KEY_NEXT, | ||
530 | |||
531 | [ 0x69 ] = KEY_KP0, | ||
532 | [ 0x6a ] = KEY_KP1, | ||
533 | [ 0x6b ] = KEY_KP2, | ||
534 | [ 0x6c ] = KEY_KP3, | ||
535 | [ 0x6d ] = KEY_KP4, | ||
536 | [ 0x6e ] = KEY_KP5, | ||
537 | [ 0x6f ] = KEY_KP6, | ||
538 | [ 0x70 ] = KEY_KP7, | ||
539 | [ 0x71 ] = KEY_KP8, | ||
540 | [ 0x72 ] = KEY_KP9, | ||
541 | |||
542 | [ 0x74 ] = KEY_CHANNEL, | ||
543 | [ 0x0a ] = KEY_BACKSPACE, | ||
544 | }; | ||
545 | |||
546 | /* Mapping for the 28 key remote control as seen at | 488 | /* Mapping for the 28 key remote control as seen at |
547 | http://www.sednacomputer.com/photo/cardbus-tv.jpg | 489 | http://www.sednacomputer.com/photo/cardbus-tv.jpg |
548 | Pavel Mihaylov <bin@bash.info> */ | 490 | Pavel Mihaylov <bin@bash.info> */ |
@@ -635,57 +577,6 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
635 | return 1; | 577 | return 1; |
636 | } | 578 | } |
637 | 579 | ||
638 | /* The new pinnacle PCTV remote (with the colored buttons) | ||
639 | * | ||
640 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
641 | */ | ||
642 | |||
643 | static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
644 | { | ||
645 | unsigned char b[4]; | ||
646 | unsigned int start = 0,parity = 0,code = 0; | ||
647 | |||
648 | /* poll IR chip */ | ||
649 | if (4 != i2c_master_recv(&ir->c,b,4)) { | ||
650 | i2cdprintk("read error\n"); | ||
651 | return -EIO; | ||
652 | } | ||
653 | |||
654 | for (start = 0; start<4; start++) { | ||
655 | if (b[start] == 0x80) { | ||
656 | code=b[(start+3)%4]; | ||
657 | parity=b[(start+2)%4]; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | /* Empty Request */ | ||
662 | if (parity==0) | ||
663 | return 0; | ||
664 | |||
665 | /* Repeating... */ | ||
666 | if (ir->old == parity) | ||
667 | return 0; | ||
668 | |||
669 | |||
670 | ir->old = parity; | ||
671 | |||
672 | /* Reduce code value to fit inside IR_KEYTAB_SIZE | ||
673 | * | ||
674 | * this is the only value that results in 42 unique | ||
675 | * codes < 128 | ||
676 | */ | ||
677 | |||
678 | code %= 0x88; | ||
679 | |||
680 | *ir_raw = code; | ||
681 | *ir_key = code; | ||
682 | |||
683 | i2cdprintk("Pinnacle PCTV key %02x\n", code); | ||
684 | |||
685 | return 1; | ||
686 | } | ||
687 | |||
688 | |||
689 | void saa7134_input_irq(struct saa7134_dev *dev) | 580 | void saa7134_input_irq(struct saa7134_dev *dev) |
690 | { | 581 | { |
691 | struct saa7134_ir *ir = dev->remote; | 582 | struct saa7134_ir *ir = dev->remote; |
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c index fd53dfcc1644..fd9ed11ab1e2 100644 --- a/drivers/media/video/saa7134/saa7134-oss.c +++ b/drivers/media/video/saa7134/saa7134-oss.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * oss dsp interface | 4 | * oss dsp interface |
5 | * | 5 | * |
6 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | 6 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] |
7 | * 2005 conversion to standalone module: | ||
8 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
7 | * | 9 | * |
8 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -25,7 +27,9 @@ | |||
25 | #include <linux/module.h> | 27 | #include <linux/module.h> |
26 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
27 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/interrupt.h> | ||
28 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/sound.h> | ||
29 | #include <linux/soundcard.h> | 33 | #include <linux/soundcard.h> |
30 | 34 | ||
31 | #include "saa7134-reg.h" | 35 | #include "saa7134-reg.h" |
@@ -33,15 +37,23 @@ | |||
33 | 37 | ||
34 | /* ------------------------------------------------------------------ */ | 38 | /* ------------------------------------------------------------------ */ |
35 | 39 | ||
36 | static unsigned int oss_debug = 0; | 40 | static unsigned int debug = 0; |
37 | module_param(oss_debug, int, 0644); | 41 | module_param(debug, int, 0644); |
38 | MODULE_PARM_DESC(oss_debug,"enable debug messages [oss]"); | 42 | MODULE_PARM_DESC(debug,"enable debug messages [oss]"); |
39 | 43 | ||
40 | static unsigned int oss_rate = 0; | 44 | static unsigned int rate = 0; |
41 | module_param(oss_rate, int, 0444); | 45 | module_param(rate, int, 0444); |
42 | MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)"); | 46 | MODULE_PARM_DESC(rate,"sample rate (valid are: 32000,48000)"); |
43 | 47 | ||
44 | #define dprintk(fmt, arg...) if (oss_debug) \ | 48 | static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
49 | MODULE_PARM_DESC(dsp_nr, "device numbers for SAA7134 capture interface(s)."); | ||
50 | module_param_array(dsp_nr, int, NULL, 0444); | ||
51 | |||
52 | static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | ||
53 | MODULE_PARM_DESC(mixer_nr, "mixer numbers for SAA7134 capture interface(s)."); | ||
54 | module_param_array(mixer_nr, int, NULL, 0444); | ||
55 | |||
56 | #define dprintk(fmt, arg...) if (debug) \ | ||
45 | printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) | 57 | printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) |
46 | 58 | ||
47 | 59 | ||
@@ -369,7 +381,7 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
369 | int __user *p = argp; | 381 | int __user *p = argp; |
370 | int val = 0; | 382 | int val = 0; |
371 | 383 | ||
372 | if (oss_debug > 1) | 384 | if (debug > 1) |
373 | saa7134_print_ioctl(dev->name,cmd); | 385 | saa7134_print_ioctl(dev->name,cmd); |
374 | switch (cmd) { | 386 | switch (cmd) { |
375 | case OSS_GETVERSION: | 387 | case OSS_GETVERSION: |
@@ -665,7 +677,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file, | |||
665 | void __user *argp = (void __user *) arg; | 677 | void __user *argp = (void __user *) arg; |
666 | int __user *p = argp; | 678 | int __user *p = argp; |
667 | 679 | ||
668 | if (oss_debug > 1) | 680 | if (debug > 1) |
669 | saa7134_print_ioctl(dev->name,cmd); | 681 | saa7134_print_ioctl(dev->name,cmd); |
670 | switch (cmd) { | 682 | switch (cmd) { |
671 | case OSS_GETVERSION: | 683 | case OSS_GETVERSION: |
@@ -768,8 +780,41 @@ struct file_operations saa7134_mixer_fops = { | |||
768 | 780 | ||
769 | /* ------------------------------------------------------------------ */ | 781 | /* ------------------------------------------------------------------ */ |
770 | 782 | ||
783 | static irqreturn_t saa7134_oss_irq(int irq, void *dev_id, struct pt_regs *regs) | ||
784 | { | ||
785 | struct saa7134_dmasound *dmasound = dev_id; | ||
786 | struct saa7134_dev *dev = dmasound->priv_data; | ||
787 | unsigned long report, status; | ||
788 | int loop, handled = 0; | ||
789 | |||
790 | for (loop = 0; loop < 10; loop++) { | ||
791 | report = saa_readl(SAA7134_IRQ_REPORT); | ||
792 | status = saa_readl(SAA7134_IRQ_STATUS); | ||
793 | |||
794 | if (report & SAA7134_IRQ_REPORT_DONE_RA3) { | ||
795 | handled = 1; | ||
796 | saa_writel(SAA7134_IRQ_REPORT,report); | ||
797 | saa7134_irq_oss_done(dev, status); | ||
798 | } else { | ||
799 | goto out; | ||
800 | } | ||
801 | } | ||
802 | |||
803 | if (loop == 10) { | ||
804 | dprintk("error! looping IRQ!"); | ||
805 | } | ||
806 | out: | ||
807 | return IRQ_RETVAL(handled); | ||
808 | } | ||
809 | |||
771 | int saa7134_oss_init1(struct saa7134_dev *dev) | 810 | int saa7134_oss_init1(struct saa7134_dev *dev) |
772 | { | 811 | { |
812 | |||
813 | if ((request_irq(dev->pci->irq, saa7134_oss_irq, | ||
814 | SA_SHIRQ | SA_INTERRUPT, dev->name, | ||
815 | (void*) &dev->dmasound)) < 0) | ||
816 | return -1; | ||
817 | |||
773 | /* general */ | 818 | /* general */ |
774 | init_MUTEX(&dev->dmasound.lock); | 819 | init_MUTEX(&dev->dmasound.lock); |
775 | init_waitqueue_head(&dev->dmasound.wq); | 820 | init_waitqueue_head(&dev->dmasound.wq); |
@@ -785,8 +830,8 @@ int saa7134_oss_init1(struct saa7134_dev *dev) | |||
785 | 830 | ||
786 | /* dsp */ | 831 | /* dsp */ |
787 | dev->dmasound.rate = 32000; | 832 | dev->dmasound.rate = 32000; |
788 | if (oss_rate) | 833 | if (rate) |
789 | dev->dmasound.rate = oss_rate; | 834 | dev->dmasound.rate = rate; |
790 | dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000; | 835 | dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000; |
791 | 836 | ||
792 | /* mixer */ | 837 | /* mixer */ |
@@ -840,7 +885,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status) | |||
840 | /* next block addr */ | 885 | /* next block addr */ |
841 | next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks; | 886 | next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks; |
842 | saa_writel(reg,next_blk * dev->dmasound.blksize); | 887 | saa_writel(reg,next_blk * dev->dmasound.blksize); |
843 | if (oss_debug > 2) | 888 | if (debug > 2) |
844 | dprintk("irq: ok, %s, next_blk=%d, addr=%x\n", | 889 | dprintk("irq: ok, %s, next_blk=%d, addr=%x\n", |
845 | (status & 0x10000000) ? "even" : "odd ", next_blk, | 890 | (status & 0x10000000) ? "even" : "odd ", next_blk, |
846 | next_blk * dev->dmasound.blksize); | 891 | next_blk * dev->dmasound.blksize); |
@@ -854,6 +899,98 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status) | |||
854 | spin_unlock(&dev->slock); | 899 | spin_unlock(&dev->slock); |
855 | } | 900 | } |
856 | 901 | ||
902 | int saa7134_dsp_create(struct saa7134_dev *dev) | ||
903 | { | ||
904 | int err; | ||
905 | |||
906 | err = dev->dmasound.minor_dsp = | ||
907 | register_sound_dsp(&saa7134_dsp_fops, | ||
908 | dsp_nr[dev->nr]); | ||
909 | if (err < 0) { | ||
910 | goto fail; | ||
911 | } | ||
912 | printk(KERN_INFO "%s: registered device dsp%d\n", | ||
913 | dev->name,dev->dmasound.minor_dsp >> 4); | ||
914 | |||
915 | err = dev->dmasound.minor_mixer = | ||
916 | register_sound_mixer(&saa7134_mixer_fops, | ||
917 | mixer_nr[dev->nr]); | ||
918 | if (err < 0) | ||
919 | goto fail; | ||
920 | printk(KERN_INFO "%s: registered device mixer%d\n", | ||
921 | dev->name,dev->dmasound.minor_mixer >> 4); | ||
922 | |||
923 | return 0; | ||
924 | |||
925 | fail: | ||
926 | unregister_sound_dsp(dev->dmasound.minor_dsp); | ||
927 | return 0; | ||
928 | |||
929 | |||
930 | } | ||
931 | |||
932 | static int saa7134_oss_init(void) | ||
933 | { | ||
934 | struct saa7134_dev *dev = NULL; | ||
935 | struct list_head *list; | ||
936 | |||
937 | printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n"); | ||
938 | |||
939 | list_for_each(list,&saa7134_devlist) { | ||
940 | dev = list_entry(list, struct saa7134_dev, devlist); | ||
941 | if (dev->dmasound.priv_data == NULL) { | ||
942 | dev->dmasound.priv_data = dev; | ||
943 | saa7134_oss_init1(dev); | ||
944 | saa7134_dsp_create(dev); | ||
945 | } else { | ||
946 | printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name); | ||
947 | return -EBUSY; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | if (dev == NULL) | ||
952 | printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n"); | ||
953 | |||
954 | return 0; | ||
955 | |||
956 | } | ||
957 | |||
958 | void saa7134_oss_exit(void) | ||
959 | { | ||
960 | struct saa7134_dev *dev = NULL; | ||
961 | struct list_head *list; | ||
962 | |||
963 | list_for_each(list,&saa7134_devlist) { | ||
964 | dev = list_entry(list, struct saa7134_dev, devlist); | ||
965 | |||
966 | /* Device isn't registered by OSS, probably ALSA's */ | ||
967 | if (!dev->dmasound.minor_dsp) | ||
968 | continue; | ||
969 | |||
970 | unregister_sound_mixer(dev->dmasound.minor_mixer); | ||
971 | unregister_sound_dsp(dev->dmasound.minor_dsp); | ||
972 | |||
973 | saa7134_oss_fini(dev); | ||
974 | |||
975 | if (dev->pci->irq > 0) { | ||
976 | synchronize_irq(dev->pci->irq); | ||
977 | free_irq(dev->pci->irq,&dev->dmasound); | ||
978 | } | ||
979 | |||
980 | dev->dmasound.priv_data = NULL; | ||
981 | |||
982 | } | ||
983 | |||
984 | printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n"); | ||
985 | |||
986 | return; | ||
987 | } | ||
988 | |||
989 | module_init(saa7134_oss_init); | ||
990 | module_exit(saa7134_oss_exit); | ||
991 | MODULE_LICENSE("GPL"); | ||
992 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | ||
993 | |||
857 | /* ----------------------------------------------------------- */ | 994 | /* ----------------------------------------------------------- */ |
858 | /* | 995 | /* |
859 | * Local variables: | 996 | * Local variables: |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index fb9727471661..244e1973081c 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -208,6 +208,7 @@ struct saa7134_format { | |||
208 | #define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79 | 208 | #define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79 |
209 | #define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80 | 209 | #define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80 |
210 | #define SAA7134_BOARD_PHILIPS_TIGER 81 | 210 | #define SAA7134_BOARD_PHILIPS_TIGER 81 |
211 | #define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82 | ||
211 | 212 | ||
212 | #define SAA7134_MAXBOARDS 8 | 213 | #define SAA7134_MAXBOARDS 8 |
213 | #define SAA7134_INPUT_MAX 8 | 214 | #define SAA7134_INPUT_MAX 8 |
@@ -383,6 +384,7 @@ struct saa7134_dmasound { | |||
383 | unsigned int dma_blk; | 384 | unsigned int dma_blk; |
384 | unsigned int read_offset; | 385 | unsigned int read_offset; |
385 | unsigned int read_count; | 386 | unsigned int read_count; |
387 | void * priv_data; | ||
386 | snd_pcm_substream_t *substream; | 388 | snd_pcm_substream_t *substream; |
387 | }; | 389 | }; |
388 | 390 | ||
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index b2dfe07e9f9d..61d94ddaff41 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
@@ -437,6 +437,10 @@ static void set_audio(struct tuner *t) | |||
437 | t->sgIF = 124; | 437 | t->sgIF = 124; |
438 | t->tda8290_easy_mode = 0x20; | 438 | t->tda8290_easy_mode = 0x20; |
439 | mode = "L"; | 439 | mode = "L"; |
440 | } else if (t->std & V4L2_STD_SECAM_LC) { | ||
441 | t->sgIF = 20; | ||
442 | t->tda8290_easy_mode = 0x40; | ||
443 | mode = "LC"; | ||
440 | } | 444 | } |
441 | tuner_dbg("setting tda8290 to system %s\n", mode); | 445 | tuner_dbg("setting tda8290 to system %s\n", mode); |
442 | } | 446 | } |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 73c4041c35d7..e58abdfcaab8 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -251,7 +251,7 @@ static inline int check_mode(struct tuner *t, char *cmd) | |||
251 | 251 | ||
252 | static char pal[] = "-"; | 252 | static char pal[] = "-"; |
253 | module_param_string(pal, pal, sizeof(pal), 0644); | 253 | module_param_string(pal, pal, sizeof(pal), 0644); |
254 | static char secam[] = "-"; | 254 | static char secam[] = "--"; |
255 | module_param_string(secam, secam, sizeof(secam), 0644); | 255 | module_param_string(secam, secam, sizeof(secam), 0644); |
256 | 256 | ||
257 | /* get more precise norm info from insmod option */ | 257 | /* get more precise norm info from insmod option */ |
@@ -307,8 +307,13 @@ static int tuner_fixup_std(struct tuner *t) | |||
307 | break; | 307 | break; |
308 | case 'l': | 308 | case 'l': |
309 | case 'L': | 309 | case 'L': |
310 | tuner_dbg ("insmod fixup: SECAM => SECAM-L\n"); | 310 | if ((secam[1]=='C')||(secam[1]=='c')) { |
311 | t->std = V4L2_STD_SECAM_L; | 311 | tuner_dbg ("insmod fixup: SECAM => SECAM-L'\n"); |
312 | t->std = V4L2_STD_SECAM_LC; | ||
313 | } else { | ||
314 | tuner_dbg ("insmod fixup: SECAM => SECAM-L\n"); | ||
315 | t->std = V4L2_STD_SECAM_L; | ||
316 | } | ||
312 | break; | 317 | break; |
313 | case '-': | 318 | case '-': |
314 | /* default parameter, do nothing */ | 319 | /* default parameter, do nothing */ |
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index d832205818f2..e0c9fdb9914a 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
@@ -233,7 +233,7 @@ static struct tunertype tuners[] = { | |||
233 | { "Ymec TVision TVF-5533MF", Philips, NTSC, | 233 | { "Ymec TVision TVF-5533MF", Philips, NTSC, |
234 | 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, | 234 | 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, |
235 | 235 | ||
236 | /* 60-68 */ | 236 | /* 60-69 */ |
237 | { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, | 237 | { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, |
238 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, | 238 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, |
239 | { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, | 239 | { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, |
@@ -252,6 +252,8 @@ static struct tunertype tuners[] = { | |||
252 | 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 }, | 252 | 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 }, |
253 | { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC, | 253 | { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC, |
254 | 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 }, | 254 | 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 }, |
255 | { "Tena TNF 5335 MF", Philips, NTSC, | ||
256 | 16*157.25,16*454.00,0x01,0x02,0x04,0x8e,732 }, | ||
255 | }; | 257 | }; |
256 | 258 | ||
257 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | 259 | unsigned const int tuner_count = ARRAY_SIZE(tuners); |
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index 22f286222004..a6936ad74fcf 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c | |||
@@ -5,6 +5,11 @@ | |||
5 | * | 5 | * |
6 | * Based on saa7115 driver | 6 | * Based on saa7115 driver |
7 | * | 7 | * |
8 | * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl> | ||
9 | * - Cleanup | ||
10 | * - V4L2 API update | ||
11 | * - sound fixes | ||
12 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 14 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 15 | * the Free Software Foundation; either version 2 of the License, or |
@@ -31,7 +36,7 @@ | |||
31 | #include <media/audiochip.h> | 36 | #include <media/audiochip.h> |
32 | 37 | ||
33 | MODULE_DESCRIPTION("wm8775 driver"); | 38 | MODULE_DESCRIPTION("wm8775 driver"); |
34 | MODULE_AUTHOR("Ulf Eklund"); | 39 | MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); |
35 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
36 | 41 | ||
37 | #define wm8775_err(fmt, arg...) do { \ | 42 | #define wm8775_err(fmt, arg...) do { \ |
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 1e6bdba26756..166c9b0ad04e 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | #include <asm/div64.h> | 23 | #include <asm/div64.h> |
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/irq.h> | ||
26 | #include <asm/scatterlist.h> | 25 | #include <asm/scatterlist.h> |
27 | #include <asm/sizes.h> | 26 | #include <asm/sizes.h> |
28 | #include <asm/hardware/amba.h> | 27 | #include <asm/hardware/amba.h> |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 48638c8097a5..846a533323a8 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -94,7 +94,7 @@ config MTD_NETSC520 | |||
94 | 94 | ||
95 | config MTD_TS5500 | 95 | config MTD_TS5500 |
96 | tristate "JEDEC Flash device mapped on Technologic Systems TS-5500" | 96 | tristate "JEDEC Flash device mapped on Technologic Systems TS-5500" |
97 | depends on ELAN | 97 | depends on X86 |
98 | select MTD_PARTITIONS | 98 | select MTD_PARTITIONS |
99 | select MTD_JEDECPROBE | 99 | select MTD_JEDECPROBE |
100 | select MTD_CFI_AMDSTD | 100 | select MTD_CFI_AMDSTD |
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 977935a3d898..824e430486c2 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c | |||
@@ -84,6 +84,7 @@ static int max_interrupt_work = 10; | |||
84 | #include <linux/netdevice.h> | 84 | #include <linux/netdevice.h> |
85 | #include <linux/etherdevice.h> | 85 | #include <linux/etherdevice.h> |
86 | #include <linux/pm.h> | 86 | #include <linux/pm.h> |
87 | #include <linux/pm_legacy.h> | ||
87 | #include <linux/skbuff.h> | 88 | #include <linux/skbuff.h> |
88 | #include <linux/delay.h> /* for udelay() */ | 89 | #include <linux/delay.h> /* for udelay() */ |
89 | #include <linux/spinlock.h> | 90 | #include <linux/spinlock.h> |
@@ -173,7 +174,7 @@ struct el3_private { | |||
173 | /* skb send-queue */ | 174 | /* skb send-queue */ |
174 | int head, size; | 175 | int head, size; |
175 | struct sk_buff *queue[SKB_QUEUE_SIZE]; | 176 | struct sk_buff *queue[SKB_QUEUE_SIZE]; |
176 | #ifdef CONFIG_PM | 177 | #ifdef CONFIG_PM_LEGACY |
177 | struct pm_dev *pmdev; | 178 | struct pm_dev *pmdev; |
178 | #endif | 179 | #endif |
179 | enum { | 180 | enum { |
@@ -200,7 +201,7 @@ static void el3_tx_timeout (struct net_device *dev); | |||
200 | static void el3_down(struct net_device *dev); | 201 | static void el3_down(struct net_device *dev); |
201 | static void el3_up(struct net_device *dev); | 202 | static void el3_up(struct net_device *dev); |
202 | static struct ethtool_ops ethtool_ops; | 203 | static struct ethtool_ops ethtool_ops; |
203 | #ifdef CONFIG_PM | 204 | #ifdef CONFIG_PM_LEGACY |
204 | static int el3_suspend(struct pm_dev *pdev); | 205 | static int el3_suspend(struct pm_dev *pdev); |
205 | static int el3_resume(struct pm_dev *pdev); | 206 | static int el3_resume(struct pm_dev *pdev); |
206 | static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data); | 207 | static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data); |
@@ -361,7 +362,7 @@ static void el3_common_remove (struct net_device *dev) | |||
361 | struct el3_private *lp = netdev_priv(dev); | 362 | struct el3_private *lp = netdev_priv(dev); |
362 | 363 | ||
363 | (void) lp; /* Keep gcc quiet... */ | 364 | (void) lp; /* Keep gcc quiet... */ |
364 | #ifdef CONFIG_PM | 365 | #ifdef CONFIG_PM_LEGACY |
365 | if (lp->pmdev) | 366 | if (lp->pmdev) |
366 | pm_unregister(lp->pmdev); | 367 | pm_unregister(lp->pmdev); |
367 | #endif | 368 | #endif |
@@ -571,7 +572,7 @@ no_pnp: | |||
571 | if (err) | 572 | if (err) |
572 | goto out1; | 573 | goto out1; |
573 | 574 | ||
574 | #ifdef CONFIG_PM | 575 | #ifdef CONFIG_PM_LEGACY |
575 | /* register power management */ | 576 | /* register power management */ |
576 | lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback); | 577 | lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback); |
577 | if (lp->pmdev) { | 578 | if (lp->pmdev) { |
@@ -1479,7 +1480,7 @@ el3_up(struct net_device *dev) | |||
1479 | } | 1480 | } |
1480 | 1481 | ||
1481 | /* Power Management support functions */ | 1482 | /* Power Management support functions */ |
1482 | #ifdef CONFIG_PM | 1483 | #ifdef CONFIG_PM_LEGACY |
1483 | 1484 | ||
1484 | static int | 1485 | static int |
1485 | el3_suspend(struct pm_dev *pdev) | 1486 | el3_suspend(struct pm_dev *pdev) |
@@ -1548,7 +1549,7 @@ el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data) | |||
1548 | return 0; | 1549 | return 0; |
1549 | } | 1550 | } |
1550 | 1551 | ||
1551 | #endif /* CONFIG_PM */ | 1552 | #endif /* CONFIG_PM_LEGACY */ |
1552 | 1553 | ||
1553 | /* Parameters that may be passed into the module. */ | 1554 | /* Parameters that may be passed into the module. */ |
1554 | static int debug = -1; | 1555 | static int debug = -1; |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index e3a329539f1c..0f030b73cbb3 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Based on 8260_io/fcc_enet.c | 6 | * Based on 8260_io/fcc_enet.c |
7 | * | 7 | * |
8 | * Author: Andy Fleming | 8 | * Author: Andy Fleming |
9 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) | 9 | * Maintainer: Kumar Gala |
10 | * | 10 | * |
11 | * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. | 11 | * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. |
12 | * | 12 | * |
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 220084e53341..5065ba82cb76 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Based on 8260_io/fcc_enet.c | 6 | * Based on 8260_io/fcc_enet.c |
7 | * | 7 | * |
8 | * Author: Andy Fleming | 8 | * Author: Andy Fleming |
9 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) | 9 | * Maintainer: Kumar Gala |
10 | * | 10 | * |
11 | * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. | 11 | * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. |
12 | * | 12 | * |
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 5a2d810ce575..cfa3cd7c91a0 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Based on e1000 ethtool support | 6 | * Based on e1000 ethtool support |
7 | * | 7 | * |
8 | * Author: Andy Fleming | 8 | * Author: Andy Fleming |
9 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) | 9 | * Maintainer: Kumar Gala |
10 | * | 10 | * |
11 | * Copyright (c) 2003,2004 Freescale Semiconductor, Inc. | 11 | * Copyright (c) 2003,2004 Freescale Semiconductor, Inc. |
12 | * | 12 | * |
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index 9544279e8bcd..04a462c2a5b7 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Provides Bus interface for MIIM regs | 5 | * Provides Bus interface for MIIM regs |
6 | * | 6 | * |
7 | * Author: Andy Fleming | 7 | * Author: Andy Fleming |
8 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) | 8 | * Maintainer: Kumar Gala |
9 | * | 9 | * |
10 | * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. | 10 | * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. |
11 | * | 11 | * |
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h index 56e5665d5c9b..e85eb216fb5b 100644 --- a/drivers/net/gianfar_mii.h +++ b/drivers/net/gianfar_mii.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * Driver for the MDIO bus controller in the Gianfar register space | 5 | * Driver for the MDIO bus controller in the Gianfar register space |
6 | * | 6 | * |
7 | * Author: Andy Fleming | 7 | * Author: Andy Fleming |
8 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) | 8 | * Maintainer: Kumar Gala |
9 | * | 9 | * |
10 | * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. | 10 | * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. |
11 | * | 11 | * |
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index 9bf34681d3df..2e7882eb7d6f 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <asm/byteorder.h> | 40 | #include <asm/byteorder.h> |
41 | 41 | ||
42 | #include <linux/pm.h> | 42 | #include <linux/pm.h> |
43 | #include <linux/pm_legacy.h> | ||
43 | 44 | ||
44 | #include <net/irda/wrapper.h> | 45 | #include <net/irda/wrapper.h> |
45 | #include <net/irda/irda.h> | 46 | #include <net/irda/irda.h> |
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 805714ec9a8a..ee717d0e939e 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <asm/byteorder.h> | 59 | #include <asm/byteorder.h> |
60 | 60 | ||
61 | #include <linux/pm.h> | 61 | #include <linux/pm.h> |
62 | #include <linux/pm_legacy.h> | ||
62 | 63 | ||
63 | #include <net/irda/wrapper.h> | 64 | #include <net/irda/wrapper.h> |
64 | #include <net/irda/irda.h> | 65 | #include <net/irda/irda.h> |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index a10cd184d597..5c2824be4ee6 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -100,14 +100,14 @@ | |||
100 | #define SMC_IO_SHIFT 0 | 100 | #define SMC_IO_SHIFT 0 |
101 | #define SMC_NOWAIT 1 | 101 | #define SMC_NOWAIT 1 |
102 | 102 | ||
103 | #define SMC_inb(a, r) inb((a) + (r)) | 103 | #define SMC_inb(a, r) readb((a) + (r)) |
104 | #define SMC_insb(a, r, p, l) insb((a) + (r), p, (l)) | 104 | #define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) |
105 | #define SMC_inw(a, r) inw((a) + (r)) | 105 | #define SMC_inw(a, r) readw((a) + (r)) |
106 | #define SMC_insw(a, r, p, l) insw((a) + (r), p, l) | 106 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
107 | #define SMC_outb(v, a, r) outb(v, (a) + (r)) | 107 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
108 | #define SMC_outsb(a, r, p, l) outsb((a) + (r), p, (l)) | 108 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) |
109 | #define SMC_outw(v, a, r) outw(v, (a) + (r)) | 109 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
110 | #define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) | 110 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
111 | 111 | ||
112 | #define set_irq_type(irq, type) do {} while (0) | 112 | #define set_irq_type(irq, type) do {} while (0) |
113 | 113 | ||
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index de399563a9db..081717d01374 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
@@ -128,6 +128,8 @@ static struct pci_device_id gem_pci_tbl[] = { | |||
128 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 128 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, |
129 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_SUNGEM, | 129 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_SUNGEM, |
130 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 130 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, |
131 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_GMAC, | ||
132 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
131 | {0, } | 133 | {0, } |
132 | }; | 134 | }; |
133 | 135 | ||
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c index 7c2cf2e76300..032c0f81928e 100644 --- a/drivers/net/wan/sdladrv.c +++ b/drivers/net/wan/sdladrv.c | |||
@@ -1994,7 +1994,7 @@ static int detect_s514 (sdlahw_t* hw) | |||
1994 | modname, hw->irq); | 1994 | modname, hw->irq); |
1995 | 1995 | ||
1996 | /* map the physical PCI memory to virtual memory */ | 1996 | /* map the physical PCI memory to virtual memory */ |
1997 | (void *)hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr, | 1997 | hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr, |
1998 | (unsigned long)MAX_SIZEOF_S514_MEMORY); | 1998 | (unsigned long)MAX_SIZEOF_S514_MEMORY); |
1999 | /* map the physical control register memory to virtual memory */ | 1999 | /* map the physical control register memory to virtual memory */ |
2000 | hw->vector = (unsigned long)ioremap( | 2000 | hw->vector = (unsigned long)ioremap( |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index b0d195d1721a..5e7c7e944c9d 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -1110,8 +1110,7 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv) | |||
1110 | error->elem_len = elem_len; | 1110 | error->elem_len = elem_len; |
1111 | error->log_len = log_len; | 1111 | error->log_len = log_len; |
1112 | error->elem = (struct ipw_error_elem *)error->payload; | 1112 | error->elem = (struct ipw_error_elem *)error->payload; |
1113 | error->log = (struct ipw_event *)(error->elem + | 1113 | error->log = (struct ipw_event *)(error->elem + elem_len); |
1114 | (sizeof(*error->elem) * elem_len)); | ||
1115 | 1114 | ||
1116 | ipw_capture_event_log(priv, log_len, error->log); | 1115 | ipw_capture_event_log(priv, log_len, error->log); |
1117 | 1116 | ||
@@ -8926,6 +8925,10 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, | |||
8926 | struct ipw_scan_request_ext scan; | 8925 | struct ipw_scan_request_ext scan; |
8927 | int err = 0, scan_type; | 8926 | int err = 0, scan_type; |
8928 | 8927 | ||
8928 | if (!(priv->status & STATUS_INIT) || | ||
8929 | (priv->status & STATUS_EXIT_PENDING)) | ||
8930 | return 0; | ||
8931 | |||
8929 | down(&priv->sem); | 8932 | down(&priv->sem); |
8930 | 8933 | ||
8931 | if (priv->status & STATUS_RF_KILL_MASK) { | 8934 | if (priv->status & STATUS_RF_KILL_MASK) { |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 4a3cecca012c..2387e75da0fe 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/interrupt.h> | ||
35 | |||
34 | #include "../pci.h" | 36 | #include "../pci.h" |
35 | #include "pciehp.h" | 37 | #include "pciehp.h" |
36 | 38 | ||
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index a7859a84d1ae..4b35097b3d9f 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c | |||
@@ -253,7 +253,7 @@ rpaphp_pci_config_slot(struct pci_bus *bus) | |||
253 | if (!dn || !dn->child) | 253 | if (!dn || !dn->child) |
254 | return NULL; | 254 | return NULL; |
255 | 255 | ||
256 | if (systemcfg->platform == PLATFORM_PSERIES_LPAR) { | 256 | if (_machine == PLATFORM_PSERIES_LPAR) { |
257 | of_scan_bus(dn, bus); | 257 | of_scan_bus(dn, bus); |
258 | if (list_empty(&bus->devices)) { | 258 | if (list_empty(&bus->devices)) { |
259 | err("%s: No new device found\n", __FUNCTION__); | 259 | err("%s: No new device found\n", __FUNCTION__); |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 40905a6c8094..9987a6fd65b8 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/interrupt.h> | ||
35 | |||
34 | #include "shpchp.h" | 36 | #include "shpchp.h" |
35 | 37 | ||
36 | #ifdef DEBUG | 38 | #ifdef DEBUG |
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 234cdca6fe13..a30aa74304a2 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
@@ -513,6 +513,11 @@ static int socket_insert(struct pcmcia_socket *skt) | |||
513 | ret = socket_setup(skt, setup_delay); | 513 | ret = socket_setup(skt, setup_delay); |
514 | if (ret == CS_SUCCESS) { | 514 | if (ret == CS_SUCCESS) { |
515 | skt->state |= SOCKET_PRESENT; | 515 | skt->state |= SOCKET_PRESENT; |
516 | |||
517 | printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n", | ||
518 | (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA", | ||
519 | skt->sock); | ||
520 | |||
516 | #ifdef CONFIG_CARDBUS | 521 | #ifdef CONFIG_CARDBUS |
517 | if (skt->state & SOCKET_CARDBUS) { | 522 | if (skt->state & SOCKET_CARDBUS) { |
518 | cb_alloc(skt); | 523 | cb_alloc(skt); |
@@ -598,6 +603,7 @@ static int socket_resume(struct pcmcia_socket *skt) | |||
598 | 603 | ||
599 | static void socket_remove(struct pcmcia_socket *skt) | 604 | static void socket_remove(struct pcmcia_socket *skt) |
600 | { | 605 | { |
606 | printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock); | ||
601 | socket_shutdown(skt); | 607 | socket_shutdown(skt); |
602 | cs_socket_put(skt); | 608 | cs_socket_put(skt); |
603 | } | 609 | } |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 39d096b52926..7f8219f3fd9e 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -544,6 +544,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
544 | list_add_tail(&p_dev->socket_device_list, &s->devices_list); | 544 | list_add_tail(&p_dev->socket_device_list, &s->devices_list); |
545 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 545 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); |
546 | 546 | ||
547 | printk(KERN_NOTICE "pcmcia: registering new device %s\n", | ||
548 | p_dev->devname); | ||
549 | |||
547 | pcmcia_device_query(p_dev); | 550 | pcmcia_device_query(p_dev); |
548 | 551 | ||
549 | if (device_register(&p_dev->dev)) { | 552 | if (device_register(&p_dev->dev)) { |
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 4ddd76239b34..4d56bc9926d6 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c | |||
@@ -1339,10 +1339,7 @@ static struct device_driver i82365_driver = { | |||
1339 | .resume = pcmcia_socket_dev_resume, | 1339 | .resume = pcmcia_socket_dev_resume, |
1340 | }; | 1340 | }; |
1341 | 1341 | ||
1342 | static struct platform_device i82365_device = { | 1342 | static struct platform_device *i82365_device; |
1343 | .name = "i82365", | ||
1344 | .id = 0, | ||
1345 | }; | ||
1346 | 1343 | ||
1347 | static int __init init_i82365(void) | 1344 | static int __init init_i82365(void) |
1348 | { | 1345 | { |
@@ -1352,7 +1349,14 @@ static int __init init_i82365(void) | |||
1352 | if (ret) | 1349 | if (ret) |
1353 | return ret; | 1350 | return ret; |
1354 | 1351 | ||
1355 | ret = platform_device_register(&i82365_device); | 1352 | i82365_device = platform_device_alloc("i82365", 0); |
1353 | if (i82365_device) { | ||
1354 | ret = platform_device_add(i82365_device); | ||
1355 | if (ret) | ||
1356 | platform_device_put(i82365_device); | ||
1357 | } else | ||
1358 | ret = -ENOMEM; | ||
1359 | |||
1356 | if (ret) { | 1360 | if (ret) { |
1357 | driver_unregister(&i82365_driver); | 1361 | driver_unregister(&i82365_driver); |
1358 | return ret; | 1362 | return ret; |
@@ -1365,7 +1369,7 @@ static int __init init_i82365(void) | |||
1365 | 1369 | ||
1366 | if (sockets == 0) { | 1370 | if (sockets == 0) { |
1367 | printk("not found.\n"); | 1371 | printk("not found.\n"); |
1368 | platform_device_unregister(&i82365_device); | 1372 | platform_device_unregister(i82365_device); |
1369 | release_region(i365_base, 2); | 1373 | release_region(i365_base, 2); |
1370 | driver_unregister(&i82365_driver); | 1374 | driver_unregister(&i82365_driver); |
1371 | return -ENODEV; | 1375 | return -ENODEV; |
@@ -1377,7 +1381,7 @@ static int __init init_i82365(void) | |||
1377 | 1381 | ||
1378 | /* register sockets with the pcmcia core */ | 1382 | /* register sockets with the pcmcia core */ |
1379 | for (i = 0; i < sockets; i++) { | 1383 | for (i = 0; i < sockets; i++) { |
1380 | socket[i].socket.dev.dev = &i82365_device.dev; | 1384 | socket[i].socket.dev.dev = &i82365_device->dev; |
1381 | socket[i].socket.ops = &pcic_operations; | 1385 | socket[i].socket.ops = &pcic_operations; |
1382 | socket[i].socket.resource_ops = &pccard_nonstatic_ops; | 1386 | socket[i].socket.resource_ops = &pccard_nonstatic_ops; |
1383 | socket[i].socket.owner = THIS_MODULE; | 1387 | socket[i].socket.owner = THIS_MODULE; |
@@ -1415,7 +1419,7 @@ static void __exit exit_i82365(void) | |||
1415 | if (socket[i].flags & IS_REGISTERED) | 1419 | if (socket[i].flags & IS_REGISTERED) |
1416 | pcmcia_unregister_socket(&socket[i].socket); | 1420 | pcmcia_unregister_socket(&socket[i].socket); |
1417 | } | 1421 | } |
1418 | platform_device_unregister(&i82365_device); | 1422 | platform_device_unregister(i82365_device); |
1419 | if (poll_interval != 0) | 1423 | if (poll_interval != 0) |
1420 | del_timer_sync(&poll_timer); | 1424 | del_timer_sync(&poll_timer); |
1421 | if (grab_irq != 0) | 1425 | if (grab_irq != 0) |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index f5b7d360fc10..1026f2bc3185 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -1179,12 +1179,12 @@ raw3270_create_attributes(struct raw3270 *rp) | |||
1179 | //FIXME: check return code | 1179 | //FIXME: check return code |
1180 | sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); | 1180 | sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); |
1181 | rp->clttydev = | 1181 | rp->clttydev = |
1182 | class_device_create(class3270, | 1182 | class_device_create(class3270, NULL, |
1183 | MKDEV(IBM_TTY3270_MAJOR, rp->minor), | 1183 | MKDEV(IBM_TTY3270_MAJOR, rp->minor), |
1184 | &rp->cdev->dev, "tty%s", | 1184 | &rp->cdev->dev, "tty%s", |
1185 | rp->cdev->dev.bus_id); | 1185 | rp->cdev->dev.bus_id); |
1186 | rp->cltubdev = | 1186 | rp->cltubdev = |
1187 | class_device_create(class3270, | 1187 | class_device_create(class3270, NULL, |
1188 | MKDEV(IBM_FS3270_MAJOR, rp->minor), | 1188 | MKDEV(IBM_FS3270_MAJOR, rp->minor), |
1189 | &rp->cdev->dev, "tub%s", | 1189 | &rp->cdev->dev, "tub%s", |
1190 | rp->cdev->dev.bus_id); | 1190 | rp->cdev->dev.bus_id); |
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c index 5774bdd0e26f..9b988baf0b51 100644 --- a/drivers/sbus/char/rtc.c +++ b/drivers/sbus/char/rtc.c | |||
@@ -210,27 +210,6 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | static long rtc_compat_ioctl(struct file *file, unsigned int cmd, | ||
214 | unsigned long arg) | ||
215 | { | ||
216 | int rval = -ENOIOCTLCMD; | ||
217 | |||
218 | switch (cmd) { | ||
219 | /* | ||
220 | * These two are specific to this driver, the generic rtc ioctls | ||
221 | * are hanlded elsewhere. | ||
222 | */ | ||
223 | case RTCGET: | ||
224 | case RTCSET: | ||
225 | lock_kernel(); | ||
226 | rval = rtc_ioctl(file->f_dentry->d_inode, file, cmd, arg); | ||
227 | unlock_kernel(); | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | return rval; | ||
232 | } | ||
233 | |||
234 | static int rtc_open(struct inode *inode, struct file *file) | 213 | static int rtc_open(struct inode *inode, struct file *file) |
235 | { | 214 | { |
236 | int ret; | 215 | int ret; |
@@ -258,7 +237,6 @@ static struct file_operations rtc_fops = { | |||
258 | .owner = THIS_MODULE, | 237 | .owner = THIS_MODULE, |
259 | .llseek = no_llseek, | 238 | .llseek = no_llseek, |
260 | .ioctl = rtc_ioctl, | 239 | .ioctl = rtc_ioctl, |
261 | .compat_ioctl = rtc_compat_ioctl, | ||
262 | .open = rtc_open, | 240 | .open = rtc_open, |
263 | .release = rtc_release, | 241 | .release = rtc_release, |
264 | }; | 242 | }; |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 84c42c44e04d..20dd85a77813 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -497,7 +497,7 @@ config SCSI_ATA_PIIX | |||
497 | If unsure, say N. | 497 | If unsure, say N. |
498 | 498 | ||
499 | config SCSI_SATA_MV | 499 | config SCSI_SATA_MV |
500 | tristate "Marvell SATA support" | 500 | tristate "Marvell SATA support (HIGHLY EXPERIMENTAL)" |
501 | depends on SCSI_SATA && PCI && EXPERIMENTAL | 501 | depends on SCSI_SATA && PCI && EXPERIMENTAL |
502 | help | 502 | help |
503 | This option enables support for the Marvell Serial ATA family. | 503 | This option enables support for the Marvell Serial ATA family. |
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 57ef7ae387d9..83467a05dc8e 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include <asm/io.h> | 48 | #include <asm/io.h> |
49 | 49 | ||
50 | #define DRV_NAME "ahci" | 50 | #define DRV_NAME "ahci" |
51 | #define DRV_VERSION "1.01" | 51 | #define DRV_VERSION "1.2" |
52 | 52 | ||
53 | 53 | ||
54 | enum { | 54 | enum { |
@@ -134,6 +134,7 @@ enum { | |||
134 | PORT_IRQ_D2H_REG_FIS, | 134 | PORT_IRQ_D2H_REG_FIS, |
135 | 135 | ||
136 | /* PORT_CMD bits */ | 136 | /* PORT_CMD bits */ |
137 | PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ | ||
137 | PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ | 138 | PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ |
138 | PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ | 139 | PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ |
139 | PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ | 140 | PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ |
@@ -441,7 +442,7 @@ static void ahci_phy_reset(struct ata_port *ap) | |||
441 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 442 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
442 | struct ata_taskfile tf; | 443 | struct ata_taskfile tf; |
443 | struct ata_device *dev = &ap->device[0]; | 444 | struct ata_device *dev = &ap->device[0]; |
444 | u32 tmp; | 445 | u32 new_tmp, tmp; |
445 | 446 | ||
446 | __sata_phy_reset(ap); | 447 | __sata_phy_reset(ap); |
447 | 448 | ||
@@ -455,8 +456,21 @@ static void ahci_phy_reset(struct ata_port *ap) | |||
455 | tf.nsect = (tmp) & 0xff; | 456 | tf.nsect = (tmp) & 0xff; |
456 | 457 | ||
457 | dev->class = ata_dev_classify(&tf); | 458 | dev->class = ata_dev_classify(&tf); |
458 | if (!ata_dev_present(dev)) | 459 | if (!ata_dev_present(dev)) { |
459 | ata_port_disable(ap); | 460 | ata_port_disable(ap); |
461 | return; | ||
462 | } | ||
463 | |||
464 | /* Make sure port's ATAPI bit is set appropriately */ | ||
465 | new_tmp = tmp = readl(port_mmio + PORT_CMD); | ||
466 | if (dev->class == ATA_DEV_ATAPI) | ||
467 | new_tmp |= PORT_CMD_ATAPI; | ||
468 | else | ||
469 | new_tmp &= ~PORT_CMD_ATAPI; | ||
470 | if (new_tmp != tmp) { | ||
471 | writel(new_tmp, port_mmio + PORT_CMD); | ||
472 | readl(port_mmio + PORT_CMD); /* flush */ | ||
473 | } | ||
460 | } | 474 | } |
461 | 475 | ||
462 | static u8 ahci_check_status(struct ata_port *ap) | 476 | static u8 ahci_check_status(struct ata_port *ap) |
@@ -474,11 +488,12 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
474 | ata_tf_from_fis(d2h_fis, tf); | 488 | ata_tf_from_fis(d2h_fis, tf); |
475 | } | 489 | } |
476 | 490 | ||
477 | static void ahci_fill_sg(struct ata_queued_cmd *qc) | 491 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc) |
478 | { | 492 | { |
479 | struct ahci_port_priv *pp = qc->ap->private_data; | 493 | struct ahci_port_priv *pp = qc->ap->private_data; |
480 | struct scatterlist *sg; | 494 | struct scatterlist *sg; |
481 | struct ahci_sg *ahci_sg; | 495 | struct ahci_sg *ahci_sg; |
496 | unsigned int n_sg = 0; | ||
482 | 497 | ||
483 | VPRINTK("ENTER\n"); | 498 | VPRINTK("ENTER\n"); |
484 | 499 | ||
@@ -493,8 +508,12 @@ static void ahci_fill_sg(struct ata_queued_cmd *qc) | |||
493 | ahci_sg->addr = cpu_to_le32(addr & 0xffffffff); | 508 | ahci_sg->addr = cpu_to_le32(addr & 0xffffffff); |
494 | ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); | 509 | ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); |
495 | ahci_sg->flags_size = cpu_to_le32(sg_len - 1); | 510 | ahci_sg->flags_size = cpu_to_le32(sg_len - 1); |
511 | |||
496 | ahci_sg++; | 512 | ahci_sg++; |
513 | n_sg++; | ||
497 | } | 514 | } |
515 | |||
516 | return n_sg; | ||
498 | } | 517 | } |
499 | 518 | ||
500 | static void ahci_qc_prep(struct ata_queued_cmd *qc) | 519 | static void ahci_qc_prep(struct ata_queued_cmd *qc) |
@@ -503,13 +522,14 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
503 | struct ahci_port_priv *pp = ap->private_data; | 522 | struct ahci_port_priv *pp = ap->private_data; |
504 | u32 opts; | 523 | u32 opts; |
505 | const u32 cmd_fis_len = 5; /* five dwords */ | 524 | const u32 cmd_fis_len = 5; /* five dwords */ |
525 | unsigned int n_elem; | ||
506 | 526 | ||
507 | /* | 527 | /* |
508 | * Fill in command slot information (currently only one slot, | 528 | * Fill in command slot information (currently only one slot, |
509 | * slot 0, is currently since we don't do queueing) | 529 | * slot 0, is currently since we don't do queueing) |
510 | */ | 530 | */ |
511 | 531 | ||
512 | opts = (qc->n_elem << 16) | cmd_fis_len; | 532 | opts = cmd_fis_len; |
513 | if (qc->tf.flags & ATA_TFLAG_WRITE) | 533 | if (qc->tf.flags & ATA_TFLAG_WRITE) |
514 | opts |= AHCI_CMD_WRITE; | 534 | opts |= AHCI_CMD_WRITE; |
515 | if (is_atapi_taskfile(&qc->tf)) | 535 | if (is_atapi_taskfile(&qc->tf)) |
@@ -533,16 +553,31 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
533 | if (!(qc->flags & ATA_QCFLAG_DMAMAP)) | 553 | if (!(qc->flags & ATA_QCFLAG_DMAMAP)) |
534 | return; | 554 | return; |
535 | 555 | ||
536 | ahci_fill_sg(qc); | 556 | n_elem = ahci_fill_sg(qc); |
557 | |||
558 | pp->cmd_slot[0].opts |= cpu_to_le32(n_elem << 16); | ||
537 | } | 559 | } |
538 | 560 | ||
539 | static void ahci_intr_error(struct ata_port *ap, u32 irq_stat) | 561 | static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) |
540 | { | 562 | { |
541 | void __iomem *mmio = ap->host_set->mmio_base; | 563 | void __iomem *mmio = ap->host_set->mmio_base; |
542 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 564 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
543 | u32 tmp; | 565 | u32 tmp; |
544 | int work; | 566 | int work; |
545 | 567 | ||
568 | if ((ap->device[0].class != ATA_DEV_ATAPI) || | ||
569 | ((irq_stat & PORT_IRQ_TF_ERR) == 0)) | ||
570 | printk(KERN_WARNING "ata%u: port reset, " | ||
571 | "p_is %x is %x pis %x cmd %x tf %x ss %x se %x\n", | ||
572 | ap->id, | ||
573 | irq_stat, | ||
574 | readl(mmio + HOST_IRQ_STAT), | ||
575 | readl(port_mmio + PORT_IRQ_STAT), | ||
576 | readl(port_mmio + PORT_CMD), | ||
577 | readl(port_mmio + PORT_TFDATA), | ||
578 | readl(port_mmio + PORT_SCR_STAT), | ||
579 | readl(port_mmio + PORT_SCR_ERR)); | ||
580 | |||
546 | /* stop DMA */ | 581 | /* stop DMA */ |
547 | tmp = readl(port_mmio + PORT_CMD); | 582 | tmp = readl(port_mmio + PORT_CMD); |
548 | tmp &= ~PORT_CMD_START; | 583 | tmp &= ~PORT_CMD_START; |
@@ -580,8 +615,6 @@ static void ahci_intr_error(struct ata_port *ap, u32 irq_stat) | |||
580 | tmp |= PORT_CMD_START; | 615 | tmp |= PORT_CMD_START; |
581 | writel(tmp, port_mmio + PORT_CMD); | 616 | writel(tmp, port_mmio + PORT_CMD); |
582 | readl(port_mmio + PORT_CMD); /* flush */ | 617 | readl(port_mmio + PORT_CMD); /* flush */ |
583 | |||
584 | printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->id); | ||
585 | } | 618 | } |
586 | 619 | ||
587 | static void ahci_eng_timeout(struct ata_port *ap) | 620 | static void ahci_eng_timeout(struct ata_port *ap) |
@@ -592,17 +625,17 @@ static void ahci_eng_timeout(struct ata_port *ap) | |||
592 | struct ata_queued_cmd *qc; | 625 | struct ata_queued_cmd *qc; |
593 | unsigned long flags; | 626 | unsigned long flags; |
594 | 627 | ||
595 | DPRINTK("ENTER\n"); | 628 | printk(KERN_WARNING "ata%u: handling error/timeout\n", ap->id); |
596 | 629 | ||
597 | spin_lock_irqsave(&host_set->lock, flags); | 630 | spin_lock_irqsave(&host_set->lock, flags); |
598 | 631 | ||
599 | ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT)); | ||
600 | |||
601 | qc = ata_qc_from_tag(ap, ap->active_tag); | 632 | qc = ata_qc_from_tag(ap, ap->active_tag); |
602 | if (!qc) { | 633 | if (!qc) { |
603 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", | 634 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", |
604 | ap->id); | 635 | ap->id); |
605 | } else { | 636 | } else { |
637 | ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); | ||
638 | |||
606 | /* hack alert! We cannot use the supplied completion | 639 | /* hack alert! We cannot use the supplied completion |
607 | * function from inside the ->eh_strategy_handler() thread. | 640 | * function from inside the ->eh_strategy_handler() thread. |
608 | * libata is the only user of ->eh_strategy_handler() in | 641 | * libata is the only user of ->eh_strategy_handler() in |
@@ -637,9 +670,19 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
637 | } | 670 | } |
638 | 671 | ||
639 | if (status & PORT_IRQ_FATAL) { | 672 | if (status & PORT_IRQ_FATAL) { |
640 | ahci_intr_error(ap, status); | 673 | unsigned int err_mask; |
674 | if (status & PORT_IRQ_TF_ERR) | ||
675 | err_mask = AC_ERR_DEV; | ||
676 | else if (status & PORT_IRQ_IF_ERR) | ||
677 | err_mask = AC_ERR_ATA_BUS; | ||
678 | else | ||
679 | err_mask = AC_ERR_HOST_BUS; | ||
680 | |||
681 | /* command processing has stopped due to error; restart */ | ||
682 | ahci_restart_port(ap, status); | ||
683 | |||
641 | if (qc) | 684 | if (qc) |
642 | ata_qc_complete(qc, AC_ERR_OTHER); | 685 | ata_qc_complete(qc, err_mask); |
643 | } | 686 | } |
644 | 687 | ||
645 | return 1; | 688 | return 1; |
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 855428ff37e9..887b2b9ee4aa 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include <linux/libata.h> | 50 | #include <linux/libata.h> |
51 | 51 | ||
52 | #define DRV_NAME "ata_piix" | 52 | #define DRV_NAME "ata_piix" |
53 | #define DRV_VERSION "1.04" | 53 | #define DRV_VERSION "1.05" |
54 | 54 | ||
55 | enum { | 55 | enum { |
56 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ | 56 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ |
@@ -78,9 +78,7 @@ enum { | |||
78 | ich5_sata = 1, | 78 | ich5_sata = 1, |
79 | piix4_pata = 2, | 79 | piix4_pata = 2, |
80 | ich6_sata = 3, | 80 | ich6_sata = 3, |
81 | ich6_sata_rm = 4, | 81 | ich6_sata_ahci = 4, |
82 | ich7_sata = 5, | ||
83 | esb2_sata = 6, | ||
84 | 82 | ||
85 | PIIX_AHCI_DEVICE = 6, | 83 | PIIX_AHCI_DEVICE = 6, |
86 | }; | 84 | }; |
@@ -111,11 +109,11 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
111 | { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, | 109 | { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, |
112 | { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, | 110 | { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, |
113 | { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata }, | 111 | { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata }, |
114 | { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm }, | 112 | { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, |
115 | { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm }, | 113 | { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, |
116 | { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata }, | 114 | { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, |
117 | { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata }, | 115 | { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, |
118 | { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_sata }, | 116 | { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, |
119 | 117 | ||
120 | { } /* terminate list */ | 118 | { } /* terminate list */ |
121 | }; | 119 | }; |
@@ -258,31 +256,7 @@ static struct ata_port_info piix_port_info[] = { | |||
258 | .port_ops = &piix_sata_ops, | 256 | .port_ops = &piix_sata_ops, |
259 | }, | 257 | }, |
260 | 258 | ||
261 | /* ich6_sata_rm */ | 259 | /* ich6_sata_ahci */ |
262 | { | ||
263 | .sht = &piix_sht, | ||
264 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | | ||
265 | PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR | | ||
266 | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI, | ||
267 | .pio_mask = 0x1f, /* pio0-4 */ | ||
268 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
269 | .udma_mask = 0x7f, /* udma0-6 */ | ||
270 | .port_ops = &piix_sata_ops, | ||
271 | }, | ||
272 | |||
273 | /* ich7_sata */ | ||
274 | { | ||
275 | .sht = &piix_sht, | ||
276 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | | ||
277 | PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR | | ||
278 | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI, | ||
279 | .pio_mask = 0x1f, /* pio0-4 */ | ||
280 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
281 | .udma_mask = 0x7f, /* udma0-6 */ | ||
282 | .port_ops = &piix_sata_ops, | ||
283 | }, | ||
284 | |||
285 | /* esb2_sata */ | ||
286 | { | 260 | { |
287 | .sht = &piix_sht, | 261 | .sht = &piix_sht, |
288 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | | 262 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index ebd0de2d1098..aae3a331d753 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -533,8 +533,7 @@ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp) | |||
533 | * @fis: Buffer from which data will be input | 533 | * @fis: Buffer from which data will be input |
534 | * @tf: Taskfile to output | 534 | * @tf: Taskfile to output |
535 | * | 535 | * |
536 | * Converts a standard ATA taskfile to a Serial ATA | 536 | * Converts a serial ATA FIS structure to a standard ATA taskfile. |
537 | * FIS structure (Register - Host to Device). | ||
538 | * | 537 | * |
539 | * LOCKING: | 538 | * LOCKING: |
540 | * Inherited from caller. | 539 | * Inherited from caller. |
@@ -1048,6 +1047,30 @@ static unsigned int ata_pio_modes(const struct ata_device *adev) | |||
1048 | return modes; | 1047 | return modes; |
1049 | } | 1048 | } |
1050 | 1049 | ||
1050 | static int ata_qc_wait_err(struct ata_queued_cmd *qc, | ||
1051 | struct completion *wait) | ||
1052 | { | ||
1053 | int rc = 0; | ||
1054 | |||
1055 | if (wait_for_completion_timeout(wait, 30 * HZ) < 1) { | ||
1056 | /* timeout handling */ | ||
1057 | unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap)); | ||
1058 | |||
1059 | if (!err_mask) { | ||
1060 | printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n", | ||
1061 | qc->ap->id, qc->tf.command); | ||
1062 | } else { | ||
1063 | printk(KERN_WARNING "ata%u: qc timeout (cmd %x)\n", | ||
1064 | qc->ap->id, qc->tf.command); | ||
1065 | rc = -EIO; | ||
1066 | } | ||
1067 | |||
1068 | ata_qc_complete(qc, err_mask); | ||
1069 | } | ||
1070 | |||
1071 | return rc; | ||
1072 | } | ||
1073 | |||
1051 | /** | 1074 | /** |
1052 | * ata_dev_identify - obtain IDENTIFY x DEVICE page | 1075 | * ata_dev_identify - obtain IDENTIFY x DEVICE page |
1053 | * @ap: port on which device we wish to probe resides | 1076 | * @ap: port on which device we wish to probe resides |
@@ -1127,7 +1150,7 @@ retry: | |||
1127 | if (rc) | 1150 | if (rc) |
1128 | goto err_out; | 1151 | goto err_out; |
1129 | else | 1152 | else |
1130 | wait_for_completion(&wait); | 1153 | ata_qc_wait_err(qc, &wait); |
1131 | 1154 | ||
1132 | spin_lock_irqsave(&ap->host_set->lock, flags); | 1155 | spin_lock_irqsave(&ap->host_set->lock, flags); |
1133 | ap->ops->tf_read(ap, &qc->tf); | 1156 | ap->ops->tf_read(ap, &qc->tf); |
@@ -1271,7 +1294,7 @@ retry: | |||
1271 | } | 1294 | } |
1272 | 1295 | ||
1273 | /* ATAPI-specific feature tests */ | 1296 | /* ATAPI-specific feature tests */ |
1274 | else { | 1297 | else if (dev->class == ATA_DEV_ATAPI) { |
1275 | if (ata_id_is_ata(dev->id)) /* sanity check */ | 1298 | if (ata_id_is_ata(dev->id)) /* sanity check */ |
1276 | goto err_out_nosup; | 1299 | goto err_out_nosup; |
1277 | 1300 | ||
@@ -1581,11 +1604,13 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, | |||
1581 | 1604 | ||
1582 | /* | 1605 | /* |
1583 | * Find the mode. | 1606 | * Find the mode. |
1584 | */ | 1607 | */ |
1585 | 1608 | ||
1586 | if (!(s = ata_timing_find_mode(speed))) | 1609 | if (!(s = ata_timing_find_mode(speed))) |
1587 | return -EINVAL; | 1610 | return -EINVAL; |
1588 | 1611 | ||
1612 | memcpy(t, s, sizeof(*s)); | ||
1613 | |||
1589 | /* | 1614 | /* |
1590 | * If the drive is an EIDE drive, it can tell us it needs extended | 1615 | * If the drive is an EIDE drive, it can tell us it needs extended |
1591 | * PIO/MW_DMA cycle timing. | 1616 | * PIO/MW_DMA cycle timing. |
@@ -1606,7 +1631,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, | |||
1606 | * Convert the timing to bus clock counts. | 1631 | * Convert the timing to bus clock counts. |
1607 | */ | 1632 | */ |
1608 | 1633 | ||
1609 | ata_timing_quantize(s, t, T, UT); | 1634 | ata_timing_quantize(t, t, T, UT); |
1610 | 1635 | ||
1611 | /* | 1636 | /* |
1612 | * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T | 1637 | * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T |
@@ -2278,7 +2303,7 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
2278 | if (rc) | 2303 | if (rc) |
2279 | ata_port_disable(ap); | 2304 | ata_port_disable(ap); |
2280 | else | 2305 | else |
2281 | wait_for_completion(&wait); | 2306 | ata_qc_wait_err(qc, &wait); |
2282 | 2307 | ||
2283 | DPRINTK("EXIT\n"); | 2308 | DPRINTK("EXIT\n"); |
2284 | } | 2309 | } |
@@ -2326,7 +2351,7 @@ static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev) | |||
2326 | if (rc) | 2351 | if (rc) |
2327 | goto err_out; | 2352 | goto err_out; |
2328 | 2353 | ||
2329 | wait_for_completion(&wait); | 2354 | ata_qc_wait_err(qc, &wait); |
2330 | 2355 | ||
2331 | swap_buf_le16(dev->id, ATA_ID_WORDS); | 2356 | swap_buf_le16(dev->id, ATA_ID_WORDS); |
2332 | 2357 | ||
@@ -2382,7 +2407,7 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev) | |||
2382 | if (rc) | 2407 | if (rc) |
2383 | ata_port_disable(ap); | 2408 | ata_port_disable(ap); |
2384 | else | 2409 | else |
2385 | wait_for_completion(&wait); | 2410 | ata_qc_wait_err(qc, &wait); |
2386 | 2411 | ||
2387 | DPRINTK("EXIT\n"); | 2412 | DPRINTK("EXIT\n"); |
2388 | } | 2413 | } |
@@ -2410,7 +2435,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
2410 | if (qc->flags & ATA_QCFLAG_SINGLE) | 2435 | if (qc->flags & ATA_QCFLAG_SINGLE) |
2411 | assert(qc->n_elem == 1); | 2436 | assert(qc->n_elem == 1); |
2412 | 2437 | ||
2413 | DPRINTK("unmapping %u sg elements\n", qc->n_elem); | 2438 | VPRINTK("unmapping %u sg elements\n", qc->n_elem); |
2414 | 2439 | ||
2415 | /* if we padded the buffer out to 32-bit bound, and data | 2440 | /* if we padded the buffer out to 32-bit bound, and data |
2416 | * xfer direction is from-device, we must copy from the | 2441 | * xfer direction is from-device, we must copy from the |
@@ -2420,7 +2445,8 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
2420 | pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); | 2445 | pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); |
2421 | 2446 | ||
2422 | if (qc->flags & ATA_QCFLAG_SG) { | 2447 | if (qc->flags & ATA_QCFLAG_SG) { |
2423 | dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir); | 2448 | if (qc->n_elem) |
2449 | dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir); | ||
2424 | /* restore last sg */ | 2450 | /* restore last sg */ |
2425 | sg[qc->orig_n_elem - 1].length += qc->pad_len; | 2451 | sg[qc->orig_n_elem - 1].length += qc->pad_len; |
2426 | if (pad_buf) { | 2452 | if (pad_buf) { |
@@ -2430,8 +2456,10 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
2430 | kunmap_atomic(psg->page, KM_IRQ0); | 2456 | kunmap_atomic(psg->page, KM_IRQ0); |
2431 | } | 2457 | } |
2432 | } else { | 2458 | } else { |
2433 | dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]), | 2459 | if (sg_dma_len(&sg[0]) > 0) |
2434 | sg_dma_len(&sg[0]), dir); | 2460 | dma_unmap_single(ap->host_set->dev, |
2461 | sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), | ||
2462 | dir); | ||
2435 | /* restore sg */ | 2463 | /* restore sg */ |
2436 | sg->length += qc->pad_len; | 2464 | sg->length += qc->pad_len; |
2437 | if (pad_buf) | 2465 | if (pad_buf) |
@@ -2630,6 +2658,11 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
2630 | sg->length, qc->pad_len); | 2658 | sg->length, qc->pad_len); |
2631 | } | 2659 | } |
2632 | 2660 | ||
2661 | if (!sg->length) { | ||
2662 | sg_dma_address(sg) = 0; | ||
2663 | goto skip_map; | ||
2664 | } | ||
2665 | |||
2633 | dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt, | 2666 | dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt, |
2634 | sg->length, dir); | 2667 | sg->length, dir); |
2635 | if (dma_mapping_error(dma_address)) { | 2668 | if (dma_mapping_error(dma_address)) { |
@@ -2639,6 +2672,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
2639 | } | 2672 | } |
2640 | 2673 | ||
2641 | sg_dma_address(sg) = dma_address; | 2674 | sg_dma_address(sg) = dma_address; |
2675 | skip_map: | ||
2642 | sg_dma_len(sg) = sg->length; | 2676 | sg_dma_len(sg) = sg->length; |
2643 | 2677 | ||
2644 | DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), | 2678 | DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), |
@@ -2666,7 +2700,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) | |||
2666 | struct ata_port *ap = qc->ap; | 2700 | struct ata_port *ap = qc->ap; |
2667 | struct scatterlist *sg = qc->__sg; | 2701 | struct scatterlist *sg = qc->__sg; |
2668 | struct scatterlist *lsg = &sg[qc->n_elem - 1]; | 2702 | struct scatterlist *lsg = &sg[qc->n_elem - 1]; |
2669 | int n_elem, dir; | 2703 | int n_elem, pre_n_elem, dir, trim_sg = 0; |
2670 | 2704 | ||
2671 | VPRINTK("ENTER, ata%u\n", ap->id); | 2705 | VPRINTK("ENTER, ata%u\n", ap->id); |
2672 | assert(qc->flags & ATA_QCFLAG_SG); | 2706 | assert(qc->flags & ATA_QCFLAG_SG); |
@@ -2700,13 +2734,24 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) | |||
2700 | sg_dma_len(psg) = ATA_DMA_PAD_SZ; | 2734 | sg_dma_len(psg) = ATA_DMA_PAD_SZ; |
2701 | /* trim last sg */ | 2735 | /* trim last sg */ |
2702 | lsg->length -= qc->pad_len; | 2736 | lsg->length -= qc->pad_len; |
2737 | if (lsg->length == 0) | ||
2738 | trim_sg = 1; | ||
2703 | 2739 | ||
2704 | DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n", | 2740 | DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n", |
2705 | qc->n_elem - 1, lsg->length, qc->pad_len); | 2741 | qc->n_elem - 1, lsg->length, qc->pad_len); |
2706 | } | 2742 | } |
2707 | 2743 | ||
2744 | pre_n_elem = qc->n_elem; | ||
2745 | if (trim_sg && pre_n_elem) | ||
2746 | pre_n_elem--; | ||
2747 | |||
2748 | if (!pre_n_elem) { | ||
2749 | n_elem = 0; | ||
2750 | goto skip_map; | ||
2751 | } | ||
2752 | |||
2708 | dir = qc->dma_dir; | 2753 | dir = qc->dma_dir; |
2709 | n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir); | 2754 | n_elem = dma_map_sg(ap->host_set->dev, sg, pre_n_elem, dir); |
2710 | if (n_elem < 1) { | 2755 | if (n_elem < 1) { |
2711 | /* restore last sg */ | 2756 | /* restore last sg */ |
2712 | lsg->length += qc->pad_len; | 2757 | lsg->length += qc->pad_len; |
@@ -2715,6 +2760,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) | |||
2715 | 2760 | ||
2716 | DPRINTK("%d sg elements mapped\n", n_elem); | 2761 | DPRINTK("%d sg elements mapped\n", n_elem); |
2717 | 2762 | ||
2763 | skip_map: | ||
2718 | qc->n_elem = n_elem; | 2764 | qc->n_elem = n_elem; |
2719 | 2765 | ||
2720 | return 0; | 2766 | return 0; |
@@ -3445,32 +3491,11 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
3445 | { | 3491 | { |
3446 | struct ata_port *ap = qc->ap; | 3492 | struct ata_port *ap = qc->ap; |
3447 | struct ata_host_set *host_set = ap->host_set; | 3493 | struct ata_host_set *host_set = ap->host_set; |
3448 | struct ata_device *dev = qc->dev; | ||
3449 | u8 host_stat = 0, drv_stat; | 3494 | u8 host_stat = 0, drv_stat; |
3450 | unsigned long flags; | 3495 | unsigned long flags; |
3451 | 3496 | ||
3452 | DPRINTK("ENTER\n"); | 3497 | DPRINTK("ENTER\n"); |
3453 | 3498 | ||
3454 | /* FIXME: doesn't this conflict with timeout handling? */ | ||
3455 | if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) { | ||
3456 | struct scsi_cmnd *cmd = qc->scsicmd; | ||
3457 | |||
3458 | if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) { | ||
3459 | |||
3460 | /* finish completing original command */ | ||
3461 | spin_lock_irqsave(&host_set->lock, flags); | ||
3462 | __ata_qc_complete(qc); | ||
3463 | spin_unlock_irqrestore(&host_set->lock, flags); | ||
3464 | |||
3465 | atapi_request_sense(ap, dev, cmd); | ||
3466 | |||
3467 | cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); | ||
3468 | scsi_finish_command(cmd); | ||
3469 | |||
3470 | goto out; | ||
3471 | } | ||
3472 | } | ||
3473 | |||
3474 | spin_lock_irqsave(&host_set->lock, flags); | 3499 | spin_lock_irqsave(&host_set->lock, flags); |
3475 | 3500 | ||
3476 | /* hack alert! We cannot use the supplied completion | 3501 | /* hack alert! We cannot use the supplied completion |
@@ -3511,7 +3536,6 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
3511 | 3536 | ||
3512 | spin_unlock_irqrestore(&host_set->lock, flags); | 3537 | spin_unlock_irqrestore(&host_set->lock, flags); |
3513 | 3538 | ||
3514 | out: | ||
3515 | DPRINTK("EXIT\n"); | 3539 | DPRINTK("EXIT\n"); |
3516 | } | 3540 | } |
3517 | 3541 | ||
@@ -3595,16 +3619,11 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | |||
3595 | 3619 | ||
3596 | qc = ata_qc_new(ap); | 3620 | qc = ata_qc_new(ap); |
3597 | if (qc) { | 3621 | if (qc) { |
3598 | qc->__sg = NULL; | ||
3599 | qc->flags = 0; | ||
3600 | qc->scsicmd = NULL; | 3622 | qc->scsicmd = NULL; |
3601 | qc->ap = ap; | 3623 | qc->ap = ap; |
3602 | qc->dev = dev; | 3624 | qc->dev = dev; |
3603 | qc->cursect = qc->cursg = qc->cursg_ofs = 0; | ||
3604 | qc->nsect = 0; | ||
3605 | qc->nbytes = qc->curbytes = 0; | ||
3606 | 3625 | ||
3607 | ata_tf_init(ap, &qc->tf, dev->devno); | 3626 | ata_qc_reinit(qc); |
3608 | } | 3627 | } |
3609 | 3628 | ||
3610 | return qc; | 3629 | return qc; |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 261be24e1df3..3b4ca55a3332 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -1955,22 +1955,44 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 | |||
1955 | done(cmd); | 1955 | done(cmd); |
1956 | } | 1956 | } |
1957 | 1957 | ||
1958 | void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | 1958 | static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask) |
1959 | struct scsi_cmnd *cmd) | ||
1960 | { | 1959 | { |
1961 | DECLARE_COMPLETION(wait); | 1960 | if (err_mask && ((err_mask & AC_ERR_DEV) == 0)) |
1962 | struct ata_queued_cmd *qc; | 1961 | /* FIXME: not quite right; we don't want the |
1963 | unsigned long flags; | 1962 | * translation of taskfile registers into |
1964 | int rc; | 1963 | * a sense descriptors, since that's only |
1964 | * correct for ATA, not ATAPI | ||
1965 | */ | ||
1966 | ata_gen_ata_desc_sense(qc); | ||
1965 | 1967 | ||
1966 | DPRINTK("ATAPI request sense\n"); | 1968 | qc->scsidone(qc->scsicmd); |
1969 | return 0; | ||
1970 | } | ||
1967 | 1971 | ||
1968 | qc = ata_qc_new_init(ap, dev); | 1972 | /* is it pointless to prefer PIO for "safety reasons"? */ |
1969 | BUG_ON(qc == NULL); | 1973 | static inline int ata_pio_use_silly(struct ata_port *ap) |
1974 | { | ||
1975 | return (ap->flags & ATA_FLAG_PIO_DMA); | ||
1976 | } | ||
1977 | |||
1978 | static void atapi_request_sense(struct ata_queued_cmd *qc) | ||
1979 | { | ||
1980 | struct ata_port *ap = qc->ap; | ||
1981 | struct scsi_cmnd *cmd = qc->scsicmd; | ||
1982 | |||
1983 | DPRINTK("ATAPI request sense\n"); | ||
1970 | 1984 | ||
1971 | /* FIXME: is this needed? */ | 1985 | /* FIXME: is this needed? */ |
1972 | memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); | 1986 | memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); |
1973 | 1987 | ||
1988 | ap->ops->tf_read(ap, &qc->tf); | ||
1989 | |||
1990 | /* fill these in, for the case where they are -not- overwritten */ | ||
1991 | cmd->sense_buffer[0] = 0x70; | ||
1992 | cmd->sense_buffer[2] = qc->tf.feature >> 4; | ||
1993 | |||
1994 | ata_qc_reinit(qc); | ||
1995 | |||
1974 | ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); | 1996 | ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); |
1975 | qc->dma_dir = DMA_FROM_DEVICE; | 1997 | qc->dma_dir = DMA_FROM_DEVICE; |
1976 | 1998 | ||
@@ -1981,22 +2003,20 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | |||
1981 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 2003 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
1982 | qc->tf.command = ATA_CMD_PACKET; | 2004 | qc->tf.command = ATA_CMD_PACKET; |
1983 | 2005 | ||
1984 | qc->tf.protocol = ATA_PROT_ATAPI; | 2006 | if (ata_pio_use_silly(ap)) { |
1985 | qc->tf.lbam = (8 * 1024) & 0xff; | 2007 | qc->tf.protocol = ATA_PROT_ATAPI_DMA; |
1986 | qc->tf.lbah = (8 * 1024) >> 8; | 2008 | qc->tf.feature |= ATAPI_PKT_DMA; |
2009 | } else { | ||
2010 | qc->tf.protocol = ATA_PROT_ATAPI; | ||
2011 | qc->tf.lbam = (8 * 1024) & 0xff; | ||
2012 | qc->tf.lbah = (8 * 1024) >> 8; | ||
2013 | } | ||
1987 | qc->nbytes = SCSI_SENSE_BUFFERSIZE; | 2014 | qc->nbytes = SCSI_SENSE_BUFFERSIZE; |
1988 | 2015 | ||
1989 | qc->waiting = &wait; | 2016 | qc->complete_fn = atapi_sense_complete; |
1990 | qc->complete_fn = ata_qc_complete_noop; | ||
1991 | |||
1992 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
1993 | rc = ata_qc_issue(qc); | ||
1994 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
1995 | 2017 | ||
1996 | if (rc) | 2018 | if (ata_qc_issue(qc)) |
1997 | ata_port_disable(ap); | 2019 | ata_qc_complete(qc, AC_ERR_OTHER); |
1998 | else | ||
1999 | wait_for_completion(&wait); | ||
2000 | 2020 | ||
2001 | DPRINTK("EXIT\n"); | 2021 | DPRINTK("EXIT\n"); |
2002 | } | 2022 | } |
@@ -2008,19 +2028,8 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) | |||
2008 | VPRINTK("ENTER, err_mask 0x%X\n", err_mask); | 2028 | VPRINTK("ENTER, err_mask 0x%X\n", err_mask); |
2009 | 2029 | ||
2010 | if (unlikely(err_mask & AC_ERR_DEV)) { | 2030 | if (unlikely(err_mask & AC_ERR_DEV)) { |
2011 | DPRINTK("request check condition\n"); | ||
2012 | |||
2013 | /* FIXME: command completion with check condition | ||
2014 | * but no sense causes the error handler to run, | ||
2015 | * which then issues REQUEST SENSE, fills in the sense | ||
2016 | * buffer, and completes the command (for the second | ||
2017 | * time). We need to issue REQUEST SENSE some other | ||
2018 | * way, to avoid completing the command twice. | ||
2019 | */ | ||
2020 | cmd->result = SAM_STAT_CHECK_CONDITION; | 2031 | cmd->result = SAM_STAT_CHECK_CONDITION; |
2021 | 2032 | atapi_request_sense(qc); | |
2022 | qc->scsidone(cmd); | ||
2023 | |||
2024 | return 1; | 2033 | return 1; |
2025 | } | 2034 | } |
2026 | 2035 | ||
@@ -2276,6 +2285,12 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) | |||
2276 | tf->device = scsicmd[8]; | 2285 | tf->device = scsicmd[8]; |
2277 | tf->command = scsicmd[9]; | 2286 | tf->command = scsicmd[9]; |
2278 | } | 2287 | } |
2288 | /* | ||
2289 | * If slave is possible, enforce correct master/slave bit | ||
2290 | */ | ||
2291 | if (qc->ap->flags & ATA_FLAG_SLAVE_POSS) | ||
2292 | tf->device = qc->dev->devno ? | ||
2293 | tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; | ||
2279 | 2294 | ||
2280 | /* | 2295 | /* |
2281 | * Filter SET_FEATURES - XFER MODE command -- otherwise, | 2296 | * Filter SET_FEATURES - XFER MODE command -- otherwise, |
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index fad051ca4672..8ebaa694d18e 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
@@ -29,7 +29,7 @@ | |||
29 | #define __LIBATA_H__ | 29 | #define __LIBATA_H__ |
30 | 30 | ||
31 | #define DRV_NAME "libata" | 31 | #define DRV_NAME "libata" |
32 | #define DRV_VERSION "1.12" /* must be exactly four chars */ | 32 | #define DRV_VERSION "1.20" /* must be exactly four chars */ |
33 | 33 | ||
34 | struct ata_scsi_args { | 34 | struct ata_scsi_args { |
35 | u16 *id; | 35 | u16 *id; |
@@ -54,8 +54,6 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); | |||
54 | 54 | ||
55 | 55 | ||
56 | /* libata-scsi.c */ | 56 | /* libata-scsi.c */ |
57 | extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | ||
58 | struct scsi_cmnd *cmd); | ||
59 | extern void ata_scsi_scan_host(struct ata_port *ap); | 57 | extern void ata_scsi_scan_host(struct ata_port *ap); |
60 | extern int ata_scsi_error(struct Scsi_Host *host); | 58 | extern int ata_scsi_error(struct Scsi_Host *host); |
61 | extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, | 59 | extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, |
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 088630a890ed..9687646d73e1 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * sata_mv.c - Marvell SATA support | 2 | * sata_mv.c - Marvell SATA support |
3 | * | 3 | * |
4 | * Copyright 2005: EMC Corporation, all rights reserved. | 4 | * Copyright 2005: EMC Corporation, all rights reserved. |
5 | * | 5 | * |
6 | * Please ALWAYS copy linux-ide@vger.kernel.org on emails. | 6 | * Please ALWAYS copy linux-ide@vger.kernel.org on emails. |
7 | * | 7 | * |
@@ -50,6 +50,9 @@ enum { | |||
50 | MV_PCI_REG_BASE = 0, | 50 | MV_PCI_REG_BASE = 0, |
51 | MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */ | 51 | MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */ |
52 | MV_SATAHC0_REG_BASE = 0x20000, | 52 | MV_SATAHC0_REG_BASE = 0x20000, |
53 | MV_FLASH_CTL = 0x1046c, | ||
54 | MV_GPIO_PORT_CTL = 0x104f0, | ||
55 | MV_RESET_CFG = 0x180d8, | ||
53 | 56 | ||
54 | MV_PCI_REG_SZ = MV_MAJOR_REG_AREA_SZ, | 57 | MV_PCI_REG_SZ = MV_MAJOR_REG_AREA_SZ, |
55 | MV_SATAHC_REG_SZ = MV_MAJOR_REG_AREA_SZ, | 58 | MV_SATAHC_REG_SZ = MV_MAJOR_REG_AREA_SZ, |
@@ -72,11 +75,6 @@ enum { | |||
72 | MV_SG_TBL_SZ = (16 * MV_MAX_SG_CT), | 75 | MV_SG_TBL_SZ = (16 * MV_MAX_SG_CT), |
73 | MV_PORT_PRIV_DMA_SZ = (MV_CRQB_Q_SZ + MV_CRPB_Q_SZ + MV_SG_TBL_SZ), | 76 | MV_PORT_PRIV_DMA_SZ = (MV_CRQB_Q_SZ + MV_CRPB_Q_SZ + MV_SG_TBL_SZ), |
74 | 77 | ||
75 | /* Our DMA boundary is determined by an ePRD being unable to handle | ||
76 | * anything larger than 64KB | ||
77 | */ | ||
78 | MV_DMA_BOUNDARY = 0xffffU, | ||
79 | |||
80 | MV_PORTS_PER_HC = 4, | 78 | MV_PORTS_PER_HC = 4, |
81 | /* == (port / MV_PORTS_PER_HC) to determine HC from 0-7 port */ | 79 | /* == (port / MV_PORTS_PER_HC) to determine HC from 0-7 port */ |
82 | MV_PORT_HC_SHIFT = 2, | 80 | MV_PORT_HC_SHIFT = 2, |
@@ -86,17 +84,10 @@ enum { | |||
86 | /* Host Flags */ | 84 | /* Host Flags */ |
87 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ | 85 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ |
88 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ | 86 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ |
89 | MV_FLAG_GLBL_SFT_RST = (1 << 28), /* Global Soft Reset support */ | ||
90 | MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 87 | MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
91 | ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | | 88 | ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | |
92 | ATA_FLAG_PIO_POLLING), | 89 | ATA_FLAG_PIO_POLLING), |
93 | MV_6XXX_FLAGS = (MV_FLAG_IRQ_COALESCE | | 90 | MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, |
94 | MV_FLAG_GLBL_SFT_RST), | ||
95 | |||
96 | chip_504x = 0, | ||
97 | chip_508x = 1, | ||
98 | chip_604x = 2, | ||
99 | chip_608x = 3, | ||
100 | 91 | ||
101 | CRQB_FLAG_READ = (1 << 0), | 92 | CRQB_FLAG_READ = (1 << 0), |
102 | CRQB_TAG_SHIFT = 1, | 93 | CRQB_TAG_SHIFT = 1, |
@@ -117,8 +108,19 @@ enum { | |||
117 | PCI_MASTER_EMPTY = (1 << 3), | 108 | PCI_MASTER_EMPTY = (1 << 3), |
118 | GLOB_SFT_RST = (1 << 4), | 109 | GLOB_SFT_RST = (1 << 4), |
119 | 110 | ||
120 | PCI_IRQ_CAUSE_OFS = 0x1d58, | 111 | MV_PCI_MODE = 0xd00, |
121 | PCI_IRQ_MASK_OFS = 0x1d5c, | 112 | MV_PCI_EXP_ROM_BAR_CTL = 0xd2c, |
113 | MV_PCI_DISC_TIMER = 0xd04, | ||
114 | MV_PCI_MSI_TRIGGER = 0xc38, | ||
115 | MV_PCI_SERR_MASK = 0xc28, | ||
116 | MV_PCI_XBAR_TMOUT = 0x1d04, | ||
117 | MV_PCI_ERR_LOW_ADDRESS = 0x1d40, | ||
118 | MV_PCI_ERR_HIGH_ADDRESS = 0x1d44, | ||
119 | MV_PCI_ERR_ATTRIBUTE = 0x1d48, | ||
120 | MV_PCI_ERR_COMMAND = 0x1d50, | ||
121 | |||
122 | PCI_IRQ_CAUSE_OFS = 0x1d58, | ||
123 | PCI_IRQ_MASK_OFS = 0x1d5c, | ||
122 | PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */ | 124 | PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */ |
123 | 125 | ||
124 | HC_MAIN_IRQ_CAUSE_OFS = 0x1d60, | 126 | HC_MAIN_IRQ_CAUSE_OFS = 0x1d60, |
@@ -135,7 +137,7 @@ enum { | |||
135 | SELF_INT = (1 << 23), | 137 | SELF_INT = (1 << 23), |
136 | TWSI_INT = (1 << 24), | 138 | TWSI_INT = (1 << 24), |
137 | HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ | 139 | HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ |
138 | HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | | 140 | HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | |
139 | PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | | 141 | PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | |
140 | HC_MAIN_RSVD), | 142 | HC_MAIN_RSVD), |
141 | 143 | ||
@@ -154,6 +156,15 @@ enum { | |||
154 | /* SATA registers */ | 156 | /* SATA registers */ |
155 | SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ | 157 | SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ |
156 | SATA_ACTIVE_OFS = 0x350, | 158 | SATA_ACTIVE_OFS = 0x350, |
159 | PHY_MODE3 = 0x310, | ||
160 | PHY_MODE4 = 0x314, | ||
161 | PHY_MODE2 = 0x330, | ||
162 | MV5_PHY_MODE = 0x74, | ||
163 | MV5_LT_MODE = 0x30, | ||
164 | MV5_PHY_CTL = 0x0C, | ||
165 | SATA_INTERFACE_CTL = 0x050, | ||
166 | |||
167 | MV_M2_PREAMP_MASK = 0x7e0, | ||
157 | 168 | ||
158 | /* Port registers */ | 169 | /* Port registers */ |
159 | EDMA_CFG_OFS = 0, | 170 | EDMA_CFG_OFS = 0, |
@@ -183,17 +194,16 @@ enum { | |||
183 | EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), | 194 | EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), |
184 | EDMA_ERR_LNK_DATA_TX = (0x1f << 26), | 195 | EDMA_ERR_LNK_DATA_TX = (0x1f << 26), |
185 | EDMA_ERR_TRANS_PROTO = (1 << 31), | 196 | EDMA_ERR_TRANS_PROTO = (1 << 31), |
186 | EDMA_ERR_FATAL = (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | | 197 | EDMA_ERR_FATAL = (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | |
187 | EDMA_ERR_DEV_DCON | EDMA_ERR_CRBQ_PAR | | 198 | EDMA_ERR_DEV_DCON | EDMA_ERR_CRBQ_PAR | |
188 | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR | | 199 | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR | |
189 | EDMA_ERR_IORDY | EDMA_ERR_LNK_CTRL_RX_2 | | 200 | EDMA_ERR_IORDY | EDMA_ERR_LNK_CTRL_RX_2 | |
190 | EDMA_ERR_LNK_DATA_RX | | 201 | EDMA_ERR_LNK_DATA_RX | |
191 | EDMA_ERR_LNK_DATA_TX | | 202 | EDMA_ERR_LNK_DATA_TX | |
192 | EDMA_ERR_TRANS_PROTO), | 203 | EDMA_ERR_TRANS_PROTO), |
193 | 204 | ||
194 | EDMA_REQ_Q_BASE_HI_OFS = 0x10, | 205 | EDMA_REQ_Q_BASE_HI_OFS = 0x10, |
195 | EDMA_REQ_Q_IN_PTR_OFS = 0x14, /* also contains BASE_LO */ | 206 | EDMA_REQ_Q_IN_PTR_OFS = 0x14, /* also contains BASE_LO */ |
196 | EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U, | ||
197 | 207 | ||
198 | EDMA_REQ_Q_OUT_PTR_OFS = 0x18, | 208 | EDMA_REQ_Q_OUT_PTR_OFS = 0x18, |
199 | EDMA_REQ_Q_PTR_SHIFT = 5, | 209 | EDMA_REQ_Q_PTR_SHIFT = 5, |
@@ -201,7 +211,6 @@ enum { | |||
201 | EDMA_RSP_Q_BASE_HI_OFS = 0x1c, | 211 | EDMA_RSP_Q_BASE_HI_OFS = 0x1c, |
202 | EDMA_RSP_Q_IN_PTR_OFS = 0x20, | 212 | EDMA_RSP_Q_IN_PTR_OFS = 0x20, |
203 | EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */ | 213 | EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */ |
204 | EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U, | ||
205 | EDMA_RSP_Q_PTR_SHIFT = 3, | 214 | EDMA_RSP_Q_PTR_SHIFT = 3, |
206 | 215 | ||
207 | EDMA_CMD_OFS = 0x28, | 216 | EDMA_CMD_OFS = 0x28, |
@@ -209,14 +218,44 @@ enum { | |||
209 | EDMA_DS = (1 << 1), | 218 | EDMA_DS = (1 << 1), |
210 | ATA_RST = (1 << 2), | 219 | ATA_RST = (1 << 2), |
211 | 220 | ||
221 | EDMA_IORDY_TMOUT = 0x34, | ||
222 | EDMA_ARB_CFG = 0x38, | ||
223 | |||
212 | /* Host private flags (hp_flags) */ | 224 | /* Host private flags (hp_flags) */ |
213 | MV_HP_FLAG_MSI = (1 << 0), | 225 | MV_HP_FLAG_MSI = (1 << 0), |
226 | MV_HP_ERRATA_50XXB0 = (1 << 1), | ||
227 | MV_HP_ERRATA_50XXB2 = (1 << 2), | ||
228 | MV_HP_ERRATA_60X1B2 = (1 << 3), | ||
229 | MV_HP_ERRATA_60X1C0 = (1 << 4), | ||
230 | MV_HP_50XX = (1 << 5), | ||
214 | 231 | ||
215 | /* Port private flags (pp_flags) */ | 232 | /* Port private flags (pp_flags) */ |
216 | MV_PP_FLAG_EDMA_EN = (1 << 0), | 233 | MV_PP_FLAG_EDMA_EN = (1 << 0), |
217 | MV_PP_FLAG_EDMA_DS_ACT = (1 << 1), | 234 | MV_PP_FLAG_EDMA_DS_ACT = (1 << 1), |
218 | }; | 235 | }; |
219 | 236 | ||
237 | #define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX) | ||
238 | #define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0) | ||
239 | |||
240 | enum { | ||
241 | /* Our DMA boundary is determined by an ePRD being unable to handle | ||
242 | * anything larger than 64KB | ||
243 | */ | ||
244 | MV_DMA_BOUNDARY = 0xffffU, | ||
245 | |||
246 | EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U, | ||
247 | |||
248 | EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U, | ||
249 | }; | ||
250 | |||
251 | enum chip_type { | ||
252 | chip_504x, | ||
253 | chip_508x, | ||
254 | chip_5080, | ||
255 | chip_604x, | ||
256 | chip_608x, | ||
257 | }; | ||
258 | |||
220 | /* Command ReQuest Block: 32B */ | 259 | /* Command ReQuest Block: 32B */ |
221 | struct mv_crqb { | 260 | struct mv_crqb { |
222 | u32 sg_addr; | 261 | u32 sg_addr; |
@@ -253,14 +292,37 @@ struct mv_port_priv { | |||
253 | u32 pp_flags; | 292 | u32 pp_flags; |
254 | }; | 293 | }; |
255 | 294 | ||
295 | struct mv_port_signal { | ||
296 | u32 amps; | ||
297 | u32 pre; | ||
298 | }; | ||
299 | |||
300 | struct mv_host_priv; | ||
301 | struct mv_hw_ops { | ||
302 | void (*phy_errata)(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
303 | unsigned int port); | ||
304 | void (*enable_leds)(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
305 | void (*read_preamp)(struct mv_host_priv *hpriv, int idx, | ||
306 | void __iomem *mmio); | ||
307 | int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
308 | unsigned int n_hc); | ||
309 | void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
310 | void (*reset_bus)(struct pci_dev *pdev, void __iomem *mmio); | ||
311 | }; | ||
312 | |||
256 | struct mv_host_priv { | 313 | struct mv_host_priv { |
257 | u32 hp_flags; | 314 | u32 hp_flags; |
315 | struct mv_port_signal signal[8]; | ||
316 | const struct mv_hw_ops *ops; | ||
258 | }; | 317 | }; |
259 | 318 | ||
260 | static void mv_irq_clear(struct ata_port *ap); | 319 | static void mv_irq_clear(struct ata_port *ap); |
261 | static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in); | 320 | static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in); |
262 | static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); | 321 | static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); |
322 | static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in); | ||
323 | static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); | ||
263 | static void mv_phy_reset(struct ata_port *ap); | 324 | static void mv_phy_reset(struct ata_port *ap); |
325 | static void __mv_phy_reset(struct ata_port *ap, int can_sleep); | ||
264 | static void mv_host_stop(struct ata_host_set *host_set); | 326 | static void mv_host_stop(struct ata_host_set *host_set); |
265 | static int mv_port_start(struct ata_port *ap); | 327 | static int mv_port_start(struct ata_port *ap); |
266 | static void mv_port_stop(struct ata_port *ap); | 328 | static void mv_port_stop(struct ata_port *ap); |
@@ -271,6 +333,29 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, | |||
271 | static void mv_eng_timeout(struct ata_port *ap); | 333 | static void mv_eng_timeout(struct ata_port *ap); |
272 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 334 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
273 | 335 | ||
336 | static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
337 | unsigned int port); | ||
338 | static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
339 | static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, | ||
340 | void __iomem *mmio); | ||
341 | static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
342 | unsigned int n_hc); | ||
343 | static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
344 | static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio); | ||
345 | |||
346 | static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
347 | unsigned int port); | ||
348 | static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
349 | static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, | ||
350 | void __iomem *mmio); | ||
351 | static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
352 | unsigned int n_hc); | ||
353 | static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
354 | static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio); | ||
355 | static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
356 | unsigned int port_no); | ||
357 | static void mv_stop_and_reset(struct ata_port *ap); | ||
358 | |||
274 | static struct scsi_host_template mv_sht = { | 359 | static struct scsi_host_template mv_sht = { |
275 | .module = THIS_MODULE, | 360 | .module = THIS_MODULE, |
276 | .name = DRV_NAME, | 361 | .name = DRV_NAME, |
@@ -279,7 +364,7 @@ static struct scsi_host_template mv_sht = { | |||
279 | .eh_strategy_handler = ata_scsi_error, | 364 | .eh_strategy_handler = ata_scsi_error, |
280 | .can_queue = MV_USE_Q_DEPTH, | 365 | .can_queue = MV_USE_Q_DEPTH, |
281 | .this_id = ATA_SHT_THIS_ID, | 366 | .this_id = ATA_SHT_THIS_ID, |
282 | .sg_tablesize = MV_MAX_SG_CT, | 367 | .sg_tablesize = MV_MAX_SG_CT / 2, |
283 | .max_sectors = ATA_MAX_SECTORS, | 368 | .max_sectors = ATA_MAX_SECTORS, |
284 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 369 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
285 | .emulated = ATA_SHT_EMULATED, | 370 | .emulated = ATA_SHT_EMULATED, |
@@ -291,7 +376,34 @@ static struct scsi_host_template mv_sht = { | |||
291 | .ordered_flush = 1, | 376 | .ordered_flush = 1, |
292 | }; | 377 | }; |
293 | 378 | ||
294 | static const struct ata_port_operations mv_ops = { | 379 | static const struct ata_port_operations mv5_ops = { |
380 | .port_disable = ata_port_disable, | ||
381 | |||
382 | .tf_load = ata_tf_load, | ||
383 | .tf_read = ata_tf_read, | ||
384 | .check_status = ata_check_status, | ||
385 | .exec_command = ata_exec_command, | ||
386 | .dev_select = ata_std_dev_select, | ||
387 | |||
388 | .phy_reset = mv_phy_reset, | ||
389 | |||
390 | .qc_prep = mv_qc_prep, | ||
391 | .qc_issue = mv_qc_issue, | ||
392 | |||
393 | .eng_timeout = mv_eng_timeout, | ||
394 | |||
395 | .irq_handler = mv_interrupt, | ||
396 | .irq_clear = mv_irq_clear, | ||
397 | |||
398 | .scr_read = mv5_scr_read, | ||
399 | .scr_write = mv5_scr_write, | ||
400 | |||
401 | .port_start = mv_port_start, | ||
402 | .port_stop = mv_port_stop, | ||
403 | .host_stop = mv_host_stop, | ||
404 | }; | ||
405 | |||
406 | static const struct ata_port_operations mv6_ops = { | ||
295 | .port_disable = ata_port_disable, | 407 | .port_disable = ata_port_disable, |
296 | 408 | ||
297 | .tf_load = ata_tf_load, | 409 | .tf_load = ata_tf_load, |
@@ -323,37 +435,44 @@ static struct ata_port_info mv_port_info[] = { | |||
323 | .sht = &mv_sht, | 435 | .sht = &mv_sht, |
324 | .host_flags = MV_COMMON_FLAGS, | 436 | .host_flags = MV_COMMON_FLAGS, |
325 | .pio_mask = 0x1f, /* pio0-4 */ | 437 | .pio_mask = 0x1f, /* pio0-4 */ |
326 | .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */ | 438 | .udma_mask = 0x7f, /* udma0-6 */ |
327 | .port_ops = &mv_ops, | 439 | .port_ops = &mv5_ops, |
328 | }, | 440 | }, |
329 | { /* chip_508x */ | 441 | { /* chip_508x */ |
330 | .sht = &mv_sht, | 442 | .sht = &mv_sht, |
331 | .host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), | 443 | .host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), |
332 | .pio_mask = 0x1f, /* pio0-4 */ | 444 | .pio_mask = 0x1f, /* pio0-4 */ |
333 | .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */ | 445 | .udma_mask = 0x7f, /* udma0-6 */ |
334 | .port_ops = &mv_ops, | 446 | .port_ops = &mv5_ops, |
447 | }, | ||
448 | { /* chip_5080 */ | ||
449 | .sht = &mv_sht, | ||
450 | .host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), | ||
451 | .pio_mask = 0x1f, /* pio0-4 */ | ||
452 | .udma_mask = 0x7f, /* udma0-6 */ | ||
453 | .port_ops = &mv5_ops, | ||
335 | }, | 454 | }, |
336 | { /* chip_604x */ | 455 | { /* chip_604x */ |
337 | .sht = &mv_sht, | 456 | .sht = &mv_sht, |
338 | .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), | 457 | .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), |
339 | .pio_mask = 0x1f, /* pio0-4 */ | 458 | .pio_mask = 0x1f, /* pio0-4 */ |
340 | .udma_mask = 0x7f, /* udma0-6 */ | 459 | .udma_mask = 0x7f, /* udma0-6 */ |
341 | .port_ops = &mv_ops, | 460 | .port_ops = &mv6_ops, |
342 | }, | 461 | }, |
343 | { /* chip_608x */ | 462 | { /* chip_608x */ |
344 | .sht = &mv_sht, | 463 | .sht = &mv_sht, |
345 | .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 464 | .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | |
346 | MV_FLAG_DUAL_HC), | 465 | MV_FLAG_DUAL_HC), |
347 | .pio_mask = 0x1f, /* pio0-4 */ | 466 | .pio_mask = 0x1f, /* pio0-4 */ |
348 | .udma_mask = 0x7f, /* udma0-6 */ | 467 | .udma_mask = 0x7f, /* udma0-6 */ |
349 | .port_ops = &mv_ops, | 468 | .port_ops = &mv6_ops, |
350 | }, | 469 | }, |
351 | }; | 470 | }; |
352 | 471 | ||
353 | static const struct pci_device_id mv_pci_tbl[] = { | 472 | static const struct pci_device_id mv_pci_tbl[] = { |
354 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x}, | 473 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x}, |
355 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x}, | 474 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x}, |
356 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_508x}, | 475 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_5080}, |
357 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5081), 0, 0, chip_508x}, | 476 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5081), 0, 0, chip_508x}, |
358 | 477 | ||
359 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x}, | 478 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x}, |
@@ -372,6 +491,24 @@ static struct pci_driver mv_pci_driver = { | |||
372 | .remove = ata_pci_remove_one, | 491 | .remove = ata_pci_remove_one, |
373 | }; | 492 | }; |
374 | 493 | ||
494 | static const struct mv_hw_ops mv5xxx_ops = { | ||
495 | .phy_errata = mv5_phy_errata, | ||
496 | .enable_leds = mv5_enable_leds, | ||
497 | .read_preamp = mv5_read_preamp, | ||
498 | .reset_hc = mv5_reset_hc, | ||
499 | .reset_flash = mv5_reset_flash, | ||
500 | .reset_bus = mv5_reset_bus, | ||
501 | }; | ||
502 | |||
503 | static const struct mv_hw_ops mv6xxx_ops = { | ||
504 | .phy_errata = mv6_phy_errata, | ||
505 | .enable_leds = mv6_enable_leds, | ||
506 | .read_preamp = mv6_read_preamp, | ||
507 | .reset_hc = mv6_reset_hc, | ||
508 | .reset_flash = mv6_reset_flash, | ||
509 | .reset_bus = mv_reset_pci_bus, | ||
510 | }; | ||
511 | |||
375 | /* | 512 | /* |
376 | * Functions | 513 | * Functions |
377 | */ | 514 | */ |
@@ -387,11 +524,27 @@ static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc) | |||
387 | return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ)); | 524 | return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ)); |
388 | } | 525 | } |
389 | 526 | ||
527 | static inline unsigned int mv_hc_from_port(unsigned int port) | ||
528 | { | ||
529 | return port >> MV_PORT_HC_SHIFT; | ||
530 | } | ||
531 | |||
532 | static inline unsigned int mv_hardport_from_port(unsigned int port) | ||
533 | { | ||
534 | return port & MV_PORT_MASK; | ||
535 | } | ||
536 | |||
537 | static inline void __iomem *mv_hc_base_from_port(void __iomem *base, | ||
538 | unsigned int port) | ||
539 | { | ||
540 | return mv_hc_base(base, mv_hc_from_port(port)); | ||
541 | } | ||
542 | |||
390 | static inline void __iomem *mv_port_base(void __iomem *base, unsigned int port) | 543 | static inline void __iomem *mv_port_base(void __iomem *base, unsigned int port) |
391 | { | 544 | { |
392 | return (mv_hc_base(base, port >> MV_PORT_HC_SHIFT) + | 545 | return mv_hc_base_from_port(base, port) + |
393 | MV_SATAHC_ARBTR_REG_SZ + | 546 | MV_SATAHC_ARBTR_REG_SZ + |
394 | ((port & MV_PORT_MASK) * MV_PORT_REG_SZ)); | 547 | (mv_hardport_from_port(port) * MV_PORT_REG_SZ); |
395 | } | 548 | } |
396 | 549 | ||
397 | static inline void __iomem *mv_ap_base(struct ata_port *ap) | 550 | static inline void __iomem *mv_ap_base(struct ata_port *ap) |
@@ -399,9 +552,9 @@ static inline void __iomem *mv_ap_base(struct ata_port *ap) | |||
399 | return mv_port_base(ap->host_set->mmio_base, ap->port_no); | 552 | return mv_port_base(ap->host_set->mmio_base, ap->port_no); |
400 | } | 553 | } |
401 | 554 | ||
402 | static inline int mv_get_hc_count(unsigned long hp_flags) | 555 | static inline int mv_get_hc_count(unsigned long host_flags) |
403 | { | 556 | { |
404 | return ((hp_flags & MV_FLAG_DUAL_HC) ? 2 : 1); | 557 | return ((host_flags & MV_FLAG_DUAL_HC) ? 2 : 1); |
405 | } | 558 | } |
406 | 559 | ||
407 | static void mv_irq_clear(struct ata_port *ap) | 560 | static void mv_irq_clear(struct ata_port *ap) |
@@ -453,7 +606,7 @@ static void mv_stop_dma(struct ata_port *ap) | |||
453 | } else { | 606 | } else { |
454 | assert(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS))); | 607 | assert(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS))); |
455 | } | 608 | } |
456 | 609 | ||
457 | /* now properly wait for the eDMA to stop */ | 610 | /* now properly wait for the eDMA to stop */ |
458 | for (i = 1000; i > 0; i--) { | 611 | for (i = 1000; i > 0; i--) { |
459 | reg = readl(port_mmio + EDMA_CMD_OFS); | 612 | reg = readl(port_mmio + EDMA_CMD_OFS); |
@@ -504,7 +657,7 @@ static void mv_dump_all_regs(void __iomem *mmio_base, int port, | |||
504 | struct pci_dev *pdev) | 657 | struct pci_dev *pdev) |
505 | { | 658 | { |
506 | #ifdef ATA_DEBUG | 659 | #ifdef ATA_DEBUG |
507 | void __iomem *hc_base = mv_hc_base(mmio_base, | 660 | void __iomem *hc_base = mv_hc_base(mmio_base, |
508 | port >> MV_PORT_HC_SHIFT); | 661 | port >> MV_PORT_HC_SHIFT); |
509 | void __iomem *port_base; | 662 | void __iomem *port_base; |
510 | int start_port, num_ports, p, start_hc, num_hcs, hc; | 663 | int start_port, num_ports, p, start_hc, num_hcs, hc; |
@@ -518,7 +671,7 @@ static void mv_dump_all_regs(void __iomem *mmio_base, int port, | |||
518 | start_port = port; | 671 | start_port = port; |
519 | num_ports = num_hcs = 1; | 672 | num_ports = num_hcs = 1; |
520 | } | 673 | } |
521 | DPRINTK("All registers for port(s) %u-%u:\n", start_port, | 674 | DPRINTK("All registers for port(s) %u-%u:\n", start_port, |
522 | num_ports > 1 ? num_ports - 1 : start_port); | 675 | num_ports > 1 ? num_ports - 1 : start_port); |
523 | 676 | ||
524 | if (NULL != pdev) { | 677 | if (NULL != pdev) { |
@@ -586,70 +739,6 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) | |||
586 | } | 739 | } |
587 | 740 | ||
588 | /** | 741 | /** |
589 | * mv_global_soft_reset - Perform the 6xxx global soft reset | ||
590 | * @mmio_base: base address of the HBA | ||
591 | * | ||
592 | * This routine only applies to 6xxx parts. | ||
593 | * | ||
594 | * LOCKING: | ||
595 | * Inherited from caller. | ||
596 | */ | ||
597 | static int mv_global_soft_reset(void __iomem *mmio_base) | ||
598 | { | ||
599 | void __iomem *reg = mmio_base + PCI_MAIN_CMD_STS_OFS; | ||
600 | int i, rc = 0; | ||
601 | u32 t; | ||
602 | |||
603 | /* Following procedure defined in PCI "main command and status | ||
604 | * register" table. | ||
605 | */ | ||
606 | t = readl(reg); | ||
607 | writel(t | STOP_PCI_MASTER, reg); | ||
608 | |||
609 | for (i = 0; i < 1000; i++) { | ||
610 | udelay(1); | ||
611 | t = readl(reg); | ||
612 | if (PCI_MASTER_EMPTY & t) { | ||
613 | break; | ||
614 | } | ||
615 | } | ||
616 | if (!(PCI_MASTER_EMPTY & t)) { | ||
617 | printk(KERN_ERR DRV_NAME ": PCI master won't flush\n"); | ||
618 | rc = 1; | ||
619 | goto done; | ||
620 | } | ||
621 | |||
622 | /* set reset */ | ||
623 | i = 5; | ||
624 | do { | ||
625 | writel(t | GLOB_SFT_RST, reg); | ||
626 | t = readl(reg); | ||
627 | udelay(1); | ||
628 | } while (!(GLOB_SFT_RST & t) && (i-- > 0)); | ||
629 | |||
630 | if (!(GLOB_SFT_RST & t)) { | ||
631 | printk(KERN_ERR DRV_NAME ": can't set global reset\n"); | ||
632 | rc = 1; | ||
633 | goto done; | ||
634 | } | ||
635 | |||
636 | /* clear reset and *reenable the PCI master* (not mentioned in spec) */ | ||
637 | i = 5; | ||
638 | do { | ||
639 | writel(t & ~(GLOB_SFT_RST | STOP_PCI_MASTER), reg); | ||
640 | t = readl(reg); | ||
641 | udelay(1); | ||
642 | } while ((GLOB_SFT_RST & t) && (i-- > 0)); | ||
643 | |||
644 | if (GLOB_SFT_RST & t) { | ||
645 | printk(KERN_ERR DRV_NAME ": can't clear global reset\n"); | ||
646 | rc = 1; | ||
647 | } | ||
648 | done: | ||
649 | return rc; | ||
650 | } | ||
651 | |||
652 | /** | ||
653 | * mv_host_stop - Host specific cleanup/stop routine. | 742 | * mv_host_stop - Host specific cleanup/stop routine. |
654 | * @host_set: host data structure | 743 | * @host_set: host data structure |
655 | * | 744 | * |
@@ -702,7 +791,7 @@ static int mv_port_start(struct ata_port *ap) | |||
702 | goto err_out; | 791 | goto err_out; |
703 | memset(pp, 0, sizeof(*pp)); | 792 | memset(pp, 0, sizeof(*pp)); |
704 | 793 | ||
705 | mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, | 794 | mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, |
706 | GFP_KERNEL); | 795 | GFP_KERNEL); |
707 | if (!mem) | 796 | if (!mem) |
708 | goto err_out_pp; | 797 | goto err_out_pp; |
@@ -712,7 +801,7 @@ static int mv_port_start(struct ata_port *ap) | |||
712 | if (rc) | 801 | if (rc) |
713 | goto err_out_priv; | 802 | goto err_out_priv; |
714 | 803 | ||
715 | /* First item in chunk of DMA memory: | 804 | /* First item in chunk of DMA memory: |
716 | * 32-slot command request table (CRQB), 32 bytes each in size | 805 | * 32-slot command request table (CRQB), 32 bytes each in size |
717 | */ | 806 | */ |
718 | pp->crqb = mem; | 807 | pp->crqb = mem; |
@@ -720,7 +809,7 @@ static int mv_port_start(struct ata_port *ap) | |||
720 | mem += MV_CRQB_Q_SZ; | 809 | mem += MV_CRQB_Q_SZ; |
721 | mem_dma += MV_CRQB_Q_SZ; | 810 | mem_dma += MV_CRQB_Q_SZ; |
722 | 811 | ||
723 | /* Second item: | 812 | /* Second item: |
724 | * 32-slot command response table (CRPB), 8 bytes each in size | 813 | * 32-slot command response table (CRPB), 8 bytes each in size |
725 | */ | 814 | */ |
726 | pp->crpb = mem; | 815 | pp->crpb = mem; |
@@ -734,18 +823,18 @@ static int mv_port_start(struct ata_port *ap) | |||
734 | pp->sg_tbl = mem; | 823 | pp->sg_tbl = mem; |
735 | pp->sg_tbl_dma = mem_dma; | 824 | pp->sg_tbl_dma = mem_dma; |
736 | 825 | ||
737 | writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT | | 826 | writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT | |
738 | EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS); | 827 | EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS); |
739 | 828 | ||
740 | writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS); | 829 | writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS); |
741 | writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK, | 830 | writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK, |
742 | port_mmio + EDMA_REQ_Q_IN_PTR_OFS); | 831 | port_mmio + EDMA_REQ_Q_IN_PTR_OFS); |
743 | 832 | ||
744 | writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); | 833 | writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); |
745 | writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS); | 834 | writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS); |
746 | 835 | ||
747 | writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS); | 836 | writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS); |
748 | writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, | 837 | writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, |
749 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); | 838 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); |
750 | 839 | ||
751 | pp->req_producer = pp->rsp_consumer = 0; | 840 | pp->req_producer = pp->rsp_consumer = 0; |
@@ -806,20 +895,30 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) | |||
806 | struct scatterlist *sg; | 895 | struct scatterlist *sg; |
807 | 896 | ||
808 | ata_for_each_sg(sg, qc) { | 897 | ata_for_each_sg(sg, qc) { |
809 | u32 sg_len; | ||
810 | dma_addr_t addr; | 898 | dma_addr_t addr; |
899 | u32 sg_len, len, offset; | ||
811 | 900 | ||
812 | addr = sg_dma_address(sg); | 901 | addr = sg_dma_address(sg); |
813 | sg_len = sg_dma_len(sg); | 902 | sg_len = sg_dma_len(sg); |
814 | 903 | ||
815 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); | 904 | while (sg_len) { |
816 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); | 905 | offset = addr & MV_DMA_BOUNDARY; |
817 | assert(0 == (sg_len & ~MV_DMA_BOUNDARY)); | 906 | len = sg_len; |
818 | pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len); | 907 | if ((offset + sg_len) > 0x10000) |
819 | if (ata_sg_is_last(sg, qc)) | 908 | len = 0x10000 - offset; |
820 | pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); | 909 | |
910 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); | ||
911 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); | ||
912 | pp->sg_tbl[i].flags_size = cpu_to_le32(len); | ||
913 | |||
914 | sg_len -= len; | ||
915 | addr += len; | ||
916 | |||
917 | if (!sg_len && ata_sg_is_last(sg, qc)) | ||
918 | pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); | ||
821 | 919 | ||
822 | i++; | 920 | i++; |
921 | } | ||
823 | } | 922 | } |
824 | } | 923 | } |
825 | 924 | ||
@@ -860,7 +959,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
860 | } | 959 | } |
861 | 960 | ||
862 | /* the req producer index should be the same as we remember it */ | 961 | /* the req producer index should be the same as we remember it */ |
863 | assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> | 962 | assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> |
864 | EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == | 963 | EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == |
865 | pp->req_producer); | 964 | pp->req_producer); |
866 | 965 | ||
@@ -872,9 +971,9 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
872 | assert(MV_MAX_Q_DEPTH > qc->tag); | 971 | assert(MV_MAX_Q_DEPTH > qc->tag); |
873 | flags |= qc->tag << CRQB_TAG_SHIFT; | 972 | flags |= qc->tag << CRQB_TAG_SHIFT; |
874 | 973 | ||
875 | pp->crqb[pp->req_producer].sg_addr = | 974 | pp->crqb[pp->req_producer].sg_addr = |
876 | cpu_to_le32(pp->sg_tbl_dma & 0xffffffff); | 975 | cpu_to_le32(pp->sg_tbl_dma & 0xffffffff); |
877 | pp->crqb[pp->req_producer].sg_addr_hi = | 976 | pp->crqb[pp->req_producer].sg_addr_hi = |
878 | cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16); | 977 | cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16); |
879 | pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags); | 978 | pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags); |
880 | 979 | ||
@@ -897,7 +996,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
897 | #ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */ | 996 | #ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */ |
898 | case ATA_CMD_FPDMA_READ: | 997 | case ATA_CMD_FPDMA_READ: |
899 | case ATA_CMD_FPDMA_WRITE: | 998 | case ATA_CMD_FPDMA_WRITE: |
900 | mv_crqb_pack_cmd(cw++, tf->hob_feature, ATA_REG_FEATURE, 0); | 999 | mv_crqb_pack_cmd(cw++, tf->hob_feature, ATA_REG_FEATURE, 0); |
901 | mv_crqb_pack_cmd(cw++, tf->feature, ATA_REG_FEATURE, 0); | 1000 | mv_crqb_pack_cmd(cw++, tf->feature, ATA_REG_FEATURE, 0); |
902 | break; | 1001 | break; |
903 | #endif /* FIXME: remove this line when NCQ added */ | 1002 | #endif /* FIXME: remove this line when NCQ added */ |
@@ -963,7 +1062,7 @@ static int mv_qc_issue(struct ata_queued_cmd *qc) | |||
963 | pp->req_producer); | 1062 | pp->req_producer); |
964 | /* until we do queuing, the queue should be empty at this point */ | 1063 | /* until we do queuing, the queue should be empty at this point */ |
965 | assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == | 1064 | assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == |
966 | ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >> | 1065 | ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >> |
967 | EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); | 1066 | EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); |
968 | 1067 | ||
969 | mv_inc_q_index(&pp->req_producer); /* now incr producer index */ | 1068 | mv_inc_q_index(&pp->req_producer); /* now incr producer index */ |
@@ -1000,15 +1099,15 @@ static u8 mv_get_crpb_status(struct ata_port *ap) | |||
1000 | out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); | 1099 | out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); |
1001 | 1100 | ||
1002 | /* the response consumer index should be the same as we remember it */ | 1101 | /* the response consumer index should be the same as we remember it */ |
1003 | assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == | 1102 | assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == |
1004 | pp->rsp_consumer); | 1103 | pp->rsp_consumer); |
1005 | 1104 | ||
1006 | /* increment our consumer index... */ | 1105 | /* increment our consumer index... */ |
1007 | pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); | 1106 | pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); |
1008 | 1107 | ||
1009 | /* and, until we do NCQ, there should only be 1 CRPB waiting */ | 1108 | /* and, until we do NCQ, there should only be 1 CRPB waiting */ |
1010 | assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >> | 1109 | assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >> |
1011 | EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == | 1110 | EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == |
1012 | pp->rsp_consumer); | 1111 | pp->rsp_consumer); |
1013 | 1112 | ||
1014 | /* write out our inc'd consumer index so EDMA knows we're caught up */ | 1113 | /* write out our inc'd consumer index so EDMA knows we're caught up */ |
@@ -1056,7 +1155,7 @@ static void mv_err_intr(struct ata_port *ap) | |||
1056 | 1155 | ||
1057 | /* check for fatal here and recover if needed */ | 1156 | /* check for fatal here and recover if needed */ |
1058 | if (EDMA_ERR_FATAL & edma_err_cause) { | 1157 | if (EDMA_ERR_FATAL & edma_err_cause) { |
1059 | mv_phy_reset(ap); | 1158 | mv_stop_and_reset(ap); |
1060 | } | 1159 | } |
1061 | } | 1160 | } |
1062 | 1161 | ||
@@ -1121,6 +1220,10 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1121 | handled++; | 1220 | handled++; |
1122 | } | 1221 | } |
1123 | 1222 | ||
1223 | if (ap && | ||
1224 | (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) | ||
1225 | continue; | ||
1226 | |||
1124 | err_mask = ac_err_mask(ata_status); | 1227 | err_mask = ac_err_mask(ata_status); |
1125 | 1228 | ||
1126 | shift = port << 1; /* (port * 2) */ | 1229 | shift = port << 1; /* (port * 2) */ |
@@ -1132,14 +1235,15 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1132 | err_mask |= AC_ERR_OTHER; | 1235 | err_mask |= AC_ERR_OTHER; |
1133 | handled++; | 1236 | handled++; |
1134 | } | 1237 | } |
1135 | 1238 | ||
1136 | if (handled && ap) { | 1239 | if (handled && ap) { |
1137 | qc = ata_qc_from_tag(ap, ap->active_tag); | 1240 | qc = ata_qc_from_tag(ap, ap->active_tag); |
1138 | if (NULL != qc) { | 1241 | if (NULL != qc) { |
1139 | VPRINTK("port %u IRQ found for qc, " | 1242 | VPRINTK("port %u IRQ found for qc, " |
1140 | "ata_status 0x%x\n", port,ata_status); | 1243 | "ata_status 0x%x\n", port,ata_status); |
1141 | /* mark qc status appropriately */ | 1244 | /* mark qc status appropriately */ |
1142 | ata_qc_complete(qc, err_mask); | 1245 | if (!(qc->tf.ctl & ATA_NIEN)) |
1246 | ata_qc_complete(qc, err_mask); | ||
1143 | } | 1247 | } |
1144 | } | 1248 | } |
1145 | } | 1249 | } |
@@ -1147,7 +1251,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1147 | } | 1251 | } |
1148 | 1252 | ||
1149 | /** | 1253 | /** |
1150 | * mv_interrupt - | 1254 | * mv_interrupt - |
1151 | * @irq: unused | 1255 | * @irq: unused |
1152 | * @dev_instance: private data; in this case the host structure | 1256 | * @dev_instance: private data; in this case the host structure |
1153 | * @regs: unused | 1257 | * @regs: unused |
@@ -1157,7 +1261,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1157 | * routine to handle. Also check for PCI errors which are only | 1261 | * routine to handle. Also check for PCI errors which are only |
1158 | * reported here. | 1262 | * reported here. |
1159 | * | 1263 | * |
1160 | * LOCKING: | 1264 | * LOCKING: |
1161 | * This routine holds the host_set lock while processing pending | 1265 | * This routine holds the host_set lock while processing pending |
1162 | * interrupts. | 1266 | * interrupts. |
1163 | */ | 1267 | */ |
@@ -1203,8 +1307,422 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, | |||
1203 | return IRQ_RETVAL(handled); | 1307 | return IRQ_RETVAL(handled); |
1204 | } | 1308 | } |
1205 | 1309 | ||
1310 | static void __iomem *mv5_phy_base(void __iomem *mmio, unsigned int port) | ||
1311 | { | ||
1312 | void __iomem *hc_mmio = mv_hc_base_from_port(mmio, port); | ||
1313 | unsigned long ofs = (mv_hardport_from_port(port) + 1) * 0x100UL; | ||
1314 | |||
1315 | return hc_mmio + ofs; | ||
1316 | } | ||
1317 | |||
1318 | static unsigned int mv5_scr_offset(unsigned int sc_reg_in) | ||
1319 | { | ||
1320 | unsigned int ofs; | ||
1321 | |||
1322 | switch (sc_reg_in) { | ||
1323 | case SCR_STATUS: | ||
1324 | case SCR_ERROR: | ||
1325 | case SCR_CONTROL: | ||
1326 | ofs = sc_reg_in * sizeof(u32); | ||
1327 | break; | ||
1328 | default: | ||
1329 | ofs = 0xffffffffU; | ||
1330 | break; | ||
1331 | } | ||
1332 | return ofs; | ||
1333 | } | ||
1334 | |||
1335 | static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in) | ||
1336 | { | ||
1337 | void __iomem *mmio = mv5_phy_base(ap->host_set->mmio_base, ap->port_no); | ||
1338 | unsigned int ofs = mv5_scr_offset(sc_reg_in); | ||
1339 | |||
1340 | if (ofs != 0xffffffffU) | ||
1341 | return readl(mmio + ofs); | ||
1342 | else | ||
1343 | return (u32) ofs; | ||
1344 | } | ||
1345 | |||
1346 | static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) | ||
1347 | { | ||
1348 | void __iomem *mmio = mv5_phy_base(ap->host_set->mmio_base, ap->port_no); | ||
1349 | unsigned int ofs = mv5_scr_offset(sc_reg_in); | ||
1350 | |||
1351 | if (ofs != 0xffffffffU) | ||
1352 | writelfl(val, mmio + ofs); | ||
1353 | } | ||
1354 | |||
1355 | static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio) | ||
1356 | { | ||
1357 | u8 rev_id; | ||
1358 | int early_5080; | ||
1359 | |||
1360 | pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); | ||
1361 | |||
1362 | early_5080 = (pdev->device == 0x5080) && (rev_id == 0); | ||
1363 | |||
1364 | if (!early_5080) { | ||
1365 | u32 tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL); | ||
1366 | tmp |= (1 << 0); | ||
1367 | writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL); | ||
1368 | } | ||
1369 | |||
1370 | mv_reset_pci_bus(pdev, mmio); | ||
1371 | } | ||
1372 | |||
1373 | static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) | ||
1374 | { | ||
1375 | writel(0x0fcfffff, mmio + MV_FLASH_CTL); | ||
1376 | } | ||
1377 | |||
1378 | static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, | ||
1379 | void __iomem *mmio) | ||
1380 | { | ||
1381 | void __iomem *phy_mmio = mv5_phy_base(mmio, idx); | ||
1382 | u32 tmp; | ||
1383 | |||
1384 | tmp = readl(phy_mmio + MV5_PHY_MODE); | ||
1385 | |||
1386 | hpriv->signal[idx].pre = tmp & 0x1800; /* bits 12:11 */ | ||
1387 | hpriv->signal[idx].amps = tmp & 0xe0; /* bits 7:5 */ | ||
1388 | } | ||
1389 | |||
1390 | static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) | ||
1391 | { | ||
1392 | u32 tmp; | ||
1393 | |||
1394 | writel(0, mmio + MV_GPIO_PORT_CTL); | ||
1395 | |||
1396 | /* FIXME: handle MV_HP_ERRATA_50XXB2 errata */ | ||
1397 | |||
1398 | tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL); | ||
1399 | tmp |= ~(1 << 0); | ||
1400 | writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL); | ||
1401 | } | ||
1402 | |||
1403 | static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
1404 | unsigned int port) | ||
1405 | { | ||
1406 | void __iomem *phy_mmio = mv5_phy_base(mmio, port); | ||
1407 | const u32 mask = (1<<12) | (1<<11) | (1<<7) | (1<<6) | (1<<5); | ||
1408 | u32 tmp; | ||
1409 | int fix_apm_sq = (hpriv->hp_flags & MV_HP_ERRATA_50XXB0); | ||
1410 | |||
1411 | if (fix_apm_sq) { | ||
1412 | tmp = readl(phy_mmio + MV5_LT_MODE); | ||
1413 | tmp |= (1 << 19); | ||
1414 | writel(tmp, phy_mmio + MV5_LT_MODE); | ||
1415 | |||
1416 | tmp = readl(phy_mmio + MV5_PHY_CTL); | ||
1417 | tmp &= ~0x3; | ||
1418 | tmp |= 0x1; | ||
1419 | writel(tmp, phy_mmio + MV5_PHY_CTL); | ||
1420 | } | ||
1421 | |||
1422 | tmp = readl(phy_mmio + MV5_PHY_MODE); | ||
1423 | tmp &= ~mask; | ||
1424 | tmp |= hpriv->signal[port].pre; | ||
1425 | tmp |= hpriv->signal[port].amps; | ||
1426 | writel(tmp, phy_mmio + MV5_PHY_MODE); | ||
1427 | } | ||
1428 | |||
1429 | |||
1430 | #undef ZERO | ||
1431 | #define ZERO(reg) writel(0, port_mmio + (reg)) | ||
1432 | static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
1433 | unsigned int port) | ||
1434 | { | ||
1435 | void __iomem *port_mmio = mv_port_base(mmio, port); | ||
1436 | |||
1437 | writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); | ||
1438 | |||
1439 | mv_channel_reset(hpriv, mmio, port); | ||
1440 | |||
1441 | ZERO(0x028); /* command */ | ||
1442 | writel(0x11f, port_mmio + EDMA_CFG_OFS); | ||
1443 | ZERO(0x004); /* timer */ | ||
1444 | ZERO(0x008); /* irq err cause */ | ||
1445 | ZERO(0x00c); /* irq err mask */ | ||
1446 | ZERO(0x010); /* rq bah */ | ||
1447 | ZERO(0x014); /* rq inp */ | ||
1448 | ZERO(0x018); /* rq outp */ | ||
1449 | ZERO(0x01c); /* respq bah */ | ||
1450 | ZERO(0x024); /* respq outp */ | ||
1451 | ZERO(0x020); /* respq inp */ | ||
1452 | ZERO(0x02c); /* test control */ | ||
1453 | writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); | ||
1454 | } | ||
1455 | #undef ZERO | ||
1456 | |||
1457 | #define ZERO(reg) writel(0, hc_mmio + (reg)) | ||
1458 | static void mv5_reset_one_hc(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
1459 | unsigned int hc) | ||
1460 | { | ||
1461 | void __iomem *hc_mmio = mv_hc_base(mmio, hc); | ||
1462 | u32 tmp; | ||
1463 | |||
1464 | ZERO(0x00c); | ||
1465 | ZERO(0x010); | ||
1466 | ZERO(0x014); | ||
1467 | ZERO(0x018); | ||
1468 | |||
1469 | tmp = readl(hc_mmio + 0x20); | ||
1470 | tmp &= 0x1c1c1c1c; | ||
1471 | tmp |= 0x03030303; | ||
1472 | writel(tmp, hc_mmio + 0x20); | ||
1473 | } | ||
1474 | #undef ZERO | ||
1475 | |||
1476 | static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
1477 | unsigned int n_hc) | ||
1478 | { | ||
1479 | unsigned int hc, port; | ||
1480 | |||
1481 | for (hc = 0; hc < n_hc; hc++) { | ||
1482 | for (port = 0; port < MV_PORTS_PER_HC; port++) | ||
1483 | mv5_reset_hc_port(hpriv, mmio, | ||
1484 | (hc * MV_PORTS_PER_HC) + port); | ||
1485 | |||
1486 | mv5_reset_one_hc(hpriv, mmio, hc); | ||
1487 | } | ||
1488 | |||
1489 | return 0; | ||
1490 | } | ||
1491 | |||
1492 | #undef ZERO | ||
1493 | #define ZERO(reg) writel(0, mmio + (reg)) | ||
1494 | static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio) | ||
1495 | { | ||
1496 | u32 tmp; | ||
1497 | |||
1498 | tmp = readl(mmio + MV_PCI_MODE); | ||
1499 | tmp &= 0xff00ffff; | ||
1500 | writel(tmp, mmio + MV_PCI_MODE); | ||
1501 | |||
1502 | ZERO(MV_PCI_DISC_TIMER); | ||
1503 | ZERO(MV_PCI_MSI_TRIGGER); | ||
1504 | writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT); | ||
1505 | ZERO(HC_MAIN_IRQ_MASK_OFS); | ||
1506 | ZERO(MV_PCI_SERR_MASK); | ||
1507 | ZERO(PCI_IRQ_CAUSE_OFS); | ||
1508 | ZERO(PCI_IRQ_MASK_OFS); | ||
1509 | ZERO(MV_PCI_ERR_LOW_ADDRESS); | ||
1510 | ZERO(MV_PCI_ERR_HIGH_ADDRESS); | ||
1511 | ZERO(MV_PCI_ERR_ATTRIBUTE); | ||
1512 | ZERO(MV_PCI_ERR_COMMAND); | ||
1513 | } | ||
1514 | #undef ZERO | ||
1515 | |||
1516 | static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) | ||
1517 | { | ||
1518 | u32 tmp; | ||
1519 | |||
1520 | mv5_reset_flash(hpriv, mmio); | ||
1521 | |||
1522 | tmp = readl(mmio + MV_GPIO_PORT_CTL); | ||
1523 | tmp &= 0x3; | ||
1524 | tmp |= (1 << 5) | (1 << 6); | ||
1525 | writel(tmp, mmio + MV_GPIO_PORT_CTL); | ||
1526 | } | ||
1527 | |||
1528 | /** | ||
1529 | * mv6_reset_hc - Perform the 6xxx global soft reset | ||
1530 | * @mmio: base address of the HBA | ||
1531 | * | ||
1532 | * This routine only applies to 6xxx parts. | ||
1533 | * | ||
1534 | * LOCKING: | ||
1535 | * Inherited from caller. | ||
1536 | */ | ||
1537 | static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
1538 | unsigned int n_hc) | ||
1539 | { | ||
1540 | void __iomem *reg = mmio + PCI_MAIN_CMD_STS_OFS; | ||
1541 | int i, rc = 0; | ||
1542 | u32 t; | ||
1543 | |||
1544 | /* Following procedure defined in PCI "main command and status | ||
1545 | * register" table. | ||
1546 | */ | ||
1547 | t = readl(reg); | ||
1548 | writel(t | STOP_PCI_MASTER, reg); | ||
1549 | |||
1550 | for (i = 0; i < 1000; i++) { | ||
1551 | udelay(1); | ||
1552 | t = readl(reg); | ||
1553 | if (PCI_MASTER_EMPTY & t) { | ||
1554 | break; | ||
1555 | } | ||
1556 | } | ||
1557 | if (!(PCI_MASTER_EMPTY & t)) { | ||
1558 | printk(KERN_ERR DRV_NAME ": PCI master won't flush\n"); | ||
1559 | rc = 1; | ||
1560 | goto done; | ||
1561 | } | ||
1562 | |||
1563 | /* set reset */ | ||
1564 | i = 5; | ||
1565 | do { | ||
1566 | writel(t | GLOB_SFT_RST, reg); | ||
1567 | t = readl(reg); | ||
1568 | udelay(1); | ||
1569 | } while (!(GLOB_SFT_RST & t) && (i-- > 0)); | ||
1570 | |||
1571 | if (!(GLOB_SFT_RST & t)) { | ||
1572 | printk(KERN_ERR DRV_NAME ": can't set global reset\n"); | ||
1573 | rc = 1; | ||
1574 | goto done; | ||
1575 | } | ||
1576 | |||
1577 | /* clear reset and *reenable the PCI master* (not mentioned in spec) */ | ||
1578 | i = 5; | ||
1579 | do { | ||
1580 | writel(t & ~(GLOB_SFT_RST | STOP_PCI_MASTER), reg); | ||
1581 | t = readl(reg); | ||
1582 | udelay(1); | ||
1583 | } while ((GLOB_SFT_RST & t) && (i-- > 0)); | ||
1584 | |||
1585 | if (GLOB_SFT_RST & t) { | ||
1586 | printk(KERN_ERR DRV_NAME ": can't clear global reset\n"); | ||
1587 | rc = 1; | ||
1588 | } | ||
1589 | done: | ||
1590 | return rc; | ||
1591 | } | ||
1592 | |||
1593 | static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, | ||
1594 | void __iomem *mmio) | ||
1595 | { | ||
1596 | void __iomem *port_mmio; | ||
1597 | u32 tmp; | ||
1598 | |||
1599 | tmp = readl(mmio + MV_RESET_CFG); | ||
1600 | if ((tmp & (1 << 0)) == 0) { | ||
1601 | hpriv->signal[idx].amps = 0x7 << 8; | ||
1602 | hpriv->signal[idx].pre = 0x1 << 5; | ||
1603 | return; | ||
1604 | } | ||
1605 | |||
1606 | port_mmio = mv_port_base(mmio, idx); | ||
1607 | tmp = readl(port_mmio + PHY_MODE2); | ||
1608 | |||
1609 | hpriv->signal[idx].amps = tmp & 0x700; /* bits 10:8 */ | ||
1610 | hpriv->signal[idx].pre = tmp & 0xe0; /* bits 7:5 */ | ||
1611 | } | ||
1612 | |||
1613 | static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) | ||
1614 | { | ||
1615 | writel(0x00000060, mmio + MV_GPIO_PORT_CTL); | ||
1616 | } | ||
1617 | |||
1618 | static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
1619 | unsigned int port) | ||
1620 | { | ||
1621 | void __iomem *port_mmio = mv_port_base(mmio, port); | ||
1622 | |||
1623 | u32 hp_flags = hpriv->hp_flags; | ||
1624 | int fix_phy_mode2 = | ||
1625 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); | ||
1626 | int fix_phy_mode4 = | ||
1627 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); | ||
1628 | u32 m2, tmp; | ||
1629 | |||
1630 | if (fix_phy_mode2) { | ||
1631 | m2 = readl(port_mmio + PHY_MODE2); | ||
1632 | m2 &= ~(1 << 16); | ||
1633 | m2 |= (1 << 31); | ||
1634 | writel(m2, port_mmio + PHY_MODE2); | ||
1635 | |||
1636 | udelay(200); | ||
1637 | |||
1638 | m2 = readl(port_mmio + PHY_MODE2); | ||
1639 | m2 &= ~((1 << 16) | (1 << 31)); | ||
1640 | writel(m2, port_mmio + PHY_MODE2); | ||
1641 | |||
1642 | udelay(200); | ||
1643 | } | ||
1644 | |||
1645 | /* who knows what this magic does */ | ||
1646 | tmp = readl(port_mmio + PHY_MODE3); | ||
1647 | tmp &= ~0x7F800000; | ||
1648 | tmp |= 0x2A800000; | ||
1649 | writel(tmp, port_mmio + PHY_MODE3); | ||
1650 | |||
1651 | if (fix_phy_mode4) { | ||
1652 | u32 m4; | ||
1653 | |||
1654 | m4 = readl(port_mmio + PHY_MODE4); | ||
1655 | |||
1656 | if (hp_flags & MV_HP_ERRATA_60X1B2) | ||
1657 | tmp = readl(port_mmio + 0x310); | ||
1658 | |||
1659 | m4 = (m4 & ~(1 << 1)) | (1 << 0); | ||
1660 | |||
1661 | writel(m4, port_mmio + PHY_MODE4); | ||
1662 | |||
1663 | if (hp_flags & MV_HP_ERRATA_60X1B2) | ||
1664 | writel(tmp, port_mmio + 0x310); | ||
1665 | } | ||
1666 | |||
1667 | /* Revert values of pre-emphasis and signal amps to the saved ones */ | ||
1668 | m2 = readl(port_mmio + PHY_MODE2); | ||
1669 | |||
1670 | m2 &= ~MV_M2_PREAMP_MASK; | ||
1671 | m2 |= hpriv->signal[port].amps; | ||
1672 | m2 |= hpriv->signal[port].pre; | ||
1673 | m2 &= ~(1 << 16); | ||
1674 | |||
1675 | writel(m2, port_mmio + PHY_MODE2); | ||
1676 | } | ||
1677 | |||
1678 | static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, | ||
1679 | unsigned int port_no) | ||
1680 | { | ||
1681 | void __iomem *port_mmio = mv_port_base(mmio, port_no); | ||
1682 | |||
1683 | writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS); | ||
1684 | |||
1685 | if (IS_60XX(hpriv)) { | ||
1686 | u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); | ||
1687 | ifctl |= (1 << 12) | (1 << 7); | ||
1688 | writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); | ||
1689 | } | ||
1690 | |||
1691 | udelay(25); /* allow reset propagation */ | ||
1692 | |||
1693 | /* Spec never mentions clearing the bit. Marvell's driver does | ||
1694 | * clear the bit, however. | ||
1695 | */ | ||
1696 | writelfl(0, port_mmio + EDMA_CMD_OFS); | ||
1697 | |||
1698 | hpriv->ops->phy_errata(hpriv, mmio, port_no); | ||
1699 | |||
1700 | if (IS_50XX(hpriv)) | ||
1701 | mdelay(1); | ||
1702 | } | ||
1703 | |||
1704 | static void mv_stop_and_reset(struct ata_port *ap) | ||
1705 | { | ||
1706 | struct mv_host_priv *hpriv = ap->host_set->private_data; | ||
1707 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1708 | |||
1709 | mv_stop_dma(ap); | ||
1710 | |||
1711 | mv_channel_reset(hpriv, mmio, ap->port_no); | ||
1712 | |||
1713 | __mv_phy_reset(ap, 0); | ||
1714 | } | ||
1715 | |||
1716 | static inline void __msleep(unsigned int msec, int can_sleep) | ||
1717 | { | ||
1718 | if (can_sleep) | ||
1719 | msleep(msec); | ||
1720 | else | ||
1721 | mdelay(msec); | ||
1722 | } | ||
1723 | |||
1206 | /** | 1724 | /** |
1207 | * mv_phy_reset - Perform eDMA reset followed by COMRESET | 1725 | * __mv_phy_reset - Perform eDMA reset followed by COMRESET |
1208 | * @ap: ATA channel to manipulate | 1726 | * @ap: ATA channel to manipulate |
1209 | * | 1727 | * |
1210 | * Part of this is taken from __sata_phy_reset and modified to | 1728 | * Part of this is taken from __sata_phy_reset and modified to |
@@ -1214,41 +1732,47 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, | |||
1214 | * Inherited from caller. This is coded to safe to call at | 1732 | * Inherited from caller. This is coded to safe to call at |
1215 | * interrupt level, i.e. it does not sleep. | 1733 | * interrupt level, i.e. it does not sleep. |
1216 | */ | 1734 | */ |
1217 | static void mv_phy_reset(struct ata_port *ap) | 1735 | static void __mv_phy_reset(struct ata_port *ap, int can_sleep) |
1218 | { | 1736 | { |
1737 | struct mv_port_priv *pp = ap->private_data; | ||
1738 | struct mv_host_priv *hpriv = ap->host_set->private_data; | ||
1219 | void __iomem *port_mmio = mv_ap_base(ap); | 1739 | void __iomem *port_mmio = mv_ap_base(ap); |
1220 | struct ata_taskfile tf; | 1740 | struct ata_taskfile tf; |
1221 | struct ata_device *dev = &ap->device[0]; | 1741 | struct ata_device *dev = &ap->device[0]; |
1222 | unsigned long timeout; | 1742 | unsigned long timeout; |
1743 | int retry = 5; | ||
1744 | u32 sstatus; | ||
1223 | 1745 | ||
1224 | VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio); | 1746 | VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio); |
1225 | 1747 | ||
1226 | mv_stop_dma(ap); | 1748 | DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " |
1227 | |||
1228 | writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS); | ||
1229 | udelay(25); /* allow reset propagation */ | ||
1230 | |||
1231 | /* Spec never mentions clearing the bit. Marvell's driver does | ||
1232 | * clear the bit, however. | ||
1233 | */ | ||
1234 | writelfl(0, port_mmio + EDMA_CMD_OFS); | ||
1235 | |||
1236 | VPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " | ||
1237 | "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), | 1749 | "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), |
1238 | mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); | 1750 | mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); |
1239 | 1751 | ||
1240 | /* proceed to init communications via the scr_control reg */ | 1752 | /* Issue COMRESET via SControl */ |
1753 | comreset_retry: | ||
1241 | scr_write_flush(ap, SCR_CONTROL, 0x301); | 1754 | scr_write_flush(ap, SCR_CONTROL, 0x301); |
1242 | mdelay(1); | 1755 | __msleep(1, can_sleep); |
1756 | |||
1243 | scr_write_flush(ap, SCR_CONTROL, 0x300); | 1757 | scr_write_flush(ap, SCR_CONTROL, 0x300); |
1244 | timeout = jiffies + (HZ * 1); | 1758 | __msleep(20, can_sleep); |
1759 | |||
1760 | timeout = jiffies + msecs_to_jiffies(200); | ||
1245 | do { | 1761 | do { |
1246 | mdelay(10); | 1762 | sstatus = scr_read(ap, SCR_STATUS) & 0x3; |
1247 | if ((scr_read(ap, SCR_STATUS) & 0xf) != 1) | 1763 | if ((sstatus == 3) || (sstatus == 0)) |
1248 | break; | 1764 | break; |
1765 | |||
1766 | __msleep(1, can_sleep); | ||
1249 | } while (time_before(jiffies, timeout)); | 1767 | } while (time_before(jiffies, timeout)); |
1250 | 1768 | ||
1251 | VPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " | 1769 | /* work around errata */ |
1770 | if (IS_60XX(hpriv) && | ||
1771 | (sstatus != 0x0) && (sstatus != 0x113) && (sstatus != 0x123) && | ||
1772 | (retry-- > 0)) | ||
1773 | goto comreset_retry; | ||
1774 | |||
1775 | DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " | ||
1252 | "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), | 1776 | "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), |
1253 | mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); | 1777 | mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); |
1254 | 1778 | ||
@@ -1262,6 +1786,21 @@ static void mv_phy_reset(struct ata_port *ap) | |||
1262 | } | 1786 | } |
1263 | ap->cbl = ATA_CBL_SATA; | 1787 | ap->cbl = ATA_CBL_SATA; |
1264 | 1788 | ||
1789 | /* even after SStatus reflects that device is ready, | ||
1790 | * it seems to take a while for link to be fully | ||
1791 | * established (and thus Status no longer 0x80/0x7F), | ||
1792 | * so we poll a bit for that, here. | ||
1793 | */ | ||
1794 | retry = 20; | ||
1795 | while (1) { | ||
1796 | u8 drv_stat = ata_check_status(ap); | ||
1797 | if ((drv_stat != 0x80) && (drv_stat != 0x7f)) | ||
1798 | break; | ||
1799 | __msleep(500, can_sleep); | ||
1800 | if (retry-- <= 0) | ||
1801 | break; | ||
1802 | } | ||
1803 | |||
1265 | tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr); | 1804 | tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr); |
1266 | tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr); | 1805 | tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr); |
1267 | tf.lbal = readb((void __iomem *) ap->ioaddr.lbal_addr); | 1806 | tf.lbal = readb((void __iomem *) ap->ioaddr.lbal_addr); |
@@ -1272,9 +1811,19 @@ static void mv_phy_reset(struct ata_port *ap) | |||
1272 | VPRINTK("Port disabled post-sig: No device present.\n"); | 1811 | VPRINTK("Port disabled post-sig: No device present.\n"); |
1273 | ata_port_disable(ap); | 1812 | ata_port_disable(ap); |
1274 | } | 1813 | } |
1814 | |||
1815 | writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | ||
1816 | |||
1817 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | ||
1818 | |||
1275 | VPRINTK("EXIT\n"); | 1819 | VPRINTK("EXIT\n"); |
1276 | } | 1820 | } |
1277 | 1821 | ||
1822 | static void mv_phy_reset(struct ata_port *ap) | ||
1823 | { | ||
1824 | __mv_phy_reset(ap, 1); | ||
1825 | } | ||
1826 | |||
1278 | /** | 1827 | /** |
1279 | * mv_eng_timeout - Routine called by libata when SCSI times out I/O | 1828 | * mv_eng_timeout - Routine called by libata when SCSI times out I/O |
1280 | * @ap: ATA channel to manipulate | 1829 | * @ap: ATA channel to manipulate |
@@ -1292,16 +1841,16 @@ static void mv_eng_timeout(struct ata_port *ap) | |||
1292 | 1841 | ||
1293 | printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id); | 1842 | printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id); |
1294 | DPRINTK("All regs @ start of eng_timeout\n"); | 1843 | DPRINTK("All regs @ start of eng_timeout\n"); |
1295 | mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no, | 1844 | mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no, |
1296 | to_pci_dev(ap->host_set->dev)); | 1845 | to_pci_dev(ap->host_set->dev)); |
1297 | 1846 | ||
1298 | qc = ata_qc_from_tag(ap, ap->active_tag); | 1847 | qc = ata_qc_from_tag(ap, ap->active_tag); |
1299 | printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n", | 1848 | printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n", |
1300 | ap->host_set->mmio_base, ap, qc, qc->scsicmd, | 1849 | ap->host_set->mmio_base, ap, qc, qc->scsicmd, |
1301 | &qc->scsicmd->cmnd); | 1850 | &qc->scsicmd->cmnd); |
1302 | 1851 | ||
1303 | mv_err_intr(ap); | 1852 | mv_err_intr(ap); |
1304 | mv_phy_reset(ap); | 1853 | mv_stop_and_reset(ap); |
1305 | 1854 | ||
1306 | if (!qc) { | 1855 | if (!qc) { |
1307 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", | 1856 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", |
@@ -1337,17 +1886,17 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) | |||
1337 | unsigned long shd_base = (unsigned long) port_mmio + SHD_BLK_OFS; | 1886 | unsigned long shd_base = (unsigned long) port_mmio + SHD_BLK_OFS; |
1338 | unsigned serr_ofs; | 1887 | unsigned serr_ofs; |
1339 | 1888 | ||
1340 | /* PIO related setup | 1889 | /* PIO related setup |
1341 | */ | 1890 | */ |
1342 | port->data_addr = shd_base + (sizeof(u32) * ATA_REG_DATA); | 1891 | port->data_addr = shd_base + (sizeof(u32) * ATA_REG_DATA); |
1343 | port->error_addr = | 1892 | port->error_addr = |
1344 | port->feature_addr = shd_base + (sizeof(u32) * ATA_REG_ERR); | 1893 | port->feature_addr = shd_base + (sizeof(u32) * ATA_REG_ERR); |
1345 | port->nsect_addr = shd_base + (sizeof(u32) * ATA_REG_NSECT); | 1894 | port->nsect_addr = shd_base + (sizeof(u32) * ATA_REG_NSECT); |
1346 | port->lbal_addr = shd_base + (sizeof(u32) * ATA_REG_LBAL); | 1895 | port->lbal_addr = shd_base + (sizeof(u32) * ATA_REG_LBAL); |
1347 | port->lbam_addr = shd_base + (sizeof(u32) * ATA_REG_LBAM); | 1896 | port->lbam_addr = shd_base + (sizeof(u32) * ATA_REG_LBAM); |
1348 | port->lbah_addr = shd_base + (sizeof(u32) * ATA_REG_LBAH); | 1897 | port->lbah_addr = shd_base + (sizeof(u32) * ATA_REG_LBAH); |
1349 | port->device_addr = shd_base + (sizeof(u32) * ATA_REG_DEVICE); | 1898 | port->device_addr = shd_base + (sizeof(u32) * ATA_REG_DEVICE); |
1350 | port->status_addr = | 1899 | port->status_addr = |
1351 | port->command_addr = shd_base + (sizeof(u32) * ATA_REG_STATUS); | 1900 | port->command_addr = shd_base + (sizeof(u32) * ATA_REG_STATUS); |
1352 | /* special case: control/altstatus doesn't have ATA_REG_ address */ | 1901 | /* special case: control/altstatus doesn't have ATA_REG_ address */ |
1353 | port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS; | 1902 | port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS; |
@@ -1363,14 +1912,92 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) | |||
1363 | /* unmask all EDMA error interrupts */ | 1912 | /* unmask all EDMA error interrupts */ |
1364 | writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS); | 1913 | writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS); |
1365 | 1914 | ||
1366 | VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n", | 1915 | VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n", |
1367 | readl(port_mmio + EDMA_CFG_OFS), | 1916 | readl(port_mmio + EDMA_CFG_OFS), |
1368 | readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS), | 1917 | readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS), |
1369 | readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); | 1918 | readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); |
1370 | } | 1919 | } |
1371 | 1920 | ||
1921 | static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, | ||
1922 | unsigned int board_idx) | ||
1923 | { | ||
1924 | u8 rev_id; | ||
1925 | u32 hp_flags = hpriv->hp_flags; | ||
1926 | |||
1927 | pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); | ||
1928 | |||
1929 | switch(board_idx) { | ||
1930 | case chip_5080: | ||
1931 | hpriv->ops = &mv5xxx_ops; | ||
1932 | hp_flags |= MV_HP_50XX; | ||
1933 | |||
1934 | switch (rev_id) { | ||
1935 | case 0x1: | ||
1936 | hp_flags |= MV_HP_ERRATA_50XXB0; | ||
1937 | break; | ||
1938 | case 0x3: | ||
1939 | hp_flags |= MV_HP_ERRATA_50XXB2; | ||
1940 | break; | ||
1941 | default: | ||
1942 | dev_printk(KERN_WARNING, &pdev->dev, | ||
1943 | "Applying 50XXB2 workarounds to unknown rev\n"); | ||
1944 | hp_flags |= MV_HP_ERRATA_50XXB2; | ||
1945 | break; | ||
1946 | } | ||
1947 | break; | ||
1948 | |||
1949 | case chip_504x: | ||
1950 | case chip_508x: | ||
1951 | hpriv->ops = &mv5xxx_ops; | ||
1952 | hp_flags |= MV_HP_50XX; | ||
1953 | |||
1954 | switch (rev_id) { | ||
1955 | case 0x0: | ||
1956 | hp_flags |= MV_HP_ERRATA_50XXB0; | ||
1957 | break; | ||
1958 | case 0x3: | ||
1959 | hp_flags |= MV_HP_ERRATA_50XXB2; | ||
1960 | break; | ||
1961 | default: | ||
1962 | dev_printk(KERN_WARNING, &pdev->dev, | ||
1963 | "Applying B2 workarounds to unknown rev\n"); | ||
1964 | hp_flags |= MV_HP_ERRATA_50XXB2; | ||
1965 | break; | ||
1966 | } | ||
1967 | break; | ||
1968 | |||
1969 | case chip_604x: | ||
1970 | case chip_608x: | ||
1971 | hpriv->ops = &mv6xxx_ops; | ||
1972 | |||
1973 | switch (rev_id) { | ||
1974 | case 0x7: | ||
1975 | hp_flags |= MV_HP_ERRATA_60X1B2; | ||
1976 | break; | ||
1977 | case 0x9: | ||
1978 | hp_flags |= MV_HP_ERRATA_60X1C0; | ||
1979 | break; | ||
1980 | default: | ||
1981 | dev_printk(KERN_WARNING, &pdev->dev, | ||
1982 | "Applying B2 workarounds to unknown rev\n"); | ||
1983 | hp_flags |= MV_HP_ERRATA_60X1B2; | ||
1984 | break; | ||
1985 | } | ||
1986 | break; | ||
1987 | |||
1988 | default: | ||
1989 | printk(KERN_ERR DRV_NAME ": BUG: invalid board index %u\n", board_idx); | ||
1990 | return 1; | ||
1991 | } | ||
1992 | |||
1993 | hpriv->hp_flags = hp_flags; | ||
1994 | |||
1995 | return 0; | ||
1996 | } | ||
1997 | |||
1372 | /** | 1998 | /** |
1373 | * mv_host_init - Perform some early initialization of the host. | 1999 | * mv_init_host - Perform some early initialization of the host. |
2000 | * @pdev: host PCI device | ||
1374 | * @probe_ent: early data struct representing the host | 2001 | * @probe_ent: early data struct representing the host |
1375 | * | 2002 | * |
1376 | * If possible, do an early global reset of the host. Then do | 2003 | * If possible, do an early global reset of the host. Then do |
@@ -1379,23 +2006,48 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) | |||
1379 | * LOCKING: | 2006 | * LOCKING: |
1380 | * Inherited from caller. | 2007 | * Inherited from caller. |
1381 | */ | 2008 | */ |
1382 | static int mv_host_init(struct ata_probe_ent *probe_ent) | 2009 | static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, |
2010 | unsigned int board_idx) | ||
1383 | { | 2011 | { |
1384 | int rc = 0, n_hc, port, hc; | 2012 | int rc = 0, n_hc, port, hc; |
1385 | void __iomem *mmio = probe_ent->mmio_base; | 2013 | void __iomem *mmio = probe_ent->mmio_base; |
1386 | void __iomem *port_mmio; | 2014 | struct mv_host_priv *hpriv = probe_ent->private_data; |
1387 | 2015 | ||
1388 | if ((MV_FLAG_GLBL_SFT_RST & probe_ent->host_flags) && | 2016 | /* global interrupt mask */ |
1389 | mv_global_soft_reset(probe_ent->mmio_base)) { | 2017 | writel(0, mmio + HC_MAIN_IRQ_MASK_OFS); |
1390 | rc = 1; | 2018 | |
2019 | rc = mv_chip_id(pdev, hpriv, board_idx); | ||
2020 | if (rc) | ||
1391 | goto done; | 2021 | goto done; |
1392 | } | ||
1393 | 2022 | ||
1394 | n_hc = mv_get_hc_count(probe_ent->host_flags); | 2023 | n_hc = mv_get_hc_count(probe_ent->host_flags); |
1395 | probe_ent->n_ports = MV_PORTS_PER_HC * n_hc; | 2024 | probe_ent->n_ports = MV_PORTS_PER_HC * n_hc; |
1396 | 2025 | ||
2026 | for (port = 0; port < probe_ent->n_ports; port++) | ||
2027 | hpriv->ops->read_preamp(hpriv, port, mmio); | ||
2028 | |||
2029 | rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc); | ||
2030 | if (rc) | ||
2031 | goto done; | ||
2032 | |||
2033 | hpriv->ops->reset_flash(hpriv, mmio); | ||
2034 | hpriv->ops->reset_bus(pdev, mmio); | ||
2035 | hpriv->ops->enable_leds(hpriv, mmio); | ||
2036 | |||
1397 | for (port = 0; port < probe_ent->n_ports; port++) { | 2037 | for (port = 0; port < probe_ent->n_ports; port++) { |
1398 | port_mmio = mv_port_base(mmio, port); | 2038 | if (IS_60XX(hpriv)) { |
2039 | void __iomem *port_mmio = mv_port_base(mmio, port); | ||
2040 | |||
2041 | u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); | ||
2042 | ifctl |= (1 << 12); | ||
2043 | writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); | ||
2044 | } | ||
2045 | |||
2046 | hpriv->ops->phy_errata(hpriv, mmio, port); | ||
2047 | } | ||
2048 | |||
2049 | for (port = 0; port < probe_ent->n_ports; port++) { | ||
2050 | void __iomem *port_mmio = mv_port_base(mmio, port); | ||
1399 | mv_port_init(&probe_ent->port[port], port_mmio); | 2051 | mv_port_init(&probe_ent->port[port], port_mmio); |
1400 | } | 2052 | } |
1401 | 2053 | ||
@@ -1419,11 +2071,12 @@ static int mv_host_init(struct ata_probe_ent *probe_ent) | |||
1419 | writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS); | 2071 | writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS); |
1420 | 2072 | ||
1421 | VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x " | 2073 | VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x " |
1422 | "PCI int cause/mask=0x%08x/0x%08x\n", | 2074 | "PCI int cause/mask=0x%08x/0x%08x\n", |
1423 | readl(mmio + HC_MAIN_IRQ_CAUSE_OFS), | 2075 | readl(mmio + HC_MAIN_IRQ_CAUSE_OFS), |
1424 | readl(mmio + HC_MAIN_IRQ_MASK_OFS), | 2076 | readl(mmio + HC_MAIN_IRQ_MASK_OFS), |
1425 | readl(mmio + PCI_IRQ_CAUSE_OFS), | 2077 | readl(mmio + PCI_IRQ_CAUSE_OFS), |
1426 | readl(mmio + PCI_IRQ_MASK_OFS)); | 2078 | readl(mmio + PCI_IRQ_MASK_OFS)); |
2079 | |||
1427 | done: | 2080 | done: |
1428 | return rc; | 2081 | return rc; |
1429 | } | 2082 | } |
@@ -1459,7 +2112,7 @@ static void mv_print_info(struct ata_probe_ent *probe_ent) | |||
1459 | 2112 | ||
1460 | dev_printk(KERN_INFO, &pdev->dev, | 2113 | dev_printk(KERN_INFO, &pdev->dev, |
1461 | "%u slots %u ports %s mode IRQ via %s\n", | 2114 | "%u slots %u ports %s mode IRQ via %s\n", |
1462 | (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports, | 2115 | (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports, |
1463 | scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx"); | 2116 | scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx"); |
1464 | } | 2117 | } |
1465 | 2118 | ||
@@ -1529,7 +2182,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1529 | probe_ent->private_data = hpriv; | 2182 | probe_ent->private_data = hpriv; |
1530 | 2183 | ||
1531 | /* initialize adapter */ | 2184 | /* initialize adapter */ |
1532 | rc = mv_host_init(probe_ent); | 2185 | rc = mv_init_host(pdev, probe_ent, board_idx); |
1533 | if (rc) { | 2186 | if (rc) { |
1534 | goto err_out_hpriv; | 2187 | goto err_out_hpriv; |
1535 | } | 2188 | } |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 7cc96ae0bc1a..e9ffc27a0493 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include "sata_promise.h" | 46 | #include "sata_promise.h" |
47 | 47 | ||
48 | #define DRV_NAME "sata_promise" | 48 | #define DRV_NAME "sata_promise" |
49 | #define DRV_VERSION "1.02" | 49 | #define DRV_VERSION "1.03" |
50 | 50 | ||
51 | 51 | ||
52 | enum { | 52 | enum { |
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index 61b17f263d33..17a39ed62306 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include <linux/libata.h> | 41 | #include <linux/libata.h> |
42 | 42 | ||
43 | #define DRV_NAME "sata_qstor" | 43 | #define DRV_NAME "sata_qstor" |
44 | #define DRV_VERSION "0.04" | 44 | #define DRV_VERSION "0.05" |
45 | 45 | ||
46 | enum { | 46 | enum { |
47 | QS_PORTS = 4, | 47 | QS_PORTS = 4, |
@@ -268,7 +268,7 @@ static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | |||
268 | writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8))); | 268 | writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8))); |
269 | } | 269 | } |
270 | 270 | ||
271 | static void qs_fill_sg(struct ata_queued_cmd *qc) | 271 | static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) |
272 | { | 272 | { |
273 | struct scatterlist *sg; | 273 | struct scatterlist *sg; |
274 | struct ata_port *ap = qc->ap; | 274 | struct ata_port *ap = qc->ap; |
@@ -296,6 +296,8 @@ static void qs_fill_sg(struct ata_queued_cmd *qc) | |||
296 | (unsigned long long)addr, len); | 296 | (unsigned long long)addr, len); |
297 | nelem++; | 297 | nelem++; |
298 | } | 298 | } |
299 | |||
300 | return nelem; | ||
299 | } | 301 | } |
300 | 302 | ||
301 | static void qs_qc_prep(struct ata_queued_cmd *qc) | 303 | static void qs_qc_prep(struct ata_queued_cmd *qc) |
@@ -304,6 +306,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) | |||
304 | u8 dflags = QS_DF_PORD, *buf = pp->pkt; | 306 | u8 dflags = QS_DF_PORD, *buf = pp->pkt; |
305 | u8 hflags = QS_HF_DAT | QS_HF_IEN | QS_HF_VLD; | 307 | u8 hflags = QS_HF_DAT | QS_HF_IEN | QS_HF_VLD; |
306 | u64 addr; | 308 | u64 addr; |
309 | unsigned int nelem; | ||
307 | 310 | ||
308 | VPRINTK("ENTER\n"); | 311 | VPRINTK("ENTER\n"); |
309 | 312 | ||
@@ -313,7 +316,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) | |||
313 | return; | 316 | return; |
314 | } | 317 | } |
315 | 318 | ||
316 | qs_fill_sg(qc); | 319 | nelem = qs_fill_sg(qc); |
317 | 320 | ||
318 | if ((qc->tf.flags & ATA_TFLAG_WRITE)) | 321 | if ((qc->tf.flags & ATA_TFLAG_WRITE)) |
319 | hflags |= QS_HF_DIRO; | 322 | hflags |= QS_HF_DIRO; |
@@ -324,7 +327,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) | |||
324 | buf[ 0] = QS_HCB_HDR; | 327 | buf[ 0] = QS_HCB_HDR; |
325 | buf[ 1] = hflags; | 328 | buf[ 1] = hflags; |
326 | *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE); | 329 | *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE); |
327 | *(__le32 *)(&buf[ 8]) = cpu_to_le32(qc->n_elem); | 330 | *(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem); |
328 | addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES; | 331 | addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES; |
329 | *(__le64 *)(&buf[16]) = cpu_to_le64(addr); | 332 | *(__le64 *)(&buf[16]) = cpu_to_le64(addr); |
330 | 333 | ||
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index d3198d9a72c1..cb1933a3bd55 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -139,6 +139,7 @@ enum { | |||
139 | PORT_CS_DEV_RST = (1 << 1), /* device reset */ | 139 | PORT_CS_DEV_RST = (1 << 1), /* device reset */ |
140 | PORT_CS_INIT = (1 << 2), /* port initialize */ | 140 | PORT_CS_INIT = (1 << 2), /* port initialize */ |
141 | PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */ | 141 | PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */ |
142 | PORT_CS_CDB16 = (1 << 5), /* 0=12b cdb, 1=16b cdb */ | ||
142 | PORT_CS_RESUME = (1 << 6), /* port resume */ | 143 | PORT_CS_RESUME = (1 << 6), /* port resume */ |
143 | PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */ | 144 | PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */ |
144 | PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */ | 145 | PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */ |
@@ -188,11 +189,29 @@ enum { | |||
188 | PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */ | 189 | PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */ |
189 | PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */ | 190 | PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */ |
190 | 191 | ||
192 | /* bits of PRB control field */ | ||
193 | PRB_CTRL_PROTOCOL = (1 << 0), /* override def. ATA protocol */ | ||
194 | PRB_CTRL_PACKET_READ = (1 << 4), /* PACKET cmd read */ | ||
195 | PRB_CTRL_PACKET_WRITE = (1 << 5), /* PACKET cmd write */ | ||
196 | PRB_CTRL_NIEN = (1 << 6), /* Mask completion irq */ | ||
197 | PRB_CTRL_SRST = (1 << 7), /* Soft reset request (ign BSY?) */ | ||
198 | |||
199 | /* PRB protocol field */ | ||
200 | PRB_PROT_PACKET = (1 << 0), | ||
201 | PRB_PROT_TCQ = (1 << 1), | ||
202 | PRB_PROT_NCQ = (1 << 2), | ||
203 | PRB_PROT_READ = (1 << 3), | ||
204 | PRB_PROT_WRITE = (1 << 4), | ||
205 | PRB_PROT_TRANSPARENT = (1 << 5), | ||
206 | |||
191 | /* | 207 | /* |
192 | * Other constants | 208 | * Other constants |
193 | */ | 209 | */ |
194 | SGE_TRM = (1 << 31), /* Last SGE in chain */ | 210 | SGE_TRM = (1 << 31), /* Last SGE in chain */ |
195 | PRB_SOFT_RST = (1 << 7), /* Soft reset request (ign BSY?) */ | 211 | SGE_LNK = (1 << 30), /* linked list |
212 | Points to SGT, not SGE */ | ||
213 | SGE_DRD = (1 << 29), /* discard data read (/dev/null) | ||
214 | data address ignored */ | ||
196 | 215 | ||
197 | /* board id */ | 216 | /* board id */ |
198 | BID_SIL3124 = 0, | 217 | BID_SIL3124 = 0, |
@@ -687,6 +706,7 @@ static void sil24_port_stop(struct ata_port *ap) | |||
687 | struct sil24_port_priv *pp = ap->private_data; | 706 | struct sil24_port_priv *pp = ap->private_data; |
688 | 707 | ||
689 | sil24_cblk_free(pp, dev); | 708 | sil24_cblk_free(pp, dev); |
709 | ata_pad_free(ap, dev); | ||
690 | kfree(pp); | 710 | kfree(pp); |
691 | } | 711 | } |
692 | 712 | ||
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 57e5a9d964c3..6e7f7c83a75a 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #endif /* CONFIG_PPC_OF */ | 54 | #endif /* CONFIG_PPC_OF */ |
55 | 55 | ||
56 | #define DRV_NAME "sata_svw" | 56 | #define DRV_NAME "sata_svw" |
57 | #define DRV_VERSION "1.06" | 57 | #define DRV_VERSION "1.07" |
58 | 58 | ||
59 | /* Taskfile registers offsets */ | 59 | /* Taskfile registers offsets */ |
60 | #define K2_SATA_TF_CMD_OFFSET 0x00 | 60 | #define K2_SATA_TF_CMD_OFFSET 0x00 |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index daeaf68743de..2eea6de12d70 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include "sata_promise.h" | 46 | #include "sata_promise.h" |
47 | 47 | ||
48 | #define DRV_NAME "sata_sx4" | 48 | #define DRV_NAME "sata_sx4" |
49 | #define DRV_VERSION "0.7" | 49 | #define DRV_VERSION "0.8" |
50 | 50 | ||
51 | 51 | ||
52 | enum { | 52 | enum { |
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 1278f631e4d7..f566e17246f0 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <linux/libata.h> | 47 | #include <linux/libata.h> |
48 | 48 | ||
49 | #define DRV_NAME "sata_vsc" | 49 | #define DRV_NAME "sata_vsc" |
50 | #define DRV_VERSION "1.0" | 50 | #define DRV_VERSION "1.1" |
51 | 51 | ||
52 | /* Interrupt register offsets (from chip base address) */ | 52 | /* Interrupt register offsets (from chip base address) */ |
53 | #define VSC_SATA_INT_STAT_OFFSET 0x00 | 53 | #define VSC_SATA_INT_STAT_OFFSET 0x00 |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 2efb317153ce..67e9afa000c1 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/keyboard.h> | 34 | #include <linux/keyboard.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/pm.h> | 36 | #include <linux/pm.h> |
37 | #include <linux/pm_legacy.h> | ||
37 | #include <linux/bitops.h> | 38 | #include <linux/bitops.h> |
38 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
39 | 40 | ||
@@ -1343,7 +1344,7 @@ static void show_serial_version(void) | |||
1343 | printk("MC68328 serial driver version 1.00\n"); | 1344 | printk("MC68328 serial driver version 1.00\n"); |
1344 | } | 1345 | } |
1345 | 1346 | ||
1346 | #ifdef CONFIG_PM | 1347 | #ifdef CONFIG_PM_LEGACY |
1347 | /* Serial Power management | 1348 | /* Serial Power management |
1348 | * The console (currently fixed at line 0) is a special case for power | 1349 | * The console (currently fixed at line 0) is a special case for power |
1349 | * management because the kernel is so chatty. The console will be | 1350 | * management because the kernel is so chatty. The console will be |
@@ -1393,7 +1394,7 @@ void startup_console(void) | |||
1393 | struct m68k_serial *info = &m68k_soft[0]; | 1394 | struct m68k_serial *info = &m68k_soft[0]; |
1394 | startup(info); | 1395 | startup(info); |
1395 | } | 1396 | } |
1396 | #endif | 1397 | #endif /* CONFIG_PM_LEGACY */ |
1397 | 1398 | ||
1398 | 1399 | ||
1399 | static struct tty_operations rs_ops = { | 1400 | static struct tty_operations rs_ops = { |
@@ -1486,7 +1487,7 @@ rs68328_init(void) | |||
1486 | IRQ_FLG_STD, | 1487 | IRQ_FLG_STD, |
1487 | "M68328_UART", NULL)) | 1488 | "M68328_UART", NULL)) |
1488 | panic("Unable to attach 68328 serial interrupt\n"); | 1489 | panic("Unable to attach 68328 serial interrupt\n"); |
1489 | #ifdef CONFIG_PM | 1490 | #ifdef CONFIG_PM_LEGACY |
1490 | serial_pm[i] = pm_register(PM_SYS_DEV, PM_SYS_COM, serial_pm_callback); | 1491 | serial_pm[i] = pm_register(PM_SYS_DEV, PM_SYS_COM, serial_pm_callback); |
1491 | if (serial_pm[i]) | 1492 | if (serial_pm[i]) |
1492 | serial_pm[i]->data = info; | 1493 | serial_pm[i]->data = info; |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 3742753241ee..e08510d09ff6 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -999,7 +999,10 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
999 | serial_outp(up, UART_MCR, save_mcr); | 999 | serial_outp(up, UART_MCR, save_mcr); |
1000 | serial8250_clear_fifos(up); | 1000 | serial8250_clear_fifos(up); |
1001 | (void)serial_in(up, UART_RX); | 1001 | (void)serial_in(up, UART_RX); |
1002 | serial_outp(up, UART_IER, 0); | 1002 | if (up->capabilities & UART_CAP_UUE) |
1003 | serial_outp(up, UART_IER, UART_IER_UUE); | ||
1004 | else | ||
1005 | serial_outp(up, UART_IER, 0); | ||
1003 | 1006 | ||
1004 | out: | 1007 | out: |
1005 | spin_unlock_irqrestore(&up->port.lock, flags); | 1008 | spin_unlock_irqrestore(&up->port.lock, flags); |
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 5d8660a42b77..b79ed0665d51 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c | |||
@@ -323,6 +323,8 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
323 | { "USR9180", 0 }, | 323 | { "USR9180", 0 }, |
324 | /* U.S. Robotics 56K Voice INT PnP*/ | 324 | /* U.S. Robotics 56K Voice INT PnP*/ |
325 | { "USR9190", 0 }, | 325 | { "USR9190", 0 }, |
326 | /* HP Compaq Tablet PC tc1100 Wacom tablet */ | ||
327 | { "WACF005", 0 }, | ||
326 | /* Rockwell's (PORALiNK) 33600 INT PNP */ | 328 | /* Rockwell's (PORALiNK) 33600 INT PNP */ |
327 | { "WCI0003", 0 }, | 329 | { "WCI0003", 0 }, |
328 | /* Unkown PnP modems */ | 330 | /* Unkown PnP modems */ |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 25825f2aba22..987d22b53c22 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Based on ppc8xx.c by Thomas Gleixner | 7 | * Based on ppc8xx.c by Thomas Gleixner |
8 | * Based on drivers/serial/amba.c by Russell King | 8 | * Based on drivers/serial/amba.c by Russell King |
9 | * | 9 | * |
10 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) | 10 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) |
11 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) | 11 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) |
12 | * | 12 | * |
13 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 13 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 4b0786e7eb7f..d789ee55cbb7 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Driver for CPM (SCC/SMC) serial ports; CPM1 definitions | 4 | * Driver for CPM (SCC/SMC) serial ports; CPM1 definitions |
5 | * | 5 | * |
6 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) | 6 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) |
7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) | 7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) |
8 | * | 8 | * |
9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 15ad58d94889..fd9e53ed3feb 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Driver for CPM (SCC/SMC) serial ports; CPM2 definitions | 4 | * Driver for CPM (SCC/SMC) serial ports; CPM2 definitions |
5 | * | 5 | * |
6 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) | 6 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) |
7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) | 7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) |
8 | * | 8 | * |
9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index e63b9dffc8d7..4d8516d1bb71 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * dz.c: Serial port driver for DECStations equiped | 2 | * dz.c: Serial port driver for DECStations equiped |
3 | * with the DZ chipset. | 3 | * with the DZ chipset. |
4 | * | 4 | * |
5 | * Copyright (C) 1998 Olivier A. D. Lebaillif | 5 | * Copyright (C) 1998 Olivier A. D. Lebaillif |
6 | * | 6 | * |
7 | * Email: olivier.lebaillif@ifrsys.com | 7 | * Email: olivier.lebaillif@ifrsys.com |
8 | * | 8 | * |
9 | * [31-AUG-98] triemer | 9 | * [31-AUG-98] triemer |
@@ -11,14 +11,14 @@ | |||
11 | * removed base_addr code - moving address assignment to setup.c | 11 | * removed base_addr code - moving address assignment to setup.c |
12 | * Changed name of dz_init to rs_init to be consistent with tc code | 12 | * Changed name of dz_init to rs_init to be consistent with tc code |
13 | * [13-NOV-98] triemer fixed code to receive characters | 13 | * [13-NOV-98] triemer fixed code to receive characters |
14 | * after patches by harald to irq code. | 14 | * after patches by harald to irq code. |
15 | * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout | 15 | * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout |
16 | * field from "current" - somewhere between 2.1.121 and 2.1.131 | 16 | * field from "current" - somewhere between 2.1.121 and 2.1.131 |
17 | Qua Jun 27 15:02:26 BRT 2001 | 17 | Qua Jun 27 15:02:26 BRT 2001 |
18 | * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups | 18 | * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups |
19 | * | 19 | * |
20 | * Parts (C) 1999 David Airlie, airlied@linux.ie | 20 | * Parts (C) 1999 David Airlie, airlied@linux.ie |
21 | * [07-SEP-99] Bugfixes | 21 | * [07-SEP-99] Bugfixes |
22 | * | 22 | * |
23 | * [06-Jan-2002] Russell King <rmk@arm.linux.org.uk> | 23 | * [06-Jan-2002] Russell King <rmk@arm.linux.org.uk> |
24 | * Converted to new serial core | 24 | * Converted to new serial core |
@@ -64,7 +64,7 @@ static struct dz_port dz_ports[DZ_NB_PORT]; | |||
64 | 64 | ||
65 | #ifdef DEBUG_DZ | 65 | #ifdef DEBUG_DZ |
66 | /* | 66 | /* |
67 | * debugging code to send out chars via prom | 67 | * debugging code to send out chars via prom |
68 | */ | 68 | */ |
69 | static void debug_console(const char *s, int count) | 69 | static void debug_console(const char *s, int count) |
70 | { | 70 | { |
@@ -82,7 +82,7 @@ static void debug_console(const char *s, int count) | |||
82 | * ------------------------------------------------------------ | 82 | * ------------------------------------------------------------ |
83 | * dz_in () and dz_out () | 83 | * dz_in () and dz_out () |
84 | * | 84 | * |
85 | * These routines are used to access the registers of the DZ | 85 | * These routines are used to access the registers of the DZ |
86 | * chip, hiding relocation differences between implementation. | 86 | * chip, hiding relocation differences between implementation. |
87 | * ------------------------------------------------------------ | 87 | * ------------------------------------------------------------ |
88 | */ | 88 | */ |
@@ -106,8 +106,8 @@ static inline void dz_out(struct dz_port *dport, unsigned offset, | |||
106 | * ------------------------------------------------------------ | 106 | * ------------------------------------------------------------ |
107 | * rs_stop () and rs_start () | 107 | * rs_stop () and rs_start () |
108 | * | 108 | * |
109 | * These routines are called before setting or resetting | 109 | * These routines are called before setting or resetting |
110 | * tty->stopped. They enable or disable transmitter interrupts, | 110 | * tty->stopped. They enable or disable transmitter interrupts, |
111 | * as necessary. | 111 | * as necessary. |
112 | * ------------------------------------------------------------ | 112 | * ------------------------------------------------------------ |
113 | */ | 113 | */ |
@@ -156,17 +156,17 @@ static void dz_enable_ms(struct uart_port *port) | |||
156 | 156 | ||
157 | /* | 157 | /* |
158 | * ------------------------------------------------------------ | 158 | * ------------------------------------------------------------ |
159 | * Here starts the interrupt handling routines. All of the | 159 | * Here starts the interrupt handling routines. All of the |
160 | * following subroutines are declared as inline and are folded | 160 | * following subroutines are declared as inline and are folded |
161 | * into dz_interrupt. They were separated out for readability's | 161 | * into dz_interrupt. They were separated out for readability's |
162 | * sake. | 162 | * sake. |
163 | * | 163 | * |
164 | * Note: rs_interrupt() is a "fast" interrupt, which means that it | 164 | * Note: rs_interrupt() is a "fast" interrupt, which means that it |
165 | * runs with interrupts turned off. People who may want to modify | 165 | * runs with interrupts turned off. People who may want to modify |
166 | * rs_interrupt() should try to keep the interrupt handler as fast as | 166 | * rs_interrupt() should try to keep the interrupt handler as fast as |
167 | * possible. After you are done making modifications, it is not a bad | 167 | * possible. After you are done making modifications, it is not a bad |
168 | * idea to do: | 168 | * idea to do: |
169 | * | 169 | * |
170 | * make drivers/serial/dz.s | 170 | * make drivers/serial/dz.s |
171 | * | 171 | * |
172 | * and look at the resulting assemble code in dz.s. | 172 | * and look at the resulting assemble code in dz.s. |
@@ -403,7 +403,7 @@ static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl) | |||
403 | * startup () | 403 | * startup () |
404 | * | 404 | * |
405 | * various initialization tasks | 405 | * various initialization tasks |
406 | * ------------------------------------------------------------------- | 406 | * ------------------------------------------------------------------- |
407 | */ | 407 | */ |
408 | static int dz_startup(struct uart_port *uport) | 408 | static int dz_startup(struct uart_port *uport) |
409 | { | 409 | { |
@@ -430,13 +430,13 @@ static int dz_startup(struct uart_port *uport) | |||
430 | return 0; | 430 | return 0; |
431 | } | 431 | } |
432 | 432 | ||
433 | /* | 433 | /* |
434 | * ------------------------------------------------------------------- | 434 | * ------------------------------------------------------------------- |
435 | * shutdown () | 435 | * shutdown () |
436 | * | 436 | * |
437 | * This routine will shutdown a serial port; interrupts are disabled, and | 437 | * This routine will shutdown a serial port; interrupts are disabled, and |
438 | * DTR is dropped if the hangup on close termio flag is on. | 438 | * DTR is dropped if the hangup on close termio flag is on. |
439 | * ------------------------------------------------------------------- | 439 | * ------------------------------------------------------------------- |
440 | */ | 440 | */ |
441 | static void dz_shutdown(struct uart_port *uport) | 441 | static void dz_shutdown(struct uart_port *uport) |
442 | { | 442 | { |
@@ -451,7 +451,7 @@ static void dz_shutdown(struct uart_port *uport) | |||
451 | * release the bus after transmitting. This must be done when | 451 | * release the bus after transmitting. This must be done when |
452 | * the transmit shift register is empty, not be done when the | 452 | * the transmit shift register is empty, not be done when the |
453 | * transmit holding register is empty. This functionality | 453 | * transmit holding register is empty. This functionality |
454 | * allows an RS485 driver to be written in user space. | 454 | * allows an RS485 driver to be written in user space. |
455 | */ | 455 | */ |
456 | static unsigned int dz_tx_empty(struct uart_port *uport) | 456 | static unsigned int dz_tx_empty(struct uart_port *uport) |
457 | { | 457 | { |
@@ -645,9 +645,9 @@ static void __init dz_init_ports(void) | |||
645 | 645 | ||
646 | if (mips_machtype == MACH_DS23100 || | 646 | if (mips_machtype == MACH_DS23100 || |
647 | mips_machtype == MACH_DS5100) | 647 | mips_machtype == MACH_DS5100) |
648 | base = (unsigned long) KN01_DZ11_BASE; | 648 | base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_DZ11); |
649 | else | 649 | else |
650 | base = (unsigned long) KN02_DZ11_BASE; | 650 | base = CKSEG1ADDR(KN02_SLOT_BASE + KN02_DZ11); |
651 | 651 | ||
652 | for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { | 652 | for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { |
653 | spin_lock_init(&dport->port.lock); | 653 | spin_lock_init(&dport->port.lock); |
@@ -695,13 +695,13 @@ static void dz_console_put_char(struct dz_port *dport, unsigned char ch) | |||
695 | 695 | ||
696 | spin_unlock_irqrestore(&dport->port.lock, flags); | 696 | spin_unlock_irqrestore(&dport->port.lock, flags); |
697 | } | 697 | } |
698 | /* | 698 | /* |
699 | * ------------------------------------------------------------------- | 699 | * ------------------------------------------------------------------- |
700 | * dz_console_print () | 700 | * dz_console_print () |
701 | * | 701 | * |
702 | * dz_console_print is registered for printk. | 702 | * dz_console_print is registered for printk. |
703 | * The console must be locked when we get here. | 703 | * The console must be locked when we get here. |
704 | * ------------------------------------------------------------------- | 704 | * ------------------------------------------------------------------- |
705 | */ | 705 | */ |
706 | static void dz_console_print(struct console *cons, | 706 | static void dz_console_print(struct console *cons, |
707 | const char *str, | 707 | const char *str, |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 5d3cb8486447..b8727d9bf690 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -725,7 +725,7 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
725 | int i, idx, ret; | 725 | int i, idx, ret; |
726 | 726 | ||
727 | /* Check validity & presence */ | 727 | /* Check validity & presence */ |
728 | idx = pdev->id; | 728 | idx = dev->id; |
729 | if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM) | 729 | if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM) |
730 | return -EINVAL; | 730 | return -EINVAL; |
731 | 731 | ||
@@ -748,7 +748,7 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
748 | port->ops = &mpc52xx_uart_ops; | 748 | port->ops = &mpc52xx_uart_ops; |
749 | 749 | ||
750 | /* Search for IRQ and mapbase */ | 750 | /* Search for IRQ and mapbase */ |
751 | for (i=0 ; i<pdev->num_resources ; i++, res++) { | 751 | for (i=0 ; i<dev->num_resources ; i++, res++) { |
752 | if (res->flags & IORESOURCE_MEM) | 752 | if (res->flags & IORESOURCE_MEM) |
753 | port->mapbase = res->start; | 753 | port->mapbase = res->start; |
754 | else if (res->flags & IORESOURCE_IRQ) | 754 | else if (res->flags & IORESOURCE_IRQ) |
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index fd9deee20e05..0e3daf6d7b50 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -156,7 +156,7 @@ static void sa1100_stop_tx(struct uart_port *port) | |||
156 | } | 156 | } |
157 | 157 | ||
158 | /* | 158 | /* |
159 | * interrupts may not be disabled on entry | 159 | * port locked and interrupts disabled |
160 | */ | 160 | */ |
161 | static void sa1100_start_tx(struct uart_port *port) | 161 | static void sa1100_start_tx(struct uart_port *port) |
162 | { | 162 | { |
@@ -164,11 +164,9 @@ static void sa1100_start_tx(struct uart_port *port) | |||
164 | unsigned long flags; | 164 | unsigned long flags; |
165 | u32 utcr3; | 165 | u32 utcr3; |
166 | 166 | ||
167 | spin_lock_irqsave(&sport->port.lock, flags); | ||
168 | utcr3 = UART_GET_UTCR3(sport); | 167 | utcr3 = UART_GET_UTCR3(sport); |
169 | sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS); | 168 | sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS); |
170 | UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE); | 169 | UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE); |
171 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
172 | } | 170 | } |
173 | 171 | ||
174 | /* | 172 | /* |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 427a23858076..2331296e1e17 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -209,33 +209,45 @@ static void uart_shutdown(struct uart_state *state) | |||
209 | struct uart_info *info = state->info; | 209 | struct uart_info *info = state->info; |
210 | struct uart_port *port = state->port; | 210 | struct uart_port *port = state->port; |
211 | 211 | ||
212 | if (!(info->flags & UIF_INITIALIZED)) | ||
213 | return; | ||
214 | |||
215 | /* | 212 | /* |
216 | * Turn off DTR and RTS early. | 213 | * Set the TTY IO error marker |
217 | */ | 214 | */ |
218 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) | 215 | if (info->tty) |
219 | uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 216 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
220 | 217 | ||
221 | /* | 218 | if (info->flags & UIF_INITIALIZED) { |
222 | * clear delta_msr_wait queue to avoid mem leaks: we may free | 219 | info->flags &= ~UIF_INITIALIZED; |
223 | * the irq here so the queue might never be woken up. Note | ||
224 | * that we won't end up waiting on delta_msr_wait again since | ||
225 | * any outstanding file descriptors should be pointing at | ||
226 | * hung_up_tty_fops now. | ||
227 | */ | ||
228 | wake_up_interruptible(&info->delta_msr_wait); | ||
229 | 220 | ||
230 | /* | 221 | /* |
231 | * Free the IRQ and disable the port. | 222 | * Turn off DTR and RTS early. |
232 | */ | 223 | */ |
233 | port->ops->shutdown(port); | 224 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) |
225 | uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
226 | |||
227 | /* | ||
228 | * clear delta_msr_wait queue to avoid mem leaks: we may free | ||
229 | * the irq here so the queue might never be woken up. Note | ||
230 | * that we won't end up waiting on delta_msr_wait again since | ||
231 | * any outstanding file descriptors should be pointing at | ||
232 | * hung_up_tty_fops now. | ||
233 | */ | ||
234 | wake_up_interruptible(&info->delta_msr_wait); | ||
235 | |||
236 | /* | ||
237 | * Free the IRQ and disable the port. | ||
238 | */ | ||
239 | port->ops->shutdown(port); | ||
240 | |||
241 | /* | ||
242 | * Ensure that the IRQ handler isn't running on another CPU. | ||
243 | */ | ||
244 | synchronize_irq(port->irq); | ||
245 | } | ||
234 | 246 | ||
235 | /* | 247 | /* |
236 | * Ensure that the IRQ handler isn't running on another CPU. | 248 | * kill off our tasklet |
237 | */ | 249 | */ |
238 | synchronize_irq(port->irq); | 250 | tasklet_kill(&info->tlet); |
239 | 251 | ||
240 | /* | 252 | /* |
241 | * Free the transmit buffer page. | 253 | * Free the transmit buffer page. |
@@ -244,15 +256,6 @@ static void uart_shutdown(struct uart_state *state) | |||
244 | free_page((unsigned long)info->xmit.buf); | 256 | free_page((unsigned long)info->xmit.buf); |
245 | info->xmit.buf = NULL; | 257 | info->xmit.buf = NULL; |
246 | } | 258 | } |
247 | |||
248 | /* | ||
249 | * kill off our tasklet | ||
250 | */ | ||
251 | tasklet_kill(&info->tlet); | ||
252 | if (info->tty) | ||
253 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
254 | |||
255 | info->flags &= ~UIF_INITIALIZED; | ||
256 | } | 259 | } |
257 | 260 | ||
258 | /** | 261 | /** |
@@ -1928,14 +1931,25 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) | |||
1928 | 1931 | ||
1929 | if (state->info && state->info->flags & UIF_INITIALIZED) { | 1932 | if (state->info && state->info->flags & UIF_INITIALIZED) { |
1930 | struct uart_ops *ops = port->ops; | 1933 | struct uart_ops *ops = port->ops; |
1934 | int ret; | ||
1931 | 1935 | ||
1932 | ops->set_mctrl(port, 0); | 1936 | ops->set_mctrl(port, 0); |
1933 | ops->startup(port); | 1937 | ret = ops->startup(port); |
1934 | uart_change_speed(state, NULL); | 1938 | if (ret == 0) { |
1935 | spin_lock_irq(&port->lock); | 1939 | uart_change_speed(state, NULL); |
1936 | ops->set_mctrl(port, port->mctrl); | 1940 | spin_lock_irq(&port->lock); |
1937 | ops->start_tx(port); | 1941 | ops->set_mctrl(port, port->mctrl); |
1938 | spin_unlock_irq(&port->lock); | 1942 | ops->start_tx(port); |
1943 | spin_unlock_irq(&port->lock); | ||
1944 | } else { | ||
1945 | /* | ||
1946 | * Failed to resume - maybe hardware went away? | ||
1947 | * Clear the "initialized" flag so we won't try | ||
1948 | * to call the low level drivers shutdown method. | ||
1949 | */ | ||
1950 | state->info->flags &= ~UIF_INITIALIZED; | ||
1951 | uart_shutdown(state); | ||
1952 | } | ||
1939 | } | 1953 | } |
1940 | 1954 | ||
1941 | up(&state->sem); | 1955 | up(&state->sem); |
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c index c52af73a251b..6756d0fab6fe 100644 --- a/drivers/tc/zs.c +++ b/drivers/tc/zs.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * | 6 | * |
7 | * DECstation changes | 7 | * DECstation changes |
8 | * Copyright (C) 1998-2000 Harald Koerfgen | 8 | * Copyright (C) 1998-2000 Harald Koerfgen |
9 | * Copyright (C) 2000, 2001, 2002, 2003, 2004 Maciej W. Rozycki | 9 | * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Maciej W. Rozycki |
10 | * | 10 | * |
11 | * For the rest of the code the original Copyright applies: | 11 | * For the rest of the code the original Copyright applies: |
12 | * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au) | 12 | * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au) |
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/delay.h> | 55 | #include <linux/delay.h> |
56 | #include <linux/init.h> | 56 | #include <linux/init.h> |
57 | #include <linux/ioport.h> | 57 | #include <linux/ioport.h> |
58 | #include <linux/spinlock.h> | ||
58 | #ifdef CONFIG_SERIAL_DEC_CONSOLE | 59 | #ifdef CONFIG_SERIAL_DEC_CONSOLE |
59 | #include <linux/console.h> | 60 | #include <linux/console.h> |
60 | #endif | 61 | #endif |
@@ -63,7 +64,6 @@ | |||
63 | #include <asm/pgtable.h> | 64 | #include <asm/pgtable.h> |
64 | #include <asm/irq.h> | 65 | #include <asm/irq.h> |
65 | #include <asm/system.h> | 66 | #include <asm/system.h> |
66 | #include <asm/uaccess.h> | ||
67 | #include <asm/bootinfo.h> | 67 | #include <asm/bootinfo.h> |
68 | 68 | ||
69 | #include <asm/dec/interrupts.h> | 69 | #include <asm/dec/interrupts.h> |
@@ -128,6 +128,8 @@ static struct zs_parms ds_parms = { | |||
128 | 128 | ||
129 | #define BUS_PRESENT (DS_BUS_PRESENT) | 129 | #define BUS_PRESENT (DS_BUS_PRESENT) |
130 | 130 | ||
131 | DEFINE_SPINLOCK(zs_lock); | ||
132 | |||
131 | struct dec_zschannel zs_channels[NUM_CHANNELS]; | 133 | struct dec_zschannel zs_channels[NUM_CHANNELS]; |
132 | struct dec_serial zs_soft[NUM_CHANNELS]; | 134 | struct dec_serial zs_soft[NUM_CHANNELS]; |
133 | int zs_channels_found; | 135 | int zs_channels_found; |
@@ -159,8 +161,6 @@ static unsigned char zs_init_regs[16] __initdata = { | |||
159 | 0 /* write 15 */ | 161 | 0 /* write 15 */ |
160 | }; | 162 | }; |
161 | 163 | ||
162 | DECLARE_TASK_QUEUE(tq_zs_serial); | ||
163 | |||
164 | static struct tty_driver *serial_driver; | 164 | static struct tty_driver *serial_driver; |
165 | 165 | ||
166 | /* serial subtype definitions */ | 166 | /* serial subtype definitions */ |
@@ -294,8 +294,7 @@ static inline void zs_rtsdtr(struct dec_serial *info, int which, int set) | |||
294 | { | 294 | { |
295 | unsigned long flags; | 295 | unsigned long flags; |
296 | 296 | ||
297 | 297 | spin_lock_irqsave(&zs_lock, flags); | |
298 | save_flags(flags); cli(); | ||
299 | if (info->zs_channel != info->zs_chan_a) { | 298 | if (info->zs_channel != info->zs_chan_a) { |
300 | if (set) { | 299 | if (set) { |
301 | info->zs_chan_a->curregs[5] |= (which & (RTS | DTR)); | 300 | info->zs_chan_a->curregs[5] |= (which & (RTS | DTR)); |
@@ -304,7 +303,7 @@ static inline void zs_rtsdtr(struct dec_serial *info, int which, int set) | |||
304 | } | 303 | } |
305 | write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]); | 304 | write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]); |
306 | } | 305 | } |
307 | restore_flags(flags); | 306 | spin_unlock_irqrestore(&zs_lock, flags); |
308 | } | 307 | } |
309 | 308 | ||
310 | /* Utility routines for the Zilog */ | 309 | /* Utility routines for the Zilog */ |
@@ -345,12 +344,10 @@ static inline void rs_recv_clear(struct dec_zschannel *zsc) | |||
345 | * This routine is used by the interrupt handler to schedule | 344 | * This routine is used by the interrupt handler to schedule |
346 | * processing in the software interrupt portion of the driver. | 345 | * processing in the software interrupt portion of the driver. |
347 | */ | 346 | */ |
348 | static _INLINE_ void rs_sched_event(struct dec_serial *info, | 347 | static _INLINE_ void rs_sched_event(struct dec_serial *info, int event) |
349 | int event) | ||
350 | { | 348 | { |
351 | info->event |= 1 << event; | 349 | info->event |= 1 << event; |
352 | queue_task(&info->tqueue, &tq_zs_serial); | 350 | tasklet_schedule(&info->tlet); |
353 | mark_bh(SERIAL_BH); | ||
354 | } | 351 | } |
355 | 352 | ||
356 | static _INLINE_ void receive_chars(struct dec_serial *info, | 353 | static _INLINE_ void receive_chars(struct dec_serial *info, |
@@ -497,9 +494,10 @@ static _INLINE_ void status_handle(struct dec_serial *info) | |||
497 | /* | 494 | /* |
498 | * This is the serial driver's generic interrupt routine | 495 | * This is the serial driver's generic interrupt routine |
499 | */ | 496 | */ |
500 | void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) | 497 | static irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
501 | { | 498 | { |
502 | struct dec_serial *info = (struct dec_serial *) dev_id; | 499 | struct dec_serial *info = (struct dec_serial *) dev_id; |
500 | irqreturn_t status = IRQ_NONE; | ||
503 | unsigned char zs_intreg; | 501 | unsigned char zs_intreg; |
504 | int shift; | 502 | int shift; |
505 | 503 | ||
@@ -521,6 +519,8 @@ void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
521 | if ((zs_intreg & CHAN_IRQMASK) == 0) | 519 | if ((zs_intreg & CHAN_IRQMASK) == 0) |
522 | break; | 520 | break; |
523 | 521 | ||
522 | status = IRQ_HANDLED; | ||
523 | |||
524 | if (zs_intreg & CHBRxIP) { | 524 | if (zs_intreg & CHBRxIP) { |
525 | receive_chars(info, regs); | 525 | receive_chars(info, regs); |
526 | } | 526 | } |
@@ -534,6 +534,8 @@ void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
534 | 534 | ||
535 | /* Why do we need this ? */ | 535 | /* Why do we need this ? */ |
536 | write_zsreg(info->zs_channel, 0, RES_H_IUS); | 536 | write_zsreg(info->zs_channel, 0, RES_H_IUS); |
537 | |||
538 | return status; | ||
537 | } | 539 | } |
538 | 540 | ||
539 | #ifdef ZS_DEBUG_REGS | 541 | #ifdef ZS_DEBUG_REGS |
@@ -578,12 +580,12 @@ static void rs_stop(struct tty_struct *tty) | |||
578 | return; | 580 | return; |
579 | 581 | ||
580 | #if 1 | 582 | #if 1 |
581 | save_flags(flags); cli(); | 583 | spin_lock_irqsave(&zs_lock, flags); |
582 | if (info->zs_channel->curregs[5] & TxENAB) { | 584 | if (info->zs_channel->curregs[5] & TxENAB) { |
583 | info->zs_channel->curregs[5] &= ~TxENAB; | 585 | info->zs_channel->curregs[5] &= ~TxENAB; |
584 | write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); | 586 | write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); |
585 | } | 587 | } |
586 | restore_flags(flags); | 588 | spin_unlock_irqrestore(&zs_lock, flags); |
587 | #endif | 589 | #endif |
588 | } | 590 | } |
589 | 591 | ||
@@ -595,7 +597,7 @@ static void rs_start(struct tty_struct *tty) | |||
595 | if (serial_paranoia_check(info, tty->name, "rs_start")) | 597 | if (serial_paranoia_check(info, tty->name, "rs_start")) |
596 | return; | 598 | return; |
597 | 599 | ||
598 | save_flags(flags); cli(); | 600 | spin_lock_irqsave(&zs_lock, flags); |
599 | #if 1 | 601 | #if 1 |
600 | if (info->xmit_cnt && info->xmit_buf && !(info->zs_channel->curregs[5] & TxENAB)) { | 602 | if (info->xmit_cnt && info->xmit_buf && !(info->zs_channel->curregs[5] & TxENAB)) { |
601 | info->zs_channel->curregs[5] |= TxENAB; | 603 | info->zs_channel->curregs[5] |= TxENAB; |
@@ -606,7 +608,7 @@ static void rs_start(struct tty_struct *tty) | |||
606 | transmit_chars(info); | 608 | transmit_chars(info); |
607 | } | 609 | } |
608 | #endif | 610 | #endif |
609 | restore_flags(flags); | 611 | spin_unlock_irqrestore(&zs_lock, flags); |
610 | } | 612 | } |
611 | 613 | ||
612 | /* | 614 | /* |
@@ -618,12 +620,8 @@ static void rs_start(struct tty_struct *tty) | |||
618 | * interrupt driver proper are done; the interrupt driver schedules | 620 | * interrupt driver proper are done; the interrupt driver schedules |
619 | * them using rs_sched_event(), and they get done here. | 621 | * them using rs_sched_event(), and they get done here. |
620 | */ | 622 | */ |
621 | static void do_serial_bh(void) | ||
622 | { | ||
623 | run_task_queue(&tq_zs_serial); | ||
624 | } | ||
625 | 623 | ||
626 | static void do_softint(void *private_) | 624 | static void do_softint(unsigned long private_) |
627 | { | 625 | { |
628 | struct dec_serial *info = (struct dec_serial *) private_; | 626 | struct dec_serial *info = (struct dec_serial *) private_; |
629 | struct tty_struct *tty; | 627 | struct tty_struct *tty; |
@@ -634,10 +632,11 @@ static void do_softint(void *private_) | |||
634 | 632 | ||
635 | if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { | 633 | if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { |
636 | tty_wakeup(tty); | 634 | tty_wakeup(tty); |
635 | wake_up_interruptible(&tty->write_wait); | ||
637 | } | 636 | } |
638 | } | 637 | } |
639 | 638 | ||
640 | int zs_startup(struct dec_serial * info) | 639 | static int zs_startup(struct dec_serial * info) |
641 | { | 640 | { |
642 | unsigned long flags; | 641 | unsigned long flags; |
643 | 642 | ||
@@ -650,7 +649,7 @@ int zs_startup(struct dec_serial * info) | |||
650 | return -ENOMEM; | 649 | return -ENOMEM; |
651 | } | 650 | } |
652 | 651 | ||
653 | save_flags(flags); cli(); | 652 | spin_lock_irqsave(&zs_lock, flags); |
654 | 653 | ||
655 | #ifdef SERIAL_DEBUG_OPEN | 654 | #ifdef SERIAL_DEBUG_OPEN |
656 | printk("starting up ttyS%d (irq %d)...", info->line, info->irq); | 655 | printk("starting up ttyS%d (irq %d)...", info->line, info->irq); |
@@ -706,7 +705,7 @@ int zs_startup(struct dec_serial * info) | |||
706 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 705 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
707 | 706 | ||
708 | info->flags |= ZILOG_INITIALIZED; | 707 | info->flags |= ZILOG_INITIALIZED; |
709 | restore_flags(flags); | 708 | spin_unlock_irqrestore(&zs_lock, flags); |
710 | return 0; | 709 | return 0; |
711 | } | 710 | } |
712 | 711 | ||
@@ -726,7 +725,7 @@ static void shutdown(struct dec_serial * info) | |||
726 | info->irq); | 725 | info->irq); |
727 | #endif | 726 | #endif |
728 | 727 | ||
729 | save_flags(flags); cli(); /* Disable interrupts */ | 728 | spin_lock_irqsave(&zs_lock, flags); |
730 | 729 | ||
731 | if (info->xmit_buf) { | 730 | if (info->xmit_buf) { |
732 | free_page((unsigned long) info->xmit_buf); | 731 | free_page((unsigned long) info->xmit_buf); |
@@ -749,7 +748,7 @@ static void shutdown(struct dec_serial * info) | |||
749 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 748 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
750 | 749 | ||
751 | info->flags &= ~ZILOG_INITIALIZED; | 750 | info->flags &= ~ZILOG_INITIALIZED; |
752 | restore_flags(flags); | 751 | spin_unlock_irqrestore(&zs_lock, flags); |
753 | } | 752 | } |
754 | 753 | ||
755 | /* | 754 | /* |
@@ -785,7 +784,7 @@ static void change_speed(struct dec_serial *info) | |||
785 | i += 15; | 784 | i += 15; |
786 | } | 785 | } |
787 | 786 | ||
788 | save_flags(flags); cli(); | 787 | spin_lock_irqsave(&zs_lock, flags); |
789 | info->zs_baud = baud_table[i]; | 788 | info->zs_baud = baud_table[i]; |
790 | if (info->zs_baud) { | 789 | if (info->zs_baud) { |
791 | brg = BPS_TO_BRG(info->zs_baud, zs_parms->clock/info->clk_divisor); | 790 | brg = BPS_TO_BRG(info->zs_baud, zs_parms->clock/info->clk_divisor); |
@@ -858,7 +857,7 @@ static void change_speed(struct dec_serial *info) | |||
858 | /* Load up the new values */ | 857 | /* Load up the new values */ |
859 | load_zsregs(info->zs_channel, info->zs_channel->curregs); | 858 | load_zsregs(info->zs_channel, info->zs_channel->curregs); |
860 | 859 | ||
861 | restore_flags(flags); | 860 | spin_unlock_irqrestore(&zs_lock, flags); |
862 | } | 861 | } |
863 | 862 | ||
864 | static void rs_flush_chars(struct tty_struct *tty) | 863 | static void rs_flush_chars(struct tty_struct *tty) |
@@ -874,9 +873,9 @@ static void rs_flush_chars(struct tty_struct *tty) | |||
874 | return; | 873 | return; |
875 | 874 | ||
876 | /* Enable transmitter */ | 875 | /* Enable transmitter */ |
877 | save_flags(flags); cli(); | 876 | spin_lock_irqsave(&zs_lock, flags); |
878 | transmit_chars(info); | 877 | transmit_chars(info); |
879 | restore_flags(flags); | 878 | spin_unlock_irqrestore(&zs_lock, flags); |
880 | } | 879 | } |
881 | 880 | ||
882 | static int rs_write(struct tty_struct * tty, | 881 | static int rs_write(struct tty_struct * tty, |
@@ -892,26 +891,17 @@ static int rs_write(struct tty_struct * tty, | |||
892 | if (!tty || !info->xmit_buf) | 891 | if (!tty || !info->xmit_buf) |
893 | return 0; | 892 | return 0; |
894 | 893 | ||
895 | save_flags(flags); | ||
896 | while (1) { | 894 | while (1) { |
897 | cli(); | 895 | spin_lock_irqsave(&zs_lock, flags); |
898 | c = min(count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, | 896 | c = min(count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, |
899 | SERIAL_XMIT_SIZE - info->xmit_head)); | 897 | SERIAL_XMIT_SIZE - info->xmit_head)); |
900 | if (c <= 0) | 898 | if (c <= 0) |
901 | break; | 899 | break; |
902 | 900 | ||
903 | if (from_user) { | 901 | memcpy(info->xmit_buf + info->xmit_head, buf, c); |
904 | down(&tmp_buf_sem); | ||
905 | copy_from_user(tmp_buf, buf, c); | ||
906 | c = min(c, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, | ||
907 | SERIAL_XMIT_SIZE - info->xmit_head)); | ||
908 | memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); | ||
909 | up(&tmp_buf_sem); | ||
910 | } else | ||
911 | memcpy(info->xmit_buf + info->xmit_head, buf, c); | ||
912 | info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); | 902 | info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); |
913 | info->xmit_cnt += c; | 903 | info->xmit_cnt += c; |
914 | restore_flags(flags); | 904 | spin_unlock_irqrestore(&zs_lock, flags); |
915 | buf += c; | 905 | buf += c; |
916 | count -= c; | 906 | count -= c; |
917 | total += c; | 907 | total += c; |
@@ -920,7 +910,7 @@ static int rs_write(struct tty_struct * tty, | |||
920 | if (info->xmit_cnt && !tty->stopped && !info->tx_stopped | 910 | if (info->xmit_cnt && !tty->stopped && !info->tx_stopped |
921 | && !info->tx_active) | 911 | && !info->tx_active) |
922 | transmit_chars(info); | 912 | transmit_chars(info); |
923 | restore_flags(flags); | 913 | spin_unlock_irqrestore(&zs_lock, flags); |
924 | return total; | 914 | return total; |
925 | } | 915 | } |
926 | 916 | ||
@@ -952,9 +942,9 @@ static void rs_flush_buffer(struct tty_struct *tty) | |||
952 | 942 | ||
953 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) | 943 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) |
954 | return; | 944 | return; |
955 | cli(); | 945 | spin_lock_irq(&zs_lock); |
956 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 946 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
957 | sti(); | 947 | spin_unlock_irq(&zs_lock); |
958 | tty_wakeup(tty); | 948 | tty_wakeup(tty); |
959 | } | 949 | } |
960 | 950 | ||
@@ -982,11 +972,11 @@ static void rs_throttle(struct tty_struct * tty) | |||
982 | return; | 972 | return; |
983 | 973 | ||
984 | if (I_IXOFF(tty)) { | 974 | if (I_IXOFF(tty)) { |
985 | save_flags(flags); cli(); | 975 | spin_lock_irqsave(&zs_lock, flags); |
986 | info->x_char = STOP_CHAR(tty); | 976 | info->x_char = STOP_CHAR(tty); |
987 | if (!info->tx_active) | 977 | if (!info->tx_active) |
988 | transmit_chars(info); | 978 | transmit_chars(info); |
989 | restore_flags(flags); | 979 | spin_unlock_irqrestore(&zs_lock, flags); |
990 | } | 980 | } |
991 | 981 | ||
992 | if (C_CRTSCTS(tty)) { | 982 | if (C_CRTSCTS(tty)) { |
@@ -1010,7 +1000,7 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
1010 | return; | 1000 | return; |
1011 | 1001 | ||
1012 | if (I_IXOFF(tty)) { | 1002 | if (I_IXOFF(tty)) { |
1013 | save_flags(flags); cli(); | 1003 | spin_lock_irqsave(&zs_lock, flags); |
1014 | if (info->x_char) | 1004 | if (info->x_char) |
1015 | info->x_char = 0; | 1005 | info->x_char = 0; |
1016 | else { | 1006 | else { |
@@ -1018,7 +1008,7 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
1018 | if (!info->tx_active) | 1008 | if (!info->tx_active) |
1019 | transmit_chars(info); | 1009 | transmit_chars(info); |
1020 | } | 1010 | } |
1021 | restore_flags(flags); | 1011 | spin_unlock_irqrestore(&zs_lock, flags); |
1022 | } | 1012 | } |
1023 | 1013 | ||
1024 | if (C_CRTSCTS(tty)) { | 1014 | if (C_CRTSCTS(tty)) { |
@@ -1111,9 +1101,9 @@ static int get_lsr_info(struct dec_serial * info, unsigned int *value) | |||
1111 | { | 1101 | { |
1112 | unsigned char status; | 1102 | unsigned char status; |
1113 | 1103 | ||
1114 | cli(); | 1104 | spin_lock(&zs_lock); |
1115 | status = read_zsreg(info->zs_channel, 0); | 1105 | status = read_zsreg(info->zs_channel, 0); |
1116 | sti(); | 1106 | spin_unlock_irq(&zs_lock); |
1117 | put_user(status,value); | 1107 | put_user(status,value); |
1118 | return 0; | 1108 | return 0; |
1119 | } | 1109 | } |
@@ -1136,11 +1126,11 @@ static int rs_tiocmget(struct tty_struct *tty, struct file *file) | |||
1136 | if (info->zs_channel == info->zs_chan_a) | 1126 | if (info->zs_channel == info->zs_chan_a) |
1137 | result = 0; | 1127 | result = 0; |
1138 | else { | 1128 | else { |
1139 | cli(); | 1129 | spin_lock(&zs_lock); |
1140 | control = info->zs_chan_a->curregs[5]; | 1130 | control = info->zs_chan_a->curregs[5]; |
1141 | status_a = read_zsreg(info->zs_chan_a, 0); | 1131 | status_a = read_zsreg(info->zs_chan_a, 0); |
1142 | status_b = read_zsreg(info->zs_channel, 0); | 1132 | status_b = read_zsreg(info->zs_channel, 0); |
1143 | sti(); | 1133 | spin_unlock_irq(&zs_lock); |
1144 | result = ((control & RTS) ? TIOCM_RTS: 0) | 1134 | result = ((control & RTS) ? TIOCM_RTS: 0) |
1145 | | ((control & DTR) ? TIOCM_DTR: 0) | 1135 | | ((control & DTR) ? TIOCM_DTR: 0) |
1146 | | ((status_b & DCD) ? TIOCM_CAR: 0) | 1136 | | ((status_b & DCD) ? TIOCM_CAR: 0) |
@@ -1155,8 +1145,6 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file, | |||
1155 | unsigned int set, unsigned int clear) | 1145 | unsigned int set, unsigned int clear) |
1156 | { | 1146 | { |
1157 | struct dec_serial * info = (struct dec_serial *)tty->driver_data; | 1147 | struct dec_serial * info = (struct dec_serial *)tty->driver_data; |
1158 | int error; | ||
1159 | unsigned int arg, bits; | ||
1160 | 1148 | ||
1161 | if (info->hook) | 1149 | if (info->hook) |
1162 | return -ENODEV; | 1150 | return -ENODEV; |
@@ -1170,8 +1158,7 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file, | |||
1170 | if (info->zs_channel == info->zs_chan_a) | 1158 | if (info->zs_channel == info->zs_chan_a) |
1171 | return 0; | 1159 | return 0; |
1172 | 1160 | ||
1173 | get_user(arg, value); | 1161 | spin_lock(&zs_lock); |
1174 | cli(); | ||
1175 | if (set & TIOCM_RTS) | 1162 | if (set & TIOCM_RTS) |
1176 | info->zs_chan_a->curregs[5] |= RTS; | 1163 | info->zs_chan_a->curregs[5] |= RTS; |
1177 | if (set & TIOCM_DTR) | 1164 | if (set & TIOCM_DTR) |
@@ -1181,7 +1168,7 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file, | |||
1181 | if (clear & TIOCM_DTR) | 1168 | if (clear & TIOCM_DTR) |
1182 | info->zs_chan_a->curregs[5] &= ~DTR; | 1169 | info->zs_chan_a->curregs[5] &= ~DTR; |
1183 | write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]); | 1170 | write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]); |
1184 | sti(); | 1171 | spin_unlock_irq(&zs_lock); |
1185 | return 0; | 1172 | return 0; |
1186 | } | 1173 | } |
1187 | 1174 | ||
@@ -1198,19 +1185,18 @@ static void rs_break(struct tty_struct *tty, int break_state) | |||
1198 | if (!info->port) | 1185 | if (!info->port) |
1199 | return; | 1186 | return; |
1200 | 1187 | ||
1201 | save_flags(flags); cli(); | 1188 | spin_lock_irqsave(&zs_lock, flags); |
1202 | if (break_state == -1) | 1189 | if (break_state == -1) |
1203 | info->zs_channel->curregs[5] |= SND_BRK; | 1190 | info->zs_channel->curregs[5] |= SND_BRK; |
1204 | else | 1191 | else |
1205 | info->zs_channel->curregs[5] &= ~SND_BRK; | 1192 | info->zs_channel->curregs[5] &= ~SND_BRK; |
1206 | write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); | 1193 | write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); |
1207 | restore_flags(flags); | 1194 | spin_unlock_irqrestore(&zs_lock, flags); |
1208 | } | 1195 | } |
1209 | 1196 | ||
1210 | static int rs_ioctl(struct tty_struct *tty, struct file * file, | 1197 | static int rs_ioctl(struct tty_struct *tty, struct file * file, |
1211 | unsigned int cmd, unsigned long arg) | 1198 | unsigned int cmd, unsigned long arg) |
1212 | { | 1199 | { |
1213 | int error; | ||
1214 | struct dec_serial * info = (struct dec_serial *)tty->driver_data; | 1200 | struct dec_serial * info = (struct dec_serial *)tty->driver_data; |
1215 | 1201 | ||
1216 | if (info->hook) | 1202 | if (info->hook) |
@@ -1287,10 +1273,10 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1287 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) | 1273 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) |
1288 | return; | 1274 | return; |
1289 | 1275 | ||
1290 | save_flags(flags); cli(); | 1276 | spin_lock_irqsave(&zs_lock, flags); |
1291 | 1277 | ||
1292 | if (tty_hung_up_p(filp)) { | 1278 | if (tty_hung_up_p(filp)) { |
1293 | restore_flags(flags); | 1279 | spin_unlock_irqrestore(&zs_lock, flags); |
1294 | return; | 1280 | return; |
1295 | } | 1281 | } |
1296 | 1282 | ||
@@ -1315,7 +1301,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1315 | info->count = 0; | 1301 | info->count = 0; |
1316 | } | 1302 | } |
1317 | if (info->count) { | 1303 | if (info->count) { |
1318 | restore_flags(flags); | 1304 | spin_unlock_irqrestore(&zs_lock, flags); |
1319 | return; | 1305 | return; |
1320 | } | 1306 | } |
1321 | info->flags |= ZILOG_CLOSING; | 1307 | info->flags |= ZILOG_CLOSING; |
@@ -1358,7 +1344,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1358 | } | 1344 | } |
1359 | info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CLOSING); | 1345 | info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CLOSING); |
1360 | wake_up_interruptible(&info->close_wait); | 1346 | wake_up_interruptible(&info->close_wait); |
1361 | restore_flags(flags); | 1347 | spin_unlock_irqrestore(&zs_lock, flags); |
1362 | } | 1348 | } |
1363 | 1349 | ||
1364 | /* | 1350 | /* |
@@ -1398,7 +1384,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1398 | /* | 1384 | /* |
1399 | * rs_hangup() --- called by tty_hangup() when a hangup is signaled. | 1385 | * rs_hangup() --- called by tty_hangup() when a hangup is signaled. |
1400 | */ | 1386 | */ |
1401 | void rs_hangup(struct tty_struct *tty) | 1387 | static void rs_hangup(struct tty_struct *tty) |
1402 | { | 1388 | { |
1403 | struct dec_serial * info = (struct dec_serial *)tty->driver_data; | 1389 | struct dec_serial * info = (struct dec_serial *)tty->driver_data; |
1404 | 1390 | ||
@@ -1466,16 +1452,16 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1466 | printk("block_til_ready before block: ttyS%d, count = %d\n", | 1452 | printk("block_til_ready before block: ttyS%d, count = %d\n", |
1467 | info->line, info->count); | 1453 | info->line, info->count); |
1468 | #endif | 1454 | #endif |
1469 | cli(); | 1455 | spin_lock(&zs_lock); |
1470 | if (!tty_hung_up_p(filp)) | 1456 | if (!tty_hung_up_p(filp)) |
1471 | info->count--; | 1457 | info->count--; |
1472 | sti(); | 1458 | spin_unlock_irq(&zs_lock); |
1473 | info->blocked_open++; | 1459 | info->blocked_open++; |
1474 | while (1) { | 1460 | while (1) { |
1475 | cli(); | 1461 | spin_lock(&zs_lock); |
1476 | if (tty->termios->c_cflag & CBAUD) | 1462 | if (tty->termios->c_cflag & CBAUD) |
1477 | zs_rtsdtr(info, RTS | DTR, 1); | 1463 | zs_rtsdtr(info, RTS | DTR, 1); |
1478 | sti(); | 1464 | spin_unlock_irq(&zs_lock); |
1479 | set_current_state(TASK_INTERRUPTIBLE); | 1465 | set_current_state(TASK_INTERRUPTIBLE); |
1480 | if (tty_hung_up_p(filp) || | 1466 | if (tty_hung_up_p(filp) || |
1481 | !(info->flags & ZILOG_INITIALIZED)) { | 1467 | !(info->flags & ZILOG_INITIALIZED)) { |
@@ -1523,7 +1509,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1523 | * the IRQ chain. It also performs the serial-specific | 1509 | * the IRQ chain. It also performs the serial-specific |
1524 | * initialization for the tty structure. | 1510 | * initialization for the tty structure. |
1525 | */ | 1511 | */ |
1526 | int rs_open(struct tty_struct *tty, struct file * filp) | 1512 | static int rs_open(struct tty_struct *tty, struct file * filp) |
1527 | { | 1513 | { |
1528 | struct dec_serial *info; | 1514 | struct dec_serial *info; |
1529 | int retval, line; | 1515 | int retval, line; |
@@ -1706,7 +1692,7 @@ static void __init probe_sccs(void) | |||
1706 | } | 1692 | } |
1707 | } | 1693 | } |
1708 | 1694 | ||
1709 | save_and_cli(flags); | 1695 | spin_lock_irqsave(&zs_lock, flags); |
1710 | for (n = 0; n < zs_channels_found; n++) { | 1696 | for (n = 0; n < zs_channels_found; n++) { |
1711 | if (n % 2 == 0) { | 1697 | if (n % 2 == 0) { |
1712 | write_zsreg(zs_soft[n].zs_chan_a, R9, FHWRES); | 1698 | write_zsreg(zs_soft[n].zs_chan_a, R9, FHWRES); |
@@ -1716,7 +1702,7 @@ static void __init probe_sccs(void) | |||
1716 | load_zsregs(zs_soft[n].zs_channel, | 1702 | load_zsregs(zs_soft[n].zs_channel, |
1717 | zs_soft[n].zs_channel->curregs); | 1703 | zs_soft[n].zs_channel->curregs); |
1718 | } | 1704 | } |
1719 | restore_flags(flags); | 1705 | spin_unlock_irqrestore(&zs_lock, flags); |
1720 | } | 1706 | } |
1721 | 1707 | ||
1722 | static struct tty_operations serial_ops = { | 1708 | static struct tty_operations serial_ops = { |
@@ -1749,9 +1735,6 @@ int __init zs_init(void) | |||
1749 | if(!BUS_PRESENT) | 1735 | if(!BUS_PRESENT) |
1750 | return -ENODEV; | 1736 | return -ENODEV; |
1751 | 1737 | ||
1752 | /* Setup base handler, and timer table. */ | ||
1753 | init_bh(SERIAL_BH, do_serial_bh); | ||
1754 | |||
1755 | /* Find out how many Z8530 SCCs we have */ | 1738 | /* Find out how many Z8530 SCCs we have */ |
1756 | if (zs_chain == 0) | 1739 | if (zs_chain == 0) |
1757 | probe_sccs(); | 1740 | probe_sccs(); |
@@ -1800,8 +1783,7 @@ int __init zs_init(void) | |||
1800 | info->event = 0; | 1783 | info->event = 0; |
1801 | info->count = 0; | 1784 | info->count = 0; |
1802 | info->blocked_open = 0; | 1785 | info->blocked_open = 0; |
1803 | info->tqueue.routine = do_softint; | 1786 | tasklet_init(&info->tlet, do_softint, (unsigned long)info); |
1804 | info->tqueue.data = info; | ||
1805 | init_waitqueue_head(&info->open_wait); | 1787 | init_waitqueue_head(&info->open_wait); |
1806 | init_waitqueue_head(&info->close_wait); | 1788 | init_waitqueue_head(&info->close_wait); |
1807 | printk("ttyS%02d at 0x%08x (irq = %d) is a Z85C30 SCC\n", | 1789 | printk("ttyS%02d at 0x%08x (irq = %d) is a Z85C30 SCC\n", |
@@ -1833,8 +1815,7 @@ int __init zs_init(void) | |||
1833 | /* | 1815 | /* |
1834 | * polling I/O routines | 1816 | * polling I/O routines |
1835 | */ | 1817 | */ |
1836 | static int | 1818 | static int zs_poll_tx_char(void *handle, unsigned char ch) |
1837 | zs_poll_tx_char(void *handle, unsigned char ch) | ||
1838 | { | 1819 | { |
1839 | struct dec_serial *info = handle; | 1820 | struct dec_serial *info = handle; |
1840 | struct dec_zschannel *chan = info->zs_channel; | 1821 | struct dec_zschannel *chan = info->zs_channel; |
@@ -1857,8 +1838,7 @@ zs_poll_tx_char(void *handle, unsigned char ch) | |||
1857 | return -ENODEV; | 1838 | return -ENODEV; |
1858 | } | 1839 | } |
1859 | 1840 | ||
1860 | static int | 1841 | static int zs_poll_rx_char(void *handle) |
1861 | zs_poll_rx_char(void *handle) | ||
1862 | { | 1842 | { |
1863 | struct dec_serial *info = handle; | 1843 | struct dec_serial *info = handle; |
1864 | struct dec_zschannel *chan = info->zs_channel; | 1844 | struct dec_zschannel *chan = info->zs_channel; |
@@ -2037,7 +2017,7 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
2037 | } | 2017 | } |
2038 | co->cflag = cflag; | 2018 | co->cflag = cflag; |
2039 | 2019 | ||
2040 | save_and_cli(flags); | 2020 | spin_lock_irqsave(&zs_lock, flags); |
2041 | 2021 | ||
2042 | /* | 2022 | /* |
2043 | * Set up the baud rate generator. | 2023 | * Set up the baud rate generator. |
@@ -2092,7 +2072,7 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
2092 | zs_soft[co->index].clk_divisor = clk_divisor; | 2072 | zs_soft[co->index].clk_divisor = clk_divisor; |
2093 | zs_soft[co->index].zs_baud = get_zsbaud(&zs_soft[co->index]); | 2073 | zs_soft[co->index].zs_baud = get_zsbaud(&zs_soft[co->index]); |
2094 | 2074 | ||
2095 | restore_flags(flags); | 2075 | spin_unlock_irqrestore(&zs_lock, flags); |
2096 | 2076 | ||
2097 | return 0; | 2077 | return 0; |
2098 | } | 2078 | } |
@@ -2229,5 +2209,3 @@ void __init zs_kgdb_hook(int tty_num) | |||
2229 | set_debug_traps(); /* init stub */ | 2209 | set_debug_traps(); /* init stub */ |
2230 | } | 2210 | } |
2231 | #endif /* ifdef CONFIG_KGDB */ | 2211 | #endif /* ifdef CONFIG_KGDB */ |
2232 | |||
2233 | |||
diff --git a/drivers/tc/zs.h b/drivers/tc/zs.h index c52edffa6049..13512200ceba 100644 --- a/drivers/tc/zs.h +++ b/drivers/tc/zs.h | |||
@@ -6,14 +6,14 @@ | |||
6 | * | 6 | * |
7 | * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au) | 7 | * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au) |
8 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | 8 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) |
9 | * Copyright (C) 2004 Maciej W. Rozycki | 9 | * Copyright (C) 2004, 2005 Maciej W. Rozycki |
10 | */ | 10 | */ |
11 | #ifndef _DECSERIAL_H | 11 | #ifndef _DECSERIAL_H |
12 | #define _DECSERIAL_H | 12 | #define _DECSERIAL_H |
13 | 13 | ||
14 | #include <asm/dec/serial.h> | 14 | #include <asm/dec/serial.h> |
15 | 15 | ||
16 | #define NUM_ZSREGS 16 | 16 | #define NUM_ZSREGS 16 |
17 | 17 | ||
18 | struct serial_struct { | 18 | struct serial_struct { |
19 | int type; | 19 | int type; |
@@ -139,8 +139,7 @@ struct dec_serial { | |||
139 | int xmit_head; | 139 | int xmit_head; |
140 | int xmit_tail; | 140 | int xmit_tail; |
141 | int xmit_cnt; | 141 | int xmit_cnt; |
142 | struct tq_struct tqueue; | 142 | struct tasklet_struct tlet; |
143 | struct tq_struct tqueue_hangup; | ||
144 | wait_queue_head_t open_wait; | 143 | wait_queue_head_t open_wait; |
145 | wait_queue_head_t close_wait; | 144 | wait_queue_head_t close_wait; |
146 | }; | 145 | }; |
@@ -282,7 +281,7 @@ struct dec_serial { | |||
282 | #define DLC 4 /* Disable Lower Chain */ | 281 | #define DLC 4 /* Disable Lower Chain */ |
283 | #define MIE 8 /* Master Interrupt Enable */ | 282 | #define MIE 8 /* Master Interrupt Enable */ |
284 | #define STATHI 0x10 /* Status high */ | 283 | #define STATHI 0x10 /* Status high */ |
285 | #define SOFTACK 0x20 /* Software Interrupt Acknowledge */ | 284 | #define SOFTACK 0x20 /* Software Interrupt Acknowledge */ |
286 | #define NORESET 0 /* No reset on write to R9 */ | 285 | #define NORESET 0 /* No reset on write to R9 */ |
287 | #define CHRB 0x40 /* Reset channel B */ | 286 | #define CHRB 0x40 /* Reset channel B */ |
288 | #define CHRA 0x80 /* Reset channel A */ | 287 | #define CHRA 0x80 /* Reset channel A */ |
@@ -395,8 +394,8 @@ struct dec_serial { | |||
395 | /* Read Register 15 (value of WR 15) */ | 394 | /* Read Register 15 (value of WR 15) */ |
396 | 395 | ||
397 | /* Misc macros */ | 396 | /* Misc macros */ |
398 | #define ZS_CLEARERR(channel) (write_zsreg(channel, 0, ERR_RES)) | 397 | #define ZS_CLEARERR(channel) (write_zsreg(channel, 0, ERR_RES)) |
399 | #define ZS_CLEARFIFO(channel) do { volatile unsigned char garbage; \ | 398 | #define ZS_CLEARFIFO(channel) do { volatile unsigned char garbage; \ |
400 | garbage = read_zsdata(channel); \ | 399 | garbage = read_zsdata(channel); \ |
401 | garbage = read_zsdata(channel); \ | 400 | garbage = read_zsdata(channel); \ |
402 | garbage = read_zsdata(channel); \ | 401 | garbage = read_zsdata(channel); \ |
diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile index 751f297be2ef..85099718c683 100644 --- a/drivers/usb/atm/Makefile +++ b/drivers/usb/atm/Makefile | |||
@@ -6,3 +6,7 @@ obj-$(CONFIG_USB_CXACRU) += cxacru.o | |||
6 | obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o | 6 | obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o |
7 | obj-$(CONFIG_USB_ATM) += usbatm.o | 7 | obj-$(CONFIG_USB_ATM) += usbatm.o |
8 | obj-$(CONFIG_USB_XUSBATM) += xusbatm.o | 8 | obj-$(CONFIG_USB_XUSBATM) += xusbatm.o |
9 | |||
10 | ifeq ($(CONFIG_USB_DEBUG),y) | ||
11 | EXTRA_CFLAGS += -DDEBUG | ||
12 | endif | ||
diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index 936646457935..1adacd60d713 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h | |||
@@ -27,14 +27,9 @@ | |||
27 | #include <linux/config.h> | 27 | #include <linux/config.h> |
28 | 28 | ||
29 | /* | 29 | /* |
30 | #define DEBUG | ||
31 | #define VERBOSE_DEBUG | 30 | #define VERBOSE_DEBUG |
32 | */ | 31 | */ |
33 | 32 | ||
34 | #if !defined (DEBUG) && defined (CONFIG_USB_DEBUG) | ||
35 | # define DEBUG | ||
36 | #endif | ||
37 | |||
38 | #include <asm/semaphore.h> | 33 | #include <asm/semaphore.h> |
39 | #include <linux/atm.h> | 34 | #include <linux/atm.h> |
40 | #include <linux/atmdev.h> | 35 | #include <linux/atmdev.h> |
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index dd1c4d2a0c31..86d5c380892d 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile | |||
@@ -14,3 +14,7 @@ ifeq ($(CONFIG_USB_DEVICEFS),y) | |||
14 | endif | 14 | endif |
15 | 15 | ||
16 | obj-$(CONFIG_USB) += usbcore.o | 16 | obj-$(CONFIG_USB) += usbcore.o |
17 | |||
18 | ifeq ($(CONFIG_USB_DEBUG),y) | ||
19 | EXTRA_CFLAGS += -DDEBUG | ||
20 | endif | ||
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 57e800ac3cee..419c9943a7cb 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -15,14 +15,6 @@ | |||
15 | #include <asm/scatterlist.h> | 15 | #include <asm/scatterlist.h> |
16 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
17 | #include <linux/dmapool.h> | 17 | #include <linux/dmapool.h> |
18 | |||
19 | |||
20 | #ifdef CONFIG_USB_DEBUG | ||
21 | #define DEBUG | ||
22 | #else | ||
23 | #undef DEBUG | ||
24 | #endif | ||
25 | |||
26 | #include <linux/usb.h> | 18 | #include <linux/usb.h> |
27 | #include "hcd.h" | 19 | #include "hcd.h" |
28 | 20 | ||
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 993019500cc3..a9d89c78cc20 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -1,9 +1,4 @@ | |||
1 | #include <linux/config.h> | 1 | #include <linux/config.h> |
2 | |||
3 | #ifdef CONFIG_USB_DEBUG | ||
4 | #define DEBUG | ||
5 | #endif | ||
6 | |||
7 | #include <linux/usb.h> | 2 | #include <linux/usb.h> |
8 | #include <linux/module.h> | 3 | #include <linux/module.h> |
9 | #include <linux/init.h> | 4 | #include <linux/init.h> |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 942cd437dc48..b1d6e9af732d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -1392,13 +1392,13 @@ static int proc_ioctl_default(struct dev_state *ps, void __user *arg) | |||
1392 | } | 1392 | } |
1393 | 1393 | ||
1394 | #ifdef CONFIG_COMPAT | 1394 | #ifdef CONFIG_COMPAT |
1395 | static int proc_ioctl_compat(struct dev_state *ps, void __user *arg) | 1395 | static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg) |
1396 | { | 1396 | { |
1397 | struct usbdevfs_ioctl32 __user *uioc; | 1397 | struct usbdevfs_ioctl32 __user *uioc; |
1398 | struct usbdevfs_ioctl ctrl; | 1398 | struct usbdevfs_ioctl ctrl; |
1399 | u32 udata; | 1399 | u32 udata; |
1400 | 1400 | ||
1401 | uioc = compat_ptr(arg); | 1401 | uioc = compat_ptr((long)arg); |
1402 | if (get_user(ctrl.ifno, &uioc->ifno) || | 1402 | if (get_user(ctrl.ifno, &uioc->ifno) || |
1403 | get_user(ctrl.ioctl_code, &uioc->ioctl_code) || | 1403 | get_user(ctrl.ioctl_code, &uioc->ioctl_code) || |
1404 | __get_user(udata, &uioc->data)) | 1404 | __get_user(udata, &uioc->data)) |
@@ -1511,7 +1511,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
1511 | 1511 | ||
1512 | case USBDEVFS_IOCTL32: | 1512 | case USBDEVFS_IOCTL32: |
1513 | snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); | 1513 | snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); |
1514 | ret = proc_ioctl_compat(ps, p); | 1514 | ret = proc_ioctl_compat(ps, (compat_uptr_t)(long)p); |
1515 | break; | 1515 | break; |
1516 | #endif | 1516 | #endif |
1517 | 1517 | ||
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index e695308095ae..37b13368c814 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -19,12 +19,6 @@ | |||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | |||
23 | #ifdef CONFIG_USB_DEBUG | ||
24 | #define DEBUG | ||
25 | #else | ||
26 | #undef DEBUG | ||
27 | #endif | ||
28 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
29 | 23 | ||
30 | #include "usb.h" | 24 | #include "usb.h" |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 84d9e69329bb..7feb829362d6 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -17,13 +17,6 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/config.h> | 19 | #include <linux/config.h> |
20 | |||
21 | #ifdef CONFIG_USB_DEBUG | ||
22 | #define DEBUG | ||
23 | #else | ||
24 | #undef DEBUG | ||
25 | #endif | ||
26 | |||
27 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 21 | #include <linux/module.h> |
29 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 6c7ca5b08cd6..5e5f65a475ab 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -23,11 +23,6 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
26 | |||
27 | #ifdef CONFIG_USB_DEBUG | ||
28 | #define DEBUG | ||
29 | #endif | ||
30 | |||
31 | #include <linux/module.h> | 26 | #include <linux/module.h> |
32 | #include <linux/version.h> | 27 | #include <linux/version.h> |
33 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 256d9f698715..840727948d84 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -9,11 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
12 | #ifdef CONFIG_USB_DEBUG | ||
13 | #define DEBUG | ||
14 | #else | ||
15 | #undef DEBUG | ||
16 | #endif | ||
17 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
18 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
19 | #include <linux/module.h> | 14 | #include <linux/module.h> |
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 12f490fdee8f..c44bbedec817 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -46,7 +46,6 @@ | |||
46 | 46 | ||
47 | static struct super_operations usbfs_ops; | 47 | static struct super_operations usbfs_ops; |
48 | static struct file_operations default_file_operations; | 48 | static struct file_operations default_file_operations; |
49 | static struct inode_operations usbfs_dir_inode_operations; | ||
50 | static struct vfsmount *usbfs_mount; | 49 | static struct vfsmount *usbfs_mount; |
51 | static int usbfs_mount_count; /* = 0 */ | 50 | static int usbfs_mount_count; /* = 0 */ |
52 | static int ignore_mount = 0; | 51 | static int ignore_mount = 0; |
@@ -262,7 +261,7 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t de | |||
262 | inode->i_fop = &default_file_operations; | 261 | inode->i_fop = &default_file_operations; |
263 | break; | 262 | break; |
264 | case S_IFDIR: | 263 | case S_IFDIR: |
265 | inode->i_op = &usbfs_dir_inode_operations; | 264 | inode->i_op = &simple_dir_inode_operations; |
266 | inode->i_fop = &simple_dir_operations; | 265 | inode->i_fop = &simple_dir_operations; |
267 | 266 | ||
268 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ | 267 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ |
@@ -417,10 +416,6 @@ static struct file_operations default_file_operations = { | |||
417 | .llseek = default_file_lseek, | 416 | .llseek = default_file_lseek, |
418 | }; | 417 | }; |
419 | 418 | ||
420 | static struct inode_operations usbfs_dir_inode_operations = { | ||
421 | .lookup = simple_lookup, | ||
422 | }; | ||
423 | |||
424 | static struct super_operations usbfs_ops = { | 419 | static struct super_operations usbfs_ops = { |
425 | .statfs = simple_statfs, | 420 | .statfs = simple_statfs, |
426 | .drop_inode = generic_delete_inode, | 421 | .drop_inode = generic_delete_inode, |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 644a3d4f12aa..fe74f99ca5f4 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -3,13 +3,6 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/config.h> | 5 | #include <linux/config.h> |
6 | |||
7 | #ifdef CONFIG_USB_DEBUG | ||
8 | #define DEBUG | ||
9 | #else | ||
10 | #undef DEBUG | ||
11 | #endif | ||
12 | |||
13 | #include <linux/pci.h> /* for scatterlist macros */ | 6 | #include <linux/pci.h> /* for scatterlist macros */ |
14 | #include <linux/usb.h> | 7 | #include <linux/usb.h> |
15 | #include <linux/module.h> | 8 | #include <linux/module.h> |
@@ -1457,12 +1450,11 @@ free_interfaces: | |||
1457 | */ | 1450 | */ |
1458 | for (i = 0; i < nintf; ++i) { | 1451 | for (i = 0; i < nintf; ++i) { |
1459 | struct usb_interface *intf = cp->interface[i]; | 1452 | struct usb_interface *intf = cp->interface[i]; |
1460 | struct usb_host_interface *alt = intf->cur_altsetting; | ||
1461 | 1453 | ||
1462 | dev_dbg (&dev->dev, | 1454 | dev_dbg (&dev->dev, |
1463 | "adding %s (config #%d, interface %d)\n", | 1455 | "adding %s (config #%d, interface %d)\n", |
1464 | intf->dev.bus_id, configuration, | 1456 | intf->dev.bus_id, configuration, |
1465 | alt->desc.bInterfaceNumber); | 1457 | intf->cur_altsetting->desc.bInterfaceNumber); |
1466 | ret = device_add (&intf->dev); | 1458 | ret = device_add (&intf->dev); |
1467 | if (ret != 0) { | 1459 | if (ret != 0) { |
1468 | dev_err(&dev->dev, | 1460 | dev_err(&dev->dev, |
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c index 37da059eced7..fbbebab52fbd 100644 --- a/drivers/usb/core/notify.c +++ b/drivers/usb/core/notify.c | |||
@@ -12,13 +12,7 @@ | |||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/notifier.h> | 14 | #include <linux/notifier.h> |
15 | #ifdef CONFIG_USB_DEBUG | ||
16 | #define DEBUG | ||
17 | #else | ||
18 | #undef DEBUG | ||
19 | #endif | ||
20 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
21 | |||
22 | #include "usb.h" | 16 | #include "usb.h" |
23 | 17 | ||
24 | 18 | ||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index edd83e014452..71d881327e88 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -12,14 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | |||
16 | #ifdef CONFIG_USB_DEBUG | ||
17 | #define DEBUG | ||
18 | #else | ||
19 | #undef DEBUG | ||
20 | #endif | ||
21 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
22 | |||
23 | #include "usb.h" | 16 | #include "usb.h" |
24 | 17 | ||
25 | /* endpoint stuff */ | 18 | /* endpoint stuff */ |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index f2a1fed2a802..081796726b95 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -4,12 +4,6 @@ | |||
4 | #include <linux/bitops.h> | 4 | #include <linux/bitops.h> |
5 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | |||
8 | #ifdef CONFIG_USB_DEBUG | ||
9 | #define DEBUG | ||
10 | #else | ||
11 | #undef DEBUG | ||
12 | #endif | ||
13 | #include <linux/usb.h> | 7 | #include <linux/usb.h> |
14 | #include "hcd.h" | 8 | #include "hcd.h" |
15 | 9 | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 0eefff7bcb3c..e197ce9353de 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -22,13 +22,6 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/config.h> | 24 | #include <linux/config.h> |
25 | |||
26 | #ifdef CONFIG_USB_DEBUG | ||
27 | #define DEBUG | ||
28 | #else | ||
29 | #undef DEBUG | ||
30 | #endif | ||
31 | |||
32 | #include <linux/module.h> | 25 | #include <linux/module.h> |
33 | #include <linux/string.h> | 26 | #include <linux/string.h> |
34 | #include <linux/bitops.h> | 27 | #include <linux/bitops.h> |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 1e407745c115..c655d46c8aed 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -944,7 +944,7 @@ static int dummy_udc_suspend (struct platform_device *dev, pm_message_t state) | |||
944 | set_link_state (dum); | 944 | set_link_state (dum); |
945 | spin_unlock_irq (&dum->lock); | 945 | spin_unlock_irq (&dum->lock); |
946 | 946 | ||
947 | dev->power.power_state = state; | 947 | dev->dev.power.power_state = state; |
948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
949 | return 0; | 949 | return 0; |
950 | } | 950 | } |
@@ -1904,7 +1904,7 @@ static int dummy_hcd_probe (struct platform_device *dev) | |||
1904 | struct usb_hcd *hcd; | 1904 | struct usb_hcd *hcd; |
1905 | int retval; | 1905 | int retval; |
1906 | 1906 | ||
1907 | dev_info (dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); | 1907 | dev_info(&dev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); |
1908 | 1908 | ||
1909 | hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id); | 1909 | hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id); |
1910 | if (!hcd) | 1910 | if (!hcd) |
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 081ec3f5cff4..3959ccc88332 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -219,7 +219,7 @@ static int ohci_hcd_lh7a404_drv_probe(struct platform_device *pdev) | |||
219 | 219 | ||
220 | static int ohci_hcd_lh7a404_drv_remove(struct platform_device *pdev) | 220 | static int ohci_hcd_lh7a404_drv_remove(struct platform_device *pdev) |
221 | { | 221 | { |
222 | struct usb_hcd *hcd = platform_get_drvdata(dev); | 222 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
223 | 223 | ||
224 | usb_hcd_lh7a404_remove(hcd, pdev); | 224 | usb_hcd_lh7a404_remove(hcd, pdev); |
225 | return 0; | 225 | return 0; |
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 18755766e406..2ec6a78bd65e 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -185,7 +185,7 @@ static int ohci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) | |||
185 | 185 | ||
186 | static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev) | 186 | static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev) |
187 | { | 187 | { |
188 | struct usb_hcd *hcd = platform_get_drvdata(dev); | 188 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
189 | 189 | ||
190 | usb_hcd_ppc_soc_remove(hcd, pdev); | 190 | usb_hcd_ppc_soc_remove(hcd, pdev); |
191 | return 0; | 191 | return 0; |
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 61a2604cce4f..950543aa5ac7 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -327,6 +327,18 @@ static inline void mts_urb_abort(struct mts_desc* desc) { | |||
327 | usb_kill_urb( desc->urb ); | 327 | usb_kill_urb( desc->urb ); |
328 | } | 328 | } |
329 | 329 | ||
330 | static int mts_slave_alloc (struct scsi_device *s) | ||
331 | { | ||
332 | s->inquiry_len = 0x24; | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int mts_slave_configure (struct scsi_device *s) | ||
337 | { | ||
338 | blk_queue_dma_alignment(s->request_queue, (512 - 1)); | ||
339 | return 0; | ||
340 | } | ||
341 | |||
330 | static int mts_scsi_abort (Scsi_Cmnd *srb) | 342 | static int mts_scsi_abort (Scsi_Cmnd *srb) |
331 | { | 343 | { |
332 | struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); | 344 | struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); |
@@ -411,7 +423,7 @@ static void mts_transfer_done( struct urb *transfer, struct pt_regs *regs ) | |||
411 | MTS_INT_INIT(); | 423 | MTS_INT_INIT(); |
412 | 424 | ||
413 | context->srb->result &= MTS_SCSI_ERR_MASK; | 425 | context->srb->result &= MTS_SCSI_ERR_MASK; |
414 | context->srb->result |= (unsigned)context->status<<1; | 426 | context->srb->result |= (unsigned)(*context->scsi_status)<<1; |
415 | 427 | ||
416 | mts_transfer_cleanup(transfer); | 428 | mts_transfer_cleanup(transfer); |
417 | 429 | ||
@@ -427,7 +439,7 @@ static void mts_get_status( struct urb *transfer ) | |||
427 | mts_int_submit_urb(transfer, | 439 | mts_int_submit_urb(transfer, |
428 | usb_rcvbulkpipe(context->instance->usb_dev, | 440 | usb_rcvbulkpipe(context->instance->usb_dev, |
429 | context->instance->ep_response), | 441 | context->instance->ep_response), |
430 | &context->status, | 442 | context->scsi_status, |
431 | 1, | 443 | 1, |
432 | mts_transfer_done ); | 444 | mts_transfer_done ); |
433 | } | 445 | } |
@@ -481,7 +493,7 @@ static void mts_command_done( struct urb *transfer, struct pt_regs *regs ) | |||
481 | context->data_pipe, | 493 | context->data_pipe, |
482 | context->data, | 494 | context->data, |
483 | context->data_length, | 495 | context->data_length, |
484 | context->srb->use_sg ? mts_do_sg : mts_data_done); | 496 | context->srb->use_sg > 1 ? mts_do_sg : mts_data_done); |
485 | } else { | 497 | } else { |
486 | mts_get_status(transfer); | 498 | mts_get_status(transfer); |
487 | } | 499 | } |
@@ -627,7 +639,6 @@ int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ) | |||
627 | callback(srb); | 639 | callback(srb); |
628 | 640 | ||
629 | } | 641 | } |
630 | |||
631 | out: | 642 | out: |
632 | return err; | 643 | return err; |
633 | } | 644 | } |
@@ -645,6 +656,9 @@ static struct scsi_host_template mts_scsi_host_template = { | |||
645 | .cmd_per_lun = 1, | 656 | .cmd_per_lun = 1, |
646 | .use_clustering = 1, | 657 | .use_clustering = 1, |
647 | .emulated = 1, | 658 | .emulated = 1, |
659 | .slave_alloc = mts_slave_alloc, | ||
660 | .slave_configure = mts_slave_configure, | ||
661 | .max_sectors= 256, /* 128 K */ | ||
648 | }; | 662 | }; |
649 | 663 | ||
650 | struct vendor_product | 664 | struct vendor_product |
@@ -771,8 +785,8 @@ static int mts_usb_probe(struct usb_interface *intf, | |||
771 | MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" ); | 785 | MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" ); |
772 | return -ENODEV; | 786 | return -ENODEV; |
773 | } | 787 | } |
774 | 788 | ||
775 | 789 | ||
776 | new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL); | 790 | new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL); |
777 | if (!new_desc) | 791 | if (!new_desc) |
778 | goto out; | 792 | goto out; |
@@ -781,6 +795,10 @@ static int mts_usb_probe(struct usb_interface *intf, | |||
781 | if (!new_desc->urb) | 795 | if (!new_desc->urb) |
782 | goto out_kfree; | 796 | goto out_kfree; |
783 | 797 | ||
798 | new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL); | ||
799 | if (!new_desc->context.scsi_status) | ||
800 | goto out_kfree2; | ||
801 | |||
784 | new_desc->usb_dev = dev; | 802 | new_desc->usb_dev = dev; |
785 | new_desc->usb_intf = intf; | 803 | new_desc->usb_intf = intf; |
786 | init_MUTEX(&new_desc->lock); | 804 | init_MUTEX(&new_desc->lock); |
@@ -817,6 +835,8 @@ static int mts_usb_probe(struct usb_interface *intf, | |||
817 | usb_set_intfdata(intf, new_desc); | 835 | usb_set_intfdata(intf, new_desc); |
818 | return 0; | 836 | return 0; |
819 | 837 | ||
838 | out_kfree2: | ||
839 | kfree(new_desc->context.scsi_status); | ||
820 | out_free_urb: | 840 | out_free_urb: |
821 | usb_free_urb(new_desc->urb); | 841 | usb_free_urb(new_desc->urb); |
822 | out_kfree: | 842 | out_kfree: |
@@ -836,6 +856,7 @@ static void mts_usb_disconnect (struct usb_interface *intf) | |||
836 | 856 | ||
837 | scsi_host_put(desc->host); | 857 | scsi_host_put(desc->host); |
838 | usb_free_urb(desc->urb); | 858 | usb_free_urb(desc->urb); |
859 | kfree(desc->context.scsi_status); | ||
839 | kfree(desc); | 860 | kfree(desc); |
840 | } | 861 | } |
841 | 862 | ||
@@ -856,5 +877,3 @@ module_exit(microtek_drv_exit); | |||
856 | MODULE_AUTHOR( DRIVER_AUTHOR ); | 877 | MODULE_AUTHOR( DRIVER_AUTHOR ); |
857 | MODULE_DESCRIPTION( DRIVER_DESC ); | 878 | MODULE_DESCRIPTION( DRIVER_DESC ); |
858 | MODULE_LICENSE("GPL"); | 879 | MODULE_LICENSE("GPL"); |
859 | |||
860 | |||
diff --git a/drivers/usb/image/microtek.h b/drivers/usb/image/microtek.h index 3271deb8c001..926d4bdc6746 100644 --- a/drivers/usb/image/microtek.h +++ b/drivers/usb/image/microtek.h | |||
@@ -22,7 +22,7 @@ struct mts_transfer_context | |||
22 | int data_pipe; | 22 | int data_pipe; |
23 | int fragment; | 23 | int fragment; |
24 | 24 | ||
25 | u8 status; /* status returned from ep_response after command completion */ | 25 | u8 *scsi_status; /* status returned from ep_response after command completion */ |
26 | }; | 26 | }; |
27 | 27 | ||
28 | 28 | ||
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 5e03b93f29f6..07cb17db42fc 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
@@ -42,3 +42,7 @@ obj-$(CONFIG_USB_ACECAD) += acecad.o | |||
42 | obj-$(CONFIG_USB_YEALINK) += yealink.o | 42 | obj-$(CONFIG_USB_YEALINK) += yealink.o |
43 | obj-$(CONFIG_USB_XPAD) += xpad.o | 43 | obj-$(CONFIG_USB_XPAD) += xpad.o |
44 | obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o | 44 | obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o |
45 | |||
46 | ifeq ($(CONFIG_USB_DEBUG),y) | ||
47 | EXTRA_CFLAGS += -DDEBUG | ||
48 | endif | ||
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 79ddce4555ab..45f3130fadea 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1318,6 +1318,7 @@ void hid_init_reports(struct hid_device *hid) | |||
1318 | #define USB_DEVICE_ID_WACOM_PTU 0x0003 | 1318 | #define USB_DEVICE_ID_WACOM_PTU 0x0003 |
1319 | #define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0 | 1319 | #define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0 |
1320 | #define USB_DEVICE_ID_WACOM_CINTIQ 0x003F | 1320 | #define USB_DEVICE_ID_WACOM_CINTIQ 0x003F |
1321 | #define USB_DEVICE_ID_WACOM_DTF 0x00C0 | ||
1321 | 1322 | ||
1322 | #define USB_VENDOR_ID_ACECAD 0x0460 | 1323 | #define USB_VENDOR_ID_ACECAD 0x0460 |
1323 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 | 1324 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 |
@@ -1524,6 +1525,9 @@ static struct hid_blacklist { | |||
1524 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE }, | 1525 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE }, |
1525 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE }, | 1526 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE }, |
1526 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE }, | 1527 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE }, |
1528 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 7, HID_QUIRK_IGNORE }, | ||
1529 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 8, HID_QUIRK_IGNORE }, | ||
1530 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 9, HID_QUIRK_IGNORE }, | ||
1527 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE }, | 1531 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE }, |
1528 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE }, | 1532 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE }, |
1529 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE }, | 1533 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE }, |
@@ -1531,11 +1535,19 @@ static struct hid_blacklist { | |||
1531 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE }, | 1535 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE }, |
1532 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, | 1536 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, |
1533 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, | 1537 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, |
1538 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 1, HID_QUIRK_IGNORE }, | ||
1539 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 2, HID_QUIRK_IGNORE }, | ||
1540 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 3, HID_QUIRK_IGNORE }, | ||
1541 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 4, HID_QUIRK_IGNORE }, | ||
1542 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 5, HID_QUIRK_IGNORE }, | ||
1543 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 6, HID_QUIRK_IGNORE }, | ||
1534 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, | 1544 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, |
1535 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, | 1545 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, |
1536 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, | 1546 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, |
1537 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, | 1547 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, |
1548 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 5, HID_QUIRK_IGNORE }, | ||
1538 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, | 1549 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, |
1550 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF, HID_QUIRK_IGNORE }, | ||
1539 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1551 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1540 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1552 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1541 | 1553 | ||
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c index 3b581853cf10..4a50acb39d29 100644 --- a/drivers/usb/input/itmtouch.c +++ b/drivers/usb/input/itmtouch.c | |||
@@ -40,13 +40,6 @@ | |||
40 | *****************************************************************************/ | 40 | *****************************************************************************/ |
41 | 41 | ||
42 | #include <linux/config.h> | 42 | #include <linux/config.h> |
43 | |||
44 | #ifdef CONFIG_USB_DEBUG | ||
45 | #define DEBUG | ||
46 | #else | ||
47 | #undef DEBUG | ||
48 | #endif | ||
49 | |||
50 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
51 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
52 | #include <linux/input.h> | 45 | #include <linux/input.h> |
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index 5b8d65f62abf..a32cfe51b77d 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c | |||
@@ -160,7 +160,8 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) | |||
160 | * though so it's not too big a deal | 160 | * though so it's not too big a deal |
161 | */ | 161 | */ |
162 | if (dev->data.pos >= dev->data.len) { | 162 | if (dev->data.pos >= dev->data.len) { |
163 | dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n", | 163 | dev_dbg(&dev->udev->dev, |
164 | "%s - Error ran out of data. pos: %d, len: %d\n", | ||
164 | __FUNCTION__, dev->data.pos, dev->data.len); | 165 | __FUNCTION__, dev->data.pos, dev->data.len); |
165 | return -1; | 166 | return -1; |
166 | } | 167 | } |
@@ -306,7 +307,7 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs) | |||
306 | err("Bad message recieved, no stop bit found.\n"); | 307 | err("Bad message recieved, no stop bit found.\n"); |
307 | } | 308 | } |
308 | 309 | ||
309 | dev_dbg(&remote->udev, | 310 | dev_dbg(&remote->udev->dev, |
310 | "%s found valid message: system: %d, button: %d, toggle: %d\n", | 311 | "%s found valid message: system: %d, button: %d, toggle: %d\n", |
311 | __FUNCTION__, message.system, message.button, message.toggle); | 312 | __FUNCTION__, message.system, message.button, message.toggle); |
312 | 313 | ||
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c index 7fce526560ca..52cc18cd247d 100644 --- a/drivers/usb/input/mtouchusb.c +++ b/drivers/usb/input/mtouchusb.c | |||
@@ -40,13 +40,6 @@ | |||
40 | *****************************************************************************/ | 40 | *****************************************************************************/ |
41 | 41 | ||
42 | #include <linux/config.h> | 42 | #include <linux/config.h> |
43 | |||
44 | #ifdef CONFIG_USB_DEBUG | ||
45 | #define DEBUG | ||
46 | #else | ||
47 | #undef DEBUG | ||
48 | #endif | ||
49 | |||
50 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
51 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
52 | #include <linux/input.h> | 45 | #include <linux/input.h> |
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c index dca5ee93a4ef..19e015d171aa 100644 --- a/drivers/usb/input/pid.c +++ b/drivers/usb/input/pid.c | |||
@@ -37,8 +37,6 @@ | |||
37 | #include "hid.h" | 37 | #include "hid.h" |
38 | #include "pid.h" | 38 | #include "pid.h" |
39 | 39 | ||
40 | #define DEBUG | ||
41 | |||
42 | #define CHECK_OWNERSHIP(i, hid_pid) \ | 40 | #define CHECK_OWNERSHIP(i, hid_pid) \ |
43 | ((i) < FF_EFFECTS_MAX && i >= 0 && \ | 41 | ((i) < FF_EFFECTS_MAX && i >= 0 && \ |
44 | test_bit(FF_PID_FLAGS_USED, &hid_pid->effects[(i)].flags) && \ | 42 | test_bit(FF_PID_FLAGS_USED, &hid_pid->effects[(i)].flags) && \ |
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 0043e6ebcd1f..7420c6b84284 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c | |||
@@ -30,10 +30,6 @@ | |||
30 | #include <linux/input.h> | 30 | #include <linux/input.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | |||
34 | #if !defined(DEBUG) && defined(CONFIG_USB_DEBUG) | ||
35 | #define DEBUG | ||
36 | #endif | ||
37 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
38 | #include <linux/usb_input.h> | 34 | #include <linux/usb_input.h> |
39 | 35 | ||
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index ea0f75773ae1..aea1cfae34cc 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c | |||
@@ -52,8 +52,10 @@ | |||
52 | * v1.30.1 (pi) - Added Graphire3 support | 52 | * v1.30.1 (pi) - Added Graphire3 support |
53 | * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... | 53 | * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... |
54 | * v1.43 (pc) - Added support for Cintiq 21UX | 54 | * v1.43 (pc) - Added support for Cintiq 21UX |
55 | - Fixed a Graphire bug | 55 | * - Fixed a Graphire bug |
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. | ||
58 | * - Report Device IDs | ||
57 | */ | 59 | */ |
58 | 60 | ||
59 | /* | 61 | /* |
@@ -76,7 +78,7 @@ | |||
76 | /* | 78 | /* |
77 | * Version Information | 79 | * Version Information |
78 | */ | 80 | */ |
79 | #define DRIVER_VERSION "v1.43" | 81 | #define DRIVER_VERSION "v1.44" |
80 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" | 82 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" |
81 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" | 83 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" |
82 | #define DRIVER_LICENSE "GPL" | 84 | #define DRIVER_LICENSE "GPL" |
@@ -86,10 +88,14 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
86 | MODULE_LICENSE(DRIVER_LICENSE); | 88 | MODULE_LICENSE(DRIVER_LICENSE); |
87 | 89 | ||
88 | #define USB_VENDOR_ID_WACOM 0x056a | 90 | #define USB_VENDOR_ID_WACOM 0x056a |
91 | #define STYLUS_DEVICE_ID 0x02 | ||
92 | #define CURSOR_DEVICE_ID 0x06 | ||
93 | #define ERASER_DEVICE_ID 0x0A | ||
89 | 94 | ||
90 | enum { | 95 | enum { |
91 | PENPARTNER = 0, | 96 | PENPARTNER = 0, |
92 | GRAPHIRE, | 97 | GRAPHIRE, |
98 | G4, | ||
93 | PL, | 99 | PL, |
94 | INTUOS, | 100 | INTUOS, |
95 | INTUOS3, | 101 | INTUOS3, |
@@ -116,6 +122,7 @@ struct wacom { | |||
116 | struct urb *irq; | 122 | struct urb *irq; |
117 | struct wacom_features *features; | 123 | struct wacom_features *features; |
118 | int tool[2]; | 124 | int tool[2]; |
125 | int id[2]; | ||
119 | __u32 serial[2]; | 126 | __u32 serial[2]; |
120 | char phys[32]; | 127 | char phys[32]; |
121 | }; | 128 | }; |
@@ -136,7 +143,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) | |||
136 | struct wacom *wacom = urb->context; | 143 | struct wacom *wacom = urb->context; |
137 | unsigned char *data = wacom->data; | 144 | unsigned char *data = wacom->data; |
138 | struct input_dev *dev = wacom->dev; | 145 | struct input_dev *dev = wacom->dev; |
139 | int prox, pressure; | 146 | int prox, pressure, id; |
140 | int retval; | 147 | int retval; |
141 | 148 | ||
142 | switch (urb->status) { | 149 | switch (urb->status) { |
@@ -163,6 +170,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) | |||
163 | 170 | ||
164 | input_regs(dev, regs); | 171 | input_regs(dev, regs); |
165 | 172 | ||
173 | id = ERASER_DEVICE_ID; | ||
166 | if (prox) { | 174 | if (prox) { |
167 | 175 | ||
168 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); | 176 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); |
@@ -177,11 +185,15 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) | |||
177 | * an out of proximity for previous tool then a in for new tool. | 185 | * an out of proximity for previous tool then a in for new tool. |
178 | */ | 186 | */ |
179 | if (!wacom->tool[0]) { | 187 | if (!wacom->tool[0]) { |
180 | /* Going into proximity select tool */ | 188 | /* Eraser bit set for DTF */ |
181 | wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 189 | if (data[1] & 0x10) |
190 | wacom->tool[1] = BTN_TOOL_RUBBER; | ||
191 | else | ||
192 | /* Going into proximity select tool */ | ||
193 | wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
182 | } else { | 194 | } else { |
183 | /* was entered with stylus2 pressed */ | 195 | /* was entered with stylus2 pressed */ |
184 | if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) { | 196 | if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { |
185 | /* report out proximity for previous tool */ | 197 | /* report out proximity for previous tool */ |
186 | input_report_key(dev, wacom->tool[1], 0); | 198 | input_report_key(dev, wacom->tool[1], 0); |
187 | input_sync(dev); | 199 | input_sync(dev); |
@@ -192,8 +204,9 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) | |||
192 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | 204 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { |
193 | /* Unknown tool selected default to pen tool */ | 205 | /* Unknown tool selected default to pen tool */ |
194 | wacom->tool[1] = BTN_TOOL_PEN; | 206 | wacom->tool[1] = BTN_TOOL_PEN; |
207 | id = STYLUS_DEVICE_ID; | ||
195 | } | 208 | } |
196 | input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ | 209 | input_report_key(dev, wacom->tool[1], id); /* report in proximity for tool */ |
197 | input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); | 210 | input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); |
198 | input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); | 211 | input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); |
199 | input_report_abs(dev, ABS_PRESSURE, pressure); | 212 | input_report_abs(dev, ABS_PRESSURE, pressure); |
@@ -250,10 +263,10 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) | |||
250 | 263 | ||
251 | input_regs(dev, regs); | 264 | input_regs(dev, regs); |
252 | if (data[1] & 0x04) { | 265 | if (data[1] & 0x04) { |
253 | input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); | 266 | input_report_key(dev, BTN_TOOL_RUBBER, (data[1] & 0x20) ? ERASER_DEVICE_ID : 0); |
254 | input_report_key(dev, BTN_TOUCH, data[1] & 0x08); | 267 | input_report_key(dev, BTN_TOUCH, data[1] & 0x08); |
255 | } else { | 268 | } else { |
256 | input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); | 269 | input_report_key(dev, BTN_TOOL_PEN, (data[1] & 0x20) ? STYLUS_DEVICE_ID : 0); |
257 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); | 270 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); |
258 | } | 271 | } |
259 | input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2])); | 272 | input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2])); |
@@ -299,7 +312,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) | |||
299 | } | 312 | } |
300 | 313 | ||
301 | input_regs(dev, regs); | 314 | input_regs(dev, regs); |
302 | input_report_key(dev, BTN_TOOL_PEN, 1); | 315 | input_report_key(dev, BTN_TOOL_PEN, STYLUS_DEVICE_ID); |
303 | input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); | 316 | input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); |
304 | input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); | 317 | input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); |
305 | input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); | 318 | input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); |
@@ -319,7 +332,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
319 | struct wacom *wacom = urb->context; | 332 | struct wacom *wacom = urb->context; |
320 | unsigned char *data = wacom->data; | 333 | unsigned char *data = wacom->data; |
321 | struct input_dev *dev = wacom->dev; | 334 | struct input_dev *dev = wacom->dev; |
322 | int x, y; | 335 | int x, y, id, rw; |
323 | int retval; | 336 | int retval; |
324 | 337 | ||
325 | switch (urb->status) { | 338 | switch (urb->status) { |
@@ -344,6 +357,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
344 | 357 | ||
345 | input_regs(dev, regs); | 358 | input_regs(dev, regs); |
346 | 359 | ||
360 | id = STYLUS_DEVICE_ID; | ||
347 | if (data[1] & 0x10) { /* in prox */ | 361 | if (data[1] & 0x10) { /* in prox */ |
348 | 362 | ||
349 | switch ((data[1] >> 5) & 3) { | 363 | switch ((data[1] >> 5) & 3) { |
@@ -354,18 +368,27 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
354 | 368 | ||
355 | case 1: /* Rubber */ | 369 | case 1: /* Rubber */ |
356 | wacom->tool[0] = BTN_TOOL_RUBBER; | 370 | wacom->tool[0] = BTN_TOOL_RUBBER; |
371 | id = ERASER_DEVICE_ID; | ||
357 | break; | 372 | break; |
358 | 373 | ||
359 | case 2: /* Mouse with wheel */ | 374 | case 2: /* Mouse with wheel */ |
360 | input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); | 375 | input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); |
361 | input_report_rel(dev, REL_WHEEL, (signed char) data[6]); | 376 | if (wacom->features->type == G4) { |
377 | rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03); | ||
378 | input_report_rel(dev, REL_WHEEL, rw); | ||
379 | } else | ||
380 | input_report_rel(dev, REL_WHEEL, (signed char) data[6]); | ||
362 | /* fall through */ | 381 | /* fall through */ |
363 | 382 | ||
364 | case 3: /* Mouse without wheel */ | 383 | case 3: /* Mouse without wheel */ |
365 | wacom->tool[0] = BTN_TOOL_MOUSE; | 384 | wacom->tool[0] = BTN_TOOL_MOUSE; |
385 | id = CURSOR_DEVICE_ID; | ||
366 | input_report_key(dev, BTN_LEFT, data[1] & 0x01); | 386 | input_report_key(dev, BTN_LEFT, data[1] & 0x01); |
367 | input_report_key(dev, BTN_RIGHT, data[1] & 0x02); | 387 | input_report_key(dev, BTN_RIGHT, data[1] & 0x02); |
368 | input_report_abs(dev, ABS_DISTANCE, data[7]); | 388 | if (wacom->features->type == G4) |
389 | input_report_abs(dev, ABS_DISTANCE, data[6]); | ||
390 | else | ||
391 | input_report_abs(dev, ABS_DISTANCE, data[7]); | ||
369 | break; | 392 | break; |
370 | } | 393 | } |
371 | } | 394 | } |
@@ -376,16 +399,50 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
376 | input_report_abs(dev, ABS_X, x); | 399 | input_report_abs(dev, ABS_X, x); |
377 | input_report_abs(dev, ABS_Y, y); | 400 | input_report_abs(dev, ABS_Y, y); |
378 | if (wacom->tool[0] != BTN_TOOL_MOUSE) { | 401 | if (wacom->tool[0] != BTN_TOOL_MOUSE) { |
379 | input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); | 402 | input_report_abs(dev, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); |
380 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); | 403 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); |
381 | input_report_key(dev, BTN_STYLUS, data[1] & 0x02); | 404 | input_report_key(dev, BTN_STYLUS, data[1] & 0x02); |
382 | input_report_key(dev, BTN_STYLUS2, data[1] & 0x04); | 405 | input_report_key(dev, BTN_STYLUS2, data[1] & 0x04); |
383 | } | 406 | } |
384 | } | 407 | } |
385 | 408 | ||
386 | input_report_key(dev, wacom->tool[0], data[1] & 0x10); | 409 | input_report_key(dev, wacom->tool[0], (data[1] & 0x10) ? id : 0); |
387 | input_sync(dev); | 410 | input_sync(dev); |
388 | 411 | ||
412 | /* send pad data */ | ||
413 | if (wacom->features->type == G4) { | ||
414 | /* fist time sending pad data */ | ||
415 | if (wacom->tool[1] != BTN_TOOL_FINGER) { | ||
416 | wacom->id[1] = 0; | ||
417 | wacom->serial[1] = (data[7] & 0x38) >> 2; | ||
418 | } | ||
419 | if (data[7] & 0xf8) { | ||
420 | input_report_key(dev, BTN_0, (data[7] & 0x40)); | ||
421 | input_report_key(dev, BTN_4, (data[7] & 0x80)); | ||
422 | if (((data[7] & 0x38) >> 2) == (wacom->serial[1] & 0x0e)) | ||
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); | ||
434 | wacom->tool[1] = BTN_TOOL_FINGER; | ||
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); | ||
438 | } else if (wacom->id[1]) { | ||
439 | wacom->id[1] = 0; | ||
440 | wacom->serial[1] = 0; | ||
441 | input_report_key(dev, wacom->tool[1], 0); | ||
442 | input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); | ||
443 | } | ||
444 | input_sync(dev); | ||
445 | } | ||
389 | exit: | 446 | exit: |
390 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 447 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
391 | if (retval) | 448 | if (retval) |
@@ -410,7 +467,8 @@ static int wacom_intuos_inout(struct urb *urb) | |||
410 | (data[4] << 20) + (data[5] << 12) + | 467 | (data[4] << 20) + (data[5] << 12) + |
411 | (data[6] << 4) + (data[7] >> 4); | 468 | (data[6] << 4) + (data[7] >> 4); |
412 | 469 | ||
413 | switch ((data[2] << 4) | (data[3] >> 4)) { | 470 | wacom->id[idx] = (data[2] << 4) | (data[3] >> 4); |
471 | switch (wacom->id[idx]) { | ||
414 | case 0x812: /* Inking pen */ | 472 | case 0x812: /* Inking pen */ |
415 | case 0x801: /* Intuos3 Inking pen */ | 473 | case 0x801: /* Intuos3 Inking pen */ |
416 | case 0x012: | 474 | case 0x012: |
@@ -458,7 +516,7 @@ static int wacom_intuos_inout(struct urb *urb) | |||
458 | default: /* Unknown tool */ | 516 | default: /* Unknown tool */ |
459 | wacom->tool[idx] = BTN_TOOL_PEN; | 517 | wacom->tool[idx] = BTN_TOOL_PEN; |
460 | } | 518 | } |
461 | input_report_key(dev, wacom->tool[idx], 1); | 519 | input_report_key(dev, wacom->tool[idx], wacom->id[idx]); |
462 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 520 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); |
463 | input_sync(dev); | 521 | input_sync(dev); |
464 | return 1; | 522 | return 1; |
@@ -637,7 +695,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) | |||
637 | } | 695 | } |
638 | } | 696 | } |
639 | 697 | ||
640 | input_report_key(dev, wacom->tool[idx], 1); | 698 | input_report_key(dev, wacom->tool[idx], wacom->id[idx]); |
641 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 699 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); |
642 | input_sync(dev); | 700 | input_sync(dev); |
643 | 701 | ||
@@ -655,6 +713,13 @@ static struct wacom_features wacom_features[] = { | |||
655 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq }, | 713 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
656 | { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq }, | 714 | { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
657 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq }, | 715 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
716 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, G4, wacom_graphire_irq }, | ||
717 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, G4, wacom_graphire_irq }, | ||
718 | { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, | ||
719 | { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq }, | ||
720 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, | ||
721 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 32, GRAPHIRE, wacom_graphire_irq }, | ||
722 | { "Wacom PenPartner2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq }, | ||
658 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, | 723 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, |
659 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, | 724 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, |
660 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq }, | 725 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq }, |
@@ -666,16 +731,20 @@ static struct wacom_features wacom_features[] = { | |||
666 | { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_pl_irq }, | 731 | { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_pl_irq }, |
667 | { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_pl_irq }, | 732 | { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_pl_irq }, |
668 | { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq }, | 733 | { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq }, |
734 | { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_pl_irq }, | ||
735 | { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq }, | ||
736 | { "Wacom PL710", 8, 34080, 27660, 511, 32, PL, wacom_pl_irq }, | ||
737 | { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_pl_irq }, | ||
738 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq }, | ||
669 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, | 739 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, |
670 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, | 740 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, |
671 | { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq }, | 741 | { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq }, |
672 | { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq }, | 742 | { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq }, |
673 | { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq }, | 743 | { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq }, |
674 | { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, | ||
675 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq }, | ||
676 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq }, | 744 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq }, |
677 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq }, | 745 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq }, |
678 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq }, | 746 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq }, |
747 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_intuos_irq }, | ||
679 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq }, | 748 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq }, |
680 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, | 749 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, |
681 | { } | 750 | { } |
@@ -688,6 +757,13 @@ static struct usb_device_id wacom_ids[] = { | |||
688 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, | 757 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, |
689 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, | 758 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, |
690 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, | 759 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, |
760 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, | ||
761 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, | ||
762 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, | ||
763 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, | ||
764 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, | ||
765 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, | ||
766 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, | ||
691 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, | 767 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, |
692 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, | 768 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, |
693 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, | 769 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, |
@@ -699,16 +775,20 @@ static struct usb_device_id wacom_ids[] = { | |||
699 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, | 775 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, |
700 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, | 776 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, |
701 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, | 777 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, |
778 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, | ||
779 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, | ||
780 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, | ||
781 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, | ||
782 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, | ||
702 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, | 783 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, |
703 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, | 784 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, |
704 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, | 785 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, |
705 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, | 786 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, |
706 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, | 787 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, |
707 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, | ||
708 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, | ||
709 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, | 788 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, |
710 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, | 789 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, |
711 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, | 790 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, |
791 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, | ||
712 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, | 792 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, |
713 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | 793 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, |
714 | { } | 794 | { } |
@@ -779,6 +859,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
779 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); | 859 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); |
780 | 860 | ||
781 | switch (wacom->features->type) { | 861 | switch (wacom->features->type) { |
862 | case G4: | ||
863 | input_dev->evbit[0] |= BIT(EV_MSC); | ||
864 | input_dev->mscbit[0] |= BIT(MSC_SERIAL); | ||
865 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); | ||
866 | 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); | ||
867 | /* fall through */ | ||
868 | |||
782 | case GRAPHIRE: | 869 | case GRAPHIRE: |
783 | input_dev->evbit[0] |= BIT(EV_REL); | 870 | input_dev->evbit[0] |= BIT(EV_REL); |
784 | input_dev->relbit[0] |= BIT(REL_WHEEL); | 871 | input_dev->relbit[0] |= BIT(REL_WHEEL); |
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 862e40a83689..6c693bc68e2e 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
@@ -18,4 +18,8 @@ obj-$(CONFIG_USB_RIO500) += rio500.o | |||
18 | obj-$(CONFIG_USB_TEST) += usbtest.o | 18 | obj-$(CONFIG_USB_TEST) += usbtest.o |
19 | obj-$(CONFIG_USB_USS720) += uss720.o | 19 | obj-$(CONFIG_USB_USS720) += uss720.o |
20 | 20 | ||
21 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ \ No newline at end of file | 21 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ |
22 | |||
23 | ifeq ($(CONFIG_USB_DEBUG),y) | ||
24 | EXTRA_CFLAGS += -DDEBUG | ||
25 | endif | ||
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 5f33f7c64885..2a28ceeaa66a 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/wait.h> | 32 | #include <linux/wait.h> |
33 | #undef DEBUG /* include debug macros until it's done */ | ||
34 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
35 | 34 | ||
36 | /*-------------------------------------------------------------------*/ | 35 | /*-------------------------------------------------------------------*/ |
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index b84eda631ab5..a30d4a6ee824 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c | |||
@@ -26,9 +26,6 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/config.h> | 28 | #include <linux/config.h> |
29 | #ifdef CONFIG_USB_DEBUG | ||
30 | #define DEBUG 1 | ||
31 | #endif | ||
32 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
33 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
34 | #include <linux/init.h> | 31 | #include <linux/init.h> |
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 7d02d8ec6b1a..9590dbac5d9a 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -393,7 +393,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
393 | ibuf, this_read, &partial, | 393 | ibuf, this_read, &partial, |
394 | 8000); | 394 | 8000); |
395 | 395 | ||
396 | dbg(KERN_DEBUG "read stats: result:%d this_read:%u partial:%u", | 396 | dbg("read stats: result:%d this_read:%u partial:%u", |
397 | result, this_read, partial); | 397 | result, this_read, partial); |
398 | 398 | ||
399 | if (partial) { | 399 | if (partial) { |
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index f6ba4c788dbc..3c93921cb6b3 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c | |||
@@ -10,9 +10,6 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
13 | #ifdef CONFIG_USB_DEBUG | ||
14 | #define DEBUG 1 | ||
15 | #endif | ||
16 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
17 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
18 | #include <linux/init.h> | 15 | #include <linux/init.h> |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 2997f558159b..605a2afe34ed 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -1,7 +1,4 @@ | |||
1 | #include <linux/config.h> | 1 | #include <linux/config.h> |
2 | #if !defined (DEBUG) && defined (CONFIG_USB_DEBUG) | ||
3 | # define DEBUG | ||
4 | #endif | ||
5 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
6 | #include <linux/errno.h> | 3 | #include <linux/errno.h> |
7 | #include <linux/init.h> | 4 | #include <linux/init.h> |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 0592cb5e6c4d..1cabe7ed91f5 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -41,8 +41,6 @@ | |||
41 | 41 | ||
42 | /*****************************************************************************/ | 42 | /*****************************************************************************/ |
43 | 43 | ||
44 | #define DEBUG | ||
45 | |||
46 | #include <linux/module.h> | 44 | #include <linux/module.h> |
47 | #include <linux/socket.h> | 45 | #include <linux/socket.h> |
48 | #include <linux/parport.h> | 46 | #include <linux/parport.h> |
diff --git a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile index 222c0495f791..a21e6eaabaf6 100644 --- a/drivers/usb/net/Makefile +++ b/drivers/usb/net/Makefile | |||
@@ -16,3 +16,7 @@ obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o | |||
16 | obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o | 16 | obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o |
17 | obj-$(CONFIG_USB_USBNET) += usbnet.o | 17 | obj-$(CONFIG_USB_USBNET) += usbnet.o |
18 | obj-$(CONFIG_USB_ZD1201) += zd1201.o | 18 | obj-$(CONFIG_USB_ZD1201) += zd1201.o |
19 | |||
20 | ifeq ($(CONFIG_USB_DEBUG),y) | ||
21 | EXTRA_CFLAGS += -DDEBUG | ||
22 | endif | ||
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 252a34fbb42c..542120ef1fd2 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c | |||
@@ -23,9 +23,6 @@ | |||
23 | // #define VERBOSE // more; success messages | 23 | // #define VERBOSE // more; success messages |
24 | 24 | ||
25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
26 | #ifdef CONFIG_USB_DEBUG | ||
27 | # define DEBUG | ||
28 | #endif | ||
29 | #include <linux/module.h> | 26 | #include <linux/module.h> |
30 | #include <linux/kmod.h> | 27 | #include <linux/kmod.h> |
31 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c index 652b04bbf6af..c008c981862b 100644 --- a/drivers/usb/net/cdc_ether.c +++ b/drivers/usb/net/cdc_ether.c | |||
@@ -21,9 +21,6 @@ | |||
21 | // #define VERBOSE // more; success messages | 21 | // #define VERBOSE // more; success messages |
22 | 22 | ||
23 | #include <linux/config.h> | 23 | #include <linux/config.h> |
24 | #ifdef CONFIG_USB_DEBUG | ||
25 | # define DEBUG | ||
26 | #endif | ||
27 | #include <linux/module.h> | 24 | #include <linux/module.h> |
28 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
29 | #include <linux/init.h> | 26 | #include <linux/init.h> |
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c index f1730b685fd2..f05cfb83c82d 100644 --- a/drivers/usb/net/cdc_subset.c +++ b/drivers/usb/net/cdc_subset.c | |||
@@ -18,9 +18,6 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/config.h> | 20 | #include <linux/config.h> |
21 | #ifdef CONFIG_USB_DEBUG | ||
22 | # define DEBUG | ||
23 | #endif | ||
24 | #include <linux/module.h> | 21 | #include <linux/module.h> |
25 | #include <linux/kmod.h> | 22 | #include <linux/kmod.h> |
26 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c index c0f263b202a6..2455e9a85674 100644 --- a/drivers/usb/net/gl620a.c +++ b/drivers/usb/net/gl620a.c | |||
@@ -22,9 +22,6 @@ | |||
22 | // #define VERBOSE // more; success messages | 22 | // #define VERBOSE // more; success messages |
23 | 23 | ||
24 | #include <linux/config.h> | 24 | #include <linux/config.h> |
25 | #ifdef CONFIG_USB_DEBUG | ||
26 | # define DEBUG | ||
27 | #endif | ||
28 | #include <linux/module.h> | 25 | #include <linux/module.h> |
29 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
30 | #include <linux/init.h> | 27 | #include <linux/init.h> |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index 6bef1be6b36c..b5776518020f 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -219,7 +219,6 @@ struct kaweth_device | |||
219 | 219 | ||
220 | __u32 status; | 220 | __u32 status; |
221 | int end; | 221 | int end; |
222 | int removed; | ||
223 | int suspend_lowmem_rx; | 222 | int suspend_lowmem_rx; |
224 | int suspend_lowmem_ctrl; | 223 | int suspend_lowmem_ctrl; |
225 | int linkstate; | 224 | int linkstate; |
@@ -699,6 +698,7 @@ static int kaweth_close(struct net_device *net) | |||
699 | 698 | ||
700 | usb_kill_urb(kaweth->irq_urb); | 699 | usb_kill_urb(kaweth->irq_urb); |
701 | usb_kill_urb(kaweth->rx_urb); | 700 | usb_kill_urb(kaweth->rx_urb); |
701 | usb_kill_urb(kaweth->tx_urb); | ||
702 | 702 | ||
703 | flush_scheduled_work(); | 703 | flush_scheduled_work(); |
704 | 704 | ||
@@ -750,13 +750,6 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
750 | 750 | ||
751 | spin_lock(&kaweth->device_lock); | 751 | spin_lock(&kaweth->device_lock); |
752 | 752 | ||
753 | if (kaweth->removed) { | ||
754 | /* our device is undergoing disconnection - we bail out */ | ||
755 | spin_unlock(&kaweth->device_lock); | ||
756 | dev_kfree_skb_irq(skb); | ||
757 | return 0; | ||
758 | } | ||
759 | |||
760 | kaweth_async_set_rx_mode(kaweth); | 753 | kaweth_async_set_rx_mode(kaweth); |
761 | netif_stop_queue(net); | 754 | netif_stop_queue(net); |
762 | 755 | ||
@@ -1136,10 +1129,6 @@ static void kaweth_disconnect(struct usb_interface *intf) | |||
1136 | return; | 1129 | return; |
1137 | } | 1130 | } |
1138 | netdev = kaweth->net; | 1131 | netdev = kaweth->net; |
1139 | kaweth->removed = 1; | ||
1140 | usb_kill_urb(kaweth->irq_urb); | ||
1141 | usb_kill_urb(kaweth->rx_urb); | ||
1142 | usb_kill_urb(kaweth->tx_urb); | ||
1143 | 1132 | ||
1144 | kaweth_dbg("Unregistering net device"); | 1133 | kaweth_dbg("Unregistering net device"); |
1145 | unregister_netdev(netdev); | 1134 | unregister_netdev(netdev); |
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c index cee55f8cf64f..b3799b1a2b0d 100644 --- a/drivers/usb/net/net1080.c +++ b/drivers/usb/net/net1080.c | |||
@@ -21,9 +21,6 @@ | |||
21 | // #define VERBOSE // more; success messages | 21 | // #define VERBOSE // more; success messages |
22 | 22 | ||
23 | #include <linux/config.h> | 23 | #include <linux/config.h> |
24 | #ifdef CONFIG_USB_DEBUG | ||
25 | # define DEBUG | ||
26 | #endif | ||
27 | #include <linux/module.h> | 24 | #include <linux/module.h> |
28 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
29 | #include <linux/init.h> | 26 | #include <linux/init.h> |
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 537eb181d985..683e3df5d607 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
@@ -28,8 +28,6 @@ | |||
28 | * is out of the interrupt routine. | 28 | * is out of the interrupt routine. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #undef DEBUG | ||
32 | |||
33 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
34 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
35 | #include <linux/init.h> | 33 | #include <linux/init.h> |
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c index 74c2b3581c76..89856aa0e3b8 100644 --- a/drivers/usb/net/plusb.c +++ b/drivers/usb/net/plusb.c | |||
@@ -21,9 +21,6 @@ | |||
21 | // #define VERBOSE // more; success messages | 21 | // #define VERBOSE // more; success messages |
22 | 22 | ||
23 | #include <linux/config.h> | 23 | #include <linux/config.h> |
24 | #ifdef CONFIG_USB_DEBUG | ||
25 | # define DEBUG | ||
26 | #endif | ||
27 | #include <linux/module.h> | 24 | #include <linux/module.h> |
28 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
29 | #include <linux/init.h> | 26 | #include <linux/init.h> |
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index b5a925dc1beb..c0ecbab6f6ba 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c | |||
@@ -21,9 +21,6 @@ | |||
21 | // #define VERBOSE // more; success messages | 21 | // #define VERBOSE // more; success messages |
22 | 22 | ||
23 | #include <linux/config.h> | 23 | #include <linux/config.h> |
24 | #ifdef CONFIG_USB_DEBUG | ||
25 | # define DEBUG | ||
26 | #endif | ||
27 | #include <linux/module.h> | 24 | #include <linux/module.h> |
28 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
29 | #include <linux/init.h> | 26 | #include <linux/init.h> |
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 74f05c9c84d5..362d6907c9bb 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -34,9 +34,6 @@ | |||
34 | // #define VERBOSE // more; success messages | 34 | // #define VERBOSE // more; success messages |
35 | 35 | ||
36 | #include <linux/config.h> | 36 | #include <linux/config.h> |
37 | #ifdef CONFIG_USB_DEBUG | ||
38 | # define DEBUG | ||
39 | #endif | ||
40 | #include <linux/module.h> | 37 | #include <linux/module.h> |
41 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
42 | #include <linux/init.h> | 39 | #include <linux/init.h> |
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c index 5d4b7d55b097..680d13957af4 100644 --- a/drivers/usb/net/zaurus.c +++ b/drivers/usb/net/zaurus.c | |||
@@ -21,9 +21,6 @@ | |||
21 | // #define VERBOSE // more; success messages | 21 | // #define VERBOSE // more; success messages |
22 | 22 | ||
23 | #include <linux/config.h> | 23 | #include <linux/config.h> |
24 | #ifdef CONFIG_USB_DEBUG | ||
25 | # define DEBUG | ||
26 | #endif | ||
27 | #include <linux/module.h> | 24 | #include <linux/module.h> |
28 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
29 | #include <linux/init.h> | 26 | #include <linux/init.h> |
diff --git a/drivers/usb/serial/ChangeLog.old b/drivers/usb/serial/ChangeLog.history index c1b279939bbf..52c4f7bd7a80 100644 --- a/drivers/usb/serial/ChangeLog.old +++ b/drivers/usb/serial/ChangeLog.history | |||
@@ -400,7 +400,7 @@ visor.c Change Log comments: | |||
400 | 400 | ||
401 | (11/11/2001) gkh | 401 | (11/11/2001) gkh |
402 | Added support for the m125 devices, and added check to prevent oopses | 402 | Added support for the m125 devices, and added check to prevent oopses |
403 | for Clié devices that lie about the number of ports they have. | 403 | for Clié devices that lie about the number of ports they have. |
404 | 404 | ||
405 | (08/30/2001) gkh | 405 | (08/30/2001) gkh |
406 | Added support for the Clie devices, both the 3.5 and 4.0 os versions. | 406 | Added support for the Clie devices, both the 3.5 and 4.0 os versions. |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 7b5e8e4ee2bb..14f55fd26a64 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -62,6 +62,15 @@ config USB_SERIAL_AIRPRIME | |||
62 | To compile this driver as a module, choose M here: the | 62 | To compile this driver as a module, choose M here: the |
63 | module will be called airprime. | 63 | module will be called airprime. |
64 | 64 | ||
65 | config USB_SERIAL_ANYDATA | ||
66 | tristate "USB AnyData CDMA Wireless Driver" | ||
67 | depends on USB_SERIAL | ||
68 | help | ||
69 | Say Y here if you want to use a AnyData CDMA device. | ||
70 | |||
71 | To compile this driver as a module, choose M here: the | ||
72 | module will be called anydata. | ||
73 | |||
65 | config USB_SERIAL_BELKIN | 74 | config USB_SERIAL_BELKIN |
66 | tristate "USB Belkin and Peracom Single Port Serial Driver" | 75 | tristate "USB Belkin and Peracom Single Port Serial Driver" |
67 | depends on USB_SERIAL | 76 | depends on USB_SERIAL |
@@ -394,15 +403,6 @@ config USB_SERIAL_MCT_U232 | |||
394 | To compile this driver as a module, choose M here: the | 403 | To compile this driver as a module, choose M here: the |
395 | module will be called mct_u232. | 404 | module will be called mct_u232. |
396 | 405 | ||
397 | config USB_SERIAL_NOKIA_DKU2 | ||
398 | tristate "USB Nokia DKU2 Driver" | ||
399 | depends on USB_SERIAL | ||
400 | help | ||
401 | Say Y here if you want to use a Nokia DKU2 device. | ||
402 | |||
403 | To compile this driver as a module, choose M here: the | ||
404 | module will be called nokia_dku2. | ||
405 | |||
406 | config USB_SERIAL_PL2303 | 406 | config USB_SERIAL_PL2303 |
407 | tristate "USB Prolific 2303 Single Port Serial Driver" | 407 | tristate "USB Prolific 2303 Single Port Serial Driver" |
408 | depends on USB_SERIAL | 408 | depends on USB_SERIAL |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 55fd461793b7..f0b04420cea1 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -12,6 +12,7 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ezusb.o | |||
12 | usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) | 12 | usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) |
13 | 13 | ||
14 | obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o | 14 | obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o |
15 | obj-$(CONFIG_USB_SERIAL_ANYDATA) += anydata.o | ||
15 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o | 16 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o |
16 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o | 17 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o |
17 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o | 18 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o |
@@ -31,7 +32,6 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o | |||
31 | obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o | 32 | obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o |
32 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o | 33 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o |
33 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o | 34 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o |
34 | obj-$(CONFIG_USB_SERIAL_NOKIA_DKU2) += nokia_dku2.o | ||
35 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o | 35 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o |
36 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o | 36 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o |
37 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o | 37 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o |
diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c new file mode 100644 index 000000000000..18022a74a3dc --- /dev/null +++ b/drivers/usb/serial/anydata.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * AnyData CDMA Serial USB driver | ||
3 | * | ||
4 | * Copyright (C) 2005 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(0x16d5, 0x6501) }, /* AirData CDMA device */ | ||
20 | { }, | ||
21 | }; | ||
22 | MODULE_DEVICE_TABLE(usb, id_table); | ||
23 | |||
24 | /* if overridden by the user, then use their value for the size of the | ||
25 | * read and write urbs */ | ||
26 | static int buffer_size; | ||
27 | static int debug; | ||
28 | |||
29 | static struct usb_driver anydata_driver = { | ||
30 | .owner = THIS_MODULE, | ||
31 | .name = "anydata", | ||
32 | .probe = usb_serial_probe, | ||
33 | .disconnect = usb_serial_disconnect, | ||
34 | .id_table = id_table, | ||
35 | }; | ||
36 | |||
37 | static int anydata_open(struct usb_serial_port *port, struct file *filp) | ||
38 | { | ||
39 | char *buffer; | ||
40 | int result = 0; | ||
41 | |||
42 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
43 | |||
44 | if (buffer_size) { | ||
45 | /* override the default buffer sizes */ | ||
46 | buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
47 | if (!buffer) { | ||
48 | dev_err(&port->dev, "%s - out of memory.\n", | ||
49 | __FUNCTION__); | ||
50 | return -ENOMEM; | ||
51 | } | ||
52 | kfree (port->read_urb->transfer_buffer); | ||
53 | port->read_urb->transfer_buffer = buffer; | ||
54 | port->read_urb->transfer_buffer_length = buffer_size; | ||
55 | |||
56 | buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
57 | if (!buffer) { | ||
58 | dev_err(&port->dev, "%s - out of memory.\n", | ||
59 | __FUNCTION__); | ||
60 | return -ENOMEM; | ||
61 | } | ||
62 | kfree (port->write_urb->transfer_buffer); | ||
63 | port->write_urb->transfer_buffer = buffer; | ||
64 | port->write_urb->transfer_buffer_length = buffer_size; | ||
65 | port->bulk_out_size = buffer_size; | ||
66 | } | ||
67 | |||
68 | /* Start reading from the device */ | ||
69 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
70 | usb_rcvbulkpipe(port->serial->dev, | ||
71 | port->bulk_in_endpointAddress), | ||
72 | port->read_urb->transfer_buffer, | ||
73 | port->read_urb->transfer_buffer_length, | ||
74 | usb_serial_generic_write_bulk_callback, port); | ||
75 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
76 | if (result) | ||
77 | dev_err(&port->dev, | ||
78 | "%s - failed submitting read urb, error %d\n", | ||
79 | __FUNCTION__, result); | ||
80 | |||
81 | return result; | ||
82 | } | ||
83 | |||
84 | static struct usb_serial_driver anydata_device = { | ||
85 | .driver = { | ||
86 | .owner = THIS_MODULE, | ||
87 | .name = "anydata", | ||
88 | }, | ||
89 | .id_table = id_table, | ||
90 | .num_interrupt_in = NUM_DONT_CARE, | ||
91 | .num_bulk_in = NUM_DONT_CARE, | ||
92 | .num_bulk_out = NUM_DONT_CARE, | ||
93 | .num_ports = 1, | ||
94 | .open = anydata_open, | ||
95 | }; | ||
96 | |||
97 | static int __init anydata_init(void) | ||
98 | { | ||
99 | int retval; | ||
100 | |||
101 | retval = usb_serial_register(&anydata_device); | ||
102 | if (retval) | ||
103 | return retval; | ||
104 | retval = usb_register(&anydata_driver); | ||
105 | if (retval) | ||
106 | usb_serial_deregister(&anydata_device); | ||
107 | return retval; | ||
108 | } | ||
109 | |||
110 | static void __exit anydata_exit(void) | ||
111 | { | ||
112 | usb_deregister(&anydata_driver); | ||
113 | usb_serial_deregister(&anydata_device); | ||
114 | } | ||
115 | |||
116 | module_init(anydata_init); | ||
117 | module_exit(anydata_exit); | ||
118 | MODULE_LICENSE("GPL"); | ||
119 | |||
120 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
121 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
122 | module_param(buffer_size, int, 0); | ||
123 | MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers"); | ||
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index c5334dd89b12..c9787001cf2a 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -60,6 +60,7 @@ static struct usb_device_id id_table [] = { | |||
60 | { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ | 60 | { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ |
61 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ | 61 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ |
62 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 62 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
63 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | ||
63 | { } /* Terminating Entry */ | 64 | { } /* Terminating Entry */ |
64 | }; | 65 | }; |
65 | 66 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 8909208f506a..53a47c31cd0e 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -309,6 +309,7 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *re | |||
309 | 309 | ||
310 | schedule_work(&port->work); | 310 | schedule_work(&port->work); |
311 | } | 311 | } |
312 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | ||
312 | 313 | ||
313 | void usb_serial_generic_shutdown (struct usb_serial *serial) | 314 | void usb_serial_generic_shutdown (struct usb_serial *serial) |
314 | { | 315 | { |
diff --git a/drivers/usb/serial/nokia_dku2.c b/drivers/usb/serial/nokia_dku2.c deleted file mode 100644 index fad01bef3a64..000000000000 --- a/drivers/usb/serial/nokia_dku2.c +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
1 | /* | ||
2 | * Nokia DKU2 USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004 | ||
5 | * Author: C Kemp | ||
6 | * | ||
7 | * This program is largely derived from work by the linux-usb group | ||
8 | * and associated source files. Please see the usb/serial files for | ||
9 | * individual credits and copyrights. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * 20.09.2005 - Matthias Blaesing <matthias.blaesing@rwth-aachen.de> | ||
17 | * Added short name to device structure to make driver load into kernel 2.6.13 | ||
18 | * | ||
19 | * 20.09.2005 - Matthias Blaesing <matthias.blaesing@rwth-aachen.de> | ||
20 | * Added usb_deregister to exit code - to allow remove and reinsert of module | ||
21 | */ | ||
22 | |||
23 | |||
24 | #include <linux/config.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/tty.h> | ||
30 | #include <linux/tty_driver.h> | ||
31 | #include <linux/tty_flip.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/usb.h> | ||
34 | #include "usb-serial.h" | ||
35 | |||
36 | |||
37 | #define NOKIA_VENDOR_ID 0x0421 | ||
38 | #define NOKIA7600_PRODUCT_ID 0x0400 | ||
39 | #define NOKIA6230_PRODUCT_ID 0x040f | ||
40 | #define NOKIA6170_PRODUCT_ID 0x0416 | ||
41 | #define NOKIA6670_PRODUCT_ID 0x041d | ||
42 | #define NOKIA6680_PRODUCT_ID 0x041e | ||
43 | #define NOKIA6230i_PRODUCT_ID 0x0428 | ||
44 | |||
45 | #define NOKIA_AT_PORT 0x82 | ||
46 | #define NOKIA_FBUS_PORT 0x86 | ||
47 | |||
48 | /* | ||
49 | * Version Information | ||
50 | */ | ||
51 | #define DRIVER_VERSION "v0.2" | ||
52 | #define DRIVER_AUTHOR "C Kemp" | ||
53 | #define DRIVER_DESC "Nokia DKU2 Driver" | ||
54 | |||
55 | static struct usb_device_id id_table [] = { | ||
56 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA7600_PRODUCT_ID) }, | ||
57 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230_PRODUCT_ID) }, | ||
58 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6170_PRODUCT_ID) }, | ||
59 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6670_PRODUCT_ID) }, | ||
60 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6680_PRODUCT_ID) }, | ||
61 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230i_PRODUCT_ID) }, | ||
62 | { } /* Terminating entry */ | ||
63 | }; | ||
64 | MODULE_DEVICE_TABLE(usb, id_table); | ||
65 | |||
66 | /* The only thing which makes this device different from a generic | ||
67 | * device is that we have to set an alternative configuration to make | ||
68 | * the relevant endpoints available. In 2.6 this is really easy... */ | ||
69 | static int nokia_probe(struct usb_serial *serial, | ||
70 | const struct usb_device_id *id) | ||
71 | { | ||
72 | int retval = -ENODEV; | ||
73 | |||
74 | if (serial->interface->altsetting[0].endpoint[0].desc.bEndpointAddress == NOKIA_AT_PORT) { | ||
75 | /* the AT port */ | ||
76 | dev_info(&serial->dev->dev, "Nokia AT Port:\n"); | ||
77 | retval = 0; | ||
78 | } else if (serial->interface->num_altsetting == 2 && | ||
79 | serial->interface->altsetting[1].endpoint[0].desc.bEndpointAddress == NOKIA_FBUS_PORT) { | ||
80 | /* the FBUS port */ | ||
81 | dev_info(&serial->dev->dev, "Nokia FBUS Port:\n"); | ||
82 | usb_set_interface(serial->dev, 10, 1); | ||
83 | retval = 0; | ||
84 | } | ||
85 | |||
86 | return retval; | ||
87 | } | ||
88 | |||
89 | static struct usb_driver nokia_driver = { | ||
90 | .owner = THIS_MODULE, | ||
91 | .name = "nokia_dku2", | ||
92 | .probe = usb_serial_probe, | ||
93 | .disconnect = usb_serial_disconnect, | ||
94 | .id_table = id_table, | ||
95 | }; | ||
96 | |||
97 | static struct usb_serial_driver nokia_serial_driver = { | ||
98 | .driver = { | ||
99 | .owner = THIS_MODULE, | ||
100 | .name = "nokia_dku2", | ||
101 | }, | ||
102 | .description = "Nokia 7600/6230(i)/6170/66x0 DKU2 driver", | ||
103 | .id_table = id_table, | ||
104 | .num_interrupt_in = 1, | ||
105 | .num_bulk_in = 1, | ||
106 | .num_bulk_out = 1, | ||
107 | .num_ports = 1, | ||
108 | .probe = nokia_probe, | ||
109 | }; | ||
110 | |||
111 | static int __init nokia_init(void) | ||
112 | { | ||
113 | int retval; | ||
114 | |||
115 | retval = usb_serial_register(&nokia_serial_driver); | ||
116 | if (retval) | ||
117 | return retval; | ||
118 | |||
119 | retval = usb_register(&nokia_driver); | ||
120 | if (retval) { | ||
121 | usb_serial_deregister(&nokia_serial_driver); | ||
122 | return retval; | ||
123 | } | ||
124 | |||
125 | info(DRIVER_VERSION " " DRIVER_AUTHOR); | ||
126 | info(DRIVER_DESC); | ||
127 | |||
128 | return retval; | ||
129 | } | ||
130 | |||
131 | static void __exit nokia_exit(void) | ||
132 | { | ||
133 | usb_deregister(&nokia_driver); | ||
134 | usb_serial_deregister(&nokia_serial_driver); | ||
135 | } | ||
136 | |||
137 | module_init(nokia_init); | ||
138 | module_exit(nokia_exit); | ||
139 | |||
140 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
141 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
142 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 165c119bf10e..41a45a5025b2 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -71,7 +71,9 @@ static struct usb_device_id id_table [] = { | |||
71 | { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) }, | 71 | { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) }, |
72 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) }, | 72 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) }, |
73 | { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) }, | 73 | { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) }, |
74 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) }, | ||
74 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, | 75 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, |
76 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, | ||
75 | { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, | 77 | { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, |
76 | { USB_DEVICE( NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) }, | 78 | { USB_DEVICE( NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) }, |
77 | { } /* Terminating entry */ | 79 | { } /* Terminating entry */ |
@@ -811,7 +813,9 @@ static void pl2303_update_line_status(struct usb_serial_port *port, | |||
811 | u8 length = UART_STATE; | 813 | u8 length = UART_STATE; |
812 | 814 | ||
813 | if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && | 815 | if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && |
814 | (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65)) { | 816 | (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 || |
817 | le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_SX1 || | ||
818 | le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X75)) { | ||
815 | length = 1; | 819 | length = 1; |
816 | status_idx = 0; | 820 | status_idx = 0; |
817 | } | 821 | } |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 7be9644f5a03..21d434d81813 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -54,7 +54,9 @@ | |||
54 | #define SAMSUNG_PRODUCT_ID 0x8001 | 54 | #define SAMSUNG_PRODUCT_ID 0x8001 |
55 | 55 | ||
56 | #define SIEMENS_VENDOR_ID 0x11f5 | 56 | #define SIEMENS_VENDOR_ID 0x11f5 |
57 | #define SIEMENS_PRODUCT_ID_SX1 0x0001 | ||
57 | #define SIEMENS_PRODUCT_ID_X65 0x0003 | 58 | #define SIEMENS_PRODUCT_ID_X65 0x0003 |
59 | #define SIEMENS_PRODUCT_ID_X75 0x0004 | ||
58 | 60 | ||
59 | #define SYNTECH_VENDOR_ID 0x0745 | 61 | #define SYNTECH_VENDOR_ID 0x0745 |
60 | #define SYNTECH_PRODUCT_ID 0x0001 | 62 | #define SYNTECH_PRODUCT_ID 0x0001 |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 1a9679f76f5a..c41d64dbb0f0 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -115,7 +115,7 @@ config USB_STORAGE_JUMPSHOT | |||
115 | 115 | ||
116 | config USB_STORAGE_ONETOUCH | 116 | config USB_STORAGE_ONETOUCH |
117 | bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" | 117 | bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" |
118 | depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL | 118 | depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL && !PM |
119 | help | 119 | help |
120 | Say Y here to include additional code to support the Maxtor OneTouch | 120 | Say Y here to include additional code to support the Maxtor OneTouch |
121 | USB hard drive's onetouch button. | 121 | USB hard drive's onetouch button. |
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 33c55a6261bb..fea176d7e79a 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -853,7 +853,7 @@ static int usbat_identify_device(struct us_data *us, | |||
853 | rc = usbat_device_reset(us); | 853 | rc = usbat_device_reset(us); |
854 | if (rc != USB_STOR_TRANSPORT_GOOD) | 854 | if (rc != USB_STOR_TRANSPORT_GOOD) |
855 | return rc; | 855 | return rc; |
856 | msleep(25); | 856 | msleep(500); |
857 | 857 | ||
858 | /* | 858 | /* |
859 | * In attempt to distinguish between HP CDRW's and Flash readers, we now | 859 | * In attempt to distinguish between HP CDRW's and Flash readers, we now |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 9e926a8f2116..0a9858f69a9b 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -710,11 +710,6 @@ UNUSUAL_DEV( 0x0686, 0x4017, 0x0001, 0x0001, | |||
710 | "DIMAGE E223", | 710 | "DIMAGE E223", |
711 | US_SC_SCSI, US_PR_DEVICE, NULL, 0 ), | 711 | US_SC_SCSI, US_PR_DEVICE, NULL, 0 ), |
712 | 712 | ||
713 | UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100, | ||
714 | "Hagiwara", | ||
715 | "FlashGate SmartMedia", | ||
716 | US_SC_SCSI, US_PR_BULK, NULL, 0 ), | ||
717 | |||
718 | UNUSUAL_DEV( 0x0693, 0x0005, 0x0100, 0x0100, | 713 | UNUSUAL_DEV( 0x0693, 0x0005, 0x0100, 0x0100, |
719 | "Hagiwara", | 714 | "Hagiwara", |
720 | "Flashgate", | 715 | "Flashgate", |
@@ -1008,6 +1003,11 @@ UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | |||
1008 | * | 1003 | * |
1009 | */ | 1004 | */ |
1010 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | 1005 | #ifdef CONFIG_USB_STORAGE_ONETOUCH |
1006 | UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999, | ||
1007 | "Maxtor", | ||
1008 | "OneTouch External Harddrive", | ||
1009 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
1010 | 0), | ||
1011 | UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999, | 1011 | UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999, |
1012 | "Maxtor", | 1012 | "Maxtor", |
1013 | "OneTouch External Harddrive", | 1013 | "OneTouch External Harddrive", |
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index f53bf3ba1278..d3728f60961e 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c | |||
@@ -51,6 +51,9 @@ static struct fb_ops bw2_ops = { | |||
51 | .fb_imageblit = cfb_imageblit, | 51 | .fb_imageblit = cfb_imageblit, |
52 | .fb_mmap = bw2_mmap, | 52 | .fb_mmap = bw2_mmap, |
53 | .fb_ioctl = bw2_ioctl, | 53 | .fb_ioctl = bw2_ioctl, |
54 | #ifdef CONFIG_COMPAT | ||
55 | .fb_compat_ioctl = sbusfb_compat_ioctl, | ||
56 | #endif | ||
54 | }; | 57 | }; |
55 | 58 | ||
56 | /* OBio addresses for the bwtwo registers */ | 59 | /* OBio addresses for the bwtwo registers */ |
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 030d4b13b1c2..1bed50f2a276 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c | |||
@@ -49,6 +49,9 @@ static struct fb_ops cg14_ops = { | |||
49 | .fb_imageblit = cfb_imageblit, | 49 | .fb_imageblit = cfb_imageblit, |
50 | .fb_mmap = cg14_mmap, | 50 | .fb_mmap = cg14_mmap, |
51 | .fb_ioctl = cg14_ioctl, | 51 | .fb_ioctl = cg14_ioctl, |
52 | #ifdef CONFIG_COMPAT | ||
53 | .fb_compat_ioctl = sbusfb_compat_ioctl, | ||
54 | #endif | ||
52 | }; | 55 | }; |
53 | 56 | ||
54 | #define CG14_MCR_INTENABLE_SHIFT 7 | 57 | #define CG14_MCR_INTENABLE_SHIFT 7 |
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index b94eee8c42d5..a1354e7e0513 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c | |||
@@ -50,6 +50,9 @@ static struct fb_ops cg3_ops = { | |||
50 | .fb_imageblit = cfb_imageblit, | 50 | .fb_imageblit = cfb_imageblit, |
51 | .fb_mmap = cg3_mmap, | 51 | .fb_mmap = cg3_mmap, |
52 | .fb_ioctl = cg3_ioctl, | 52 | .fb_ioctl = cg3_ioctl, |
53 | #ifdef CONFIG_COMPAT | ||
54 | .fb_compat_ioctl = sbusfb_compat_ioctl, | ||
55 | #endif | ||
53 | }; | 56 | }; |
54 | 57 | ||
55 | 58 | ||
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 414c4409e924..9debe642fd2f 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c | |||
@@ -54,6 +54,9 @@ static struct fb_ops cg6_ops = { | |||
54 | .fb_sync = cg6_sync, | 54 | .fb_sync = cg6_sync, |
55 | .fb_mmap = cg6_mmap, | 55 | .fb_mmap = cg6_mmap, |
56 | .fb_ioctl = cg6_ioctl, | 56 | .fb_ioctl = cg6_ioctl, |
57 | #ifdef CONFIG_COMPAT | ||
58 | .fb_compat_ioctl = sbusfb_compat_ioctl, | ||
59 | #endif | ||
57 | }; | 60 | }; |
58 | 61 | ||
59 | /* Offset of interesting structures in the OBIO space */ | 62 | /* Offset of interesting structures in the OBIO space */ |
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 94c5f1392cce..5f74df993406 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig | |||
@@ -215,12 +215,5 @@ config FONT_10x18 | |||
215 | big letters. It fits between the sun 12x22 and the normal 8x16 font. | 215 | big letters. It fits between the sun 12x22 and the normal 8x16 font. |
216 | If other fonts are too big or too small for you, say Y, otherwise say N. | 216 | If other fonts are too big or too small for you, say Y, otherwise say N. |
217 | 217 | ||
218 | config FONT_RL | ||
219 | bool "console Roman Large 8x16 font" if FONTS | ||
220 | depends on FRAMEBUFFER_CONSOLE | ||
221 | help | ||
222 | This is the visually-appealing "RL" console font that is | ||
223 | included with the kbd package. | ||
224 | |||
225 | endmenu | 218 | endmenu |
226 | 219 | ||
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile index fed600c9ca55..9b26dda18a38 100644 --- a/drivers/video/console/Makefile +++ b/drivers/video/console/Makefile | |||
@@ -15,7 +15,6 @@ font-objs-$(CONFIG_FONT_10x18) += font_10x18.o | |||
15 | font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o | 15 | font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o |
16 | font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o | 16 | font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o |
17 | font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o | 17 | font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o |
18 | font-objs-$(CONFIG_FONT_RL) += font_rl.o | ||
19 | 18 | ||
20 | font-objs += $(font-objs-y) | 19 | font-objs += $(font-objs-y) |
21 | 20 | ||
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index e7802ffe549a..bcea87c3cc06 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -106,8 +106,7 @@ enum { | |||
106 | FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */ | 106 | FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */ |
107 | }; | 107 | }; |
108 | 108 | ||
109 | struct display fb_display[MAX_NR_CONSOLES]; | 109 | static struct display fb_display[MAX_NR_CONSOLES]; |
110 | EXPORT_SYMBOL(fb_display); | ||
111 | 110 | ||
112 | static signed char con2fb_map[MAX_NR_CONSOLES]; | 111 | static signed char con2fb_map[MAX_NR_CONSOLES]; |
113 | static signed char con2fb_map_boot[MAX_NR_CONSOLES]; | 112 | static signed char con2fb_map_boot[MAX_NR_CONSOLES]; |
@@ -653,13 +652,12 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info, | |||
653 | { | 652 | { |
654 | struct fbcon_ops *ops = info->fbcon_par; | 653 | struct fbcon_ops *ops = info->fbcon_par; |
655 | 654 | ||
655 | ops->p = (p) ? p : &fb_display[vc->vc_num]; | ||
656 | |||
656 | if ((info->flags & FBINFO_MISC_TILEBLITTING)) | 657 | if ((info->flags & FBINFO_MISC_TILEBLITTING)) |
657 | fbcon_set_tileops(vc, info, p, ops); | 658 | fbcon_set_tileops(vc, info, p, ops); |
658 | else { | 659 | else { |
659 | struct display *disp; | 660 | fbcon_set_rotation(info, ops->p); |
660 | |||
661 | disp = (p) ? p : &fb_display[vc->vc_num]; | ||
662 | fbcon_set_rotation(info, disp); | ||
663 | fbcon_set_bitops(ops); | 661 | fbcon_set_bitops(ops); |
664 | } | 662 | } |
665 | } | 663 | } |
@@ -668,11 +666,10 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info, | |||
668 | struct display *p) | 666 | struct display *p) |
669 | { | 667 | { |
670 | struct fbcon_ops *ops = info->fbcon_par; | 668 | struct fbcon_ops *ops = info->fbcon_par; |
671 | struct display *disp; | ||
672 | 669 | ||
673 | info->flags &= ~FBINFO_MISC_TILEBLITTING; | 670 | info->flags &= ~FBINFO_MISC_TILEBLITTING; |
674 | disp = (p) ? p : &fb_display[vc->vc_num]; | 671 | ops->p = (p) ? p : &fb_display[vc->vc_num]; |
675 | fbcon_set_rotation(info, disp); | 672 | fbcon_set_rotation(info, ops->p); |
676 | fbcon_set_bitops(ops); | 673 | fbcon_set_bitops(ops); |
677 | } | 674 | } |
678 | #endif /* CONFIG_MISC_TILEBLITTING */ | 675 | #endif /* CONFIG_MISC_TILEBLITTING */ |
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index accfd7bd8e93..6892e7ff34de 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h | |||
@@ -52,8 +52,6 @@ struct display { | |||
52 | struct fb_videomode *mode; | 52 | struct fb_videomode *mode; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | extern struct display fb_display[]; | ||
56 | |||
57 | struct fbcon_ops { | 55 | struct fbcon_ops { |
58 | void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy, | 56 | void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy, |
59 | int sx, int dy, int dx, int height, int width); | 57 | int sx, int dy, int dx, int height, int width); |
@@ -73,6 +71,7 @@ struct fbcon_ops { | |||
73 | struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */ | 71 | struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */ |
74 | struct timer_list cursor_timer; /* Cursor timer */ | 72 | struct timer_list cursor_timer; /* Cursor timer */ |
75 | struct fb_cursor cursor_state; | 73 | struct fb_cursor cursor_state; |
74 | struct display *p; | ||
76 | int currcon; /* Current VC. */ | 75 | int currcon; /* Current VC. */ |
77 | int cursor_flash; | 76 | int cursor_flash; |
78 | int cursor_reset; | 77 | int cursor_reset; |
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 680aabab73c5..3afd1eeb1ade 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c | |||
@@ -63,9 +63,9 @@ static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute, | |||
63 | static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy, | 63 | static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy, |
64 | int sx, int dy, int dx, int height, int width) | 64 | int sx, int dy, int dx, int height, int width) |
65 | { | 65 | { |
66 | struct display *p = &fb_display[vc->vc_num]; | 66 | struct fbcon_ops *ops = info->fbcon_par; |
67 | struct fb_copyarea area; | 67 | struct fb_copyarea area; |
68 | u32 vyres = GETVYRES(p->scrollmode, info); | 68 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
69 | 69 | ||
70 | area.sx = sy * vc->vc_font.height; | 70 | area.sx = sy * vc->vc_font.height; |
71 | area.sy = vyres - ((sx + width) * vc->vc_font.width); | 71 | area.sy = vyres - ((sx + width) * vc->vc_font.width); |
@@ -80,10 +80,10 @@ static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy, | |||
80 | static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy, | 80 | static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy, |
81 | int sx, int height, int width) | 81 | int sx, int height, int width) |
82 | { | 82 | { |
83 | struct display *p = &fb_display[vc->vc_num]; | 83 | struct fbcon_ops *ops = info->fbcon_par; |
84 | struct fb_fillrect region; | 84 | struct fb_fillrect region; |
85 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; | 85 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; |
86 | u32 vyres = GETVYRES(p->scrollmode, info); | 86 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
87 | 87 | ||
88 | region.color = attr_bgcol_ec(bgshift,vc); | 88 | region.color = attr_bgcol_ec(bgshift,vc); |
89 | region.dx = sy * vc->vc_font.height; | 89 | region.dx = sy * vc->vc_font.height; |
@@ -131,7 +131,6 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info, | |||
131 | int fg, int bg) | 131 | int fg, int bg) |
132 | { | 132 | { |
133 | struct fb_image image; | 133 | struct fb_image image; |
134 | struct display *p = &fb_display[vc->vc_num]; | ||
135 | struct fbcon_ops *ops = info->fbcon_par; | 134 | struct fbcon_ops *ops = info->fbcon_par; |
136 | u32 width = (vc->vc_font.height + 7)/8; | 135 | u32 width = (vc->vc_font.height + 7)/8; |
137 | u32 cellsize = width * vc->vc_font.width; | 136 | u32 cellsize = width * vc->vc_font.width; |
@@ -141,7 +140,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info, | |||
141 | u32 cnt, pitch, size; | 140 | u32 cnt, pitch, size; |
142 | u32 attribute = get_attribute(info, scr_readw(s)); | 141 | u32 attribute = get_attribute(info, scr_readw(s)); |
143 | u8 *dst, *buf = NULL; | 142 | u8 *dst, *buf = NULL; |
144 | u32 vyres = GETVYRES(p->scrollmode, info); | 143 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
145 | 144 | ||
146 | if (!ops->fontbuffer) | 145 | if (!ops->fontbuffer) |
147 | return; | 146 | return; |
@@ -397,9 +396,8 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, | |||
397 | int ccw_update_start(struct fb_info *info) | 396 | int ccw_update_start(struct fb_info *info) |
398 | { | 397 | { |
399 | struct fbcon_ops *ops = info->fbcon_par; | 398 | struct fbcon_ops *ops = info->fbcon_par; |
400 | struct display *p = &fb_display[ops->currcon]; | ||
401 | u32 yoffset; | 399 | u32 yoffset; |
402 | u32 vyres = GETVYRES(p->scrollmode, info); | 400 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
403 | int err; | 401 | int err; |
404 | 402 | ||
405 | yoffset = (vyres - info->var.yres) - ops->var.xoffset; | 403 | yoffset = (vyres - info->var.yres) - ops->var.xoffset; |
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index 6c6f3b6dd175..6d92b8456206 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c | |||
@@ -49,9 +49,9 @@ static inline void cw_update_attr(u8 *dst, u8 *src, int attribute, | |||
49 | static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy, | 49 | static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy, |
50 | int sx, int dy, int dx, int height, int width) | 50 | int sx, int dy, int dx, int height, int width) |
51 | { | 51 | { |
52 | struct display *p = &fb_display[vc->vc_num]; | 52 | struct fbcon_ops *ops = info->fbcon_par; |
53 | struct fb_copyarea area; | 53 | struct fb_copyarea area; |
54 | u32 vxres = GETVXRES(p->scrollmode, info); | 54 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
55 | 55 | ||
56 | area.sx = vxres - ((sy + height) * vc->vc_font.height); | 56 | area.sx = vxres - ((sy + height) * vc->vc_font.height); |
57 | area.sy = sx * vc->vc_font.width; | 57 | area.sy = sx * vc->vc_font.width; |
@@ -66,10 +66,10 @@ static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy, | |||
66 | static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy, | 66 | static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy, |
67 | int sx, int height, int width) | 67 | int sx, int height, int width) |
68 | { | 68 | { |
69 | struct display *p = &fb_display[vc->vc_num]; | 69 | struct fbcon_ops *ops = info->fbcon_par; |
70 | struct fb_fillrect region; | 70 | struct fb_fillrect region; |
71 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; | 71 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; |
72 | u32 vxres = GETVXRES(p->scrollmode, info); | 72 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
73 | 73 | ||
74 | region.color = attr_bgcol_ec(bgshift,vc); | 74 | region.color = attr_bgcol_ec(bgshift,vc); |
75 | region.dx = vxres - ((sy + height) * vc->vc_font.height); | 75 | region.dx = vxres - ((sy + height) * vc->vc_font.height); |
@@ -117,7 +117,6 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info, | |||
117 | int fg, int bg) | 117 | int fg, int bg) |
118 | { | 118 | { |
119 | struct fb_image image; | 119 | struct fb_image image; |
120 | struct display *p = &fb_display[vc->vc_num]; | ||
121 | struct fbcon_ops *ops = info->fbcon_par; | 120 | struct fbcon_ops *ops = info->fbcon_par; |
122 | u32 width = (vc->vc_font.height + 7)/8; | 121 | u32 width = (vc->vc_font.height + 7)/8; |
123 | u32 cellsize = width * vc->vc_font.width; | 122 | u32 cellsize = width * vc->vc_font.width; |
@@ -127,7 +126,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info, | |||
127 | u32 cnt, pitch, size; | 126 | u32 cnt, pitch, size; |
128 | u32 attribute = get_attribute(info, scr_readw(s)); | 127 | u32 attribute = get_attribute(info, scr_readw(s)); |
129 | u8 *dst, *buf = NULL; | 128 | u8 *dst, *buf = NULL; |
130 | u32 vxres = GETVXRES(p->scrollmode, info); | 129 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
131 | 130 | ||
132 | if (!ops->fontbuffer) | 131 | if (!ops->fontbuffer) |
133 | return; | 132 | return; |
@@ -381,8 +380,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, | |||
381 | int cw_update_start(struct fb_info *info) | 380 | int cw_update_start(struct fb_info *info) |
382 | { | 381 | { |
383 | struct fbcon_ops *ops = info->fbcon_par; | 382 | struct fbcon_ops *ops = info->fbcon_par; |
384 | struct display *p = &fb_display[ops->currcon]; | 383 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
385 | u32 vxres = GETVXRES(p->scrollmode, info); | ||
386 | u32 xoffset; | 384 | u32 xoffset; |
387 | int err; | 385 | int err; |
388 | 386 | ||
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index 2e1d9d4249cd..c4d7c89212b4 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c | |||
@@ -48,10 +48,10 @@ static inline void ud_update_attr(u8 *dst, u8 *src, int attribute, | |||
48 | static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy, | 48 | static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy, |
49 | int sx, int dy, int dx, int height, int width) | 49 | int sx, int dy, int dx, int height, int width) |
50 | { | 50 | { |
51 | struct display *p = &fb_display[vc->vc_num]; | 51 | struct fbcon_ops *ops = info->fbcon_par; |
52 | struct fb_copyarea area; | 52 | struct fb_copyarea area; |
53 | u32 vyres = GETVYRES(p->scrollmode, info); | 53 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
54 | u32 vxres = GETVXRES(p->scrollmode, info); | 54 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
55 | 55 | ||
56 | area.sy = vyres - ((sy + height) * vc->vc_font.height); | 56 | area.sy = vyres - ((sy + height) * vc->vc_font.height); |
57 | area.sx = vxres - ((sx + width) * vc->vc_font.width); | 57 | area.sx = vxres - ((sx + width) * vc->vc_font.width); |
@@ -66,11 +66,11 @@ static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy, | |||
66 | static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy, | 66 | static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy, |
67 | int sx, int height, int width) | 67 | int sx, int height, int width) |
68 | { | 68 | { |
69 | struct display *p = &fb_display[vc->vc_num]; | 69 | struct fbcon_ops *ops = info->fbcon_par; |
70 | struct fb_fillrect region; | 70 | struct fb_fillrect region; |
71 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; | 71 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; |
72 | u32 vyres = GETVYRES(p->scrollmode, info); | 72 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
73 | u32 vxres = GETVXRES(p->scrollmode, info); | 73 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
74 | 74 | ||
75 | region.color = attr_bgcol_ec(bgshift,vc); | 75 | region.color = attr_bgcol_ec(bgshift,vc); |
76 | region.dy = vyres - ((sy + height) * vc->vc_font.height); | 76 | region.dy = vyres - ((sy + height) * vc->vc_font.height); |
@@ -153,7 +153,6 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info, | |||
153 | int fg, int bg) | 153 | int fg, int bg) |
154 | { | 154 | { |
155 | struct fb_image image; | 155 | struct fb_image image; |
156 | struct display *p = &fb_display[vc->vc_num]; | ||
157 | struct fbcon_ops *ops = info->fbcon_par; | 156 | struct fbcon_ops *ops = info->fbcon_par; |
158 | u32 width = (vc->vc_font.width + 7)/8; | 157 | u32 width = (vc->vc_font.width + 7)/8; |
159 | u32 cellsize = width * vc->vc_font.height; | 158 | u32 cellsize = width * vc->vc_font.height; |
@@ -163,8 +162,8 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info, | |||
163 | u32 mod = vc->vc_font.width % 8, cnt, pitch, size; | 162 | u32 mod = vc->vc_font.width % 8, cnt, pitch, size; |
164 | u32 attribute = get_attribute(info, scr_readw(s)); | 163 | u32 attribute = get_attribute(info, scr_readw(s)); |
165 | u8 *dst, *buf = NULL; | 164 | u8 *dst, *buf = NULL; |
166 | u32 vyres = GETVYRES(p->scrollmode, info); | 165 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
167 | u32 vxres = GETVXRES(p->scrollmode, info); | 166 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
168 | 167 | ||
169 | if (!ops->fontbuffer) | 168 | if (!ops->fontbuffer) |
170 | return; | 169 | return; |
@@ -421,10 +420,9 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, | |||
421 | int ud_update_start(struct fb_info *info) | 420 | int ud_update_start(struct fb_info *info) |
422 | { | 421 | { |
423 | struct fbcon_ops *ops = info->fbcon_par; | 422 | struct fbcon_ops *ops = info->fbcon_par; |
424 | struct display *p = &fb_display[ops->currcon]; | ||
425 | u32 xoffset, yoffset; | 423 | u32 xoffset, yoffset; |
426 | u32 vyres = GETVYRES(p->scrollmode, info); | 424 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
427 | u32 vxres = GETVXRES(p->scrollmode, info); | 425 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
428 | int err; | 426 | int err; |
429 | 427 | ||
430 | xoffset = (vxres - info->var.xres) - ops->var.xoffset; | 428 | xoffset = (vxres - info->var.xres) - ops->var.xoffset; |
diff --git a/drivers/video/console/font_rl.c b/drivers/video/console/font_rl.c deleted file mode 100644 index dfecc27d8ded..000000000000 --- a/drivers/video/console/font_rl.c +++ /dev/null | |||
@@ -1,4374 +0,0 @@ | |||
1 | |||
2 | /* This font is simply the "rl.fnt" console font from the kbd utility. | ||
3 | * Converted by Zack T Smith, fbui@comcast.net. | ||
4 | * The original binary file is covered under the GNU Public License. | ||
5 | */ | ||
6 | |||
7 | #include <linux/font.h> | ||
8 | |||
9 | #define FONTDATAMAX 4096 | ||
10 | |||
11 | static unsigned char patterns[4096] = { | ||
12 | 0x00, | ||
13 | 0x00, | ||
14 | 0x00, | ||
15 | 0x00, | ||
16 | 0x00, | ||
17 | 0x00, | ||
18 | 0x00, | ||
19 | 0x00, | ||
20 | 0x00, | ||
21 | 0x00, | ||
22 | 0x00, | ||
23 | 0x00, | ||
24 | 0x00, | ||
25 | 0x00, | ||
26 | 0x00, | ||
27 | 0x00, | ||
28 | |||
29 | 0x00, | ||
30 | 0x00, | ||
31 | 0x3c, | ||
32 | 0x42, | ||
33 | 0x81, | ||
34 | 0xe7, | ||
35 | 0xa5, | ||
36 | 0x99, | ||
37 | 0x81, | ||
38 | 0x81, | ||
39 | 0x99, | ||
40 | 0x42, | ||
41 | 0x3c, | ||
42 | 0x00, | ||
43 | 0x00, | ||
44 | 0x00, | ||
45 | |||
46 | 0x00, | ||
47 | 0x00, | ||
48 | 0x3c, | ||
49 | 0x7e, | ||
50 | 0xff, | ||
51 | 0x99, | ||
52 | 0xdb, | ||
53 | 0xe7, | ||
54 | 0xff, | ||
55 | 0xff, | ||
56 | 0xe7, | ||
57 | 0x7e, | ||
58 | 0x3c, | ||
59 | 0x00, | ||
60 | 0x00, | ||
61 | 0x00, | ||
62 | |||
63 | 0x00, | ||
64 | 0x00, | ||
65 | 0x00, | ||
66 | 0x6c, | ||
67 | 0xfe, | ||
68 | 0xfe, | ||
69 | 0xfe, | ||
70 | 0xfe, | ||
71 | 0xfe, | ||
72 | 0x7c, | ||
73 | 0x38, | ||
74 | 0x10, | ||
75 | 0x00, | ||
76 | 0x00, | ||
77 | 0x00, | ||
78 | 0x00, | ||
79 | |||
80 | 0x00, | ||
81 | 0x00, | ||
82 | 0x00, | ||
83 | 0x00, | ||
84 | 0x10, | ||
85 | 0x38, | ||
86 | 0x7c, | ||
87 | 0xfe, | ||
88 | 0x7c, | ||
89 | 0x38, | ||
90 | 0x10, | ||
91 | 0x00, | ||
92 | 0x00, | ||
93 | 0x00, | ||
94 | 0x00, | ||
95 | 0x00, | ||
96 | |||
97 | 0x00, | ||
98 | 0x00, | ||
99 | 0x38, | ||
100 | 0x38, | ||
101 | 0x10, | ||
102 | 0xd6, | ||
103 | 0xfe, | ||
104 | 0xd6, | ||
105 | 0x10, | ||
106 | 0x10, | ||
107 | 0x38, | ||
108 | 0x7c, | ||
109 | 0x00, | ||
110 | 0x00, | ||
111 | 0x00, | ||
112 | 0x00, | ||
113 | |||
114 | 0x00, | ||
115 | 0x00, | ||
116 | 0x10, | ||
117 | 0x38, | ||
118 | 0x7c, | ||
119 | 0xfe, | ||
120 | 0xfe, | ||
121 | 0x54, | ||
122 | 0x10, | ||
123 | 0x10, | ||
124 | 0x38, | ||
125 | 0x7c, | ||
126 | 0x00, | ||
127 | 0x00, | ||
128 | 0x00, | ||
129 | 0x00, | ||
130 | |||
131 | 0x00, | ||
132 | 0x00, | ||
133 | 0x00, | ||
134 | 0x00, | ||
135 | 0x00, | ||
136 | 0x00, | ||
137 | 0x18, | ||
138 | 0x3c, | ||
139 | 0x3c, | ||
140 | 0x18, | ||
141 | 0x00, | ||
142 | 0x00, | ||
143 | 0x00, | ||
144 | 0x00, | ||
145 | 0x00, | ||
146 | 0x00, | ||
147 | |||
148 | 0xff, | ||
149 | 0xff, | ||
150 | 0xff, | ||
151 | 0xff, | ||
152 | 0xff, | ||
153 | 0xff, | ||
154 | 0xe7, | ||
155 | 0xc3, | ||
156 | 0xc3, | ||
157 | 0xe7, | ||
158 | 0xff, | ||
159 | 0xff, | ||
160 | 0xff, | ||
161 | 0xff, | ||
162 | 0xff, | ||
163 | 0xff, | ||
164 | |||
165 | 0x00, | ||
166 | 0x00, | ||
167 | 0x00, | ||
168 | 0x00, | ||
169 | 0x00, | ||
170 | 0x3c, | ||
171 | 0x66, | ||
172 | 0x42, | ||
173 | 0x42, | ||
174 | 0x66, | ||
175 | 0x3c, | ||
176 | 0x00, | ||
177 | 0x00, | ||
178 | 0x00, | ||
179 | 0x00, | ||
180 | 0x00, | ||
181 | |||
182 | 0xff, | ||
183 | 0xff, | ||
184 | 0xff, | ||
185 | 0xff, | ||
186 | 0xff, | ||
187 | 0xc3, | ||
188 | 0x99, | ||
189 | 0xbd, | ||
190 | 0xbd, | ||
191 | 0x99, | ||
192 | 0xc3, | ||
193 | 0xff, | ||
194 | 0xff, | ||
195 | 0xff, | ||
196 | 0xff, | ||
197 | 0xff, | ||
198 | |||
199 | 0x00, | ||
200 | 0x00, | ||
201 | 0x0f, | ||
202 | 0x07, | ||
203 | 0x0d, | ||
204 | 0x18, | ||
205 | 0x78, | ||
206 | 0xcc, | ||
207 | 0xcc, | ||
208 | 0xcc, | ||
209 | 0xcc, | ||
210 | 0x78, | ||
211 | 0x00, | ||
212 | 0x00, | ||
213 | 0x00, | ||
214 | 0x00, | ||
215 | |||
216 | 0x00, | ||
217 | 0x00, | ||
218 | 0x3c, | ||
219 | 0x66, | ||
220 | 0x66, | ||
221 | 0x66, | ||
222 | 0x3c, | ||
223 | 0x18, | ||
224 | 0x7e, | ||
225 | 0x18, | ||
226 | 0x18, | ||
227 | 0x18, | ||
228 | 0x00, | ||
229 | 0x00, | ||
230 | 0x00, | ||
231 | 0x00, | ||
232 | |||
233 | 0x00, | ||
234 | 0x08, | ||
235 | 0x0c, | ||
236 | 0x0a, | ||
237 | 0x0a, | ||
238 | 0x0a, | ||
239 | 0x08, | ||
240 | 0x08, | ||
241 | 0x08, | ||
242 | 0x38, | ||
243 | 0x78, | ||
244 | 0x30, | ||
245 | 0x00, | ||
246 | 0x00, | ||
247 | 0x00, | ||
248 | 0x00, | ||
249 | |||
250 | 0x00, | ||
251 | 0x10, | ||
252 | 0x18, | ||
253 | 0x1c, | ||
254 | 0x1e, | ||
255 | 0x1e, | ||
256 | 0x16, | ||
257 | 0x12, | ||
258 | 0x72, | ||
259 | 0xf2, | ||
260 | 0x62, | ||
261 | 0x0e, | ||
262 | 0x1e, | ||
263 | 0x0c, | ||
264 | 0x00, | ||
265 | 0x00, | ||
266 | |||
267 | 0x00, | ||
268 | 0x00, | ||
269 | 0x00, | ||
270 | 0x10, | ||
271 | 0x92, | ||
272 | 0x54, | ||
273 | 0x38, | ||
274 | 0xfe, | ||
275 | 0x38, | ||
276 | 0x54, | ||
277 | 0x92, | ||
278 | 0x10, | ||
279 | 0x00, | ||
280 | 0x00, | ||
281 | 0x00, | ||
282 | 0x00, | ||
283 | |||
284 | 0x00, | ||
285 | 0x00, | ||
286 | 0x00, | ||
287 | 0x80, | ||
288 | 0xc0, | ||
289 | 0xe0, | ||
290 | 0xb8, | ||
291 | 0x8e, | ||
292 | 0xb8, | ||
293 | 0xe0, | ||
294 | 0xc0, | ||
295 | 0x80, | ||
296 | 0x00, | ||
297 | 0x00, | ||
298 | 0x00, | ||
299 | 0x00, | ||
300 | |||
301 | 0x00, | ||
302 | 0x00, | ||
303 | 0x00, | ||
304 | 0x02, | ||
305 | 0x06, | ||
306 | 0x0e, | ||
307 | 0x3a, | ||
308 | 0xe2, | ||
309 | 0x3a, | ||
310 | 0x0e, | ||
311 | 0x06, | ||
312 | 0x02, | ||
313 | 0x00, | ||
314 | 0x00, | ||
315 | 0x00, | ||
316 | 0x00, | ||
317 | |||
318 | 0x00, | ||
319 | 0x00, | ||
320 | 0x10, | ||
321 | 0x38, | ||
322 | 0x7c, | ||
323 | 0xd6, | ||
324 | 0x10, | ||
325 | 0x10, | ||
326 | 0x10, | ||
327 | 0x10, | ||
328 | 0xd6, | ||
329 | 0x7c, | ||
330 | 0x38, | ||
331 | 0x10, | ||
332 | 0x00, | ||
333 | 0x00, | ||
334 | |||
335 | 0x00, | ||
336 | 0x42, | ||
337 | 0xe7, | ||
338 | 0xe7, | ||
339 | 0xe7, | ||
340 | 0xe7, | ||
341 | 0x42, | ||
342 | 0x42, | ||
343 | 0x42, | ||
344 | 0x00, | ||
345 | 0x66, | ||
346 | 0x66, | ||
347 | 0x66, | ||
348 | 0x00, | ||
349 | 0x00, | ||
350 | 0x00, | ||
351 | |||
352 | 0x00, | ||
353 | 0x7f, | ||
354 | 0xca, | ||
355 | 0xca, | ||
356 | 0xca, | ||
357 | 0xca, | ||
358 | 0x7a, | ||
359 | 0x0a, | ||
360 | 0x0a, | ||
361 | 0x0a, | ||
362 | 0x0a, | ||
363 | 0x0a, | ||
364 | 0x1b, | ||
365 | 0x00, | ||
366 | 0x00, | ||
367 | 0x00, | ||
368 | |||
369 | 0x00, | ||
370 | 0x1e, | ||
371 | 0x31, | ||
372 | 0x78, | ||
373 | 0xcc, | ||
374 | 0xc6, | ||
375 | 0xc3, | ||
376 | 0x63, | ||
377 | 0x33, | ||
378 | 0x1e, | ||
379 | 0x8c, | ||
380 | 0x78, | ||
381 | 0x00, | ||
382 | 0x00, | ||
383 | 0x00, | ||
384 | 0x00, | ||
385 | |||
386 | 0x00, | ||
387 | 0x00, | ||
388 | 0x00, | ||
389 | 0x00, | ||
390 | 0x00, | ||
391 | 0x00, | ||
392 | 0x00, | ||
393 | 0x00, | ||
394 | 0xfe, | ||
395 | 0xfe, | ||
396 | 0xfe, | ||
397 | 0xfe, | ||
398 | 0x00, | ||
399 | 0x00, | ||
400 | 0x00, | ||
401 | 0x00, | ||
402 | |||
403 | 0x00, | ||
404 | 0x00, | ||
405 | 0x10, | ||
406 | 0x38, | ||
407 | 0x7c, | ||
408 | 0xd6, | ||
409 | 0x10, | ||
410 | 0x10, | ||
411 | 0x10, | ||
412 | 0x10, | ||
413 | 0xd6, | ||
414 | 0x7c, | ||
415 | 0x38, | ||
416 | 0x10, | ||
417 | 0xfe, | ||
418 | 0x00, | ||
419 | |||
420 | 0x00, | ||
421 | 0x00, | ||
422 | 0x10, | ||
423 | 0x38, | ||
424 | 0x7c, | ||
425 | 0xd6, | ||
426 | 0x10, | ||
427 | 0x10, | ||
428 | 0x10, | ||
429 | 0x10, | ||
430 | 0x10, | ||
431 | 0x10, | ||
432 | 0x10, | ||
433 | 0x10, | ||
434 | 0x00, | ||
435 | 0x00, | ||
436 | |||
437 | 0x00, | ||
438 | 0x00, | ||
439 | 0x10, | ||
440 | 0x10, | ||
441 | 0x10, | ||
442 | 0x10, | ||
443 | 0x10, | ||
444 | 0x10, | ||
445 | 0x10, | ||
446 | 0x10, | ||
447 | 0xd6, | ||
448 | 0x7c, | ||
449 | 0x38, | ||
450 | 0x10, | ||
451 | 0x00, | ||
452 | 0x00, | ||
453 | |||
454 | 0x00, | ||
455 | 0x00, | ||
456 | 0x00, | ||
457 | 0x00, | ||
458 | 0x00, | ||
459 | 0x08, | ||
460 | 0x0c, | ||
461 | 0x06, | ||
462 | 0xff, | ||
463 | 0x06, | ||
464 | 0x0c, | ||
465 | 0x08, | ||
466 | 0x00, | ||
467 | 0x00, | ||
468 | 0x00, | ||
469 | 0x00, | ||
470 | |||
471 | 0x00, | ||
472 | 0x00, | ||
473 | 0x00, | ||
474 | 0x00, | ||
475 | 0x00, | ||
476 | 0x10, | ||
477 | 0x30, | ||
478 | 0x60, | ||
479 | 0xff, | ||
480 | 0x60, | ||
481 | 0x30, | ||
482 | 0x10, | ||
483 | 0x00, | ||
484 | 0x00, | ||
485 | 0x00, | ||
486 | 0x00, | ||
487 | |||
488 | 0x22, | ||
489 | 0x44, | ||
490 | 0x88, | ||
491 | 0xcc, | ||
492 | 0xee, | ||
493 | 0x44, | ||
494 | 0x00, | ||
495 | 0x00, | ||
496 | 0x00, | ||
497 | 0x00, | ||
498 | 0x00, | ||
499 | 0x00, | ||
500 | 0x00, | ||
501 | 0x00, | ||
502 | 0x00, | ||
503 | 0x00, | ||
504 | |||
505 | 0x00, | ||
506 | 0x00, | ||
507 | 0x00, | ||
508 | 0x00, | ||
509 | 0x00, | ||
510 | 0x24, | ||
511 | 0x42, | ||
512 | 0xff, | ||
513 | 0x42, | ||
514 | 0x24, | ||
515 | 0x00, | ||
516 | 0x00, | ||
517 | 0x00, | ||
518 | 0x00, | ||
519 | 0x00, | ||
520 | 0x00, | ||
521 | |||
522 | 0x00, | ||
523 | 0x00, | ||
524 | 0x00, | ||
525 | 0x10, | ||
526 | 0x38, | ||
527 | 0x38, | ||
528 | 0x6c, | ||
529 | 0x6c, | ||
530 | 0xc6, | ||
531 | 0xfe, | ||
532 | 0x00, | ||
533 | 0x00, | ||
534 | 0x00, | ||
535 | 0x00, | ||
536 | 0x00, | ||
537 | 0x00, | ||
538 | |||
539 | 0x00, | ||
540 | 0x00, | ||
541 | 0x00, | ||
542 | 0xfe, | ||
543 | 0xc6, | ||
544 | 0x6c, | ||
545 | 0x6c, | ||
546 | 0x38, | ||
547 | 0x38, | ||
548 | 0x10, | ||
549 | 0x00, | ||
550 | 0x00, | ||
551 | 0x00, | ||
552 | 0x00, | ||
553 | 0x00, | ||
554 | 0x00, | ||
555 | |||
556 | 0x00, | ||
557 | 0x00, | ||
558 | 0x00, | ||
559 | 0x00, | ||
560 | 0x00, | ||
561 | 0x00, | ||
562 | 0x00, | ||
563 | 0x00, | ||
564 | 0x00, | ||
565 | 0x00, | ||
566 | 0x00, | ||
567 | 0x00, | ||
568 | 0x00, | ||
569 | 0x00, | ||
570 | 0x00, | ||
571 | 0x00, | ||
572 | |||
573 | 0x00, | ||
574 | 0x18, | ||
575 | 0x3c, | ||
576 | 0x3c, | ||
577 | 0x3c, | ||
578 | 0x3c, | ||
579 | 0x18, | ||
580 | 0x18, | ||
581 | 0x18, | ||
582 | 0x10, | ||
583 | 0x00, | ||
584 | 0x18, | ||
585 | 0x18, | ||
586 | 0x00, | ||
587 | 0x00, | ||
588 | 0x00, | ||
589 | |||
590 | 0x22, | ||
591 | 0x77, | ||
592 | 0x33, | ||
593 | 0x11, | ||
594 | 0x22, | ||
595 | 0x44, | ||
596 | 0x00, | ||
597 | 0x00, | ||
598 | 0x00, | ||
599 | 0x00, | ||
600 | 0x00, | ||
601 | 0x00, | ||
602 | 0x00, | ||
603 | 0x00, | ||
604 | 0x00, | ||
605 | 0x00, | ||
606 | |||
607 | 0x00, | ||
608 | 0x00, | ||
609 | 0x12, | ||
610 | 0x12, | ||
611 | 0x12, | ||
612 | 0x7f, | ||
613 | 0x24, | ||
614 | 0x24, | ||
615 | 0x24, | ||
616 | 0xfe, | ||
617 | 0x48, | ||
618 | 0x48, | ||
619 | 0x48, | ||
620 | 0x00, | ||
621 | 0x00, | ||
622 | 0x00, | ||
623 | |||
624 | 0x10, | ||
625 | 0x10, | ||
626 | 0x7c, | ||
627 | 0xd2, | ||
628 | 0xd0, | ||
629 | 0xd0, | ||
630 | 0xd0, | ||
631 | 0x7c, | ||
632 | 0x16, | ||
633 | 0x16, | ||
634 | 0x16, | ||
635 | 0x96, | ||
636 | 0x7c, | ||
637 | 0x10, | ||
638 | 0x10, | ||
639 | 0x00, | ||
640 | |||
641 | 0x00, | ||
642 | 0x42, | ||
643 | 0xbe, | ||
644 | 0x44, | ||
645 | 0x0c, | ||
646 | 0x08, | ||
647 | 0x18, | ||
648 | 0x10, | ||
649 | 0x30, | ||
650 | 0x20, | ||
651 | 0x64, | ||
652 | 0x4a, | ||
653 | 0xc4, | ||
654 | 0x00, | ||
655 | 0x00, | ||
656 | 0x00, | ||
657 | |||
658 | 0x00, | ||
659 | 0x38, | ||
660 | 0x6c, | ||
661 | 0x6c, | ||
662 | 0x6c, | ||
663 | 0x38, | ||
664 | 0x37, | ||
665 | 0x72, | ||
666 | 0xdc, | ||
667 | 0xcc, | ||
668 | 0xcc, | ||
669 | 0xcc, | ||
670 | 0x77, | ||
671 | 0x00, | ||
672 | 0x00, | ||
673 | 0x00, | ||
674 | |||
675 | 0x10, | ||
676 | 0x38, | ||
677 | 0x18, | ||
678 | 0x08, | ||
679 | 0x10, | ||
680 | 0x20, | ||
681 | 0x00, | ||
682 | 0x00, | ||
683 | 0x00, | ||
684 | 0x00, | ||
685 | 0x00, | ||
686 | 0x00, | ||
687 | 0x00, | ||
688 | 0x00, | ||
689 | 0x00, | ||
690 | 0x00, | ||
691 | |||
692 | 0x00, | ||
693 | 0x04, | ||
694 | 0x08, | ||
695 | 0x10, | ||
696 | 0x10, | ||
697 | 0x30, | ||
698 | 0x30, | ||
699 | 0x30, | ||
700 | 0x30, | ||
701 | 0x30, | ||
702 | 0x10, | ||
703 | 0x10, | ||
704 | 0x08, | ||
705 | 0x04, | ||
706 | 0x00, | ||
707 | 0x00, | ||
708 | |||
709 | 0x00, | ||
710 | 0x20, | ||
711 | 0x10, | ||
712 | 0x08, | ||
713 | 0x08, | ||
714 | 0x0c, | ||
715 | 0x0c, | ||
716 | 0x0c, | ||
717 | 0x0c, | ||
718 | 0x0c, | ||
719 | 0x08, | ||
720 | 0x08, | ||
721 | 0x10, | ||
722 | 0x20, | ||
723 | 0x00, | ||
724 | 0x00, | ||
725 | |||
726 | 0x00, | ||
727 | 0x00, | ||
728 | 0x00, | ||
729 | 0x00, | ||
730 | 0x44, | ||
731 | 0x28, | ||
732 | 0x38, | ||
733 | 0xfe, | ||
734 | 0x38, | ||
735 | 0x28, | ||
736 | 0x44, | ||
737 | 0x00, | ||
738 | 0x00, | ||
739 | 0x00, | ||
740 | 0x00, | ||
741 | 0x00, | ||
742 | |||
743 | 0x00, | ||
744 | 0x00, | ||
745 | 0x00, | ||
746 | 0x00, | ||
747 | 0x00, | ||
748 | 0x18, | ||
749 | 0x18, | ||
750 | 0x7e, | ||
751 | 0x18, | ||
752 | 0x18, | ||
753 | 0x00, | ||
754 | 0x00, | ||
755 | 0x00, | ||
756 | 0x00, | ||
757 | 0x00, | ||
758 | 0x00, | ||
759 | |||
760 | 0x00, | ||
761 | 0x00, | ||
762 | 0x00, | ||
763 | 0x00, | ||
764 | 0x00, | ||
765 | 0x00, | ||
766 | 0x00, | ||
767 | 0x00, | ||
768 | 0x00, | ||
769 | 0x00, | ||
770 | 0x10, | ||
771 | 0x38, | ||
772 | 0x18, | ||
773 | 0x08, | ||
774 | 0x10, | ||
775 | 0x20, | ||
776 | |||
777 | 0x00, | ||
778 | 0x00, | ||
779 | 0x00, | ||
780 | 0x00, | ||
781 | 0x00, | ||
782 | 0x00, | ||
783 | 0x00, | ||
784 | 0x7e, | ||
785 | 0x00, | ||
786 | 0x00, | ||
787 | 0x00, | ||
788 | 0x00, | ||
789 | 0x00, | ||
790 | 0x00, | ||
791 | 0x00, | ||
792 | 0x00, | ||
793 | |||
794 | 0x00, | ||
795 | 0x00, | ||
796 | 0x00, | ||
797 | 0x00, | ||
798 | 0x00, | ||
799 | 0x00, | ||
800 | 0x00, | ||
801 | 0x00, | ||
802 | 0x00, | ||
803 | 0x00, | ||
804 | 0x10, | ||
805 | 0x38, | ||
806 | 0x10, | ||
807 | 0x00, | ||
808 | 0x00, | ||
809 | 0x00, | ||
810 | |||
811 | 0x00, | ||
812 | 0x06, | ||
813 | 0x06, | ||
814 | 0x0c, | ||
815 | 0x0c, | ||
816 | 0x18, | ||
817 | 0x18, | ||
818 | 0x30, | ||
819 | 0x30, | ||
820 | 0x60, | ||
821 | 0x60, | ||
822 | 0xc0, | ||
823 | 0xc0, | ||
824 | 0x00, | ||
825 | 0x00, | ||
826 | 0x00, | ||
827 | |||
828 | 0x00, | ||
829 | 0x00, | ||
830 | 0x00, | ||
831 | 0x00, | ||
832 | 0x3c, | ||
833 | 0x46, | ||
834 | 0xc6, | ||
835 | 0xc6, | ||
836 | 0xc6, | ||
837 | 0xc6, | ||
838 | 0xc6, | ||
839 | 0xc4, | ||
840 | 0x78, | ||
841 | 0x00, | ||
842 | 0x00, | ||
843 | 0x00, | ||
844 | |||
845 | 0x00, | ||
846 | 0x00, | ||
847 | 0x00, | ||
848 | 0x00, | ||
849 | 0x08, | ||
850 | 0x18, | ||
851 | 0x78, | ||
852 | 0x18, | ||
853 | 0x18, | ||
854 | 0x18, | ||
855 | 0x18, | ||
856 | 0x18, | ||
857 | 0x7e, | ||
858 | 0x00, | ||
859 | 0x00, | ||
860 | 0x00, | ||
861 | |||
862 | 0x00, | ||
863 | 0x00, | ||
864 | 0x00, | ||
865 | 0x00, | ||
866 | 0x7c, | ||
867 | 0x86, | ||
868 | 0x06, | ||
869 | 0x0c, | ||
870 | 0x18, | ||
871 | 0x20, | ||
872 | 0x40, | ||
873 | 0xc1, | ||
874 | 0xfe, | ||
875 | 0x00, | ||
876 | 0x00, | ||
877 | 0x00, | ||
878 | |||
879 | 0x00, | ||
880 | 0x00, | ||
881 | 0x00, | ||
882 | 0x00, | ||
883 | 0x3c, | ||
884 | 0x46, | ||
885 | 0x04, | ||
886 | 0x08, | ||
887 | 0x1c, | ||
888 | 0x06, | ||
889 | 0x06, | ||
890 | 0x06, | ||
891 | 0x06, | ||
892 | 0x0c, | ||
893 | 0x70, | ||
894 | 0x00, | ||
895 | |||
896 | 0x00, | ||
897 | 0x00, | ||
898 | 0x00, | ||
899 | 0x00, | ||
900 | 0x04, | ||
901 | 0x08, | ||
902 | 0x10, | ||
903 | 0x2c, | ||
904 | 0x4c, | ||
905 | 0x8c, | ||
906 | 0x8c, | ||
907 | 0xfe, | ||
908 | 0x0c, | ||
909 | 0x0c, | ||
910 | 0x0c, | ||
911 | 0x00, | ||
912 | |||
913 | 0x00, | ||
914 | 0x00, | ||
915 | 0x00, | ||
916 | 0x02, | ||
917 | 0x3c, | ||
918 | 0x20, | ||
919 | 0x20, | ||
920 | 0x70, | ||
921 | 0x0c, | ||
922 | 0x06, | ||
923 | 0x06, | ||
924 | 0x06, | ||
925 | 0x06, | ||
926 | 0x0c, | ||
927 | 0x70, | ||
928 | 0x00, | ||
929 | |||
930 | 0x00, | ||
931 | 0x00, | ||
932 | 0x18, | ||
933 | 0x20, | ||
934 | 0x40, | ||
935 | 0xc0, | ||
936 | 0xdc, | ||
937 | 0xc6, | ||
938 | 0xc6, | ||
939 | 0xc6, | ||
940 | 0xc6, | ||
941 | 0x44, | ||
942 | 0x38, | ||
943 | 0x00, | ||
944 | 0x00, | ||
945 | 0x00, | ||
946 | |||
947 | 0x00, | ||
948 | 0x00, | ||
949 | 0x00, | ||
950 | 0x40, | ||
951 | 0x7e, | ||
952 | 0x82, | ||
953 | 0x06, | ||
954 | 0x04, | ||
955 | 0x0c, | ||
956 | 0x18, | ||
957 | 0x18, | ||
958 | 0x30, | ||
959 | 0x30, | ||
960 | 0x30, | ||
961 | 0x30, | ||
962 | 0x00, | ||
963 | |||
964 | 0x00, | ||
965 | 0x00, | ||
966 | 0x7c, | ||
967 | 0xc6, | ||
968 | 0xc6, | ||
969 | 0x64, | ||
970 | 0x38, | ||
971 | 0x4c, | ||
972 | 0xc6, | ||
973 | 0xc6, | ||
974 | 0xc6, | ||
975 | 0xc6, | ||
976 | 0x7c, | ||
977 | 0x00, | ||
978 | 0x00, | ||
979 | 0x00, | ||
980 | |||
981 | 0x00, | ||
982 | 0x00, | ||
983 | 0x00, | ||
984 | 0x00, | ||
985 | 0x38, | ||
986 | 0x44, | ||
987 | 0xc6, | ||
988 | 0xc6, | ||
989 | 0x76, | ||
990 | 0x06, | ||
991 | 0x06, | ||
992 | 0x06, | ||
993 | 0x04, | ||
994 | 0x08, | ||
995 | 0x30, | ||
996 | 0x00, | ||
997 | |||
998 | 0x00, | ||
999 | 0x00, | ||
1000 | 0x00, | ||
1001 | 0x00, | ||
1002 | 0x10, | ||
1003 | 0x38, | ||
1004 | 0x10, | ||
1005 | 0x00, | ||
1006 | 0x00, | ||
1007 | 0x00, | ||
1008 | 0x10, | ||
1009 | 0x38, | ||
1010 | 0x10, | ||
1011 | 0x00, | ||
1012 | 0x00, | ||
1013 | 0x00, | ||
1014 | |||
1015 | 0x00, | ||
1016 | 0x00, | ||
1017 | 0x00, | ||
1018 | 0x00, | ||
1019 | 0x10, | ||
1020 | 0x38, | ||
1021 | 0x10, | ||
1022 | 0x00, | ||
1023 | 0x00, | ||
1024 | 0x00, | ||
1025 | 0x10, | ||
1026 | 0x38, | ||
1027 | 0x18, | ||
1028 | 0x08, | ||
1029 | 0x10, | ||
1030 | 0x20, | ||
1031 | |||
1032 | 0x00, | ||
1033 | 0x06, | ||
1034 | 0x0c, | ||
1035 | 0x18, | ||
1036 | 0x30, | ||
1037 | 0x60, | ||
1038 | 0xa0, | ||
1039 | 0xa0, | ||
1040 | 0x60, | ||
1041 | 0x30, | ||
1042 | 0x18, | ||
1043 | 0x0c, | ||
1044 | 0x06, | ||
1045 | 0x00, | ||
1046 | 0x00, | ||
1047 | 0x00, | ||
1048 | |||
1049 | 0x00, | ||
1050 | 0x00, | ||
1051 | 0x00, | ||
1052 | 0x00, | ||
1053 | 0x00, | ||
1054 | 0x7e, | ||
1055 | 0x00, | ||
1056 | 0x00, | ||
1057 | 0x7e, | ||
1058 | 0x00, | ||
1059 | 0x00, | ||
1060 | 0x00, | ||
1061 | 0x00, | ||
1062 | 0x00, | ||
1063 | 0x00, | ||
1064 | 0x00, | ||
1065 | |||
1066 | 0x00, | ||
1067 | 0x60, | ||
1068 | 0x30, | ||
1069 | 0x18, | ||
1070 | 0x0c, | ||
1071 | 0x06, | ||
1072 | 0x05, | ||
1073 | 0x05, | ||
1074 | 0x06, | ||
1075 | 0x0c, | ||
1076 | 0x18, | ||
1077 | 0x30, | ||
1078 | 0x60, | ||
1079 | 0x00, | ||
1080 | 0x00, | ||
1081 | 0x00, | ||
1082 | |||
1083 | 0x00, | ||
1084 | 0x7c, | ||
1085 | 0x86, | ||
1086 | 0xc6, | ||
1087 | 0x06, | ||
1088 | 0x04, | ||
1089 | 0x08, | ||
1090 | 0x10, | ||
1091 | 0x10, | ||
1092 | 0x18, | ||
1093 | 0x00, | ||
1094 | 0x18, | ||
1095 | 0x18, | ||
1096 | 0x00, | ||
1097 | 0x00, | ||
1098 | 0x00, | ||
1099 | |||
1100 | 0x00, | ||
1101 | 0x00, | ||
1102 | 0x3c, | ||
1103 | 0x46, | ||
1104 | 0xc6, | ||
1105 | 0xce, | ||
1106 | 0xd6, | ||
1107 | 0xd6, | ||
1108 | 0xd6, | ||
1109 | 0xdc, | ||
1110 | 0xc0, | ||
1111 | 0xc4, | ||
1112 | 0x78, | ||
1113 | 0x00, | ||
1114 | 0x00, | ||
1115 | 0x00, | ||
1116 | |||
1117 | 0x00, | ||
1118 | 0x18, | ||
1119 | 0x18, | ||
1120 | 0x18, | ||
1121 | 0x3c, | ||
1122 | 0x2c, | ||
1123 | 0x2c, | ||
1124 | 0x2c, | ||
1125 | 0x7e, | ||
1126 | 0x46, | ||
1127 | 0x46, | ||
1128 | 0x46, | ||
1129 | 0xef, | ||
1130 | 0x00, | ||
1131 | 0x00, | ||
1132 | 0x00, | ||
1133 | |||
1134 | 0x00, | ||
1135 | 0xfc, | ||
1136 | 0x66, | ||
1137 | 0x66, | ||
1138 | 0x66, | ||
1139 | 0x66, | ||
1140 | 0x7c, | ||
1141 | 0x66, | ||
1142 | 0x66, | ||
1143 | 0x66, | ||
1144 | 0x66, | ||
1145 | 0x66, | ||
1146 | 0xfc, | ||
1147 | 0x00, | ||
1148 | 0x00, | ||
1149 | 0x00, | ||
1150 | |||
1151 | 0x00, | ||
1152 | 0x3a, | ||
1153 | 0x66, | ||
1154 | 0xc2, | ||
1155 | 0xc0, | ||
1156 | 0xc0, | ||
1157 | 0xc0, | ||
1158 | 0xc0, | ||
1159 | 0xc0, | ||
1160 | 0xc0, | ||
1161 | 0xc0, | ||
1162 | 0x62, | ||
1163 | 0x3c, | ||
1164 | 0x00, | ||
1165 | 0x00, | ||
1166 | 0x00, | ||
1167 | |||
1168 | 0x00, | ||
1169 | 0xfc, | ||
1170 | 0x66, | ||
1171 | 0x63, | ||
1172 | 0x63, | ||
1173 | 0x63, | ||
1174 | 0x63, | ||
1175 | 0x63, | ||
1176 | 0x63, | ||
1177 | 0x63, | ||
1178 | 0x63, | ||
1179 | 0x66, | ||
1180 | 0xfc, | ||
1181 | 0x00, | ||
1182 | 0x00, | ||
1183 | 0x00, | ||
1184 | |||
1185 | 0x00, | ||
1186 | 0xff, | ||
1187 | 0x61, | ||
1188 | 0x60, | ||
1189 | 0x60, | ||
1190 | 0x64, | ||
1191 | 0x7c, | ||
1192 | 0x64, | ||
1193 | 0x60, | ||
1194 | 0x60, | ||
1195 | 0x60, | ||
1196 | 0x61, | ||
1197 | 0xfe, | ||
1198 | 0x00, | ||
1199 | 0x00, | ||
1200 | 0x00, | ||
1201 | |||
1202 | 0x00, | ||
1203 | 0xff, | ||
1204 | 0x61, | ||
1205 | 0x61, | ||
1206 | 0x60, | ||
1207 | 0x64, | ||
1208 | 0x7c, | ||
1209 | 0x64, | ||
1210 | 0x60, | ||
1211 | 0x60, | ||
1212 | 0x60, | ||
1213 | 0x60, | ||
1214 | 0xf0, | ||
1215 | 0x00, | ||
1216 | 0x00, | ||
1217 | 0x00, | ||
1218 | |||
1219 | 0x00, | ||
1220 | 0x3a, | ||
1221 | 0x66, | ||
1222 | 0xc2, | ||
1223 | 0xc0, | ||
1224 | 0xc0, | ||
1225 | 0xc0, | ||
1226 | 0xcf, | ||
1227 | 0xc6, | ||
1228 | 0xc6, | ||
1229 | 0xc6, | ||
1230 | 0x66, | ||
1231 | 0x38, | ||
1232 | 0x00, | ||
1233 | 0x00, | ||
1234 | 0x00, | ||
1235 | |||
1236 | 0x00, | ||
1237 | 0xf7, | ||
1238 | 0x62, | ||
1239 | 0x62, | ||
1240 | 0x62, | ||
1241 | 0x62, | ||
1242 | 0x7e, | ||
1243 | 0x62, | ||
1244 | 0x62, | ||
1245 | 0x62, | ||
1246 | 0x62, | ||
1247 | 0x62, | ||
1248 | 0xf7, | ||
1249 | 0x00, | ||
1250 | 0x00, | ||
1251 | 0x00, | ||
1252 | |||
1253 | 0x00, | ||
1254 | 0x3c, | ||
1255 | 0x18, | ||
1256 | 0x18, | ||
1257 | 0x18, | ||
1258 | 0x18, | ||
1259 | 0x18, | ||
1260 | 0x18, | ||
1261 | 0x18, | ||
1262 | 0x18, | ||
1263 | 0x18, | ||
1264 | 0x18, | ||
1265 | 0x3c, | ||
1266 | 0x00, | ||
1267 | 0x00, | ||
1268 | 0x00, | ||
1269 | |||
1270 | 0x00, | ||
1271 | 0x1e, | ||
1272 | 0x0c, | ||
1273 | 0x0c, | ||
1274 | 0x0c, | ||
1275 | 0x0c, | ||
1276 | 0x0c, | ||
1277 | 0x0c, | ||
1278 | 0x0c, | ||
1279 | 0x0c, | ||
1280 | 0x0c, | ||
1281 | 0x0c, | ||
1282 | 0x0c, | ||
1283 | 0x0c, | ||
1284 | 0x08, | ||
1285 | 0xf0, | ||
1286 | |||
1287 | 0x00, | ||
1288 | 0xf7, | ||
1289 | 0x64, | ||
1290 | 0x6c, | ||
1291 | 0x68, | ||
1292 | 0x68, | ||
1293 | 0x78, | ||
1294 | 0x6c, | ||
1295 | 0x6c, | ||
1296 | 0x6c, | ||
1297 | 0x66, | ||
1298 | 0x66, | ||
1299 | 0xf7, | ||
1300 | 0x00, | ||
1301 | 0x00, | ||
1302 | 0x00, | ||
1303 | |||
1304 | 0x00, | ||
1305 | 0xf8, | ||
1306 | 0x60, | ||
1307 | 0x60, | ||
1308 | 0x60, | ||
1309 | 0x60, | ||
1310 | 0x60, | ||
1311 | 0x60, | ||
1312 | 0x60, | ||
1313 | 0x60, | ||
1314 | 0x60, | ||
1315 | 0x61, | ||
1316 | 0xfe, | ||
1317 | 0x00, | ||
1318 | 0x00, | ||
1319 | 0x00, | ||
1320 | |||
1321 | 0x00, | ||
1322 | 0xc3, | ||
1323 | 0x66, | ||
1324 | 0x76, | ||
1325 | 0x7e, | ||
1326 | 0x56, | ||
1327 | 0x56, | ||
1328 | 0x46, | ||
1329 | 0x46, | ||
1330 | 0x46, | ||
1331 | 0x46, | ||
1332 | 0x46, | ||
1333 | 0xef, | ||
1334 | 0x00, | ||
1335 | 0x00, | ||
1336 | 0x00, | ||
1337 | |||
1338 | 0x00, | ||
1339 | 0xe7, | ||
1340 | 0x62, | ||
1341 | 0x62, | ||
1342 | 0x72, | ||
1343 | 0x52, | ||
1344 | 0x5a, | ||
1345 | 0x4a, | ||
1346 | 0x4e, | ||
1347 | 0x46, | ||
1348 | 0x46, | ||
1349 | 0x42, | ||
1350 | 0xe2, | ||
1351 | 0x00, | ||
1352 | 0x00, | ||
1353 | 0x00, | ||
1354 | |||
1355 | 0x00, | ||
1356 | 0x3c, | ||
1357 | 0x66, | ||
1358 | 0xc3, | ||
1359 | 0xc3, | ||
1360 | 0xc3, | ||
1361 | 0xc3, | ||
1362 | 0xc3, | ||
1363 | 0xc3, | ||
1364 | 0xc3, | ||
1365 | 0xc3, | ||
1366 | 0x66, | ||
1367 | 0x3c, | ||
1368 | 0x00, | ||
1369 | 0x00, | ||
1370 | 0x00, | ||
1371 | |||
1372 | 0x00, | ||
1373 | 0xfc, | ||
1374 | 0x66, | ||
1375 | 0x66, | ||
1376 | 0x66, | ||
1377 | 0x66, | ||
1378 | 0x6c, | ||
1379 | 0x60, | ||
1380 | 0x60, | ||
1381 | 0x60, | ||
1382 | 0x60, | ||
1383 | 0x60, | ||
1384 | 0xf0, | ||
1385 | 0x00, | ||
1386 | 0x00, | ||
1387 | 0x00, | ||
1388 | |||
1389 | 0x00, | ||
1390 | 0x3c, | ||
1391 | 0x66, | ||
1392 | 0xc3, | ||
1393 | 0xc3, | ||
1394 | 0xc3, | ||
1395 | 0xc3, | ||
1396 | 0xc3, | ||
1397 | 0xc3, | ||
1398 | 0xc3, | ||
1399 | 0xc3, | ||
1400 | 0x66, | ||
1401 | 0x3c, | ||
1402 | 0x10, | ||
1403 | 0x39, | ||
1404 | 0x0e, | ||
1405 | |||
1406 | 0x00, | ||
1407 | 0xfc, | ||
1408 | 0x66, | ||
1409 | 0x66, | ||
1410 | 0x66, | ||
1411 | 0x66, | ||
1412 | 0x7c, | ||
1413 | 0x6c, | ||
1414 | 0x66, | ||
1415 | 0x66, | ||
1416 | 0x66, | ||
1417 | 0x66, | ||
1418 | 0xf3, | ||
1419 | 0x00, | ||
1420 | 0x00, | ||
1421 | 0x00, | ||
1422 | |||
1423 | 0x00, | ||
1424 | 0x7a, | ||
1425 | 0xc6, | ||
1426 | 0xc2, | ||
1427 | 0xc0, | ||
1428 | 0x70, | ||
1429 | 0x3c, | ||
1430 | 0x0e, | ||
1431 | 0x06, | ||
1432 | 0x06, | ||
1433 | 0x86, | ||
1434 | 0xc6, | ||
1435 | 0xbc, | ||
1436 | 0x00, | ||
1437 | 0x00, | ||
1438 | 0x00, | ||
1439 | |||
1440 | 0x00, | ||
1441 | 0xff, | ||
1442 | 0x99, | ||
1443 | 0x18, | ||
1444 | 0x18, | ||
1445 | 0x18, | ||
1446 | 0x18, | ||
1447 | 0x18, | ||
1448 | 0x18, | ||
1449 | 0x18, | ||
1450 | 0x18, | ||
1451 | 0x18, | ||
1452 | 0x3c, | ||
1453 | 0x00, | ||
1454 | 0x00, | ||
1455 | 0x00, | ||
1456 | |||
1457 | 0x00, | ||
1458 | 0xf7, | ||
1459 | 0x62, | ||
1460 | 0x62, | ||
1461 | 0x62, | ||
1462 | 0x62, | ||
1463 | 0x62, | ||
1464 | 0x62, | ||
1465 | 0x62, | ||
1466 | 0x62, | ||
1467 | 0x62, | ||
1468 | 0x62, | ||
1469 | 0x3c, | ||
1470 | 0x00, | ||
1471 | 0x00, | ||
1472 | 0x00, | ||
1473 | |||
1474 | 0x00, | ||
1475 | 0xf7, | ||
1476 | 0x62, | ||
1477 | 0x62, | ||
1478 | 0x62, | ||
1479 | 0x76, | ||
1480 | 0x34, | ||
1481 | 0x34, | ||
1482 | 0x34, | ||
1483 | 0x3c, | ||
1484 | 0x18, | ||
1485 | 0x18, | ||
1486 | 0x18, | ||
1487 | 0x00, | ||
1488 | 0x00, | ||
1489 | 0x00, | ||
1490 | |||
1491 | 0x00, | ||
1492 | 0xf7, | ||
1493 | 0x62, | ||
1494 | 0x62, | ||
1495 | 0x62, | ||
1496 | 0x62, | ||
1497 | 0x6a, | ||
1498 | 0x6a, | ||
1499 | 0x6a, | ||
1500 | 0x6a, | ||
1501 | 0x7e, | ||
1502 | 0x7e, | ||
1503 | 0x34, | ||
1504 | 0x00, | ||
1505 | 0x00, | ||
1506 | 0x00, | ||
1507 | |||
1508 | 0x00, | ||
1509 | 0xf7, | ||
1510 | 0x62, | ||
1511 | 0x62, | ||
1512 | 0x34, | ||
1513 | 0x34, | ||
1514 | 0x18, | ||
1515 | 0x18, | ||
1516 | 0x2c, | ||
1517 | 0x2c, | ||
1518 | 0x46, | ||
1519 | 0x46, | ||
1520 | 0xef, | ||
1521 | 0x00, | ||
1522 | 0x00, | ||
1523 | 0x00, | ||
1524 | |||
1525 | 0x00, | ||
1526 | 0xf7, | ||
1527 | 0x62, | ||
1528 | 0x62, | ||
1529 | 0x62, | ||
1530 | 0x34, | ||
1531 | 0x34, | ||
1532 | 0x18, | ||
1533 | 0x18, | ||
1534 | 0x18, | ||
1535 | 0x18, | ||
1536 | 0x18, | ||
1537 | 0x3c, | ||
1538 | 0x00, | ||
1539 | 0x00, | ||
1540 | 0x00, | ||
1541 | |||
1542 | 0x00, | ||
1543 | 0x7f, | ||
1544 | 0x46, | ||
1545 | 0x86, | ||
1546 | 0x0c, | ||
1547 | 0x0c, | ||
1548 | 0x18, | ||
1549 | 0x18, | ||
1550 | 0x30, | ||
1551 | 0x30, | ||
1552 | 0x61, | ||
1553 | 0x62, | ||
1554 | 0xfe, | ||
1555 | 0x00, | ||
1556 | 0x00, | ||
1557 | 0x00, | ||
1558 | |||
1559 | 0x00, | ||
1560 | 0x3c, | ||
1561 | 0x30, | ||
1562 | 0x30, | ||
1563 | 0x30, | ||
1564 | 0x30, | ||
1565 | 0x30, | ||
1566 | 0x30, | ||
1567 | 0x30, | ||
1568 | 0x30, | ||
1569 | 0x30, | ||
1570 | 0x30, | ||
1571 | 0x3c, | ||
1572 | 0x00, | ||
1573 | 0x00, | ||
1574 | 0x00, | ||
1575 | |||
1576 | 0x00, | ||
1577 | 0xc0, | ||
1578 | 0xc0, | ||
1579 | 0x60, | ||
1580 | 0x60, | ||
1581 | 0x30, | ||
1582 | 0x30, | ||
1583 | 0x18, | ||
1584 | 0x18, | ||
1585 | 0x0c, | ||
1586 | 0x0c, | ||
1587 | 0x06, | ||
1588 | 0x06, | ||
1589 | 0x00, | ||
1590 | 0x00, | ||
1591 | 0x00, | ||
1592 | |||
1593 | 0x00, | ||
1594 | 0x3c, | ||
1595 | 0x0c, | ||
1596 | 0x0c, | ||
1597 | 0x0c, | ||
1598 | 0x0c, | ||
1599 | 0x0c, | ||
1600 | 0x0c, | ||
1601 | 0x0c, | ||
1602 | 0x0c, | ||
1603 | 0x0c, | ||
1604 | 0x0c, | ||
1605 | 0x3c, | ||
1606 | 0x00, | ||
1607 | 0x00, | ||
1608 | 0x00, | ||
1609 | |||
1610 | 0x00, | ||
1611 | 0x10, | ||
1612 | 0x38, | ||
1613 | 0x4c, | ||
1614 | 0x86, | ||
1615 | 0x00, | ||
1616 | 0x00, | ||
1617 | 0x00, | ||
1618 | 0x00, | ||
1619 | 0x00, | ||
1620 | 0x00, | ||
1621 | 0x00, | ||
1622 | 0x00, | ||
1623 | 0x00, | ||
1624 | 0x00, | ||
1625 | 0x00, | ||
1626 | |||
1627 | 0x00, | ||
1628 | 0x00, | ||
1629 | 0x00, | ||
1630 | 0x00, | ||
1631 | 0x00, | ||
1632 | 0x00, | ||
1633 | 0x00, | ||
1634 | 0x00, | ||
1635 | 0x00, | ||
1636 | 0x00, | ||
1637 | 0x00, | ||
1638 | 0x00, | ||
1639 | 0x00, | ||
1640 | 0xff, | ||
1641 | 0x00, | ||
1642 | 0x00, | ||
1643 | |||
1644 | 0x00, | ||
1645 | 0x18, | ||
1646 | 0x20, | ||
1647 | 0x30, | ||
1648 | 0x38, | ||
1649 | 0x10, | ||
1650 | 0x00, | ||
1651 | 0x00, | ||
1652 | 0x00, | ||
1653 | 0x00, | ||
1654 | 0x00, | ||
1655 | 0x00, | ||
1656 | 0x00, | ||
1657 | 0x00, | ||
1658 | 0x00, | ||
1659 | 0x00, | ||
1660 | |||
1661 | 0x00, | ||
1662 | 0x00, | ||
1663 | 0x00, | ||
1664 | 0x00, | ||
1665 | 0x00, | ||
1666 | 0x78, | ||
1667 | 0x8c, | ||
1668 | 0x0c, | ||
1669 | 0x3c, | ||
1670 | 0xcc, | ||
1671 | 0xcc, | ||
1672 | 0xcd, | ||
1673 | 0x76, | ||
1674 | 0x00, | ||
1675 | 0x00, | ||
1676 | 0x00, | ||
1677 | |||
1678 | 0x00, | ||
1679 | 0x20, | ||
1680 | 0xe0, | ||
1681 | 0x60, | ||
1682 | 0x60, | ||
1683 | 0x6c, | ||
1684 | 0x76, | ||
1685 | 0x66, | ||
1686 | 0x66, | ||
1687 | 0x66, | ||
1688 | 0x66, | ||
1689 | 0x76, | ||
1690 | 0x6c, | ||
1691 | 0x00, | ||
1692 | 0x00, | ||
1693 | 0x00, | ||
1694 | |||
1695 | 0x00, | ||
1696 | 0x00, | ||
1697 | 0x00, | ||
1698 | 0x00, | ||
1699 | 0x00, | ||
1700 | 0x3c, | ||
1701 | 0x66, | ||
1702 | 0x60, | ||
1703 | 0x60, | ||
1704 | 0x60, | ||
1705 | 0x60, | ||
1706 | 0x62, | ||
1707 | 0x3c, | ||
1708 | 0x00, | ||
1709 | 0x00, | ||
1710 | 0x00, | ||
1711 | |||
1712 | 0x00, | ||
1713 | 0x04, | ||
1714 | 0x1c, | ||
1715 | 0x0c, | ||
1716 | 0x0c, | ||
1717 | 0x6c, | ||
1718 | 0xdc, | ||
1719 | 0xcc, | ||
1720 | 0xcc, | ||
1721 | 0xcc, | ||
1722 | 0xcc, | ||
1723 | 0xdc, | ||
1724 | 0x66, | ||
1725 | 0x00, | ||
1726 | 0x00, | ||
1727 | 0x00, | ||
1728 | |||
1729 | 0x00, | ||
1730 | 0x00, | ||
1731 | 0x00, | ||
1732 | 0x00, | ||
1733 | 0x00, | ||
1734 | 0x3c, | ||
1735 | 0x66, | ||
1736 | 0x7e, | ||
1737 | 0x60, | ||
1738 | 0x60, | ||
1739 | 0x60, | ||
1740 | 0x62, | ||
1741 | 0x3c, | ||
1742 | 0x00, | ||
1743 | 0x00, | ||
1744 | 0x00, | ||
1745 | |||
1746 | 0x00, | ||
1747 | 0x1e, | ||
1748 | 0x31, | ||
1749 | 0x33, | ||
1750 | 0x30, | ||
1751 | 0x30, | ||
1752 | 0x78, | ||
1753 | 0x30, | ||
1754 | 0x30, | ||
1755 | 0x30, | ||
1756 | 0x30, | ||
1757 | 0x30, | ||
1758 | 0x78, | ||
1759 | 0x00, | ||
1760 | 0x00, | ||
1761 | 0x00, | ||
1762 | |||
1763 | 0x00, | ||
1764 | 0x00, | ||
1765 | 0x00, | ||
1766 | 0x00, | ||
1767 | 0x00, | ||
1768 | 0x7b, | ||
1769 | 0xce, | ||
1770 | 0xcc, | ||
1771 | 0xcc, | ||
1772 | 0xcc, | ||
1773 | 0x78, | ||
1774 | 0x60, | ||
1775 | 0x7c, | ||
1776 | 0x86, | ||
1777 | 0xc6, | ||
1778 | 0x7c, | ||
1779 | |||
1780 | 0x00, | ||
1781 | 0x20, | ||
1782 | 0xe0, | ||
1783 | 0x60, | ||
1784 | 0x60, | ||
1785 | 0x6c, | ||
1786 | 0x76, | ||
1787 | 0x66, | ||
1788 | 0x66, | ||
1789 | 0x66, | ||
1790 | 0x66, | ||
1791 | 0x66, | ||
1792 | 0xf7, | ||
1793 | 0x00, | ||
1794 | 0x00, | ||
1795 | 0x00, | ||
1796 | |||
1797 | 0x00, | ||
1798 | 0x10, | ||
1799 | 0x38, | ||
1800 | 0x10, | ||
1801 | 0x00, | ||
1802 | 0x18, | ||
1803 | 0x38, | ||
1804 | 0x18, | ||
1805 | 0x18, | ||
1806 | 0x18, | ||
1807 | 0x18, | ||
1808 | 0x18, | ||
1809 | 0x3c, | ||
1810 | 0x00, | ||
1811 | 0x00, | ||
1812 | 0x00, | ||
1813 | |||
1814 | 0x00, | ||
1815 | 0x08, | ||
1816 | 0x1c, | ||
1817 | 0x08, | ||
1818 | 0x00, | ||
1819 | 0x0c, | ||
1820 | 0x1c, | ||
1821 | 0x0c, | ||
1822 | 0x0c, | ||
1823 | 0x0c, | ||
1824 | 0x0c, | ||
1825 | 0x0c, | ||
1826 | 0x6c, | ||
1827 | 0x4c, | ||
1828 | 0x38, | ||
1829 | 0x00, | ||
1830 | |||
1831 | 0x00, | ||
1832 | 0x20, | ||
1833 | 0xe0, | ||
1834 | 0x60, | ||
1835 | 0x60, | ||
1836 | 0x67, | ||
1837 | 0x66, | ||
1838 | 0x6c, | ||
1839 | 0x78, | ||
1840 | 0x6c, | ||
1841 | 0x6c, | ||
1842 | 0x66, | ||
1843 | 0xe7, | ||
1844 | 0x00, | ||
1845 | 0x00, | ||
1846 | 0x00, | ||
1847 | |||
1848 | 0x00, | ||
1849 | 0x08, | ||
1850 | 0x38, | ||
1851 | 0x18, | ||
1852 | 0x18, | ||
1853 | 0x18, | ||
1854 | 0x18, | ||
1855 | 0x18, | ||
1856 | 0x18, | ||
1857 | 0x18, | ||
1858 | 0x18, | ||
1859 | 0x18, | ||
1860 | 0x3c, | ||
1861 | 0x00, | ||
1862 | 0x00, | ||
1863 | 0x00, | ||
1864 | |||
1865 | 0x00, | ||
1866 | 0x00, | ||
1867 | 0x00, | ||
1868 | 0x00, | ||
1869 | 0x00, | ||
1870 | 0x6a, | ||
1871 | 0xfe, | ||
1872 | 0x6a, | ||
1873 | 0x6a, | ||
1874 | 0x6a, | ||
1875 | 0x62, | ||
1876 | 0x62, | ||
1877 | 0xf7, | ||
1878 | 0x00, | ||
1879 | 0x00, | ||
1880 | 0x00, | ||
1881 | |||
1882 | 0x00, | ||
1883 | 0x00, | ||
1884 | 0x00, | ||
1885 | 0x00, | ||
1886 | 0x00, | ||
1887 | 0x5c, | ||
1888 | 0xf6, | ||
1889 | 0x66, | ||
1890 | 0x66, | ||
1891 | 0x66, | ||
1892 | 0x66, | ||
1893 | 0x66, | ||
1894 | 0xf7, | ||
1895 | 0x00, | ||
1896 | 0x00, | ||
1897 | 0x00, | ||
1898 | |||
1899 | 0x00, | ||
1900 | 0x00, | ||
1901 | 0x00, | ||
1902 | 0x00, | ||
1903 | 0x00, | ||
1904 | 0x3c, | ||
1905 | 0x66, | ||
1906 | 0x66, | ||
1907 | 0x66, | ||
1908 | 0x66, | ||
1909 | 0x66, | ||
1910 | 0x66, | ||
1911 | 0x3c, | ||
1912 | 0x00, | ||
1913 | 0x00, | ||
1914 | 0x00, | ||
1915 | |||
1916 | 0x00, | ||
1917 | 0x00, | ||
1918 | 0x00, | ||
1919 | 0x00, | ||
1920 | 0x00, | ||
1921 | 0x5c, | ||
1922 | 0xe6, | ||
1923 | 0x66, | ||
1924 | 0x66, | ||
1925 | 0x66, | ||
1926 | 0x66, | ||
1927 | 0x66, | ||
1928 | 0x7c, | ||
1929 | 0x60, | ||
1930 | 0x60, | ||
1931 | 0xf0, | ||
1932 | |||
1933 | 0x00, | ||
1934 | 0x00, | ||
1935 | 0x00, | ||
1936 | 0x00, | ||
1937 | 0x00, | ||
1938 | 0x76, | ||
1939 | 0xcc, | ||
1940 | 0xcc, | ||
1941 | 0xcc, | ||
1942 | 0xcc, | ||
1943 | 0xcc, | ||
1944 | 0xcc, | ||
1945 | 0x7c, | ||
1946 | 0x0c, | ||
1947 | 0x0c, | ||
1948 | 0x1e, | ||
1949 | |||
1950 | 0x00, | ||
1951 | 0x00, | ||
1952 | 0x00, | ||
1953 | 0x00, | ||
1954 | 0x00, | ||
1955 | 0x5e, | ||
1956 | 0xf6, | ||
1957 | 0x60, | ||
1958 | 0x60, | ||
1959 | 0x60, | ||
1960 | 0x60, | ||
1961 | 0x60, | ||
1962 | 0xf0, | ||
1963 | 0x00, | ||
1964 | 0x00, | ||
1965 | 0x00, | ||
1966 | |||
1967 | 0x00, | ||
1968 | 0x00, | ||
1969 | 0x00, | ||
1970 | 0x00, | ||
1971 | 0x00, | ||
1972 | 0x7a, | ||
1973 | 0xc6, | ||
1974 | 0x72, | ||
1975 | 0x1c, | ||
1976 | 0x06, | ||
1977 | 0x86, | ||
1978 | 0xc6, | ||
1979 | 0xbc, | ||
1980 | 0x00, | ||
1981 | 0x00, | ||
1982 | 0x00, | ||
1983 | |||
1984 | 0x00, | ||
1985 | 0x00, | ||
1986 | 0x00, | ||
1987 | 0x10, | ||
1988 | 0x30, | ||
1989 | 0x7c, | ||
1990 | 0x30, | ||
1991 | 0x30, | ||
1992 | 0x30, | ||
1993 | 0x30, | ||
1994 | 0x30, | ||
1995 | 0x34, | ||
1996 | 0x18, | ||
1997 | 0x00, | ||
1998 | 0x00, | ||
1999 | 0x00, | ||
2000 | |||
2001 | 0x00, | ||
2002 | 0x00, | ||
2003 | 0x00, | ||
2004 | 0x00, | ||
2005 | 0x00, | ||
2006 | 0xee, | ||
2007 | 0x66, | ||
2008 | 0x66, | ||
2009 | 0x66, | ||
2010 | 0x66, | ||
2011 | 0x66, | ||
2012 | 0x67, | ||
2013 | 0x3a, | ||
2014 | 0x00, | ||
2015 | 0x00, | ||
2016 | 0x00, | ||
2017 | |||
2018 | 0x00, | ||
2019 | 0x00, | ||
2020 | 0x00, | ||
2021 | 0x00, | ||
2022 | 0x00, | ||
2023 | 0xf7, | ||
2024 | 0x62, | ||
2025 | 0x76, | ||
2026 | 0x34, | ||
2027 | 0x34, | ||
2028 | 0x3c, | ||
2029 | 0x18, | ||
2030 | 0x18, | ||
2031 | 0x00, | ||
2032 | 0x00, | ||
2033 | 0x00, | ||
2034 | |||
2035 | 0x00, | ||
2036 | 0x00, | ||
2037 | 0x00, | ||
2038 | 0x00, | ||
2039 | 0x00, | ||
2040 | 0xf7, | ||
2041 | 0x62, | ||
2042 | 0x6a, | ||
2043 | 0x6a, | ||
2044 | 0x6a, | ||
2045 | 0x6a, | ||
2046 | 0x7e, | ||
2047 | 0x24, | ||
2048 | 0x00, | ||
2049 | 0x00, | ||
2050 | 0x00, | ||
2051 | |||
2052 | 0x00, | ||
2053 | 0x00, | ||
2054 | 0x00, | ||
2055 | 0x00, | ||
2056 | 0x00, | ||
2057 | 0xf7, | ||
2058 | 0x62, | ||
2059 | 0x34, | ||
2060 | 0x18, | ||
2061 | 0x2c, | ||
2062 | 0x46, | ||
2063 | 0x46, | ||
2064 | 0xef, | ||
2065 | 0x00, | ||
2066 | 0x00, | ||
2067 | 0x00, | ||
2068 | |||
2069 | 0x00, | ||
2070 | 0x00, | ||
2071 | 0x00, | ||
2072 | 0x00, | ||
2073 | 0x00, | ||
2074 | 0xf7, | ||
2075 | 0x62, | ||
2076 | 0x62, | ||
2077 | 0x34, | ||
2078 | 0x34, | ||
2079 | 0x18, | ||
2080 | 0x18, | ||
2081 | 0x18, | ||
2082 | 0x10, | ||
2083 | 0xb0, | ||
2084 | 0xe0, | ||
2085 | |||
2086 | 0x00, | ||
2087 | 0x00, | ||
2088 | 0x00, | ||
2089 | 0x00, | ||
2090 | 0x00, | ||
2091 | 0xfe, | ||
2092 | 0x8c, | ||
2093 | 0x18, | ||
2094 | 0x30, | ||
2095 | 0x30, | ||
2096 | 0x60, | ||
2097 | 0xc2, | ||
2098 | 0xfe, | ||
2099 | 0x00, | ||
2100 | 0x00, | ||
2101 | 0x00, | ||
2102 | |||
2103 | 0x00, | ||
2104 | 0x0e, | ||
2105 | 0x18, | ||
2106 | 0x10, | ||
2107 | 0x10, | ||
2108 | 0x08, | ||
2109 | 0x70, | ||
2110 | 0x70, | ||
2111 | 0x08, | ||
2112 | 0x10, | ||
2113 | 0x10, | ||
2114 | 0x18, | ||
2115 | 0x0e, | ||
2116 | 0x00, | ||
2117 | 0x00, | ||
2118 | 0x00, | ||
2119 | |||
2120 | 0x18, | ||
2121 | 0x18, | ||
2122 | 0x18, | ||
2123 | 0x18, | ||
2124 | 0x18, | ||
2125 | 0x18, | ||
2126 | 0x18, | ||
2127 | 0x18, | ||
2128 | 0x18, | ||
2129 | 0x18, | ||
2130 | 0x18, | ||
2131 | 0x18, | ||
2132 | 0x18, | ||
2133 | 0x18, | ||
2134 | 0x00, | ||
2135 | 0x00, | ||
2136 | |||
2137 | 0x00, | ||
2138 | 0x70, | ||
2139 | 0x18, | ||
2140 | 0x08, | ||
2141 | 0x08, | ||
2142 | 0x10, | ||
2143 | 0x0e, | ||
2144 | 0x0e, | ||
2145 | 0x10, | ||
2146 | 0x08, | ||
2147 | 0x08, | ||
2148 | 0x18, | ||
2149 | 0x70, | ||
2150 | 0x00, | ||
2151 | 0x00, | ||
2152 | 0x00, | ||
2153 | |||
2154 | 0x00, | ||
2155 | 0x00, | ||
2156 | 0x00, | ||
2157 | 0x00, | ||
2158 | 0x00, | ||
2159 | 0x00, | ||
2160 | 0x76, | ||
2161 | 0xdc, | ||
2162 | 0x00, | ||
2163 | 0x00, | ||
2164 | 0x00, | ||
2165 | 0x00, | ||
2166 | 0x00, | ||
2167 | 0x00, | ||
2168 | 0x00, | ||
2169 | 0x00, | ||
2170 | |||
2171 | 0x00, | ||
2172 | 0x00, | ||
2173 | 0x00, | ||
2174 | 0x00, | ||
2175 | 0x10, | ||
2176 | 0x38, | ||
2177 | 0x6c, | ||
2178 | 0xc6, | ||
2179 | 0xc6, | ||
2180 | 0xc6, | ||
2181 | 0xfe, | ||
2182 | 0x00, | ||
2183 | 0x00, | ||
2184 | 0x00, | ||
2185 | 0x00, | ||
2186 | 0x00, | ||
2187 | |||
2188 | 0x00, | ||
2189 | 0x00, | ||
2190 | 0x3a, | ||
2191 | 0x66, | ||
2192 | 0xc2, | ||
2193 | 0xc0, | ||
2194 | 0xc0, | ||
2195 | 0xc0, | ||
2196 | 0xc0, | ||
2197 | 0xc0, | ||
2198 | 0x62, | ||
2199 | 0x3c, | ||
2200 | 0x18, | ||
2201 | 0x0c, | ||
2202 | 0x24, | ||
2203 | 0x18, | ||
2204 | |||
2205 | 0x00, | ||
2206 | 0x00, | ||
2207 | 0x66, | ||
2208 | 0x00, | ||
2209 | 0x00, | ||
2210 | 0xee, | ||
2211 | 0x66, | ||
2212 | 0x66, | ||
2213 | 0x66, | ||
2214 | 0x66, | ||
2215 | 0x66, | ||
2216 | 0x66, | ||
2217 | 0x3b, | ||
2218 | 0x00, | ||
2219 | 0x00, | ||
2220 | 0x00, | ||
2221 | |||
2222 | 0x00, | ||
2223 | 0x0c, | ||
2224 | 0x18, | ||
2225 | 0x20, | ||
2226 | 0x00, | ||
2227 | 0x3c, | ||
2228 | 0x66, | ||
2229 | 0x7e, | ||
2230 | 0x60, | ||
2231 | 0x60, | ||
2232 | 0x60, | ||
2233 | 0x62, | ||
2234 | 0x3c, | ||
2235 | 0x00, | ||
2236 | 0x00, | ||
2237 | 0x00, | ||
2238 | |||
2239 | 0x00, | ||
2240 | 0x30, | ||
2241 | 0x58, | ||
2242 | 0x8c, | ||
2243 | 0x00, | ||
2244 | 0x78, | ||
2245 | 0x8c, | ||
2246 | 0x0c, | ||
2247 | 0x3c, | ||
2248 | 0xcc, | ||
2249 | 0xcc, | ||
2250 | 0xcd, | ||
2251 | 0x76, | ||
2252 | 0x00, | ||
2253 | 0x00, | ||
2254 | 0x00, | ||
2255 | |||
2256 | 0x00, | ||
2257 | 0x00, | ||
2258 | 0x66, | ||
2259 | 0x00, | ||
2260 | 0x00, | ||
2261 | 0x78, | ||
2262 | 0x8c, | ||
2263 | 0x0c, | ||
2264 | 0x3c, | ||
2265 | 0xcc, | ||
2266 | 0xcc, | ||
2267 | 0xcd, | ||
2268 | 0x76, | ||
2269 | 0x00, | ||
2270 | 0x00, | ||
2271 | 0x00, | ||
2272 | |||
2273 | 0x00, | ||
2274 | 0x30, | ||
2275 | 0x18, | ||
2276 | 0x04, | ||
2277 | 0x00, | ||
2278 | 0x78, | ||
2279 | 0x8c, | ||
2280 | 0x0c, | ||
2281 | 0x3c, | ||
2282 | 0xcc, | ||
2283 | 0xcc, | ||
2284 | 0xcd, | ||
2285 | 0x76, | ||
2286 | 0x00, | ||
2287 | 0x00, | ||
2288 | 0x00, | ||
2289 | |||
2290 | 0x38, | ||
2291 | 0x44, | ||
2292 | 0x44, | ||
2293 | 0x38, | ||
2294 | 0x00, | ||
2295 | 0x78, | ||
2296 | 0x8c, | ||
2297 | 0x0c, | ||
2298 | 0x3c, | ||
2299 | 0xcc, | ||
2300 | 0xcc, | ||
2301 | 0xcd, | ||
2302 | 0x76, | ||
2303 | 0x00, | ||
2304 | 0x00, | ||
2305 | 0x00, | ||
2306 | |||
2307 | 0x00, | ||
2308 | 0x00, | ||
2309 | 0x00, | ||
2310 | 0x00, | ||
2311 | 0x00, | ||
2312 | 0x3c, | ||
2313 | 0x66, | ||
2314 | 0x60, | ||
2315 | 0x60, | ||
2316 | 0x60, | ||
2317 | 0x60, | ||
2318 | 0x62, | ||
2319 | 0x3c, | ||
2320 | 0x08, | ||
2321 | 0x24, | ||
2322 | 0x18, | ||
2323 | |||
2324 | 0x00, | ||
2325 | 0x18, | ||
2326 | 0x2c, | ||
2327 | 0x46, | ||
2328 | 0x00, | ||
2329 | 0x3c, | ||
2330 | 0x66, | ||
2331 | 0x7e, | ||
2332 | 0x60, | ||
2333 | 0x60, | ||
2334 | 0x60, | ||
2335 | 0x62, | ||
2336 | 0x3c, | ||
2337 | 0x00, | ||
2338 | 0x00, | ||
2339 | 0x00, | ||
2340 | |||
2341 | 0x00, | ||
2342 | 0x00, | ||
2343 | 0x66, | ||
2344 | 0x00, | ||
2345 | 0x00, | ||
2346 | 0x3c, | ||
2347 | 0x66, | ||
2348 | 0x7e, | ||
2349 | 0x60, | ||
2350 | 0x60, | ||
2351 | 0x60, | ||
2352 | 0x62, | ||
2353 | 0x3c, | ||
2354 | 0x00, | ||
2355 | 0x00, | ||
2356 | 0x00, | ||
2357 | |||
2358 | 0x00, | ||
2359 | 0x30, | ||
2360 | 0x18, | ||
2361 | 0x04, | ||
2362 | 0x00, | ||
2363 | 0x3c, | ||
2364 | 0x66, | ||
2365 | 0x7e, | ||
2366 | 0x60, | ||
2367 | 0x60, | ||
2368 | 0x60, | ||
2369 | 0x62, | ||
2370 | 0x3c, | ||
2371 | 0x00, | ||
2372 | 0x00, | ||
2373 | 0x00, | ||
2374 | |||
2375 | 0x00, | ||
2376 | 0x00, | ||
2377 | 0x66, | ||
2378 | 0x00, | ||
2379 | 0x00, | ||
2380 | 0x38, | ||
2381 | 0x18, | ||
2382 | 0x18, | ||
2383 | 0x18, | ||
2384 | 0x18, | ||
2385 | 0x18, | ||
2386 | 0x18, | ||
2387 | 0x3c, | ||
2388 | 0x00, | ||
2389 | 0x00, | ||
2390 | 0x00, | ||
2391 | |||
2392 | 0x00, | ||
2393 | 0x18, | ||
2394 | 0x2c, | ||
2395 | 0x46, | ||
2396 | 0x00, | ||
2397 | 0x38, | ||
2398 | 0x18, | ||
2399 | 0x18, | ||
2400 | 0x18, | ||
2401 | 0x18, | ||
2402 | 0x18, | ||
2403 | 0x18, | ||
2404 | 0x3c, | ||
2405 | 0x00, | ||
2406 | 0x00, | ||
2407 | 0x00, | ||
2408 | |||
2409 | 0x00, | ||
2410 | 0x60, | ||
2411 | 0x30, | ||
2412 | 0x08, | ||
2413 | 0x00, | ||
2414 | 0x38, | ||
2415 | 0x18, | ||
2416 | 0x18, | ||
2417 | 0x18, | ||
2418 | 0x18, | ||
2419 | 0x18, | ||
2420 | 0x18, | ||
2421 | 0x3c, | ||
2422 | 0x00, | ||
2423 | 0x00, | ||
2424 | 0x00, | ||
2425 | |||
2426 | 0x66, | ||
2427 | 0x18, | ||
2428 | 0x18, | ||
2429 | 0x18, | ||
2430 | 0x3c, | ||
2431 | 0x2c, | ||
2432 | 0x2c, | ||
2433 | 0x2c, | ||
2434 | 0x7e, | ||
2435 | 0x46, | ||
2436 | 0x46, | ||
2437 | 0x46, | ||
2438 | 0xef, | ||
2439 | 0x00, | ||
2440 | 0x00, | ||
2441 | 0x00, | ||
2442 | |||
2443 | 0x18, | ||
2444 | 0x24, | ||
2445 | 0x18, | ||
2446 | 0x18, | ||
2447 | 0x3c, | ||
2448 | 0x2c, | ||
2449 | 0x2c, | ||
2450 | 0x2c, | ||
2451 | 0x7e, | ||
2452 | 0x46, | ||
2453 | 0x46, | ||
2454 | 0x46, | ||
2455 | 0xef, | ||
2456 | 0x00, | ||
2457 | 0x00, | ||
2458 | 0x00, | ||
2459 | |||
2460 | 0x0c, | ||
2461 | 0x18, | ||
2462 | 0xff, | ||
2463 | 0x61, | ||
2464 | 0x60, | ||
2465 | 0x60, | ||
2466 | 0x64, | ||
2467 | 0x7c, | ||
2468 | 0x64, | ||
2469 | 0x60, | ||
2470 | 0x60, | ||
2471 | 0x61, | ||
2472 | 0xfe, | ||
2473 | 0x00, | ||
2474 | 0x00, | ||
2475 | 0x00, | ||
2476 | |||
2477 | 0x00, | ||
2478 | 0x00, | ||
2479 | 0x00, | ||
2480 | 0x00, | ||
2481 | 0x00, | ||
2482 | 0x76, | ||
2483 | 0x9b, | ||
2484 | 0x1b, | ||
2485 | 0x3f, | ||
2486 | 0xd8, | ||
2487 | 0xd8, | ||
2488 | 0xd9, | ||
2489 | 0x6e, | ||
2490 | 0x00, | ||
2491 | 0x00, | ||
2492 | 0x00, | ||
2493 | |||
2494 | 0x00, | ||
2495 | 0x1f, | ||
2496 | 0x1d, | ||
2497 | 0x1d, | ||
2498 | 0x3c, | ||
2499 | 0x2c, | ||
2500 | 0x2e, | ||
2501 | 0x2c, | ||
2502 | 0x7c, | ||
2503 | 0x4c, | ||
2504 | 0x4c, | ||
2505 | 0x4d, | ||
2506 | 0xef, | ||
2507 | 0x00, | ||
2508 | 0x00, | ||
2509 | 0x00, | ||
2510 | |||
2511 | 0x00, | ||
2512 | 0x18, | ||
2513 | 0x2c, | ||
2514 | 0x46, | ||
2515 | 0x00, | ||
2516 | 0x3c, | ||
2517 | 0x66, | ||
2518 | 0x66, | ||
2519 | 0x66, | ||
2520 | 0x66, | ||
2521 | 0x66, | ||
2522 | 0x66, | ||
2523 | 0x3c, | ||
2524 | 0x00, | ||
2525 | 0x00, | ||
2526 | 0x00, | ||
2527 | |||
2528 | 0x00, | ||
2529 | 0x00, | ||
2530 | 0x66, | ||
2531 | 0x00, | ||
2532 | 0x00, | ||
2533 | 0x3c, | ||
2534 | 0x66, | ||
2535 | 0x66, | ||
2536 | 0x66, | ||
2537 | 0x66, | ||
2538 | 0x66, | ||
2539 | 0x66, | ||
2540 | 0x3c, | ||
2541 | 0x00, | ||
2542 | 0x00, | ||
2543 | 0x00, | ||
2544 | |||
2545 | 0x00, | ||
2546 | 0x30, | ||
2547 | 0x18, | ||
2548 | 0x04, | ||
2549 | 0x00, | ||
2550 | 0x3c, | ||
2551 | 0x66, | ||
2552 | 0x66, | ||
2553 | 0x66, | ||
2554 | 0x66, | ||
2555 | 0x66, | ||
2556 | 0x66, | ||
2557 | 0x3c, | ||
2558 | 0x00, | ||
2559 | 0x00, | ||
2560 | 0x00, | ||
2561 | |||
2562 | 0x00, | ||
2563 | 0x18, | ||
2564 | 0x2c, | ||
2565 | 0x46, | ||
2566 | 0x00, | ||
2567 | 0xee, | ||
2568 | 0x66, | ||
2569 | 0x66, | ||
2570 | 0x66, | ||
2571 | 0x66, | ||
2572 | 0x66, | ||
2573 | 0x67, | ||
2574 | 0x3a, | ||
2575 | 0x00, | ||
2576 | 0x00, | ||
2577 | 0x00, | ||
2578 | |||
2579 | 0x00, | ||
2580 | 0x30, | ||
2581 | 0x18, | ||
2582 | 0x04, | ||
2583 | 0x00, | ||
2584 | 0xee, | ||
2585 | 0x66, | ||
2586 | 0x66, | ||
2587 | 0x66, | ||
2588 | 0x66, | ||
2589 | 0x66, | ||
2590 | 0x67, | ||
2591 | 0x3a, | ||
2592 | 0x00, | ||
2593 | 0x00, | ||
2594 | 0x00, | ||
2595 | |||
2596 | 0x00, | ||
2597 | 0x00, | ||
2598 | 0x66, | ||
2599 | 0x00, | ||
2600 | 0x00, | ||
2601 | 0xf7, | ||
2602 | 0x62, | ||
2603 | 0x62, | ||
2604 | 0x34, | ||
2605 | 0x34, | ||
2606 | 0x18, | ||
2607 | 0x18, | ||
2608 | 0x18, | ||
2609 | 0x10, | ||
2610 | 0xb0, | ||
2611 | 0xe0, | ||
2612 | |||
2613 | 0x66, | ||
2614 | 0x00, | ||
2615 | 0x3c, | ||
2616 | 0x66, | ||
2617 | 0xc3, | ||
2618 | 0xc3, | ||
2619 | 0xc3, | ||
2620 | 0xc3, | ||
2621 | 0xc3, | ||
2622 | 0xc3, | ||
2623 | 0xc3, | ||
2624 | 0x66, | ||
2625 | 0x3c, | ||
2626 | 0x00, | ||
2627 | 0x00, | ||
2628 | 0x00, | ||
2629 | |||
2630 | 0x66, | ||
2631 | 0x00, | ||
2632 | 0xf7, | ||
2633 | 0x62, | ||
2634 | 0x62, | ||
2635 | 0x62, | ||
2636 | 0x62, | ||
2637 | 0x62, | ||
2638 | 0x62, | ||
2639 | 0x62, | ||
2640 | 0x62, | ||
2641 | 0x62, | ||
2642 | 0x3c, | ||
2643 | 0x00, | ||
2644 | 0x00, | ||
2645 | 0x00, | ||
2646 | |||
2647 | 0x00, | ||
2648 | 0x00, | ||
2649 | 0x10, | ||
2650 | 0x10, | ||
2651 | 0x10, | ||
2652 | 0x7c, | ||
2653 | 0xc6, | ||
2654 | 0xc0, | ||
2655 | 0xc0, | ||
2656 | 0xc0, | ||
2657 | 0xc0, | ||
2658 | 0xc2, | ||
2659 | 0x7c, | ||
2660 | 0x10, | ||
2661 | 0x10, | ||
2662 | 0x00, | ||
2663 | |||
2664 | 0x00, | ||
2665 | 0x38, | ||
2666 | 0x64, | ||
2667 | 0x6c, | ||
2668 | 0x60, | ||
2669 | 0x60, | ||
2670 | 0xf0, | ||
2671 | 0x60, | ||
2672 | 0x60, | ||
2673 | 0x60, | ||
2674 | 0x60, | ||
2675 | 0x66, | ||
2676 | 0xfc, | ||
2677 | 0x00, | ||
2678 | 0x00, | ||
2679 | 0x00, | ||
2680 | |||
2681 | 0x00, | ||
2682 | 0x81, | ||
2683 | 0xc3, | ||
2684 | 0x66, | ||
2685 | 0x3c, | ||
2686 | 0x18, | ||
2687 | 0xff, | ||
2688 | 0x18, | ||
2689 | 0x18, | ||
2690 | 0xff, | ||
2691 | 0x18, | ||
2692 | 0x18, | ||
2693 | 0x18, | ||
2694 | 0x00, | ||
2695 | 0x00, | ||
2696 | 0x00, | ||
2697 | |||
2698 | 0x00, | ||
2699 | 0xfe, | ||
2700 | 0x63, | ||
2701 | 0x63, | ||
2702 | 0x63, | ||
2703 | 0x63, | ||
2704 | 0x6e, | ||
2705 | 0x60, | ||
2706 | 0x64, | ||
2707 | 0x6e, | ||
2708 | 0x64, | ||
2709 | 0x64, | ||
2710 | 0xf5, | ||
2711 | 0x06, | ||
2712 | 0x00, | ||
2713 | 0x00, | ||
2714 | |||
2715 | 0x00, | ||
2716 | 0x0e, | ||
2717 | 0x19, | ||
2718 | 0x1b, | ||
2719 | 0x18, | ||
2720 | 0x18, | ||
2721 | 0x3c, | ||
2722 | 0x18, | ||
2723 | 0x18, | ||
2724 | 0x18, | ||
2725 | 0x18, | ||
2726 | 0xd8, | ||
2727 | 0x98, | ||
2728 | 0x70, | ||
2729 | 0x00, | ||
2730 | 0x00, | ||
2731 | |||
2732 | 0x00, | ||
2733 | 0x0c, | ||
2734 | 0x18, | ||
2735 | 0x20, | ||
2736 | 0x00, | ||
2737 | 0x78, | ||
2738 | 0x8c, | ||
2739 | 0x0c, | ||
2740 | 0x3c, | ||
2741 | 0xcc, | ||
2742 | 0xcc, | ||
2743 | 0xcd, | ||
2744 | 0x76, | ||
2745 | 0x00, | ||
2746 | 0x00, | ||
2747 | 0x00, | ||
2748 | |||
2749 | 0x00, | ||
2750 | 0x06, | ||
2751 | 0x0c, | ||
2752 | 0x10, | ||
2753 | 0x00, | ||
2754 | 0x38, | ||
2755 | 0x18, | ||
2756 | 0x18, | ||
2757 | 0x18, | ||
2758 | 0x18, | ||
2759 | 0x18, | ||
2760 | 0x18, | ||
2761 | 0x3c, | ||
2762 | 0x00, | ||
2763 | 0x00, | ||
2764 | 0x00, | ||
2765 | |||
2766 | 0x00, | ||
2767 | 0x0c, | ||
2768 | 0x18, | ||
2769 | 0x20, | ||
2770 | 0x00, | ||
2771 | 0x3c, | ||
2772 | 0x66, | ||
2773 | 0x66, | ||
2774 | 0x66, | ||
2775 | 0x66, | ||
2776 | 0x66, | ||
2777 | 0x66, | ||
2778 | 0x3c, | ||
2779 | 0x00, | ||
2780 | 0x00, | ||
2781 | 0x00, | ||
2782 | |||
2783 | 0x00, | ||
2784 | 0x0c, | ||
2785 | 0x18, | ||
2786 | 0x20, | ||
2787 | 0x00, | ||
2788 | 0xee, | ||
2789 | 0x66, | ||
2790 | 0x66, | ||
2791 | 0x66, | ||
2792 | 0x66, | ||
2793 | 0x66, | ||
2794 | 0x67, | ||
2795 | 0x3a, | ||
2796 | 0x00, | ||
2797 | 0x00, | ||
2798 | 0x00, | ||
2799 | |||
2800 | 0x00, | ||
2801 | 0x00, | ||
2802 | 0x32, | ||
2803 | 0x4c, | ||
2804 | 0x00, | ||
2805 | 0x5c, | ||
2806 | 0xf6, | ||
2807 | 0x66, | ||
2808 | 0x66, | ||
2809 | 0x66, | ||
2810 | 0x66, | ||
2811 | 0x66, | ||
2812 | 0xf7, | ||
2813 | 0x00, | ||
2814 | 0x00, | ||
2815 | 0x00, | ||
2816 | |||
2817 | 0x32, | ||
2818 | 0x4c, | ||
2819 | 0x00, | ||
2820 | 0xe7, | ||
2821 | 0x72, | ||
2822 | 0x52, | ||
2823 | 0x5a, | ||
2824 | 0x4a, | ||
2825 | 0x4e, | ||
2826 | 0x46, | ||
2827 | 0x46, | ||
2828 | 0x42, | ||
2829 | 0xe2, | ||
2830 | 0x00, | ||
2831 | 0x00, | ||
2832 | 0x00, | ||
2833 | |||
2834 | 0x00, | ||
2835 | 0x78, | ||
2836 | 0x8c, | ||
2837 | 0x0c, | ||
2838 | 0x3c, | ||
2839 | 0xcc, | ||
2840 | 0xcc, | ||
2841 | 0xcd, | ||
2842 | 0x76, | ||
2843 | 0x00, | ||
2844 | 0xfe, | ||
2845 | 0x00, | ||
2846 | 0x00, | ||
2847 | 0x00, | ||
2848 | 0x00, | ||
2849 | 0x00, | ||
2850 | |||
2851 | 0x00, | ||
2852 | 0x3c, | ||
2853 | 0x66, | ||
2854 | 0x66, | ||
2855 | 0x66, | ||
2856 | 0x66, | ||
2857 | 0x66, | ||
2858 | 0x66, | ||
2859 | 0x3c, | ||
2860 | 0x00, | ||
2861 | 0x7e, | ||
2862 | 0x00, | ||
2863 | 0x00, | ||
2864 | 0x00, | ||
2865 | 0x00, | ||
2866 | 0x00, | ||
2867 | |||
2868 | 0x00, | ||
2869 | 0x30, | ||
2870 | 0x30, | ||
2871 | 0x00, | ||
2872 | 0x30, | ||
2873 | 0x10, | ||
2874 | 0x10, | ||
2875 | 0x20, | ||
2876 | 0x40, | ||
2877 | 0xc0, | ||
2878 | 0xc6, | ||
2879 | 0xc2, | ||
2880 | 0x7c, | ||
2881 | 0x00, | ||
2882 | 0x00, | ||
2883 | 0x00, | ||
2884 | |||
2885 | 0x00, | ||
2886 | 0x00, | ||
2887 | 0x00, | ||
2888 | 0x00, | ||
2889 | 0x00, | ||
2890 | 0x00, | ||
2891 | 0xfe, | ||
2892 | 0xc0, | ||
2893 | 0xc0, | ||
2894 | 0xc0, | ||
2895 | 0xc0, | ||
2896 | 0x00, | ||
2897 | 0x00, | ||
2898 | 0x00, | ||
2899 | 0x00, | ||
2900 | 0x00, | ||
2901 | |||
2902 | 0x00, | ||
2903 | 0x00, | ||
2904 | 0x00, | ||
2905 | 0x00, | ||
2906 | 0x00, | ||
2907 | 0x00, | ||
2908 | 0xfe, | ||
2909 | 0x06, | ||
2910 | 0x06, | ||
2911 | 0x06, | ||
2912 | 0x06, | ||
2913 | 0x00, | ||
2914 | 0x00, | ||
2915 | 0x00, | ||
2916 | 0x00, | ||
2917 | 0x00, | ||
2918 | |||
2919 | 0x00, | ||
2920 | 0x20, | ||
2921 | 0xe0, | ||
2922 | 0x63, | ||
2923 | 0x66, | ||
2924 | 0xfc, | ||
2925 | 0x18, | ||
2926 | 0x30, | ||
2927 | 0x60, | ||
2928 | 0xce, | ||
2929 | 0x93, | ||
2930 | 0x06, | ||
2931 | 0x0c, | ||
2932 | 0x1f, | ||
2933 | 0x00, | ||
2934 | 0x00, | ||
2935 | |||
2936 | 0x00, | ||
2937 | 0x20, | ||
2938 | 0xe0, | ||
2939 | 0x63, | ||
2940 | 0x66, | ||
2941 | 0xfc, | ||
2942 | 0x18, | ||
2943 | 0x30, | ||
2944 | 0x64, | ||
2945 | 0xc8, | ||
2946 | 0x96, | ||
2947 | 0x3f, | ||
2948 | 0x06, | ||
2949 | 0x06, | ||
2950 | 0x00, | ||
2951 | 0x00, | ||
2952 | |||
2953 | 0x00, | ||
2954 | 0x18, | ||
2955 | 0x18, | ||
2956 | 0x00, | ||
2957 | 0x08, | ||
2958 | 0x18, | ||
2959 | 0x18, | ||
2960 | 0x18, | ||
2961 | 0x3c, | ||
2962 | 0x3c, | ||
2963 | 0x3c, | ||
2964 | 0x3c, | ||
2965 | 0x18, | ||
2966 | 0x00, | ||
2967 | 0x00, | ||
2968 | 0x00, | ||
2969 | |||
2970 | 0x00, | ||
2971 | 0x00, | ||
2972 | 0x00, | ||
2973 | 0x00, | ||
2974 | 0x00, | ||
2975 | 0x36, | ||
2976 | 0x6c, | ||
2977 | 0xd8, | ||
2978 | 0xd8, | ||
2979 | 0x6c, | ||
2980 | 0x36, | ||
2981 | 0x00, | ||
2982 | 0x00, | ||
2983 | 0x00, | ||
2984 | 0x00, | ||
2985 | 0x00, | ||
2986 | |||
2987 | 0x00, | ||
2988 | 0x00, | ||
2989 | 0x00, | ||
2990 | 0x00, | ||
2991 | 0x00, | ||
2992 | 0xd8, | ||
2993 | 0x6c, | ||
2994 | 0x36, | ||
2995 | 0x36, | ||
2996 | 0x6c, | ||
2997 | 0xd8, | ||
2998 | 0x00, | ||
2999 | 0x00, | ||
3000 | 0x00, | ||
3001 | 0x00, | ||
3002 | 0x00, | ||
3003 | |||
3004 | 0x82, | ||
3005 | 0x10, | ||
3006 | 0x82, | ||
3007 | 0x10, | ||
3008 | 0x82, | ||
3009 | 0x10, | ||
3010 | 0x82, | ||
3011 | 0x10, | ||
3012 | 0x82, | ||
3013 | 0x10, | ||
3014 | 0x82, | ||
3015 | 0x10, | ||
3016 | 0x82, | ||
3017 | 0x10, | ||
3018 | 0x82, | ||
3019 | 0x10, | ||
3020 | |||
3021 | 0x00, | ||
3022 | 0x95, | ||
3023 | 0x00, | ||
3024 | 0xa9, | ||
3025 | 0x00, | ||
3026 | 0x95, | ||
3027 | 0x00, | ||
3028 | 0xa9, | ||
3029 | 0x00, | ||
3030 | 0x95, | ||
3031 | 0x00, | ||
3032 | 0xa9, | ||
3033 | 0x00, | ||
3034 | 0x95, | ||
3035 | 0x00, | ||
3036 | 0xa9, | ||
3037 | |||
3038 | 0x92, | ||
3039 | 0x49, | ||
3040 | 0x92, | ||
3041 | 0x49, | ||
3042 | 0x92, | ||
3043 | 0x49, | ||
3044 | 0x92, | ||
3045 | 0x49, | ||
3046 | 0x92, | ||
3047 | 0x49, | ||
3048 | 0x92, | ||
3049 | 0x49, | ||
3050 | 0x92, | ||
3051 | 0x49, | ||
3052 | 0x92, | ||
3053 | 0x49, | ||
3054 | |||
3055 | 0x18, | ||
3056 | 0x18, | ||
3057 | 0x18, | ||
3058 | 0x18, | ||
3059 | 0x18, | ||
3060 | 0x18, | ||
3061 | 0x18, | ||
3062 | 0x18, | ||
3063 | 0x18, | ||
3064 | 0x18, | ||
3065 | 0x18, | ||
3066 | 0x18, | ||
3067 | 0x18, | ||
3068 | 0x18, | ||
3069 | 0x18, | ||
3070 | 0x18, | ||
3071 | |||
3072 | 0x18, | ||
3073 | 0x18, | ||
3074 | 0x18, | ||
3075 | 0x18, | ||
3076 | 0x18, | ||
3077 | 0x18, | ||
3078 | 0x18, | ||
3079 | 0xf8, | ||
3080 | 0x18, | ||
3081 | 0x18, | ||
3082 | 0x18, | ||
3083 | 0x18, | ||
3084 | 0x18, | ||
3085 | 0x18, | ||
3086 | 0x18, | ||
3087 | 0x18, | ||
3088 | |||
3089 | 0x18, | ||
3090 | 0x18, | ||
3091 | 0x18, | ||
3092 | 0x18, | ||
3093 | 0x18, | ||
3094 | 0x18, | ||
3095 | 0xf8, | ||
3096 | 0x18, | ||
3097 | 0x18, | ||
3098 | 0xf8, | ||
3099 | 0x18, | ||
3100 | 0x18, | ||
3101 | 0x18, | ||
3102 | 0x18, | ||
3103 | 0x18, | ||
3104 | 0x18, | ||
3105 | |||
3106 | 0x66, | ||
3107 | 0x66, | ||
3108 | 0x66, | ||
3109 | 0x66, | ||
3110 | 0x66, | ||
3111 | 0x66, | ||
3112 | 0x66, | ||
3113 | 0xe6, | ||
3114 | 0x66, | ||
3115 | 0x66, | ||
3116 | 0x66, | ||
3117 | 0x66, | ||
3118 | 0x66, | ||
3119 | 0x66, | ||
3120 | 0x66, | ||
3121 | 0x66, | ||
3122 | |||
3123 | 0x00, | ||
3124 | 0x00, | ||
3125 | 0x00, | ||
3126 | 0x00, | ||
3127 | 0x00, | ||
3128 | 0x00, | ||
3129 | 0x00, | ||
3130 | 0xfe, | ||
3131 | 0x66, | ||
3132 | 0x66, | ||
3133 | 0x66, | ||
3134 | 0x66, | ||
3135 | 0x66, | ||
3136 | 0x66, | ||
3137 | 0x66, | ||
3138 | 0x66, | ||
3139 | |||
3140 | 0x00, | ||
3141 | 0x00, | ||
3142 | 0x00, | ||
3143 | 0x00, | ||
3144 | 0x00, | ||
3145 | 0x00, | ||
3146 | 0xf8, | ||
3147 | 0x18, | ||
3148 | 0x18, | ||
3149 | 0xf8, | ||
3150 | 0x18, | ||
3151 | 0x18, | ||
3152 | 0x18, | ||
3153 | 0x18, | ||
3154 | 0x18, | ||
3155 | 0x18, | ||
3156 | |||
3157 | 0x66, | ||
3158 | 0x66, | ||
3159 | 0x66, | ||
3160 | 0x66, | ||
3161 | 0x66, | ||
3162 | 0x66, | ||
3163 | 0xe6, | ||
3164 | 0x06, | ||
3165 | 0x06, | ||
3166 | 0xe6, | ||
3167 | 0x66, | ||
3168 | 0x66, | ||
3169 | 0x66, | ||
3170 | 0x66, | ||
3171 | 0x66, | ||
3172 | 0x66, | ||
3173 | |||
3174 | 0x66, | ||
3175 | 0x66, | ||
3176 | 0x66, | ||
3177 | 0x66, | ||
3178 | 0x66, | ||
3179 | 0x66, | ||
3180 | 0x66, | ||
3181 | 0x66, | ||
3182 | 0x66, | ||
3183 | 0x66, | ||
3184 | 0x66, | ||
3185 | 0x66, | ||
3186 | 0x66, | ||
3187 | 0x66, | ||
3188 | 0x66, | ||
3189 | 0x66, | ||
3190 | |||
3191 | 0x00, | ||
3192 | 0x00, | ||
3193 | 0x00, | ||
3194 | 0x00, | ||
3195 | 0x00, | ||
3196 | 0x00, | ||
3197 | 0xfe, | ||
3198 | 0x06, | ||
3199 | 0x06, | ||
3200 | 0xe6, | ||
3201 | 0x66, | ||
3202 | 0x66, | ||
3203 | 0x66, | ||
3204 | 0x66, | ||
3205 | 0x66, | ||
3206 | 0x66, | ||
3207 | |||
3208 | 0x66, | ||
3209 | 0x66, | ||
3210 | 0x66, | ||
3211 | 0x66, | ||
3212 | 0x66, | ||
3213 | 0x66, | ||
3214 | 0xe6, | ||
3215 | 0x06, | ||
3216 | 0x06, | ||
3217 | 0xfe, | ||
3218 | 0x00, | ||
3219 | 0x00, | ||
3220 | 0x00, | ||
3221 | 0x00, | ||
3222 | 0x00, | ||
3223 | 0x00, | ||
3224 | |||
3225 | 0x66, | ||
3226 | 0x66, | ||
3227 | 0x66, | ||
3228 | 0x66, | ||
3229 | 0x66, | ||
3230 | 0x66, | ||
3231 | 0x66, | ||
3232 | 0xfe, | ||
3233 | 0x00, | ||
3234 | 0x00, | ||
3235 | 0x00, | ||
3236 | 0x00, | ||
3237 | 0x00, | ||
3238 | 0x00, | ||
3239 | 0x00, | ||
3240 | 0x00, | ||
3241 | |||
3242 | 0x18, | ||
3243 | 0x18, | ||
3244 | 0x18, | ||
3245 | 0x18, | ||
3246 | 0x18, | ||
3247 | 0x18, | ||
3248 | 0xf8, | ||
3249 | 0x18, | ||
3250 | 0x18, | ||
3251 | 0xf8, | ||
3252 | 0x00, | ||
3253 | 0x00, | ||
3254 | 0x00, | ||
3255 | 0x00, | ||
3256 | 0x00, | ||
3257 | 0x00, | ||
3258 | |||
3259 | 0x00, | ||
3260 | 0x00, | ||
3261 | 0x00, | ||
3262 | 0x00, | ||
3263 | 0x00, | ||
3264 | 0x00, | ||
3265 | 0x00, | ||
3266 | 0xf8, | ||
3267 | 0x18, | ||
3268 | 0x18, | ||
3269 | 0x18, | ||
3270 | 0x18, | ||
3271 | 0x18, | ||
3272 | 0x18, | ||
3273 | 0x18, | ||
3274 | 0x18, | ||
3275 | |||
3276 | 0x18, | ||
3277 | 0x18, | ||
3278 | 0x18, | ||
3279 | 0x18, | ||
3280 | 0x18, | ||
3281 | 0x18, | ||
3282 | 0x18, | ||
3283 | 0x1f, | ||
3284 | 0x00, | ||
3285 | 0x00, | ||
3286 | 0x00, | ||
3287 | 0x00, | ||
3288 | 0x00, | ||
3289 | 0x00, | ||
3290 | 0x00, | ||
3291 | 0x00, | ||
3292 | |||
3293 | 0x18, | ||
3294 | 0x18, | ||
3295 | 0x18, | ||
3296 | 0x18, | ||
3297 | 0x18, | ||
3298 | 0x18, | ||
3299 | 0x18, | ||
3300 | 0xff, | ||
3301 | 0x00, | ||
3302 | 0x00, | ||
3303 | 0x00, | ||
3304 | 0x00, | ||
3305 | 0x00, | ||
3306 | 0x00, | ||
3307 | 0x00, | ||
3308 | 0x00, | ||
3309 | |||
3310 | 0x00, | ||
3311 | 0x00, | ||
3312 | 0x00, | ||
3313 | 0x00, | ||
3314 | 0x00, | ||
3315 | 0x00, | ||
3316 | 0x00, | ||
3317 | 0xff, | ||
3318 | 0x18, | ||
3319 | 0x18, | ||
3320 | 0x18, | ||
3321 | 0x18, | ||
3322 | 0x18, | ||
3323 | 0x18, | ||
3324 | 0x18, | ||
3325 | 0x18, | ||
3326 | |||
3327 | 0x18, | ||
3328 | 0x18, | ||
3329 | 0x18, | ||
3330 | 0x18, | ||
3331 | 0x18, | ||
3332 | 0x18, | ||
3333 | 0x18, | ||
3334 | 0x1f, | ||
3335 | 0x18, | ||
3336 | 0x18, | ||
3337 | 0x18, | ||
3338 | 0x18, | ||
3339 | 0x18, | ||
3340 | 0x18, | ||
3341 | 0x18, | ||
3342 | 0x18, | ||
3343 | |||
3344 | 0x00, | ||
3345 | 0x00, | ||
3346 | 0x00, | ||
3347 | 0x00, | ||
3348 | 0x00, | ||
3349 | 0x00, | ||
3350 | 0x00, | ||
3351 | 0xff, | ||
3352 | 0x00, | ||
3353 | 0x00, | ||
3354 | 0x00, | ||
3355 | 0x00, | ||
3356 | 0x00, | ||
3357 | 0x00, | ||
3358 | 0x00, | ||
3359 | 0x00, | ||
3360 | |||
3361 | 0x18, | ||
3362 | 0x18, | ||
3363 | 0x18, | ||
3364 | 0x18, | ||
3365 | 0x18, | ||
3366 | 0x18, | ||
3367 | 0x18, | ||
3368 | 0xff, | ||
3369 | 0x18, | ||
3370 | 0x18, | ||
3371 | 0x18, | ||
3372 | 0x18, | ||
3373 | 0x18, | ||
3374 | 0x18, | ||
3375 | 0x18, | ||
3376 | 0x18, | ||
3377 | |||
3378 | 0x18, | ||
3379 | 0x18, | ||
3380 | 0x18, | ||
3381 | 0x18, | ||
3382 | 0x18, | ||
3383 | 0x18, | ||
3384 | 0x1f, | ||
3385 | 0x18, | ||
3386 | 0x18, | ||
3387 | 0x1f, | ||
3388 | 0x18, | ||
3389 | 0x18, | ||
3390 | 0x18, | ||
3391 | 0x18, | ||
3392 | 0x18, | ||
3393 | 0x18, | ||
3394 | |||
3395 | 0x66, | ||
3396 | 0x66, | ||
3397 | 0x66, | ||
3398 | 0x66, | ||
3399 | 0x66, | ||
3400 | 0x66, | ||
3401 | 0x66, | ||
3402 | 0x67, | ||
3403 | 0x66, | ||
3404 | 0x66, | ||
3405 | 0x66, | ||
3406 | 0x66, | ||
3407 | 0x66, | ||
3408 | 0x66, | ||
3409 | 0x66, | ||
3410 | 0x66, | ||
3411 | |||
3412 | 0x66, | ||
3413 | 0x66, | ||
3414 | 0x66, | ||
3415 | 0x66, | ||
3416 | 0x66, | ||
3417 | 0x66, | ||
3418 | 0x67, | ||
3419 | 0x60, | ||
3420 | 0x60, | ||
3421 | 0x7f, | ||
3422 | 0x00, | ||
3423 | 0x00, | ||
3424 | 0x00, | ||
3425 | 0x00, | ||
3426 | 0x00, | ||
3427 | 0x00, | ||
3428 | |||
3429 | 0x00, | ||
3430 | 0x00, | ||
3431 | 0x00, | ||
3432 | 0x00, | ||
3433 | 0x00, | ||
3434 | 0x00, | ||
3435 | 0x7f, | ||
3436 | 0x60, | ||
3437 | 0x60, | ||
3438 | 0x67, | ||
3439 | 0x66, | ||
3440 | 0x66, | ||
3441 | 0x66, | ||
3442 | 0x66, | ||
3443 | 0x66, | ||
3444 | 0x66, | ||
3445 | |||
3446 | 0x66, | ||
3447 | 0x66, | ||
3448 | 0x66, | ||
3449 | 0x66, | ||
3450 | 0x66, | ||
3451 | 0x66, | ||
3452 | 0xe7, | ||
3453 | 0x00, | ||
3454 | 0x00, | ||
3455 | 0xff, | ||
3456 | 0x00, | ||
3457 | 0x00, | ||
3458 | 0x00, | ||
3459 | 0x00, | ||
3460 | 0x00, | ||
3461 | 0x00, | ||
3462 | |||
3463 | 0x00, | ||
3464 | 0x00, | ||
3465 | 0x00, | ||
3466 | 0x00, | ||
3467 | 0x00, | ||
3468 | 0x00, | ||
3469 | 0xff, | ||
3470 | 0x00, | ||
3471 | 0x00, | ||
3472 | 0xe7, | ||
3473 | 0x66, | ||
3474 | 0x66, | ||
3475 | 0x66, | ||
3476 | 0x66, | ||
3477 | 0x66, | ||
3478 | 0x66, | ||
3479 | |||
3480 | 0x66, | ||
3481 | 0x66, | ||
3482 | 0x66, | ||
3483 | 0x66, | ||
3484 | 0x66, | ||
3485 | 0x66, | ||
3486 | 0x67, | ||
3487 | 0x60, | ||
3488 | 0x60, | ||
3489 | 0x67, | ||
3490 | 0x66, | ||
3491 | 0x66, | ||
3492 | 0x66, | ||
3493 | 0x66, | ||
3494 | 0x66, | ||
3495 | 0x66, | ||
3496 | |||
3497 | 0x00, | ||
3498 | 0x00, | ||
3499 | 0x00, | ||
3500 | 0x00, | ||
3501 | 0x00, | ||
3502 | 0x00, | ||
3503 | 0xff, | ||
3504 | 0x00, | ||
3505 | 0x00, | ||
3506 | 0xff, | ||
3507 | 0x00, | ||
3508 | 0x00, | ||
3509 | 0x00, | ||
3510 | 0x00, | ||
3511 | 0x00, | ||
3512 | 0x00, | ||
3513 | |||
3514 | 0x66, | ||
3515 | 0x66, | ||
3516 | 0x66, | ||
3517 | 0x66, | ||
3518 | 0x66, | ||
3519 | 0x66, | ||
3520 | 0xe7, | ||
3521 | 0x00, | ||
3522 | 0x00, | ||
3523 | 0xe7, | ||
3524 | 0x66, | ||
3525 | 0x66, | ||
3526 | 0x66, | ||
3527 | 0x66, | ||
3528 | 0x66, | ||
3529 | 0x66, | ||
3530 | |||
3531 | 0x18, | ||
3532 | 0x18, | ||
3533 | 0x18, | ||
3534 | 0x18, | ||
3535 | 0x18, | ||
3536 | 0x18, | ||
3537 | 0xff, | ||
3538 | 0x00, | ||
3539 | 0x00, | ||
3540 | 0xff, | ||
3541 | 0x00, | ||
3542 | 0x00, | ||
3543 | 0x00, | ||
3544 | 0x00, | ||
3545 | 0x00, | ||
3546 | 0x00, | ||
3547 | |||
3548 | 0x66, | ||
3549 | 0x66, | ||
3550 | 0x66, | ||
3551 | 0x66, | ||
3552 | 0x66, | ||
3553 | 0x66, | ||
3554 | 0x66, | ||
3555 | 0xff, | ||
3556 | 0x00, | ||
3557 | 0x00, | ||
3558 | 0x00, | ||
3559 | 0x00, | ||
3560 | 0x00, | ||
3561 | 0x00, | ||
3562 | 0x00, | ||
3563 | 0x00, | ||
3564 | |||
3565 | 0x00, | ||
3566 | 0x00, | ||
3567 | 0x00, | ||
3568 | 0x00, | ||
3569 | 0x00, | ||
3570 | 0x00, | ||
3571 | 0xff, | ||
3572 | 0x00, | ||
3573 | 0x00, | ||
3574 | 0xff, | ||
3575 | 0x18, | ||
3576 | 0x18, | ||
3577 | 0x18, | ||
3578 | 0x18, | ||
3579 | 0x18, | ||
3580 | 0x18, | ||
3581 | |||
3582 | 0x00, | ||
3583 | 0x00, | ||
3584 | 0x00, | ||
3585 | 0x00, | ||
3586 | 0x00, | ||
3587 | 0x00, | ||
3588 | 0x00, | ||
3589 | 0xff, | ||
3590 | 0x66, | ||
3591 | 0x66, | ||
3592 | 0x66, | ||
3593 | 0x66, | ||
3594 | 0x66, | ||
3595 | 0x66, | ||
3596 | 0x66, | ||
3597 | 0x66, | ||
3598 | |||
3599 | 0x66, | ||
3600 | 0x66, | ||
3601 | 0x66, | ||
3602 | 0x66, | ||
3603 | 0x66, | ||
3604 | 0x66, | ||
3605 | 0x66, | ||
3606 | 0x7f, | ||
3607 | 0x00, | ||
3608 | 0x00, | ||
3609 | 0x00, | ||
3610 | 0x00, | ||
3611 | 0x00, | ||
3612 | 0x00, | ||
3613 | 0x00, | ||
3614 | 0x00, | ||
3615 | |||
3616 | 0x18, | ||
3617 | 0x18, | ||
3618 | 0x18, | ||
3619 | 0x18, | ||
3620 | 0x18, | ||
3621 | 0x18, | ||
3622 | 0x1f, | ||
3623 | 0x18, | ||
3624 | 0x18, | ||
3625 | 0x1f, | ||
3626 | 0x00, | ||
3627 | 0x00, | ||
3628 | 0x00, | ||
3629 | 0x00, | ||
3630 | 0x00, | ||
3631 | 0x00, | ||
3632 | |||
3633 | 0x00, | ||
3634 | 0x00, | ||
3635 | 0x00, | ||
3636 | 0x00, | ||
3637 | 0x00, | ||
3638 | 0x00, | ||
3639 | 0x1f, | ||
3640 | 0x18, | ||
3641 | 0x18, | ||
3642 | 0x1f, | ||
3643 | 0x18, | ||
3644 | 0x18, | ||
3645 | 0x18, | ||
3646 | 0x18, | ||
3647 | 0x18, | ||
3648 | 0x18, | ||
3649 | |||
3650 | 0x00, | ||
3651 | 0x00, | ||
3652 | 0x00, | ||
3653 | 0x00, | ||
3654 | 0x00, | ||
3655 | 0x00, | ||
3656 | 0x00, | ||
3657 | 0x7f, | ||
3658 | 0x66, | ||
3659 | 0x66, | ||
3660 | 0x66, | ||
3661 | 0x66, | ||
3662 | 0x66, | ||
3663 | 0x66, | ||
3664 | 0x66, | ||
3665 | 0x66, | ||
3666 | |||
3667 | 0x66, | ||
3668 | 0x66, | ||
3669 | 0x66, | ||
3670 | 0x66, | ||
3671 | 0x66, | ||
3672 | 0x66, | ||
3673 | 0x66, | ||
3674 | 0xff, | ||
3675 | 0x66, | ||
3676 | 0x66, | ||
3677 | 0x66, | ||
3678 | 0x66, | ||
3679 | 0x66, | ||
3680 | 0x66, | ||
3681 | 0x66, | ||
3682 | 0x66, | ||
3683 | |||
3684 | 0x18, | ||
3685 | 0x18, | ||
3686 | 0x18, | ||
3687 | 0x18, | ||
3688 | 0x18, | ||
3689 | 0x18, | ||
3690 | 0xff, | ||
3691 | 0x00, | ||
3692 | 0x00, | ||
3693 | 0xff, | ||
3694 | 0x18, | ||
3695 | 0x18, | ||
3696 | 0x18, | ||
3697 | 0x18, | ||
3698 | 0x18, | ||
3699 | 0x18, | ||
3700 | |||
3701 | 0x18, | ||
3702 | 0x18, | ||
3703 | 0x18, | ||
3704 | 0x18, | ||
3705 | 0x18, | ||
3706 | 0x18, | ||
3707 | 0x18, | ||
3708 | 0xf8, | ||
3709 | 0x00, | ||
3710 | 0x00, | ||
3711 | 0x00, | ||
3712 | 0x00, | ||
3713 | 0x00, | ||
3714 | 0x00, | ||
3715 | 0x00, | ||
3716 | 0x00, | ||
3717 | |||
3718 | 0x00, | ||
3719 | 0x00, | ||
3720 | 0x00, | ||
3721 | 0x00, | ||
3722 | 0x00, | ||
3723 | 0x00, | ||
3724 | 0x00, | ||
3725 | 0x1f, | ||
3726 | 0x18, | ||
3727 | 0x18, | ||
3728 | 0x18, | ||
3729 | 0x18, | ||
3730 | 0x18, | ||
3731 | 0x18, | ||
3732 | 0x18, | ||
3733 | 0x18, | ||
3734 | |||
3735 | 0xff, | ||
3736 | 0xff, | ||
3737 | 0xff, | ||
3738 | 0xff, | ||
3739 | 0xff, | ||
3740 | 0xff, | ||
3741 | 0xff, | ||
3742 | 0xff, | ||
3743 | 0xff, | ||
3744 | 0xff, | ||
3745 | 0xff, | ||
3746 | 0xff, | ||
3747 | 0xff, | ||
3748 | 0xff, | ||
3749 | 0xff, | ||
3750 | 0xff, | ||
3751 | |||
3752 | 0x00, | ||
3753 | 0x00, | ||
3754 | 0x00, | ||
3755 | 0x00, | ||
3756 | 0x00, | ||
3757 | 0x00, | ||
3758 | 0x00, | ||
3759 | 0x00, | ||
3760 | 0xff, | ||
3761 | 0xff, | ||
3762 | 0xff, | ||
3763 | 0xff, | ||
3764 | 0xff, | ||
3765 | 0xff, | ||
3766 | 0xff, | ||
3767 | 0xff, | ||
3768 | |||
3769 | 0xf0, | ||
3770 | 0xf0, | ||
3771 | 0xf0, | ||
3772 | 0xf0, | ||
3773 | 0xf0, | ||
3774 | 0xf0, | ||
3775 | 0xf0, | ||
3776 | 0xf0, | ||
3777 | 0xf0, | ||
3778 | 0xf0, | ||
3779 | 0xf0, | ||
3780 | 0xf0, | ||
3781 | 0xf0, | ||
3782 | 0xf0, | ||
3783 | 0xf0, | ||
3784 | 0xf0, | ||
3785 | |||
3786 | 0x0f, | ||
3787 | 0x0f, | ||
3788 | 0x0f, | ||
3789 | 0x0f, | ||
3790 | 0x0f, | ||
3791 | 0x0f, | ||
3792 | 0x0f, | ||
3793 | 0x0f, | ||
3794 | 0x0f, | ||
3795 | 0x0f, | ||
3796 | 0x0f, | ||
3797 | 0x0f, | ||
3798 | 0x0f, | ||
3799 | 0x0f, | ||
3800 | 0x0f, | ||
3801 | 0x0f, | ||
3802 | |||
3803 | 0xff, | ||
3804 | 0xff, | ||
3805 | 0xff, | ||
3806 | 0xff, | ||
3807 | 0xff, | ||
3808 | 0xff, | ||
3809 | 0xff, | ||
3810 | 0xff, | ||
3811 | 0x00, | ||
3812 | 0x00, | ||
3813 | 0x00, | ||
3814 | 0x00, | ||
3815 | 0x00, | ||
3816 | 0x00, | ||
3817 | 0x00, | ||
3818 | 0x00, | ||
3819 | |||
3820 | 0x00, | ||
3821 | 0x00, | ||
3822 | 0x00, | ||
3823 | 0x00, | ||
3824 | 0x00, | ||
3825 | 0x00, | ||
3826 | 0x77, | ||
3827 | 0xcc, | ||
3828 | 0xcc, | ||
3829 | 0xcc, | ||
3830 | 0xcc, | ||
3831 | 0xde, | ||
3832 | 0x73, | ||
3833 | 0x00, | ||
3834 | 0x00, | ||
3835 | 0x00, | ||
3836 | |||
3837 | 0x00, | ||
3838 | 0x7c, | ||
3839 | 0xc6, | ||
3840 | 0xc6, | ||
3841 | 0xc6, | ||
3842 | 0xc4, | ||
3843 | 0xc8, | ||
3844 | 0xc4, | ||
3845 | 0xc6, | ||
3846 | 0xc6, | ||
3847 | 0xc6, | ||
3848 | 0xc6, | ||
3849 | 0xdc, | ||
3850 | 0xc0, | ||
3851 | 0xc0, | ||
3852 | 0x00, | ||
3853 | |||
3854 | 0x00, | ||
3855 | 0xff, | ||
3856 | 0x61, | ||
3857 | 0x60, | ||
3858 | 0x60, | ||
3859 | 0x60, | ||
3860 | 0x60, | ||
3861 | 0x60, | ||
3862 | 0x60, | ||
3863 | 0x60, | ||
3864 | 0x60, | ||
3865 | 0x60, | ||
3866 | 0xf0, | ||
3867 | 0x00, | ||
3868 | 0x00, | ||
3869 | 0x00, | ||
3870 | |||
3871 | 0x00, | ||
3872 | 0x00, | ||
3873 | 0x00, | ||
3874 | 0x00, | ||
3875 | 0x01, | ||
3876 | 0x7e, | ||
3877 | 0xa4, | ||
3878 | 0x24, | ||
3879 | 0x2c, | ||
3880 | 0x6c, | ||
3881 | 0x6c, | ||
3882 | 0x6c, | ||
3883 | 0x48, | ||
3884 | 0x00, | ||
3885 | 0x00, | ||
3886 | 0x00, | ||
3887 | |||
3888 | 0x00, | ||
3889 | 0xff, | ||
3890 | 0xc1, | ||
3891 | 0x60, | ||
3892 | 0x30, | ||
3893 | 0x18, | ||
3894 | 0x0c, | ||
3895 | 0x18, | ||
3896 | 0x30, | ||
3897 | 0x60, | ||
3898 | 0xc0, | ||
3899 | 0xc1, | ||
3900 | 0xfe, | ||
3901 | 0x00, | ||
3902 | 0x00, | ||
3903 | 0x00, | ||
3904 | |||
3905 | 0x00, | ||
3906 | 0x00, | ||
3907 | 0x00, | ||
3908 | 0x00, | ||
3909 | 0x00, | ||
3910 | 0x7f, | ||
3911 | 0xc8, | ||
3912 | 0xc8, | ||
3913 | 0xc8, | ||
3914 | 0xc8, | ||
3915 | 0xc8, | ||
3916 | 0xc8, | ||
3917 | 0x70, | ||
3918 | 0x00, | ||
3919 | 0x00, | ||
3920 | 0x00, | ||
3921 | |||
3922 | 0x00, | ||
3923 | 0x00, | ||
3924 | 0x00, | ||
3925 | 0x00, | ||
3926 | 0x00, | ||
3927 | 0x22, | ||
3928 | 0x66, | ||
3929 | 0x66, | ||
3930 | 0x66, | ||
3931 | 0x66, | ||
3932 | 0x66, | ||
3933 | 0x7c, | ||
3934 | 0x60, | ||
3935 | 0x60, | ||
3936 | 0x60, | ||
3937 | 0xc0, | ||
3938 | |||
3939 | 0x00, | ||
3940 | 0x00, | ||
3941 | 0x00, | ||
3942 | 0x00, | ||
3943 | 0x00, | ||
3944 | 0x76, | ||
3945 | 0xdc, | ||
3946 | 0x18, | ||
3947 | 0x18, | ||
3948 | 0x18, | ||
3949 | 0x18, | ||
3950 | 0x18, | ||
3951 | 0x10, | ||
3952 | 0x00, | ||
3953 | 0x00, | ||
3954 | 0x00, | ||
3955 | |||
3956 | 0x00, | ||
3957 | 0x38, | ||
3958 | 0x10, | ||
3959 | 0x7c, | ||
3960 | 0xd6, | ||
3961 | 0xd6, | ||
3962 | 0xd6, | ||
3963 | 0xd6, | ||
3964 | 0xd6, | ||
3965 | 0xd6, | ||
3966 | 0x7c, | ||
3967 | 0x10, | ||
3968 | 0x38, | ||
3969 | 0x00, | ||
3970 | 0x00, | ||
3971 | 0x00, | ||
3972 | |||
3973 | 0x00, | ||
3974 | 0x38, | ||
3975 | 0x6c, | ||
3976 | 0xc6, | ||
3977 | 0xc6, | ||
3978 | 0xc6, | ||
3979 | 0xfe, | ||
3980 | 0xc6, | ||
3981 | 0xc6, | ||
3982 | 0xc6, | ||
3983 | 0xc6, | ||
3984 | 0x6c, | ||
3985 | 0x38, | ||
3986 | 0x00, | ||
3987 | 0x00, | ||
3988 | 0x00, | ||
3989 | |||
3990 | 0x00, | ||
3991 | 0x3c, | ||
3992 | 0x66, | ||
3993 | 0xc3, | ||
3994 | 0xc3, | ||
3995 | 0xc3, | ||
3996 | 0xc3, | ||
3997 | 0xc3, | ||
3998 | 0x66, | ||
3999 | 0x24, | ||
4000 | 0x24, | ||
4001 | 0xa5, | ||
4002 | 0xe7, | ||
4003 | 0x00, | ||
4004 | 0x00, | ||
4005 | 0x00, | ||
4006 | |||
4007 | 0x00, | ||
4008 | 0x1e, | ||
4009 | 0x31, | ||
4010 | 0x30, | ||
4011 | 0x18, | ||
4012 | 0x0c, | ||
4013 | 0x3e, | ||
4014 | 0x66, | ||
4015 | 0x66, | ||
4016 | 0x66, | ||
4017 | 0x66, | ||
4018 | 0x66, | ||
4019 | 0x3c, | ||
4020 | 0x00, | ||
4021 | 0x00, | ||
4022 | 0x00, | ||
4023 | |||
4024 | 0x00, | ||
4025 | 0x00, | ||
4026 | 0x00, | ||
4027 | 0x00, | ||
4028 | 0x6e, | ||
4029 | 0xff, | ||
4030 | 0x99, | ||
4031 | 0x99, | ||
4032 | 0x99, | ||
4033 | 0x99, | ||
4034 | 0xff, | ||
4035 | 0x76, | ||
4036 | 0x00, | ||
4037 | 0x00, | ||
4038 | 0x00, | ||
4039 | 0x00, | ||
4040 | |||
4041 | 0x00, | ||
4042 | 0x00, | ||
4043 | 0x00, | ||
4044 | 0x02, | ||
4045 | 0x04, | ||
4046 | 0x7c, | ||
4047 | 0xca, | ||
4048 | 0x92, | ||
4049 | 0xa6, | ||
4050 | 0x7c, | ||
4051 | 0x40, | ||
4052 | 0x80, | ||
4053 | 0x00, | ||
4054 | 0x00, | ||
4055 | 0x00, | ||
4056 | 0x00, | ||
4057 | |||
4058 | 0x00, | ||
4059 | 0x1c, | ||
4060 | 0x30, | ||
4061 | 0x60, | ||
4062 | 0x60, | ||
4063 | 0x60, | ||
4064 | 0x7c, | ||
4065 | 0x60, | ||
4066 | 0x60, | ||
4067 | 0x60, | ||
4068 | 0x60, | ||
4069 | 0x30, | ||
4070 | 0x1c, | ||
4071 | 0x00, | ||
4072 | 0x00, | ||
4073 | 0x00, | ||
4074 | |||
4075 | 0x00, | ||
4076 | 0x00, | ||
4077 | 0x7c, | ||
4078 | 0xc6, | ||
4079 | 0xc6, | ||
4080 | 0xc6, | ||
4081 | 0xc6, | ||
4082 | 0xc6, | ||
4083 | 0xc6, | ||
4084 | 0xc6, | ||
4085 | 0xc6, | ||
4086 | 0xc6, | ||
4087 | 0xc6, | ||
4088 | 0x00, | ||
4089 | 0x00, | ||
4090 | 0x00, | ||
4091 | |||
4092 | 0x00, | ||
4093 | 0x00, | ||
4094 | 0x00, | ||
4095 | 0xfe, | ||
4096 | 0x00, | ||
4097 | 0x00, | ||
4098 | 0x00, | ||
4099 | 0x7c, | ||
4100 | 0x00, | ||
4101 | 0x00, | ||
4102 | 0x00, | ||
4103 | 0xfe, | ||
4104 | 0x00, | ||
4105 | 0x00, | ||
4106 | 0x00, | ||
4107 | 0x00, | ||
4108 | |||
4109 | 0x00, | ||
4110 | 0x00, | ||
4111 | 0x00, | ||
4112 | 0x00, | ||
4113 | 0x18, | ||
4114 | 0x18, | ||
4115 | 0x7e, | ||
4116 | 0x18, | ||
4117 | 0x18, | ||
4118 | 0x00, | ||
4119 | 0x00, | ||
4120 | 0x7e, | ||
4121 | 0x00, | ||
4122 | 0x00, | ||
4123 | 0x00, | ||
4124 | 0x00, | ||
4125 | |||
4126 | 0x00, | ||
4127 | 0x00, | ||
4128 | 0x00, | ||
4129 | 0x30, | ||
4130 | 0x18, | ||
4131 | 0x0c, | ||
4132 | 0x06, | ||
4133 | 0x0c, | ||
4134 | 0x18, | ||
4135 | 0x30, | ||
4136 | 0x00, | ||
4137 | 0x7e, | ||
4138 | 0x00, | ||
4139 | 0x00, | ||
4140 | 0x00, | ||
4141 | 0x00, | ||
4142 | |||
4143 | 0x00, | ||
4144 | 0x00, | ||
4145 | 0x00, | ||
4146 | 0x0c, | ||
4147 | 0x18, | ||
4148 | 0x30, | ||
4149 | 0x60, | ||
4150 | 0x30, | ||
4151 | 0x18, | ||
4152 | 0x0c, | ||
4153 | 0x00, | ||
4154 | 0x7e, | ||
4155 | 0x00, | ||
4156 | 0x00, | ||
4157 | 0x00, | ||
4158 | 0x00, | ||
4159 | |||
4160 | 0x00, | ||
4161 | 0x00, | ||
4162 | 0x00, | ||
4163 | 0x0e, | ||
4164 | 0x19, | ||
4165 | 0x1b, | ||
4166 | 0x18, | ||
4167 | 0x18, | ||
4168 | 0x18, | ||
4169 | 0x18, | ||
4170 | 0x18, | ||
4171 | 0x18, | ||
4172 | 0x18, | ||
4173 | 0x18, | ||
4174 | 0x18, | ||
4175 | 0x18, | ||
4176 | |||
4177 | 0x18, | ||
4178 | 0x18, | ||
4179 | 0x18, | ||
4180 | 0x18, | ||
4181 | 0x18, | ||
4182 | 0x18, | ||
4183 | 0x18, | ||
4184 | 0x18, | ||
4185 | 0x18, | ||
4186 | 0xd8, | ||
4187 | 0x98, | ||
4188 | 0x70, | ||
4189 | 0x00, | ||
4190 | 0x00, | ||
4191 | 0x00, | ||
4192 | 0x00, | ||
4193 | |||
4194 | 0x00, | ||
4195 | 0x00, | ||
4196 | 0x00, | ||
4197 | 0x00, | ||
4198 | 0x18, | ||
4199 | 0x18, | ||
4200 | 0x00, | ||
4201 | 0x7e, | ||
4202 | 0x00, | ||
4203 | 0x18, | ||
4204 | 0x18, | ||
4205 | 0x00, | ||
4206 | 0x00, | ||
4207 | 0x00, | ||
4208 | 0x00, | ||
4209 | 0x00, | ||
4210 | |||
4211 | 0x00, | ||
4212 | 0x00, | ||
4213 | 0x00, | ||
4214 | 0x00, | ||
4215 | 0x00, | ||
4216 | 0x76, | ||
4217 | 0xdc, | ||
4218 | 0x00, | ||
4219 | 0x00, | ||
4220 | 0x76, | ||
4221 | 0xdc, | ||
4222 | 0x00, | ||
4223 | 0x00, | ||
4224 | 0x00, | ||
4225 | 0x00, | ||
4226 | 0x00, | ||
4227 | |||
4228 | 0x00, | ||
4229 | 0x38, | ||
4230 | 0x44, | ||
4231 | 0x44, | ||
4232 | 0x44, | ||
4233 | 0x38, | ||
4234 | 0x00, | ||
4235 | 0x00, | ||
4236 | 0x00, | ||
4237 | 0x00, | ||
4238 | 0x00, | ||
4239 | 0x00, | ||
4240 | 0x00, | ||
4241 | 0x00, | ||
4242 | 0x00, | ||
4243 | 0x00, | ||
4244 | |||
4245 | 0x00, | ||
4246 | 0x00, | ||
4247 | 0x00, | ||
4248 | 0x00, | ||
4249 | 0x00, | ||
4250 | 0x00, | ||
4251 | 0x00, | ||
4252 | 0x18, | ||
4253 | 0x18, | ||
4254 | 0x00, | ||
4255 | 0x00, | ||
4256 | 0x00, | ||
4257 | 0x00, | ||
4258 | 0x00, | ||
4259 | 0x00, | ||
4260 | 0x00, | ||
4261 | |||
4262 | 0x00, | ||
4263 | 0x00, | ||
4264 | 0x00, | ||
4265 | 0x00, | ||
4266 | 0x00, | ||
4267 | 0x00, | ||
4268 | 0x00, | ||
4269 | 0x00, | ||
4270 | 0x18, | ||
4271 | 0x00, | ||
4272 | 0x00, | ||
4273 | 0x00, | ||
4274 | 0x00, | ||
4275 | 0x00, | ||
4276 | 0x00, | ||
4277 | 0x00, | ||
4278 | |||
4279 | 0x00, | ||
4280 | 0x00, | ||
4281 | 0x07, | ||
4282 | 0x06, | ||
4283 | 0x06, | ||
4284 | 0x0c, | ||
4285 | 0x0c, | ||
4286 | 0x08, | ||
4287 | 0x98, | ||
4288 | 0xd0, | ||
4289 | 0xf0, | ||
4290 | 0x60, | ||
4291 | 0x20, | ||
4292 | 0x00, | ||
4293 | 0x00, | ||
4294 | 0x00, | ||
4295 | |||
4296 | 0x00, | ||
4297 | 0xcc, | ||
4298 | 0x76, | ||
4299 | 0x66, | ||
4300 | 0x66, | ||
4301 | 0x66, | ||
4302 | 0x66, | ||
4303 | 0xf7, | ||
4304 | 0x00, | ||
4305 | 0x00, | ||
4306 | 0x00, | ||
4307 | 0x00, | ||
4308 | 0x00, | ||
4309 | 0x00, | ||
4310 | 0x00, | ||
4311 | 0x00, | ||
4312 | |||
4313 | 0x00, | ||
4314 | 0x70, | ||
4315 | 0x98, | ||
4316 | 0x18, | ||
4317 | 0x30, | ||
4318 | 0x60, | ||
4319 | 0x88, | ||
4320 | 0xf8, | ||
4321 | 0x00, | ||
4322 | 0x00, | ||
4323 | 0x00, | ||
4324 | 0x00, | ||
4325 | 0x00, | ||
4326 | 0x00, | ||
4327 | 0x00, | ||
4328 | 0x00, | ||
4329 | |||
4330 | 0x00, | ||
4331 | 0x00, | ||
4332 | 0x00, | ||
4333 | 0x00, | ||
4334 | 0x00, | ||
4335 | 0x7c, | ||
4336 | 0x64, | ||
4337 | 0x64, | ||
4338 | 0x64, | ||
4339 | 0x64, | ||
4340 | 0x64, | ||
4341 | 0x7c, | ||
4342 | 0x00, | ||
4343 | 0x00, | ||
4344 | 0x00, | ||
4345 | 0x00, | ||
4346 | |||
4347 | 0x00, | ||
4348 | 0x00, | ||
4349 | 0x00, | ||
4350 | 0x00, | ||
4351 | 0x00, | ||
4352 | 0x00, | ||
4353 | 0x00, | ||
4354 | 0x00, | ||
4355 | 0x00, | ||
4356 | 0x00, | ||
4357 | 0x00, | ||
4358 | 0x00, | ||
4359 | 0x00, | ||
4360 | 0x00, | ||
4361 | 0x00, | ||
4362 | 0x00, | ||
4363 | |||
4364 | }; | ||
4365 | |||
4366 | |||
4367 | const struct font_desc font_rl = { | ||
4368 | RL_IDX, | ||
4369 | "RomanLarge", | ||
4370 | 8, | ||
4371 | 16, | ||
4372 | patterns, | ||
4373 | -1 | ||
4374 | }; | ||
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c index 9be83bed1959..4fd07d9eca03 100644 --- a/drivers/video/console/fonts.c +++ b/drivers/video/console/fonts.c | |||
@@ -64,10 +64,6 @@ static const struct font_desc *fonts[] = { | |||
64 | #undef NO_FONTS | 64 | #undef NO_FONTS |
65 | &font_mini_4x6, | 65 | &font_mini_4x6, |
66 | #endif | 66 | #endif |
67 | #ifdef CONFIG_FONT_RL | ||
68 | #undef NO_FONTS | ||
69 | &font_rl, | ||
70 | #endif | ||
71 | }; | 67 | }; |
72 | 68 | ||
73 | #define num_fonts (sizeof(fonts)/sizeof(*fonts)) | 69 | #define num_fonts (sizeof(fonts)/sizeof(*fonts)) |
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 04417dc16c2e..2584daec7bbf 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c | |||
@@ -57,6 +57,9 @@ static struct fb_ops ffb_ops = { | |||
57 | .fb_sync = ffb_sync, | 57 | .fb_sync = ffb_sync, |
58 | .fb_mmap = ffb_mmap, | 58 | .fb_mmap = ffb_mmap, |
59 | .fb_ioctl = ffb_ioctl, | 59 | .fb_ioctl = ffb_ioctl, |
60 | #ifdef CONFIG_COMPAT | ||
61 | .fb_compat_ioctl = sbusfb_compat_ioctl, | ||
62 | #endif | ||
60 | }; | 63 | }; |
61 | 64 | ||
62 | /* Register layout and definitions */ | 65 | /* Register layout and definitions */ |
diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 84a7fe435bb8..376d4a171ec7 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c | |||
@@ -51,6 +51,9 @@ static struct fb_ops leo_ops = { | |||
51 | .fb_imageblit = cfb_imageblit, | 51 | .fb_imageblit = cfb_imageblit, |
52 | .fb_mmap = leo_mmap, | 52 | .fb_mmap = leo_mmap, |
53 | .fb_ioctl = leo_ioctl, | 53 | .fb_ioctl = leo_ioctl, |
54 | #ifdef CONFIG_COMPAT | ||
55 | .fb_compat_ioctl = sbusfb_compat_ioctl, | ||
56 | #endif | ||
54 | }; | 57 | }; |
55 | 58 | ||
56 | #define LEO_OFF_LC_SS0_KRN 0x00200000UL | 59 | #define LEO_OFF_LC_SS0_KRN 0x00200000UL |
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h index f60b1f432270..3353103e8b0b 100644 --- a/drivers/video/nvidia/nv_proto.h +++ b/drivers/video/nvidia/nv_proto.h | |||
@@ -42,7 +42,7 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn, | |||
42 | #define nvidia_probe_i2c_connector(p, c, edid) (-1) | 42 | #define nvidia_probe_i2c_connector(p, c, edid) (-1) |
43 | #endif | 43 | #endif |
44 | 44 | ||
45 | #ifdef CONFIG_FB_OF | 45 | #ifdef CONFIG_PPC_OF |
46 | int nvidia_probe_of_connector(struct fb_info *info, int conn, | 46 | int nvidia_probe_of_connector(struct fb_info *info, int conn, |
47 | u8 ** out_edid); | 47 | u8 ** out_edid); |
48 | #else | 48 | #else |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 0b40a2a721c1..bee09c6e48f6 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -1301,7 +1301,7 @@ static int nvidiafb_pan_display(struct fb_var_screeninfo *var, | |||
1301 | struct nvidia_par *par = info->par; | 1301 | struct nvidia_par *par = info->par; |
1302 | u32 total; | 1302 | u32 total; |
1303 | 1303 | ||
1304 | total = info->var.yoffset * info->fix.line_length + info->var.xoffset; | 1304 | total = var->yoffset * info->fix.line_length + var->xoffset; |
1305 | 1305 | ||
1306 | NVSetStartAddress(par, total); | 1306 | NVSetStartAddress(par, total); |
1307 | 1307 | ||
diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 2c856838694e..00d87f5bb7be 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/fb.h> | 26 | #include <linux/fb.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/pci.h> | ||
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
30 | #include <asm/prom.h> | 31 | #include <asm/prom.h> |
31 | 32 | ||
@@ -325,8 +326,8 @@ static void __init offb_init_nodriver(struct device_node *dp) | |||
325 | int *pp, i; | 326 | int *pp, i; |
326 | unsigned int len; | 327 | unsigned int len; |
327 | int width = 640, height = 480, depth = 8, pitch; | 328 | int width = 640, height = 480, depth = 8, pitch; |
328 | unsigned *up; | 329 | unsigned int rsize, *up; |
329 | unsigned long address; | 330 | unsigned long address = 0; |
330 | 331 | ||
331 | if ((pp = (int *) get_property(dp, "depth", &len)) != NULL | 332 | if ((pp = (int *) get_property(dp, "depth", &len)) != NULL |
332 | && len == sizeof(int)) | 333 | && len == sizeof(int)) |
@@ -344,10 +345,40 @@ static void __init offb_init_nodriver(struct device_node *dp) | |||
344 | pitch = 0x1000; | 345 | pitch = 0x1000; |
345 | } else | 346 | } else |
346 | pitch = width; | 347 | pitch = width; |
347 | if ((up = (unsigned *) get_property(dp, "address", &len)) != NULL | 348 | |
348 | && len == sizeof(unsigned)) | 349 | rsize = (unsigned long)pitch * (unsigned long)height * |
350 | (unsigned long)(depth / 8); | ||
351 | |||
352 | /* Try to match device to a PCI device in order to get a properly | ||
353 | * translated address rather then trying to decode the open firmware | ||
354 | * stuff in various incorrect ways | ||
355 | */ | ||
356 | #ifdef CONFIG_PCI | ||
357 | /* First try to locate the PCI device if any */ | ||
358 | { | ||
359 | struct pci_dev *pdev = NULL; | ||
360 | |||
361 | for_each_pci_dev(pdev) { | ||
362 | if (dp == pci_device_to_OF_node(pdev)) | ||
363 | break; | ||
364 | } | ||
365 | if (pdev) { | ||
366 | for (i = 0; i < 6 && address == 0; i++) { | ||
367 | if ((pci_resource_flags(pdev, i) & | ||
368 | IORESOURCE_MEM) && | ||
369 | (pci_resource_len(pdev, i) >= rsize)) | ||
370 | address = pci_resource_start(pdev, i); | ||
371 | } | ||
372 | pci_dev_put(pdev); | ||
373 | } | ||
374 | } | ||
375 | #endif /* CONFIG_PCI */ | ||
376 | |||
377 | if (address == 0 && | ||
378 | (up = (unsigned *) get_property(dp, "address", &len)) != NULL && | ||
379 | len == sizeof(unsigned)) | ||
349 | address = (u_long) * up; | 380 | address = (u_long) * up; |
350 | else { | 381 | if (address == 0) { |
351 | for (i = 0; i < dp->n_addrs; ++i) | 382 | for (i = 0; i < dp->n_addrs; ++i) |
352 | if (dp->addrs[i].size >= | 383 | if (dp->addrs[i].size >= |
353 | pitch * height * depth / 8) | 384 | pitch * height * depth / 8) |
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 9aaf65fb623a..18bcda23d2cf 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c | |||
@@ -48,6 +48,9 @@ static struct fb_ops p9100_ops = { | |||
48 | .fb_imageblit = cfb_imageblit, | 48 | .fb_imageblit = cfb_imageblit, |
49 | .fb_mmap = p9100_mmap, | 49 | .fb_mmap = p9100_mmap, |
50 | .fb_ioctl = p9100_ioctl, | 50 | .fb_ioctl = p9100_ioctl, |
51 | #ifdef CONFIG_COMPAT | ||
52 | .fb_compat_ioctl = sbusfb_compat_ioctl, | ||
53 | #endif | ||
51 | }; | 54 | }; |
52 | 55 | ||
53 | /* P9100 control registers */ | 56 | /* P9100 control registers */ |
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c index 34f72edba820..646c43f921c5 100644 --- a/drivers/video/sbuslib.c +++ b/drivers/video/sbuslib.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright (C) 2003 David S. Miller (davem@redhat.com) | 3 | * Copyright (C) 2003 David S. Miller (davem@redhat.com) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/compat.h> | ||
6 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
7 | #include <linux/module.h> | 8 | #include <linux/module.h> |
8 | #include <linux/string.h> | 9 | #include <linux/string.h> |
@@ -182,3 +183,109 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg, | |||
182 | }; | 183 | }; |
183 | } | 184 | } |
184 | EXPORT_SYMBOL(sbusfb_ioctl_helper); | 185 | EXPORT_SYMBOL(sbusfb_ioctl_helper); |
186 | |||
187 | #ifdef CONFIG_COMPAT | ||
188 | struct fbcmap32 { | ||
189 | int index; /* first element (0 origin) */ | ||
190 | int count; | ||
191 | u32 red; | ||
192 | u32 green; | ||
193 | u32 blue; | ||
194 | }; | ||
195 | |||
196 | #define FBIOPUTCMAP32 _IOW('F', 3, struct fbcmap32) | ||
197 | #define FBIOGETCMAP32 _IOW('F', 4, struct fbcmap32) | ||
198 | |||
199 | static int fbiogetputcmap(struct file *file, struct fb_info *info, | ||
200 | unsigned int cmd, unsigned long arg) | ||
201 | { | ||
202 | struct fbcmap32 __user *argp = (void __user *)arg; | ||
203 | struct fbcmap __user *p = compat_alloc_user_space(sizeof(*p)); | ||
204 | u32 addr; | ||
205 | int ret; | ||
206 | |||
207 | ret = copy_in_user(p, argp, 2 * sizeof(int)); | ||
208 | ret |= get_user(addr, &argp->red); | ||
209 | ret |= put_user(compat_ptr(addr), &p->red); | ||
210 | ret |= get_user(addr, &argp->green); | ||
211 | ret |= put_user(compat_ptr(addr), &p->green); | ||
212 | ret |= get_user(addr, &argp->blue); | ||
213 | ret |= put_user(compat_ptr(addr), &p->blue); | ||
214 | if (ret) | ||
215 | return -EFAULT; | ||
216 | return info->fbops->fb_ioctl(file->f_dentry->d_inode, file, | ||
217 | (cmd == FBIOPUTCMAP32) ? | ||
218 | FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, | ||
219 | (unsigned long)p, info); | ||
220 | } | ||
221 | |||
222 | struct fbcursor32 { | ||
223 | short set; /* what to set, choose from the list above */ | ||
224 | short enable; /* cursor on/off */ | ||
225 | struct fbcurpos pos; /* cursor position */ | ||
226 | struct fbcurpos hot; /* cursor hot spot */ | ||
227 | struct fbcmap32 cmap; /* color map info */ | ||
228 | struct fbcurpos size; /* cursor bit map size */ | ||
229 | u32 image; /* cursor image bits */ | ||
230 | u32 mask; /* cursor mask bits */ | ||
231 | }; | ||
232 | |||
233 | #define FBIOSCURSOR32 _IOW('F', 24, struct fbcursor32) | ||
234 | #define FBIOGCURSOR32 _IOW('F', 25, struct fbcursor32) | ||
235 | |||
236 | static int fbiogscursor(struct file *file, struct fb_info *info, | ||
237 | unsigned long arg) | ||
238 | { | ||
239 | struct fbcursor __user *p = compat_alloc_user_space(sizeof(*p)); | ||
240 | struct fbcursor32 __user *argp = (void __user *)arg; | ||
241 | compat_uptr_t addr; | ||
242 | int ret; | ||
243 | |||
244 | ret = copy_in_user(p, argp, | ||
245 | 2 * sizeof (short) + 2 * sizeof(struct fbcurpos)); | ||
246 | ret |= copy_in_user(&p->size, &argp->size, sizeof(struct fbcurpos)); | ||
247 | ret |= copy_in_user(&p->cmap, &argp->cmap, 2 * sizeof(int)); | ||
248 | ret |= get_user(addr, &argp->cmap.red); | ||
249 | ret |= put_user(compat_ptr(addr), &p->cmap.red); | ||
250 | ret |= get_user(addr, &argp->cmap.green); | ||
251 | ret |= put_user(compat_ptr(addr), &p->cmap.green); | ||
252 | ret |= get_user(addr, &argp->cmap.blue); | ||
253 | ret |= put_user(compat_ptr(addr), &p->cmap.blue); | ||
254 | ret |= get_user(addr, &argp->mask); | ||
255 | ret |= put_user(compat_ptr(addr), &p->mask); | ||
256 | ret |= get_user(addr, &argp->image); | ||
257 | ret |= put_user(compat_ptr(addr), &p->image); | ||
258 | if (ret) | ||
259 | return -EFAULT; | ||
260 | return info->fbops->fb_ioctl(file->f_dentry->d_inode, file, | ||
261 | FBIOSCURSOR, (unsigned long)p, info); | ||
262 | } | ||
263 | |||
264 | long sbusfb_compat_ioctl(struct file *file, unsigned int cmd, | ||
265 | unsigned long arg, struct fb_info *info) | ||
266 | { | ||
267 | switch (cmd) { | ||
268 | case FBIOGTYPE: | ||
269 | case FBIOSATTR: | ||
270 | case FBIOGATTR: | ||
271 | case FBIOSVIDEO: | ||
272 | case FBIOGVIDEO: | ||
273 | case FBIOGCURSOR32: /* This is not implemented yet. | ||
274 | Later it should be converted... */ | ||
275 | case FBIOSCURPOS: | ||
276 | case FBIOGCURPOS: | ||
277 | case FBIOGCURMAX: | ||
278 | return info->fbops->fb_ioctl(file->f_dentry->d_inode, | ||
279 | file, cmd, arg, info); | ||
280 | case FBIOPUTCMAP32: | ||
281 | return fbiogetputcmap(file, info, cmd, arg); | ||
282 | case FBIOGETCMAP32: | ||
283 | return fbiogetputcmap(file, info, cmd, arg); | ||
284 | case FBIOSCURSOR32: | ||
285 | return fbiogscursor(file, info, arg); | ||
286 | default: | ||
287 | return -ENOIOCTLCMD; | ||
288 | } | ||
289 | } | ||
290 | EXPORT_SYMBOL(sbusfb_compat_ioctl); | ||
291 | #endif | ||
diff --git a/drivers/video/sbuslib.h b/drivers/video/sbuslib.h index a6aa33ba09d6..b470e52ce9e2 100644 --- a/drivers/video/sbuslib.h +++ b/drivers/video/sbuslib.h | |||
@@ -20,5 +20,7 @@ extern int sbusfb_mmap_helper(struct sbus_mmap_map *map, | |||
20 | int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg, | 20 | int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg, |
21 | struct fb_info *info, | 21 | struct fb_info *info, |
22 | int type, int fb_depth, unsigned long fb_size); | 22 | int type, int fb_depth, unsigned long fb_size); |
23 | long sbusfb_compat_ioctl(struct file *file, unsigned int cmd, | ||
24 | unsigned long arg, struct fb_info *info); | ||
23 | 25 | ||
24 | #endif /* _SBUSLIB_H */ | 26 | #endif /* _SBUSLIB_H */ |
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index 59fff29bc02e..fe4f63f3849d 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c | |||
@@ -52,6 +52,9 @@ static struct fb_ops tcx_ops = { | |||
52 | .fb_imageblit = cfb_imageblit, | 52 | .fb_imageblit = cfb_imageblit, |
53 | .fb_mmap = tcx_mmap, | 53 | .fb_mmap = tcx_mmap, |
54 | .fb_ioctl = tcx_ioctl, | 54 | .fb_ioctl = tcx_ioctl, |
55 | #ifdef CONFIG_COMPAT | ||
56 | .fb_compat_ioctl = sbusfb_compat_ioctl, | ||
57 | #endif | ||
55 | }; | 58 | }; |
56 | 59 | ||
57 | /* THC definitions */ | 60 | /* THC definitions */ |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 2c3aa2fcfd91..3e58ddc2bc38 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -413,6 +413,7 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
413 | * region already (FIXME) */ | 413 | * region already (FIXME) */ |
414 | request_region(0x3c0, 32, "vesafb"); | 414 | request_region(0x3c0, 32, "vesafb"); |
415 | 415 | ||
416 | #ifdef CONFIG_MTRR | ||
416 | if (mtrr) { | 417 | if (mtrr) { |
417 | unsigned int temp_size = size_total; | 418 | unsigned int temp_size = size_total; |
418 | unsigned int type = 0; | 419 | unsigned int type = 0; |
@@ -450,6 +451,7 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
450 | } while (temp_size >= PAGE_SIZE && rc == -EINVAL); | 451 | } while (temp_size >= PAGE_SIZE && rc == -EINVAL); |
451 | } | 452 | } |
452 | } | 453 | } |
454 | #endif | ||
453 | 455 | ||
454 | info->fbops = &vesafb_ops; | 456 | info->fbops = &vesafb_ops; |
455 | info->var = vesafb_defined; | 457 | info->var = vesafb_defined; |
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index daa46051f55d..f6e24ee85f07 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c | |||
@@ -514,7 +514,7 @@ int __init w100fb_probe(struct platform_device *pdev) | |||
514 | if (remapped_fbuf == NULL) | 514 | if (remapped_fbuf == NULL) |
515 | goto out; | 515 | goto out; |
516 | 516 | ||
517 | info=framebuffer_alloc(sizeof(struct w100fb_par), dev); | 517 | info=framebuffer_alloc(sizeof(struct w100fb_par), &pdev->dev); |
518 | if (!info) { | 518 | if (!info) { |
519 | err = -ENOMEM; | 519 | err = -ENOMEM; |
520 | goto out; | 520 | goto out; |