diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-04-11 12:51:40 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-11 12:51:40 -0400 |
commit | 10a5fd5e6b7e2d464c9f95f67cade4ddbd63f4e1 (patch) | |
tree | eddf856286234f28cac747d20eb59d918e1bc8b5 /drivers | |
parent | c2a6585296009379e0f4eff39cdcb108b457ebf2 (diff) | |
parent | a145410dccdb44f81d3b56763ef9b6f721f4e47c (diff) |
Merge branch 'master'
Conflicts:
drivers/scsi/libata-scsi.c
include/linux/libata.h
Diffstat (limited to 'drivers')
91 files changed, 3187 insertions, 3453 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 5cb96300eb0f..c24652d31bf9 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -329,7 +329,7 @@ config ACPI_CONTAINER | |||
329 | config ACPI_HOTPLUG_MEMORY | 329 | config ACPI_HOTPLUG_MEMORY |
330 | tristate "Memory Hotplug" | 330 | tristate "Memory Hotplug" |
331 | depends on ACPI | 331 | depends on ACPI |
332 | depends on MEMORY_HOTPLUG | 332 | depends on MEMORY_HOTPLUG || X86_64 |
333 | default n | 333 | default n |
334 | help | 334 | help |
335 | This driver adds supports for ACPI Memory Hotplug. This driver | 335 | This driver adds supports for ACPI Memory Hotplug. This driver |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 16c513aa4d48..c80c3aeed004 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -106,7 +106,7 @@ static ssize_t node_read_numastat(struct sys_device * dev, char * buf) | |||
106 | other_node = 0; | 106 | other_node = 0; |
107 | for (i = 0; i < MAX_NR_ZONES; i++) { | 107 | for (i = 0; i < MAX_NR_ZONES; i++) { |
108 | struct zone *z = &pg->node_zones[i]; | 108 | struct zone *z = &pg->node_zones[i]; |
109 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 109 | for_each_online_cpu(cpu) { |
110 | struct per_cpu_pageset *ps = zone_pcp(z,cpu); | 110 | struct per_cpu_pageset *ps = zone_pcp(z,cpu); |
111 | numa_hit += ps->numa_hit; | 111 | numa_hit += ps->numa_hit; |
112 | numa_miss += ps->numa_miss; | 112 | numa_miss += ps->numa_miss; |
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c index ce4a1ce59d6a..ec004897b634 100644 --- a/drivers/cdrom/aztcd.c +++ b/drivers/cdrom/aztcd.c | |||
@@ -1763,7 +1763,7 @@ static int __init aztcd_init(void) | |||
1763 | release_region(azt_port, 4); | 1763 | release_region(azt_port, 4); |
1764 | } | 1764 | } |
1765 | } | 1765 | } |
1766 | if ((azt_port_auto[i] == 0) || (i == 16)) { | 1766 | if ((i == 16) || (azt_port_auto[i] == 0)) { |
1767 | printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n"); | 1767 | printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n"); |
1768 | return -EIO; | 1768 | return -EIO; |
1769 | } | 1769 | } |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 889cad07774e..402296670d3a 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -805,10 +805,6 @@ config S3C2410_RTC | |||
805 | Samsung S3C2410. This can provide periodic interrupt rates | 805 | Samsung S3C2410. This can provide periodic interrupt rates |
806 | from 1Hz to 64Hz for user programs, and wakeup from Alarm. | 806 | from 1Hz to 64Hz for user programs, and wakeup from Alarm. |
807 | 807 | ||
808 | config RTC_VR41XX | ||
809 | tristate "NEC VR4100 series Real Time Clock Support" | ||
810 | depends on CPU_VR41XX | ||
811 | |||
812 | config COBALT_LCD | 808 | config COBALT_LCD |
813 | bool "Support for Cobalt LCD" | 809 | bool "Support for Cobalt LCD" |
814 | depends on MIPS_COBALT | 810 | depends on MIPS_COBALT |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index a73cb4956928..f5b01c6d498e 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -67,7 +67,6 @@ obj-$(CONFIG_SGI_DS1286) += ds1286.o | |||
67 | obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o | 67 | obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o |
68 | obj-$(CONFIG_DS1302) += ds1302.o | 68 | obj-$(CONFIG_DS1302) += ds1302.o |
69 | obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o | 69 | obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o |
70 | obj-$(CONFIG_RTC_VR41XX) += vr41xx_rtc.o | ||
71 | ifeq ($(CONFIG_GENERIC_NVRAM),y) | 70 | ifeq ($(CONFIG_GENERIC_NVRAM),y) |
72 | obj-$(CONFIG_NVRAM) += generic_nvram.o | 71 | obj-$(CONFIG_NVRAM) += generic_nvram.o |
73 | else | 72 | else |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 927a5bbe112c..a370e7a0bad5 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -142,7 +142,7 @@ static int ac_register_board(unsigned long physloc, void __iomem *loc, | |||
142 | if (!boardno) | 142 | if (!boardno) |
143 | boardno = readb(loc + NUMCARD_OWNER_TO_PC); | 143 | boardno = readb(loc + NUMCARD_OWNER_TO_PC); |
144 | 144 | ||
145 | if (!boardno && boardno > MAX_BOARD) { | 145 | if (!boardno || boardno > MAX_BOARD) { |
146 | printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n", | 146 | printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n", |
147 | boardno, physloc, MAX_BOARD); | 147 | boardno, physloc, MAX_BOARD); |
148 | return 0; | 148 | return 0; |
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index a229915ce1b2..87dcaa237f07 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -490,7 +490,7 @@ for (i = 0; i < 10; i++) \ | |||
490 | release_region(dtlk_portlist[i], DTLK_IO_EXTENT); | 490 | release_region(dtlk_portlist[i], DTLK_IO_EXTENT); |
491 | } | 491 | } |
492 | 492 | ||
493 | printk(KERN_INFO "\nDoubleTalk PC - not found\n"); | 493 | printk(KERN_INFO "DoubleTalk PC - not found\n"); |
494 | return -ENODEV; | 494 | return -ENODEV; |
495 | } | 495 | } |
496 | 496 | ||
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 0ded046d5aa8..9f2f8fdec69a 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -941,6 +941,7 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) | |||
941 | list_del(&msg->link); | 941 | list_del(&msg->link); |
942 | list_add_tail(&msg->link, &msgs); | 942 | list_add_tail(&msg->link, &msgs); |
943 | } | 943 | } |
944 | intf->waiting_events_count = 0; | ||
944 | } | 945 | } |
945 | 946 | ||
946 | /* Hold the events lock while doing this to preserve order. */ | 947 | /* Hold the events lock while doing this to preserve order. */ |
@@ -2916,6 +2917,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf, | |||
2916 | 2917 | ||
2917 | copy_event_into_recv_msg(recv_msg, msg); | 2918 | copy_event_into_recv_msg(recv_msg, msg); |
2918 | list_add_tail(&(recv_msg->link), &(intf->waiting_events)); | 2919 | list_add_tail(&(recv_msg->link), &(intf->waiting_events)); |
2920 | intf->waiting_events_count++; | ||
2919 | } else { | 2921 | } else { |
2920 | /* There's too many things in the queue, discard this | 2922 | /* There's too many things in the queue, discard this |
2921 | message. */ | 2923 | message. */ |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 86be04b241e1..58f3512c52e1 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1584,7 +1584,6 @@ u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dpo | |||
1584 | 1584 | ||
1585 | return twothirdsMD4Transform(daddr, hash); | 1585 | return twothirdsMD4Transform(daddr, hash); |
1586 | } | 1586 | } |
1587 | EXPORT_SYMBOL(secure_ipv6_port_ephemeral); | ||
1588 | #endif | 1587 | #endif |
1589 | 1588 | ||
1590 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) | 1589 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) |
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 2546637a55c0..f58ad7f68267 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c | |||
@@ -327,7 +327,7 @@ static ssize_t store_received_ref_clk3a(struct device *d, | |||
327 | return strnlen(buf, count); | 327 | return strnlen(buf, count); |
328 | } | 328 | } |
329 | 329 | ||
330 | static DEVICE_ATTR(received_ref_clk3a, S_IWUGO, NULL, | 330 | static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL, |
331 | store_received_ref_clk3a); | 331 | store_received_ref_clk3a); |
332 | 332 | ||
333 | 333 | ||
@@ -349,7 +349,7 @@ static ssize_t store_received_ref_clk3b(struct device *d, | |||
349 | return strnlen(buf, count); | 349 | return strnlen(buf, count); |
350 | } | 350 | } |
351 | 351 | ||
352 | static DEVICE_ATTR(received_ref_clk3b, S_IWUGO, NULL, | 352 | static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL, |
353 | store_received_ref_clk3b); | 353 | store_received_ref_clk3b); |
354 | 354 | ||
355 | 355 | ||
@@ -371,7 +371,7 @@ static ssize_t store_enable_clk3b_output(struct device *d, | |||
371 | return strnlen(buf, count); | 371 | return strnlen(buf, count); |
372 | } | 372 | } |
373 | 373 | ||
374 | static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL, | 374 | static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL, |
375 | store_enable_clk3b_output); | 375 | store_enable_clk3b_output); |
376 | 376 | ||
377 | static ssize_t store_enable_clk3a_output(struct device *d, | 377 | static ssize_t store_enable_clk3a_output(struct device *d, |
@@ -392,7 +392,7 @@ static ssize_t store_enable_clk3a_output(struct device *d, | |||
392 | return strnlen(buf, count); | 392 | return strnlen(buf, count); |
393 | } | 393 | } |
394 | 394 | ||
395 | static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL, | 395 | static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL, |
396 | store_enable_clk3a_output); | 396 | store_enable_clk3a_output); |
397 | 397 | ||
398 | static ssize_t store_enable_clkb1_output(struct device *d, | 398 | static ssize_t store_enable_clkb1_output(struct device *d, |
@@ -413,7 +413,7 @@ static ssize_t store_enable_clkb1_output(struct device *d, | |||
413 | return strnlen(buf, count); | 413 | return strnlen(buf, count); |
414 | } | 414 | } |
415 | 415 | ||
416 | static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL, | 416 | static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL, |
417 | store_enable_clkb1_output); | 417 | store_enable_clkb1_output); |
418 | 418 | ||
419 | 419 | ||
@@ -435,7 +435,7 @@ static ssize_t store_enable_clka1_output(struct device *d, | |||
435 | return strnlen(buf, count); | 435 | return strnlen(buf, count); |
436 | } | 436 | } |
437 | 437 | ||
438 | static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL, | 438 | static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL, |
439 | store_enable_clka1_output); | 439 | store_enable_clka1_output); |
440 | 440 | ||
441 | static ssize_t store_enable_clkb0_output(struct device *d, | 441 | static ssize_t store_enable_clkb0_output(struct device *d, |
@@ -456,7 +456,7 @@ static ssize_t store_enable_clkb0_output(struct device *d, | |||
456 | return strnlen(buf, count); | 456 | return strnlen(buf, count); |
457 | } | 457 | } |
458 | 458 | ||
459 | static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL, | 459 | static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL, |
460 | store_enable_clkb0_output); | 460 | store_enable_clkb0_output); |
461 | 461 | ||
462 | static ssize_t store_enable_clka0_output(struct device *d, | 462 | static ssize_t store_enable_clka0_output(struct device *d, |
@@ -477,7 +477,7 @@ static ssize_t store_enable_clka0_output(struct device *d, | |||
477 | return strnlen(buf, count); | 477 | return strnlen(buf, count); |
478 | } | 478 | } |
479 | 479 | ||
480 | static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, | 480 | static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL, |
481 | store_enable_clka0_output); | 481 | store_enable_clka0_output); |
482 | 482 | ||
483 | static ssize_t store_select_amcb2_transmit_clock(struct device *d, | 483 | static ssize_t store_select_amcb2_transmit_clock(struct device *d, |
@@ -519,7 +519,7 @@ static ssize_t store_select_amcb2_transmit_clock(struct device *d, | |||
519 | return strnlen(buf, count); | 519 | return strnlen(buf, count); |
520 | } | 520 | } |
521 | 521 | ||
522 | static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL, | 522 | static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL, |
523 | store_select_amcb2_transmit_clock); | 523 | store_select_amcb2_transmit_clock); |
524 | 524 | ||
525 | static ssize_t store_select_amcb1_transmit_clock(struct device *d, | 525 | static ssize_t store_select_amcb1_transmit_clock(struct device *d, |
@@ -560,7 +560,7 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d, | |||
560 | return strnlen(buf, count); | 560 | return strnlen(buf, count); |
561 | } | 561 | } |
562 | 562 | ||
563 | static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL, | 563 | static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL, |
564 | store_select_amcb1_transmit_clock); | 564 | store_select_amcb1_transmit_clock); |
565 | 565 | ||
566 | static ssize_t store_select_redundant_clock(struct device *d, | 566 | static ssize_t store_select_redundant_clock(struct device *d, |
@@ -581,7 +581,7 @@ static ssize_t store_select_redundant_clock(struct device *d, | |||
581 | return strnlen(buf, count); | 581 | return strnlen(buf, count); |
582 | } | 582 | } |
583 | 583 | ||
584 | static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL, | 584 | static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL, |
585 | store_select_redundant_clock); | 585 | store_select_redundant_clock); |
586 | 586 | ||
587 | static ssize_t store_select_ref_frequency(struct device *d, | 587 | static ssize_t store_select_ref_frequency(struct device *d, |
@@ -602,7 +602,7 @@ static ssize_t store_select_ref_frequency(struct device *d, | |||
602 | return strnlen(buf, count); | 602 | return strnlen(buf, count); |
603 | } | 603 | } |
604 | 604 | ||
605 | static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL, | 605 | static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL, |
606 | store_select_ref_frequency); | 606 | store_select_ref_frequency); |
607 | 607 | ||
608 | static ssize_t store_filter_select(struct device *d, | 608 | static ssize_t store_filter_select(struct device *d, |
@@ -623,7 +623,7 @@ static ssize_t store_filter_select(struct device *d, | |||
623 | return strnlen(buf, count); | 623 | return strnlen(buf, count); |
624 | } | 624 | } |
625 | 625 | ||
626 | static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select); | 626 | static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select); |
627 | 627 | ||
628 | static ssize_t store_hardware_switching_mode(struct device *d, | 628 | static ssize_t store_hardware_switching_mode(struct device *d, |
629 | struct device_attribute *attr, const char *buf, size_t count) | 629 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -643,7 +643,7 @@ static ssize_t store_hardware_switching_mode(struct device *d, | |||
643 | return strnlen(buf, count); | 643 | return strnlen(buf, count); |
644 | } | 644 | } |
645 | 645 | ||
646 | static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL, | 646 | static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL, |
647 | store_hardware_switching_mode); | 647 | store_hardware_switching_mode); |
648 | 648 | ||
649 | static ssize_t store_hardware_switching(struct device *d, | 649 | static ssize_t store_hardware_switching(struct device *d, |
@@ -664,7 +664,7 @@ static ssize_t store_hardware_switching(struct device *d, | |||
664 | return strnlen(buf, count); | 664 | return strnlen(buf, count); |
665 | } | 665 | } |
666 | 666 | ||
667 | static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL, | 667 | static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL, |
668 | store_hardware_switching); | 668 | store_hardware_switching); |
669 | 669 | ||
670 | static ssize_t store_refalign (struct device *d, | 670 | static ssize_t store_refalign (struct device *d, |
@@ -684,7 +684,7 @@ static ssize_t store_refalign (struct device *d, | |||
684 | return strnlen(buf, count); | 684 | return strnlen(buf, count); |
685 | } | 685 | } |
686 | 686 | ||
687 | static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign); | 687 | static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign); |
688 | 688 | ||
689 | static ssize_t store_mode_select (struct device *d, | 689 | static ssize_t store_mode_select (struct device *d, |
690 | struct device_attribute *attr, const char *buf, size_t count) | 690 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -704,7 +704,7 @@ static ssize_t store_mode_select (struct device *d, | |||
704 | return strnlen(buf, count); | 704 | return strnlen(buf, count); |
705 | } | 705 | } |
706 | 706 | ||
707 | static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select); | 707 | static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select); |
708 | 708 | ||
709 | static ssize_t store_reset (struct device *d, | 709 | static ssize_t store_reset (struct device *d, |
710 | struct device_attribute *attr, const char *buf, size_t count) | 710 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -724,7 +724,7 @@ static ssize_t store_reset (struct device *d, | |||
724 | return strnlen(buf, count); | 724 | return strnlen(buf, count); |
725 | } | 725 | } |
726 | 726 | ||
727 | static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset); | 727 | static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset); |
728 | 728 | ||
729 | static struct attribute *tlclk_sysfs_entries[] = { | 729 | static struct attribute *tlclk_sysfs_entries[] = { |
730 | &dev_attr_current_ref.attr, | 730 | &dev_attr_current_ref.attr, |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 98b126c2ded8..f70a47eadb52 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -351,10 +351,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
351 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 351 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
352 | return size; | 352 | return size; |
353 | } | 353 | } |
354 | |||
355 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | 354 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); |
356 | 355 | ||
357 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size) | 356 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, |
357 | size_t size) | ||
358 | { | 358 | { |
359 | int copied = 0; | 359 | int copied = 0; |
360 | do { | 360 | do { |
@@ -368,17 +368,16 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, s | |||
368 | tb->used += space; | 368 | tb->used += space; |
369 | copied += space; | 369 | copied += space; |
370 | chars += space; | 370 | chars += space; |
371 | /* printk("Flip insert %d.\n", space); */ | ||
372 | } | 371 | } |
373 | /* There is a small chance that we need to split the data over | 372 | /* There is a small chance that we need to split the data over |
374 | several buffers. If this is the case we must loop */ | 373 | several buffers. If this is the case we must loop */ |
375 | while (unlikely(size > copied)); | 374 | while (unlikely(size > copied)); |
376 | return copied; | 375 | return copied; |
377 | } | 376 | } |
378 | |||
379 | EXPORT_SYMBOL(tty_insert_flip_string); | 377 | EXPORT_SYMBOL(tty_insert_flip_string); |
380 | 378 | ||
381 | int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) | 379 | int tty_insert_flip_string_flags(struct tty_struct *tty, |
380 | const unsigned char *chars, const char *flags, size_t size) | ||
382 | { | 381 | { |
383 | int copied = 0; | 382 | int copied = 0; |
384 | do { | 383 | do { |
@@ -399,9 +398,20 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *ch | |||
399 | while (unlikely(size > copied)); | 398 | while (unlikely(size > copied)); |
400 | return copied; | 399 | return copied; |
401 | } | 400 | } |
402 | |||
403 | EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); | 401 | EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); |
404 | 402 | ||
403 | void tty_schedule_flip(struct tty_struct *tty) | ||
404 | { | ||
405 | unsigned long flags; | ||
406 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
407 | if (tty->buf.tail != NULL) { | ||
408 | tty->buf.tail->active = 0; | ||
409 | tty->buf.tail->commit = tty->buf.tail->used; | ||
410 | } | ||
411 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
412 | schedule_delayed_work(&tty->buf.work, 1); | ||
413 | } | ||
414 | EXPORT_SYMBOL(tty_schedule_flip); | ||
405 | 415 | ||
406 | /* | 416 | /* |
407 | * Prepare a block of space in the buffer for data. Returns the length | 417 | * Prepare a block of space in the buffer for data. Returns the length |
@@ -1730,7 +1740,7 @@ static void release_dev(struct file * filp) | |||
1730 | { | 1740 | { |
1731 | struct tty_struct *tty, *o_tty; | 1741 | struct tty_struct *tty, *o_tty; |
1732 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1742 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1733 | int devpts_master, devpts; | 1743 | int devpts; |
1734 | int idx; | 1744 | int idx; |
1735 | char buf[64]; | 1745 | char buf[64]; |
1736 | unsigned long flags; | 1746 | unsigned long flags; |
@@ -1747,7 +1757,6 @@ static void release_dev(struct file * filp) | |||
1747 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1757 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1748 | tty->driver->subtype == PTY_TYPE_MASTER); | 1758 | tty->driver->subtype == PTY_TYPE_MASTER); |
1749 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1759 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1750 | devpts_master = pty_master && devpts; | ||
1751 | o_tty = tty->link; | 1760 | o_tty = tty->link; |
1752 | 1761 | ||
1753 | #ifdef TTY_PARANOIA_CHECK | 1762 | #ifdef TTY_PARANOIA_CHECK |
@@ -2185,6 +2194,7 @@ static int ptmx_open(struct inode * inode, struct file * filp) | |||
2185 | return 0; | 2194 | return 0; |
2186 | out1: | 2195 | out1: |
2187 | release_dev(filp); | 2196 | release_dev(filp); |
2197 | return retval; | ||
2188 | out: | 2198 | out: |
2189 | down(&allocated_ptys_lock); | 2199 | down(&allocated_ptys_lock); |
2190 | idr_remove(&allocated_ptys, index); | 2200 | idr_remove(&allocated_ptys, index); |
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index 23a9e1ea8e32..1659f6c41458 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
@@ -509,12 +509,22 @@ static int hdaps_dmi_match_invert(struct dmi_system_id *id) | |||
509 | } \ | 509 | } \ |
510 | } | 510 | } |
511 | 511 | ||
512 | #define HDAPS_DMI_MATCH_LENOVO(model) { \ | ||
513 | .ident = "Lenovo " model, \ | ||
514 | .callback = hdaps_dmi_match_invert, \ | ||
515 | .matches = { \ | ||
516 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), \ | ||
517 | DMI_MATCH(DMI_PRODUCT_VERSION, model) \ | ||
518 | } \ | ||
519 | } | ||
520 | |||
512 | static int __init hdaps_init(void) | 521 | static int __init hdaps_init(void) |
513 | { | 522 | { |
514 | int ret; | 523 | int ret; |
515 | 524 | ||
516 | /* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */ | 525 | /* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */ |
517 | struct dmi_system_id hdaps_whitelist[] = { | 526 | struct dmi_system_id hdaps_whitelist[] = { |
527 | HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), | ||
518 | HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), | 528 | HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), |
519 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), | 529 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), |
520 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), | 530 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), |
@@ -524,15 +534,17 @@ static int __init hdaps_init(void) | |||
524 | HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), | 534 | HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), |
525 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"), | 535 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"), |
526 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), | 536 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), |
537 | HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"), | ||
527 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), | 538 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), |
528 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"), | 539 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"), |
529 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), | 540 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), |
541 | HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"), | ||
530 | { .ident = NULL } | 542 | { .ident = NULL } |
531 | }; | 543 | }; |
532 | 544 | ||
533 | if (!dmi_check_system(hdaps_whitelist)) { | 545 | if (!dmi_check_system(hdaps_whitelist)) { |
534 | printk(KERN_WARNING "hdaps: supported laptop not found!\n"); | 546 | printk(KERN_WARNING "hdaps: supported laptop not found!\n"); |
535 | ret = -ENXIO; | 547 | ret = -ENODEV; |
536 | goto out; | 548 | goto out; |
537 | } | 549 | } |
538 | 550 | ||
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig index 53c4fb62ed85..5b203fe21dcd 100644 --- a/drivers/isdn/gigaset/Kconfig +++ b/drivers/isdn/gigaset/Kconfig | |||
@@ -3,8 +3,8 @@ menu "Siemens Gigaset" | |||
3 | 3 | ||
4 | config ISDN_DRV_GIGASET | 4 | config ISDN_DRV_GIGASET |
5 | tristate "Siemens Gigaset support (isdn)" | 5 | tristate "Siemens Gigaset support (isdn)" |
6 | depends on ISDN_I4L && m | 6 | depends on ISDN_I4L |
7 | # depends on ISDN_I4L && MODULES | 7 | select CRC_CCITT |
8 | help | 8 | help |
9 | Say m here if you have a Gigaset or Sinus isdn device. | 9 | Say m here if you have a Gigaset or Sinus isdn device. |
10 | 10 | ||
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c index 171f8b703d61..ce3cd77094b3 100644 --- a/drivers/isdn/gigaset/asyncdata.c +++ b/drivers/isdn/gigaset/asyncdata.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>, | 4 | * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>, |
5 | * Hansjoerg Lipp <hjlipp@web.de>, | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Stefan Eilers <Eilers.Stefan@epost.de>. | 6 | * Stefan Eilers. |
7 | * | 7 | * |
8 | * ===================================================================== | 8 | * ===================================================================== |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
@@ -11,10 +11,6 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: asyncdata.c,v 1.2.2.7 2005/11/13 23:05:18 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
@@ -45,7 +41,7 @@ static inline int muststuff(unsigned char c) | |||
45 | * number of processed bytes | 41 | * number of processed bytes |
46 | */ | 42 | */ |
47 | static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, | 43 | static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, |
48 | struct inbuf_t *inbuf) | 44 | struct inbuf_t *inbuf) |
49 | { | 45 | { |
50 | struct cardstate *cs = inbuf->cs; | 46 | struct cardstate *cs = inbuf->cs; |
51 | unsigned cbytes = cs->cbytes; | 47 | unsigned cbytes = cs->cbytes; |
@@ -55,10 +51,11 @@ static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, | |||
55 | for (;;) { | 51 | for (;;) { |
56 | cs->respdata[cbytes] = c; | 52 | cs->respdata[cbytes] = c; |
57 | if (c == 10 || c == 13) { | 53 | if (c == 10 || c == 13) { |
58 | dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", | 54 | gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", |
59 | __func__, cbytes); | 55 | __func__, cbytes); |
60 | cs->cbytes = cbytes; | 56 | cs->cbytes = cbytes; |
61 | gigaset_handle_modem_response(cs); /* can change cs->dle */ | 57 | gigaset_handle_modem_response(cs); /* can change |
58 | cs->dle */ | ||
62 | cbytes = 0; | 59 | cbytes = 0; |
63 | 60 | ||
64 | if (cs->dle && | 61 | if (cs->dle && |
@@ -71,7 +68,7 @@ static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, | |||
71 | if (cbytes < MAX_RESP_SIZE - 1) | 68 | if (cbytes < MAX_RESP_SIZE - 1) |
72 | cbytes++; | 69 | cbytes++; |
73 | else | 70 | else |
74 | warn("response too large"); | 71 | dev_warn(cs->dev, "response too large\n"); |
75 | } | 72 | } |
76 | 73 | ||
77 | if (!numbytes) | 74 | if (!numbytes) |
@@ -96,11 +93,12 @@ static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, | |||
96 | * number of processed bytes | 93 | * number of processed bytes |
97 | */ | 94 | */ |
98 | static inline int lock_loop(unsigned char *src, int numbytes, | 95 | static inline int lock_loop(unsigned char *src, int numbytes, |
99 | struct inbuf_t *inbuf) | 96 | struct inbuf_t *inbuf) |
100 | { | 97 | { |
101 | struct cardstate *cs = inbuf->cs; | 98 | struct cardstate *cs = inbuf->cs; |
102 | 99 | ||
103 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", numbytes, src, 0); | 100 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", |
101 | numbytes, src); | ||
104 | gigaset_if_receive(cs, src, numbytes); | 102 | gigaset_if_receive(cs, src, numbytes); |
105 | 103 | ||
106 | return numbytes; | 104 | return numbytes; |
@@ -115,24 +113,18 @@ static inline int lock_loop(unsigned char *src, int numbytes, | |||
115 | * numbytes (all bytes processed) on error --FIXME | 113 | * numbytes (all bytes processed) on error --FIXME |
116 | */ | 114 | */ |
117 | static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes, | 115 | static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes, |
118 | struct inbuf_t *inbuf) | 116 | struct inbuf_t *inbuf) |
119 | { | 117 | { |
120 | struct cardstate *cs = inbuf->cs; | 118 | struct cardstate *cs = inbuf->cs; |
121 | struct bc_state *bcs = inbuf->bcs; | 119 | struct bc_state *bcs = inbuf->bcs; |
122 | int inputstate; | 120 | int inputstate = bcs->inputstate; |
123 | __u16 fcs; | 121 | __u16 fcs = bcs->fcs; |
124 | struct sk_buff *skb; | 122 | struct sk_buff *skb = bcs->skb; |
125 | unsigned char error; | 123 | unsigned char error; |
126 | struct sk_buff *compskb; | 124 | struct sk_buff *compskb; |
127 | int startbytes = numbytes; | 125 | int startbytes = numbytes; |
128 | int l; | 126 | int l; |
129 | 127 | ||
130 | IFNULLRETVAL(bcs, numbytes); | ||
131 | inputstate = bcs->inputstate; | ||
132 | fcs = bcs->fcs; | ||
133 | skb = bcs->skb; | ||
134 | IFNULLRETVAL(skb, numbytes); | ||
135 | |||
136 | if (unlikely(inputstate & INS_byte_stuff)) { | 128 | if (unlikely(inputstate & INS_byte_stuff)) { |
137 | inputstate &= ~INS_byte_stuff; | 129 | inputstate &= ~INS_byte_stuff; |
138 | goto byte_stuff; | 130 | goto byte_stuff; |
@@ -156,39 +148,37 @@ byte_stuff: | |||
156 | c ^= PPP_TRANS; | 148 | c ^= PPP_TRANS; |
157 | #ifdef CONFIG_GIGASET_DEBUG | 149 | #ifdef CONFIG_GIGASET_DEBUG |
158 | if (unlikely(!muststuff(c))) | 150 | if (unlikely(!muststuff(c))) |
159 | dbg(DEBUG_HDLC, | 151 | gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c); |
160 | "byte stuffed: 0x%02x", c); | ||
161 | #endif | 152 | #endif |
162 | } else if (unlikely(c == PPP_FLAG)) { | 153 | } else if (unlikely(c == PPP_FLAG)) { |
163 | if (unlikely(inputstate & INS_skip_frame)) { | 154 | if (unlikely(inputstate & INS_skip_frame)) { |
164 | if (!(inputstate & INS_have_data)) { /* 7E 7E */ | 155 | if (!(inputstate & INS_have_data)) { /* 7E 7E */ |
165 | //dbg(DEBUG_HDLC, "(7e)7e------------------------"); | ||
166 | #ifdef CONFIG_GIGASET_DEBUG | 156 | #ifdef CONFIG_GIGASET_DEBUG |
167 | ++bcs->emptycount; | 157 | ++bcs->emptycount; |
168 | #endif | 158 | #endif |
169 | } else | 159 | } else |
170 | dbg(DEBUG_HDLC, | 160 | gig_dbg(DEBUG_HDLC, |
171 | "7e----------------------------"); | 161 | "7e----------------------------"); |
172 | 162 | ||
173 | /* end of frame */ | 163 | /* end of frame */ |
174 | error = 1; | 164 | error = 1; |
175 | gigaset_rcv_error(NULL, cs, bcs); | 165 | gigaset_rcv_error(NULL, cs, bcs); |
176 | } else if (!(inputstate & INS_have_data)) { /* 7E 7E */ | 166 | } else if (!(inputstate & INS_have_data)) { /* 7E 7E */ |
177 | //dbg(DEBUG_HDLC, "(7e)7e------------------------"); | ||
178 | #ifdef CONFIG_GIGASET_DEBUG | 167 | #ifdef CONFIG_GIGASET_DEBUG |
179 | ++bcs->emptycount; | 168 | ++bcs->emptycount; |
180 | #endif | 169 | #endif |
181 | break; | 170 | break; |
182 | } else { | 171 | } else { |
183 | dbg(DEBUG_HDLC, | 172 | gig_dbg(DEBUG_HDLC, |
184 | "7e----------------------------"); | 173 | "7e----------------------------"); |
185 | 174 | ||
186 | /* end of frame */ | 175 | /* end of frame */ |
187 | error = 0; | 176 | error = 0; |
188 | 177 | ||
189 | if (unlikely(fcs != PPP_GOODFCS)) { | 178 | if (unlikely(fcs != PPP_GOODFCS)) { |
190 | err("Packet checksum at %lu failed, " | 179 | dev_err(cs->dev, |
191 | "packet is corrupted (%u bytes)!", | 180 | "Packet checksum at %lu failed, " |
181 | "packet is corrupted (%u bytes)!\n", | ||
192 | bcs->rcvbytes, skb->len); | 182 | bcs->rcvbytes, skb->len); |
193 | compskb = NULL; | 183 | compskb = NULL; |
194 | gigaset_rcv_error(compskb, cs, bcs); | 184 | gigaset_rcv_error(compskb, cs, bcs); |
@@ -202,9 +192,11 @@ byte_stuff: | |||
202 | skb = NULL; | 192 | skb = NULL; |
203 | inputstate |= INS_skip_frame; | 193 | inputstate |= INS_skip_frame; |
204 | if (l == 1) { | 194 | if (l == 1) { |
205 | err("invalid packet size (1)!"); | 195 | dev_err(cs->dev, |
196 | "invalid packet size (1)!\n"); | ||
206 | error = 1; | 197 | error = 1; |
207 | gigaset_rcv_error(NULL, cs, bcs); | 198 | gigaset_rcv_error(NULL, |
199 | cs, bcs); | ||
208 | } | 200 | } |
209 | } | 201 | } |
210 | if (likely(!(error || | 202 | if (likely(!(error || |
@@ -227,7 +219,8 @@ byte_stuff: | |||
227 | } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) { | 219 | } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) { |
228 | skb_reserve(skb, HW_HDR_LEN); | 220 | skb_reserve(skb, HW_HDR_LEN); |
229 | } else { | 221 | } else { |
230 | warn("could not allocate new skb"); | 222 | dev_warn(cs->dev, |
223 | "could not allocate new skb\n"); | ||
231 | inputstate |= INS_skip_frame; | 224 | inputstate |= INS_skip_frame; |
232 | } | 225 | } |
233 | 226 | ||
@@ -235,7 +228,7 @@ byte_stuff: | |||
235 | #ifdef CONFIG_GIGASET_DEBUG | 228 | #ifdef CONFIG_GIGASET_DEBUG |
236 | } else if (unlikely(muststuff(c))) { | 229 | } else if (unlikely(muststuff(c))) { |
237 | /* Should not happen. Possible after ZDLE=1<CR><LF>. */ | 230 | /* Should not happen. Possible after ZDLE=1<CR><LF>. */ |
238 | dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c); | 231 | gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c); |
239 | #endif | 232 | #endif |
240 | } | 233 | } |
241 | 234 | ||
@@ -243,8 +236,8 @@ byte_stuff: | |||
243 | 236 | ||
244 | #ifdef CONFIG_GIGASET_DEBUG | 237 | #ifdef CONFIG_GIGASET_DEBUG |
245 | if (unlikely(!(inputstate & INS_have_data))) { | 238 | if (unlikely(!(inputstate & INS_have_data))) { |
246 | dbg(DEBUG_HDLC, | 239 | gig_dbg(DEBUG_HDLC, "7e (%d x) ================", |
247 | "7e (%d x) ================", bcs->emptycount); | 240 | bcs->emptycount); |
248 | bcs->emptycount = 0; | 241 | bcs->emptycount = 0; |
249 | } | 242 | } |
250 | #endif | 243 | #endif |
@@ -253,14 +246,13 @@ byte_stuff: | |||
253 | 246 | ||
254 | if (likely(!(inputstate & INS_skip_frame))) { | 247 | if (likely(!(inputstate & INS_skip_frame))) { |
255 | if (unlikely(skb->len == SBUFSIZE)) { | 248 | if (unlikely(skb->len == SBUFSIZE)) { |
256 | warn("received packet too long"); | 249 | dev_warn(cs->dev, "received packet too long\n"); |
257 | dev_kfree_skb_any(skb); | 250 | dev_kfree_skb_any(skb); |
258 | skb = NULL; | 251 | skb = NULL; |
259 | inputstate |= INS_skip_frame; | 252 | inputstate |= INS_skip_frame; |
260 | break; | 253 | break; |
261 | } | 254 | } |
262 | *gigaset_skb_put_quick(skb, 1) = c; | 255 | *__skb_put(skb, 1) = c; |
263 | /* *__skb_put (skb, 1) = c; */ | ||
264 | fcs = crc_ccitt_byte(fcs, c); | 256 | fcs = crc_ccitt_byte(fcs, c); |
265 | } | 257 | } |
266 | 258 | ||
@@ -289,19 +281,14 @@ byte_stuff: | |||
289 | * numbytes (all bytes processed) on error --FIXME | 281 | * numbytes (all bytes processed) on error --FIXME |
290 | */ | 282 | */ |
291 | static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, | 283 | static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, |
292 | struct inbuf_t *inbuf) | 284 | struct inbuf_t *inbuf) |
293 | { | 285 | { |
294 | struct cardstate *cs = inbuf->cs; | 286 | struct cardstate *cs = inbuf->cs; |
295 | struct bc_state *bcs = inbuf->bcs; | 287 | struct bc_state *bcs = inbuf->bcs; |
296 | int inputstate; | 288 | int inputstate = bcs->inputstate; |
297 | struct sk_buff *skb; | 289 | struct sk_buff *skb = bcs->skb; |
298 | int startbytes = numbytes; | 290 | int startbytes = numbytes; |
299 | 291 | ||
300 | IFNULLRETVAL(bcs, numbytes); | ||
301 | inputstate = bcs->inputstate; | ||
302 | skb = bcs->skb; | ||
303 | IFNULLRETVAL(skb, numbytes); | ||
304 | |||
305 | for (;;) { | 292 | for (;;) { |
306 | /* add character */ | 293 | /* add character */ |
307 | inputstate |= INS_have_data; | 294 | inputstate |= INS_have_data; |
@@ -309,13 +296,13 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, | |||
309 | if (likely(!(inputstate & INS_skip_frame))) { | 296 | if (likely(!(inputstate & INS_skip_frame))) { |
310 | if (unlikely(skb->len == SBUFSIZE)) { | 297 | if (unlikely(skb->len == SBUFSIZE)) { |
311 | //FIXME just pass skb up and allocate a new one | 298 | //FIXME just pass skb up and allocate a new one |
312 | warn("received packet too long"); | 299 | dev_warn(cs->dev, "received packet too long\n"); |
313 | dev_kfree_skb_any(skb); | 300 | dev_kfree_skb_any(skb); |
314 | skb = NULL; | 301 | skb = NULL; |
315 | inputstate |= INS_skip_frame; | 302 | inputstate |= INS_skip_frame; |
316 | break; | 303 | break; |
317 | } | 304 | } |
318 | *gigaset_skb_put_quick(skb, 1) = gigaset_invtab[c]; | 305 | *__skb_put(skb, 1) = gigaset_invtab[c]; |
319 | } | 306 | } |
320 | 307 | ||
321 | if (unlikely(!numbytes)) | 308 | if (unlikely(!numbytes)) |
@@ -343,7 +330,7 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, | |||
343 | != NULL)) { | 330 | != NULL)) { |
344 | skb_reserve(skb, HW_HDR_LEN); | 331 | skb_reserve(skb, HW_HDR_LEN); |
345 | } else { | 332 | } else { |
346 | warn("could not allocate new skb"); | 333 | dev_warn(cs->dev, "could not allocate new skb\n"); |
347 | inputstate |= INS_skip_frame; | 334 | inputstate |= INS_skip_frame; |
348 | } | 335 | } |
349 | } | 336 | } |
@@ -364,13 +351,13 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
364 | 351 | ||
365 | head = atomic_read(&inbuf->head); | 352 | head = atomic_read(&inbuf->head); |
366 | tail = atomic_read(&inbuf->tail); | 353 | tail = atomic_read(&inbuf->tail); |
367 | dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | 354 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); |
368 | 355 | ||
369 | if (head != tail) { | 356 | if (head != tail) { |
370 | cs = inbuf->cs; | 357 | cs = inbuf->cs; |
371 | src = inbuf->data + head; | 358 | src = inbuf->data + head; |
372 | numbytes = (head > tail ? RBUFSIZE : tail) - head; | 359 | numbytes = (head > tail ? RBUFSIZE : tail) - head; |
373 | dbg(DEBUG_INTR, "processing %u bytes", numbytes); | 360 | gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); |
374 | 361 | ||
375 | while (numbytes) { | 362 | while (numbytes) { |
376 | if (atomic_read(&cs->mstate) == MS_LOCKED) { | 363 | if (atomic_read(&cs->mstate) == MS_LOCKED) { |
@@ -392,8 +379,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
392 | 379 | ||
393 | if (!(inbuf->inputstate & INS_DLE_char)) { | 380 | if (!(inbuf->inputstate & INS_DLE_char)) { |
394 | 381 | ||
395 | /* FIXME Einfach je nach Modus Funktionszeiger in cs setzen [hier+hdlc_loop]? */ | 382 | /* FIXME use function pointers? */ |
396 | /* FIXME Spart folgendes "if" und ermoeglicht andere Protokolle */ | ||
397 | if (inbuf->inputstate & INS_command) | 383 | if (inbuf->inputstate & INS_command) |
398 | procbytes = cmd_loop(c, src, numbytes, inbuf); | 384 | procbytes = cmd_loop(c, src, numbytes, inbuf); |
399 | else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC) | 385 | else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC) |
@@ -403,13 +389,14 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
403 | 389 | ||
404 | src += procbytes; | 390 | src += procbytes; |
405 | numbytes -= procbytes; | 391 | numbytes -= procbytes; |
406 | } else { /* DLE-char */ | 392 | } else { /* DLE char */ |
407 | inbuf->inputstate &= ~INS_DLE_char; | 393 | inbuf->inputstate &= ~INS_DLE_char; |
408 | switch (c) { | 394 | switch (c) { |
409 | case 'X': /*begin of command*/ | 395 | case 'X': /*begin of command*/ |
410 | #ifdef CONFIG_GIGASET_DEBUG | 396 | #ifdef CONFIG_GIGASET_DEBUG |
411 | if (inbuf->inputstate & INS_command) | 397 | if (inbuf->inputstate & INS_command) |
412 | err("received <DLE> 'X' in command mode"); | 398 | dev_err(cs->dev, |
399 | "received <DLE> 'X' in command mode\n"); | ||
413 | #endif | 400 | #endif |
414 | inbuf->inputstate |= | 401 | inbuf->inputstate |= |
415 | INS_command | INS_DLE_command; | 402 | INS_command | INS_DLE_command; |
@@ -417,7 +404,8 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
417 | case '.': /*end of command*/ | 404 | case '.': /*end of command*/ |
418 | #ifdef CONFIG_GIGASET_DEBUG | 405 | #ifdef CONFIG_GIGASET_DEBUG |
419 | if (!(inbuf->inputstate & INS_command)) | 406 | if (!(inbuf->inputstate & INS_command)) |
420 | err("received <DLE> '.' in hdlc mode"); | 407 | dev_err(cs->dev, |
408 | "received <DLE> '.' in hdlc mode\n"); | ||
421 | #endif | 409 | #endif |
422 | inbuf->inputstate &= cs->dle ? | 410 | inbuf->inputstate &= cs->dle ? |
423 | ~(INS_DLE_command|INS_command) | 411 | ~(INS_DLE_command|INS_command) |
@@ -425,7 +413,9 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
425 | break; | 413 | break; |
426 | //case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */ | 414 | //case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */ |
427 | default: | 415 | default: |
428 | err("received 0x10 0x%02x!", (int) c); | 416 | dev_err(cs->dev, |
417 | "received 0x10 0x%02x!\n", | ||
418 | (int) c); | ||
429 | /* FIXME: reset driver?? */ | 419 | /* FIXME: reset driver?? */ |
430 | } | 420 | } |
431 | } | 421 | } |
@@ -444,7 +434,7 @@ nextbyte: | |||
444 | } | 434 | } |
445 | } | 435 | } |
446 | 436 | ||
447 | dbg(DEBUG_INTR, "setting head to %u", head); | 437 | gig_dbg(DEBUG_INTR, "setting head to %u", head); |
448 | atomic_set(&inbuf->head, head); | 438 | atomic_set(&inbuf->head, head); |
449 | } | 439 | } |
450 | } | 440 | } |
@@ -479,14 +469,13 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) | |||
479 | stuf_cnt++; | 469 | stuf_cnt++; |
480 | fcs = crc_ccitt_byte(fcs, *cp++); | 470 | fcs = crc_ccitt_byte(fcs, *cp++); |
481 | } | 471 | } |
482 | fcs ^= 0xffff; /* complement */ | 472 | fcs ^= 0xffff; /* complement */ |
483 | 473 | ||
484 | /* size of new buffer: original size + number of stuffing bytes | 474 | /* size of new buffer: original size + number of stuffing bytes |
485 | * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes | 475 | * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes |
486 | */ | 476 | */ |
487 | hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head); | 477 | hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head); |
488 | if (!hdlc_skb) { | 478 | if (!hdlc_skb) { |
489 | err("unable to allocate memory for HDLC encoding!"); | ||
490 | dev_kfree_skb(skb); | 479 | dev_kfree_skb(skb); |
491 | return NULL; | 480 | return NULL; |
492 | } | 481 | } |
@@ -508,7 +497,7 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) | |||
508 | } | 497 | } |
509 | 498 | ||
510 | /* Finally add FCS (byte stuffed) and flag sequence */ | 499 | /* Finally add FCS (byte stuffed) and flag sequence */ |
511 | c = (fcs & 0x00ff); /* least significant byte first */ | 500 | c = (fcs & 0x00ff); /* least significant byte first */ |
512 | if (muststuff(c)) { | 501 | if (muststuff(c)) { |
513 | *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; | 502 | *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; |
514 | c ^= PPP_TRANS; | 503 | c ^= PPP_TRANS; |
@@ -546,7 +535,6 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) | |||
546 | /* worst case: every byte must be stuffed */ | 535 | /* worst case: every byte must be stuffed */ |
547 | iraw_skb = dev_alloc_skb(2*skb->len + tail + head); | 536 | iraw_skb = dev_alloc_skb(2*skb->len + tail + head); |
548 | if (!iraw_skb) { | 537 | if (!iraw_skb) { |
549 | err("unable to allocate memory for HDLC encoding!"); | ||
550 | dev_kfree_skb(skb); | 538 | dev_kfree_skb(skb); |
551 | return NULL; | 539 | return NULL; |
552 | } | 540 | } |
@@ -577,21 +565,23 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) | |||
577 | */ | 565 | */ |
578 | int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) | 566 | int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) |
579 | { | 567 | { |
580 | unsigned len; | 568 | unsigned len = skb->len; |
581 | 569 | unsigned long flags; | |
582 | IFNULLRETVAL(bcs, -EFAULT); | ||
583 | IFNULLRETVAL(skb, -EFAULT); | ||
584 | len = skb->len; | ||
585 | 570 | ||
586 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) | 571 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) |
587 | skb = HDLC_Encode(skb, HW_HDR_LEN, 0); | 572 | skb = HDLC_Encode(skb, HW_HDR_LEN, 0); |
588 | else | 573 | else |
589 | skb = iraw_encode(skb, HW_HDR_LEN, 0); | 574 | skb = iraw_encode(skb, HW_HDR_LEN, 0); |
590 | if (!skb) | 575 | if (!skb) { |
576 | err("unable to allocate memory for encoding!\n"); | ||
591 | return -ENOMEM; | 577 | return -ENOMEM; |
578 | } | ||
592 | 579 | ||
593 | skb_queue_tail(&bcs->squeue, skb); | 580 | skb_queue_tail(&bcs->squeue, skb); |
594 | tasklet_schedule(&bcs->cs->write_tasklet); | 581 | spin_lock_irqsave(&bcs->cs->lock, flags); |
582 | if (bcs->cs->connected) | ||
583 | tasklet_schedule(&bcs->cs->write_tasklet); | ||
584 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
595 | 585 | ||
596 | return len; /* ok so far */ | 586 | return len; /* ok so far */ |
597 | } | 587 | } |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 31f0f07832bc..f86ed6af3aa2 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Hansjoerg Lipp <hjlipp@web.de>, | 4 | * Copyright (c) 2001 by Hansjoerg Lipp <hjlipp@web.de>, |
5 | * Tilman Schmidt <tilman@imap.cc>, | 5 | * Tilman Schmidt <tilman@imap.cc>, |
6 | * Stefan Eilers <Eilers.Stefan@epost.de>. | 6 | * Stefan Eilers. |
7 | * | 7 | * |
8 | * Based on usb-gigaset.c. | 8 | * Based on usb-gigaset.c. |
9 | * | 9 | * |
@@ -13,10 +13,6 @@ | |||
13 | * published by the Free Software Foundation; either version 2 of | 13 | * published by the Free Software Foundation; either version 2 of |
14 | * the License, or (at your option) any later version. | 14 | * the License, or (at your option) any later version. |
15 | * ===================================================================== | 15 | * ===================================================================== |
16 | * ToDo: ... | ||
17 | * ===================================================================== | ||
18 | * Version: $Id: bas-gigaset.c,v 1.52.4.19 2006/02/04 18:28:16 hjlipp Exp $ | ||
19 | * ===================================================================== | ||
20 | */ | 16 | */ |
21 | 17 | ||
22 | #include "gigaset.h" | 18 | #include "gigaset.h" |
@@ -30,7 +26,7 @@ | |||
30 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
31 | 27 | ||
32 | /* Version Information */ | 28 | /* Version Information */ |
33 | #define DRIVER_AUTHOR "Tilman Schmidt <tilman@imap.cc>, Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers <Eilers.Stefan@epost.de>" | 29 | #define DRIVER_AUTHOR "Tilman Schmidt <tilman@imap.cc>, Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers" |
34 | #define DRIVER_DESC "USB Driver for Gigaset 307x" | 30 | #define DRIVER_DESC "USB Driver for Gigaset 307x" |
35 | 31 | ||
36 | 32 | ||
@@ -70,9 +66,6 @@ static struct usb_device_id gigaset_table [] = { | |||
70 | 66 | ||
71 | MODULE_DEVICE_TABLE(usb, gigaset_table); | 67 | MODULE_DEVICE_TABLE(usb, gigaset_table); |
72 | 68 | ||
73 | /* Get a minor range for your devices from the usb maintainer */ | ||
74 | #define USB_SKEL_MINOR_BASE 200 | ||
75 | |||
76 | /*======================= local function prototypes =============================*/ | 69 | /*======================= local function prototypes =============================*/ |
77 | 70 | ||
78 | /* This function is called if a new device is connected to the USB port. It | 71 | /* This function is called if a new device is connected to the USB port. It |
@@ -88,25 +81,25 @@ static void gigaset_disconnect(struct usb_interface *interface); | |||
88 | /*==============================================================================*/ | 81 | /*==============================================================================*/ |
89 | 82 | ||
90 | struct bas_cardstate { | 83 | struct bas_cardstate { |
91 | struct usb_device *udev; /* USB device pointer */ | 84 | struct usb_device *udev; /* USB device pointer */ |
92 | struct usb_interface *interface; /* interface for this device */ | 85 | struct usb_interface *interface; /* interface for this device */ |
93 | unsigned char minor; /* starting minor number */ | 86 | unsigned char minor; /* starting minor number */ |
94 | 87 | ||
95 | struct urb *urb_ctrl; /* control pipe default URB */ | 88 | struct urb *urb_ctrl; /* control pipe default URB */ |
96 | struct usb_ctrlrequest dr_ctrl; | 89 | struct usb_ctrlrequest dr_ctrl; |
97 | struct timer_list timer_ctrl; /* control request timeout */ | 90 | struct timer_list timer_ctrl; /* control request timeout */ |
98 | 91 | ||
99 | struct timer_list timer_atrdy; /* AT command ready timeout */ | 92 | struct timer_list timer_atrdy; /* AT command ready timeout */ |
100 | struct urb *urb_cmd_out; /* for sending AT commands */ | 93 | struct urb *urb_cmd_out; /* for sending AT commands */ |
101 | struct usb_ctrlrequest dr_cmd_out; | 94 | struct usb_ctrlrequest dr_cmd_out; |
102 | int retry_cmd_out; | 95 | int retry_cmd_out; |
103 | 96 | ||
104 | struct urb *urb_cmd_in; /* for receiving AT replies */ | 97 | struct urb *urb_cmd_in; /* for receiving AT replies */ |
105 | struct usb_ctrlrequest dr_cmd_in; | 98 | struct usb_ctrlrequest dr_cmd_in; |
106 | struct timer_list timer_cmd_in; /* receive request timeout */ | 99 | struct timer_list timer_cmd_in; /* receive request timeout */ |
107 | unsigned char *rcvbuf; /* AT reply receive buffer */ | 100 | unsigned char *rcvbuf; /* AT reply receive buffer */ |
108 | 101 | ||
109 | struct urb *urb_int_in; /* URB for interrupt pipe */ | 102 | struct urb *urb_int_in; /* URB for interrupt pipe */ |
110 | unsigned char int_in_buf[3]; | 103 | unsigned char int_in_buf[3]; |
111 | 104 | ||
112 | spinlock_t lock; /* locks all following */ | 105 | spinlock_t lock; /* locks all following */ |
@@ -208,53 +201,54 @@ static inline char *usb_pipetype_str(int pipe) | |||
208 | * write content of URB to syslog for debugging | 201 | * write content of URB to syslog for debugging |
209 | */ | 202 | */ |
210 | static inline void dump_urb(enum debuglevel level, const char *tag, | 203 | static inline void dump_urb(enum debuglevel level, const char *tag, |
211 | struct urb *urb) | 204 | struct urb *urb) |
212 | { | 205 | { |
213 | #ifdef CONFIG_GIGASET_DEBUG | 206 | #ifdef CONFIG_GIGASET_DEBUG |
214 | int i; | 207 | int i; |
215 | IFNULLRET(tag); | 208 | gig_dbg(level, "%s urb(0x%08lx)->{", tag, (unsigned long) urb); |
216 | dbg(level, "%s urb(0x%08lx)->{", tag, (unsigned long) urb); | ||
217 | if (urb) { | 209 | if (urb) { |
218 | dbg(level, | 210 | gig_dbg(level, |
219 | " dev=0x%08lx, pipe=%s:EP%d/DV%d:%s, " | 211 | " dev=0x%08lx, pipe=%s:EP%d/DV%d:%s, " |
220 | "status=%d, hcpriv=0x%08lx, transfer_flags=0x%x,", | 212 | "status=%d, hcpriv=0x%08lx, transfer_flags=0x%x,", |
221 | (unsigned long) urb->dev, | 213 | (unsigned long) urb->dev, |
222 | usb_pipetype_str(urb->pipe), | 214 | usb_pipetype_str(urb->pipe), |
223 | usb_pipeendpoint(urb->pipe), usb_pipedevice(urb->pipe), | 215 | usb_pipeendpoint(urb->pipe), usb_pipedevice(urb->pipe), |
224 | usb_pipein(urb->pipe) ? "in" : "out", | 216 | usb_pipein(urb->pipe) ? "in" : "out", |
225 | urb->status, (unsigned long) urb->hcpriv, | 217 | urb->status, (unsigned long) urb->hcpriv, |
226 | urb->transfer_flags); | 218 | urb->transfer_flags); |
227 | dbg(level, | 219 | gig_dbg(level, |
228 | " transfer_buffer=0x%08lx[%d], actual_length=%d, " | 220 | " transfer_buffer=0x%08lx[%d], actual_length=%d, " |
229 | "bandwidth=%d, setup_packet=0x%08lx,", | 221 | "bandwidth=%d, setup_packet=0x%08lx,", |
230 | (unsigned long) urb->transfer_buffer, | 222 | (unsigned long) urb->transfer_buffer, |
231 | urb->transfer_buffer_length, urb->actual_length, | 223 | urb->transfer_buffer_length, urb->actual_length, |
232 | urb->bandwidth, (unsigned long) urb->setup_packet); | 224 | urb->bandwidth, (unsigned long) urb->setup_packet); |
233 | dbg(level, | 225 | gig_dbg(level, |
234 | " start_frame=%d, number_of_packets=%d, interval=%d, " | 226 | " start_frame=%d, number_of_packets=%d, interval=%d, " |
235 | "error_count=%d,", | 227 | "error_count=%d,", |
236 | urb->start_frame, urb->number_of_packets, urb->interval, | 228 | urb->start_frame, urb->number_of_packets, urb->interval, |
237 | urb->error_count); | 229 | urb->error_count); |
238 | dbg(level, | 230 | gig_dbg(level, |
239 | " context=0x%08lx, complete=0x%08lx, iso_frame_desc[]={", | 231 | " context=0x%08lx, complete=0x%08lx, " |
240 | (unsigned long) urb->context, | 232 | "iso_frame_desc[]={", |
241 | (unsigned long) urb->complete); | 233 | (unsigned long) urb->context, |
234 | (unsigned long) urb->complete); | ||
242 | for (i = 0; i < urb->number_of_packets; i++) { | 235 | for (i = 0; i < urb->number_of_packets; i++) { |
243 | struct usb_iso_packet_descriptor *pifd = &urb->iso_frame_desc[i]; | 236 | struct usb_iso_packet_descriptor *pifd |
244 | dbg(level, | 237 | = &urb->iso_frame_desc[i]; |
245 | " {offset=%u, length=%u, actual_length=%u, " | 238 | gig_dbg(level, |
246 | "status=%u}", | 239 | " {offset=%u, length=%u, actual_length=%u, " |
247 | pifd->offset, pifd->length, pifd->actual_length, | 240 | "status=%u}", |
248 | pifd->status); | 241 | pifd->offset, pifd->length, pifd->actual_length, |
242 | pifd->status); | ||
249 | } | 243 | } |
250 | } | 244 | } |
251 | dbg(level, "}}"); | 245 | gig_dbg(level, "}}"); |
252 | #endif | 246 | #endif |
253 | } | 247 | } |
254 | 248 | ||
255 | /* read/set modem control bits etc. (m10x only) */ | 249 | /* read/set modem control bits etc. (m10x only) */ |
256 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | 250 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, |
257 | unsigned new_state) | 251 | unsigned new_state) |
258 | { | 252 | { |
259 | return -EINVAL; | 253 | return -EINVAL; |
260 | } | 254 | } |
@@ -280,8 +274,8 @@ static inline void error_hangup(struct bc_state *bcs) | |||
280 | { | 274 | { |
281 | struct cardstate *cs = bcs->cs; | 275 | struct cardstate *cs = bcs->cs; |
282 | 276 | ||
283 | dbg(DEBUG_ANY, | 277 | gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d", |
284 | "%s: scheduling HUP for channel %d", __func__, bcs->channel); | 278 | __func__, bcs->channel); |
285 | 279 | ||
286 | if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) { | 280 | if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) { |
287 | //FIXME what should we do? | 281 | //FIXME what should we do? |
@@ -301,22 +295,19 @@ static inline void error_hangup(struct bc_state *bcs) | |||
301 | static inline void error_reset(struct cardstate *cs) | 295 | static inline void error_reset(struct cardstate *cs) |
302 | { | 296 | { |
303 | //FIXME try to recover without bothering the user | 297 | //FIXME try to recover without bothering the user |
304 | err("unrecoverable error - please disconnect the Gigaset base to reset"); | 298 | dev_err(cs->dev, |
299 | "unrecoverable error - please disconnect Gigaset base to reset\n"); | ||
305 | } | 300 | } |
306 | 301 | ||
307 | /* check_pending | 302 | /* check_pending |
308 | * check for completion of pending control request | 303 | * check for completion of pending control request |
309 | * parameter: | 304 | * parameter: |
310 | * urb USB request block of completed request | 305 | * ucs hardware specific controller state structure |
311 | * urb->context = hardware specific controller state structure | ||
312 | */ | 306 | */ |
313 | static void check_pending(struct bas_cardstate *ucs) | 307 | static void check_pending(struct bas_cardstate *ucs) |
314 | { | 308 | { |
315 | unsigned long flags; | 309 | unsigned long flags; |
316 | 310 | ||
317 | IFNULLRET(ucs); | ||
318 | IFNULLRET(cardstate); | ||
319 | |||
320 | spin_lock_irqsave(&ucs->lock, flags); | 311 | spin_lock_irqsave(&ucs->lock, flags); |
321 | switch (ucs->pending) { | 312 | switch (ucs->pending) { |
322 | case 0: | 313 | case 0: |
@@ -336,8 +327,6 @@ static void check_pending(struct bas_cardstate *ucs) | |||
336 | case HD_CLOSE_ATCHANNEL: | 327 | case HD_CLOSE_ATCHANNEL: |
337 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) | 328 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) |
338 | ucs->pending = 0; | 329 | ucs->pending = 0; |
339 | //wake_up_interruptible(cs->initwait); | ||
340 | //FIXME need own wait queue? | ||
341 | break; | 330 | break; |
342 | case HD_CLOSE_B1CHANNEL: | 331 | case HD_CLOSE_B1CHANNEL: |
343 | if (!(atomic_read(&ucs->basstate) & BS_B1OPEN)) | 332 | if (!(atomic_read(&ucs->basstate) & BS_B1OPEN)) |
@@ -354,7 +343,9 @@ static void check_pending(struct bas_cardstate *ucs) | |||
354 | * are handled separately and should never end up here | 343 | * are handled separately and should never end up here |
355 | */ | 344 | */ |
356 | default: | 345 | default: |
357 | warn("unknown pending request 0x%02x cleared", ucs->pending); | 346 | dev_warn(&ucs->interface->dev, |
347 | "unknown pending request 0x%02x cleared\n", | ||
348 | ucs->pending); | ||
358 | ucs->pending = 0; | 349 | ucs->pending = 0; |
359 | } | 350 | } |
360 | 351 | ||
@@ -372,27 +363,23 @@ static void check_pending(struct bas_cardstate *ucs) | |||
372 | static void cmd_in_timeout(unsigned long data) | 363 | static void cmd_in_timeout(unsigned long data) |
373 | { | 364 | { |
374 | struct cardstate *cs = (struct cardstate *) data; | 365 | struct cardstate *cs = (struct cardstate *) data; |
375 | struct bas_cardstate *ucs; | 366 | struct bas_cardstate *ucs = cs->hw.bas; |
376 | unsigned long flags; | 367 | unsigned long flags; |
377 | 368 | ||
378 | IFNULLRET(cs); | ||
379 | ucs = cs->hw.bas; | ||
380 | IFNULLRET(ucs); | ||
381 | |||
382 | spin_lock_irqsave(&cs->lock, flags); | 369 | spin_lock_irqsave(&cs->lock, flags); |
383 | if (!atomic_read(&cs->connected)) { | 370 | if (unlikely(!cs->connected)) { |
384 | dbg(DEBUG_USBREQ, "%s: disconnected", __func__); | 371 | gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__); |
385 | spin_unlock_irqrestore(&cs->lock, flags); | 372 | spin_unlock_irqrestore(&cs->lock, flags); |
386 | return; | 373 | return; |
387 | } | 374 | } |
388 | if (!ucs->rcvbuf_size) { | 375 | if (!ucs->rcvbuf_size) { |
389 | dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); | 376 | gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); |
390 | spin_unlock_irqrestore(&cs->lock, flags); | 377 | spin_unlock_irqrestore(&cs->lock, flags); |
391 | return; | 378 | return; |
392 | } | 379 | } |
393 | spin_unlock_irqrestore(&cs->lock, flags); | 380 | spin_unlock_irqrestore(&cs->lock, flags); |
394 | 381 | ||
395 | err("timeout reading AT response"); | 382 | dev_err(cs->dev, "timeout reading AT response\n"); |
396 | error_reset(cs); //FIXME retry? | 383 | error_reset(cs); //FIXME retry? |
397 | } | 384 | } |
398 | 385 | ||
@@ -412,18 +399,15 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs); | |||
412 | */ | 399 | */ |
413 | static int atread_submit(struct cardstate *cs, int timeout) | 400 | static int atread_submit(struct cardstate *cs, int timeout) |
414 | { | 401 | { |
415 | struct bas_cardstate *ucs; | 402 | struct bas_cardstate *ucs = cs->hw.bas; |
416 | int ret; | 403 | int ret; |
417 | 404 | ||
418 | IFNULLRETVAL(cs, -EINVAL); | 405 | gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", |
419 | ucs = cs->hw.bas; | 406 | ucs->rcvbuf_size); |
420 | IFNULLRETVAL(ucs, -EINVAL); | ||
421 | IFNULLRETVAL(ucs->urb_cmd_in, -EINVAL); | ||
422 | |||
423 | dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", ucs->rcvbuf_size); | ||
424 | 407 | ||
425 | if (ucs->urb_cmd_in->status == -EINPROGRESS) { | 408 | if (ucs->urb_cmd_in->status == -EINPROGRESS) { |
426 | err("could not submit HD_READ_ATMESSAGE: URB busy"); | 409 | dev_err(cs->dev, |
410 | "could not submit HD_READ_ATMESSAGE: URB busy\n"); | ||
427 | return -EBUSY; | 411 | return -EBUSY; |
428 | } | 412 | } |
429 | 413 | ||
@@ -433,19 +417,19 @@ static int atread_submit(struct cardstate *cs, int timeout) | |||
433 | ucs->dr_cmd_in.wIndex = 0; | 417 | ucs->dr_cmd_in.wIndex = 0; |
434 | ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size); | 418 | ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size); |
435 | usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev, | 419 | usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev, |
436 | usb_rcvctrlpipe(ucs->udev, 0), | 420 | usb_rcvctrlpipe(ucs->udev, 0), |
437 | (unsigned char*) & ucs->dr_cmd_in, | 421 | (unsigned char*) & ucs->dr_cmd_in, |
438 | ucs->rcvbuf, ucs->rcvbuf_size, | 422 | ucs->rcvbuf, ucs->rcvbuf_size, |
439 | read_ctrl_callback, cs->inbuf); | 423 | read_ctrl_callback, cs->inbuf); |
440 | 424 | ||
441 | if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { | 425 | if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { |
442 | err("could not submit HD_READ_ATMESSAGE: %s", | 426 | dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", |
443 | get_usb_statmsg(ret)); | 427 | get_usb_statmsg(ret)); |
444 | return ret; | 428 | return ret; |
445 | } | 429 | } |
446 | 430 | ||
447 | if (timeout > 0) { | 431 | if (timeout > 0) { |
448 | dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); | 432 | gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); |
449 | ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10; | 433 | ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10; |
450 | ucs->timer_cmd_in.data = (unsigned long) cs; | 434 | ucs->timer_cmd_in.data = (unsigned long) cs; |
451 | ucs->timer_cmd_in.function = cmd_in_timeout; | 435 | ucs->timer_cmd_in.function = cmd_in_timeout; |
@@ -483,25 +467,14 @@ inline static void update_basstate(struct bas_cardstate *ucs, | |||
483 | */ | 467 | */ |
484 | static void read_int_callback(struct urb *urb, struct pt_regs *regs) | 468 | static void read_int_callback(struct urb *urb, struct pt_regs *regs) |
485 | { | 469 | { |
486 | struct cardstate *cs; | 470 | struct cardstate *cs = urb->context; |
487 | struct bas_cardstate *ucs; | 471 | struct bas_cardstate *ucs = cs->hw.bas; |
488 | struct bc_state *bcs; | 472 | struct bc_state *bcs; |
489 | unsigned long flags; | 473 | unsigned long flags; |
490 | int status; | 474 | int status; |
491 | unsigned l; | 475 | unsigned l; |
492 | int channel; | 476 | int channel; |
493 | 477 | ||
494 | IFNULLRET(urb); | ||
495 | cs = (struct cardstate *) urb->context; | ||
496 | IFNULLRET(cs); | ||
497 | ucs = cs->hw.bas; | ||
498 | IFNULLRET(ucs); | ||
499 | |||
500 | if (unlikely(!atomic_read(&cs->connected))) { | ||
501 | warn("%s: disconnected", __func__); | ||
502 | return; | ||
503 | } | ||
504 | |||
505 | switch (urb->status) { | 478 | switch (urb->status) { |
506 | case 0: /* success */ | 479 | case 0: /* success */ |
507 | break; | 480 | break; |
@@ -509,11 +482,12 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
509 | case -ECONNRESET: /* canceled (async) */ | 482 | case -ECONNRESET: /* canceled (async) */ |
510 | case -EINPROGRESS: /* pending */ | 483 | case -EINPROGRESS: /* pending */ |
511 | /* ignore silently */ | 484 | /* ignore silently */ |
512 | dbg(DEBUG_USBREQ, | 485 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
513 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 486 | __func__, get_usb_statmsg(urb->status)); |
514 | return; | 487 | return; |
515 | default: /* severe trouble */ | 488 | default: /* severe trouble */ |
516 | warn("interrupt read: %s", get_usb_statmsg(urb->status)); | 489 | dev_warn(cs->dev, "interrupt read: %s\n", |
490 | get_usb_statmsg(urb->status)); | ||
517 | //FIXME corrective action? resubmission always ok? | 491 | //FIXME corrective action? resubmission always ok? |
518 | goto resubmit; | 492 | goto resubmit; |
519 | } | 493 | } |
@@ -521,10 +495,9 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
521 | l = (unsigned) ucs->int_in_buf[1] + | 495 | l = (unsigned) ucs->int_in_buf[1] + |
522 | (((unsigned) ucs->int_in_buf[2]) << 8); | 496 | (((unsigned) ucs->int_in_buf[2]) << 8); |
523 | 497 | ||
524 | dbg(DEBUG_USBREQ, | 498 | gig_dbg(DEBUG_USBREQ, "<-------%d: 0x%02x (%u [0x%02x 0x%02x])", |
525 | "<-------%d: 0x%02x (%u [0x%02x 0x%02x])", urb->actual_length, | 499 | urb->actual_length, (int)ucs->int_in_buf[0], l, |
526 | (int)ucs->int_in_buf[0], l, | 500 | (int)ucs->int_in_buf[1], (int)ucs->int_in_buf[2]); |
527 | (int)ucs->int_in_buf[1], (int)ucs->int_in_buf[2]); | ||
528 | 501 | ||
529 | channel = 0; | 502 | channel = 0; |
530 | 503 | ||
@@ -570,28 +543,30 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
570 | case HD_B1_FLOW_CONTROL: | 543 | case HD_B1_FLOW_CONTROL: |
571 | bcs = cs->bcs + channel; | 544 | bcs = cs->bcs + channel; |
572 | atomic_add((l - BAS_NORMFRAME) * BAS_CORRFRAMES, | 545 | atomic_add((l - BAS_NORMFRAME) * BAS_CORRFRAMES, |
573 | &bcs->hw.bas->corrbytes); | 546 | &bcs->hw.bas->corrbytes); |
574 | dbg(DEBUG_ISO, | 547 | gig_dbg(DEBUG_ISO, |
575 | "Flow control (channel %d, sub %d): 0x%02x => %d", | 548 | "Flow control (channel %d, sub %d): 0x%02x => %d", |
576 | channel, bcs->hw.bas->numsub, l, | 549 | channel, bcs->hw.bas->numsub, l, |
577 | atomic_read(&bcs->hw.bas->corrbytes)); | 550 | atomic_read(&bcs->hw.bas->corrbytes)); |
578 | break; | 551 | break; |
579 | 552 | ||
580 | case HD_RECEIVEATDATA_ACK: /* AT response ready to be received */ | 553 | case HD_RECEIVEATDATA_ACK: /* AT response ready to be received */ |
581 | if (!l) { | 554 | if (!l) { |
582 | warn("HD_RECEIVEATDATA_ACK with length 0 ignored"); | 555 | dev_warn(cs->dev, |
556 | "HD_RECEIVEATDATA_ACK with length 0 ignored\n"); | ||
583 | break; | 557 | break; |
584 | } | 558 | } |
585 | spin_lock_irqsave(&cs->lock, flags); | 559 | spin_lock_irqsave(&cs->lock, flags); |
586 | if (ucs->rcvbuf_size) { | 560 | if (ucs->rcvbuf_size) { |
587 | spin_unlock_irqrestore(&cs->lock, flags); | 561 | spin_unlock_irqrestore(&cs->lock, flags); |
588 | err("receive AT data overrun, %d bytes lost", l); | 562 | dev_err(cs->dev, |
563 | "receive AT data overrun, %d bytes lost\n", l); | ||
589 | error_reset(cs); //FIXME reschedule | 564 | error_reset(cs); //FIXME reschedule |
590 | break; | 565 | break; |
591 | } | 566 | } |
592 | if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { | 567 | if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { |
593 | spin_unlock_irqrestore(&cs->lock, flags); | 568 | spin_unlock_irqrestore(&cs->lock, flags); |
594 | err("%s: out of memory, %d bytes lost", __func__, l); | 569 | dev_err(cs->dev, "out of memory, %d bytes lost\n", l); |
595 | error_reset(cs); //FIXME reschedule | 570 | error_reset(cs); //FIXME reschedule |
596 | break; | 571 | break; |
597 | } | 572 | } |
@@ -607,25 +582,28 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
607 | break; | 582 | break; |
608 | 583 | ||
609 | case HD_RESET_INTERRUPT_PIPE_ACK: | 584 | case HD_RESET_INTERRUPT_PIPE_ACK: |
610 | dbg(DEBUG_USBREQ, "HD_RESET_INTERRUPT_PIPE_ACK"); | 585 | gig_dbg(DEBUG_USBREQ, "HD_RESET_INTERRUPT_PIPE_ACK"); |
611 | break; | 586 | break; |
612 | 587 | ||
613 | case HD_SUSPEND_END: | 588 | case HD_SUSPEND_END: |
614 | dbg(DEBUG_USBREQ, "HD_SUSPEND_END"); | 589 | gig_dbg(DEBUG_USBREQ, "HD_SUSPEND_END"); |
615 | break; | 590 | break; |
616 | 591 | ||
617 | default: | 592 | default: |
618 | warn("unknown Gigaset signal 0x%02x (%u) ignored", | 593 | dev_warn(cs->dev, |
619 | (int) ucs->int_in_buf[0], l); | 594 | "unknown Gigaset signal 0x%02x (%u) ignored\n", |
595 | (int) ucs->int_in_buf[0], l); | ||
620 | } | 596 | } |
621 | 597 | ||
622 | check_pending(ucs); | 598 | check_pending(ucs); |
623 | 599 | ||
624 | resubmit: | 600 | resubmit: |
625 | status = usb_submit_urb(urb, SLAB_ATOMIC); | 601 | spin_lock_irqsave(&cs->lock, flags); |
602 | status = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | ||
603 | spin_unlock_irqrestore(&cs->lock, flags); | ||
626 | if (unlikely(status)) { | 604 | if (unlikely(status)) { |
627 | err("could not resubmit interrupt URB: %s", | 605 | dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", |
628 | get_usb_statmsg(status)); | 606 | get_usb_statmsg(status)); |
629 | error_reset(cs); | 607 | error_reset(cs); |
630 | } | 608 | } |
631 | } | 609 | } |
@@ -639,30 +617,22 @@ resubmit: | |||
639 | */ | 617 | */ |
640 | static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | 618 | static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) |
641 | { | 619 | { |
642 | struct cardstate *cs; | 620 | struct inbuf_t *inbuf = urb->context; |
643 | struct bas_cardstate *ucs; | 621 | struct cardstate *cs = inbuf->cs; |
622 | struct bas_cardstate *ucs = cs->hw.bas; | ||
623 | int have_data = 0; | ||
644 | unsigned numbytes; | 624 | unsigned numbytes; |
645 | unsigned long flags; | 625 | unsigned long flags; |
646 | struct inbuf_t *inbuf; | ||
647 | int have_data = 0; | ||
648 | |||
649 | IFNULLRET(urb); | ||
650 | inbuf = (struct inbuf_t *) urb->context; | ||
651 | IFNULLRET(inbuf); | ||
652 | cs = inbuf->cs; | ||
653 | IFNULLRET(cs); | ||
654 | ucs = cs->hw.bas; | ||
655 | IFNULLRET(ucs); | ||
656 | 626 | ||
657 | spin_lock_irqsave(&cs->lock, flags); | 627 | spin_lock_irqsave(&cs->lock, flags); |
658 | if (!atomic_read(&cs->connected)) { | 628 | if (unlikely(!cs->connected)) { |
659 | warn("%s: disconnected", __func__); | 629 | warn("%s: disconnected", __func__); |
660 | spin_unlock_irqrestore(&cs->lock, flags); | 630 | spin_unlock_irqrestore(&cs->lock, flags); |
661 | return; | 631 | return; |
662 | } | 632 | } |
663 | 633 | ||
664 | if (!ucs->rcvbuf_size) { | 634 | if (!ucs->rcvbuf_size) { |
665 | warn("%s: no receive in progress", __func__); | 635 | dev_warn(cs->dev, "%s: no receive in progress\n", __func__); |
666 | spin_unlock_irqrestore(&cs->lock, flags); | 636 | spin_unlock_irqrestore(&cs->lock, flags); |
667 | return; | 637 | return; |
668 | } | 638 | } |
@@ -673,12 +643,14 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
673 | case 0: /* normal completion */ | 643 | case 0: /* normal completion */ |
674 | numbytes = urb->actual_length; | 644 | numbytes = urb->actual_length; |
675 | if (unlikely(numbytes == 0)) { | 645 | if (unlikely(numbytes == 0)) { |
676 | warn("control read: empty block received"); | 646 | dev_warn(cs->dev, |
647 | "control read: empty block received\n"); | ||
677 | goto retry; | 648 | goto retry; |
678 | } | 649 | } |
679 | if (unlikely(numbytes != ucs->rcvbuf_size)) { | 650 | if (unlikely(numbytes != ucs->rcvbuf_size)) { |
680 | warn("control read: received %d chars, expected %d", | 651 | dev_warn(cs->dev, |
681 | numbytes, ucs->rcvbuf_size); | 652 | "control read: received %d chars, expected %d\n", |
653 | numbytes, ucs->rcvbuf_size); | ||
682 | if (numbytes > ucs->rcvbuf_size) | 654 | if (numbytes > ucs->rcvbuf_size) |
683 | numbytes = ucs->rcvbuf_size; | 655 | numbytes = ucs->rcvbuf_size; |
684 | } | 656 | } |
@@ -698,23 +670,26 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
698 | case -ECONNRESET: /* canceled (async) */ | 670 | case -ECONNRESET: /* canceled (async) */ |
699 | case -EINPROGRESS: /* pending */ | 671 | case -EINPROGRESS: /* pending */ |
700 | /* no action necessary */ | 672 | /* no action necessary */ |
701 | dbg(DEBUG_USBREQ, | 673 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
702 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 674 | __func__, get_usb_statmsg(urb->status)); |
703 | break; | 675 | break; |
704 | 676 | ||
705 | default: /* severe trouble */ | 677 | default: /* severe trouble */ |
706 | warn("control read: %s", get_usb_statmsg(urb->status)); | 678 | dev_warn(cs->dev, "control read: %s\n", |
679 | get_usb_statmsg(urb->status)); | ||
707 | retry: | 680 | retry: |
708 | if (ucs->retry_cmd_in++ < BAS_RETRY) { | 681 | if (ucs->retry_cmd_in++ < BAS_RETRY) { |
709 | notice("control read: retry %d", ucs->retry_cmd_in); | 682 | dev_notice(cs->dev, "control read: retry %d\n", |
683 | ucs->retry_cmd_in); | ||
710 | if (atread_submit(cs, BAS_TIMEOUT) >= 0) { | 684 | if (atread_submit(cs, BAS_TIMEOUT) >= 0) { |
711 | /* resubmitted - bypass regular exit block */ | 685 | /* resubmitted - bypass regular exit block */ |
712 | spin_unlock_irqrestore(&cs->lock, flags); | 686 | spin_unlock_irqrestore(&cs->lock, flags); |
713 | return; | 687 | return; |
714 | } | 688 | } |
715 | } else { | 689 | } else { |
716 | err("control read: giving up after %d tries", | 690 | dev_err(cs->dev, |
717 | ucs->retry_cmd_in); | 691 | "control read: giving up after %d tries\n", |
692 | ucs->retry_cmd_in); | ||
718 | } | 693 | } |
719 | error_reset(cs); | 694 | error_reset(cs); |
720 | } | 695 | } |
@@ -724,7 +699,7 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
724 | ucs->rcvbuf_size = 0; | 699 | ucs->rcvbuf_size = 0; |
725 | spin_unlock_irqrestore(&cs->lock, flags); | 700 | spin_unlock_irqrestore(&cs->lock, flags); |
726 | if (have_data) { | 701 | if (have_data) { |
727 | dbg(DEBUG_INTR, "%s-->BH", __func__); | 702 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); |
728 | gigaset_schedule_event(cs); | 703 | gigaset_schedule_event(cs); |
729 | } | 704 | } |
730 | } | 705 | } |
@@ -743,21 +718,16 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
743 | unsigned long flags; | 718 | unsigned long flags; |
744 | int i, rc; | 719 | int i, rc; |
745 | 720 | ||
746 | IFNULLRET(urb); | ||
747 | IFNULLRET(urb->context); | ||
748 | IFNULLRET(cardstate); | ||
749 | |||
750 | /* status codes not worth bothering the tasklet with */ | 721 | /* status codes not worth bothering the tasklet with */ |
751 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || | 722 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || |
752 | urb->status == -EINPROGRESS)) { | 723 | urb->status == -EINPROGRESS)) { |
753 | dbg(DEBUG_ISO, | 724 | gig_dbg(DEBUG_ISO, "%s: %s", |
754 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 725 | __func__, get_usb_statmsg(urb->status)); |
755 | return; | 726 | return; |
756 | } | 727 | } |
757 | 728 | ||
758 | bcs = (struct bc_state *) urb->context; | 729 | bcs = urb->context; |
759 | ubc = bcs->hw.bas; | 730 | ubc = bcs->hw.bas; |
760 | IFNULLRET(ubc); | ||
761 | 731 | ||
762 | spin_lock_irqsave(&ubc->isoinlock, flags); | 732 | spin_lock_irqsave(&ubc->isoinlock, flags); |
763 | if (likely(ubc->isoindone == NULL)) { | 733 | if (likely(ubc->isoindone == NULL)) { |
@@ -777,14 +747,17 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
777 | urb->iso_frame_desc[i].actual_length = 0; | 747 | urb->iso_frame_desc[i].actual_length = 0; |
778 | } | 748 | } |
779 | if (likely(atomic_read(&ubc->running))) { | 749 | if (likely(atomic_read(&ubc->running))) { |
780 | urb->dev = bcs->cs->hw.bas->udev; /* clobbered by USB subsystem */ | 750 | /* urb->dev is clobbered by USB subsystem */ |
751 | urb->dev = bcs->cs->hw.bas->udev; | ||
781 | urb->transfer_flags = URB_ISO_ASAP; | 752 | urb->transfer_flags = URB_ISO_ASAP; |
782 | urb->number_of_packets = BAS_NUMFRAMES; | 753 | urb->number_of_packets = BAS_NUMFRAMES; |
783 | dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", __func__); | 754 | gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", |
755 | __func__); | ||
784 | rc = usb_submit_urb(urb, SLAB_ATOMIC); | 756 | rc = usb_submit_urb(urb, SLAB_ATOMIC); |
785 | if (unlikely(rc != 0)) { | 757 | if (unlikely(rc != 0)) { |
786 | err("could not resubmit isochronous read URB: %s", | 758 | dev_err(bcs->cs->dev, |
787 | get_usb_statmsg(rc)); | 759 | "could not resubmit isochronous read " |
760 | "URB: %s\n", get_usb_statmsg(rc)); | ||
788 | dump_urb(DEBUG_ISO, "isoc read", urb); | 761 | dump_urb(DEBUG_ISO, "isoc read", urb); |
789 | error_hangup(bcs); | 762 | error_hangup(bcs); |
790 | } | 763 | } |
@@ -806,23 +779,17 @@ static void write_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
806 | struct bas_bc_state *ubc; | 779 | struct bas_bc_state *ubc; |
807 | unsigned long flags; | 780 | unsigned long flags; |
808 | 781 | ||
809 | IFNULLRET(urb); | ||
810 | IFNULLRET(urb->context); | ||
811 | IFNULLRET(cardstate); | ||
812 | |||
813 | /* status codes not worth bothering the tasklet with */ | 782 | /* status codes not worth bothering the tasklet with */ |
814 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || | 783 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || |
815 | urb->status == -EINPROGRESS)) { | 784 | urb->status == -EINPROGRESS)) { |
816 | dbg(DEBUG_ISO, | 785 | gig_dbg(DEBUG_ISO, "%s: %s", |
817 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 786 | __func__, get_usb_statmsg(urb->status)); |
818 | return; | 787 | return; |
819 | } | 788 | } |
820 | 789 | ||
821 | /* pass URB context to tasklet */ | 790 | /* pass URB context to tasklet */ |
822 | ucx = (struct isow_urbctx_t *) urb->context; | 791 | ucx = urb->context; |
823 | IFNULLRET(ucx->bcs); | ||
824 | ubc = ucx->bcs->hw.bas; | 792 | ubc = ucx->bcs->hw.bas; |
825 | IFNULLRET(ubc); | ||
826 | 793 | ||
827 | spin_lock_irqsave(&ubc->isooutlock, flags); | 794 | spin_lock_irqsave(&ubc->isooutlock, flags); |
828 | ubc->isooutovfl = ubc->isooutdone; | 795 | ubc->isooutovfl = ubc->isooutdone; |
@@ -841,15 +808,11 @@ static void write_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
841 | */ | 808 | */ |
842 | static int starturbs(struct bc_state *bcs) | 809 | static int starturbs(struct bc_state *bcs) |
843 | { | 810 | { |
811 | struct bas_bc_state *ubc = bcs->hw.bas; | ||
844 | struct urb *urb; | 812 | struct urb *urb; |
845 | struct bas_bc_state *ubc; | ||
846 | int j, k; | 813 | int j, k; |
847 | int rc; | 814 | int rc; |
848 | 815 | ||
849 | IFNULLRETVAL(bcs, -EFAULT); | ||
850 | ubc = bcs->hw.bas; | ||
851 | IFNULLRETVAL(ubc, -EFAULT); | ||
852 | |||
853 | /* initialize L2 reception */ | 816 | /* initialize L2 reception */ |
854 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) | 817 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) |
855 | bcs->inputstate |= INS_flag_hunt; | 818 | bcs->inputstate |= INS_flag_hunt; |
@@ -859,7 +822,7 @@ static int starturbs(struct bc_state *bcs) | |||
859 | for (k = 0; k < BAS_INURBS; k++) { | 822 | for (k = 0; k < BAS_INURBS; k++) { |
860 | urb = ubc->isoinurbs[k]; | 823 | urb = ubc->isoinurbs[k]; |
861 | if (!urb) { | 824 | if (!urb) { |
862 | err("isoinurbs[%d]==NULL", k); | 825 | dev_err(bcs->cs->dev, "isoinurbs[%d]==NULL\n", k); |
863 | rc = -EFAULT; | 826 | rc = -EFAULT; |
864 | goto error; | 827 | goto error; |
865 | } | 828 | } |
@@ -882,8 +845,9 @@ static int starturbs(struct bc_state *bcs) | |||
882 | 845 | ||
883 | dump_urb(DEBUG_ISO, "Initial isoc read", urb); | 846 | dump_urb(DEBUG_ISO, "Initial isoc read", urb); |
884 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { | 847 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { |
885 | err("could not submit isochronous read URB %d: %s", | 848 | dev_err(bcs->cs->dev, |
886 | k, get_usb_statmsg(rc)); | 849 | "could not submit isochronous read URB %d: %s\n", |
850 | k, get_usb_statmsg(rc)); | ||
887 | goto error; | 851 | goto error; |
888 | } | 852 | } |
889 | } | 853 | } |
@@ -895,7 +859,7 @@ static int starturbs(struct bc_state *bcs) | |||
895 | for (k = 0; k < BAS_OUTURBS; ++k) { | 859 | for (k = 0; k < BAS_OUTURBS; ++k) { |
896 | urb = ubc->isoouturbs[k].urb; | 860 | urb = ubc->isoouturbs[k].urb; |
897 | if (!urb) { | 861 | if (!urb) { |
898 | err("isoouturbs[%d].urb==NULL", k); | 862 | dev_err(bcs->cs->dev, "isoouturbs[%d].urb==NULL\n", k); |
899 | rc = -EFAULT; | 863 | rc = -EFAULT; |
900 | goto error; | 864 | goto error; |
901 | } | 865 | } |
@@ -922,8 +886,9 @@ static int starturbs(struct bc_state *bcs) | |||
922 | dump_urb(DEBUG_ISO, "Initial isoc write", urb); | 886 | dump_urb(DEBUG_ISO, "Initial isoc write", urb); |
923 | rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); | 887 | rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); |
924 | if (rc != 0) { | 888 | if (rc != 0) { |
925 | err("could not submit isochronous write URB %d: %s", | 889 | dev_err(bcs->cs->dev, |
926 | k, get_usb_statmsg(rc)); | 890 | "could not submit isochronous write URB %d: %s\n", |
891 | k, get_usb_statmsg(rc)); | ||
927 | goto error; | 892 | goto error; |
928 | } | 893 | } |
929 | } | 894 | } |
@@ -946,20 +911,20 @@ static void stopurbs(struct bas_bc_state *ubc) | |||
946 | { | 911 | { |
947 | int k, rc; | 912 | int k, rc; |
948 | 913 | ||
949 | IFNULLRET(ubc); | ||
950 | |||
951 | atomic_set(&ubc->running, 0); | 914 | atomic_set(&ubc->running, 0); |
952 | 915 | ||
953 | for (k = 0; k < BAS_INURBS; ++k) { | 916 | for (k = 0; k < BAS_INURBS; ++k) { |
954 | rc = usb_unlink_urb(ubc->isoinurbs[k]); | 917 | rc = usb_unlink_urb(ubc->isoinurbs[k]); |
955 | dbg(DEBUG_ISO, "%s: isoc input URB %d unlinked, result = %d", | 918 | gig_dbg(DEBUG_ISO, |
956 | __func__, k, rc); | 919 | "%s: isoc input URB %d unlinked, result = %d", |
920 | __func__, k, rc); | ||
957 | } | 921 | } |
958 | 922 | ||
959 | for (k = 0; k < BAS_OUTURBS; ++k) { | 923 | for (k = 0; k < BAS_OUTURBS; ++k) { |
960 | rc = usb_unlink_urb(ubc->isoouturbs[k].urb); | 924 | rc = usb_unlink_urb(ubc->isoouturbs[k].urb); |
961 | dbg(DEBUG_ISO, "%s: isoc output URB %d unlinked, result = %d", | 925 | gig_dbg(DEBUG_ISO, |
962 | __func__, k, rc); | 926 | "%s: isoc output URB %d unlinked, result = %d", |
927 | __func__, k, rc); | ||
963 | } | 928 | } |
964 | } | 929 | } |
965 | 930 | ||
@@ -977,19 +942,14 @@ static void stopurbs(struct bas_bc_state *ubc) | |||
977 | */ | 942 | */ |
978 | static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | 943 | static int submit_iso_write_urb(struct isow_urbctx_t *ucx) |
979 | { | 944 | { |
980 | struct urb *urb; | 945 | struct urb *urb = ucx->urb; |
981 | struct bas_bc_state *ubc; | 946 | struct bas_bc_state *ubc = ucx->bcs->hw.bas; |
982 | struct usb_iso_packet_descriptor *ifd; | 947 | struct usb_iso_packet_descriptor *ifd; |
983 | int corrbytes, nframe, rc; | 948 | int corrbytes, nframe, rc; |
949 | unsigned long flags; | ||
984 | 950 | ||
985 | IFNULLRETVAL(ucx, -EFAULT); | 951 | /* urb->dev is clobbered by USB subsystem */ |
986 | urb = ucx->urb; | 952 | urb->dev = ucx->bcs->cs->hw.bas->udev; |
987 | IFNULLRETVAL(urb, -EFAULT); | ||
988 | IFNULLRETVAL(ucx->bcs, -EFAULT); | ||
989 | ubc = ucx->bcs->hw.bas; | ||
990 | IFNULLRETVAL(ubc, -EFAULT); | ||
991 | |||
992 | urb->dev = ucx->bcs->cs->hw.bas->udev; /* clobbered by USB subsystem */ | ||
993 | urb->transfer_flags = URB_ISO_ASAP; | 953 | urb->transfer_flags = URB_ISO_ASAP; |
994 | urb->transfer_buffer = ubc->isooutbuf->data; | 954 | urb->transfer_buffer = ubc->isooutbuf->data; |
995 | urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data); | 955 | urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data); |
@@ -1000,7 +960,8 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1000 | /* compute frame length according to flow control */ | 960 | /* compute frame length according to flow control */ |
1001 | ifd->length = BAS_NORMFRAME; | 961 | ifd->length = BAS_NORMFRAME; |
1002 | if ((corrbytes = atomic_read(&ubc->corrbytes)) != 0) { | 962 | if ((corrbytes = atomic_read(&ubc->corrbytes)) != 0) { |
1003 | dbg(DEBUG_ISO, "%s: corrbytes=%d", __func__, corrbytes); | 963 | gig_dbg(DEBUG_ISO, "%s: corrbytes=%d", |
964 | __func__, corrbytes); | ||
1004 | if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME) | 965 | if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME) |
1005 | corrbytes = BAS_HIGHFRAME - BAS_NORMFRAME; | 966 | corrbytes = BAS_HIGHFRAME - BAS_NORMFRAME; |
1006 | else if (corrbytes < BAS_LOWFRAME - BAS_NORMFRAME) | 967 | else if (corrbytes < BAS_LOWFRAME - BAS_NORMFRAME) |
@@ -1008,18 +969,21 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1008 | ifd->length += corrbytes; | 969 | ifd->length += corrbytes; |
1009 | atomic_add(-corrbytes, &ubc->corrbytes); | 970 | atomic_add(-corrbytes, &ubc->corrbytes); |
1010 | } | 971 | } |
1011 | //dbg(DEBUG_ISO, "%s: frame %d length=%d", __func__, nframe, ifd->length); | ||
1012 | 972 | ||
1013 | /* retrieve block of data to send */ | 973 | /* retrieve block of data to send */ |
1014 | ifd->offset = gigaset_isowbuf_getbytes(ubc->isooutbuf, ifd->length); | 974 | ifd->offset = gigaset_isowbuf_getbytes(ubc->isooutbuf, |
975 | ifd->length); | ||
1015 | if (ifd->offset < 0) { | 976 | if (ifd->offset < 0) { |
1016 | if (ifd->offset == -EBUSY) { | 977 | if (ifd->offset == -EBUSY) { |
1017 | dbg(DEBUG_ISO, "%s: buffer busy at frame %d", | 978 | gig_dbg(DEBUG_ISO, |
1018 | __func__, nframe); | 979 | "%s: buffer busy at frame %d", |
1019 | /* tasklet will be restarted from gigaset_send_skb() */ | 980 | __func__, nframe); |
981 | /* tasklet will be restarted from | ||
982 | gigaset_send_skb() */ | ||
1020 | } else { | 983 | } else { |
1021 | err("%s: buffer error %d at frame %d", | 984 | dev_err(ucx->bcs->cs->dev, |
1022 | __func__, ifd->offset, nframe); | 985 | "%s: buffer error %d at frame %d\n", |
986 | __func__, ifd->offset, nframe); | ||
1023 | return ifd->offset; | 987 | return ifd->offset; |
1024 | } | 988 | } |
1025 | break; | 989 | break; |
@@ -1029,9 +993,14 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1029 | ifd->actual_length = 0; | 993 | ifd->actual_length = 0; |
1030 | } | 994 | } |
1031 | if ((urb->number_of_packets = nframe) > 0) { | 995 | if ((urb->number_of_packets = nframe) > 0) { |
1032 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { | 996 | spin_lock_irqsave(&ucx->bcs->cs->lock, flags); |
1033 | err("could not submit isochronous write URB: %s", | 997 | rc = ucx->bcs->cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; |
1034 | get_usb_statmsg(rc)); | 998 | spin_unlock_irqrestore(&ucx->bcs->cs->lock, flags); |
999 | |||
1000 | if (rc) { | ||
1001 | dev_err(ucx->bcs->cs->dev, | ||
1002 | "could not submit isochronous write URB: %s\n", | ||
1003 | get_usb_statmsg(rc)); | ||
1035 | dump_urb(DEBUG_ISO, "isoc write", urb); | 1004 | dump_urb(DEBUG_ISO, "isoc write", urb); |
1036 | return rc; | 1005 | return rc; |
1037 | } | 1006 | } |
@@ -1048,9 +1017,9 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1048 | */ | 1017 | */ |
1049 | static void write_iso_tasklet(unsigned long data) | 1018 | static void write_iso_tasklet(unsigned long data) |
1050 | { | 1019 | { |
1051 | struct bc_state *bcs; | 1020 | struct bc_state *bcs = (struct bc_state *) data; |
1052 | struct bas_bc_state *ubc; | 1021 | struct bas_bc_state *ubc = bcs->hw.bas; |
1053 | struct cardstate *cs; | 1022 | struct cardstate *cs = bcs->cs; |
1054 | struct isow_urbctx_t *done, *next, *ovfl; | 1023 | struct isow_urbctx_t *done, *next, *ovfl; |
1055 | struct urb *urb; | 1024 | struct urb *urb; |
1056 | struct usb_iso_packet_descriptor *ifd; | 1025 | struct usb_iso_packet_descriptor *ifd; |
@@ -1060,22 +1029,10 @@ static void write_iso_tasklet(unsigned long data) | |||
1060 | struct sk_buff *skb; | 1029 | struct sk_buff *skb; |
1061 | int len; | 1030 | int len; |
1062 | 1031 | ||
1063 | bcs = (struct bc_state *) data; | ||
1064 | IFNULLRET(bcs); | ||
1065 | ubc = bcs->hw.bas; | ||
1066 | IFNULLRET(ubc); | ||
1067 | cs = bcs->cs; | ||
1068 | IFNULLRET(cs); | ||
1069 | |||
1070 | /* loop while completed URBs arrive in time */ | 1032 | /* loop while completed URBs arrive in time */ |
1071 | for (;;) { | 1033 | for (;;) { |
1072 | if (unlikely(!atomic_read(&cs->connected))) { | ||
1073 | warn("%s: disconnected", __func__); | ||
1074 | return; | ||
1075 | } | ||
1076 | |||
1077 | if (unlikely(!(atomic_read(&ubc->running)))) { | 1034 | if (unlikely(!(atomic_read(&ubc->running)))) { |
1078 | dbg(DEBUG_ISO, "%s: not running", __func__); | 1035 | gig_dbg(DEBUG_ISO, "%s: not running", __func__); |
1079 | return; | 1036 | return; |
1080 | } | 1037 | } |
1081 | 1038 | ||
@@ -1087,7 +1044,7 @@ static void write_iso_tasklet(unsigned long data) | |||
1087 | ubc->isooutovfl = NULL; | 1044 | ubc->isooutovfl = NULL; |
1088 | spin_unlock_irqrestore(&ubc->isooutlock, flags); | 1045 | spin_unlock_irqrestore(&ubc->isooutlock, flags); |
1089 | if (ovfl) { | 1046 | if (ovfl) { |
1090 | err("isochronous write buffer underrun - buy a faster machine :-)"); | 1047 | dev_err(cs->dev, "isochronous write buffer underrun\n"); |
1091 | error_hangup(bcs); | 1048 | error_hangup(bcs); |
1092 | break; | 1049 | break; |
1093 | } | 1050 | } |
@@ -1110,7 +1067,8 @@ static void write_iso_tasklet(unsigned long data) | |||
1110 | spin_unlock_irqrestore(&ubc->isooutlock, flags); | 1067 | spin_unlock_irqrestore(&ubc->isooutlock, flags); |
1111 | if (next) { | 1068 | if (next) { |
1112 | /* couldn't put it back */ | 1069 | /* couldn't put it back */ |
1113 | err("losing isochronous write URB"); | 1070 | dev_err(cs->dev, |
1071 | "losing isochronous write URB\n"); | ||
1114 | error_hangup(bcs); | 1072 | error_hangup(bcs); |
1115 | } | 1073 | } |
1116 | } | 1074 | } |
@@ -1123,22 +1081,25 @@ static void write_iso_tasklet(unsigned long data) | |||
1123 | break; | 1081 | break; |
1124 | case -EXDEV: /* inspect individual frames */ | 1082 | case -EXDEV: /* inspect individual frames */ |
1125 | /* assumptions (for lack of documentation): | 1083 | /* assumptions (for lack of documentation): |
1126 | * - actual_length bytes of the frame in error are successfully sent | 1084 | * - actual_length bytes of the frame in error are |
1085 | * successfully sent | ||
1127 | * - all following frames are not sent at all | 1086 | * - all following frames are not sent at all |
1128 | */ | 1087 | */ |
1129 | dbg(DEBUG_ISO, "%s: URB partially completed", __func__); | 1088 | gig_dbg(DEBUG_ISO, "%s: URB partially completed", |
1089 | __func__); | ||
1130 | offset = done->limit; /* just in case */ | 1090 | offset = done->limit; /* just in case */ |
1131 | for (i = 0; i < BAS_NUMFRAMES; i++) { | 1091 | for (i = 0; i < BAS_NUMFRAMES; i++) { |
1132 | ifd = &urb->iso_frame_desc[i]; | 1092 | ifd = &urb->iso_frame_desc[i]; |
1133 | if (ifd->status || | 1093 | if (ifd->status || |
1134 | ifd->actual_length != ifd->length) { | 1094 | ifd->actual_length != ifd->length) { |
1135 | warn("isochronous write: frame %d: %s, " | 1095 | dev_warn(cs->dev, |
1136 | "only %d of %d bytes sent", | 1096 | "isochronous write: frame %d: %s, " |
1097 | "only %d of %d bytes sent\n", | ||
1137 | i, get_usb_statmsg(ifd->status), | 1098 | i, get_usb_statmsg(ifd->status), |
1138 | ifd->actual_length, ifd->length); | 1099 | ifd->actual_length, ifd->length); |
1139 | offset = (ifd->offset + | 1100 | offset = (ifd->offset + |
1140 | ifd->actual_length) | 1101 | ifd->actual_length) |
1141 | % BAS_OUTBUFSIZE; | 1102 | % BAS_OUTBUFSIZE; |
1142 | break; | 1103 | break; |
1143 | } | 1104 | } |
1144 | } | 1105 | } |
@@ -1148,25 +1109,26 @@ static void write_iso_tasklet(unsigned long data) | |||
1148 | ifd = &urb->iso_frame_desc[i]; | 1109 | ifd = &urb->iso_frame_desc[i]; |
1149 | if (ifd->status != -EINPROGRESS | 1110 | if (ifd->status != -EINPROGRESS |
1150 | || ifd->actual_length != 0) { | 1111 | || ifd->actual_length != 0) { |
1151 | warn("isochronous write: frame %d: %s, " | 1112 | dev_warn(cs->dev, |
1152 | "%d of %d bytes sent", | 1113 | "isochronous write: frame %d: %s, " |
1114 | "%d of %d bytes sent\n", | ||
1153 | i, get_usb_statmsg(ifd->status), | 1115 | i, get_usb_statmsg(ifd->status), |
1154 | ifd->actual_length, ifd->length); | 1116 | ifd->actual_length, ifd->length); |
1155 | offset = (ifd->offset + | 1117 | offset = (ifd->offset + |
1156 | ifd->actual_length) | 1118 | ifd->actual_length) |
1157 | % BAS_OUTBUFSIZE; | 1119 | % BAS_OUTBUFSIZE; |
1158 | break; | 1120 | break; |
1159 | } | 1121 | } |
1160 | } | 1122 | } |
1161 | #endif | 1123 | #endif |
1162 | break; | 1124 | break; |
1163 | case -EPIPE: //FIXME is this the code for "underrun"? | 1125 | case -EPIPE: //FIXME is this the code for "underrun"? |
1164 | err("isochronous write stalled"); | 1126 | dev_err(cs->dev, "isochronous write stalled\n"); |
1165 | error_hangup(bcs); | 1127 | error_hangup(bcs); |
1166 | break; | 1128 | break; |
1167 | default: /* severe trouble */ | 1129 | default: /* severe trouble */ |
1168 | warn("isochronous write: %s", | 1130 | dev_warn(cs->dev, "isochronous write: %s\n", |
1169 | get_usb_statmsg(urb->status)); | 1131 | get_usb_statmsg(urb->status)); |
1170 | } | 1132 | } |
1171 | 1133 | ||
1172 | /* mark the write buffer area covered by this URB as free */ | 1134 | /* mark the write buffer area covered by this URB as free */ |
@@ -1194,8 +1156,8 @@ static void write_iso_tasklet(unsigned long data) | |||
1194 | if (gigaset_isoc_buildframe(bcs, skb->data, len) == -EAGAIN) { | 1156 | if (gigaset_isoc_buildframe(bcs, skb->data, len) == -EAGAIN) { |
1195 | /* insufficient buffer space, push back onto queue */ | 1157 | /* insufficient buffer space, push back onto queue */ |
1196 | skb_queue_head(&bcs->squeue, skb); | 1158 | skb_queue_head(&bcs->squeue, skb); |
1197 | dbg(DEBUG_ISO, "%s: skb requeued, qlen=%d", | 1159 | gig_dbg(DEBUG_ISO, "%s: skb requeued, qlen=%d", |
1198 | __func__, skb_queue_len(&bcs->squeue)); | 1160 | __func__, skb_queue_len(&bcs->squeue)); |
1199 | break; | 1161 | break; |
1200 | } | 1162 | } |
1201 | skb_pull(skb, len); | 1163 | skb_pull(skb, len); |
@@ -1215,28 +1177,16 @@ static void write_iso_tasklet(unsigned long data) | |||
1215 | */ | 1177 | */ |
1216 | static void read_iso_tasklet(unsigned long data) | 1178 | static void read_iso_tasklet(unsigned long data) |
1217 | { | 1179 | { |
1218 | struct bc_state *bcs; | 1180 | struct bc_state *bcs = (struct bc_state *) data; |
1219 | struct bas_bc_state *ubc; | 1181 | struct bas_bc_state *ubc = bcs->hw.bas; |
1220 | struct cardstate *cs; | 1182 | struct cardstate *cs = bcs->cs; |
1221 | struct urb *urb; | 1183 | struct urb *urb; |
1222 | char *rcvbuf; | 1184 | char *rcvbuf; |
1223 | unsigned long flags; | 1185 | unsigned long flags; |
1224 | int totleft, numbytes, offset, frame, rc; | 1186 | int totleft, numbytes, offset, frame, rc; |
1225 | 1187 | ||
1226 | bcs = (struct bc_state *) data; | ||
1227 | IFNULLRET(bcs); | ||
1228 | ubc = bcs->hw.bas; | ||
1229 | IFNULLRET(ubc); | ||
1230 | cs = bcs->cs; | ||
1231 | IFNULLRET(cs); | ||
1232 | |||
1233 | /* loop while more completed URBs arrive in the meantime */ | 1188 | /* loop while more completed URBs arrive in the meantime */ |
1234 | for (;;) { | 1189 | for (;;) { |
1235 | if (!atomic_read(&cs->connected)) { | ||
1236 | warn("%s: disconnected", __func__); | ||
1237 | return; | ||
1238 | } | ||
1239 | |||
1240 | /* retrieve URB */ | 1190 | /* retrieve URB */ |
1241 | spin_lock_irqsave(&ubc->isoinlock, flags); | 1191 | spin_lock_irqsave(&ubc->isoinlock, flags); |
1242 | if (!(urb = ubc->isoindone)) { | 1192 | if (!(urb = ubc->isoindone)) { |
@@ -1245,38 +1195,45 @@ static void read_iso_tasklet(unsigned long data) | |||
1245 | } | 1195 | } |
1246 | ubc->isoindone = NULL; | 1196 | ubc->isoindone = NULL; |
1247 | if (unlikely(ubc->loststatus != -EINPROGRESS)) { | 1197 | if (unlikely(ubc->loststatus != -EINPROGRESS)) { |
1248 | warn("isochronous read overrun, dropped URB with status: %s, %d bytes lost", | 1198 | dev_warn(cs->dev, |
1249 | get_usb_statmsg(ubc->loststatus), ubc->isoinlost); | 1199 | "isochronous read overrun, " |
1200 | "dropped URB with status: %s, %d bytes lost\n", | ||
1201 | get_usb_statmsg(ubc->loststatus), | ||
1202 | ubc->isoinlost); | ||
1250 | ubc->loststatus = -EINPROGRESS; | 1203 | ubc->loststatus = -EINPROGRESS; |
1251 | } | 1204 | } |
1252 | spin_unlock_irqrestore(&ubc->isoinlock, flags); | 1205 | spin_unlock_irqrestore(&ubc->isoinlock, flags); |
1253 | 1206 | ||
1254 | if (unlikely(!(atomic_read(&ubc->running)))) { | 1207 | if (unlikely(!(atomic_read(&ubc->running)))) { |
1255 | dbg(DEBUG_ISO, "%s: channel not running, dropped URB with status: %s", | 1208 | gig_dbg(DEBUG_ISO, |
1256 | __func__, get_usb_statmsg(urb->status)); | 1209 | "%s: channel not running, " |
1210 | "dropped URB with status: %s", | ||
1211 | __func__, get_usb_statmsg(urb->status)); | ||
1257 | return; | 1212 | return; |
1258 | } | 1213 | } |
1259 | 1214 | ||
1260 | switch (urb->status) { | 1215 | switch (urb->status) { |
1261 | case 0: /* normal completion */ | 1216 | case 0: /* normal completion */ |
1262 | break; | 1217 | break; |
1263 | case -EXDEV: /* inspect individual frames (we do that anyway) */ | 1218 | case -EXDEV: /* inspect individual frames |
1264 | dbg(DEBUG_ISO, "%s: URB partially completed", __func__); | 1219 | (we do that anyway) */ |
1220 | gig_dbg(DEBUG_ISO, "%s: URB partially completed", | ||
1221 | __func__); | ||
1265 | break; | 1222 | break; |
1266 | case -ENOENT: | 1223 | case -ENOENT: |
1267 | case -ECONNRESET: | 1224 | case -ECONNRESET: |
1268 | dbg(DEBUG_ISO, "%s: URB canceled", __func__); | 1225 | gig_dbg(DEBUG_ISO, "%s: URB canceled", __func__); |
1269 | continue; /* -> skip */ | 1226 | continue; /* -> skip */ |
1270 | case -EINPROGRESS: /* huh? */ | 1227 | case -EINPROGRESS: /* huh? */ |
1271 | dbg(DEBUG_ISO, "%s: URB still pending", __func__); | 1228 | gig_dbg(DEBUG_ISO, "%s: URB still pending", __func__); |
1272 | continue; /* -> skip */ | 1229 | continue; /* -> skip */ |
1273 | case -EPIPE: | 1230 | case -EPIPE: |
1274 | err("isochronous read stalled"); | 1231 | dev_err(cs->dev, "isochronous read stalled\n"); |
1275 | error_hangup(bcs); | 1232 | error_hangup(bcs); |
1276 | continue; /* -> skip */ | 1233 | continue; /* -> skip */ |
1277 | default: /* severe trouble */ | 1234 | default: /* severe trouble */ |
1278 | warn("isochronous read: %s", | 1235 | dev_warn(cs->dev, "isochronous read: %s\n", |
1279 | get_usb_statmsg(urb->status)); | 1236 | get_usb_statmsg(urb->status)); |
1280 | goto error; | 1237 | goto error; |
1281 | } | 1238 | } |
1282 | 1239 | ||
@@ -1284,33 +1241,44 @@ static void read_iso_tasklet(unsigned long data) | |||
1284 | totleft = urb->actual_length; | 1241 | totleft = urb->actual_length; |
1285 | for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { | 1242 | for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { |
1286 | if (unlikely(urb->iso_frame_desc[frame].status)) { | 1243 | if (unlikely(urb->iso_frame_desc[frame].status)) { |
1287 | warn("isochronous read: frame %d: %s", | 1244 | dev_warn(cs->dev, |
1288 | frame, get_usb_statmsg(urb->iso_frame_desc[frame].status)); | 1245 | "isochronous read: frame %d: %s\n", |
1246 | frame, | ||
1247 | get_usb_statmsg( | ||
1248 | urb->iso_frame_desc[frame].status)); | ||
1289 | break; | 1249 | break; |
1290 | } | 1250 | } |
1291 | numbytes = urb->iso_frame_desc[frame].actual_length; | 1251 | numbytes = urb->iso_frame_desc[frame].actual_length; |
1292 | if (unlikely(numbytes > BAS_MAXFRAME)) { | 1252 | if (unlikely(numbytes > BAS_MAXFRAME)) { |
1293 | warn("isochronous read: frame %d: numbytes (%d) > BAS_MAXFRAME", | 1253 | dev_warn(cs->dev, |
1294 | frame, numbytes); | 1254 | "isochronous read: frame %d: " |
1255 | "numbytes (%d) > BAS_MAXFRAME\n", | ||
1256 | frame, numbytes); | ||
1295 | break; | 1257 | break; |
1296 | } | 1258 | } |
1297 | if (unlikely(numbytes > totleft)) { | 1259 | if (unlikely(numbytes > totleft)) { |
1298 | warn("isochronous read: frame %d: numbytes (%d) > totleft (%d)", | 1260 | dev_warn(cs->dev, |
1299 | frame, numbytes, totleft); | 1261 | "isochronous read: frame %d: " |
1262 | "numbytes (%d) > totleft (%d)\n", | ||
1263 | frame, numbytes, totleft); | ||
1300 | break; | 1264 | break; |
1301 | } | 1265 | } |
1302 | offset = urb->iso_frame_desc[frame].offset; | 1266 | offset = urb->iso_frame_desc[frame].offset; |
1303 | if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { | 1267 | if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { |
1304 | warn("isochronous read: frame %d: offset (%d) + numbytes (%d) > BAS_INBUFSIZE", | 1268 | dev_warn(cs->dev, |
1305 | frame, offset, numbytes); | 1269 | "isochronous read: frame %d: " |
1270 | "offset (%d) + numbytes (%d) " | ||
1271 | "> BAS_INBUFSIZE\n", | ||
1272 | frame, offset, numbytes); | ||
1306 | break; | 1273 | break; |
1307 | } | 1274 | } |
1308 | gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); | 1275 | gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); |
1309 | totleft -= numbytes; | 1276 | totleft -= numbytes; |
1310 | } | 1277 | } |
1311 | if (unlikely(totleft > 0)) | 1278 | if (unlikely(totleft > 0)) |
1312 | warn("isochronous read: %d data bytes missing", | 1279 | dev_warn(cs->dev, |
1313 | totleft); | 1280 | "isochronous read: %d data bytes missing\n", |
1281 | totleft); | ||
1314 | 1282 | ||
1315 | error: | 1283 | error: |
1316 | /* URB processed, resubmit */ | 1284 | /* URB processed, resubmit */ |
@@ -1318,12 +1286,17 @@ static void read_iso_tasklet(unsigned long data) | |||
1318 | urb->iso_frame_desc[frame].status = 0; | 1286 | urb->iso_frame_desc[frame].status = 0; |
1319 | urb->iso_frame_desc[frame].actual_length = 0; | 1287 | urb->iso_frame_desc[frame].actual_length = 0; |
1320 | } | 1288 | } |
1321 | urb->dev = bcs->cs->hw.bas->udev; /* clobbered by USB subsystem */ | 1289 | /* urb->dev is clobbered by USB subsystem */ |
1290 | urb->dev = bcs->cs->hw.bas->udev; | ||
1322 | urb->transfer_flags = URB_ISO_ASAP; | 1291 | urb->transfer_flags = URB_ISO_ASAP; |
1323 | urb->number_of_packets = BAS_NUMFRAMES; | 1292 | urb->number_of_packets = BAS_NUMFRAMES; |
1324 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { | 1293 | spin_lock_irqsave(&cs->lock, flags); |
1325 | err("could not resubmit isochronous read URB: %s", | 1294 | rc = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; |
1326 | get_usb_statmsg(rc)); | 1295 | spin_unlock_irqrestore(&cs->lock, flags); |
1296 | if (rc) { | ||
1297 | dev_err(cs->dev, | ||
1298 | "could not resubmit isochronous read URB: %s\n", | ||
1299 | get_usb_statmsg(rc)); | ||
1327 | dump_urb(DEBUG_ISO, "resubmit iso read", urb); | 1300 | dump_urb(DEBUG_ISO, "resubmit iso read", urb); |
1328 | error_hangup(bcs); | 1301 | error_hangup(bcs); |
1329 | } | 1302 | } |
@@ -1341,15 +1314,10 @@ static void read_iso_tasklet(unsigned long data) | |||
1341 | static void req_timeout(unsigned long data) | 1314 | static void req_timeout(unsigned long data) |
1342 | { | 1315 | { |
1343 | struct bc_state *bcs = (struct bc_state *) data; | 1316 | struct bc_state *bcs = (struct bc_state *) data; |
1344 | struct bas_cardstate *ucs; | 1317 | struct bas_cardstate *ucs = bcs->cs->hw.bas; |
1345 | int pending; | 1318 | int pending; |
1346 | unsigned long flags; | 1319 | unsigned long flags; |
1347 | 1320 | ||
1348 | IFNULLRET(bcs); | ||
1349 | IFNULLRET(bcs->cs); | ||
1350 | ucs = bcs->cs->hw.bas; | ||
1351 | IFNULLRET(ucs); | ||
1352 | |||
1353 | check_pending(ucs); | 1321 | check_pending(ucs); |
1354 | 1322 | ||
1355 | spin_lock_irqsave(&ucs->lock, flags); | 1323 | spin_lock_irqsave(&ucs->lock, flags); |
@@ -1359,33 +1327,34 @@ static void req_timeout(unsigned long data) | |||
1359 | 1327 | ||
1360 | switch (pending) { | 1328 | switch (pending) { |
1361 | case 0: /* no pending request */ | 1329 | case 0: /* no pending request */ |
1362 | dbg(DEBUG_USBREQ, "%s: no request pending", __func__); | 1330 | gig_dbg(DEBUG_USBREQ, "%s: no request pending", __func__); |
1363 | break; | 1331 | break; |
1364 | 1332 | ||
1365 | case HD_OPEN_ATCHANNEL: | 1333 | case HD_OPEN_ATCHANNEL: |
1366 | err("timeout opening AT channel"); | 1334 | dev_err(bcs->cs->dev, "timeout opening AT channel\n"); |
1367 | error_reset(bcs->cs); | 1335 | error_reset(bcs->cs); |
1368 | break; | 1336 | break; |
1369 | 1337 | ||
1370 | case HD_OPEN_B2CHANNEL: | 1338 | case HD_OPEN_B2CHANNEL: |
1371 | case HD_OPEN_B1CHANNEL: | 1339 | case HD_OPEN_B1CHANNEL: |
1372 | err("timeout opening channel %d", bcs->channel + 1); | 1340 | dev_err(bcs->cs->dev, "timeout opening channel %d\n", |
1341 | bcs->channel + 1); | ||
1373 | error_hangup(bcs); | 1342 | error_hangup(bcs); |
1374 | break; | 1343 | break; |
1375 | 1344 | ||
1376 | case HD_CLOSE_ATCHANNEL: | 1345 | case HD_CLOSE_ATCHANNEL: |
1377 | err("timeout closing AT channel"); | 1346 | dev_err(bcs->cs->dev, "timeout closing AT channel\n"); |
1378 | //wake_up_interruptible(cs->initwait); | ||
1379 | //FIXME need own wait queue? | ||
1380 | break; | 1347 | break; |
1381 | 1348 | ||
1382 | case HD_CLOSE_B2CHANNEL: | 1349 | case HD_CLOSE_B2CHANNEL: |
1383 | case HD_CLOSE_B1CHANNEL: | 1350 | case HD_CLOSE_B1CHANNEL: |
1384 | err("timeout closing channel %d", bcs->channel + 1); | 1351 | dev_err(bcs->cs->dev, "timeout closing channel %d\n", |
1352 | bcs->channel + 1); | ||
1385 | break; | 1353 | break; |
1386 | 1354 | ||
1387 | default: | 1355 | default: |
1388 | warn("request 0x%02x timed out, clearing", pending); | 1356 | dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", |
1357 | pending); | ||
1389 | } | 1358 | } |
1390 | } | 1359 | } |
1391 | 1360 | ||
@@ -1398,18 +1367,14 @@ static void req_timeout(unsigned long data) | |||
1398 | */ | 1367 | */ |
1399 | static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) | 1368 | static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) |
1400 | { | 1369 | { |
1401 | struct bas_cardstate *ucs; | 1370 | struct bas_cardstate *ucs = urb->context; |
1402 | unsigned long flags; | 1371 | unsigned long flags; |
1403 | 1372 | ||
1404 | IFNULLRET(urb); | ||
1405 | IFNULLRET(urb->context); | ||
1406 | IFNULLRET(cardstate); | ||
1407 | |||
1408 | ucs = (struct bas_cardstate *) urb->context; | ||
1409 | spin_lock_irqsave(&ucs->lock, flags); | 1373 | spin_lock_irqsave(&ucs->lock, flags); |
1410 | if (urb->status && ucs->pending) { | 1374 | if (urb->status && ucs->pending) { |
1411 | err("control request 0x%02x failed: %s", | 1375 | dev_err(&ucs->interface->dev, |
1412 | ucs->pending, get_usb_statmsg(urb->status)); | 1376 | "control request 0x%02x failed: %s\n", |
1377 | ucs->pending, get_usb_statmsg(urb->status)); | ||
1413 | del_timer(&ucs->timer_ctrl); | 1378 | del_timer(&ucs->timer_ctrl); |
1414 | ucs->pending = 0; | 1379 | ucs->pending = 0; |
1415 | } | 1380 | } |
@@ -1438,28 +1403,25 @@ static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
1438 | */ | 1403 | */ |
1439 | static int req_submit(struct bc_state *bcs, int req, int val, int timeout) | 1404 | static int req_submit(struct bc_state *bcs, int req, int val, int timeout) |
1440 | { | 1405 | { |
1441 | struct bas_cardstate *ucs; | 1406 | struct bas_cardstate *ucs = bcs->cs->hw.bas; |
1442 | int ret; | 1407 | int ret; |
1443 | unsigned long flags; | 1408 | unsigned long flags; |
1444 | 1409 | ||
1445 | IFNULLRETVAL(bcs, -EINVAL); | 1410 | gig_dbg(DEBUG_USBREQ, "-------> 0x%02x (%d)", req, val); |
1446 | IFNULLRETVAL(bcs->cs, -EINVAL); | ||
1447 | ucs = bcs->cs->hw.bas; | ||
1448 | IFNULLRETVAL(ucs, -EINVAL); | ||
1449 | IFNULLRETVAL(ucs->urb_ctrl, -EINVAL); | ||
1450 | |||
1451 | dbg(DEBUG_USBREQ, "-------> 0x%02x (%d)", req, val); | ||
1452 | 1411 | ||
1453 | spin_lock_irqsave(&ucs->lock, flags); | 1412 | spin_lock_irqsave(&ucs->lock, flags); |
1454 | if (ucs->pending) { | 1413 | if (ucs->pending) { |
1455 | spin_unlock_irqrestore(&ucs->lock, flags); | 1414 | spin_unlock_irqrestore(&ucs->lock, flags); |
1456 | err("submission of request 0x%02x failed: request 0x%02x still pending", | 1415 | dev_err(bcs->cs->dev, |
1457 | req, ucs->pending); | 1416 | "submission of request 0x%02x failed: " |
1417 | "request 0x%02x still pending\n", | ||
1418 | req, ucs->pending); | ||
1458 | return -EBUSY; | 1419 | return -EBUSY; |
1459 | } | 1420 | } |
1460 | if (ucs->urb_ctrl->status == -EINPROGRESS) { | 1421 | if (ucs->urb_ctrl->status == -EINPROGRESS) { |
1461 | spin_unlock_irqrestore(&ucs->lock, flags); | 1422 | spin_unlock_irqrestore(&ucs->lock, flags); |
1462 | err("could not submit request 0x%02x: URB busy", req); | 1423 | dev_err(bcs->cs->dev, |
1424 | "could not submit request 0x%02x: URB busy\n", req); | ||
1463 | return -EBUSY; | 1425 | return -EBUSY; |
1464 | } | 1426 | } |
1465 | 1427 | ||
@@ -1469,19 +1431,19 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) | |||
1469 | ucs->dr_ctrl.wIndex = 0; | 1431 | ucs->dr_ctrl.wIndex = 0; |
1470 | ucs->dr_ctrl.wLength = 0; | 1432 | ucs->dr_ctrl.wLength = 0; |
1471 | usb_fill_control_urb(ucs->urb_ctrl, ucs->udev, | 1433 | usb_fill_control_urb(ucs->urb_ctrl, ucs->udev, |
1472 | usb_sndctrlpipe(ucs->udev, 0), | 1434 | usb_sndctrlpipe(ucs->udev, 0), |
1473 | (unsigned char*) &ucs->dr_ctrl, NULL, 0, | 1435 | (unsigned char*) &ucs->dr_ctrl, NULL, 0, |
1474 | write_ctrl_callback, ucs); | 1436 | write_ctrl_callback, ucs); |
1475 | if ((ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC)) != 0) { | 1437 | if ((ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC)) != 0) { |
1476 | err("could not submit request 0x%02x: %s", | 1438 | dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n", |
1477 | req, get_usb_statmsg(ret)); | 1439 | req, get_usb_statmsg(ret)); |
1478 | spin_unlock_irqrestore(&ucs->lock, flags); | 1440 | spin_unlock_irqrestore(&ucs->lock, flags); |
1479 | return ret; | 1441 | return ret; |
1480 | } | 1442 | } |
1481 | ucs->pending = req; | 1443 | ucs->pending = req; |
1482 | 1444 | ||
1483 | if (timeout > 0) { | 1445 | if (timeout > 0) { |
1484 | dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); | 1446 | gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); |
1485 | ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10; | 1447 | ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10; |
1486 | ucs->timer_ctrl.data = (unsigned long) bcs; | 1448 | ucs->timer_ctrl.data = (unsigned long) bcs; |
1487 | ucs->timer_ctrl.function = req_timeout; | 1449 | ucs->timer_ctrl.function = req_timeout; |
@@ -1504,19 +1466,18 @@ static int gigaset_init_bchannel(struct bc_state *bcs) | |||
1504 | { | 1466 | { |
1505 | int req, ret; | 1467 | int req, ret; |
1506 | 1468 | ||
1507 | IFNULLRETVAL(bcs, -EINVAL); | ||
1508 | |||
1509 | if ((ret = starturbs(bcs)) < 0) { | 1469 | if ((ret = starturbs(bcs)) < 0) { |
1510 | err("could not start isochronous I/O for channel %d", | 1470 | dev_err(bcs->cs->dev, |
1511 | bcs->channel + 1); | 1471 | "could not start isochronous I/O for channel %d\n", |
1472 | bcs->channel + 1); | ||
1512 | error_hangup(bcs); | 1473 | error_hangup(bcs); |
1513 | return ret; | 1474 | return ret; |
1514 | } | 1475 | } |
1515 | 1476 | ||
1516 | req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; | 1477 | req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; |
1517 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { | 1478 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { |
1518 | err("could not open channel %d: %s", | 1479 | dev_err(bcs->cs->dev, "could not open channel %d: %s\n", |
1519 | bcs->channel + 1, get_usb_statmsg(ret)); | 1480 | bcs->channel + 1, get_usb_statmsg(ret)); |
1520 | stopurbs(bcs->hw.bas); | 1481 | stopurbs(bcs->hw.bas); |
1521 | error_hangup(bcs); | 1482 | error_hangup(bcs); |
1522 | } | 1483 | } |
@@ -1537,8 +1498,6 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
1537 | { | 1498 | { |
1538 | int req, ret; | 1499 | int req, ret; |
1539 | 1500 | ||
1540 | IFNULLRETVAL(bcs, -EINVAL); | ||
1541 | |||
1542 | if (!(atomic_read(&bcs->cs->hw.bas->basstate) & | 1501 | if (!(atomic_read(&bcs->cs->hw.bas->basstate) & |
1543 | (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { | 1502 | (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { |
1544 | /* channel not running: just signal common.c */ | 1503 | /* channel not running: just signal common.c */ |
@@ -1548,8 +1507,9 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
1548 | 1507 | ||
1549 | req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; | 1508 | req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; |
1550 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) | 1509 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) |
1551 | err("could not submit HD_CLOSE_BxCHANNEL request: %s", | 1510 | dev_err(bcs->cs->dev, |
1552 | get_usb_statmsg(ret)); | 1511 | "could not submit HD_CLOSE_BxCHANNEL request: %s\n", |
1512 | get_usb_statmsg(ret)); | ||
1553 | return ret; | 1513 | return ret; |
1554 | } | 1514 | } |
1555 | 1515 | ||
@@ -1564,17 +1524,13 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
1564 | */ | 1524 | */ |
1565 | static void complete_cb(struct cardstate *cs) | 1525 | static void complete_cb(struct cardstate *cs) |
1566 | { | 1526 | { |
1567 | struct cmdbuf_t *cb; | 1527 | struct cmdbuf_t *cb = cs->cmdbuf; |
1568 | |||
1569 | IFNULLRET(cs); | ||
1570 | cb = cs->cmdbuf; | ||
1571 | IFNULLRET(cb); | ||
1572 | 1528 | ||
1573 | /* unqueue completed buffer */ | 1529 | /* unqueue completed buffer */ |
1574 | cs->cmdbytes -= cs->curlen; | 1530 | cs->cmdbytes -= cs->curlen; |
1575 | dbg(DEBUG_TRANSCMD | DEBUG_LOCKCMD, | 1531 | gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, |
1576 | "write_command: sent %u bytes, %u left", | 1532 | "write_command: sent %u bytes, %u left", |
1577 | cs->curlen, cs->cmdbytes); | 1533 | cs->curlen, cs->cmdbytes); |
1578 | if ((cs->cmdbuf = cb->next) != NULL) { | 1534 | if ((cs->cmdbuf = cb->next) != NULL) { |
1579 | cs->cmdbuf->prev = NULL; | 1535 | cs->cmdbuf->prev = NULL; |
1580 | cs->curlen = cs->cmdbuf->len; | 1536 | cs->curlen = cs->cmdbuf->len; |
@@ -1600,15 +1556,9 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len); | |||
1600 | */ | 1556 | */ |
1601 | static void write_command_callback(struct urb *urb, struct pt_regs *regs) | 1557 | static void write_command_callback(struct urb *urb, struct pt_regs *regs) |
1602 | { | 1558 | { |
1603 | struct cardstate *cs; | 1559 | struct cardstate *cs = urb->context; |
1560 | struct bas_cardstate *ucs = cs->hw.bas; | ||
1604 | unsigned long flags; | 1561 | unsigned long flags; |
1605 | struct bas_cardstate *ucs; | ||
1606 | |||
1607 | IFNULLRET(urb); | ||
1608 | cs = (struct cardstate *) urb->context; | ||
1609 | IFNULLRET(cs); | ||
1610 | ucs = cs->hw.bas; | ||
1611 | IFNULLRET(ucs); | ||
1612 | 1562 | ||
1613 | /* check status */ | 1563 | /* check status */ |
1614 | switch (urb->status) { | 1564 | switch (urb->status) { |
@@ -1618,22 +1568,27 @@ static void write_command_callback(struct urb *urb, struct pt_regs *regs) | |||
1618 | case -ECONNRESET: /* canceled (async) */ | 1568 | case -ECONNRESET: /* canceled (async) */ |
1619 | case -EINPROGRESS: /* pending */ | 1569 | case -EINPROGRESS: /* pending */ |
1620 | /* ignore silently */ | 1570 | /* ignore silently */ |
1621 | dbg(DEBUG_USBREQ, | 1571 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
1622 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 1572 | __func__, get_usb_statmsg(urb->status)); |
1623 | return; | 1573 | return; |
1624 | default: /* any failure */ | 1574 | default: /* any failure */ |
1625 | if (++ucs->retry_cmd_out > BAS_RETRY) { | 1575 | if (++ucs->retry_cmd_out > BAS_RETRY) { |
1626 | warn("command write: %s, giving up after %d retries", | 1576 | dev_warn(cs->dev, |
1627 | get_usb_statmsg(urb->status), ucs->retry_cmd_out); | 1577 | "command write: %s, " |
1578 | "giving up after %d retries\n", | ||
1579 | get_usb_statmsg(urb->status), | ||
1580 | ucs->retry_cmd_out); | ||
1628 | break; | 1581 | break; |
1629 | } | 1582 | } |
1630 | if (cs->cmdbuf == NULL) { | 1583 | if (cs->cmdbuf == NULL) { |
1631 | warn("command write: %s, cannot retry - cmdbuf gone", | 1584 | dev_warn(cs->dev, |
1632 | get_usb_statmsg(urb->status)); | 1585 | "command write: %s, " |
1586 | "cannot retry - cmdbuf gone\n", | ||
1587 | get_usb_statmsg(urb->status)); | ||
1633 | break; | 1588 | break; |
1634 | } | 1589 | } |
1635 | notice("command write: %s, retry %d", | 1590 | dev_notice(cs->dev, "command write: %s, retry %d\n", |
1636 | get_usb_statmsg(urb->status), ucs->retry_cmd_out); | 1591 | get_usb_statmsg(urb->status), ucs->retry_cmd_out); |
1637 | if (atwrite_submit(cs, cs->cmdbuf->buf, cs->cmdbuf->len) >= 0) | 1592 | if (atwrite_submit(cs, cs->cmdbuf->buf, cs->cmdbuf->len) >= 0) |
1638 | /* resubmitted - bypass regular exit block */ | 1593 | /* resubmitted - bypass regular exit block */ |
1639 | return; | 1594 | return; |
@@ -1655,13 +1610,9 @@ static void write_command_callback(struct urb *urb, struct pt_regs *regs) | |||
1655 | static void atrdy_timeout(unsigned long data) | 1610 | static void atrdy_timeout(unsigned long data) |
1656 | { | 1611 | { |
1657 | struct cardstate *cs = (struct cardstate *) data; | 1612 | struct cardstate *cs = (struct cardstate *) data; |
1658 | struct bas_cardstate *ucs; | 1613 | struct bas_cardstate *ucs = cs->hw.bas; |
1659 | |||
1660 | IFNULLRET(cs); | ||
1661 | ucs = cs->hw.bas; | ||
1662 | IFNULLRET(ucs); | ||
1663 | 1614 | ||
1664 | warn("timeout waiting for HD_READY_SEND_ATDATA"); | 1615 | dev_warn(cs->dev, "timeout waiting for HD_READY_SEND_ATDATA\n"); |
1665 | 1616 | ||
1666 | /* fake the missing signal - what else can I do? */ | 1617 | /* fake the missing signal - what else can I do? */ |
1667 | update_basstate(ucs, BS_ATREADY, BS_ATTIMER); | 1618 | update_basstate(ucs, BS_ATREADY, BS_ATTIMER); |
@@ -1682,18 +1633,15 @@ static void atrdy_timeout(unsigned long data) | |||
1682 | */ | 1633 | */ |
1683 | static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | 1634 | static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) |
1684 | { | 1635 | { |
1685 | struct bas_cardstate *ucs; | 1636 | struct bas_cardstate *ucs = cs->hw.bas; |
1637 | unsigned long flags; | ||
1686 | int ret; | 1638 | int ret; |
1687 | 1639 | ||
1688 | IFNULLRETVAL(cs, -EFAULT); | 1640 | gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); |
1689 | ucs = cs->hw.bas; | ||
1690 | IFNULLRETVAL(ucs, -EFAULT); | ||
1691 | IFNULLRETVAL(ucs->urb_cmd_out, -EFAULT); | ||
1692 | |||
1693 | dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); | ||
1694 | 1641 | ||
1695 | if (ucs->urb_cmd_out->status == -EINPROGRESS) { | 1642 | if (ucs->urb_cmd_out->status == -EINPROGRESS) { |
1696 | err("could not submit HD_WRITE_ATMESSAGE: URB busy"); | 1643 | dev_err(cs->dev, |
1644 | "could not submit HD_WRITE_ATMESSAGE: URB busy\n"); | ||
1697 | return -EBUSY; | 1645 | return -EBUSY; |
1698 | } | 1646 | } |
1699 | 1647 | ||
@@ -1707,9 +1655,13 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | |||
1707 | (unsigned char*) &ucs->dr_cmd_out, buf, len, | 1655 | (unsigned char*) &ucs->dr_cmd_out, buf, len, |
1708 | write_command_callback, cs); | 1656 | write_command_callback, cs); |
1709 | 1657 | ||
1710 | if ((ret = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC)) != 0) { | 1658 | spin_lock_irqsave(&cs->lock, flags); |
1711 | err("could not submit HD_WRITE_ATMESSAGE: %s", | 1659 | ret = cs->connected ? usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC) : -ENODEV; |
1712 | get_usb_statmsg(ret)); | 1660 | spin_unlock_irqrestore(&cs->lock, flags); |
1661 | |||
1662 | if (ret) { | ||
1663 | dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", | ||
1664 | get_usb_statmsg(ret)); | ||
1713 | return ret; | 1665 | return ret; |
1714 | } | 1666 | } |
1715 | 1667 | ||
@@ -1718,8 +1670,8 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | |||
1718 | 1670 | ||
1719 | /* start timeout if necessary */ | 1671 | /* start timeout if necessary */ |
1720 | if (!(atomic_read(&ucs->basstate) & BS_ATTIMER)) { | 1672 | if (!(atomic_read(&ucs->basstate) & BS_ATTIMER)) { |
1721 | dbg(DEBUG_OUTPUT, | 1673 | gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", |
1722 | "setting ATREADY timeout of %d/10 secs", ATRDY_TIMEOUT); | 1674 | ATRDY_TIMEOUT); |
1723 | ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; | 1675 | ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; |
1724 | ucs->timer_atrdy.data = (unsigned long) cs; | 1676 | ucs->timer_atrdy.data = (unsigned long) cs; |
1725 | ucs->timer_atrdy.function = atrdy_timeout; | 1677 | ucs->timer_atrdy.function = atrdy_timeout; |
@@ -1740,21 +1692,17 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | |||
1740 | static int start_cbsend(struct cardstate *cs) | 1692 | static int start_cbsend(struct cardstate *cs) |
1741 | { | 1693 | { |
1742 | struct cmdbuf_t *cb; | 1694 | struct cmdbuf_t *cb; |
1743 | struct bas_cardstate *ucs; | 1695 | struct bas_cardstate *ucs = cs->hw.bas; |
1744 | unsigned long flags; | 1696 | unsigned long flags; |
1745 | int rc; | 1697 | int rc; |
1746 | int retval = 0; | 1698 | int retval = 0; |
1747 | 1699 | ||
1748 | IFNULLRETVAL(cs, -EFAULT); | ||
1749 | ucs = cs->hw.bas; | ||
1750 | IFNULLRETVAL(ucs, -EFAULT); | ||
1751 | |||
1752 | /* check if AT channel is open */ | 1700 | /* check if AT channel is open */ |
1753 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) { | 1701 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) { |
1754 | dbg(DEBUG_TRANSCMD | DEBUG_LOCKCMD, "AT channel not open"); | 1702 | gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); |
1755 | rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); | 1703 | rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); |
1756 | if (rc < 0) { | 1704 | if (rc < 0) { |
1757 | err("could not open AT channel"); | 1705 | dev_err(cs->dev, "could not open AT channel\n"); |
1758 | /* flush command queue */ | 1706 | /* flush command queue */ |
1759 | spin_lock_irqsave(&cs->cmdlock, flags); | 1707 | spin_lock_irqsave(&cs->cmdlock, flags); |
1760 | while (cs->cmdbuf != NULL) | 1708 | while (cs->cmdbuf != NULL) |
@@ -1792,27 +1740,23 @@ static int start_cbsend(struct cardstate *cs) | |||
1792 | * cs controller state structure | 1740 | * cs controller state structure |
1793 | * buf command string to send | 1741 | * buf command string to send |
1794 | * len number of bytes to send (max. IF_WRITEBUF) | 1742 | * len number of bytes to send (max. IF_WRITEBUF) |
1795 | * wake_tasklet tasklet to run when transmission is completed (NULL if none) | 1743 | * wake_tasklet tasklet to run when transmission is completed |
1744 | * (NULL if none) | ||
1796 | * return value: | 1745 | * return value: |
1797 | * number of bytes queued on success | 1746 | * number of bytes queued on success |
1798 | * error code < 0 on error | 1747 | * error code < 0 on error |
1799 | */ | 1748 | */ |
1800 | static int gigaset_write_cmd(struct cardstate *cs, | 1749 | static int gigaset_write_cmd(struct cardstate *cs, |
1801 | const unsigned char *buf, int len, | 1750 | const unsigned char *buf, int len, |
1802 | struct tasklet_struct *wake_tasklet) | 1751 | struct tasklet_struct *wake_tasklet) |
1803 | { | 1752 | { |
1804 | struct cmdbuf_t *cb; | 1753 | struct cmdbuf_t *cb; |
1805 | unsigned long flags; | 1754 | unsigned long flags; |
1806 | int status; | 1755 | int status; |
1807 | 1756 | ||
1808 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? | 1757 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? |
1809 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 1758 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
1810 | "CMD Transmit", len, buf, 0); | 1759 | "CMD Transmit", len, buf); |
1811 | |||
1812 | if (!atomic_read(&cs->connected)) { | ||
1813 | err("%s: not connected", __func__); | ||
1814 | return -ENODEV; | ||
1815 | } | ||
1816 | 1760 | ||
1817 | if (len <= 0) | 1761 | if (len <= 0) |
1818 | return 0; /* nothing to do */ | 1762 | return 0; /* nothing to do */ |
@@ -1820,7 +1764,7 @@ static int gigaset_write_cmd(struct cardstate *cs, | |||
1820 | if (len > IF_WRITEBUF) | 1764 | if (len > IF_WRITEBUF) |
1821 | len = IF_WRITEBUF; | 1765 | len = IF_WRITEBUF; |
1822 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { | 1766 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { |
1823 | err("%s: out of memory", __func__); | 1767 | dev_err(cs->dev, "%s: out of memory\n", __func__); |
1824 | return -ENOMEM; | 1768 | return -ENOMEM; |
1825 | } | 1769 | } |
1826 | 1770 | ||
@@ -1849,7 +1793,8 @@ static int gigaset_write_cmd(struct cardstate *cs, | |||
1849 | 1793 | ||
1850 | /* gigaset_write_room | 1794 | /* gigaset_write_room |
1851 | * tty_driver.write_room interface routine | 1795 | * tty_driver.write_room interface routine |
1852 | * return number of characters the driver will accept to be written via gigaset_write_cmd | 1796 | * return number of characters the driver will accept to be written via |
1797 | * gigaset_write_cmd | ||
1853 | * parameter: | 1798 | * parameter: |
1854 | * controller state structure | 1799 | * controller state structure |
1855 | * return value: | 1800 | * return value: |
@@ -1947,7 +1892,7 @@ static int gigaset_initbcshw(struct bc_state *bcs) | |||
1947 | return 0; | 1892 | return 0; |
1948 | } | 1893 | } |
1949 | tasklet_init(&ubc->sent_tasklet, | 1894 | tasklet_init(&ubc->sent_tasklet, |
1950 | &write_iso_tasklet, (unsigned long) bcs); | 1895 | &write_iso_tasklet, (unsigned long) bcs); |
1951 | 1896 | ||
1952 | spin_lock_init(&ubc->isoinlock); | 1897 | spin_lock_init(&ubc->isoinlock); |
1953 | for (i = 0; i < BAS_INURBS; ++i) | 1898 | for (i = 0; i < BAS_INURBS; ++i) |
@@ -1968,7 +1913,7 @@ static int gigaset_initbcshw(struct bc_state *bcs) | |||
1968 | ubc->shared0s = 0; | 1913 | ubc->shared0s = 0; |
1969 | ubc->stolen0s = 0; | 1914 | ubc->stolen0s = 0; |
1970 | tasklet_init(&ubc->rcvd_tasklet, | 1915 | tasklet_init(&ubc->rcvd_tasklet, |
1971 | &read_iso_tasklet, (unsigned long) bcs); | 1916 | &read_iso_tasklet, (unsigned long) bcs); |
1972 | return 1; | 1917 | return 1; |
1973 | } | 1918 | } |
1974 | 1919 | ||
@@ -2027,57 +1972,56 @@ static int gigaset_initcshw(struct cardstate *cs) | |||
2027 | */ | 1972 | */ |
2028 | static void freeurbs(struct cardstate *cs) | 1973 | static void freeurbs(struct cardstate *cs) |
2029 | { | 1974 | { |
2030 | struct bas_cardstate *ucs; | 1975 | struct bas_cardstate *ucs = cs->hw.bas; |
2031 | struct bas_bc_state *ubc; | 1976 | struct bas_bc_state *ubc; |
2032 | int i, j; | 1977 | int i, j; |
2033 | 1978 | ||
2034 | IFNULLRET(cs); | ||
2035 | ucs = cs->hw.bas; | ||
2036 | IFNULLRET(ucs); | ||
2037 | |||
2038 | for (j = 0; j < 2; ++j) { | 1979 | for (j = 0; j < 2; ++j) { |
2039 | ubc = cs->bcs[j].hw.bas; | 1980 | ubc = cs->bcs[j].hw.bas; |
2040 | IFNULLCONT(ubc); | ||
2041 | for (i = 0; i < BAS_OUTURBS; ++i) | 1981 | for (i = 0; i < BAS_OUTURBS; ++i) |
2042 | if (ubc->isoouturbs[i].urb) { | 1982 | if (ubc->isoouturbs[i].urb) { |
2043 | usb_kill_urb(ubc->isoouturbs[i].urb); | 1983 | usb_kill_urb(ubc->isoouturbs[i].urb); |
2044 | dbg(DEBUG_INIT, | 1984 | gig_dbg(DEBUG_INIT, |
2045 | "%s: isoc output URB %d/%d unlinked", | 1985 | "%s: isoc output URB %d/%d unlinked", |
2046 | __func__, j, i); | 1986 | __func__, j, i); |
2047 | usb_free_urb(ubc->isoouturbs[i].urb); | 1987 | usb_free_urb(ubc->isoouturbs[i].urb); |
2048 | ubc->isoouturbs[i].urb = NULL; | 1988 | ubc->isoouturbs[i].urb = NULL; |
2049 | } | 1989 | } |
2050 | for (i = 0; i < BAS_INURBS; ++i) | 1990 | for (i = 0; i < BAS_INURBS; ++i) |
2051 | if (ubc->isoinurbs[i]) { | 1991 | if (ubc->isoinurbs[i]) { |
2052 | usb_kill_urb(ubc->isoinurbs[i]); | 1992 | usb_kill_urb(ubc->isoinurbs[i]); |
2053 | dbg(DEBUG_INIT, | 1993 | gig_dbg(DEBUG_INIT, |
2054 | "%s: isoc input URB %d/%d unlinked", | 1994 | "%s: isoc input URB %d/%d unlinked", |
2055 | __func__, j, i); | 1995 | __func__, j, i); |
2056 | usb_free_urb(ubc->isoinurbs[i]); | 1996 | usb_free_urb(ubc->isoinurbs[i]); |
2057 | ubc->isoinurbs[i] = NULL; | 1997 | ubc->isoinurbs[i] = NULL; |
2058 | } | 1998 | } |
2059 | } | 1999 | } |
2060 | if (ucs->urb_int_in) { | 2000 | if (ucs->urb_int_in) { |
2061 | usb_kill_urb(ucs->urb_int_in); | 2001 | usb_kill_urb(ucs->urb_int_in); |
2062 | dbg(DEBUG_INIT, "%s: interrupt input URB unlinked", __func__); | 2002 | gig_dbg(DEBUG_INIT, "%s: interrupt input URB unlinked", |
2003 | __func__); | ||
2063 | usb_free_urb(ucs->urb_int_in); | 2004 | usb_free_urb(ucs->urb_int_in); |
2064 | ucs->urb_int_in = NULL; | 2005 | ucs->urb_int_in = NULL; |
2065 | } | 2006 | } |
2066 | if (ucs->urb_cmd_out) { | 2007 | if (ucs->urb_cmd_out) { |
2067 | usb_kill_urb(ucs->urb_cmd_out); | 2008 | usb_kill_urb(ucs->urb_cmd_out); |
2068 | dbg(DEBUG_INIT, "%s: command output URB unlinked", __func__); | 2009 | gig_dbg(DEBUG_INIT, "%s: command output URB unlinked", |
2010 | __func__); | ||
2069 | usb_free_urb(ucs->urb_cmd_out); | 2011 | usb_free_urb(ucs->urb_cmd_out); |
2070 | ucs->urb_cmd_out = NULL; | 2012 | ucs->urb_cmd_out = NULL; |
2071 | } | 2013 | } |
2072 | if (ucs->urb_cmd_in) { | 2014 | if (ucs->urb_cmd_in) { |
2073 | usb_kill_urb(ucs->urb_cmd_in); | 2015 | usb_kill_urb(ucs->urb_cmd_in); |
2074 | dbg(DEBUG_INIT, "%s: command input URB unlinked", __func__); | 2016 | gig_dbg(DEBUG_INIT, "%s: command input URB unlinked", |
2017 | __func__); | ||
2075 | usb_free_urb(ucs->urb_cmd_in); | 2018 | usb_free_urb(ucs->urb_cmd_in); |
2076 | ucs->urb_cmd_in = NULL; | 2019 | ucs->urb_cmd_in = NULL; |
2077 | } | 2020 | } |
2078 | if (ucs->urb_ctrl) { | 2021 | if (ucs->urb_ctrl) { |
2079 | usb_kill_urb(ucs->urb_ctrl); | 2022 | usb_kill_urb(ucs->urb_ctrl); |
2080 | dbg(DEBUG_INIT, "%s: control output URB unlinked", __func__); | 2023 | gig_dbg(DEBUG_INIT, "%s: control output URB unlinked", |
2024 | __func__); | ||
2081 | usb_free_urb(ucs->urb_ctrl); | 2025 | usb_free_urb(ucs->urb_ctrl); |
2082 | ucs->urb_ctrl = NULL; | 2026 | ucs->urb_ctrl = NULL; |
2083 | } | 2027 | } |
@@ -2099,12 +2043,10 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2099 | int i, j; | 2043 | int i, j; |
2100 | int ret; | 2044 | int ret; |
2101 | 2045 | ||
2102 | IFNULLRETVAL(udev, -ENODEV); | 2046 | gig_dbg(DEBUG_ANY, |
2103 | 2047 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", | |
2104 | dbg(DEBUG_ANY, | 2048 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
2105 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", | 2049 | le16_to_cpu(udev->descriptor.idProduct)); |
2106 | __func__, le16_to_cpu(udev->descriptor.idVendor), | ||
2107 | le16_to_cpu(udev->descriptor.idProduct)); | ||
2108 | 2050 | ||
2109 | /* See if the device offered us matches what we can accept */ | 2051 | /* See if the device offered us matches what we can accept */ |
2110 | if ((le16_to_cpu(udev->descriptor.idVendor) != USB_GIGA_VENDOR_ID) || | 2052 | if ((le16_to_cpu(udev->descriptor.idVendor) != USB_GIGA_VENDOR_ID) || |
@@ -2112,20 +2054,21 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2112 | le16_to_cpu(udev->descriptor.idProduct) != USB_4175_PRODUCT_ID && | 2054 | le16_to_cpu(udev->descriptor.idProduct) != USB_4175_PRODUCT_ID && |
2113 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX303_PRODUCT_ID && | 2055 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX303_PRODUCT_ID && |
2114 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX353_PRODUCT_ID)) { | 2056 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX353_PRODUCT_ID)) { |
2115 | dbg(DEBUG_ANY, "%s: unmatched ID - exiting", __func__); | 2057 | gig_dbg(DEBUG_ANY, "%s: unmatched ID - exiting", __func__); |
2116 | return -ENODEV; | 2058 | return -ENODEV; |
2117 | } | 2059 | } |
2118 | 2060 | ||
2119 | /* set required alternate setting */ | 2061 | /* set required alternate setting */ |
2120 | hostif = interface->cur_altsetting; | 2062 | hostif = interface->cur_altsetting; |
2121 | if (hostif->desc.bAlternateSetting != 3) { | 2063 | if (hostif->desc.bAlternateSetting != 3) { |
2122 | dbg(DEBUG_ANY, | 2064 | gig_dbg(DEBUG_ANY, |
2123 | "%s: wrong alternate setting %d - trying to switch", | 2065 | "%s: wrong alternate setting %d - trying to switch", |
2124 | __func__, hostif->desc.bAlternateSetting); | 2066 | __func__, hostif->desc.bAlternateSetting); |
2125 | if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3) < 0) { | 2067 | if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3) < 0) { |
2126 | warn("usb_set_interface failed, device %d interface %d altsetting %d", | 2068 | dev_warn(&udev->dev, "usb_set_interface failed, " |
2127 | udev->devnum, hostif->desc.bInterfaceNumber, | 2069 | "device %d interface %d altsetting %d\n", |
2128 | hostif->desc.bAlternateSetting); | 2070 | udev->devnum, hostif->desc.bInterfaceNumber, |
2071 | hostif->desc.bAlternateSetting); | ||
2129 | return -ENODEV; | 2072 | return -ENODEV; |
2130 | } | 2073 | } |
2131 | hostif = interface->cur_altsetting; | 2074 | hostif = interface->cur_altsetting; |
@@ -2134,23 +2077,28 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2134 | /* Reject application specific interfaces | 2077 | /* Reject application specific interfaces |
2135 | */ | 2078 | */ |
2136 | if (hostif->desc.bInterfaceClass != 255) { | 2079 | if (hostif->desc.bInterfaceClass != 255) { |
2137 | warn("%s: bInterfaceClass == %d", | 2080 | dev_warn(&udev->dev, "%s: bInterfaceClass == %d\n", |
2138 | __func__, hostif->desc.bInterfaceClass); | 2081 | __func__, hostif->desc.bInterfaceClass); |
2139 | return -ENODEV; | 2082 | return -ENODEV; |
2140 | } | 2083 | } |
2141 | 2084 | ||
2142 | info("%s: Device matched (Vendor: 0x%x, Product: 0x%x)", | 2085 | dev_info(&udev->dev, |
2143 | __func__, le16_to_cpu(udev->descriptor.idVendor), | 2086 | "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n", |
2144 | le16_to_cpu(udev->descriptor.idProduct)); | 2087 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
2088 | le16_to_cpu(udev->descriptor.idProduct)); | ||
2145 | 2089 | ||
2146 | cs = gigaset_getunassignedcs(driver); | 2090 | cs = gigaset_getunassignedcs(driver); |
2147 | if (!cs) { | 2091 | if (!cs) { |
2148 | err("%s: no free cardstate", __func__); | 2092 | dev_err(&udev->dev, "no free cardstate\n"); |
2149 | return -ENODEV; | 2093 | return -ENODEV; |
2150 | } | 2094 | } |
2151 | ucs = cs->hw.bas; | 2095 | ucs = cs->hw.bas; |
2096 | |||
2097 | /* save off device structure ptrs for later use */ | ||
2098 | usb_get_dev(udev); | ||
2152 | ucs->udev = udev; | 2099 | ucs->udev = udev; |
2153 | ucs->interface = interface; | 2100 | ucs->interface = interface; |
2101 | cs->dev = &interface->dev; | ||
2154 | 2102 | ||
2155 | /* allocate URBs: | 2103 | /* allocate URBs: |
2156 | * - one for the interrupt pipe | 2104 | * - one for the interrupt pipe |
@@ -2159,22 +2107,22 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2159 | */ | 2107 | */ |
2160 | ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL); | 2108 | ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL); |
2161 | if (!ucs->urb_int_in) { | 2109 | if (!ucs->urb_int_in) { |
2162 | err("No free urbs available"); | 2110 | dev_err(cs->dev, "no free urbs available\n"); |
2163 | goto error; | 2111 | goto error; |
2164 | } | 2112 | } |
2165 | ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL); | 2113 | ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL); |
2166 | if (!ucs->urb_cmd_in) { | 2114 | if (!ucs->urb_cmd_in) { |
2167 | err("No free urbs available"); | 2115 | dev_err(cs->dev, "no free urbs available\n"); |
2168 | goto error; | 2116 | goto error; |
2169 | } | 2117 | } |
2170 | ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL); | 2118 | ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL); |
2171 | if (!ucs->urb_cmd_out) { | 2119 | if (!ucs->urb_cmd_out) { |
2172 | err("No free urbs available"); | 2120 | dev_err(cs->dev, "no free urbs available\n"); |
2173 | goto error; | 2121 | goto error; |
2174 | } | 2122 | } |
2175 | ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL); | 2123 | ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL); |
2176 | if (!ucs->urb_ctrl) { | 2124 | if (!ucs->urb_ctrl) { |
2177 | err("No free urbs available"); | 2125 | dev_err(cs->dev, "no free urbs available\n"); |
2178 | goto error; | 2126 | goto error; |
2179 | } | 2127 | } |
2180 | 2128 | ||
@@ -2184,7 +2132,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2184 | ubc->isoouturbs[i].urb = | 2132 | ubc->isoouturbs[i].urb = |
2185 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); | 2133 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); |
2186 | if (!ubc->isoouturbs[i].urb) { | 2134 | if (!ubc->isoouturbs[i].urb) { |
2187 | err("No free urbs available"); | 2135 | dev_err(cs->dev, "no free urbs available\n"); |
2188 | goto error; | 2136 | goto error; |
2189 | } | 2137 | } |
2190 | } | 2138 | } |
@@ -2192,7 +2140,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2192 | ubc->isoinurbs[i] = | 2140 | ubc->isoinurbs[i] = |
2193 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); | 2141 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); |
2194 | if (!ubc->isoinurbs[i]) { | 2142 | if (!ubc->isoinurbs[i]) { |
2195 | err("No free urbs available"); | 2143 | dev_err(cs->dev, "no free urbs available\n"); |
2196 | goto error; | 2144 | goto error; |
2197 | } | 2145 | } |
2198 | } | 2146 | } |
@@ -2204,13 +2152,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2204 | /* Fill the interrupt urb and send it to the core */ | 2152 | /* Fill the interrupt urb and send it to the core */ |
2205 | endpoint = &hostif->endpoint[0].desc; | 2153 | endpoint = &hostif->endpoint[0].desc; |
2206 | usb_fill_int_urb(ucs->urb_int_in, udev, | 2154 | usb_fill_int_urb(ucs->urb_int_in, udev, |
2207 | usb_rcvintpipe(udev, | 2155 | usb_rcvintpipe(udev, |
2208 | (endpoint->bEndpointAddress) & 0x0f), | 2156 | (endpoint->bEndpointAddress) & 0x0f), |
2209 | ucs->int_in_buf, 3, read_int_callback, cs, | 2157 | ucs->int_in_buf, 3, read_int_callback, cs, |
2210 | endpoint->bInterval); | 2158 | endpoint->bInterval); |
2211 | ret = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL); | 2159 | ret = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL); |
2212 | if (ret) { | 2160 | if (ret) { |
2213 | err("could not submit interrupt URB: %s", get_usb_statmsg(ret)); | 2161 | dev_err(cs->dev, "could not submit interrupt URB: %s\n", |
2162 | get_usb_statmsg(ret)); | ||
2214 | goto error; | 2163 | goto error; |
2215 | } | 2164 | } |
2216 | 2165 | ||
@@ -2221,18 +2170,18 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2221 | /* tell common part that the device is ready */ | 2170 | /* tell common part that the device is ready */ |
2222 | if (startmode == SM_LOCKED) | 2171 | if (startmode == SM_LOCKED) |
2223 | atomic_set(&cs->mstate, MS_LOCKED); | 2172 | atomic_set(&cs->mstate, MS_LOCKED); |
2224 | if (!gigaset_start(cs)) | ||
2225 | goto error; | ||
2226 | 2173 | ||
2227 | /* save address of controller structure */ | 2174 | /* save address of controller structure */ |
2228 | usb_set_intfdata(interface, cs); | 2175 | usb_set_intfdata(interface, cs); |
2229 | 2176 | ||
2230 | /* set up device sysfs */ | 2177 | if (!gigaset_start(cs)) |
2231 | gigaset_init_dev_sysfs(interface); | 2178 | goto error; |
2179 | |||
2232 | return 0; | 2180 | return 0; |
2233 | 2181 | ||
2234 | error: | 2182 | error: |
2235 | freeurbs(cs); | 2183 | freeurbs(cs); |
2184 | usb_set_intfdata(interface, NULL); | ||
2236 | gigaset_unassign(cs); | 2185 | gigaset_unassign(cs); |
2237 | return -ENODEV; | 2186 | return -ENODEV; |
2238 | } | 2187 | } |
@@ -2245,23 +2194,22 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
2245 | struct cardstate *cs; | 2194 | struct cardstate *cs; |
2246 | struct bas_cardstate *ucs; | 2195 | struct bas_cardstate *ucs; |
2247 | 2196 | ||
2248 | /* clear device sysfs */ | ||
2249 | gigaset_free_dev_sysfs(interface); | ||
2250 | |||
2251 | cs = usb_get_intfdata(interface); | 2197 | cs = usb_get_intfdata(interface); |
2252 | usb_set_intfdata(interface, NULL); | ||
2253 | 2198 | ||
2254 | IFNULLRET(cs); | ||
2255 | ucs = cs->hw.bas; | 2199 | ucs = cs->hw.bas; |
2256 | IFNULLRET(ucs); | ||
2257 | 2200 | ||
2258 | info("disconnecting GigaSet base"); | 2201 | dev_info(cs->dev, "disconnecting Gigaset base\n"); |
2259 | gigaset_stop(cs); | 2202 | gigaset_stop(cs); |
2260 | freeurbs(cs); | 2203 | freeurbs(cs); |
2204 | usb_set_intfdata(interface, NULL); | ||
2261 | kfree(ucs->rcvbuf); | 2205 | kfree(ucs->rcvbuf); |
2262 | ucs->rcvbuf = NULL; | 2206 | ucs->rcvbuf = NULL; |
2263 | ucs->rcvbuf_size = 0; | 2207 | ucs->rcvbuf_size = 0; |
2264 | atomic_set(&ucs->basstate, 0); | 2208 | atomic_set(&ucs->basstate, 0); |
2209 | usb_put_dev(ucs->udev); | ||
2210 | ucs->interface = NULL; | ||
2211 | ucs->udev = NULL; | ||
2212 | cs->dev = NULL; | ||
2265 | gigaset_unassign(cs); | 2213 | gigaset_unassign(cs); |
2266 | } | 2214 | } |
2267 | 2215 | ||
@@ -2293,13 +2241,14 @@ static int __init bas_gigaset_init(void) | |||
2293 | 2241 | ||
2294 | /* allocate memory for our driver state and intialize it */ | 2242 | /* allocate memory for our driver state and intialize it */ |
2295 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 2243 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
2296 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 2244 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
2297 | GIGASET_DEVFSNAME, &gigops, | 2245 | GIGASET_DEVFSNAME, &gigops, |
2298 | THIS_MODULE)) == NULL) | 2246 | THIS_MODULE)) == NULL) |
2299 | goto error; | 2247 | goto error; |
2300 | 2248 | ||
2301 | /* allocate memory for our device state and intialize it */ | 2249 | /* allocate memory for our device state and intialize it */ |
2302 | cardstate = gigaset_initcs(driver, 2, 0, 0, cidmode, GIGASET_MODULENAME); | 2250 | cardstate = gigaset_initcs(driver, 2, 0, 0, cidmode, |
2251 | GIGASET_MODULENAME); | ||
2303 | if (!cardstate) | 2252 | if (!cardstate) |
2304 | goto error; | 2253 | goto error; |
2305 | 2254 | ||
@@ -2329,19 +2278,18 @@ error: if (cardstate) | |||
2329 | static void __exit bas_gigaset_exit(void) | 2278 | static void __exit bas_gigaset_exit(void) |
2330 | { | 2279 | { |
2331 | gigaset_blockdriver(driver); /* => probe will fail | 2280 | gigaset_blockdriver(driver); /* => probe will fail |
2332 | * => no gigaset_start any more | 2281 | * => no gigaset_start any more |
2333 | */ | 2282 | */ |
2334 | 2283 | ||
2335 | gigaset_shutdown(cardstate); | 2284 | gigaset_shutdown(cardstate); |
2336 | /* from now on, no isdn callback should be possible */ | 2285 | /* from now on, no isdn callback should be possible */ |
2337 | 2286 | ||
2338 | if (atomic_read(&cardstate->hw.bas->basstate) & BS_ATOPEN) { | 2287 | if (atomic_read(&cardstate->hw.bas->basstate) & BS_ATOPEN) { |
2339 | dbg(DEBUG_ANY, "closing AT channel"); | 2288 | gig_dbg(DEBUG_ANY, "closing AT channel"); |
2340 | if (req_submit(cardstate->bcs, | 2289 | if (req_submit(cardstate->bcs, |
2341 | HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT) >= 0) { | 2290 | HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT) >= 0) { |
2342 | /* successfully submitted - wait for completion */ | 2291 | /* successfully submitted */ |
2343 | //wait_event_interruptible(cs->initwait, !cs->hw.bas->pending); | 2292 | //FIXME wait for completion? |
2344 | //FIXME need own wait queue? wakeup? | ||
2345 | } | 2293 | } |
2346 | } | 2294 | } |
2347 | 2295 | ||
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 64371995c1a9..749b3da1236e 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Stuff used by all variants of the driver | 2 | * Stuff used by all variants of the driver |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de>, | 4 | * Copyright (c) 2001 by Stefan Eilers, |
5 | * Hansjoerg Lipp <hjlipp@web.de>, | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Tilman Schmidt <tilman@imap.cc>. | 6 | * Tilman Schmidt <tilman@imap.cc>. |
7 | * | 7 | * |
@@ -11,10 +11,6 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: common.c,v 1.104.4.22 2006/02/04 18:28:16 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
@@ -23,7 +19,7 @@ | |||
23 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
24 | 20 | ||
25 | /* Version Information */ | 21 | /* Version Information */ |
26 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers <Eilers.Stefan@epost.de>" | 22 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers" |
27 | #define DRIVER_DESC "Driver for Gigaset 307x" | 23 | #define DRIVER_DESC "Driver for Gigaset 307x" |
28 | 24 | ||
29 | /* Module parameters */ | 25 | /* Module parameters */ |
@@ -32,21 +28,10 @@ EXPORT_SYMBOL_GPL(gigaset_debuglevel); | |||
32 | module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR); | 28 | module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR); |
33 | MODULE_PARM_DESC(debug, "debug level"); | 29 | MODULE_PARM_DESC(debug, "debug level"); |
34 | 30 | ||
35 | /*====================================================================== | 31 | /* driver state flags */ |
36 | Prototypes of internal functions | 32 | #define VALID_MINOR 0x01 |
37 | */ | 33 | #define VALID_ID 0x02 |
38 | 34 | #define ASSIGNED 0x04 | |
39 | //static void gigaset_process_response(int resp_code, int parameter, | ||
40 | // struct at_state_t *at_state, | ||
41 | // unsigned char ** pstring); | ||
42 | static struct cardstate *alloc_cs(struct gigaset_driver *drv); | ||
43 | static void free_cs(struct cardstate *cs); | ||
44 | static void make_valid(struct cardstate *cs, unsigned mask); | ||
45 | static void make_invalid(struct cardstate *cs, unsigned mask); | ||
46 | |||
47 | #define VALID_MINOR 0x01 | ||
48 | #define VALID_ID 0x02 | ||
49 | #define ASSIGNED 0x04 | ||
50 | 35 | ||
51 | /* bitwise byte inversion table */ | 36 | /* bitwise byte inversion table */ |
52 | __u8 gigaset_invtab[256] = { | 37 | __u8 gigaset_invtab[256] = { |
@@ -86,42 +71,40 @@ __u8 gigaset_invtab[256] = { | |||
86 | EXPORT_SYMBOL_GPL(gigaset_invtab); | 71 | EXPORT_SYMBOL_GPL(gigaset_invtab); |
87 | 72 | ||
88 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | 73 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, |
89 | size_t len, const unsigned char *buf, int from_user) | 74 | size_t len, const unsigned char *buf) |
90 | { | 75 | { |
91 | unsigned char outbuf[80]; | 76 | unsigned char outbuf[80]; |
92 | unsigned char inbuf[80 - 1]; | 77 | unsigned char c; |
93 | size_t numin; | ||
94 | const unsigned char *in; | ||
95 | size_t space = sizeof outbuf - 1; | 78 | size_t space = sizeof outbuf - 1; |
96 | unsigned char *out = outbuf; | 79 | unsigned char *out = outbuf; |
80 | size_t numin = len; | ||
97 | 81 | ||
98 | if (!from_user) { | 82 | while (numin--) { |
99 | in = buf; | 83 | c = *buf++; |
100 | numin = len; | 84 | if (c == '~' || c == '^' || c == '\\') { |
101 | } else { | 85 | if (!space--) |
102 | numin = len < sizeof inbuf ? len : sizeof inbuf; | 86 | break; |
103 | in = inbuf; | 87 | *out++ = '\\'; |
104 | if (copy_from_user(inbuf, (const unsigned char __user *) buf, numin)) { | ||
105 | strncpy(inbuf, "<FAULT>", sizeof inbuf); | ||
106 | numin = sizeof "<FAULT>" - 1; | ||
107 | } | 88 | } |
108 | } | 89 | if (c & 0x80) { |
109 | 90 | if (!space--) | |
110 | for (; numin && space; --numin, ++in) { | 91 | break; |
111 | --space; | 92 | *out++ = '~'; |
112 | if (*in >= 32) | 93 | c ^= 0x80; |
113 | *out++ = *in; | 94 | } |
114 | else { | 95 | if (c < 0x20 || c == 0x7f) { |
96 | if (!space--) | ||
97 | break; | ||
115 | *out++ = '^'; | 98 | *out++ = '^'; |
116 | if (space) { | 99 | c ^= 0x40; |
117 | *out++ = '@' + *in; | ||
118 | --space; | ||
119 | } | ||
120 | } | 100 | } |
101 | if (!space--) | ||
102 | break; | ||
103 | *out++ = c; | ||
121 | } | 104 | } |
122 | *out = 0; | 105 | *out = 0; |
123 | 106 | ||
124 | dbg(level, "%s (%u bytes): %s", msg, (unsigned) len, outbuf); | 107 | gig_dbg(level, "%s (%u bytes): %s", msg, (unsigned) len, outbuf); |
125 | } | 108 | } |
126 | EXPORT_SYMBOL_GPL(gigaset_dbg_buffer); | 109 | EXPORT_SYMBOL_GPL(gigaset_dbg_buffer); |
127 | 110 | ||
@@ -146,11 +129,6 @@ int gigaset_enterconfigmode(struct cardstate *cs) | |||
146 | { | 129 | { |
147 | int i, r; | 130 | int i, r; |
148 | 131 | ||
149 | if (!atomic_read(&cs->connected)) { | ||
150 | err("not connected!"); | ||
151 | return -1; | ||
152 | } | ||
153 | |||
154 | cs->control_state = TIOCM_RTS; //FIXME | 132 | cs->control_state = TIOCM_RTS; //FIXME |
155 | 133 | ||
156 | r = setflags(cs, TIOCM_DTR, 200); | 134 | r = setflags(cs, TIOCM_DTR, 200); |
@@ -174,7 +152,7 @@ int gigaset_enterconfigmode(struct cardstate *cs) | |||
174 | return 0; | 152 | return 0; |
175 | 153 | ||
176 | error: | 154 | error: |
177 | err("error %d on setuartbits!\n", -r); | 155 | dev_err(cs->dev, "error %d on setuartbits\n", -r); |
178 | cs->control_state = TIOCM_RTS|TIOCM_DTR; // FIXME is this a good value? | 156 | cs->control_state = TIOCM_RTS|TIOCM_DTR; // FIXME is this a good value? |
179 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR); | 157 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR); |
180 | 158 | ||
@@ -187,13 +165,13 @@ static int test_timeout(struct at_state_t *at_state) | |||
187 | return 0; | 165 | return 0; |
188 | 166 | ||
189 | if (--at_state->timer_expires) { | 167 | if (--at_state->timer_expires) { |
190 | dbg(DEBUG_MCMD, "decreased timer of %p to %lu", | 168 | gig_dbg(DEBUG_MCMD, "decreased timer of %p to %lu", |
191 | at_state, at_state->timer_expires); | 169 | at_state, at_state->timer_expires); |
192 | return 0; | 170 | return 0; |
193 | } | 171 | } |
194 | 172 | ||
195 | if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL, | 173 | if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL, |
196 | atomic_read(&at_state->timer_index), NULL)) { | 174 | at_state->timer_index, NULL)) { |
197 | //FIXME what should we do? | 175 | //FIXME what should we do? |
198 | } | 176 | } |
199 | 177 | ||
@@ -221,10 +199,10 @@ static void timer_tick(unsigned long data) | |||
221 | if (test_timeout(at_state)) | 199 | if (test_timeout(at_state)) |
222 | timeout = 1; | 200 | timeout = 1; |
223 | 201 | ||
224 | if (atomic_read(&cs->running)) { | 202 | if (cs->running) { |
225 | mod_timer(&cs->timer, jiffies + GIG_TICK); | 203 | mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK)); |
226 | if (timeout) { | 204 | if (timeout) { |
227 | dbg(DEBUG_CMD, "scheduling timeout"); | 205 | gig_dbg(DEBUG_CMD, "scheduling timeout"); |
228 | tasklet_schedule(&cs->event_tasklet); | 206 | tasklet_schedule(&cs->event_tasklet); |
229 | } | 207 | } |
230 | } | 208 | } |
@@ -238,13 +216,14 @@ int gigaset_get_channel(struct bc_state *bcs) | |||
238 | 216 | ||
239 | spin_lock_irqsave(&bcs->cs->lock, flags); | 217 | spin_lock_irqsave(&bcs->cs->lock, flags); |
240 | if (bcs->use_count) { | 218 | if (bcs->use_count) { |
241 | dbg(DEBUG_ANY, "could not allocate channel %d", bcs->channel); | 219 | gig_dbg(DEBUG_ANY, "could not allocate channel %d", |
220 | bcs->channel); | ||
242 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 221 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
243 | return 0; | 222 | return 0; |
244 | } | 223 | } |
245 | ++bcs->use_count; | 224 | ++bcs->use_count; |
246 | bcs->busy = 1; | 225 | bcs->busy = 1; |
247 | dbg(DEBUG_ANY, "allocated channel %d", bcs->channel); | 226 | gig_dbg(DEBUG_ANY, "allocated channel %d", bcs->channel); |
248 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 227 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
249 | return 1; | 228 | return 1; |
250 | } | 229 | } |
@@ -255,13 +234,13 @@ void gigaset_free_channel(struct bc_state *bcs) | |||
255 | 234 | ||
256 | spin_lock_irqsave(&bcs->cs->lock, flags); | 235 | spin_lock_irqsave(&bcs->cs->lock, flags); |
257 | if (!bcs->busy) { | 236 | if (!bcs->busy) { |
258 | dbg(DEBUG_ANY, "could not free channel %d", bcs->channel); | 237 | gig_dbg(DEBUG_ANY, "could not free channel %d", bcs->channel); |
259 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 238 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
260 | return; | 239 | return; |
261 | } | 240 | } |
262 | --bcs->use_count; | 241 | --bcs->use_count; |
263 | bcs->busy = 0; | 242 | bcs->busy = 0; |
264 | dbg(DEBUG_ANY, "freed channel %d", bcs->channel); | 243 | gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel); |
265 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 244 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
266 | } | 245 | } |
267 | 246 | ||
@@ -274,14 +253,14 @@ int gigaset_get_channels(struct cardstate *cs) | |||
274 | for (i = 0; i < cs->channels; ++i) | 253 | for (i = 0; i < cs->channels; ++i) |
275 | if (cs->bcs[i].use_count) { | 254 | if (cs->bcs[i].use_count) { |
276 | spin_unlock_irqrestore(&cs->lock, flags); | 255 | spin_unlock_irqrestore(&cs->lock, flags); |
277 | dbg(DEBUG_ANY, "could not allocated all channels"); | 256 | gig_dbg(DEBUG_ANY, "could not allocate all channels"); |
278 | return 0; | 257 | return 0; |
279 | } | 258 | } |
280 | for (i = 0; i < cs->channels; ++i) | 259 | for (i = 0; i < cs->channels; ++i) |
281 | ++cs->bcs[i].use_count; | 260 | ++cs->bcs[i].use_count; |
282 | spin_unlock_irqrestore(&cs->lock, flags); | 261 | spin_unlock_irqrestore(&cs->lock, flags); |
283 | 262 | ||
284 | dbg(DEBUG_ANY, "allocated all channels"); | 263 | gig_dbg(DEBUG_ANY, "allocated all channels"); |
285 | 264 | ||
286 | return 1; | 265 | return 1; |
287 | } | 266 | } |
@@ -291,7 +270,7 @@ void gigaset_free_channels(struct cardstate *cs) | |||
291 | unsigned long flags; | 270 | unsigned long flags; |
292 | int i; | 271 | int i; |
293 | 272 | ||
294 | dbg(DEBUG_ANY, "unblocking all channels"); | 273 | gig_dbg(DEBUG_ANY, "unblocking all channels"); |
295 | spin_lock_irqsave(&cs->lock, flags); | 274 | spin_lock_irqsave(&cs->lock, flags); |
296 | for (i = 0; i < cs->channels; ++i) | 275 | for (i = 0; i < cs->channels; ++i) |
297 | --cs->bcs[i].use_count; | 276 | --cs->bcs[i].use_count; |
@@ -303,7 +282,7 @@ void gigaset_block_channels(struct cardstate *cs) | |||
303 | unsigned long flags; | 282 | unsigned long flags; |
304 | int i; | 283 | int i; |
305 | 284 | ||
306 | dbg(DEBUG_ANY, "blocking all channels"); | 285 | gig_dbg(DEBUG_ANY, "blocking all channels"); |
307 | spin_lock_irqsave(&cs->lock, flags); | 286 | spin_lock_irqsave(&cs->lock, flags); |
308 | for (i = 0; i < cs->channels; ++i) | 287 | for (i = 0; i < cs->channels; ++i) |
309 | ++cs->bcs[i].use_count; | 288 | ++cs->bcs[i].use_count; |
@@ -314,25 +293,27 @@ static void clear_events(struct cardstate *cs) | |||
314 | { | 293 | { |
315 | struct event_t *ev; | 294 | struct event_t *ev; |
316 | unsigned head, tail; | 295 | unsigned head, tail; |
296 | unsigned long flags; | ||
317 | 297 | ||
318 | /* no locking needed (no reader/writer allowed) */ | 298 | spin_lock_irqsave(&cs->ev_lock, flags); |
319 | 299 | ||
320 | head = atomic_read(&cs->ev_head); | 300 | head = cs->ev_head; |
321 | tail = atomic_read(&cs->ev_tail); | 301 | tail = cs->ev_tail; |
322 | 302 | ||
323 | while (tail != head) { | 303 | while (tail != head) { |
324 | ev = cs->events + head; | 304 | ev = cs->events + head; |
325 | kfree(ev->ptr); | 305 | kfree(ev->ptr); |
326 | |||
327 | head = (head + 1) % MAX_EVENTS; | 306 | head = (head + 1) % MAX_EVENTS; |
328 | } | 307 | } |
329 | 308 | ||
330 | atomic_set(&cs->ev_head, tail); | 309 | cs->ev_head = tail; |
310 | |||
311 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
331 | } | 312 | } |
332 | 313 | ||
333 | struct event_t *gigaset_add_event(struct cardstate *cs, | 314 | struct event_t *gigaset_add_event(struct cardstate *cs, |
334 | struct at_state_t *at_state, int type, | 315 | struct at_state_t *at_state, int type, |
335 | void *ptr, int parameter, void *arg) | 316 | void *ptr, int parameter, void *arg) |
336 | { | 317 | { |
337 | unsigned long flags; | 318 | unsigned long flags; |
338 | unsigned next, tail; | 319 | unsigned next, tail; |
@@ -340,9 +321,9 @@ struct event_t *gigaset_add_event(struct cardstate *cs, | |||
340 | 321 | ||
341 | spin_lock_irqsave(&cs->ev_lock, flags); | 322 | spin_lock_irqsave(&cs->ev_lock, flags); |
342 | 323 | ||
343 | tail = atomic_read(&cs->ev_tail); | 324 | tail = cs->ev_tail; |
344 | next = (tail + 1) % MAX_EVENTS; | 325 | next = (tail + 1) % MAX_EVENTS; |
345 | if (unlikely(next == atomic_read(&cs->ev_head))) | 326 | if (unlikely(next == cs->ev_head)) |
346 | err("event queue full"); | 327 | err("event queue full"); |
347 | else { | 328 | else { |
348 | event = cs->events + tail; | 329 | event = cs->events + tail; |
@@ -352,7 +333,7 @@ struct event_t *gigaset_add_event(struct cardstate *cs, | |||
352 | event->ptr = ptr; | 333 | event->ptr = ptr; |
353 | event->arg = arg; | 334 | event->arg = arg; |
354 | event->parameter = parameter; | 335 | event->parameter = parameter; |
355 | atomic_set(&cs->ev_tail, next); | 336 | cs->ev_tail = next; |
356 | } | 337 | } |
357 | 338 | ||
358 | spin_unlock_irqrestore(&cs->ev_lock, flags); | 339 | spin_unlock_irqrestore(&cs->ev_lock, flags); |
@@ -391,14 +372,14 @@ static void gigaset_freebcs(struct bc_state *bcs) | |||
391 | { | 372 | { |
392 | int i; | 373 | int i; |
393 | 374 | ||
394 | dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel); | 375 | gig_dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel); |
395 | if (!bcs->cs->ops->freebcshw(bcs)) { | 376 | if (!bcs->cs->ops->freebcshw(bcs)) { |
396 | dbg(DEBUG_INIT, "failed"); | 377 | gig_dbg(DEBUG_INIT, "failed"); |
397 | } | 378 | } |
398 | 379 | ||
399 | dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel); | 380 | gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel); |
400 | clear_at_state(&bcs->at_state); | 381 | clear_at_state(&bcs->at_state); |
401 | dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel); | 382 | gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel); |
402 | 383 | ||
403 | if (bcs->skb) | 384 | if (bcs->skb) |
404 | dev_kfree_skb(bcs->skb); | 385 | dev_kfree_skb(bcs->skb); |
@@ -408,6 +389,52 @@ static void gigaset_freebcs(struct bc_state *bcs) | |||
408 | } | 389 | } |
409 | } | 390 | } |
410 | 391 | ||
392 | static struct cardstate *alloc_cs(struct gigaset_driver *drv) | ||
393 | { | ||
394 | unsigned long flags; | ||
395 | unsigned i; | ||
396 | static struct cardstate *ret = NULL; | ||
397 | |||
398 | spin_lock_irqsave(&drv->lock, flags); | ||
399 | for (i = 0; i < drv->minors; ++i) { | ||
400 | if (!(drv->flags[i] & VALID_MINOR)) { | ||
401 | drv->flags[i] = VALID_MINOR; | ||
402 | ret = drv->cs + i; | ||
403 | } | ||
404 | if (ret) | ||
405 | break; | ||
406 | } | ||
407 | spin_unlock_irqrestore(&drv->lock, flags); | ||
408 | return ret; | ||
409 | } | ||
410 | |||
411 | static void free_cs(struct cardstate *cs) | ||
412 | { | ||
413 | unsigned long flags; | ||
414 | struct gigaset_driver *drv = cs->driver; | ||
415 | spin_lock_irqsave(&drv->lock, flags); | ||
416 | drv->flags[cs->minor_index] = 0; | ||
417 | spin_unlock_irqrestore(&drv->lock, flags); | ||
418 | } | ||
419 | |||
420 | static void make_valid(struct cardstate *cs, unsigned mask) | ||
421 | { | ||
422 | unsigned long flags; | ||
423 | struct gigaset_driver *drv = cs->driver; | ||
424 | spin_lock_irqsave(&drv->lock, flags); | ||
425 | drv->flags[cs->minor_index] |= mask; | ||
426 | spin_unlock_irqrestore(&drv->lock, flags); | ||
427 | } | ||
428 | |||
429 | static void make_invalid(struct cardstate *cs, unsigned mask) | ||
430 | { | ||
431 | unsigned long flags; | ||
432 | struct gigaset_driver *drv = cs->driver; | ||
433 | spin_lock_irqsave(&drv->lock, flags); | ||
434 | drv->flags[cs->minor_index] &= ~mask; | ||
435 | spin_unlock_irqrestore(&drv->lock, flags); | ||
436 | } | ||
437 | |||
411 | void gigaset_freecs(struct cardstate *cs) | 438 | void gigaset_freecs(struct cardstate *cs) |
412 | { | 439 | { |
413 | int i; | 440 | int i; |
@@ -416,7 +443,7 @@ void gigaset_freecs(struct cardstate *cs) | |||
416 | if (!cs) | 443 | if (!cs) |
417 | return; | 444 | return; |
418 | 445 | ||
419 | down(&cs->sem); | 446 | mutex_lock(&cs->mutex); |
420 | 447 | ||
421 | if (!cs->bcs) | 448 | if (!cs->bcs) |
422 | goto f_cs; | 449 | goto f_cs; |
@@ -424,8 +451,9 @@ void gigaset_freecs(struct cardstate *cs) | |||
424 | goto f_bcs; | 451 | goto f_bcs; |
425 | 452 | ||
426 | spin_lock_irqsave(&cs->lock, flags); | 453 | spin_lock_irqsave(&cs->lock, flags); |
427 | atomic_set(&cs->running, 0); | 454 | cs->running = 0; |
428 | spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are not rescheduled below */ | 455 | spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are |
456 | not rescheduled below */ | ||
429 | 457 | ||
430 | tasklet_kill(&cs->event_tasklet); | 458 | tasklet_kill(&cs->event_tasklet); |
431 | del_timer_sync(&cs->timer); | 459 | del_timer_sync(&cs->timer); |
@@ -434,7 +462,7 @@ void gigaset_freecs(struct cardstate *cs) | |||
434 | default: | 462 | default: |
435 | gigaset_if_free(cs); | 463 | gigaset_if_free(cs); |
436 | 464 | ||
437 | dbg(DEBUG_INIT, "clearing hw"); | 465 | gig_dbg(DEBUG_INIT, "clearing hw"); |
438 | cs->ops->freecshw(cs); | 466 | cs->ops->freecshw(cs); |
439 | 467 | ||
440 | //FIXME cmdbuf | 468 | //FIXME cmdbuf |
@@ -443,36 +471,36 @@ void gigaset_freecs(struct cardstate *cs) | |||
443 | case 2: /* error in initcshw */ | 471 | case 2: /* error in initcshw */ |
444 | /* Deregister from LL */ | 472 | /* Deregister from LL */ |
445 | make_invalid(cs, VALID_ID); | 473 | make_invalid(cs, VALID_ID); |
446 | dbg(DEBUG_INIT, "clearing iif"); | 474 | gig_dbg(DEBUG_INIT, "clearing iif"); |
447 | gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD); | 475 | gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD); |
448 | 476 | ||
449 | /* fall through */ | 477 | /* fall through */ |
450 | case 1: /* error when regestering to LL */ | 478 | case 1: /* error when regestering to LL */ |
451 | dbg(DEBUG_INIT, "clearing at_state"); | 479 | gig_dbg(DEBUG_INIT, "clearing at_state"); |
452 | clear_at_state(&cs->at_state); | 480 | clear_at_state(&cs->at_state); |
453 | dealloc_at_states(cs); | 481 | dealloc_at_states(cs); |
454 | 482 | ||
455 | /* fall through */ | 483 | /* fall through */ |
456 | case 0: /* error in one call to initbcs */ | 484 | case 0: /* error in one call to initbcs */ |
457 | for (i = 0; i < cs->channels; ++i) { | 485 | for (i = 0; i < cs->channels; ++i) { |
458 | dbg(DEBUG_INIT, "clearing bcs[%d]", i); | 486 | gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i); |
459 | gigaset_freebcs(cs->bcs + i); | 487 | gigaset_freebcs(cs->bcs + i); |
460 | } | 488 | } |
461 | 489 | ||
462 | clear_events(cs); | 490 | clear_events(cs); |
463 | dbg(DEBUG_INIT, "freeing inbuf"); | 491 | gig_dbg(DEBUG_INIT, "freeing inbuf"); |
464 | kfree(cs->inbuf); | 492 | kfree(cs->inbuf); |
465 | } | 493 | } |
466 | f_bcs: dbg(DEBUG_INIT, "freeing bcs[]"); | 494 | f_bcs: gig_dbg(DEBUG_INIT, "freeing bcs[]"); |
467 | kfree(cs->bcs); | 495 | kfree(cs->bcs); |
468 | f_cs: dbg(DEBUG_INIT, "freeing cs"); | 496 | f_cs: gig_dbg(DEBUG_INIT, "freeing cs"); |
469 | up(&cs->sem); | 497 | mutex_unlock(&cs->mutex); |
470 | free_cs(cs); | 498 | free_cs(cs); |
471 | } | 499 | } |
472 | EXPORT_SYMBOL_GPL(gigaset_freecs); | 500 | EXPORT_SYMBOL_GPL(gigaset_freecs); |
473 | 501 | ||
474 | void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, | 502 | void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, |
475 | struct cardstate *cs, int cid) | 503 | struct cardstate *cs, int cid) |
476 | { | 504 | { |
477 | int i; | 505 | int i; |
478 | 506 | ||
@@ -482,8 +510,8 @@ void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, | |||
482 | at_state->pending_commands = 0; | 510 | at_state->pending_commands = 0; |
483 | at_state->timer_expires = 0; | 511 | at_state->timer_expires = 0; |
484 | at_state->timer_active = 0; | 512 | at_state->timer_active = 0; |
485 | atomic_set(&at_state->timer_index, 0); | 513 | at_state->timer_index = 0; |
486 | atomic_set(&at_state->seq_index, 0); | 514 | at_state->seq_index = 0; |
487 | at_state->ConState = 0; | 515 | at_state->ConState = 0; |
488 | for (i = 0; i < STR_NUM; ++i) | 516 | for (i = 0; i < STR_NUM; ++i) |
489 | at_state->str_var[i] = NULL; | 517 | at_state->str_var[i] = NULL; |
@@ -501,7 +529,7 @@ void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, | |||
501 | 529 | ||
502 | 530 | ||
503 | static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs, | 531 | static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs, |
504 | struct cardstate *cs, int inputstate) | 532 | struct cardstate *cs, int inputstate) |
505 | /* inbuf->read must be allocated before! */ | 533 | /* inbuf->read must be allocated before! */ |
506 | { | 534 | { |
507 | atomic_set(&inbuf->head, 0); | 535 | atomic_set(&inbuf->head, 0); |
@@ -512,9 +540,50 @@ static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs, | |||
512 | inbuf->inputstate = inputstate; | 540 | inbuf->inputstate = inputstate; |
513 | } | 541 | } |
514 | 542 | ||
543 | /* append received bytes to inbuf */ | ||
544 | int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, | ||
545 | unsigned numbytes) | ||
546 | { | ||
547 | unsigned n, head, tail, bytesleft; | ||
548 | |||
549 | gig_dbg(DEBUG_INTR, "received %u bytes", numbytes); | ||
550 | |||
551 | if (!numbytes) | ||
552 | return 0; | ||
553 | |||
554 | bytesleft = numbytes; | ||
555 | tail = atomic_read(&inbuf->tail); | ||
556 | head = atomic_read(&inbuf->head); | ||
557 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | ||
558 | |||
559 | while (bytesleft) { | ||
560 | if (head > tail) | ||
561 | n = head - 1 - tail; | ||
562 | else if (head == 0) | ||
563 | n = (RBUFSIZE-1) - tail; | ||
564 | else | ||
565 | n = RBUFSIZE - tail; | ||
566 | if (!n) { | ||
567 | dev_err(inbuf->cs->dev, | ||
568 | "buffer overflow (%u bytes lost)", bytesleft); | ||
569 | break; | ||
570 | } | ||
571 | if (n > bytesleft) | ||
572 | n = bytesleft; | ||
573 | memcpy(inbuf->data + tail, src, n); | ||
574 | bytesleft -= n; | ||
575 | tail = (tail + n) % RBUFSIZE; | ||
576 | src += n; | ||
577 | } | ||
578 | gig_dbg(DEBUG_INTR, "setting tail to %u", tail); | ||
579 | atomic_set(&inbuf->tail, tail); | ||
580 | return numbytes != bytesleft; | ||
581 | } | ||
582 | EXPORT_SYMBOL_GPL(gigaset_fill_inbuf); | ||
583 | |||
515 | /* Initialize the b-channel structure */ | 584 | /* Initialize the b-channel structure */ |
516 | static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | 585 | static struct bc_state *gigaset_initbcs(struct bc_state *bcs, |
517 | struct cardstate *cs, int channel) | 586 | struct cardstate *cs, int channel) |
518 | { | 587 | { |
519 | int i; | 588 | int i; |
520 | 589 | ||
@@ -526,7 +595,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
526 | bcs->trans_down = 0; | 595 | bcs->trans_down = 0; |
527 | bcs->trans_up = 0; | 596 | bcs->trans_up = 0; |
528 | 597 | ||
529 | dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel); | 598 | gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel); |
530 | gigaset_at_init(&bcs->at_state, bcs, cs, -1); | 599 | gigaset_at_init(&bcs->at_state, bcs, cs, -1); |
531 | 600 | ||
532 | bcs->rcvbytes = 0; | 601 | bcs->rcvbytes = 0; |
@@ -535,7 +604,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
535 | bcs->emptycount = 0; | 604 | bcs->emptycount = 0; |
536 | #endif | 605 | #endif |
537 | 606 | ||
538 | dbg(DEBUG_INIT, "allocating bcs[%d]->skb", channel); | 607 | gig_dbg(DEBUG_INIT, "allocating bcs[%d]->skb", channel); |
539 | bcs->fcs = PPP_INITFCS; | 608 | bcs->fcs = PPP_INITFCS; |
540 | bcs->inputstate = 0; | 609 | bcs->inputstate = 0; |
541 | if (cs->ignoreframes) { | 610 | if (cs->ignoreframes) { |
@@ -544,7 +613,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
544 | } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 613 | } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
545 | skb_reserve(bcs->skb, HW_HDR_LEN); | 614 | skb_reserve(bcs->skb, HW_HDR_LEN); |
546 | else { | 615 | else { |
547 | warn("could not allocate skb"); | 616 | dev_warn(cs->dev, "could not allocate skb\n"); |
548 | bcs->inputstate |= INS_skip_frame; | 617 | bcs->inputstate |= INS_skip_frame; |
549 | } | 618 | } |
550 | 619 | ||
@@ -559,14 +628,13 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
559 | for (i = 0; i < AT_NUM; ++i) | 628 | for (i = 0; i < AT_NUM; ++i) |
560 | bcs->commands[i] = NULL; | 629 | bcs->commands[i] = NULL; |
561 | 630 | ||
562 | dbg(DEBUG_INIT, " setting up bcs[%d]->hw", channel); | 631 | gig_dbg(DEBUG_INIT, " setting up bcs[%d]->hw", channel); |
563 | if (cs->ops->initbcshw(bcs)) | 632 | if (cs->ops->initbcshw(bcs)) |
564 | return bcs; | 633 | return bcs; |
565 | 634 | ||
566 | //error: | 635 | gig_dbg(DEBUG_INIT, " failed"); |
567 | dbg(DEBUG_INIT, " failed"); | ||
568 | 636 | ||
569 | dbg(DEBUG_INIT, " freeing bcs[%d]->skb", channel); | 637 | gig_dbg(DEBUG_INIT, " freeing bcs[%d]->skb", channel); |
570 | if (bcs->skb) | 638 | if (bcs->skb) |
571 | dev_kfree_skb(bcs->skb); | 639 | dev_kfree_skb(bcs->skb); |
572 | 640 | ||
@@ -578,9 +646,10 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
578 | * Calls hardware dependent gigaset_initcshw() function | 646 | * Calls hardware dependent gigaset_initcshw() function |
579 | * Calls B channel initialization function gigaset_initbcs() for each B channel | 647 | * Calls B channel initialization function gigaset_initbcs() for each B channel |
580 | * parameters: | 648 | * parameters: |
581 | * drv hardware driver the device belongs to | 649 | * drv hardware driver the device belongs to |
582 | * channels number of B channels supported by device | 650 | * channels number of B channels supported by device |
583 | * onechannel !=0: B channel data and AT commands share one communication channel | 651 | * onechannel !=0: B channel data and AT commands share one |
652 | * communication channel | ||
584 | * ==0: B channels have separate communication channels | 653 | * ==0: B channels have separate communication channels |
585 | * ignoreframes number of frames to ignore after setting up B channel | 654 | * ignoreframes number of frames to ignore after setting up B channel |
586 | * cidmode !=0: start in CallID mode | 655 | * cidmode !=0: start in CallID mode |
@@ -593,17 +662,18 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
593 | int cidmode, const char *modulename) | 662 | int cidmode, const char *modulename) |
594 | { | 663 | { |
595 | struct cardstate *cs = NULL; | 664 | struct cardstate *cs = NULL; |
665 | unsigned long flags; | ||
596 | int i; | 666 | int i; |
597 | 667 | ||
598 | dbg(DEBUG_INIT, "allocating cs"); | 668 | gig_dbg(DEBUG_INIT, "allocating cs"); |
599 | cs = alloc_cs(drv); | 669 | cs = alloc_cs(drv); |
600 | if (!cs) | 670 | if (!cs) |
601 | goto error; | 671 | goto error; |
602 | dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); | 672 | gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); |
603 | cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); | 673 | cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); |
604 | if (!cs->bcs) | 674 | if (!cs->bcs) |
605 | goto error; | 675 | goto error; |
606 | dbg(DEBUG_INIT, "allocating inbuf"); | 676 | gig_dbg(DEBUG_INIT, "allocating inbuf"); |
607 | cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); | 677 | cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); |
608 | if (!cs->inbuf) | 678 | if (!cs->inbuf) |
609 | goto error; | 679 | goto error; |
@@ -613,19 +683,23 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
613 | cs->onechannel = onechannel; | 683 | cs->onechannel = onechannel; |
614 | cs->ignoreframes = ignoreframes; | 684 | cs->ignoreframes = ignoreframes; |
615 | INIT_LIST_HEAD(&cs->temp_at_states); | 685 | INIT_LIST_HEAD(&cs->temp_at_states); |
616 | atomic_set(&cs->running, 0); | 686 | cs->running = 0; |
617 | init_timer(&cs->timer); /* clear next & prev */ | 687 | init_timer(&cs->timer); /* clear next & prev */ |
618 | spin_lock_init(&cs->ev_lock); | 688 | spin_lock_init(&cs->ev_lock); |
619 | atomic_set(&cs->ev_tail, 0); | 689 | cs->ev_tail = 0; |
620 | atomic_set(&cs->ev_head, 0); | 690 | cs->ev_head = 0; |
621 | init_MUTEX_LOCKED(&cs->sem); | 691 | mutex_init(&cs->mutex); |
622 | tasklet_init(&cs->event_tasklet, &gigaset_handle_event, (unsigned long) cs); | 692 | mutex_lock(&cs->mutex); |
693 | |||
694 | tasklet_init(&cs->event_tasklet, &gigaset_handle_event, | ||
695 | (unsigned long) cs); | ||
623 | atomic_set(&cs->commands_pending, 0); | 696 | atomic_set(&cs->commands_pending, 0); |
624 | cs->cur_at_seq = 0; | 697 | cs->cur_at_seq = 0; |
625 | cs->gotfwver = -1; | 698 | cs->gotfwver = -1; |
626 | cs->open_count = 0; | 699 | cs->open_count = 0; |
700 | cs->dev = NULL; | ||
627 | cs->tty = NULL; | 701 | cs->tty = NULL; |
628 | atomic_set(&cs->cidmode, cidmode != 0); | 702 | cs->cidmode = cidmode != 0; |
629 | 703 | ||
630 | //if(onechannel) { //FIXME | 704 | //if(onechannel) { //FIXME |
631 | cs->tabnocid = gigaset_tab_nocid_m10x; | 705 | cs->tabnocid = gigaset_tab_nocid_m10x; |
@@ -642,50 +716,43 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
642 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 716 | atomic_set(&cs->mstate, MS_UNINITIALIZED); |
643 | 717 | ||
644 | for (i = 0; i < channels; ++i) { | 718 | for (i = 0; i < channels; ++i) { |
645 | dbg(DEBUG_INIT, "setting up bcs[%d].read", i); | 719 | gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); |
646 | if (!gigaset_initbcs(cs->bcs + i, cs, i)) | 720 | if (!gigaset_initbcs(cs->bcs + i, cs, i)) |
647 | goto error; | 721 | goto error; |
648 | } | 722 | } |
649 | 723 | ||
650 | ++cs->cs_init; | 724 | ++cs->cs_init; |
651 | 725 | ||
652 | dbg(DEBUG_INIT, "setting up at_state"); | 726 | gig_dbg(DEBUG_INIT, "setting up at_state"); |
653 | spin_lock_init(&cs->lock); | 727 | spin_lock_init(&cs->lock); |
654 | gigaset_at_init(&cs->at_state, NULL, cs, 0); | 728 | gigaset_at_init(&cs->at_state, NULL, cs, 0); |
655 | cs->dle = 0; | 729 | cs->dle = 0; |
656 | cs->cbytes = 0; | 730 | cs->cbytes = 0; |
657 | 731 | ||
658 | dbg(DEBUG_INIT, "setting up inbuf"); | 732 | gig_dbg(DEBUG_INIT, "setting up inbuf"); |
659 | if (onechannel) { //FIXME distinction necessary? | 733 | if (onechannel) { //FIXME distinction necessary? |
660 | gigaset_inbuf_init(cs->inbuf, cs->bcs, cs, INS_command); | 734 | gigaset_inbuf_init(cs->inbuf, cs->bcs, cs, INS_command); |
661 | } else | 735 | } else |
662 | gigaset_inbuf_init(cs->inbuf, NULL, cs, INS_command); | 736 | gigaset_inbuf_init(cs->inbuf, NULL, cs, INS_command); |
663 | 737 | ||
664 | atomic_set(&cs->connected, 0); | 738 | cs->connected = 0; |
739 | cs->isdn_up = 0; | ||
665 | 740 | ||
666 | dbg(DEBUG_INIT, "setting up cmdbuf"); | 741 | gig_dbg(DEBUG_INIT, "setting up cmdbuf"); |
667 | cs->cmdbuf = cs->lastcmdbuf = NULL; | 742 | cs->cmdbuf = cs->lastcmdbuf = NULL; |
668 | spin_lock_init(&cs->cmdlock); | 743 | spin_lock_init(&cs->cmdlock); |
669 | cs->curlen = 0; | 744 | cs->curlen = 0; |
670 | cs->cmdbytes = 0; | 745 | cs->cmdbytes = 0; |
671 | 746 | ||
672 | /* | 747 | gig_dbg(DEBUG_INIT, "setting up iif"); |
673 | * Tell the ISDN4Linux subsystem (the LL) that | ||
674 | * a driver for a USB-Device is available ! | ||
675 | * If this is done, "isdnctrl" is able to bind a device for this driver even | ||
676 | * if no physical usb-device is currently connected. | ||
677 | * But this device will just be accessable if a physical USB device is connected | ||
678 | * (via "gigaset_probe") . | ||
679 | */ | ||
680 | dbg(DEBUG_INIT, "setting up iif"); | ||
681 | if (!gigaset_register_to_LL(cs, modulename)) { | 748 | if (!gigaset_register_to_LL(cs, modulename)) { |
682 | err("register_isdn=>error"); | 749 | err("register_isdn failed"); |
683 | goto error; | 750 | goto error; |
684 | } | 751 | } |
685 | 752 | ||
686 | make_valid(cs, VALID_ID); | 753 | make_valid(cs, VALID_ID); |
687 | ++cs->cs_init; | 754 | ++cs->cs_init; |
688 | dbg(DEBUG_INIT, "setting up hw"); | 755 | gig_dbg(DEBUG_INIT, "setting up hw"); |
689 | if (!cs->ops->initcshw(cs)) | 756 | if (!cs->ops->initcshw(cs)) |
690 | goto error; | 757 | goto error; |
691 | 758 | ||
@@ -693,27 +760,29 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
693 | 760 | ||
694 | gigaset_if_init(cs); | 761 | gigaset_if_init(cs); |
695 | 762 | ||
696 | atomic_set(&cs->running, 1); | 763 | spin_lock_irqsave(&cs->lock, flags); |
697 | cs->timer.data = (unsigned long) cs; | 764 | cs->running = 1; |
698 | cs->timer.function = timer_tick; | 765 | spin_unlock_irqrestore(&cs->lock, flags); |
699 | cs->timer.expires = jiffies + GIG_TICK; | 766 | setup_timer(&cs->timer, timer_tick, (unsigned long) cs); |
767 | cs->timer.expires = jiffies + msecs_to_jiffies(GIG_TICK); | ||
700 | /* FIXME: can jiffies increase too much until the timer is added? | 768 | /* FIXME: can jiffies increase too much until the timer is added? |
701 | * Same problem(?) with mod_timer() in timer_tick(). */ | 769 | * Same problem(?) with mod_timer() in timer_tick(). */ |
702 | add_timer(&cs->timer); | 770 | add_timer(&cs->timer); |
703 | 771 | ||
704 | dbg(DEBUG_INIT, "cs initialized!"); | 772 | gig_dbg(DEBUG_INIT, "cs initialized"); |
705 | up(&cs->sem); | 773 | mutex_unlock(&cs->mutex); |
706 | return cs; | 774 | return cs; |
707 | 775 | ||
708 | error: if (cs) | 776 | error: if (cs) |
709 | up(&cs->sem); | 777 | mutex_unlock(&cs->mutex); |
710 | dbg(DEBUG_INIT, "failed"); | 778 | gig_dbg(DEBUG_INIT, "failed"); |
711 | gigaset_freecs(cs); | 779 | gigaset_freecs(cs); |
712 | return NULL; | 780 | return NULL; |
713 | } | 781 | } |
714 | EXPORT_SYMBOL_GPL(gigaset_initcs); | 782 | EXPORT_SYMBOL_GPL(gigaset_initcs); |
715 | 783 | ||
716 | /* ReInitialize the b-channel structure */ /* e.g. called on hangup, disconnect */ | 784 | /* ReInitialize the b-channel structure */ |
785 | /* e.g. called on hangup, disconnect */ | ||
717 | void gigaset_bcs_reinit(struct bc_state *bcs) | 786 | void gigaset_bcs_reinit(struct bc_state *bcs) |
718 | { | 787 | { |
719 | struct sk_buff *skb; | 788 | struct sk_buff *skb; |
@@ -723,12 +792,12 @@ void gigaset_bcs_reinit(struct bc_state *bcs) | |||
723 | while ((skb = skb_dequeue(&bcs->squeue)) != NULL) | 792 | while ((skb = skb_dequeue(&bcs->squeue)) != NULL) |
724 | dev_kfree_skb(skb); | 793 | dev_kfree_skb(skb); |
725 | 794 | ||
726 | spin_lock_irqsave(&cs->lock, flags); //FIXME | 795 | spin_lock_irqsave(&cs->lock, flags); |
727 | clear_at_state(&bcs->at_state); | 796 | clear_at_state(&bcs->at_state); |
728 | bcs->at_state.ConState = 0; | 797 | bcs->at_state.ConState = 0; |
729 | bcs->at_state.timer_active = 0; | 798 | bcs->at_state.timer_active = 0; |
730 | bcs->at_state.timer_expires = 0; | 799 | bcs->at_state.timer_expires = 0; |
731 | bcs->at_state.cid = -1; /* No CID defined */ | 800 | bcs->at_state.cid = -1; /* No CID defined */ |
732 | spin_unlock_irqrestore(&cs->lock, flags); | 801 | spin_unlock_irqrestore(&cs->lock, flags); |
733 | 802 | ||
734 | bcs->inputstate = 0; | 803 | bcs->inputstate = 0; |
@@ -803,11 +872,14 @@ static void cleanup_cs(struct cardstate *cs) | |||
803 | 872 | ||
804 | int gigaset_start(struct cardstate *cs) | 873 | int gigaset_start(struct cardstate *cs) |
805 | { | 874 | { |
806 | if (down_interruptible(&cs->sem)) | 875 | unsigned long flags; |
876 | |||
877 | if (mutex_lock_interruptible(&cs->mutex)) | ||
807 | return 0; | 878 | return 0; |
808 | //info("USB device for Gigaset 307x now attached to Dev %d", ucs->minor); | ||
809 | 879 | ||
810 | atomic_set(&cs->connected, 1); | 880 | spin_lock_irqsave(&cs->lock, flags); |
881 | cs->connected = 1; | ||
882 | spin_unlock_irqrestore(&cs->lock, flags); | ||
811 | 883 | ||
812 | if (atomic_read(&cs->mstate) != MS_LOCKED) { | 884 | if (atomic_read(&cs->mstate) != MS_LOCKED) { |
813 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); | 885 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); |
@@ -826,23 +898,26 @@ int gigaset_start(struct cardstate *cs) | |||
826 | goto error; | 898 | goto error; |
827 | } | 899 | } |
828 | 900 | ||
829 | dbg(DEBUG_CMD, "scheduling START"); | 901 | gig_dbg(DEBUG_CMD, "scheduling START"); |
830 | gigaset_schedule_event(cs); | 902 | gigaset_schedule_event(cs); |
831 | 903 | ||
832 | wait_event(cs->waitqueue, !cs->waiting); | 904 | wait_event(cs->waitqueue, !cs->waiting); |
833 | 905 | ||
834 | up(&cs->sem); | 906 | /* set up device sysfs */ |
907 | gigaset_init_dev_sysfs(cs); | ||
908 | |||
909 | mutex_unlock(&cs->mutex); | ||
835 | return 1; | 910 | return 1; |
836 | 911 | ||
837 | error: | 912 | error: |
838 | up(&cs->sem); | 913 | mutex_unlock(&cs->mutex); |
839 | return 0; | 914 | return 0; |
840 | } | 915 | } |
841 | EXPORT_SYMBOL_GPL(gigaset_start); | 916 | EXPORT_SYMBOL_GPL(gigaset_start); |
842 | 917 | ||
843 | void gigaset_shutdown(struct cardstate *cs) | 918 | void gigaset_shutdown(struct cardstate *cs) |
844 | { | 919 | { |
845 | down(&cs->sem); | 920 | mutex_lock(&cs->mutex); |
846 | 921 | ||
847 | cs->waiting = 1; | 922 | cs->waiting = 1; |
848 | 923 | ||
@@ -851,11 +926,11 @@ void gigaset_shutdown(struct cardstate *cs) | |||
851 | goto exit; | 926 | goto exit; |
852 | } | 927 | } |
853 | 928 | ||
854 | dbg(DEBUG_CMD, "scheduling SHUTDOWN"); | 929 | gig_dbg(DEBUG_CMD, "scheduling SHUTDOWN"); |
855 | gigaset_schedule_event(cs); | 930 | gigaset_schedule_event(cs); |
856 | 931 | ||
857 | if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { | 932 | if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { |
858 | warn("aborted"); | 933 | warn("%s: aborted", __func__); |
859 | //FIXME | 934 | //FIXME |
860 | } | 935 | } |
861 | 936 | ||
@@ -872,15 +947,13 @@ void gigaset_shutdown(struct cardstate *cs) | |||
872 | cleanup_cs(cs); | 947 | cleanup_cs(cs); |
873 | 948 | ||
874 | exit: | 949 | exit: |
875 | up(&cs->sem); | 950 | mutex_unlock(&cs->mutex); |
876 | } | 951 | } |
877 | EXPORT_SYMBOL_GPL(gigaset_shutdown); | 952 | EXPORT_SYMBOL_GPL(gigaset_shutdown); |
878 | 953 | ||
879 | void gigaset_stop(struct cardstate *cs) | 954 | void gigaset_stop(struct cardstate *cs) |
880 | { | 955 | { |
881 | down(&cs->sem); | 956 | mutex_lock(&cs->mutex); |
882 | |||
883 | atomic_set(&cs->connected, 0); | ||
884 | 957 | ||
885 | cs->waiting = 1; | 958 | cs->waiting = 1; |
886 | 959 | ||
@@ -889,21 +962,21 @@ void gigaset_stop(struct cardstate *cs) | |||
889 | goto exit; | 962 | goto exit; |
890 | } | 963 | } |
891 | 964 | ||
892 | dbg(DEBUG_CMD, "scheduling STOP"); | 965 | gig_dbg(DEBUG_CMD, "scheduling STOP"); |
893 | gigaset_schedule_event(cs); | 966 | gigaset_schedule_event(cs); |
894 | 967 | ||
895 | if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { | 968 | if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { |
896 | warn("aborted"); | 969 | warn("%s: aborted", __func__); |
897 | //FIXME | 970 | //FIXME |
898 | } | 971 | } |
899 | 972 | ||
900 | /* Tell the LL that the device is not available .. */ | 973 | /* clear device sysfs */ |
901 | gigaset_i4l_cmd(cs, ISDN_STAT_STOP); // FIXME move to event layer? | 974 | gigaset_free_dev_sysfs(cs); |
902 | 975 | ||
903 | cleanup_cs(cs); | 976 | cleanup_cs(cs); |
904 | 977 | ||
905 | exit: | 978 | exit: |
906 | up(&cs->sem); | 979 | mutex_unlock(&cs->mutex); |
907 | } | 980 | } |
908 | EXPORT_SYMBOL_GPL(gigaset_stop); | 981 | EXPORT_SYMBOL_GPL(gigaset_stop); |
909 | 982 | ||
@@ -947,31 +1020,25 @@ void gigaset_debugdrivers(void) | |||
947 | 1020 | ||
948 | spin_lock_irqsave(&driver_lock, flags); | 1021 | spin_lock_irqsave(&driver_lock, flags); |
949 | list_for_each_entry(drv, &drivers, list) { | 1022 | list_for_each_entry(drv, &drivers, list) { |
950 | dbg(DEBUG_DRIVER, "driver %p", drv); | 1023 | gig_dbg(DEBUG_DRIVER, "driver %p", drv); |
951 | spin_lock(&drv->lock); | 1024 | spin_lock(&drv->lock); |
952 | for (i = 0; i < drv->minors; ++i) { | 1025 | for (i = 0; i < drv->minors; ++i) { |
953 | dbg(DEBUG_DRIVER, " index %u", i); | 1026 | gig_dbg(DEBUG_DRIVER, " index %u", i); |
954 | dbg(DEBUG_DRIVER, " flags 0x%02x", drv->flags[i]); | 1027 | gig_dbg(DEBUG_DRIVER, " flags 0x%02x", |
1028 | drv->flags[i]); | ||
955 | cs = drv->cs + i; | 1029 | cs = drv->cs + i; |
956 | dbg(DEBUG_DRIVER, " cardstate %p", cs); | 1030 | gig_dbg(DEBUG_DRIVER, " cardstate %p", cs); |
957 | dbg(DEBUG_DRIVER, " minor_index %u", cs->minor_index); | 1031 | gig_dbg(DEBUG_DRIVER, " minor_index %u", |
958 | dbg(DEBUG_DRIVER, " driver %p", cs->driver); | 1032 | cs->minor_index); |
959 | dbg(DEBUG_DRIVER, " i4l id %d", cs->myid); | 1033 | gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver); |
1034 | gig_dbg(DEBUG_DRIVER, " i4l id %d", cs->myid); | ||
960 | } | 1035 | } |
961 | spin_unlock(&drv->lock); | 1036 | spin_unlock(&drv->lock); |
962 | } | 1037 | } |
963 | spin_unlock_irqrestore(&driver_lock, flags); | 1038 | spin_unlock_irqrestore(&driver_lock, flags); |
964 | } | 1039 | } |
965 | EXPORT_SYMBOL_GPL(gigaset_debugdrivers); | ||
966 | |||
967 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty) | ||
968 | { | ||
969 | if (tty->index < 0 || tty->index >= tty->driver->num) | ||
970 | return NULL; | ||
971 | return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start); | ||
972 | } | ||
973 | 1040 | ||
974 | struct cardstate *gigaset_get_cs_by_minor(unsigned minor) | 1041 | static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) |
975 | { | 1042 | { |
976 | unsigned long flags; | 1043 | unsigned long flags; |
977 | static struct cardstate *ret = NULL; | 1044 | static struct cardstate *ret = NULL; |
@@ -994,6 +1061,13 @@ struct cardstate *gigaset_get_cs_by_minor(unsigned minor) | |||
994 | return ret; | 1061 | return ret; |
995 | } | 1062 | } |
996 | 1063 | ||
1064 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty) | ||
1065 | { | ||
1066 | if (tty->index < 0 || tty->index >= tty->driver->num) | ||
1067 | return NULL; | ||
1068 | return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start); | ||
1069 | } | ||
1070 | |||
997 | void gigaset_freedriver(struct gigaset_driver *drv) | 1071 | void gigaset_freedriver(struct gigaset_driver *drv) |
998 | { | 1072 | { |
999 | unsigned long flags; | 1073 | unsigned long flags; |
@@ -1014,20 +1088,20 @@ EXPORT_SYMBOL_GPL(gigaset_freedriver); | |||
1014 | /* gigaset_initdriver | 1088 | /* gigaset_initdriver |
1015 | * Allocate and initialize gigaset_driver structure. Initialize interface. | 1089 | * Allocate and initialize gigaset_driver structure. Initialize interface. |
1016 | * parameters: | 1090 | * parameters: |
1017 | * minor First minor number | 1091 | * minor First minor number |
1018 | * minors Number of minors this driver can handle | 1092 | * minors Number of minors this driver can handle |
1019 | * procname Name of the driver (e.g. for /proc/tty/drivers, path in /proc/driver) | 1093 | * procname Name of the driver |
1020 | * devname Name of the device files (prefix without minor number) | 1094 | * devname Name of the device files (prefix without minor number) |
1021 | * devfsname Devfs name of the device files without %d | 1095 | * devfsname Devfs name of the device files without %d |
1022 | * return value: | 1096 | * return value: |
1023 | * Pointer to the gigaset_driver structure on success, NULL on failure. | 1097 | * Pointer to the gigaset_driver structure on success, NULL on failure. |
1024 | */ | 1098 | */ |
1025 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | 1099 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, |
1026 | const char *procname, | 1100 | const char *procname, |
1027 | const char *devname, | 1101 | const char *devname, |
1028 | const char *devfsname, | 1102 | const char *devfsname, |
1029 | const struct gigaset_ops *ops, | 1103 | const struct gigaset_ops *ops, |
1030 | struct module *owner) | 1104 | struct module *owner) |
1031 | { | 1105 | { |
1032 | struct gigaset_driver *drv; | 1106 | struct gigaset_driver *drv; |
1033 | unsigned long flags; | 1107 | unsigned long flags; |
@@ -1036,8 +1110,9 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1036 | drv = kmalloc(sizeof *drv, GFP_KERNEL); | 1110 | drv = kmalloc(sizeof *drv, GFP_KERNEL); |
1037 | if (!drv) | 1111 | if (!drv) |
1038 | return NULL; | 1112 | return NULL; |
1113 | |||
1039 | if (!try_module_get(owner)) | 1114 | if (!try_module_get(owner)) |
1040 | return NULL; | 1115 | goto out1; |
1041 | 1116 | ||
1042 | drv->cs = NULL; | 1117 | drv->cs = NULL; |
1043 | drv->have_tty = 0; | 1118 | drv->have_tty = 0; |
@@ -1051,10 +1126,11 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1051 | 1126 | ||
1052 | drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); | 1127 | drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); |
1053 | if (!drv->cs) | 1128 | if (!drv->cs) |
1054 | goto out1; | 1129 | goto out2; |
1130 | |||
1055 | drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); | 1131 | drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); |
1056 | if (!drv->flags) | 1132 | if (!drv->flags) |
1057 | goto out2; | 1133 | goto out3; |
1058 | 1134 | ||
1059 | for (i = 0; i < minors; ++i) { | 1135 | for (i = 0; i < minors; ++i) { |
1060 | drv->flags[i] = 0; | 1136 | drv->flags[i] = 0; |
@@ -1071,61 +1147,16 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1071 | 1147 | ||
1072 | return drv; | 1148 | return drv; |
1073 | 1149 | ||
1074 | out2: | 1150 | out3: |
1075 | kfree(drv->cs); | 1151 | kfree(drv->cs); |
1152 | out2: | ||
1153 | module_put(owner); | ||
1076 | out1: | 1154 | out1: |
1077 | kfree(drv); | 1155 | kfree(drv); |
1078 | module_put(owner); | ||
1079 | return NULL; | 1156 | return NULL; |
1080 | } | 1157 | } |
1081 | EXPORT_SYMBOL_GPL(gigaset_initdriver); | 1158 | EXPORT_SYMBOL_GPL(gigaset_initdriver); |
1082 | 1159 | ||
1083 | static struct cardstate *alloc_cs(struct gigaset_driver *drv) | ||
1084 | { | ||
1085 | unsigned long flags; | ||
1086 | unsigned i; | ||
1087 | static struct cardstate *ret = NULL; | ||
1088 | |||
1089 | spin_lock_irqsave(&drv->lock, flags); | ||
1090 | for (i = 0; i < drv->minors; ++i) { | ||
1091 | if (!(drv->flags[i] & VALID_MINOR)) { | ||
1092 | drv->flags[i] = VALID_MINOR; | ||
1093 | ret = drv->cs + i; | ||
1094 | } | ||
1095 | if (ret) | ||
1096 | break; | ||
1097 | } | ||
1098 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1099 | return ret; | ||
1100 | } | ||
1101 | |||
1102 | static void free_cs(struct cardstate *cs) | ||
1103 | { | ||
1104 | unsigned long flags; | ||
1105 | struct gigaset_driver *drv = cs->driver; | ||
1106 | spin_lock_irqsave(&drv->lock, flags); | ||
1107 | drv->flags[cs->minor_index] = 0; | ||
1108 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1109 | } | ||
1110 | |||
1111 | static void make_valid(struct cardstate *cs, unsigned mask) | ||
1112 | { | ||
1113 | unsigned long flags; | ||
1114 | struct gigaset_driver *drv = cs->driver; | ||
1115 | spin_lock_irqsave(&drv->lock, flags); | ||
1116 | drv->flags[cs->minor_index] |= mask; | ||
1117 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1118 | } | ||
1119 | |||
1120 | static void make_invalid(struct cardstate *cs, unsigned mask) | ||
1121 | { | ||
1122 | unsigned long flags; | ||
1123 | struct gigaset_driver *drv = cs->driver; | ||
1124 | spin_lock_irqsave(&drv->lock, flags); | ||
1125 | drv->flags[cs->minor_index] &= ~mask; | ||
1126 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1127 | } | ||
1128 | |||
1129 | /* For drivers without fixed assignment device<->cardstate (usb) */ | 1160 | /* For drivers without fixed assignment device<->cardstate (usb) */ |
1130 | struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv) | 1161 | struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv) |
1131 | { | 1162 | { |
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index fdcb80bb21c7..1ba3424a286b 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Stuff used by all variants of the driver | 2 | * Stuff used by all variants of the driver |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de>, | 4 | * Copyright (c) 2001 by Stefan Eilers, |
5 | * Hansjoerg Lipp <hjlipp@web.de>, | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Tilman Schmidt <tilman@imap.cc>. | 6 | * Tilman Schmidt <tilman@imap.cc>. |
7 | * | 7 | * |
@@ -11,82 +11,78 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: ev-layer.c,v 1.4.2.18 2006/02/04 18:28:16 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
21 | 17 | ||
22 | /* ========================================================== */ | 18 | /* ========================================================== */ |
23 | /* bit masks for pending commands */ | 19 | /* bit masks for pending commands */ |
24 | #define PC_INIT 0x004 | 20 | #define PC_DIAL 0x001 |
25 | #define PC_DLE0 0x008 | 21 | #define PC_HUP 0x002 |
26 | #define PC_DLE1 0x010 | 22 | #define PC_INIT 0x004 |
27 | #define PC_CID 0x080 | 23 | #define PC_DLE0 0x008 |
28 | #define PC_NOCID 0x100 | 24 | #define PC_DLE1 0x010 |
29 | #define PC_HUP 0x002 | 25 | #define PC_SHUTDOWN 0x020 |
30 | #define PC_DIAL 0x001 | 26 | #define PC_ACCEPT 0x040 |
31 | #define PC_ACCEPT 0x040 | 27 | #define PC_CID 0x080 |
32 | #define PC_SHUTDOWN 0x020 | 28 | #define PC_NOCID 0x100 |
33 | #define PC_CIDMODE 0x200 | 29 | #define PC_CIDMODE 0x200 |
34 | #define PC_UMMODE 0x400 | 30 | #define PC_UMMODE 0x400 |
35 | 31 | ||
36 | /* types of modem responses */ | 32 | /* types of modem responses */ |
37 | #define RT_NOTHING 0 | 33 | #define RT_NOTHING 0 |
38 | #define RT_ZSAU 1 | 34 | #define RT_ZSAU 1 |
39 | #define RT_RING 2 | 35 | #define RT_RING 2 |
40 | #define RT_NUMBER 3 | 36 | #define RT_NUMBER 3 |
41 | #define RT_STRING 4 | 37 | #define RT_STRING 4 |
42 | #define RT_HEX 5 | 38 | #define RT_HEX 5 |
43 | #define RT_ZCAU 6 | 39 | #define RT_ZCAU 6 |
44 | 40 | ||
45 | /* Possible ASCII responses */ | 41 | /* Possible ASCII responses */ |
46 | #define RSP_OK 0 | 42 | #define RSP_OK 0 |
47 | //#define RSP_BUSY 1 | 43 | //#define RSP_BUSY 1 |
48 | //#define RSP_CONNECT 2 | 44 | //#define RSP_CONNECT 2 |
49 | #define RSP_ZGCI 3 | 45 | #define RSP_ZGCI 3 |
50 | #define RSP_RING 4 | 46 | #define RSP_RING 4 |
51 | #define RSP_ZAOC 5 | 47 | #define RSP_ZAOC 5 |
52 | #define RSP_ZCSTR 6 | 48 | #define RSP_ZCSTR 6 |
53 | #define RSP_ZCFGT 7 | 49 | #define RSP_ZCFGT 7 |
54 | #define RSP_ZCFG 8 | 50 | #define RSP_ZCFG 8 |
55 | #define RSP_ZCCR 9 | 51 | #define RSP_ZCCR 9 |
56 | #define RSP_EMPTY 10 | 52 | #define RSP_EMPTY 10 |
57 | #define RSP_ZLOG 11 | 53 | #define RSP_ZLOG 11 |
58 | #define RSP_ZCAU 12 | 54 | #define RSP_ZCAU 12 |
59 | #define RSP_ZMWI 13 | 55 | #define RSP_ZMWI 13 |
60 | #define RSP_ZABINFO 14 | 56 | #define RSP_ZABINFO 14 |
61 | #define RSP_ZSMLSTCHG 15 | 57 | #define RSP_ZSMLSTCHG 15 |
62 | #define RSP_VAR 100 | 58 | #define RSP_VAR 100 |
63 | #define RSP_ZSAU (RSP_VAR + VAR_ZSAU) | 59 | #define RSP_ZSAU (RSP_VAR + VAR_ZSAU) |
64 | #define RSP_ZDLE (RSP_VAR + VAR_ZDLE) | 60 | #define RSP_ZDLE (RSP_VAR + VAR_ZDLE) |
65 | #define RSP_ZVLS (RSP_VAR + VAR_ZVLS) | 61 | #define RSP_ZVLS (RSP_VAR + VAR_ZVLS) |
66 | #define RSP_ZCTP (RSP_VAR + VAR_ZCTP) | 62 | #define RSP_ZCTP (RSP_VAR + VAR_ZCTP) |
67 | #define RSP_STR (RSP_VAR + VAR_NUM) | 63 | #define RSP_STR (RSP_VAR + VAR_NUM) |
68 | #define RSP_NMBR (RSP_STR + STR_NMBR) | 64 | #define RSP_NMBR (RSP_STR + STR_NMBR) |
69 | #define RSP_ZCPN (RSP_STR + STR_ZCPN) | 65 | #define RSP_ZCPN (RSP_STR + STR_ZCPN) |
70 | #define RSP_ZCON (RSP_STR + STR_ZCON) | 66 | #define RSP_ZCON (RSP_STR + STR_ZCON) |
71 | #define RSP_ZBC (RSP_STR + STR_ZBC) | 67 | #define RSP_ZBC (RSP_STR + STR_ZBC) |
72 | #define RSP_ZHLC (RSP_STR + STR_ZHLC) | 68 | #define RSP_ZHLC (RSP_STR + STR_ZHLC) |
73 | #define RSP_ERROR -1 /* ERROR */ | 69 | #define RSP_ERROR -1 /* ERROR */ |
74 | #define RSP_WRONG_CID -2 /* unknown cid in cmd */ | 70 | #define RSP_WRONG_CID -2 /* unknown cid in cmd */ |
75 | //#define RSP_EMPTY -3 | 71 | //#define RSP_EMPTY -3 |
76 | #define RSP_UNKNOWN -4 /* unknown response */ | 72 | #define RSP_UNKNOWN -4 /* unknown response */ |
77 | #define RSP_FAIL -5 /* internal error */ | 73 | #define RSP_FAIL -5 /* internal error */ |
78 | #define RSP_INVAL -6 /* invalid response */ | 74 | #define RSP_INVAL -6 /* invalid response */ |
79 | 75 | ||
80 | #define RSP_NONE -19 | 76 | #define RSP_NONE -19 |
81 | #define RSP_STRING -20 | 77 | #define RSP_STRING -20 |
82 | #define RSP_NULL -21 | 78 | #define RSP_NULL -21 |
83 | //#define RSP_RETRYFAIL -22 | 79 | //#define RSP_RETRYFAIL -22 |
84 | //#define RSP_RETRY -23 | 80 | //#define RSP_RETRY -23 |
85 | //#define RSP_SKIP -24 | 81 | //#define RSP_SKIP -24 |
86 | #define RSP_INIT -27 | 82 | #define RSP_INIT -27 |
87 | #define RSP_ANY -26 | 83 | #define RSP_ANY -26 |
88 | #define RSP_LAST -28 | 84 | #define RSP_LAST -28 |
89 | #define RSP_NODEV -9 | 85 | #define RSP_NODEV -9 |
90 | 86 | ||
91 | /* actions for process_response */ | 87 | /* actions for process_response */ |
92 | #define ACT_NOTHING 0 | 88 | #define ACT_NOTHING 0 |
@@ -112,7 +108,7 @@ | |||
112 | #define ACT_DISCONNECT 20 | 108 | #define ACT_DISCONNECT 20 |
113 | #define ACT_CONNECT 21 | 109 | #define ACT_CONNECT 21 |
114 | #define ACT_REMOTEREJECT 22 | 110 | #define ACT_REMOTEREJECT 22 |
115 | #define ACT_CONNTIMEOUT 23 | 111 | #define ACT_CONNTIMEOUT 23 |
116 | #define ACT_REMOTEHUP 24 | 112 | #define ACT_REMOTEHUP 24 |
117 | #define ACT_ABORTHUP 25 | 113 | #define ACT_ABORTHUP 25 |
118 | #define ACT_ICALL 26 | 114 | #define ACT_ICALL 26 |
@@ -127,40 +123,40 @@ | |||
127 | #define ACT_ERROR 35 | 123 | #define ACT_ERROR 35 |
128 | #define ACT_ABORTCID 36 | 124 | #define ACT_ABORTCID 36 |
129 | #define ACT_ZCAU 37 | 125 | #define ACT_ZCAU 37 |
130 | #define ACT_NOTIFY_BC_DOWN 38 | 126 | #define ACT_NOTIFY_BC_DOWN 38 |
131 | #define ACT_NOTIFY_BC_UP 39 | 127 | #define ACT_NOTIFY_BC_UP 39 |
132 | #define ACT_DIAL 40 | 128 | #define ACT_DIAL 40 |
133 | #define ACT_ACCEPT 41 | 129 | #define ACT_ACCEPT 41 |
134 | #define ACT_PROTO_L2 42 | 130 | #define ACT_PROTO_L2 42 |
135 | #define ACT_HUP 43 | 131 | #define ACT_HUP 43 |
136 | #define ACT_IF_LOCK 44 | 132 | #define ACT_IF_LOCK 44 |
137 | #define ACT_START 45 | 133 | #define ACT_START 45 |
138 | #define ACT_STOP 46 | 134 | #define ACT_STOP 46 |
139 | #define ACT_FAKEDLE0 47 | 135 | #define ACT_FAKEDLE0 47 |
140 | #define ACT_FAKEHUP 48 | 136 | #define ACT_FAKEHUP 48 |
141 | #define ACT_FAKESDOWN 49 | 137 | #define ACT_FAKESDOWN 49 |
142 | #define ACT_SHUTDOWN 50 | 138 | #define ACT_SHUTDOWN 50 |
143 | #define ACT_PROC_CIDMODE 51 | 139 | #define ACT_PROC_CIDMODE 51 |
144 | #define ACT_UMODESET 52 | 140 | #define ACT_UMODESET 52 |
145 | #define ACT_FAILUMODE 53 | 141 | #define ACT_FAILUMODE 53 |
146 | #define ACT_CMODESET 54 | 142 | #define ACT_CMODESET 54 |
147 | #define ACT_FAILCMODE 55 | 143 | #define ACT_FAILCMODE 55 |
148 | #define ACT_IF_VER 56 | 144 | #define ACT_IF_VER 56 |
149 | #define ACT_CMD 100 | 145 | #define ACT_CMD 100 |
150 | 146 | ||
151 | /* at command sequences */ | 147 | /* at command sequences */ |
152 | #define SEQ_NONE 0 | 148 | #define SEQ_NONE 0 |
153 | #define SEQ_INIT 100 | 149 | #define SEQ_INIT 100 |
154 | #define SEQ_DLE0 200 | 150 | #define SEQ_DLE0 200 |
155 | #define SEQ_DLE1 250 | 151 | #define SEQ_DLE1 250 |
156 | #define SEQ_CID 300 | 152 | #define SEQ_CID 300 |
157 | #define SEQ_NOCID 350 | 153 | #define SEQ_NOCID 350 |
158 | #define SEQ_HUP 400 | 154 | #define SEQ_HUP 400 |
159 | #define SEQ_DIAL 600 | 155 | #define SEQ_DIAL 600 |
160 | #define SEQ_ACCEPT 720 | 156 | #define SEQ_ACCEPT 720 |
161 | #define SEQ_SHUTDOWN 500 | 157 | #define SEQ_SHUTDOWN 500 |
162 | #define SEQ_CIDMODE 10 | 158 | #define SEQ_CIDMODE 10 |
163 | #define SEQ_UMMODE 11 | 159 | #define SEQ_UMMODE 11 |
164 | 160 | ||
165 | 161 | ||
166 | // 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring | 162 | // 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring |
@@ -175,7 +171,7 @@ struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */ | |||
175 | // {ACT_TIMEOUT}}, | 171 | // {ACT_TIMEOUT}}, |
176 | 172 | ||
177 | {RSP_INIT, -1, -1,SEQ_INIT, 100, INIT_TIMEOUT, | 173 | {RSP_INIT, -1, -1,SEQ_INIT, 100, INIT_TIMEOUT, |
178 | {ACT_TIMEOUT}}, /* wait until device is ready */ | 174 | {ACT_TIMEOUT}}, /* wait until device is ready */ |
179 | 175 | ||
180 | {EV_TIMEOUT, 100,100, -1, 101, 3, {0}, "Z\r"}, /* device in transparent mode? try to initialize it. */ | 176 | {EV_TIMEOUT, 100,100, -1, 101, 3, {0}, "Z\r"}, /* device in transparent mode? try to initialize it. */ |
181 | {RSP_OK, 101,103, -1, 120, 5, {ACT_GETSTRING}, "+GMR\r"}, /* get version */ | 177 | {RSP_OK, 101,103, -1, 120, 5, {ACT_GETSTRING}, "+GMR\r"}, /* get version */ |
@@ -190,8 +186,8 @@ struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */ | |||
190 | {RSP_ERROR, 108,108, -1, 0, 0, {ACT_FAILINIT}}, | 186 | {RSP_ERROR, 108,108, -1, 0, 0, {ACT_FAILINIT}}, |
191 | 187 | ||
192 | {EV_TIMEOUT, 108,108, -1, 105, 2, {ACT_SETDLE0, | 188 | {EV_TIMEOUT, 108,108, -1, 105, 2, {ACT_SETDLE0, |
193 | ACT_HUPMODEM, | 189 | ACT_HUPMODEM, |
194 | ACT_TIMEOUT}}, /* still timeout => connection in unimodem mode? */ | 190 | ACT_TIMEOUT}}, /* still timeout => connection in unimodem mode? */ |
195 | {EV_TIMEOUT, 105,105, -1, 103, 5, {0}, "Z\r"}, | 191 | {EV_TIMEOUT, 105,105, -1, 103, 5, {0}, "Z\r"}, |
196 | 192 | ||
197 | {RSP_ERROR, 102,102, -1, 107, 5, {0}, "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */ | 193 | {RSP_ERROR, 102,102, -1, 107, 5, {0}, "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */ |
@@ -393,7 +389,7 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */ | |||
393 | 389 | ||
394 | 390 | ||
395 | #if 0 | 391 | #if 0 |
396 | static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME aenderungen uebernehmen | 392 | static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME |
397 | { | 393 | { |
398 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 394 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
399 | 395 | ||
@@ -401,7 +397,7 @@ static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME aenderungen ueberne | |||
401 | {RSP_LAST,0,0,0,0,0,0} | 397 | {RSP_LAST,0,0,0,0,0,0} |
402 | }; | 398 | }; |
403 | 399 | ||
404 | static struct reply_t tab_cid[] = /* no dle mode */ //FIXME aenderungen uebernehmen | 400 | static struct reply_t tab_cid[] = /* no dle mode */ //FIXME |
405 | { | 401 | { |
406 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 402 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
407 | 403 | ||
@@ -412,30 +408,30 @@ static struct reply_t tab_cid[] = /* no dle mode */ //FIXME aenderungen ueberneh | |||
412 | 408 | ||
413 | static struct resp_type_t resp_type[]= | 409 | static struct resp_type_t resp_type[]= |
414 | { | 410 | { |
415 | /*{"", RSP_EMPTY, RT_NOTHING},*/ | 411 | /*{"", RSP_EMPTY, RT_NOTHING},*/ |
416 | {"OK", RSP_OK, RT_NOTHING}, | 412 | {"OK", RSP_OK, RT_NOTHING}, |
417 | {"ERROR", RSP_ERROR, RT_NOTHING}, | 413 | {"ERROR", RSP_ERROR, RT_NOTHING}, |
418 | {"ZSAU", RSP_ZSAU, RT_ZSAU}, | 414 | {"ZSAU", RSP_ZSAU, RT_ZSAU}, |
419 | {"ZCAU", RSP_ZCAU, RT_ZCAU}, | 415 | {"ZCAU", RSP_ZCAU, RT_ZCAU}, |
420 | {"RING", RSP_RING, RT_RING}, | 416 | {"RING", RSP_RING, RT_RING}, |
421 | {"ZGCI", RSP_ZGCI, RT_NUMBER}, | 417 | {"ZGCI", RSP_ZGCI, RT_NUMBER}, |
422 | {"ZVLS", RSP_ZVLS, RT_NUMBER}, | 418 | {"ZVLS", RSP_ZVLS, RT_NUMBER}, |
423 | {"ZCTP", RSP_ZCTP, RT_NUMBER}, | 419 | {"ZCTP", RSP_ZCTP, RT_NUMBER}, |
424 | {"ZDLE", RSP_ZDLE, RT_NUMBER}, | 420 | {"ZDLE", RSP_ZDLE, RT_NUMBER}, |
425 | {"ZCFGT", RSP_ZCFGT, RT_NUMBER}, | 421 | {"ZCFGT", RSP_ZCFGT, RT_NUMBER}, |
426 | {"ZCCR", RSP_ZCCR, RT_NUMBER}, | 422 | {"ZCCR", RSP_ZCCR, RT_NUMBER}, |
427 | {"ZMWI", RSP_ZMWI, RT_NUMBER}, | 423 | {"ZMWI", RSP_ZMWI, RT_NUMBER}, |
428 | {"ZHLC", RSP_ZHLC, RT_STRING}, | 424 | {"ZHLC", RSP_ZHLC, RT_STRING}, |
429 | {"ZBC", RSP_ZBC, RT_STRING}, | 425 | {"ZBC", RSP_ZBC, RT_STRING}, |
430 | {"NMBR", RSP_NMBR, RT_STRING}, | 426 | {"NMBR", RSP_NMBR, RT_STRING}, |
431 | {"ZCPN", RSP_ZCPN, RT_STRING}, | 427 | {"ZCPN", RSP_ZCPN, RT_STRING}, |
432 | {"ZCON", RSP_ZCON, RT_STRING}, | 428 | {"ZCON", RSP_ZCON, RT_STRING}, |
433 | {"ZAOC", RSP_ZAOC, RT_STRING}, | 429 | {"ZAOC", RSP_ZAOC, RT_STRING}, |
434 | {"ZCSTR", RSP_ZCSTR, RT_STRING}, | 430 | {"ZCSTR", RSP_ZCSTR, RT_STRING}, |
435 | {"ZCFG", RSP_ZCFG, RT_HEX}, | 431 | {"ZCFG", RSP_ZCFG, RT_HEX}, |
436 | {"ZLOG", RSP_ZLOG, RT_NOTHING}, | 432 | {"ZLOG", RSP_ZLOG, RT_NOTHING}, |
437 | {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, | 433 | {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, |
438 | {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, | 434 | {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, |
439 | {NULL,0,0} | 435 | {NULL,0,0} |
440 | }; | 436 | }; |
441 | 437 | ||
@@ -446,9 +442,7 @@ static int isdn_getnum(char *p) | |||
446 | { | 442 | { |
447 | int v = -1; | 443 | int v = -1; |
448 | 444 | ||
449 | IFNULLRETVAL(p, -1); | 445 | gig_dbg(DEBUG_TRANSCMD, "string: %s", p); |
450 | |||
451 | dbg(DEBUG_TRANSCMD, "string: %s", p); | ||
452 | 446 | ||
453 | while (*p >= '0' && *p <= '9') | 447 | while (*p >= '0' && *p <= '9') |
454 | v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); | 448 | v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); |
@@ -465,9 +459,7 @@ static int isdn_gethex(char *p) | |||
465 | int v = 0; | 459 | int v = 0; |
466 | int c; | 460 | int c; |
467 | 461 | ||
468 | IFNULLRETVAL(p, -1); | 462 | gig_dbg(DEBUG_TRANSCMD, "string: %s", p); |
469 | |||
470 | dbg(DEBUG_TRANSCMD, "string: %s", p); | ||
471 | 463 | ||
472 | if (!*p) | 464 | if (!*p) |
473 | return -1; | 465 | return -1; |
@@ -490,14 +482,6 @@ static int isdn_gethex(char *p) | |||
490 | return v; | 482 | return v; |
491 | } | 483 | } |
492 | 484 | ||
493 | static inline void new_index(atomic_t *index, int max) | ||
494 | { | ||
495 | if (atomic_read(index) == max) //FIXME race? | ||
496 | atomic_set(index, 0); | ||
497 | else | ||
498 | atomic_inc(index); | ||
499 | } | ||
500 | |||
501 | /* retrieve CID from parsed response | 485 | /* retrieve CID from parsed response |
502 | * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 | 486 | * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 |
503 | */ | 487 | */ |
@@ -536,16 +520,14 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
536 | int cid; | 520 | int cid; |
537 | int rawstring; | 521 | int rawstring; |
538 | 522 | ||
539 | IFNULLRET(cs); | ||
540 | |||
541 | len = cs->cbytes; | 523 | len = cs->cbytes; |
542 | if (!len) { | 524 | if (!len) { |
543 | /* ignore additional LFs/CRs (M10x config mode or cx100) */ | 525 | /* ignore additional LFs/CRs (M10x config mode or cx100) */ |
544 | dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); | 526 | gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); |
545 | return; | 527 | return; |
546 | } | 528 | } |
547 | cs->respdata[len] = 0; | 529 | cs->respdata[len] = 0; |
548 | dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata); | 530 | gig_dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata); |
549 | argv[0] = cs->respdata; | 531 | argv[0] = cs->respdata; |
550 | params = 1; | 532 | params = 1; |
551 | if (cs->at_state.getstring) { | 533 | if (cs->at_state.getstring) { |
@@ -561,7 +543,8 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
561 | case ',': | 543 | case ',': |
562 | case '=': | 544 | case '=': |
563 | if (params > MAX_REC_PARAMS) { | 545 | if (params > MAX_REC_PARAMS) { |
564 | warn("too many parameters in response"); | 546 | dev_warn(cs->dev, |
547 | "too many parameters in response\n"); | ||
565 | /* need last parameter (might be CID) */ | 548 | /* need last parameter (might be CID) */ |
566 | params--; | 549 | params--; |
567 | } | 550 | } |
@@ -572,33 +555,33 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
572 | cid = params > 1 ? cid_of_response(argv[params-1]) : 0; | 555 | cid = params > 1 ? cid_of_response(argv[params-1]) : 0; |
573 | if (cid < 0) { | 556 | if (cid < 0) { |
574 | gigaset_add_event(cs, &cs->at_state, RSP_INVAL, | 557 | gigaset_add_event(cs, &cs->at_state, RSP_INVAL, |
575 | NULL, 0, NULL); | 558 | NULL, 0, NULL); |
576 | return; | 559 | return; |
577 | } | 560 | } |
578 | 561 | ||
579 | for (j = 1; j < params; ++j) | 562 | for (j = 1; j < params; ++j) |
580 | argv[j][-1] = 0; | 563 | argv[j][-1] = 0; |
581 | 564 | ||
582 | dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); | 565 | gig_dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); |
583 | if (cid) { | 566 | if (cid) { |
584 | --params; | 567 | --params; |
585 | dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); | 568 | gig_dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); |
586 | } | 569 | } |
587 | dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); | 570 | gig_dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); |
588 | for (j = 1; j < params; j++) | 571 | for (j = 1; j < params; j++) |
589 | dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); | 572 | gig_dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); |
590 | } | 573 | } |
591 | 574 | ||
592 | spin_lock_irqsave(&cs->ev_lock, flags); | 575 | spin_lock_irqsave(&cs->ev_lock, flags); |
593 | head = atomic_read(&cs->ev_head); | 576 | head = cs->ev_head; |
594 | tail = atomic_read(&cs->ev_tail); | 577 | tail = cs->ev_tail; |
595 | 578 | ||
596 | abort = 1; | 579 | abort = 1; |
597 | curarg = 0; | 580 | curarg = 0; |
598 | while (curarg < params) { | 581 | while (curarg < params) { |
599 | next = (tail + 1) % MAX_EVENTS; | 582 | next = (tail + 1) % MAX_EVENTS; |
600 | if (unlikely(next == head)) { | 583 | if (unlikely(next == head)) { |
601 | err("event queue full"); | 584 | dev_err(cs->dev, "event queue full\n"); |
602 | break; | 585 | break; |
603 | } | 586 | } |
604 | 587 | ||
@@ -619,8 +602,9 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
619 | 602 | ||
620 | if (!rt->response) { | 603 | if (!rt->response) { |
621 | event->type = RSP_UNKNOWN; | 604 | event->type = RSP_UNKNOWN; |
622 | warn("unknown modem response: %s", | 605 | dev_warn(cs->dev, |
623 | argv[curarg]); | 606 | "unknown modem response: %s\n", |
607 | argv[curarg]); | ||
624 | break; | 608 | break; |
625 | } | 609 | } |
626 | 610 | ||
@@ -636,7 +620,8 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
636 | break; | 620 | break; |
637 | case RT_RING: | 621 | case RT_RING: |
638 | if (!cid) { | 622 | if (!cid) { |
639 | err("received RING without CID!"); | 623 | dev_err(cs->dev, |
624 | "received RING without CID!\n"); | ||
640 | event->type = RSP_INVAL; | 625 | event->type = RSP_INVAL; |
641 | abort = 1; | 626 | abort = 1; |
642 | } else { | 627 | } else { |
@@ -664,27 +649,25 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
664 | event->parameter = ZSAU_DISCONNECT_REQ; | 649 | event->parameter = ZSAU_DISCONNECT_REQ; |
665 | else { | 650 | else { |
666 | event->parameter = ZSAU_UNKNOWN; | 651 | event->parameter = ZSAU_UNKNOWN; |
667 | warn("%s: unknown parameter %s after ZSAU", | 652 | dev_warn(cs->dev, |
668 | __func__, argv[curarg]); | 653 | "%s: unknown parameter %s after ZSAU\n", |
654 | __func__, argv[curarg]); | ||
669 | } | 655 | } |
670 | ++curarg; | 656 | ++curarg; |
671 | break; | 657 | break; |
672 | case RT_STRING: | 658 | case RT_STRING: |
673 | if (curarg < params) { | 659 | if (curarg < params) { |
674 | len = strlen(argv[curarg]) + 1; | 660 | event->ptr = kstrdup(argv[curarg], GFP_ATOMIC); |
675 | event->ptr = kmalloc(len, GFP_ATOMIC); | 661 | if (!event->ptr) |
676 | if (event->ptr) | 662 | dev_err(cs->dev, "out of memory\n"); |
677 | memcpy(event->ptr, argv[curarg], len); | ||
678 | else | ||
679 | err("no memory for string!"); | ||
680 | ++curarg; | 663 | ++curarg; |
681 | } | 664 | } |
682 | #ifdef CONFIG_GIGASET_DEBUG | 665 | #ifdef CONFIG_GIGASET_DEBUG |
683 | if (!event->ptr) | 666 | if (!event->ptr) |
684 | dbg(DEBUG_CMD, "string==NULL"); | 667 | gig_dbg(DEBUG_CMD, "string==NULL"); |
685 | else | 668 | else |
686 | dbg(DEBUG_CMD, | 669 | gig_dbg(DEBUG_CMD, "string==%s", |
687 | "string==%s", (char *) event->ptr); | 670 | (char *) event->ptr); |
688 | #endif | 671 | #endif |
689 | break; | 672 | break; |
690 | case RT_ZCAU: | 673 | case RT_ZCAU: |
@@ -694,7 +677,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
694 | j = isdn_gethex(argv[curarg + 1]); | 677 | j = isdn_gethex(argv[curarg + 1]); |
695 | if (i >= 0 && i < 256 && j >= 0 && j < 256) | 678 | if (i >= 0 && i < 256 && j >= 0 && j < 256) |
696 | event->parameter = (unsigned) i << 8 | 679 | event->parameter = (unsigned) i << 8 |
697 | | j; | 680 | | j; |
698 | curarg += 2; | 681 | curarg += 2; |
699 | } else | 682 | } else |
700 | curarg = params - 1; | 683 | curarg = params - 1; |
@@ -712,7 +695,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
712 | } else | 695 | } else |
713 | event->parameter = -1; | 696 | event->parameter = -1; |
714 | #ifdef CONFIG_GIGASET_DEBUG | 697 | #ifdef CONFIG_GIGASET_DEBUG |
715 | dbg(DEBUG_CMD, "parameter==%d", event->parameter); | 698 | gig_dbg(DEBUG_CMD, "parameter==%d", event->parameter); |
716 | #endif | 699 | #endif |
717 | break; | 700 | break; |
718 | } | 701 | } |
@@ -724,12 +707,13 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
724 | break; | 707 | break; |
725 | } | 708 | } |
726 | 709 | ||
727 | atomic_set(&cs->ev_tail, tail); | 710 | cs->ev_tail = tail; |
728 | spin_unlock_irqrestore(&cs->ev_lock, flags); | 711 | spin_unlock_irqrestore(&cs->ev_lock, flags); |
729 | 712 | ||
730 | if (curarg != params) | 713 | if (curarg != params) |
731 | dbg(DEBUG_ANY, "invalid number of processed parameters: %d/%d", | 714 | gig_dbg(DEBUG_ANY, |
732 | curarg, params); | 715 | "invalid number of processed parameters: %d/%d", |
716 | curarg, params); | ||
733 | } | 717 | } |
734 | EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); | 718 | EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); |
735 | 719 | ||
@@ -739,23 +723,19 @@ EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); | |||
739 | static void disconnect(struct at_state_t **at_state_p) | 723 | static void disconnect(struct at_state_t **at_state_p) |
740 | { | 724 | { |
741 | unsigned long flags; | 725 | unsigned long flags; |
742 | struct bc_state *bcs; | 726 | struct bc_state *bcs = (*at_state_p)->bcs; |
743 | struct cardstate *cs; | 727 | struct cardstate *cs = (*at_state_p)->cs; |
744 | 728 | ||
745 | IFNULLRET(at_state_p); | 729 | spin_lock_irqsave(&cs->lock, flags); |
746 | IFNULLRET(*at_state_p); | 730 | ++(*at_state_p)->seq_index; |
747 | bcs = (*at_state_p)->bcs; | ||
748 | cs = (*at_state_p)->cs; | ||
749 | IFNULLRET(cs); | ||
750 | |||
751 | new_index(&(*at_state_p)->seq_index, MAX_SEQ_INDEX); | ||
752 | 731 | ||
753 | /* revert to selected idle mode */ | 732 | /* revert to selected idle mode */ |
754 | if (!atomic_read(&cs->cidmode)) { | 733 | if (!cs->cidmode) { |
755 | cs->at_state.pending_commands |= PC_UMMODE; | 734 | cs->at_state.pending_commands |= PC_UMMODE; |
756 | atomic_set(&cs->commands_pending, 1); //FIXME | 735 | atomic_set(&cs->commands_pending, 1); //FIXME |
757 | dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 736 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
758 | } | 737 | } |
738 | spin_unlock_irqrestore(&cs->lock, flags); | ||
759 | 739 | ||
760 | if (bcs) { | 740 | if (bcs) { |
761 | /* B channel assigned: invoke hardware specific handler */ | 741 | /* B channel assigned: invoke hardware specific handler */ |
@@ -777,7 +757,7 @@ static void disconnect(struct at_state_t **at_state_p) | |||
777 | * The structure should be freed by calling disconnect() after use. | 757 | * The structure should be freed by calling disconnect() after use. |
778 | */ | 758 | */ |
779 | static inline struct at_state_t *get_free_channel(struct cardstate *cs, | 759 | static inline struct at_state_t *get_free_channel(struct cardstate *cs, |
780 | int cid) | 760 | int cid) |
781 | /* cids: >0: siemens-cid | 761 | /* cids: >0: siemens-cid |
782 | 0: without cid | 762 | 0: without cid |
783 | -1: no cid assigned yet | 763 | -1: no cid assigned yet |
@@ -826,7 +806,7 @@ static void init_failed(struct cardstate *cs, int mode) | |||
826 | static void schedule_init(struct cardstate *cs, int state) | 806 | static void schedule_init(struct cardstate *cs, int state) |
827 | { | 807 | { |
828 | if (cs->at_state.pending_commands & PC_INIT) { | 808 | if (cs->at_state.pending_commands & PC_INIT) { |
829 | dbg(DEBUG_CMD, "not scheduling PC_INIT again"); | 809 | gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again"); |
830 | return; | 810 | return; |
831 | } | 811 | } |
832 | atomic_set(&cs->mstate, state); | 812 | atomic_set(&cs->mstate, state); |
@@ -834,52 +814,56 @@ static void schedule_init(struct cardstate *cs, int state) | |||
834 | gigaset_block_channels(cs); | 814 | gigaset_block_channels(cs); |
835 | cs->at_state.pending_commands |= PC_INIT; | 815 | cs->at_state.pending_commands |= PC_INIT; |
836 | atomic_set(&cs->commands_pending, 1); | 816 | atomic_set(&cs->commands_pending, 1); |
837 | dbg(DEBUG_CMD, "Scheduling PC_INIT"); | 817 | gig_dbg(DEBUG_CMD, "Scheduling PC_INIT"); |
838 | } | 818 | } |
839 | 819 | ||
840 | /* Add "AT" to a command, add the cid, dle encode it, send the result to the hardware. */ | 820 | /* Add "AT" to a command, add the cid, dle encode it, send the result to the |
821 | hardware. */ | ||
841 | static void send_command(struct cardstate *cs, const char *cmd, int cid, | 822 | static void send_command(struct cardstate *cs, const char *cmd, int cid, |
842 | int dle, gfp_t kmallocflags) | 823 | int dle, gfp_t kmallocflags) |
843 | { | 824 | { |
844 | size_t cmdlen, buflen; | 825 | size_t cmdlen, buflen; |
845 | char *cmdpos, *cmdbuf, *cmdtail; | 826 | char *cmdpos, *cmdbuf, *cmdtail; |
846 | 827 | ||
847 | cmdlen = strlen(cmd); | 828 | cmdlen = strlen(cmd); |
848 | buflen = 11 + cmdlen; | 829 | buflen = 11 + cmdlen; |
830 | if (unlikely(buflen <= cmdlen)) { | ||
831 | dev_err(cs->dev, "integer overflow in buflen\n"); | ||
832 | return; | ||
833 | } | ||
849 | 834 | ||
850 | if (likely(buflen > cmdlen)) { | 835 | cmdbuf = kmalloc(buflen, kmallocflags); |
851 | cmdbuf = kmalloc(buflen, kmallocflags); | 836 | if (unlikely(!cmdbuf)) { |
852 | if (likely(cmdbuf != NULL)) { | 837 | dev_err(cs->dev, "out of memory\n"); |
853 | cmdpos = cmdbuf + 9; | 838 | return; |
854 | cmdtail = cmdpos + cmdlen; | 839 | } |
855 | memcpy(cmdpos, cmd, cmdlen); | ||
856 | |||
857 | if (cid > 0 && cid <= 65535) { | ||
858 | do { | ||
859 | *--cmdpos = '0' + cid % 10; | ||
860 | cid /= 10; | ||
861 | ++cmdlen; | ||
862 | } while (cid); | ||
863 | } | ||
864 | 840 | ||
865 | cmdlen += 2; | 841 | cmdpos = cmdbuf + 9; |
866 | *--cmdpos = 'T'; | 842 | cmdtail = cmdpos + cmdlen; |
867 | *--cmdpos = 'A'; | 843 | memcpy(cmdpos, cmd, cmdlen); |
868 | 844 | ||
869 | if (dle) { | 845 | if (cid > 0 && cid <= 65535) { |
870 | cmdlen += 4; | 846 | do { |
871 | *--cmdpos = '('; | 847 | *--cmdpos = '0' + cid % 10; |
872 | *--cmdpos = 0x10; | 848 | cid /= 10; |
873 | *cmdtail++ = 0x10; | 849 | ++cmdlen; |
874 | *cmdtail++ = ')'; | 850 | } while (cid); |
875 | } | 851 | } |
876 | 852 | ||
877 | cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL); | 853 | cmdlen += 2; |
878 | kfree(cmdbuf); | 854 | *--cmdpos = 'T'; |
879 | } else | 855 | *--cmdpos = 'A'; |
880 | err("no memory for command buffer"); | 856 | |
881 | } else | 857 | if (dle) { |
882 | err("overflow in buflen"); | 858 | cmdlen += 4; |
859 | *--cmdpos = '('; | ||
860 | *--cmdpos = 0x10; | ||
861 | *cmdtail++ = 0x10; | ||
862 | *cmdtail++ = ')'; | ||
863 | } | ||
864 | |||
865 | cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL); | ||
866 | kfree(cmdbuf); | ||
883 | } | 867 | } |
884 | 868 | ||
885 | static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) | 869 | static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) |
@@ -910,9 +894,6 @@ static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) | |||
910 | 894 | ||
911 | static void bchannel_down(struct bc_state *bcs) | 895 | static void bchannel_down(struct bc_state *bcs) |
912 | { | 896 | { |
913 | IFNULLRET(bcs); | ||
914 | IFNULLRET(bcs->cs); | ||
915 | |||
916 | if (bcs->chstate & CHS_B_UP) { | 897 | if (bcs->chstate & CHS_B_UP) { |
917 | bcs->chstate &= ~CHS_B_UP; | 898 | bcs->chstate &= ~CHS_B_UP; |
918 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); | 899 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); |
@@ -930,16 +911,15 @@ static void bchannel_down(struct bc_state *bcs) | |||
930 | 911 | ||
931 | static void bchannel_up(struct bc_state *bcs) | 912 | static void bchannel_up(struct bc_state *bcs) |
932 | { | 913 | { |
933 | IFNULLRET(bcs); | ||
934 | |||
935 | if (!(bcs->chstate & CHS_D_UP)) { | 914 | if (!(bcs->chstate & CHS_D_UP)) { |
936 | notice("%s: D channel not up", __func__); | 915 | dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__); |
937 | bcs->chstate |= CHS_D_UP; | 916 | bcs->chstate |= CHS_D_UP; |
938 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); | 917 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); |
939 | } | 918 | } |
940 | 919 | ||
941 | if (bcs->chstate & CHS_B_UP) { | 920 | if (bcs->chstate & CHS_B_UP) { |
942 | notice("%s: B channel already up", __func__); | 921 | dev_notice(bcs->cs->dev, "%s: B channel already up\n", |
922 | __func__); | ||
943 | return; | 923 | return; |
944 | } | 924 | } |
945 | 925 | ||
@@ -947,17 +927,21 @@ static void bchannel_up(struct bc_state *bcs) | |||
947 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); | 927 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); |
948 | } | 928 | } |
949 | 929 | ||
950 | static void start_dial(struct at_state_t *at_state, void *data, int seq_index) | 930 | static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index) |
951 | { | 931 | { |
952 | struct bc_state *bcs = at_state->bcs; | 932 | struct bc_state *bcs = at_state->bcs; |
953 | struct cardstate *cs = at_state->cs; | 933 | struct cardstate *cs = at_state->cs; |
954 | int retval; | 934 | int retval; |
935 | unsigned long flags; | ||
955 | 936 | ||
956 | bcs->chstate |= CHS_NOTIFY_LL; | 937 | bcs->chstate |= CHS_NOTIFY_LL; |
957 | //atomic_set(&bcs->status, BCS_INIT); | ||
958 | 938 | ||
959 | if (atomic_read(&at_state->seq_index) != seq_index) | 939 | spin_lock_irqsave(&cs->lock, flags); |
940 | if (at_state->seq_index != seq_index) { | ||
941 | spin_unlock_irqrestore(&cs->lock, flags); | ||
960 | goto error; | 942 | goto error; |
943 | } | ||
944 | spin_unlock_irqrestore(&cs->lock, flags); | ||
961 | 945 | ||
962 | retval = gigaset_isdn_setup_dial(at_state, data); | 946 | retval = gigaset_isdn_setup_dial(at_state, data); |
963 | if (retval != 0) | 947 | if (retval != 0) |
@@ -965,20 +949,14 @@ static void start_dial(struct at_state_t *at_state, void *data, int seq_index) | |||
965 | 949 | ||
966 | 950 | ||
967 | at_state->pending_commands |= PC_CID; | 951 | at_state->pending_commands |= PC_CID; |
968 | dbg(DEBUG_CMD, "Scheduling PC_CID"); | 952 | gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); |
969 | //#ifdef GIG_MAYINITONDIAL | 953 | atomic_set(&cs->commands_pending, 1); |
970 | // if (atomic_read(&cs->MState) == MS_UNKNOWN) { | ||
971 | // cs->at_state.pending_commands |= PC_INIT; | ||
972 | // dbg(DEBUG_CMD, "Scheduling PC_INIT"); | ||
973 | // } | ||
974 | //#endif | ||
975 | atomic_set(&cs->commands_pending, 1); //FIXME | ||
976 | return; | 954 | return; |
977 | 955 | ||
978 | error: | 956 | error: |
979 | at_state->pending_commands |= PC_NOCID; | 957 | at_state->pending_commands |= PC_NOCID; |
980 | dbg(DEBUG_CMD, "Scheduling PC_NOCID"); | 958 | gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); |
981 | atomic_set(&cs->commands_pending, 1); //FIXME | 959 | atomic_set(&cs->commands_pending, 1); |
982 | return; | 960 | return; |
983 | } | 961 | } |
984 | 962 | ||
@@ -991,13 +969,13 @@ static void start_accept(struct at_state_t *at_state) | |||
991 | 969 | ||
992 | if (retval == 0) { | 970 | if (retval == 0) { |
993 | at_state->pending_commands |= PC_ACCEPT; | 971 | at_state->pending_commands |= PC_ACCEPT; |
994 | dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); | 972 | gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); |
995 | atomic_set(&cs->commands_pending, 1); //FIXME | 973 | atomic_set(&cs->commands_pending, 1); |
996 | } else { | 974 | } else { |
997 | //FIXME | 975 | //FIXME |
998 | at_state->pending_commands |= PC_HUP; | 976 | at_state->pending_commands |= PC_HUP; |
999 | dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 977 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
1000 | atomic_set(&cs->commands_pending, 1); //FIXME | 978 | atomic_set(&cs->commands_pending, 1); |
1001 | } | 979 | } |
1002 | } | 980 | } |
1003 | 981 | ||
@@ -1008,9 +986,10 @@ static void do_start(struct cardstate *cs) | |||
1008 | if (atomic_read(&cs->mstate) != MS_LOCKED) | 986 | if (atomic_read(&cs->mstate) != MS_LOCKED) |
1009 | schedule_init(cs, MS_INIT); | 987 | schedule_init(cs, MS_INIT); |
1010 | 988 | ||
989 | cs->isdn_up = 1; | ||
1011 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); | 990 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); |
1012 | // FIXME: not in locked mode | 991 | // FIXME: not in locked mode |
1013 | // FIXME 2: only after init sequence | 992 | // FIXME 2: only after init sequence |
1014 | 993 | ||
1015 | cs->waiting = 0; | 994 | cs->waiting = 0; |
1016 | wake_up(&cs->waitqueue); | 995 | wake_up(&cs->waitqueue); |
@@ -1023,6 +1002,12 @@ static void finish_shutdown(struct cardstate *cs) | |||
1023 | atomic_set(&cs->mode, M_UNKNOWN); | 1002 | atomic_set(&cs->mode, M_UNKNOWN); |
1024 | } | 1003 | } |
1025 | 1004 | ||
1005 | /* Tell the LL that the device is not available .. */ | ||
1006 | if (cs->isdn_up) { | ||
1007 | cs->isdn_up = 0; | ||
1008 | gigaset_i4l_cmd(cs, ISDN_STAT_STOP); | ||
1009 | } | ||
1010 | |||
1026 | /* The rest is done by cleanup_cs () in user mode. */ | 1011 | /* The rest is done by cleanup_cs () in user mode. */ |
1027 | 1012 | ||
1028 | cs->cmd_result = -ENODEV; | 1013 | cs->cmd_result = -ENODEV; |
@@ -1037,15 +1022,20 @@ static void do_shutdown(struct cardstate *cs) | |||
1037 | if (atomic_read(&cs->mstate) == MS_READY) { | 1022 | if (atomic_read(&cs->mstate) == MS_READY) { |
1038 | atomic_set(&cs->mstate, MS_SHUTDOWN); | 1023 | atomic_set(&cs->mstate, MS_SHUTDOWN); |
1039 | cs->at_state.pending_commands |= PC_SHUTDOWN; | 1024 | cs->at_state.pending_commands |= PC_SHUTDOWN; |
1040 | atomic_set(&cs->commands_pending, 1); //FIXME | 1025 | atomic_set(&cs->commands_pending, 1); |
1041 | dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); //FIXME | 1026 | gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); |
1042 | //gigaset_schedule_event(cs); //FIXME | ||
1043 | } else | 1027 | } else |
1044 | finish_shutdown(cs); | 1028 | finish_shutdown(cs); |
1045 | } | 1029 | } |
1046 | 1030 | ||
1047 | static void do_stop(struct cardstate *cs) | 1031 | static void do_stop(struct cardstate *cs) |
1048 | { | 1032 | { |
1033 | unsigned long flags; | ||
1034 | |||
1035 | spin_lock_irqsave(&cs->lock, flags); | ||
1036 | cs->connected = 0; | ||
1037 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1038 | |||
1049 | do_shutdown(cs); | 1039 | do_shutdown(cs); |
1050 | } | 1040 | } |
1051 | 1041 | ||
@@ -1069,9 +1059,11 @@ static int reinit_and_retry(struct cardstate *cs, int channel) | |||
1069 | return 0; | 1059 | return 0; |
1070 | 1060 | ||
1071 | if (channel < 0) | 1061 | if (channel < 0) |
1072 | warn("Could not enter cid mode. Reinit device and try again."); | 1062 | dev_warn(cs->dev, |
1063 | "Could not enter cid mode. Reinit device and try again.\n"); | ||
1073 | else { | 1064 | else { |
1074 | warn("Could not get a call id. Reinit device and try again."); | 1065 | dev_warn(cs->dev, |
1066 | "Could not get a call id. Reinit device and try again.\n"); | ||
1075 | cs->bcs[channel].at_state.pending_commands |= PC_CID; | 1067 | cs->bcs[channel].at_state.pending_commands |= PC_CID; |
1076 | } | 1068 | } |
1077 | schedule_init(cs, MS_INIT); | 1069 | schedule_init(cs, MS_INIT); |
@@ -1079,7 +1071,7 @@ static int reinit_and_retry(struct cardstate *cs, int channel) | |||
1079 | } | 1071 | } |
1080 | 1072 | ||
1081 | static int at_state_invalid(struct cardstate *cs, | 1073 | static int at_state_invalid(struct cardstate *cs, |
1082 | struct at_state_t *test_ptr) | 1074 | struct at_state_t *test_ptr) |
1083 | { | 1075 | { |
1084 | unsigned long flags; | 1076 | unsigned long flags; |
1085 | unsigned channel; | 1077 | unsigned channel; |
@@ -1116,7 +1108,7 @@ static void handle_icall(struct cardstate *cs, struct bc_state *bcs, | |||
1116 | case ICALL_ACCEPT: | 1108 | case ICALL_ACCEPT: |
1117 | break; | 1109 | break; |
1118 | default: | 1110 | default: |
1119 | err("internal error: disposition=%d", retval); | 1111 | dev_err(cs->dev, "internal error: disposition=%d\n", retval); |
1120 | /* --v-- fall through --v-- */ | 1112 | /* --v-- fall through --v-- */ |
1121 | case ICALL_IGNORE: | 1113 | case ICALL_IGNORE: |
1122 | case ICALL_REJECT: | 1114 | case ICALL_REJECT: |
@@ -1160,7 +1152,6 @@ static int do_lock(struct cardstate *cs) | |||
1160 | mode = atomic_read(&cs->mode); | 1152 | mode = atomic_read(&cs->mode); |
1161 | atomic_set(&cs->mstate, MS_LOCKED); | 1153 | atomic_set(&cs->mstate, MS_LOCKED); |
1162 | atomic_set(&cs->mode, M_UNKNOWN); | 1154 | atomic_set(&cs->mode, M_UNKNOWN); |
1163 | //FIXME reset card state / at states / bcs states | ||
1164 | 1155 | ||
1165 | return mode; | 1156 | return mode; |
1166 | } | 1157 | } |
@@ -1173,8 +1164,7 @@ static int do_unlock(struct cardstate *cs) | |||
1173 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 1164 | atomic_set(&cs->mstate, MS_UNINITIALIZED); |
1174 | atomic_set(&cs->mode, M_UNKNOWN); | 1165 | atomic_set(&cs->mode, M_UNKNOWN); |
1175 | gigaset_free_channels(cs); | 1166 | gigaset_free_channels(cs); |
1176 | //FIXME reset card state / at states / bcs states | 1167 | if (cs->connected) |
1177 | if (atomic_read(&cs->connected)) | ||
1178 | schedule_init(cs, MS_INIT); | 1168 | schedule_init(cs, MS_INIT); |
1179 | 1169 | ||
1180 | return 0; | 1170 | return 0; |
@@ -1203,21 +1193,23 @@ static void do_action(int action, struct cardstate *cs, | |||
1203 | at_state->waiting = 1; | 1193 | at_state->waiting = 1; |
1204 | break; | 1194 | break; |
1205 | case ACT_INIT: | 1195 | case ACT_INIT: |
1206 | //FIXME setup everything | ||
1207 | cs->at_state.pending_commands &= ~PC_INIT; | 1196 | cs->at_state.pending_commands &= ~PC_INIT; |
1208 | cs->cur_at_seq = SEQ_NONE; | 1197 | cs->cur_at_seq = SEQ_NONE; |
1209 | atomic_set(&cs->mode, M_UNIMODEM); | 1198 | atomic_set(&cs->mode, M_UNIMODEM); |
1210 | if (!atomic_read(&cs->cidmode)) { | 1199 | spin_lock_irqsave(&cs->lock, flags); |
1200 | if (!cs->cidmode) { | ||
1201 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1211 | gigaset_free_channels(cs); | 1202 | gigaset_free_channels(cs); |
1212 | atomic_set(&cs->mstate, MS_READY); | 1203 | atomic_set(&cs->mstate, MS_READY); |
1213 | break; | 1204 | break; |
1214 | } | 1205 | } |
1206 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1215 | cs->at_state.pending_commands |= PC_CIDMODE; | 1207 | cs->at_state.pending_commands |= PC_CIDMODE; |
1216 | atomic_set(&cs->commands_pending, 1); //FIXME | 1208 | atomic_set(&cs->commands_pending, 1); |
1217 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1209 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1218 | break; | 1210 | break; |
1219 | case ACT_FAILINIT: | 1211 | case ACT_FAILINIT: |
1220 | warn("Could not initialize the device."); | 1212 | dev_warn(cs->dev, "Could not initialize the device.\n"); |
1221 | cs->dle = 0; | 1213 | cs->dle = 0; |
1222 | init_failed(cs, M_UNKNOWN); | 1214 | init_failed(cs, M_UNKNOWN); |
1223 | cs->cur_at_seq = SEQ_NONE; | 1215 | cs->cur_at_seq = SEQ_NONE; |
@@ -1273,8 +1265,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1273 | /* get fresh AT state structure for new CID */ | 1265 | /* get fresh AT state structure for new CID */ |
1274 | at_state2 = get_free_channel(cs, ev->parameter); | 1266 | at_state2 = get_free_channel(cs, ev->parameter); |
1275 | if (!at_state2) { | 1267 | if (!at_state2) { |
1276 | warn("RING ignored: " | 1268 | dev_warn(cs->dev, |
1277 | "could not allocate channel structure"); | 1269 | "RING ignored: could not allocate channel structure\n"); |
1278 | break; | 1270 | break; |
1279 | } | 1271 | } |
1280 | 1272 | ||
@@ -1302,7 +1294,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1302 | at_state = *p_at_state; | 1294 | at_state = *p_at_state; |
1303 | break; | 1295 | break; |
1304 | case ACT_FAILSDOWN: | 1296 | case ACT_FAILSDOWN: |
1305 | warn("Could not shut down the device."); | 1297 | dev_warn(cs->dev, "Could not shut down the device.\n"); |
1306 | /* fall through */ | 1298 | /* fall through */ |
1307 | case ACT_FAKESDOWN: | 1299 | case ACT_FAKESDOWN: |
1308 | case ACT_SDOWN: | 1300 | case ACT_SDOWN: |
@@ -1355,7 +1347,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1355 | break; | 1347 | break; |
1356 | case ACT_ABORTHUP: | 1348 | case ACT_ABORTHUP: |
1357 | cs->cur_at_seq = SEQ_NONE; | 1349 | cs->cur_at_seq = SEQ_NONE; |
1358 | warn("Could not hang up."); | 1350 | dev_warn(cs->dev, "Could not hang up.\n"); |
1359 | at_state->cid = -1; | 1351 | at_state->cid = -1; |
1360 | if (bcs && cs->onechannel) | 1352 | if (bcs && cs->onechannel) |
1361 | at_state->pending_commands |= PC_DLE0; | 1353 | at_state->pending_commands |= PC_DLE0; |
@@ -1367,14 +1359,15 @@ static void do_action(int action, struct cardstate *cs, | |||
1367 | break; | 1359 | break; |
1368 | case ACT_FAILDLE0: | 1360 | case ACT_FAILDLE0: |
1369 | cs->cur_at_seq = SEQ_NONE; | 1361 | cs->cur_at_seq = SEQ_NONE; |
1370 | warn("Could not leave DLE mode."); | 1362 | dev_warn(cs->dev, "Could not leave DLE mode.\n"); |
1371 | at_state2 = &cs->bcs[cs->curchannel].at_state; | 1363 | at_state2 = &cs->bcs[cs->curchannel].at_state; |
1372 | disconnect(&at_state2); | 1364 | disconnect(&at_state2); |
1373 | schedule_init(cs, MS_RECOVER); | 1365 | schedule_init(cs, MS_RECOVER); |
1374 | break; | 1366 | break; |
1375 | case ACT_FAILDLE1: | 1367 | case ACT_FAILDLE1: |
1376 | cs->cur_at_seq = SEQ_NONE; | 1368 | cs->cur_at_seq = SEQ_NONE; |
1377 | warn("Could not enter DLE mode. Try to hang up."); | 1369 | dev_warn(cs->dev, |
1370 | "Could not enter DLE mode. Trying to hang up.\n"); | ||
1378 | channel = cs->curchannel; | 1371 | channel = cs->curchannel; |
1379 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; | 1372 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; |
1380 | atomic_set(&cs->commands_pending, 1); | 1373 | atomic_set(&cs->commands_pending, 1); |
@@ -1395,7 +1388,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1395 | cs->cur_at_seq = SEQ_NONE; | 1388 | cs->cur_at_seq = SEQ_NONE; |
1396 | channel = cs->curchannel; | 1389 | channel = cs->curchannel; |
1397 | if (!reinit_and_retry(cs, channel)) { | 1390 | if (!reinit_and_retry(cs, channel)) { |
1398 | warn("Could not get a call id. Dialing not possible"); | 1391 | dev_warn(cs->dev, |
1392 | "Could not get a call ID. Cannot dial.\n"); | ||
1399 | at_state2 = &cs->bcs[channel].at_state; | 1393 | at_state2 = &cs->bcs[channel].at_state; |
1400 | disconnect(&at_state2); | 1394 | disconnect(&at_state2); |
1401 | } | 1395 | } |
@@ -1428,7 +1422,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1428 | at_state->pending_commands |= PC_HUP; | 1422 | at_state->pending_commands |= PC_HUP; |
1429 | atomic_set(&cs->commands_pending, 1); | 1423 | atomic_set(&cs->commands_pending, 1); |
1430 | break; | 1424 | break; |
1431 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... are not handled properly any more */ | 1425 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... |
1426 | are not handled properly anymore */ | ||
1432 | at_state->getstring = 1; | 1427 | at_state->getstring = 1; |
1433 | break; | 1428 | break; |
1434 | case ACT_SETVER: | 1429 | case ACT_SETVER: |
@@ -1469,16 +1464,16 @@ static void do_action(int action, struct cardstate *cs, | |||
1469 | case ACT_GOTVER: | 1464 | case ACT_GOTVER: |
1470 | if (cs->gotfwver == 0) { | 1465 | if (cs->gotfwver == 0) { |
1471 | cs->gotfwver = 1; | 1466 | cs->gotfwver = 1; |
1472 | dbg(DEBUG_ANY, | 1467 | gig_dbg(DEBUG_ANY, |
1473 | "firmware version %02d.%03d.%02d.%02d", | 1468 | "firmware version %02d.%03d.%02d.%02d", |
1474 | cs->fwver[0], cs->fwver[1], | 1469 | cs->fwver[0], cs->fwver[1], |
1475 | cs->fwver[2], cs->fwver[3]); | 1470 | cs->fwver[2], cs->fwver[3]); |
1476 | break; | 1471 | break; |
1477 | } | 1472 | } |
1478 | /* fall through */ | 1473 | /* fall through */ |
1479 | case ACT_FAILVER: | 1474 | case ACT_FAILVER: |
1480 | cs->gotfwver = -1; | 1475 | cs->gotfwver = -1; |
1481 | err("could not read firmware version."); | 1476 | dev_err(cs->dev, "could not read firmware version.\n"); |
1482 | break; | 1477 | break; |
1483 | #ifdef CONFIG_GIGASET_DEBUG | 1478 | #ifdef CONFIG_GIGASET_DEBUG |
1484 | case ACT_ERROR: | 1479 | case ACT_ERROR: |
@@ -1496,16 +1491,16 @@ static void do_action(int action, struct cardstate *cs, | |||
1496 | break; | 1491 | break; |
1497 | #endif | 1492 | #endif |
1498 | case ACT_DEBUG: | 1493 | case ACT_DEBUG: |
1499 | dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", | 1494 | gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", |
1500 | __func__, ev->type, at_state->ConState); | 1495 | __func__, ev->type, at_state->ConState); |
1501 | break; | 1496 | break; |
1502 | case ACT_WARN: | 1497 | case ACT_WARN: |
1503 | warn("%s: resp_code %d in ConState %d!", | 1498 | dev_warn(cs->dev, "%s: resp_code %d in ConState %d!\n", |
1504 | __func__, ev->type, at_state->ConState); | 1499 | __func__, ev->type, at_state->ConState); |
1505 | break; | 1500 | break; |
1506 | case ACT_ZCAU: | 1501 | case ACT_ZCAU: |
1507 | warn("cause code %04x in connection state %d.", | 1502 | dev_warn(cs->dev, "cause code %04x in connection state %d.\n", |
1508 | ev->parameter, at_state->ConState); | 1503 | ev->parameter, at_state->ConState); |
1509 | break; | 1504 | break; |
1510 | 1505 | ||
1511 | /* events from the LL */ | 1506 | /* events from the LL */ |
@@ -1516,14 +1511,14 @@ static void do_action(int action, struct cardstate *cs, | |||
1516 | start_accept(at_state); | 1511 | start_accept(at_state); |
1517 | break; | 1512 | break; |
1518 | case ACT_PROTO_L2: | 1513 | case ACT_PROTO_L2: |
1519 | dbg(DEBUG_CMD, | 1514 | gig_dbg(DEBUG_CMD, "set protocol to %u", |
1520 | "set protocol to %u", (unsigned) ev->parameter); | 1515 | (unsigned) ev->parameter); |
1521 | at_state->bcs->proto2 = ev->parameter; | 1516 | at_state->bcs->proto2 = ev->parameter; |
1522 | break; | 1517 | break; |
1523 | case ACT_HUP: | 1518 | case ACT_HUP: |
1524 | at_state->pending_commands |= PC_HUP; | 1519 | at_state->pending_commands |= PC_HUP; |
1525 | atomic_set(&cs->commands_pending, 1); //FIXME | 1520 | atomic_set(&cs->commands_pending, 1); |
1526 | dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 1521 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
1527 | break; | 1522 | break; |
1528 | 1523 | ||
1529 | /* hotplug events */ | 1524 | /* hotplug events */ |
@@ -1555,17 +1550,19 @@ static void do_action(int action, struct cardstate *cs, | |||
1555 | 1550 | ||
1556 | /* events from the proc file system */ // FIXME without ACT_xxxx? | 1551 | /* events from the proc file system */ // FIXME without ACT_xxxx? |
1557 | case ACT_PROC_CIDMODE: | 1552 | case ACT_PROC_CIDMODE: |
1558 | if (ev->parameter != atomic_read(&cs->cidmode)) { | 1553 | spin_lock_irqsave(&cs->lock, flags); |
1559 | atomic_set(&cs->cidmode, ev->parameter); | 1554 | if (ev->parameter != cs->cidmode) { |
1555 | cs->cidmode = ev->parameter; | ||
1560 | if (ev->parameter) { | 1556 | if (ev->parameter) { |
1561 | cs->at_state.pending_commands |= PC_CIDMODE; | 1557 | cs->at_state.pending_commands |= PC_CIDMODE; |
1562 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1558 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1563 | } else { | 1559 | } else { |
1564 | cs->at_state.pending_commands |= PC_UMMODE; | 1560 | cs->at_state.pending_commands |= PC_UMMODE; |
1565 | dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 1561 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
1566 | } | 1562 | } |
1567 | atomic_set(&cs->commands_pending, 1); | 1563 | atomic_set(&cs->commands_pending, 1); |
1568 | } | 1564 | } |
1565 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1569 | cs->waiting = 0; | 1566 | cs->waiting = 0; |
1570 | wake_up(&cs->waitqueue); | 1567 | wake_up(&cs->waitqueue); |
1571 | break; | 1568 | break; |
@@ -1590,7 +1587,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1590 | *p_resp_code = RSP_NULL; | 1587 | *p_resp_code = RSP_NULL; |
1591 | } | 1588 | } |
1592 | } else | 1589 | } else |
1593 | err("%s: action==%d!", __func__, action); | 1590 | dev_err(cs->dev, "%s: action==%d!\n", __func__, action); |
1594 | } | 1591 | } |
1595 | } | 1592 | } |
1596 | 1593 | ||
@@ -1609,47 +1606,46 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1609 | int curact; | 1606 | int curact; |
1610 | unsigned long flags; | 1607 | unsigned long flags; |
1611 | 1608 | ||
1612 | IFNULLRET(cs); | ||
1613 | IFNULLRET(ev); | ||
1614 | |||
1615 | if (ev->cid >= 0) { | 1609 | if (ev->cid >= 0) { |
1616 | at_state = at_state_from_cid(cs, ev->cid); | 1610 | at_state = at_state_from_cid(cs, ev->cid); |
1617 | if (!at_state) { | 1611 | if (!at_state) { |
1618 | gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, | 1612 | gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, |
1619 | NULL, 0, NULL); | 1613 | NULL, 0, NULL); |
1620 | return; | 1614 | return; |
1621 | } | 1615 | } |
1622 | } else { | 1616 | } else { |
1623 | at_state = ev->at_state; | 1617 | at_state = ev->at_state; |
1624 | if (at_state_invalid(cs, at_state)) { | 1618 | if (at_state_invalid(cs, at_state)) { |
1625 | dbg(DEBUG_ANY, | 1619 | gig_dbg(DEBUG_ANY, "event for invalid at_state %p", |
1626 | "event for invalid at_state %p", at_state); | 1620 | at_state); |
1627 | return; | 1621 | return; |
1628 | } | 1622 | } |
1629 | } | 1623 | } |
1630 | 1624 | ||
1631 | dbg(DEBUG_CMD, | 1625 | gig_dbg(DEBUG_CMD, "connection state %d, event %d", |
1632 | "connection state %d, event %d", at_state->ConState, ev->type); | 1626 | at_state->ConState, ev->type); |
1633 | 1627 | ||
1634 | bcs = at_state->bcs; | 1628 | bcs = at_state->bcs; |
1635 | sendcid = at_state->cid; | 1629 | sendcid = at_state->cid; |
1636 | 1630 | ||
1637 | /* Setting the pointer to the dial array */ | 1631 | /* Setting the pointer to the dial array */ |
1638 | rep = at_state->replystruct; | 1632 | rep = at_state->replystruct; |
1639 | IFNULLRET(rep); | ||
1640 | 1633 | ||
1634 | spin_lock_irqsave(&cs->lock, flags); | ||
1641 | if (ev->type == EV_TIMEOUT) { | 1635 | if (ev->type == EV_TIMEOUT) { |
1642 | if (ev->parameter != atomic_read(&at_state->timer_index) | 1636 | if (ev->parameter != at_state->timer_index |
1643 | || !at_state->timer_active) { | 1637 | || !at_state->timer_active) { |
1644 | ev->type = RSP_NONE; /* old timeout */ | 1638 | ev->type = RSP_NONE; /* old timeout */ |
1645 | dbg(DEBUG_ANY, "old timeout"); | 1639 | gig_dbg(DEBUG_ANY, "old timeout"); |
1646 | } else if (!at_state->waiting) | 1640 | } else if (!at_state->waiting) |
1647 | dbg(DEBUG_ANY, "timeout occured"); | 1641 | gig_dbg(DEBUG_ANY, "timeout occurred"); |
1648 | else | 1642 | else |
1649 | dbg(DEBUG_ANY, "stopped waiting"); | 1643 | gig_dbg(DEBUG_ANY, "stopped waiting"); |
1650 | } | 1644 | } |
1645 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1651 | 1646 | ||
1652 | /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] or at_state->str_var[STR_XXXX], set it */ | 1647 | /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] |
1648 | or at_state->str_var[STR_XXXX], set it */ | ||
1653 | if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) { | 1649 | if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) { |
1654 | index = ev->type - RSP_VAR; | 1650 | index = ev->type - RSP_VAR; |
1655 | at_state->int_var[index] = ev->parameter; | 1651 | at_state->int_var[index] = ev->parameter; |
@@ -1657,20 +1653,22 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1657 | index = ev->type - RSP_STR; | 1653 | index = ev->type - RSP_STR; |
1658 | kfree(at_state->str_var[index]); | 1654 | kfree(at_state->str_var[index]); |
1659 | at_state->str_var[index] = ev->ptr; | 1655 | at_state->str_var[index] = ev->ptr; |
1660 | ev->ptr = NULL; /* prevent process_events() from deallocating ptr */ | 1656 | ev->ptr = NULL; /* prevent process_events() from |
1657 | deallocating ptr */ | ||
1661 | } | 1658 | } |
1662 | 1659 | ||
1663 | if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING) | 1660 | if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING) |
1664 | at_state->getstring = 0; | 1661 | at_state->getstring = 0; |
1665 | 1662 | ||
1666 | /* Search row in dial array which matches modem response and current constate */ | 1663 | /* Search row in dial array which matches modem response and current |
1664 | constate */ | ||
1667 | for (;; rep++) { | 1665 | for (;; rep++) { |
1668 | rcode = rep->resp_code; | 1666 | rcode = rep->resp_code; |
1669 | /* dbg (DEBUG_ANY, "rcode %d", rcode); */ | ||
1670 | if (rcode == RSP_LAST) { | 1667 | if (rcode == RSP_LAST) { |
1671 | /* found nothing...*/ | 1668 | /* found nothing...*/ |
1672 | warn("%s: rcode=RSP_LAST: resp_code %d in ConState %d!", | 1669 | dev_warn(cs->dev, "%s: rcode=RSP_LAST: " |
1673 | __func__, ev->type, at_state->ConState); | 1670 | "resp_code %d in ConState %d!\n", |
1671 | __func__, ev->type, at_state->ConState); | ||
1674 | return; | 1672 | return; |
1675 | } | 1673 | } |
1676 | if ((rcode == RSP_ANY || rcode == ev->type) | 1674 | if ((rcode == RSP_ANY || rcode == ev->type) |
@@ -1706,14 +1704,14 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1706 | } else { | 1704 | } else { |
1707 | /* Send command to modem if not NULL... */ | 1705 | /* Send command to modem if not NULL... */ |
1708 | if (p_command/*rep->command*/) { | 1706 | if (p_command/*rep->command*/) { |
1709 | if (atomic_read(&cs->connected)) | 1707 | if (cs->connected) |
1710 | send_command(cs, p_command, | 1708 | send_command(cs, p_command, |
1711 | sendcid, cs->dle, | 1709 | sendcid, cs->dle, |
1712 | GFP_ATOMIC); | 1710 | GFP_ATOMIC); |
1713 | else | 1711 | else |
1714 | gigaset_add_event(cs, at_state, | 1712 | gigaset_add_event(cs, at_state, |
1715 | RSP_NODEV, | 1713 | RSP_NODEV, |
1716 | NULL, 0, NULL); | 1714 | NULL, 0, NULL); |
1717 | } | 1715 | } |
1718 | 1716 | ||
1719 | spin_lock_irqsave(&cs->lock, flags); | 1717 | spin_lock_irqsave(&cs->lock, flags); |
@@ -1723,8 +1721,7 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1723 | } else if (rep->timeout > 0) { /* new timeout */ | 1721 | } else if (rep->timeout > 0) { /* new timeout */ |
1724 | at_state->timer_expires = rep->timeout * 10; | 1722 | at_state->timer_expires = rep->timeout * 10; |
1725 | at_state->timer_active = 1; | 1723 | at_state->timer_active = 1; |
1726 | new_index(&at_state->timer_index, | 1724 | ++at_state->timer_index; |
1727 | MAX_TIMER_INDEX); | ||
1728 | } | 1725 | } |
1729 | spin_unlock_irqrestore(&cs->lock, flags); | 1726 | spin_unlock_irqrestore(&cs->lock, flags); |
1730 | } | 1727 | } |
@@ -1744,17 +1741,16 @@ static void process_command_flags(struct cardstate *cs) | |||
1744 | struct bc_state *bcs; | 1741 | struct bc_state *bcs; |
1745 | int i; | 1742 | int i; |
1746 | int sequence; | 1743 | int sequence; |
1747 | 1744 | unsigned long flags; | |
1748 | IFNULLRET(cs); | ||
1749 | 1745 | ||
1750 | atomic_set(&cs->commands_pending, 0); | 1746 | atomic_set(&cs->commands_pending, 0); |
1751 | 1747 | ||
1752 | if (cs->cur_at_seq) { | 1748 | if (cs->cur_at_seq) { |
1753 | dbg(DEBUG_CMD, "not searching scheduled commands: busy"); | 1749 | gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy"); |
1754 | return; | 1750 | return; |
1755 | } | 1751 | } |
1756 | 1752 | ||
1757 | dbg(DEBUG_CMD, "searching scheduled commands"); | 1753 | gig_dbg(DEBUG_CMD, "searching scheduled commands"); |
1758 | 1754 | ||
1759 | sequence = SEQ_NONE; | 1755 | sequence = SEQ_NONE; |
1760 | 1756 | ||
@@ -1795,8 +1791,9 @@ static void process_command_flags(struct cardstate *cs) | |||
1795 | } | 1791 | } |
1796 | 1792 | ||
1797 | /* only switch back to unimodem mode, if no commands are pending and no channels are up */ | 1793 | /* only switch back to unimodem mode, if no commands are pending and no channels are up */ |
1794 | spin_lock_irqsave(&cs->lock, flags); | ||
1798 | if (cs->at_state.pending_commands == PC_UMMODE | 1795 | if (cs->at_state.pending_commands == PC_UMMODE |
1799 | && !atomic_read(&cs->cidmode) | 1796 | && !cs->cidmode |
1800 | && list_empty(&cs->temp_at_states) | 1797 | && list_empty(&cs->temp_at_states) |
1801 | && atomic_read(&cs->mode) == M_CID) { | 1798 | && atomic_read(&cs->mode) == M_CID) { |
1802 | sequence = SEQ_UMMODE; | 1799 | sequence = SEQ_UMMODE; |
@@ -1810,6 +1807,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1810 | } | 1807 | } |
1811 | } | 1808 | } |
1812 | } | 1809 | } |
1810 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1813 | cs->at_state.pending_commands &= ~PC_UMMODE; | 1811 | cs->at_state.pending_commands &= ~PC_UMMODE; |
1814 | if (sequence != SEQ_NONE) { | 1812 | if (sequence != SEQ_NONE) { |
1815 | schedule_sequence(cs, at_state, sequence); | 1813 | schedule_sequence(cs, at_state, sequence); |
@@ -1865,11 +1863,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1865 | if (cs->at_state.pending_commands & PC_CIDMODE) { | 1863 | if (cs->at_state.pending_commands & PC_CIDMODE) { |
1866 | cs->at_state.pending_commands &= ~PC_CIDMODE; | 1864 | cs->at_state.pending_commands &= ~PC_CIDMODE; |
1867 | if (atomic_read(&cs->mode) == M_UNIMODEM) { | 1865 | if (atomic_read(&cs->mode) == M_UNIMODEM) { |
1868 | #if 0 | ||
1869 | cs->retry_count = 2; | ||
1870 | #else | ||
1871 | cs->retry_count = 1; | 1866 | cs->retry_count = 1; |
1872 | #endif | ||
1873 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); | 1867 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); |
1874 | return; | 1868 | return; |
1875 | } | 1869 | } |
@@ -1897,7 +1891,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1897 | switch (atomic_read(&cs->mode)) { | 1891 | switch (atomic_read(&cs->mode)) { |
1898 | case M_UNIMODEM: | 1892 | case M_UNIMODEM: |
1899 | cs->at_state.pending_commands |= PC_CIDMODE; | 1893 | cs->at_state.pending_commands |= PC_CIDMODE; |
1900 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1894 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1901 | atomic_set(&cs->commands_pending, 1); | 1895 | atomic_set(&cs->commands_pending, 1); |
1902 | return; | 1896 | return; |
1903 | #ifdef GIG_MAYINITONDIAL | 1897 | #ifdef GIG_MAYINITONDIAL |
@@ -1926,18 +1920,21 @@ static void process_events(struct cardstate *cs) | |||
1926 | int i; | 1920 | int i; |
1927 | int check_flags = 0; | 1921 | int check_flags = 0; |
1928 | int was_busy; | 1922 | int was_busy; |
1923 | unsigned long flags; | ||
1929 | 1924 | ||
1930 | /* no locking needed (only one reader) */ | 1925 | spin_lock_irqsave(&cs->ev_lock, flags); |
1931 | head = atomic_read(&cs->ev_head); | 1926 | head = cs->ev_head; |
1932 | 1927 | ||
1933 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { | 1928 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { |
1934 | tail = atomic_read(&cs->ev_tail); | 1929 | tail = cs->ev_tail; |
1935 | if (tail == head) { | 1930 | if (tail == head) { |
1936 | if (!check_flags && !atomic_read(&cs->commands_pending)) | 1931 | if (!check_flags && !atomic_read(&cs->commands_pending)) |
1937 | break; | 1932 | break; |
1938 | check_flags = 0; | 1933 | check_flags = 0; |
1934 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1939 | process_command_flags(cs); | 1935 | process_command_flags(cs); |
1940 | tail = atomic_read(&cs->ev_tail); | 1936 | spin_lock_irqsave(&cs->ev_lock, flags); |
1937 | tail = cs->ev_tail; | ||
1941 | if (tail == head) { | 1938 | if (tail == head) { |
1942 | if (!atomic_read(&cs->commands_pending)) | 1939 | if (!atomic_read(&cs->commands_pending)) |
1943 | break; | 1940 | break; |
@@ -1947,18 +1944,23 @@ static void process_events(struct cardstate *cs) | |||
1947 | 1944 | ||
1948 | ev = cs->events + head; | 1945 | ev = cs->events + head; |
1949 | was_busy = cs->cur_at_seq != SEQ_NONE; | 1946 | was_busy = cs->cur_at_seq != SEQ_NONE; |
1947 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1950 | process_event(cs, ev); | 1948 | process_event(cs, ev); |
1949 | spin_lock_irqsave(&cs->ev_lock, flags); | ||
1951 | kfree(ev->ptr); | 1950 | kfree(ev->ptr); |
1952 | ev->ptr = NULL; | 1951 | ev->ptr = NULL; |
1953 | if (was_busy && cs->cur_at_seq == SEQ_NONE) | 1952 | if (was_busy && cs->cur_at_seq == SEQ_NONE) |
1954 | check_flags = 1; | 1953 | check_flags = 1; |
1955 | 1954 | ||
1956 | head = (head + 1) % MAX_EVENTS; | 1955 | head = (head + 1) % MAX_EVENTS; |
1957 | atomic_set(&cs->ev_head, head); | 1956 | cs->ev_head = head; |
1958 | } | 1957 | } |
1959 | 1958 | ||
1959 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1960 | |||
1960 | if (i == 2 * MAX_EVENTS) { | 1961 | if (i == 2 * MAX_EVENTS) { |
1961 | err("infinite loop in process_events; aborting."); | 1962 | dev_err(cs->dev, |
1963 | "infinite loop in process_events; aborting.\n"); | ||
1962 | } | 1964 | } |
1963 | } | 1965 | } |
1964 | 1966 | ||
@@ -1970,12 +1972,9 @@ void gigaset_handle_event(unsigned long data) | |||
1970 | { | 1972 | { |
1971 | struct cardstate *cs = (struct cardstate *) data; | 1973 | struct cardstate *cs = (struct cardstate *) data; |
1972 | 1974 | ||
1973 | IFNULLRET(cs); | ||
1974 | IFNULLRET(cs->inbuf); | ||
1975 | |||
1976 | /* handle incoming data on control/common channel */ | 1975 | /* handle incoming data on control/common channel */ |
1977 | if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { | 1976 | if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { |
1978 | dbg(DEBUG_INTR, "processing new data"); | 1977 | gig_dbg(DEBUG_INTR, "processing new data"); |
1979 | cs->ops->handle_input(cs->inbuf); | 1978 | cs->ops->handle_input(cs->inbuf); |
1980 | } | 1979 | } |
1981 | 1980 | ||
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 729edcdb6dac..9d21ba8757b0 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -1,11 +1,16 @@ | |||
1 | /* Siemens Gigaset 307x driver | 1 | /* |
2 | * Siemens Gigaset 307x driver | ||
2 | * Common header file for all connection variants | 3 | * Common header file for all connection variants |
3 | * | 4 | * |
4 | * Written by Stefan Eilers <Eilers.Stefan@epost.de> | 5 | * Written by Stefan Eilers |
5 | * and Hansjoerg Lipp <hjlipp@web.de> | 6 | * and Hansjoerg Lipp <hjlipp@web.de> |
6 | * | 7 | * |
7 | * Version: $Id: gigaset.h,v 1.97.4.26 2006/02/04 18:28:16 hjlipp Exp $ | 8 | * ===================================================================== |
8 | * =========================================================================== | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of | ||
12 | * the License, or (at your option) any later version. | ||
13 | * ===================================================================== | ||
9 | */ | 14 | */ |
10 | 15 | ||
11 | #ifndef GIGASET_H | 16 | #ifndef GIGASET_H |
@@ -15,7 +20,6 @@ | |||
15 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
16 | #include <linux/compiler.h> | 21 | #include <linux/compiler.h> |
17 | #include <linux/types.h> | 22 | #include <linux/types.h> |
18 | #include <asm/atomic.h> | ||
19 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
20 | #include <linux/isdnif.h> | 24 | #include <linux/isdnif.h> |
21 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
@@ -27,21 +31,22 @@ | |||
27 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
28 | #include <linux/tty_driver.h> | 32 | #include <linux/tty_driver.h> |
29 | #include <linux/list.h> | 33 | #include <linux/list.h> |
34 | #include <asm/atomic.h> | ||
30 | 35 | ||
31 | #define GIG_VERSION {0,5,0,0} | 36 | #define GIG_VERSION {0,5,0,0} |
32 | #define GIG_COMPAT {0,4,0,0} | 37 | #define GIG_COMPAT {0,4,0,0} |
33 | 38 | ||
34 | #define MAX_REC_PARAMS 10 /* Max. number of params in response string */ | 39 | #define MAX_REC_PARAMS 10 /* Max. number of params in response string */ |
35 | #define MAX_RESP_SIZE 512 /* Max. size of a response string */ | 40 | #define MAX_RESP_SIZE 512 /* Max. size of a response string */ |
36 | #define HW_HDR_LEN 2 /* Header size used to store ack info */ | 41 | #define HW_HDR_LEN 2 /* Header size used to store ack info */ |
37 | 42 | ||
38 | #define MAX_EVENTS 64 /* size of event queue */ | 43 | #define MAX_EVENTS 64 /* size of event queue */ |
39 | 44 | ||
40 | #define RBUFSIZE 8192 | 45 | #define RBUFSIZE 8192 |
41 | #define SBUFSIZE 4096 /* sk_buff payload size */ | 46 | #define SBUFSIZE 4096 /* sk_buff payload size */ |
42 | 47 | ||
43 | #define MAX_BUF_SIZE (SBUFSIZE - 2) /* Max. size of a data packet from LL */ | 48 | #define TRANSBUFSIZE 768 /* bytes per skb for transparent receive */ |
44 | #define TRANSBUFSIZE 768 /* bytes per skb for transparent receive */ | 49 | #define MAX_BUF_SIZE (SBUFSIZE - 2) /* Max. size of a data packet from LL */ |
45 | 50 | ||
46 | /* compile time options */ | 51 | /* compile time options */ |
47 | #define GIG_MAJOR 0 | 52 | #define GIG_MAJOR 0 |
@@ -50,10 +55,7 @@ | |||
50 | #define GIG_RETRYCID | 55 | #define GIG_RETRYCID |
51 | #define GIG_X75 | 56 | #define GIG_X75 |
52 | 57 | ||
53 | #define MAX_TIMER_INDEX 1000 | 58 | #define GIG_TICK 100 /* in milliseconds */ |
54 | #define MAX_SEQ_INDEX 1000 | ||
55 | |||
56 | #define GIG_TICK (HZ / 10) | ||
57 | 59 | ||
58 | /* timeout values (unit: 1 sec) */ | 60 | /* timeout values (unit: 1 sec) */ |
59 | #define INIT_TIMEOUT 1 | 61 | #define INIT_TIMEOUT 1 |
@@ -67,74 +69,89 @@ | |||
67 | 69 | ||
68 | #define MAXACT 3 | 70 | #define MAXACT 3 |
69 | 71 | ||
70 | #define IFNULL(a) if (unlikely(!(a))) | ||
71 | #define IFNULLRET(a) if (unlikely(!(a))) {err("%s==NULL at %s:%d!", #a, __FILE__, __LINE__); return; } | ||
72 | #define IFNULLRETVAL(a,b) if (unlikely(!(a))) {err("%s==NULL at %s:%d!", #a, __FILE__, __LINE__); return (b); } | ||
73 | #define IFNULLCONT(a) if (unlikely(!(a))) {err("%s==NULL at %s:%d!", #a, __FILE__, __LINE__); continue; } | ||
74 | #define IFNULLGOTO(a,b) if (unlikely(!(a))) {err("%s==NULL at %s:%d!", #a, __FILE__, __LINE__); goto b; } | ||
75 | |||
76 | extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */ | 72 | extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */ |
77 | 73 | ||
78 | /* any combination of these can be given with the 'debug=' parameter to insmod, e.g. | 74 | /* any combination of these can be given with the 'debug=' parameter to insmod, |
79 | * 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and DEBUG_INTR. */ | 75 | * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and |
76 | * DEBUG_INTR. | ||
77 | */ | ||
80 | enum debuglevel { /* up to 24 bits (atomic_t) */ | 78 | enum debuglevel { /* up to 24 bits (atomic_t) */ |
81 | DEBUG_REG = 0x0002, /* serial port I/O register operations */ | 79 | DEBUG_REG = 0x0002, /* serial port I/O register operations */ |
82 | DEBUG_OPEN = 0x0004, /* open/close serial port */ | 80 | DEBUG_OPEN = 0x0004, /* open/close serial port */ |
83 | DEBUG_INTR = 0x0008, /* interrupt processing */ | 81 | DEBUG_INTR = 0x0008, /* interrupt processing */ |
84 | DEBUG_INTR_DUMP = 0x0010, /* Activating hexdump debug output on interrupt | 82 | DEBUG_INTR_DUMP = 0x0010, /* Activating hexdump debug output on |
85 | requests, not available as run-time option */ | 83 | interrupt requests, not available as |
84 | run-time option */ | ||
86 | DEBUG_CMD = 0x00020, /* sent/received LL commands */ | 85 | DEBUG_CMD = 0x00020, /* sent/received LL commands */ |
87 | DEBUG_STREAM = 0x00040, /* application data stream I/O events */ | 86 | DEBUG_STREAM = 0x00040, /* application data stream I/O events */ |
88 | DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ | 87 | DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ |
89 | DEBUG_LLDATA = 0x00100, /* sent/received LL data */ | 88 | DEBUG_LLDATA = 0x00100, /* sent/received LL data */ |
90 | DEBUG_INTR_0 = 0x00200, /* serial port output interrupt processing */ | 89 | DEBUG_INTR_0 = 0x00200, /* serial port interrupt processing */ |
91 | DEBUG_DRIVER = 0x00400, /* driver structure */ | 90 | DEBUG_DRIVER = 0x00400, /* driver structure */ |
92 | DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ | 91 | DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ |
93 | DEBUG_WRITE = 0x01000, /* M105 data write */ | 92 | DEBUG_WRITE = 0x01000, /* M105 data write */ |
94 | DEBUG_TRANSCMD = 0x02000, /*AT-COMMANDS+RESPONSES*/ | 93 | DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */ |
95 | DEBUG_MCMD = 0x04000, /*COMMANDS THAT ARE SENT VERY OFTEN*/ | 94 | DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */ |
96 | DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data structures */ | 95 | DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data |
96 | structures */ | ||
97 | DEBUG_LOCK = 0x10000, /* semaphore operations */ | 97 | DEBUG_LOCK = 0x10000, /* semaphore operations */ |
98 | DEBUG_OUTPUT = 0x20000, /* output to device */ | 98 | DEBUG_OUTPUT = 0x20000, /* output to device */ |
99 | DEBUG_ISO = 0x40000, /* isochronous transfers */ | 99 | DEBUG_ISO = 0x40000, /* isochronous transfers */ |
100 | DEBUG_IF = 0x80000, /* character device operations */ | 100 | DEBUG_IF = 0x80000, /* character device operations */ |
101 | DEBUG_USBREQ = 0x100000, /* USB communication (except payload data) */ | 101 | DEBUG_USBREQ = 0x100000, /* USB communication (except payload |
102 | DEBUG_LOCKCMD = 0x200000, /* AT commands and responses when MS_LOCKED */ | 102 | data) */ |
103 | DEBUG_LOCKCMD = 0x200000, /* AT commands and responses when | ||
104 | MS_LOCKED */ | ||
103 | 105 | ||
104 | DEBUG_ANY = 0x3fffff, /* print message if any of the others is activated */ | 106 | DEBUG_ANY = 0x3fffff, /* print message if any of the others is |
107 | activated */ | ||
105 | }; | 108 | }; |
106 | 109 | ||
107 | #ifdef CONFIG_GIGASET_DEBUG | 110 | /* missing from linux/device.h ... */ |
108 | #define DEBUG_DEFAULT (DEBUG_INIT | DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ) | 111 | #ifndef dev_notice |
109 | //#define DEBUG_DEFAULT (DEBUG_LOCK | DEBUG_INIT | DEBUG_TRANSCMD | DEBUG_CMD | DEBUF_IF | DEBUG_DRIVER | DEBUG_OUTPUT | DEBUG_INTR) | 112 | #define dev_notice(dev, format, arg...) \ |
110 | #else | 113 | dev_printk(KERN_NOTICE , dev , format , ## arg) |
111 | #define DEBUG_DEFAULT 0 | ||
112 | #endif | 114 | #endif |
113 | 115 | ||
114 | /* redefine syslog macros to prepend module name instead of entire source path */ | 116 | /* Kernel message macros for situations where dev_printk and friends cannot be |
115 | /* The space before the comma in ", ##" is needed by gcc 2.95 */ | 117 | * used for lack of reliable access to a device structure. |
118 | * linux/usb.h already contains these but in an obsolete form which clutters | ||
119 | * the log needlessly, and according to the USB maintainer those should be | ||
120 | * removed rather than fixed anyway. | ||
121 | */ | ||
122 | #undef err | ||
116 | #undef info | 123 | #undef info |
117 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg) | ||
118 | |||
119 | #undef notice | ||
120 | #define notice(format, arg...) printk(KERN_NOTICE "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg) | ||
121 | |||
122 | #undef warn | 124 | #undef warn |
123 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg) | 125 | #undef notice |
124 | 126 | ||
125 | #undef err | 127 | #define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ |
126 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg) | 128 | format "\n" , ## arg) |
129 | #define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \ | ||
130 | format "\n" , ## arg) | ||
131 | #define warn(format, arg...) printk(KERN_WARNING KBUILD_MODNAME ": " \ | ||
132 | format "\n" , ## arg) | ||
133 | #define notice(format, arg...) printk(KERN_NOTICE KBUILD_MODNAME ": " \ | ||
134 | format "\n" , ## arg) | ||
127 | 135 | ||
128 | #undef dbg | ||
129 | #ifdef CONFIG_GIGASET_DEBUG | 136 | #ifdef CONFIG_GIGASET_DEBUG |
130 | #define dbg(level, format, arg...) do { if (unlikely(((enum debuglevel)gigaset_debuglevel) & (level))) \ | 137 | |
131 | printk(KERN_DEBUG "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg); } while (0) | 138 | #define gig_dbg(level, format, arg...) \ |
139 | do { \ | ||
140 | if (unlikely(((enum debuglevel)gigaset_debuglevel) & (level))) \ | ||
141 | printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \ | ||
142 | ## arg); \ | ||
143 | } while (0) | ||
144 | #define DEBUG_DEFAULT (DEBUG_INIT | DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ) | ||
145 | |||
132 | #else | 146 | #else |
133 | #define dbg(level, format, arg...) do {} while (0) | 147 | |
148 | #define gig_dbg(level, format, arg...) do {} while (0) | ||
149 | #define DEBUG_DEFAULT 0 | ||
150 | |||
134 | #endif | 151 | #endif |
135 | 152 | ||
136 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | 153 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, |
137 | size_t len, const unsigned char *buf, int from_user); | 154 | size_t len, const unsigned char *buf); |
138 | 155 | ||
139 | /* connection state */ | 156 | /* connection state */ |
140 | #define ZSAU_NONE 0 | 157 | #define ZSAU_NONE 0 |
@@ -148,13 +165,14 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
148 | #define ZSAU_UNKNOWN -1 | 165 | #define ZSAU_UNKNOWN -1 |
149 | 166 | ||
150 | /* USB control transfer requests */ | 167 | /* USB control transfer requests */ |
151 | #define OUT_VENDOR_REQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) | 168 | #define OUT_VENDOR_REQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) |
152 | #define IN_VENDOR_REQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) | 169 | #define IN_VENDOR_REQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) |
153 | 170 | ||
154 | /* int-in-events 3070 */ | 171 | /* int-in-events 3070 */ |
155 | #define HD_B1_FLOW_CONTROL 0x80 | 172 | #define HD_B1_FLOW_CONTROL 0x80 |
156 | #define HD_B2_FLOW_CONTROL 0x81 | 173 | #define HD_B2_FLOW_CONTROL 0x81 |
157 | #define HD_RECEIVEATDATA_ACK (0x35) // 3070 // att: HD_RECEIVE>>AT<<DATA_ACK | 174 | #define HD_RECEIVEATDATA_ACK (0x35) // 3070 |
175 | // att: HD_RECEIVE>>AT<<DATA_ACK | ||
158 | #define HD_READY_SEND_ATDATA (0x36) // 3070 | 176 | #define HD_READY_SEND_ATDATA (0x36) // 3070 |
159 | #define HD_OPEN_ATCHANNEL_ACK (0x37) // 3070 | 177 | #define HD_OPEN_ATCHANNEL_ACK (0x37) // 3070 |
160 | #define HD_CLOSE_ATCHANNEL_ACK (0x38) // 3070 | 178 | #define HD_CLOSE_ATCHANNEL_ACK (0x38) // 3070 |
@@ -181,17 +199,18 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
181 | #define HD_CLOSE_ATCHANNEL (0x29) // 3070 | 199 | #define HD_CLOSE_ATCHANNEL (0x29) // 3070 |
182 | 200 | ||
183 | /* USB frames for isochronous transfer */ | 201 | /* USB frames for isochronous transfer */ |
184 | #define BAS_FRAMETIME 1 /* number of milliseconds between frames */ | 202 | #define BAS_FRAMETIME 1 /* number of milliseconds between frames */ |
185 | #define BAS_NUMFRAMES 8 /* number of frames per URB */ | 203 | #define BAS_NUMFRAMES 8 /* number of frames per URB */ |
186 | #define BAS_MAXFRAME 16 /* allocated bytes per frame */ | 204 | #define BAS_MAXFRAME 16 /* allocated bytes per frame */ |
187 | #define BAS_NORMFRAME 8 /* send size without flow control */ | 205 | #define BAS_NORMFRAME 8 /* send size without flow control */ |
188 | #define BAS_HIGHFRAME 10 /* " " with positive flow control */ | 206 | #define BAS_HIGHFRAME 10 /* " " with positive flow control */ |
189 | #define BAS_LOWFRAME 5 /* " " with negative flow control */ | 207 | #define BAS_LOWFRAME 5 /* " " with negative flow control */ |
190 | #define BAS_CORRFRAMES 4 /* flow control multiplicator */ | 208 | #define BAS_CORRFRAMES 4 /* flow control multiplicator */ |
191 | 209 | ||
192 | #define BAS_INBUFSIZE (BAS_MAXFRAME * BAS_NUMFRAMES) /* size of isochronous input buffer per URB */ | 210 | #define BAS_INBUFSIZE (BAS_MAXFRAME * BAS_NUMFRAMES) |
193 | #define BAS_OUTBUFSIZE 4096 /* size of common isochronous output buffer */ | 211 | /* size of isoc in buf per URB */ |
194 | #define BAS_OUTBUFPAD BAS_MAXFRAME /* size of pad area for isochronous output buffer */ | 212 | #define BAS_OUTBUFSIZE 4096 /* size of common isoc out buffer */ |
213 | #define BAS_OUTBUFPAD BAS_MAXFRAME /* size of pad area for isoc out buf */ | ||
195 | 214 | ||
196 | #define BAS_INURBS 3 | 215 | #define BAS_INURBS 3 |
197 | #define BAS_OUTURBS 3 | 216 | #define BAS_OUTURBS 3 |
@@ -207,40 +226,40 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
207 | #define AT_NUM 7 | 226 | #define AT_NUM 7 |
208 | 227 | ||
209 | /* variables in struct at_state_t */ | 228 | /* variables in struct at_state_t */ |
210 | #define VAR_ZSAU 0 | 229 | #define VAR_ZSAU 0 |
211 | #define VAR_ZDLE 1 | 230 | #define VAR_ZDLE 1 |
212 | #define VAR_ZVLS 2 | 231 | #define VAR_ZVLS 2 |
213 | #define VAR_ZCTP 3 | 232 | #define VAR_ZCTP 3 |
214 | #define VAR_NUM 4 | 233 | #define VAR_NUM 4 |
215 | 234 | ||
216 | #define STR_NMBR 0 | 235 | #define STR_NMBR 0 |
217 | #define STR_ZCPN 1 | 236 | #define STR_ZCPN 1 |
218 | #define STR_ZCON 2 | 237 | #define STR_ZCON 2 |
219 | #define STR_ZBC 3 | 238 | #define STR_ZBC 3 |
220 | #define STR_ZHLC 4 | 239 | #define STR_ZHLC 4 |
221 | #define STR_NUM 5 | 240 | #define STR_NUM 5 |
222 | 241 | ||
223 | #define EV_TIMEOUT -105 | 242 | #define EV_TIMEOUT -105 |
224 | #define EV_IF_VER -106 | 243 | #define EV_IF_VER -106 |
225 | #define EV_PROC_CIDMODE -107 | 244 | #define EV_PROC_CIDMODE -107 |
226 | #define EV_SHUTDOWN -108 | 245 | #define EV_SHUTDOWN -108 |
227 | #define EV_START -110 | 246 | #define EV_START -110 |
228 | #define EV_STOP -111 | 247 | #define EV_STOP -111 |
229 | #define EV_IF_LOCK -112 | 248 | #define EV_IF_LOCK -112 |
230 | #define EV_PROTO_L2 -113 | 249 | #define EV_PROTO_L2 -113 |
231 | #define EV_ACCEPT -114 | 250 | #define EV_ACCEPT -114 |
232 | #define EV_DIAL -115 | 251 | #define EV_DIAL -115 |
233 | #define EV_HUP -116 | 252 | #define EV_HUP -116 |
234 | #define EV_BC_OPEN -117 | 253 | #define EV_BC_OPEN -117 |
235 | #define EV_BC_CLOSED -118 | 254 | #define EV_BC_CLOSED -118 |
236 | 255 | ||
237 | /* input state */ | 256 | /* input state */ |
238 | #define INS_command 0x0001 | 257 | #define INS_command 0x0001 |
239 | #define INS_DLE_char 0x0002 | 258 | #define INS_DLE_char 0x0002 |
240 | #define INS_byte_stuff 0x0004 | 259 | #define INS_byte_stuff 0x0004 |
241 | #define INS_have_data 0x0008 | 260 | #define INS_have_data 0x0008 |
242 | #define INS_skip_frame 0x0010 | 261 | #define INS_skip_frame 0x0010 |
243 | #define INS_DLE_command 0x0020 | 262 | #define INS_DLE_command 0x0020 |
244 | #define INS_flag_hunt 0x0040 | 263 | #define INS_flag_hunt 0x0040 |
245 | 264 | ||
246 | /* channel state */ | 265 | /* channel state */ |
@@ -248,27 +267,27 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
248 | #define CHS_B_UP 0x02 | 267 | #define CHS_B_UP 0x02 |
249 | #define CHS_NOTIFY_LL 0x04 | 268 | #define CHS_NOTIFY_LL 0x04 |
250 | 269 | ||
251 | #define ICALL_REJECT 0 | 270 | #define ICALL_REJECT 0 |
252 | #define ICALL_ACCEPT 1 | 271 | #define ICALL_ACCEPT 1 |
253 | #define ICALL_IGNORE 2 | 272 | #define ICALL_IGNORE 2 |
254 | 273 | ||
255 | /* device state */ | 274 | /* device state */ |
256 | #define MS_UNINITIALIZED 0 | 275 | #define MS_UNINITIALIZED 0 |
257 | #define MS_INIT 1 | 276 | #define MS_INIT 1 |
258 | #define MS_LOCKED 2 | 277 | #define MS_LOCKED 2 |
259 | #define MS_SHUTDOWN 3 | 278 | #define MS_SHUTDOWN 3 |
260 | #define MS_RECOVER 4 | 279 | #define MS_RECOVER 4 |
261 | #define MS_READY 5 | 280 | #define MS_READY 5 |
262 | 281 | ||
263 | /* mode */ | 282 | /* mode */ |
264 | #define M_UNKNOWN 0 | 283 | #define M_UNKNOWN 0 |
265 | #define M_CONFIG 1 | 284 | #define M_CONFIG 1 |
266 | #define M_UNIMODEM 2 | 285 | #define M_UNIMODEM 2 |
267 | #define M_CID 3 | 286 | #define M_CID 3 |
268 | 287 | ||
269 | /* start mode */ | 288 | /* start mode */ |
270 | #define SM_LOCKED 0 | 289 | #define SM_LOCKED 0 |
271 | #define SM_ISDN 1 /* default */ | 290 | #define SM_ISDN 1 /* default */ |
272 | 291 | ||
273 | struct gigaset_ops; | 292 | struct gigaset_ops; |
274 | struct gigaset_driver; | 293 | struct gigaset_driver; |
@@ -283,27 +302,26 @@ struct ser_bc_state; | |||
283 | struct bas_bc_state; | 302 | struct bas_bc_state; |
284 | 303 | ||
285 | struct reply_t { | 304 | struct reply_t { |
286 | int resp_code; /* RSP_XXXX */ | 305 | int resp_code; /* RSP_XXXX */ |
287 | int min_ConState; /* <0 => ignore */ | 306 | int min_ConState; /* <0 => ignore */ |
288 | int max_ConState; /* <0 => ignore */ | 307 | int max_ConState; /* <0 => ignore */ |
289 | int parameter; /* e.g. ZSAU_XXXX <0: ignore*/ | 308 | int parameter; /* e.g. ZSAU_XXXX <0: ignore*/ |
290 | int new_ConState; /* <0 => ignore */ | 309 | int new_ConState; /* <0 => ignore */ |
291 | int timeout; /* >0 => *HZ; <=0 => TOUT_XXXX*/ | 310 | int timeout; /* >0 => *HZ; <=0 => TOUT_XXXX*/ |
292 | int action[MAXACT]; /* ACT_XXXX */ | 311 | int action[MAXACT]; /* ACT_XXXX */ |
293 | char *command; /* NULL==none */ | 312 | char *command; /* NULL==none */ |
294 | }; | 313 | }; |
295 | 314 | ||
296 | extern struct reply_t gigaset_tab_cid_m10x[]; | 315 | extern struct reply_t gigaset_tab_cid_m10x[]; |
297 | extern struct reply_t gigaset_tab_nocid_m10x[]; | 316 | extern struct reply_t gigaset_tab_nocid_m10x[]; |
298 | 317 | ||
299 | struct inbuf_t { | 318 | struct inbuf_t { |
300 | unsigned char *rcvbuf; /* usb-gigaset receive buffer */ | 319 | unsigned char *rcvbuf; /* usb-gigaset receive buffer */ |
301 | struct bc_state *bcs; | 320 | struct bc_state *bcs; |
302 | struct cardstate *cs; | 321 | struct cardstate *cs; |
303 | int inputstate; | 322 | int inputstate; |
304 | 323 | atomic_t head, tail; | |
305 | atomic_t head, tail; | 324 | unsigned char data[RBUFSIZE]; |
306 | unsigned char data[RBUFSIZE]; | ||
307 | }; | 325 | }; |
308 | 326 | ||
309 | /* isochronous write buffer structure | 327 | /* isochronous write buffer structure |
@@ -319,16 +337,9 @@ struct inbuf_t { | |||
319 | * if writesem <= 0, data[write..read-1] is currently being written to | 337 | * if writesem <= 0, data[write..read-1] is currently being written to |
320 | * - idle contains the byte value to repeat when the end of valid data is | 338 | * - idle contains the byte value to repeat when the end of valid data is |
321 | * reached; if nextread==write (buffer contains no data to send), either the | 339 | * reached; if nextread==write (buffer contains no data to send), either the |
322 | * BAS_OUTBUFPAD bytes immediately before data[write] (if write>=BAS_OUTBUFPAD) | 340 | * BAS_OUTBUFPAD bytes immediately before data[write] (if |
323 | * or those of the pad area (if write<BAS_OUTBUFPAD) are also filled with that | 341 | * write>=BAS_OUTBUFPAD) or those of the pad area (if write<BAS_OUTBUFPAD) |
324 | * value | 342 | * are also filled with that value |
325 | * - optionally, the following statistics on the buffer's usage can be collected: | ||
326 | * maxfill: maximum number of bytes occupied | ||
327 | * idlefills: number of times a frame of idle bytes is prepared | ||
328 | * emptygets: number of times the buffer was empty when a data frame was requested | ||
329 | * backtoback: number of times two data packets were entered into the buffer | ||
330 | * without intervening idle flags | ||
331 | * nakedback: set if no idle flags have been inserted since the last data packet | ||
332 | */ | 343 | */ |
333 | struct isowbuf_t { | 344 | struct isowbuf_t { |
334 | atomic_t read; | 345 | atomic_t read; |
@@ -358,34 +369,28 @@ struct isow_urbctx_t { | |||
358 | * it is currently assigned a B channel | 369 | * it is currently assigned a B channel |
359 | */ | 370 | */ |
360 | struct at_state_t { | 371 | struct at_state_t { |
361 | struct list_head list; | 372 | struct list_head list; |
362 | int waiting; | 373 | int waiting; |
363 | int getstring; | 374 | int getstring; |
364 | atomic_t timer_index; | 375 | unsigned timer_index; |
365 | unsigned long timer_expires; | 376 | unsigned long timer_expires; |
366 | int timer_active; | 377 | int timer_active; |
367 | unsigned int ConState; /* State of connection */ | 378 | unsigned int ConState; /* State of connection */ |
368 | struct reply_t *replystruct; | 379 | struct reply_t *replystruct; |
369 | int cid; | 380 | int cid; |
370 | int int_var[VAR_NUM]; /* see VAR_XXXX */ | 381 | int int_var[VAR_NUM]; /* see VAR_XXXX */ |
371 | char *str_var[STR_NUM]; /* see STR_XXXX */ | 382 | char *str_var[STR_NUM]; /* see STR_XXXX */ |
372 | unsigned pending_commands; /* see PC_XXXX */ | 383 | unsigned pending_commands; /* see PC_XXXX */ |
373 | atomic_t seq_index; | 384 | unsigned seq_index; |
374 | 385 | ||
375 | struct cardstate *cs; | 386 | struct cardstate *cs; |
376 | struct bc_state *bcs; | 387 | struct bc_state *bcs; |
377 | }; | 388 | }; |
378 | 389 | ||
379 | struct resp_type_t { | 390 | struct resp_type_t { |
380 | unsigned char *response; | 391 | unsigned char *response; |
381 | int resp_code; /* RSP_XXXX */ | 392 | int resp_code; /* RSP_XXXX */ |
382 | int type; /* RT_XXXX */ | 393 | int type; /* RT_XXXX */ |
383 | }; | ||
384 | |||
385 | struct prot_skb { | ||
386 | atomic_t empty; | ||
387 | struct semaphore *sem; | ||
388 | struct sk_buff *skb; | ||
389 | }; | 394 | }; |
390 | 395 | ||
391 | struct event_t { | 396 | struct event_t { |
@@ -398,29 +403,29 @@ struct event_t { | |||
398 | 403 | ||
399 | /* This buffer holds all information about the used B-Channel */ | 404 | /* This buffer holds all information about the used B-Channel */ |
400 | struct bc_state { | 405 | struct bc_state { |
401 | struct sk_buff *tx_skb; /* Current transfer buffer to modem */ | 406 | struct sk_buff *tx_skb; /* Current transfer buffer to modem */ |
402 | struct sk_buff_head squeue; /* B-Channel send Queue */ | 407 | struct sk_buff_head squeue; /* B-Channel send Queue */ |
403 | 408 | ||
404 | /* Variables for debugging .. */ | 409 | /* Variables for debugging .. */ |
405 | int corrupted; /* Counter for corrupted packages */ | 410 | int corrupted; /* Counter for corrupted packages */ |
406 | int trans_down; /* Counter of packages (downstream) */ | 411 | int trans_down; /* Counter of packages (downstream) */ |
407 | int trans_up; /* Counter of packages (upstream) */ | 412 | int trans_up; /* Counter of packages (upstream) */ |
408 | 413 | ||
409 | struct at_state_t at_state; | 414 | struct at_state_t at_state; |
410 | unsigned long rcvbytes; | 415 | unsigned long rcvbytes; |
411 | 416 | ||
412 | __u16 fcs; | 417 | __u16 fcs; |
413 | struct sk_buff *skb; | 418 | struct sk_buff *skb; |
414 | int inputstate; /* see INS_XXXX */ | 419 | int inputstate; /* see INS_XXXX */ |
415 | 420 | ||
416 | int channel; | 421 | int channel; |
417 | 422 | ||
418 | struct cardstate *cs; | 423 | struct cardstate *cs; |
419 | 424 | ||
420 | unsigned chstate; /* bitmap (CHS_*) */ | 425 | unsigned chstate; /* bitmap (CHS_*) */ |
421 | int ignore; | 426 | int ignore; |
422 | unsigned proto2; /* Layer 2 protocol (ISDN_PROTO_L2_*) */ | 427 | unsigned proto2; /* Layer 2 protocol (ISDN_PROTO_L2_*) */ |
423 | char *commands[AT_NUM]; /* see AT_XXXX */ | 428 | char *commands[AT_NUM]; /* see AT_XXXX */ |
424 | 429 | ||
425 | #ifdef CONFIG_GIGASET_DEBUG | 430 | #ifdef CONFIG_GIGASET_DEBUG |
426 | int emptycount; | 431 | int emptycount; |
@@ -428,37 +433,39 @@ struct bc_state { | |||
428 | int busy; | 433 | int busy; |
429 | int use_count; | 434 | int use_count; |
430 | 435 | ||
431 | /* hardware drivers */ | 436 | /* private data of hardware drivers */ |
432 | union { | 437 | union { |
433 | struct ser_bc_state *ser; /* private data of serial hardware driver */ | 438 | struct ser_bc_state *ser; /* serial hardware driver */ |
434 | struct usb_bc_state *usb; /* private data of usb hardware driver */ | 439 | struct usb_bc_state *usb; /* usb hardware driver (m105) */ |
435 | struct bas_bc_state *bas; | 440 | struct bas_bc_state *bas; /* usb hardware driver (base) */ |
436 | } hw; | 441 | } hw; |
437 | }; | 442 | }; |
438 | 443 | ||
439 | struct cardstate { | 444 | struct cardstate { |
440 | struct gigaset_driver *driver; | 445 | struct gigaset_driver *driver; |
441 | unsigned minor_index; | 446 | unsigned minor_index; |
447 | struct device *dev; | ||
442 | 448 | ||
443 | const struct gigaset_ops *ops; | 449 | const struct gigaset_ops *ops; |
444 | 450 | ||
445 | /* Stuff to handle communication */ | 451 | /* Stuff to handle communication */ |
446 | //wait_queue_head_t initwait; | ||
447 | wait_queue_head_t waitqueue; | 452 | wait_queue_head_t waitqueue; |
448 | int waiting; | 453 | int waiting; |
449 | atomic_t mode; /* see M_XXXX */ | 454 | atomic_t mode; /* see M_XXXX */ |
450 | atomic_t mstate; /* Modem state: see MS_XXXX */ | 455 | atomic_t mstate; /* Modem state: see MS_XXXX */ |
451 | /* only changed by the event layer */ | 456 | /* only changed by the event layer */ |
452 | int cmd_result; | 457 | int cmd_result; |
453 | 458 | ||
454 | int channels; | 459 | int channels; |
455 | struct bc_state *bcs; /* Array of struct bc_state */ | 460 | struct bc_state *bcs; /* Array of struct bc_state */ |
456 | 461 | ||
457 | int onechannel; /* data and commands transmitted in one stream (M10x) */ | 462 | int onechannel; /* data and commands transmitted in one |
463 | stream (M10x) */ | ||
458 | 464 | ||
459 | spinlock_t lock; | 465 | spinlock_t lock; |
460 | struct at_state_t at_state; /* at_state_t for cid == 0 */ | 466 | struct at_state_t at_state; /* at_state_t for cid == 0 */ |
461 | struct list_head temp_at_states; /* list of temporary "struct at_state_t"s without B channel */ | 467 | struct list_head temp_at_states;/* list of temporary "struct |
468 | at_state_t"s without B channel */ | ||
462 | 469 | ||
463 | struct inbuf_t *inbuf; | 470 | struct inbuf_t *inbuf; |
464 | 471 | ||
@@ -474,58 +481,69 @@ struct cardstate { | |||
474 | unsigned fwver[4]; | 481 | unsigned fwver[4]; |
475 | int gotfwver; | 482 | int gotfwver; |
476 | 483 | ||
477 | atomic_t running; /* !=0 if events are handled */ | 484 | unsigned running; /* !=0 if events are handled */ |
478 | atomic_t connected; /* !=0 if hardware is connected */ | 485 | unsigned connected; /* !=0 if hardware is connected */ |
486 | unsigned isdn_up; /* !=0 after ISDN_STAT_RUN */ | ||
479 | 487 | ||
480 | atomic_t cidmode; | 488 | unsigned cidmode; |
481 | 489 | ||
482 | int myid; /* id for communication with LL */ | 490 | int myid; /* id for communication with LL */ |
483 | isdn_if iif; | 491 | isdn_if iif; |
484 | 492 | ||
485 | struct reply_t *tabnocid; | 493 | struct reply_t *tabnocid; |
486 | struct reply_t *tabcid; | 494 | struct reply_t *tabcid; |
487 | int cs_init; | 495 | int cs_init; |
488 | int ignoreframes; /* frames to ignore after setting up the B channel */ | 496 | int ignoreframes; /* frames to ignore after setting up the |
489 | struct semaphore sem; /* locks this structure: */ | 497 | B channel */ |
490 | /* connected is not changed, */ | 498 | struct mutex mutex; /* locks this structure: |
491 | /* hardware_up is not changed, */ | 499 | * connected is not changed, |
492 | /* MState is not changed to or from MS_LOCKED */ | 500 | * hardware_up is not changed, |
501 | * MState is not changed to or from | ||
502 | * MS_LOCKED */ | ||
493 | 503 | ||
494 | struct timer_list timer; | 504 | struct timer_list timer; |
495 | int retry_count; | 505 | int retry_count; |
496 | int dle; /* !=0 if modem commands/responses are dle encoded */ | 506 | int dle; /* !=0 if modem commands/responses are |
497 | int cur_at_seq; /* sequence of AT commands being processed */ | 507 | dle encoded */ |
498 | int curchannel; /* channel, those commands are meant for */ | 508 | int cur_at_seq; /* sequence of AT commands being |
499 | atomic_t commands_pending; /* flag(s) in xxx.commands_pending have been set */ | 509 | processed */ |
500 | struct tasklet_struct event_tasklet; /* tasklet for serializing AT commands. Scheduled | 510 | int curchannel; /* channel those commands are meant |
501 | * -> for modem reponses (and incomming data for M10x) | 511 | for */ |
502 | * -> on timeout | 512 | atomic_t commands_pending; /* flag(s) in xxx.commands_pending have |
503 | * -> after setting bits in xxx.at_state.pending_command | 513 | been set */ |
504 | * (e.g. command from LL) */ | 514 | struct tasklet_struct event_tasklet; |
505 | struct tasklet_struct write_tasklet; /* tasklet for serial output | 515 | /* tasklet for serializing AT commands. |
506 | * (not used in base driver) */ | 516 | * Scheduled |
517 | * -> for modem reponses (and | ||
518 | * incoming data for M10x) | ||
519 | * -> on timeout | ||
520 | * -> after setting bits in | ||
521 | * xxx.at_state.pending_command | ||
522 | * (e.g. command from LL) */ | ||
523 | struct tasklet_struct write_tasklet; | ||
524 | /* tasklet for serial output | ||
525 | * (not used in base driver) */ | ||
507 | 526 | ||
508 | /* event queue */ | 527 | /* event queue */ |
509 | struct event_t events[MAX_EVENTS]; | 528 | struct event_t events[MAX_EVENTS]; |
510 | atomic_t ev_tail, ev_head; | 529 | unsigned ev_tail, ev_head; |
511 | spinlock_t ev_lock; | 530 | spinlock_t ev_lock; |
512 | 531 | ||
513 | /* current modem response */ | 532 | /* current modem response */ |
514 | unsigned char respdata[MAX_RESP_SIZE]; | 533 | unsigned char respdata[MAX_RESP_SIZE]; |
515 | unsigned cbytes; | 534 | unsigned cbytes; |
516 | 535 | ||
517 | /* hardware drivers */ | 536 | /* private data of hardware drivers */ |
518 | union { | 537 | union { |
519 | struct usb_cardstate *usb; /* private data of USB hardware driver */ | 538 | struct usb_cardstate *usb; /* USB hardware driver (m105) */ |
520 | struct ser_cardstate *ser; /* private data of serial hardware driver */ | 539 | struct ser_cardstate *ser; /* serial hardware driver */ |
521 | struct bas_cardstate *bas; /* private data of base hardware driver */ | 540 | struct bas_cardstate *bas; /* USB hardware driver (base) */ |
522 | } hw; | 541 | } hw; |
523 | }; | 542 | }; |
524 | 543 | ||
525 | struct gigaset_driver { | 544 | struct gigaset_driver { |
526 | struct list_head list; | 545 | struct list_head list; |
527 | spinlock_t lock; /* locks minor tables and blocked */ | 546 | spinlock_t lock; /* locks minor tables and blocked */ |
528 | //struct semaphore sem; /* locks this structure */ | ||
529 | struct tty_driver *tty; | 547 | struct tty_driver *tty; |
530 | unsigned have_tty; | 548 | unsigned have_tty; |
531 | unsigned minor; | 549 | unsigned minor; |
@@ -553,37 +571,42 @@ struct bas_bc_state { | |||
553 | struct isow_urbctx_t isoouturbs[BAS_OUTURBS]; | 571 | struct isow_urbctx_t isoouturbs[BAS_OUTURBS]; |
554 | struct isow_urbctx_t *isooutdone, *isooutfree, *isooutovfl; | 572 | struct isow_urbctx_t *isooutdone, *isooutfree, *isooutovfl; |
555 | struct isowbuf_t *isooutbuf; | 573 | struct isowbuf_t *isooutbuf; |
556 | unsigned numsub; /* submitted URB counter (for diagnostic messages only) */ | 574 | unsigned numsub; /* submitted URB counter |
575 | (for diagnostic messages only) */ | ||
557 | struct tasklet_struct sent_tasklet; | 576 | struct tasklet_struct sent_tasklet; |
558 | 577 | ||
559 | /* isochronous input state */ | 578 | /* isochronous input state */ |
560 | spinlock_t isoinlock; | 579 | spinlock_t isoinlock; |
561 | struct urb *isoinurbs[BAS_INURBS]; | 580 | struct urb *isoinurbs[BAS_INURBS]; |
562 | unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS]; | 581 | unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS]; |
563 | struct urb *isoindone; /* completed isoc read URB */ | 582 | struct urb *isoindone; /* completed isoc read URB */ |
564 | int loststatus; /* status of dropped URB */ | 583 | int loststatus; /* status of dropped URB */ |
565 | unsigned isoinlost; /* number of bytes lost */ | 584 | unsigned isoinlost; /* number of bytes lost */ |
566 | /* state of bit unstuffing algorithm (in addition to BC_state.inputstate) */ | 585 | /* state of bit unstuffing algorithm |
567 | unsigned seqlen; /* number of '1' bits not yet unstuffed */ | 586 | (in addition to BC_state.inputstate) */ |
568 | unsigned inbyte, inbits; /* collected bits for next byte */ | 587 | unsigned seqlen; /* number of '1' bits not yet |
588 | unstuffed */ | ||
589 | unsigned inbyte, inbits; /* collected bits for next byte */ | ||
569 | /* statistics */ | 590 | /* statistics */ |
570 | unsigned goodbytes; /* bytes correctly received */ | 591 | unsigned goodbytes; /* bytes correctly received */ |
571 | unsigned alignerrs; /* frames with incomplete byte at end */ | 592 | unsigned alignerrs; /* frames with incomplete byte at end */ |
572 | unsigned fcserrs; /* FCS errors */ | 593 | unsigned fcserrs; /* FCS errors */ |
573 | unsigned frameerrs; /* framing errors */ | 594 | unsigned frameerrs; /* framing errors */ |
574 | unsigned giants; /* long frames */ | 595 | unsigned giants; /* long frames */ |
575 | unsigned runts; /* short frames */ | 596 | unsigned runts; /* short frames */ |
576 | unsigned aborts; /* HDLC aborts */ | 597 | unsigned aborts; /* HDLC aborts */ |
577 | unsigned shared0s; /* '0' bits shared between flags */ | 598 | unsigned shared0s; /* '0' bits shared between flags */ |
578 | unsigned stolen0s; /* '0' stuff bits also serving as leading flag bits */ | 599 | unsigned stolen0s; /* '0' stuff bits also serving as |
600 | leading flag bits */ | ||
579 | struct tasklet_struct rcvd_tasklet; | 601 | struct tasklet_struct rcvd_tasklet; |
580 | }; | 602 | }; |
581 | 603 | ||
582 | struct gigaset_ops { | 604 | struct gigaset_ops { |
583 | /* Called from ev-layer.c/interface.c for sending AT commands to the device */ | 605 | /* Called from ev-layer.c/interface.c for sending AT commands to the |
606 | device */ | ||
584 | int (*write_cmd)(struct cardstate *cs, | 607 | int (*write_cmd)(struct cardstate *cs, |
585 | const unsigned char *buf, int len, | 608 | const unsigned char *buf, int len, |
586 | struct tasklet_struct *wake_tasklet); | 609 | struct tasklet_struct *wake_tasklet); |
587 | 610 | ||
588 | /* Called from interface.c for additional device control */ | 611 | /* Called from interface.c for additional device control */ |
589 | int (*write_room)(struct cardstate *cs); | 612 | int (*write_room)(struct cardstate *cs); |
@@ -604,7 +627,8 @@ struct gigaset_ops { | |||
604 | /* Called by gigaset_freecs() for freeing bcs->hw.xxx */ | 627 | /* Called by gigaset_freecs() for freeing bcs->hw.xxx */ |
605 | int (*freebcshw)(struct bc_state *bcs); | 628 | int (*freebcshw)(struct bc_state *bcs); |
606 | 629 | ||
607 | /* Called by gigaset_stop() or gigaset_bchannel_down() for resetting bcs->hw.xxx */ | 630 | /* Called by gigaset_stop() or gigaset_bchannel_down() for resetting |
631 | bcs->hw.xxx */ | ||
608 | void (*reinitbcshw)(struct bc_state *bcs); | 632 | void (*reinitbcshw)(struct bc_state *bcs); |
609 | 633 | ||
610 | /* Called by gigaset_initcs() for setting up cs->hw.xxx */ | 634 | /* Called by gigaset_initcs() for setting up cs->hw.xxx */ |
@@ -613,13 +637,10 @@ struct gigaset_ops { | |||
613 | /* Called by gigaset_freecs() for freeing cs->hw.xxx */ | 637 | /* Called by gigaset_freecs() for freeing cs->hw.xxx */ |
614 | void (*freecshw)(struct cardstate *cs); | 638 | void (*freecshw)(struct cardstate *cs); |
615 | 639 | ||
616 | ///* Called by gigaset_stop() for killing URBs, shutting down the device, ... | 640 | /* Called from common.c/interface.c for additional serial port |
617 | // hardwareup: ==0: don't try to shut down the device, hardware is really not accessible | 641 | control */ |
618 | // !=0: hardware still up */ | 642 | int (*set_modem_ctrl)(struct cardstate *cs, unsigned old_state, |
619 | //void (*stophw)(struct cardstate *cs, int hardwareup); | 643 | unsigned new_state); |
620 | |||
621 | /* Called from common.c/interface.c for additional serial port control */ | ||
622 | int (*set_modem_ctrl)(struct cardstate *cs, unsigned old_state, unsigned new_state); | ||
623 | int (*baud_rate)(struct cardstate *cs, unsigned cflag); | 644 | int (*baud_rate)(struct cardstate *cs, unsigned cflag); |
624 | int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag); | 645 | int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag); |
625 | 646 | ||
@@ -639,7 +660,7 @@ struct gigaset_ops { | |||
639 | * <DLE_FLAG>: 0x10 | 660 | * <DLE_FLAG>: 0x10 |
640 | * <EVENT>: ((a-z)* | (A-Z)* | (0-10)*)+ | 661 | * <EVENT>: ((a-z)* | (A-Z)* | (0-10)*)+ |
641 | */ | 662 | */ |
642 | #define DLE_FLAG 0x10 | 663 | #define DLE_FLAG 0x10 |
643 | 664 | ||
644 | /* =========================================================================== | 665 | /* =========================================================================== |
645 | * Functions implemented in asyncdata.c | 666 | * Functions implemented in asyncdata.c |
@@ -667,7 +688,8 @@ void gigaset_isoc_input(struct inbuf_t *inbuf); | |||
667 | 688 | ||
668 | /* Called from bas-gigaset.c to process a block of data | 689 | /* Called from bas-gigaset.c to process a block of data |
669 | * received through the isochronous channel */ | 690 | * received through the isochronous channel */ |
670 | void gigaset_isoc_receive(unsigned char *src, unsigned count, struct bc_state *bcs); | 691 | void gigaset_isoc_receive(unsigned char *src, unsigned count, |
692 | struct bc_state *bcs); | ||
671 | 693 | ||
672 | /* Called from bas-gigaset.c to put a block of data | 694 | /* Called from bas-gigaset.c to put a block of data |
673 | * into the isochronous output buffer */ | 695 | * into the isochronous output buffer */ |
@@ -703,7 +725,7 @@ static inline void gigaset_isdn_rcv_err(struct bc_state *bcs) | |||
703 | isdn_ctrl response; | 725 | isdn_ctrl response; |
704 | 726 | ||
705 | /* error -> LL */ | 727 | /* error -> LL */ |
706 | dbg(DEBUG_CMD, "sending L1ERR"); | 728 | gig_dbg(DEBUG_CMD, "sending L1ERR"); |
707 | response.driver = bcs->cs->myid; | 729 | response.driver = bcs->cs->myid; |
708 | response.command = ISDN_STAT_L1ERR; | 730 | response.command = ISDN_STAT_L1ERR; |
709 | response.arg = bcs->channel; | 731 | response.arg = bcs->channel; |
@@ -727,8 +749,8 @@ void gigaset_handle_modem_response(struct cardstate *cs); | |||
727 | */ | 749 | */ |
728 | 750 | ||
729 | /* initialize sysfs for device */ | 751 | /* initialize sysfs for device */ |
730 | void gigaset_init_dev_sysfs(struct usb_interface *interface); | 752 | void gigaset_init_dev_sysfs(struct cardstate *cs); |
731 | void gigaset_free_dev_sysfs(struct usb_interface *interface); | 753 | void gigaset_free_dev_sysfs(struct cardstate *cs); |
732 | 754 | ||
733 | /* =========================================================================== | 755 | /* =========================================================================== |
734 | * Functions implemented in common.c/gigaset.h | 756 | * Functions implemented in common.c/gigaset.h |
@@ -736,7 +758,7 @@ void gigaset_free_dev_sysfs(struct usb_interface *interface); | |||
736 | 758 | ||
737 | void gigaset_bcs_reinit(struct bc_state *bcs); | 759 | void gigaset_bcs_reinit(struct bc_state *bcs); |
738 | void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, | 760 | void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, |
739 | struct cardstate *cs, int cid); | 761 | struct cardstate *cs, int cid); |
740 | int gigaset_get_channel(struct bc_state *bcs); | 762 | int gigaset_get_channel(struct bc_state *bcs); |
741 | void gigaset_free_channel(struct bc_state *bcs); | 763 | void gigaset_free_channel(struct bc_state *bcs); |
742 | int gigaset_get_channels(struct cardstate *cs); | 764 | int gigaset_get_channels(struct cardstate *cs); |
@@ -745,16 +767,15 @@ void gigaset_block_channels(struct cardstate *cs); | |||
745 | 767 | ||
746 | /* Allocate and initialize driver structure. */ | 768 | /* Allocate and initialize driver structure. */ |
747 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | 769 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, |
748 | const char *procname, | 770 | const char *procname, |
749 | const char *devname, | 771 | const char *devname, |
750 | const char *devfsname, | 772 | const char *devfsname, |
751 | const struct gigaset_ops *ops, | 773 | const struct gigaset_ops *ops, |
752 | struct module *owner); | 774 | struct module *owner); |
753 | 775 | ||
754 | /* Deallocate driver structure. */ | 776 | /* Deallocate driver structure. */ |
755 | void gigaset_freedriver(struct gigaset_driver *drv); | 777 | void gigaset_freedriver(struct gigaset_driver *drv); |
756 | void gigaset_debugdrivers(void); | 778 | void gigaset_debugdrivers(void); |
757 | struct cardstate *gigaset_get_cs_by_minor(unsigned minor); | ||
758 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); | 779 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); |
759 | struct cardstate *gigaset_get_cs_by_id(int id); | 780 | struct cardstate *gigaset_get_cs_by_id(int id); |
760 | 781 | ||
@@ -763,7 +784,8 @@ struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv); | |||
763 | void gigaset_unassign(struct cardstate *cs); | 784 | void gigaset_unassign(struct cardstate *cs); |
764 | void gigaset_blockdriver(struct gigaset_driver *drv); | 785 | void gigaset_blockdriver(struct gigaset_driver *drv); |
765 | 786 | ||
766 | /* Allocate and initialize card state. Calls hardware dependent gigaset_init[b]cs(). */ | 787 | /* Allocate and initialize card state. Calls hardware dependent |
788 | gigaset_init[b]cs(). */ | ||
767 | struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | 789 | struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, |
768 | int onechannel, int ignoreframes, | 790 | int onechannel, int ignoreframes, |
769 | int cidmode, const char *modulename); | 791 | int cidmode, const char *modulename); |
@@ -788,8 +810,8 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); | |||
788 | * ptr must be kmalloc()ed (and not be freed by the caller). | 810 | * ptr must be kmalloc()ed (and not be freed by the caller). |
789 | */ | 811 | */ |
790 | struct event_t *gigaset_add_event(struct cardstate *cs, | 812 | struct event_t *gigaset_add_event(struct cardstate *cs, |
791 | struct at_state_t *at_state, int type, | 813 | struct at_state_t *at_state, int type, |
792 | void *ptr, int parameter, void *arg); | 814 | void *ptr, int parameter, void *arg); |
793 | 815 | ||
794 | /* Called on CONFIG1 command from frontend. */ | 816 | /* Called on CONFIG1 command from frontend. */ |
795 | int gigaset_enterconfigmode(struct cardstate *cs); //0: success <0: errorcode | 817 | int gigaset_enterconfigmode(struct cardstate *cs); //0: success <0: errorcode |
@@ -799,7 +821,7 @@ static inline void gigaset_schedule_event(struct cardstate *cs) | |||
799 | { | 821 | { |
800 | unsigned long flags; | 822 | unsigned long flags; |
801 | spin_lock_irqsave(&cs->lock, flags); | 823 | spin_lock_irqsave(&cs->lock, flags); |
802 | if (atomic_read(&cs->running)) | 824 | if (cs->running) |
803 | tasklet_schedule(&cs->event_tasklet); | 825 | tasklet_schedule(&cs->event_tasklet); |
804 | spin_unlock_irqrestore(&cs->lock, flags); | 826 | spin_unlock_irqrestore(&cs->lock, flags); |
805 | } | 827 | } |
@@ -810,7 +832,7 @@ static inline void gigaset_bchannel_down(struct bc_state *bcs) | |||
810 | { | 832 | { |
811 | gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL); | 833 | gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL); |
812 | 834 | ||
813 | dbg(DEBUG_CMD, "scheduling BC_CLOSED"); | 835 | gig_dbg(DEBUG_CMD, "scheduling BC_CLOSED"); |
814 | gigaset_schedule_event(bcs->cs); | 836 | gigaset_schedule_event(bcs->cs); |
815 | } | 837 | } |
816 | 838 | ||
@@ -820,36 +842,19 @@ static inline void gigaset_bchannel_up(struct bc_state *bcs) | |||
820 | { | 842 | { |
821 | gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL); | 843 | gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL); |
822 | 844 | ||
823 | dbg(DEBUG_CMD, "scheduling BC_OPEN"); | 845 | gig_dbg(DEBUG_CMD, "scheduling BC_OPEN"); |
824 | gigaset_schedule_event(bcs->cs); | 846 | gigaset_schedule_event(bcs->cs); |
825 | } | 847 | } |
826 | 848 | ||
827 | /* handling routines for sk_buff */ | 849 | /* handling routines for sk_buff */ |
828 | /* ============================= */ | 850 | /* ============================= */ |
829 | 851 | ||
830 | /* private version of __skb_put() | ||
831 | * append 'len' bytes to the content of 'skb', already knowing that the | ||
832 | * existing buffer can accomodate them | ||
833 | * returns a pointer to the location where the new bytes should be copied to | ||
834 | * This function does not take any locks so it must be called with the | ||
835 | * appropriate locks held only. | ||
836 | */ | ||
837 | static inline unsigned char *gigaset_skb_put_quick(struct sk_buff *skb, | ||
838 | unsigned int len) | ||
839 | { | ||
840 | unsigned char *tmp = skb->tail; | ||
841 | /*SKB_LINEAR_ASSERT(skb);*/ /* not needed here */ | ||
842 | skb->tail += len; | ||
843 | skb->len += len; | ||
844 | return tmp; | ||
845 | } | ||
846 | |||
847 | /* pass received skb to LL | 852 | /* pass received skb to LL |
848 | * Warning: skb must not be accessed anymore! | 853 | * Warning: skb must not be accessed anymore! |
849 | */ | 854 | */ |
850 | static inline void gigaset_rcv_skb(struct sk_buff *skb, | 855 | static inline void gigaset_rcv_skb(struct sk_buff *skb, |
851 | struct cardstate *cs, | 856 | struct cardstate *cs, |
852 | struct bc_state *bcs) | 857 | struct bc_state *bcs) |
853 | { | 858 | { |
854 | cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb); | 859 | cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb); |
855 | bcs->trans_down++; | 860 | bcs->trans_down++; |
@@ -859,8 +864,8 @@ static inline void gigaset_rcv_skb(struct sk_buff *skb, | |||
859 | * Warning: skb must not be accessed anymore! | 864 | * Warning: skb must not be accessed anymore! |
860 | */ | 865 | */ |
861 | static inline void gigaset_rcv_error(struct sk_buff *procskb, | 866 | static inline void gigaset_rcv_error(struct sk_buff *procskb, |
862 | struct cardstate *cs, | 867 | struct cardstate *cs, |
863 | struct bc_state *bcs) | 868 | struct bc_state *bcs) |
864 | { | 869 | { |
865 | if (procskb) | 870 | if (procskb) |
866 | dev_kfree_skb(procskb); | 871 | dev_kfree_skb(procskb); |
@@ -877,46 +882,9 @@ static inline void gigaset_rcv_error(struct sk_buff *procskb, | |||
877 | /* bitwise byte inversion table */ | 882 | /* bitwise byte inversion table */ |
878 | extern __u8 gigaset_invtab[]; /* in common.c */ | 883 | extern __u8 gigaset_invtab[]; /* in common.c */ |
879 | 884 | ||
880 | |||
881 | /* append received bytes to inbuf */ | 885 | /* append received bytes to inbuf */ |
882 | static inline int gigaset_fill_inbuf(struct inbuf_t *inbuf, | 886 | int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, |
883 | const unsigned char *src, | 887 | unsigned numbytes); |
884 | unsigned numbytes) | ||
885 | { | ||
886 | unsigned n, head, tail, bytesleft; | ||
887 | |||
888 | dbg(DEBUG_INTR, "received %u bytes", numbytes); | ||
889 | |||
890 | if (!numbytes) | ||
891 | return 0; | ||
892 | |||
893 | bytesleft = numbytes; | ||
894 | tail = atomic_read(&inbuf->tail); | ||
895 | head = atomic_read(&inbuf->head); | ||
896 | dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | ||
897 | |||
898 | while (bytesleft) { | ||
899 | if (head > tail) | ||
900 | n = head - 1 - tail; | ||
901 | else if (head == 0) | ||
902 | n = (RBUFSIZE-1) - tail; | ||
903 | else | ||
904 | n = RBUFSIZE - tail; | ||
905 | if (!n) { | ||
906 | err("buffer overflow (%u bytes lost)", bytesleft); | ||
907 | break; | ||
908 | } | ||
909 | if (n > bytesleft) | ||
910 | n = bytesleft; | ||
911 | memcpy(inbuf->data + tail, src, n); | ||
912 | bytesleft -= n; | ||
913 | tail = (tail + n) % RBUFSIZE; | ||
914 | src += n; | ||
915 | } | ||
916 | dbg(DEBUG_INTR, "setting tail to %u", tail); | ||
917 | atomic_set(&inbuf->tail, tail); | ||
918 | return numbytes != bytesleft; | ||
919 | } | ||
920 | 888 | ||
921 | /* =========================================================================== | 889 | /* =========================================================================== |
922 | * Functions implemented in interface.c | 890 | * Functions implemented in interface.c |
@@ -924,7 +892,7 @@ static inline int gigaset_fill_inbuf(struct inbuf_t *inbuf, | |||
924 | 892 | ||
925 | /* initialize interface */ | 893 | /* initialize interface */ |
926 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | 894 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, |
927 | const char *devname, const char *devfsname); | 895 | const char *devname, const char *devfsname); |
928 | /* release interface */ | 896 | /* release interface */ |
929 | void gigaset_if_freedriver(struct gigaset_driver *drv); | 897 | void gigaset_if_freedriver(struct gigaset_driver *drv); |
930 | /* add minor */ | 898 | /* add minor */ |
@@ -933,6 +901,6 @@ void gigaset_if_init(struct cardstate *cs); | |||
933 | void gigaset_if_free(struct cardstate *cs); | 901 | void gigaset_if_free(struct cardstate *cs); |
934 | /* device received data */ | 902 | /* device received data */ |
935 | void gigaset_if_receive(struct cardstate *cs, | 903 | void gigaset_if_receive(struct cardstate *cs, |
936 | unsigned char *buffer, size_t len); | 904 | unsigned char *buffer, size_t len); |
937 | 905 | ||
938 | #endif | 906 | #endif |
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index 731a675f21b0..0815dbfb8291 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Stuff used by all variants of the driver | 2 | * Stuff used by all variants of the driver |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers (Eilers.Stefan@epost.de), | 4 | * Copyright (c) 2001 by Stefan Eilers, |
5 | * Hansjoerg Lipp (hjlipp@web.de), | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Tilman Schmidt (tilman@imap.cc). | 6 | * Tilman Schmidt <tilman@imap.cc>. |
7 | * | 7 | * |
8 | * ===================================================================== | 8 | * ===================================================================== |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
@@ -11,15 +11,11 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: i4l.c,v 1.3.2.9 2006/02/04 18:28:16 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
21 | 17 | ||
22 | /* == Handling of I4L IO ============================================================================*/ | 18 | /* == Handling of I4L IO =====================================================*/ |
23 | 19 | ||
24 | /* writebuf_from_LL | 20 | /* writebuf_from_LL |
25 | * called by LL to transmit data on an open channel | 21 | * called by LL to transmit data on an open channel |
@@ -29,14 +25,16 @@ | |||
29 | * parameters: | 25 | * parameters: |
30 | * driverID driver ID as assigned by LL | 26 | * driverID driver ID as assigned by LL |
31 | * channel channel number | 27 | * channel channel number |
32 | * ack if != 0 LL wants to be notified on completion via statcallb(ISDN_STAT_BSENT) | 28 | * ack if != 0 LL wants to be notified on completion via |
29 | * statcallb(ISDN_STAT_BSENT) | ||
33 | * skb skb containing data to send | 30 | * skb skb containing data to send |
34 | * return value: | 31 | * return value: |
35 | * number of accepted bytes | 32 | * number of accepted bytes |
36 | * 0 if temporarily unable to accept data (out of buffer space) | 33 | * 0 if temporarily unable to accept data (out of buffer space) |
37 | * <0 on error (eg. -EINVAL) | 34 | * <0 on error (eg. -EINVAL) |
38 | */ | 35 | */ |
39 | static int writebuf_from_LL(int driverID, int channel, int ack, struct sk_buff *skb) | 36 | static int writebuf_from_LL(int driverID, int channel, int ack, |
37 | struct sk_buff *skb) | ||
40 | { | 38 | { |
41 | struct cardstate *cs; | 39 | struct cardstate *cs; |
42 | struct bc_state *bcs; | 40 | struct bc_state *bcs; |
@@ -54,31 +52,28 @@ static int writebuf_from_LL(int driverID, int channel, int ack, struct sk_buff * | |||
54 | bcs = &cs->bcs[channel]; | 52 | bcs = &cs->bcs[channel]; |
55 | len = skb->len; | 53 | len = skb->len; |
56 | 54 | ||
57 | dbg(DEBUG_LLDATA, | 55 | gig_dbg(DEBUG_LLDATA, |
58 | "Receiving data from LL (id: %d, channel: %d, ack: %d, size: %d)", | 56 | "Receiving data from LL (id: %d, ch: %d, ack: %d, sz: %d)", |
59 | driverID, channel, ack, len); | 57 | driverID, channel, ack, len); |
60 | 58 | ||
61 | if (!len) { | 59 | if (!len) { |
62 | if (ack) | 60 | if (ack) |
63 | warn("not ACKing empty packet from LL"); | 61 | notice("%s: not ACKing empty packet", __func__); |
64 | return 0; | 62 | return 0; |
65 | } | 63 | } |
66 | if (len > MAX_BUF_SIZE) { | 64 | if (len > MAX_BUF_SIZE) { |
67 | err("%s: packet too large (%d bytes)", __func__, channel); | 65 | err("%s: packet too large (%d bytes)", __func__, len); |
68 | return -EINVAL; | 66 | return -EINVAL; |
69 | } | 67 | } |
70 | 68 | ||
71 | if (!atomic_read(&cs->connected)) | ||
72 | return -ENODEV; | ||
73 | |||
74 | skblen = ack ? len : 0; | 69 | skblen = ack ? len : 0; |
75 | skb->head[0] = skblen & 0xff; | 70 | skb->head[0] = skblen & 0xff; |
76 | skb->head[1] = skblen >> 8; | 71 | skb->head[1] = skblen >> 8; |
77 | dbg(DEBUG_MCMD, "skb: len=%u, skblen=%u: %02x %02x", len, skblen, | 72 | gig_dbg(DEBUG_MCMD, "skb: len=%u, skblen=%u: %02x %02x", |
78 | (unsigned) skb->head[0], (unsigned) skb->head[1]); | 73 | len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]); |
79 | 74 | ||
80 | /* pass to device-specific module */ | 75 | /* pass to device-specific module */ |
81 | return cs->ops->send_skb(bcs, skb); | 76 | return cs->ops->send_skb(bcs, skb); //FIXME cs->ops->send_skb() must handle !cs->connected correctly |
82 | } | 77 | } |
83 | 78 | ||
84 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) | 79 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) |
@@ -89,14 +84,14 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) | |||
89 | ++bcs->trans_up; | 84 | ++bcs->trans_up; |
90 | 85 | ||
91 | if (skb->len) | 86 | if (skb->len) |
92 | warn("%s: skb->len==%d", __func__, skb->len); | 87 | dev_warn(bcs->cs->dev, "%s: skb->len==%d\n", |
88 | __func__, skb->len); | ||
93 | 89 | ||
94 | len = (unsigned char) skb->head[0] | | 90 | len = (unsigned char) skb->head[0] | |
95 | (unsigned) (unsigned char) skb->head[1] << 8; | 91 | (unsigned) (unsigned char) skb->head[1] << 8; |
96 | if (len) { | 92 | if (len) { |
97 | dbg(DEBUG_MCMD, | 93 | gig_dbg(DEBUG_MCMD, "ACKing to LL (id: %d, ch: %d, sz: %u)", |
98 | "Acknowledge sending to LL (id: %d, channel: %d size: %u)", | 94 | bcs->cs->myid, bcs->channel, len); |
99 | bcs->cs->myid, bcs->channel, len); | ||
100 | 95 | ||
101 | response.driver = bcs->cs->myid; | 96 | response.driver = bcs->cs->myid; |
102 | response.command = ISDN_STAT_BSENT; | 97 | response.command = ISDN_STAT_BSENT; |
@@ -119,15 +114,12 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
119 | struct bc_state *bcs; | 114 | struct bc_state *bcs; |
120 | int retval = 0; | 115 | int retval = 0; |
121 | struct setup_parm *sp; | 116 | struct setup_parm *sp; |
117 | unsigned param; | ||
118 | unsigned long flags; | ||
122 | 119 | ||
123 | //dbg(DEBUG_ANY, "Gigaset_HW: Receiving command"); | ||
124 | gigaset_debugdrivers(); | 120 | gigaset_debugdrivers(); |
125 | 121 | ||
126 | /* Terminate this call if no device is present. Bt if the command is "ISDN_CMD_LOCK" or | 122 | if (!cs) { |
127 | * "ISDN_CMD_UNLOCK" then execute it due to the fact that they are device independent ! | ||
128 | */ | ||
129 | //FIXME "remove test for &connected" | ||
130 | if ((!cs || !atomic_read(&cs->connected))) { | ||
131 | warn("LL tried to access unknown device with nr. %d", | 123 | warn("LL tried to access unknown device with nr. %d", |
132 | cntrl->driver); | 124 | cntrl->driver); |
133 | return -ENODEV; | 125 | return -ENODEV; |
@@ -135,29 +127,30 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
135 | 127 | ||
136 | switch (cntrl->command) { | 128 | switch (cntrl->command) { |
137 | case ISDN_CMD_IOCTL: | 129 | case ISDN_CMD_IOCTL: |
138 | 130 | gig_dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver: %d, arg: %ld)", | |
139 | dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver:%d,arg: %ld)", | 131 | cntrl->driver, cntrl->arg); |
140 | cntrl->driver, cntrl->arg); | ||
141 | 132 | ||
142 | warn("ISDN_CMD_IOCTL is not supported."); | 133 | warn("ISDN_CMD_IOCTL is not supported."); |
143 | return -EINVAL; | 134 | return -EINVAL; |
144 | 135 | ||
145 | case ISDN_CMD_DIAL: | 136 | case ISDN_CMD_DIAL: |
146 | dbg(DEBUG_ANY, "ISDN_CMD_DIAL (driver: %d, channel: %ld, " | 137 | gig_dbg(DEBUG_ANY, |
147 | "phone: %s,ownmsn: %s, si1: %d, si2: %d)", | 138 | "ISDN_CMD_DIAL (driver: %d, ch: %ld, " |
148 | cntrl->driver, cntrl->arg, | 139 | "phone: %s, ownmsn: %s, si1: %d, si2: %d)", |
149 | cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn, | 140 | cntrl->driver, cntrl->arg, |
150 | cntrl->parm.setup.si1, cntrl->parm.setup.si2); | 141 | cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn, |
142 | cntrl->parm.setup.si1, cntrl->parm.setup.si2); | ||
151 | 143 | ||
152 | if (cntrl->arg >= cs->channels) { | 144 | if (cntrl->arg >= cs->channels) { |
153 | err("invalid channel (%d)", (int) cntrl->arg); | 145 | err("ISDN_CMD_DIAL: invalid channel (%d)", |
146 | (int) cntrl->arg); | ||
154 | return -EINVAL; | 147 | return -EINVAL; |
155 | } | 148 | } |
156 | 149 | ||
157 | bcs = cs->bcs + cntrl->arg; | 150 | bcs = cs->bcs + cntrl->arg; |
158 | 151 | ||
159 | if (!gigaset_get_channel(bcs)) { | 152 | if (!gigaset_get_channel(bcs)) { |
160 | err("channel not free"); | 153 | err("ISDN_CMD_DIAL: channel not free"); |
161 | return -EBUSY; | 154 | return -EBUSY; |
162 | } | 155 | } |
163 | 156 | ||
@@ -169,42 +162,46 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
169 | } | 162 | } |
170 | *sp = cntrl->parm.setup; | 163 | *sp = cntrl->parm.setup; |
171 | 164 | ||
172 | if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, | 165 | spin_lock_irqsave(&cs->lock, flags); |
173 | atomic_read(&bcs->at_state.seq_index), | 166 | param = bcs->at_state.seq_index; |
174 | NULL)) { | 167 | spin_unlock_irqrestore(&cs->lock, flags); |
168 | |||
169 | if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, param, | ||
170 | NULL)) { | ||
175 | //FIXME what should we do? | 171 | //FIXME what should we do? |
176 | kfree(sp); | 172 | kfree(sp); |
177 | gigaset_free_channel(bcs); | 173 | gigaset_free_channel(bcs); |
178 | return -ENOMEM; | 174 | return -ENOMEM; |
179 | } | 175 | } |
180 | 176 | ||
181 | dbg(DEBUG_CMD, "scheduling DIAL"); | 177 | gig_dbg(DEBUG_CMD, "scheduling DIAL"); |
182 | gigaset_schedule_event(cs); | 178 | gigaset_schedule_event(cs); |
183 | break; | 179 | break; |
184 | case ISDN_CMD_ACCEPTD: //FIXME | 180 | case ISDN_CMD_ACCEPTD: //FIXME |
185 | dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD"); | 181 | gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD"); |
186 | 182 | ||
187 | if (cntrl->arg >= cs->channels) { | 183 | if (cntrl->arg >= cs->channels) { |
188 | err("invalid channel (%d)", (int) cntrl->arg); | 184 | err("ISDN_CMD_ACCEPTD: invalid channel (%d)", |
185 | (int) cntrl->arg); | ||
189 | return -EINVAL; | 186 | return -EINVAL; |
190 | } | 187 | } |
191 | 188 | ||
192 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, | 189 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, |
193 | EV_ACCEPT, NULL, 0, NULL)) { | 190 | EV_ACCEPT, NULL, 0, NULL)) { |
194 | //FIXME what should we do? | 191 | //FIXME what should we do? |
195 | return -ENOMEM; | 192 | return -ENOMEM; |
196 | } | 193 | } |
197 | 194 | ||
198 | dbg(DEBUG_CMD, "scheduling ACCEPT"); | 195 | gig_dbg(DEBUG_CMD, "scheduling ACCEPT"); |
199 | gigaset_schedule_event(cs); | 196 | gigaset_schedule_event(cs); |
200 | 197 | ||
201 | break; | 198 | break; |
202 | case ISDN_CMD_ACCEPTB: | 199 | case ISDN_CMD_ACCEPTB: |
203 | dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTB"); | 200 | gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTB"); |
204 | break; | 201 | break; |
205 | case ISDN_CMD_HANGUP: | 202 | case ISDN_CMD_HANGUP: |
206 | dbg(DEBUG_ANY, | 203 | gig_dbg(DEBUG_ANY, "ISDN_CMD_HANGUP (ch: %d)", |
207 | "ISDN_CMD_HANGUP (channel: %d)", (int) cntrl->arg); | 204 | (int) cntrl->arg); |
208 | 205 | ||
209 | if (cntrl->arg >= cs->channels) { | 206 | if (cntrl->arg >= cs->channels) { |
210 | err("ISDN_CMD_HANGUP: invalid channel (%u)", | 207 | err("ISDN_CMD_HANGUP: invalid channel (%u)", |
@@ -213,66 +210,68 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
213 | } | 210 | } |
214 | 211 | ||
215 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, | 212 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, |
216 | EV_HUP, NULL, 0, NULL)) { | 213 | EV_HUP, NULL, 0, NULL)) { |
217 | //FIXME what should we do? | 214 | //FIXME what should we do? |
218 | return -ENOMEM; | 215 | return -ENOMEM; |
219 | } | 216 | } |
220 | 217 | ||
221 | dbg(DEBUG_CMD, "scheduling HUP"); | 218 | gig_dbg(DEBUG_CMD, "scheduling HUP"); |
222 | gigaset_schedule_event(cs); | 219 | gigaset_schedule_event(cs); |
223 | 220 | ||
224 | break; | 221 | break; |
225 | case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ //FIXME | 222 | case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ //FIXME |
226 | dbg(DEBUG_ANY, "ISDN_CMD_CLREAZ"); | 223 | gig_dbg(DEBUG_ANY, "ISDN_CMD_CLREAZ"); |
227 | break; | 224 | break; |
228 | case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ //FIXME | 225 | case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ //FIXME |
229 | dbg(DEBUG_ANY, | 226 | gig_dbg(DEBUG_ANY, |
230 | "ISDN_CMD_SETEAZ (id:%d, channel: %ld, number: %s)", | 227 | "ISDN_CMD_SETEAZ (id: %d, ch: %ld, number: %s)", |
231 | cntrl->driver, cntrl->arg, cntrl->parm.num); | 228 | cntrl->driver, cntrl->arg, cntrl->parm.num); |
232 | break; | 229 | break; |
233 | case ISDN_CMD_SETL2: /* Set L2 to given protocol */ | 230 | case ISDN_CMD_SETL2: /* Set L2 to given protocol */ |
234 | dbg(DEBUG_ANY, "ISDN_CMD_SETL2 (Channel: %ld, Proto: %lx)", | 231 | gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL2 (ch: %ld, proto: %lx)", |
235 | cntrl->arg & 0xff, (cntrl->arg >> 8)); | 232 | cntrl->arg & 0xff, (cntrl->arg >> 8)); |
236 | 233 | ||
237 | if ((cntrl->arg & 0xff) >= cs->channels) { | 234 | if ((cntrl->arg & 0xff) >= cs->channels) { |
238 | err("invalid channel (%u)", | 235 | err("ISDN_CMD_SETL2: invalid channel (%u)", |
239 | (unsigned) cntrl->arg & 0xff); | 236 | (unsigned) cntrl->arg & 0xff); |
240 | return -EINVAL; | 237 | return -EINVAL; |
241 | } | 238 | } |
242 | 239 | ||
243 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg & 0xff].at_state, | 240 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg & 0xff].at_state, |
244 | EV_PROTO_L2, NULL, cntrl->arg >> 8, | 241 | EV_PROTO_L2, NULL, cntrl->arg >> 8, |
245 | NULL)) { | 242 | NULL)) { |
246 | //FIXME what should we do? | 243 | //FIXME what should we do? |
247 | return -ENOMEM; | 244 | return -ENOMEM; |
248 | } | 245 | } |
249 | 246 | ||
250 | dbg(DEBUG_CMD, "scheduling PROTO_L2"); | 247 | gig_dbg(DEBUG_CMD, "scheduling PROTO_L2"); |
251 | gigaset_schedule_event(cs); | 248 | gigaset_schedule_event(cs); |
252 | break; | 249 | break; |
253 | case ISDN_CMD_SETL3: /* Set L3 to given protocol */ | 250 | case ISDN_CMD_SETL3: /* Set L3 to given protocol */ |
254 | dbg(DEBUG_ANY, "ISDN_CMD_SETL3 (Channel: %ld, Proto: %lx)", | 251 | gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL3 (ch: %ld, proto: %lx)", |
255 | cntrl->arg & 0xff, (cntrl->arg >> 8)); | 252 | cntrl->arg & 0xff, (cntrl->arg >> 8)); |
256 | 253 | ||
257 | if ((cntrl->arg & 0xff) >= cs->channels) { | 254 | if ((cntrl->arg & 0xff) >= cs->channels) { |
258 | err("invalid channel (%u)", | 255 | err("ISDN_CMD_SETL3: invalid channel (%u)", |
259 | (unsigned) cntrl->arg & 0xff); | 256 | (unsigned) cntrl->arg & 0xff); |
260 | return -EINVAL; | 257 | return -EINVAL; |
261 | } | 258 | } |
262 | 259 | ||
263 | if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) { | 260 | if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) { |
264 | err("invalid protocol %lu", cntrl->arg >> 8); | 261 | err("ISDN_CMD_SETL3: invalid protocol %lu", |
262 | cntrl->arg >> 8); | ||
265 | return -EINVAL; | 263 | return -EINVAL; |
266 | } | 264 | } |
267 | 265 | ||
268 | break; | 266 | break; |
269 | case ISDN_CMD_PROCEED: | 267 | case ISDN_CMD_PROCEED: |
270 | dbg(DEBUG_ANY, "ISDN_CMD_PROCEED"); //FIXME | 268 | gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED"); //FIXME |
271 | break; | 269 | break; |
272 | case ISDN_CMD_ALERT: | 270 | case ISDN_CMD_ALERT: |
273 | dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME | 271 | gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME |
274 | if (cntrl->arg >= cs->channels) { | 272 | if (cntrl->arg >= cs->channels) { |
275 | err("invalid channel (%d)", (int) cntrl->arg); | 273 | err("ISDN_CMD_ALERT: invalid channel (%d)", |
274 | (int) cntrl->arg); | ||
276 | return -EINVAL; | 275 | return -EINVAL; |
277 | } | 276 | } |
278 | //bcs = cs->bcs + cntrl->arg; | 277 | //bcs = cs->bcs + cntrl->arg; |
@@ -280,32 +279,31 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
280 | // FIXME | 279 | // FIXME |
281 | break; | 280 | break; |
282 | case ISDN_CMD_REDIR: | 281 | case ISDN_CMD_REDIR: |
283 | dbg(DEBUG_ANY, "ISDN_CMD_REDIR"); //FIXME | 282 | gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR"); //FIXME |
284 | break; | 283 | break; |
285 | case ISDN_CMD_PROT_IO: | 284 | case ISDN_CMD_PROT_IO: |
286 | dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO"); | 285 | gig_dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO"); |
287 | break; | 286 | break; |
288 | case ISDN_CMD_FAXCMD: | 287 | case ISDN_CMD_FAXCMD: |
289 | dbg(DEBUG_ANY, "ISDN_CMD_FAXCMD"); | 288 | gig_dbg(DEBUG_ANY, "ISDN_CMD_FAXCMD"); |
290 | break; | 289 | break; |
291 | case ISDN_CMD_GETL2: | 290 | case ISDN_CMD_GETL2: |
292 | dbg(DEBUG_ANY, "ISDN_CMD_GETL2"); | 291 | gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL2"); |
293 | break; | 292 | break; |
294 | case ISDN_CMD_GETL3: | 293 | case ISDN_CMD_GETL3: |
295 | dbg(DEBUG_ANY, "ISDN_CMD_GETL3"); | 294 | gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL3"); |
296 | break; | 295 | break; |
297 | case ISDN_CMD_GETEAZ: | 296 | case ISDN_CMD_GETEAZ: |
298 | dbg(DEBUG_ANY, "ISDN_CMD_GETEAZ"); | 297 | gig_dbg(DEBUG_ANY, "ISDN_CMD_GETEAZ"); |
299 | break; | 298 | break; |
300 | case ISDN_CMD_SETSIL: | 299 | case ISDN_CMD_SETSIL: |
301 | dbg(DEBUG_ANY, "ISDN_CMD_SETSIL"); | 300 | gig_dbg(DEBUG_ANY, "ISDN_CMD_SETSIL"); |
302 | break; | 301 | break; |
303 | case ISDN_CMD_GETSIL: | 302 | case ISDN_CMD_GETSIL: |
304 | dbg(DEBUG_ANY, "ISDN_CMD_GETSIL"); | 303 | gig_dbg(DEBUG_ANY, "ISDN_CMD_GETSIL"); |
305 | break; | 304 | break; |
306 | default: | 305 | default: |
307 | err("unknown command %d from LL", | 306 | err("unknown command %d from LL", cntrl->command); |
308 | cntrl->command); | ||
309 | return -EINVAL; | 307 | return -EINVAL; |
310 | } | 308 | } |
311 | 309 | ||
@@ -350,7 +348,8 @@ int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data) | |||
350 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ | 348 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ |
351 | break; | 349 | break; |
352 | default: | 350 | default: |
353 | err("invalid protocol: %u", bcs->proto2); | 351 | dev_err(bcs->cs->dev, "%s: invalid L2 protocol: %u\n", |
352 | __func__, bcs->proto2); | ||
354 | return -EINVAL; | 353 | return -EINVAL; |
355 | } | 354 | } |
356 | 355 | ||
@@ -378,7 +377,7 @@ int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data) | |||
378 | bcs->commands[i] = NULL; | 377 | bcs->commands[i] = NULL; |
379 | if (length[i] && | 378 | if (length[i] && |
380 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { | 379 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { |
381 | err("out of memory"); | 380 | dev_err(bcs->cs->dev, "out of memory\n"); |
382 | return -ENOMEM; | 381 | return -ENOMEM; |
383 | } | 382 | } |
384 | } | 383 | } |
@@ -396,10 +395,14 @@ int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data) | |||
396 | } | 395 | } |
397 | 396 | ||
398 | if (bcs->commands[AT_MSN]) | 397 | if (bcs->commands[AT_MSN]) |
399 | snprintf(bcs->commands[AT_MSN], length[AT_MSN], "^SMSN=%s\r", sp->eazmsn); | 398 | snprintf(bcs->commands[AT_MSN], length[AT_MSN], |
400 | snprintf(bcs->commands[AT_BC ], length[AT_BC ], "^SBC=%s\r", bc); | 399 | "^SMSN=%s\r", sp->eazmsn); |
401 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], "^SBPR=%u\r", proto); | 400 | snprintf(bcs->commands[AT_BC ], length[AT_BC ], |
402 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], "^SISO=%u\r", (unsigned)bcs->channel + 1); | 401 | "^SBC=%s\r", bc); |
402 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], | ||
403 | "^SBPR=%u\r", proto); | ||
404 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], | ||
405 | "^SISO=%u\r", (unsigned)bcs->channel + 1); | ||
403 | 406 | ||
404 | return 0; | 407 | return 0; |
405 | } | 408 | } |
@@ -419,7 +422,8 @@ int gigaset_isdn_setup_accept(struct at_state_t *at_state) | |||
419 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ | 422 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ |
420 | break; | 423 | break; |
421 | default: | 424 | default: |
422 | err("invalid protocol: %u", bcs->proto2); | 425 | dev_err(at_state->cs->dev, "%s: invalid protocol: %u\n", |
426 | __func__, bcs->proto2); | ||
423 | return -EINVAL; | 427 | return -EINVAL; |
424 | } | 428 | } |
425 | 429 | ||
@@ -436,13 +440,15 @@ int gigaset_isdn_setup_accept(struct at_state_t *at_state) | |||
436 | bcs->commands[i] = NULL; | 440 | bcs->commands[i] = NULL; |
437 | if (length[i] && | 441 | if (length[i] && |
438 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { | 442 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { |
439 | err("out of memory"); | 443 | dev_err(at_state->cs->dev, "out of memory\n"); |
440 | return -ENOMEM; | 444 | return -ENOMEM; |
441 | } | 445 | } |
442 | } | 446 | } |
443 | 447 | ||
444 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], "^SBPR=%u\r", proto); | 448 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], |
445 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], "^SISO=%u\r", (unsigned) bcs->channel + 1); | 449 | "^SBPR=%u\r", proto); |
450 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], | ||
451 | "^SISO=%u\r", (unsigned) bcs->channel + 1); | ||
446 | 452 | ||
447 | return 0; | 453 | return 0; |
448 | } | 454 | } |
@@ -473,7 +479,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
473 | response.parm.setup.si1 = 1; | 479 | response.parm.setup.si1 = 1; |
474 | response.parm.setup.si2 = 2; | 480 | response.parm.setup.si2 = 2; |
475 | } else { | 481 | } else { |
476 | warn("RING ignored - unsupported BC %s", | 482 | dev_warn(cs->dev, "RING ignored - unsupported BC %s\n", |
477 | at_state->str_var[STR_ZBC]); | 483 | at_state->str_var[STR_ZBC]); |
478 | return ICALL_IGNORE; | 484 | return ICALL_IGNORE; |
479 | } | 485 | } |
@@ -491,18 +497,17 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
491 | response.parm.setup.eazmsn[0] = 0; | 497 | response.parm.setup.eazmsn[0] = 0; |
492 | 498 | ||
493 | if (!bcs) { | 499 | if (!bcs) { |
494 | notice("no channel for incoming call"); | 500 | dev_notice(cs->dev, "no channel for incoming call\n"); |
495 | dbg(DEBUG_CMD, "Sending ICALLW"); | ||
496 | response.command = ISDN_STAT_ICALLW; | 501 | response.command = ISDN_STAT_ICALLW; |
497 | response.arg = 0; //FIXME | 502 | response.arg = 0; //FIXME |
498 | } else { | 503 | } else { |
499 | dbg(DEBUG_CMD, "Sending ICALL"); | 504 | gig_dbg(DEBUG_CMD, "Sending ICALL"); |
500 | response.command = ISDN_STAT_ICALL; | 505 | response.command = ISDN_STAT_ICALL; |
501 | response.arg = bcs->channel; //FIXME | 506 | response.arg = bcs->channel; //FIXME |
502 | } | 507 | } |
503 | response.driver = cs->myid; | 508 | response.driver = cs->myid; |
504 | retval = cs->iif.statcallb(&response); | 509 | retval = cs->iif.statcallb(&response); |
505 | dbg(DEBUG_CMD, "Response: %d", retval); | 510 | gig_dbg(DEBUG_CMD, "Response: %d", retval); |
506 | switch (retval) { | 511 | switch (retval) { |
507 | case 0: /* no takers */ | 512 | case 0: /* no takers */ |
508 | return ICALL_IGNORE; | 513 | return ICALL_IGNORE; |
@@ -512,7 +517,8 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
512 | case 2: /* reject */ | 517 | case 2: /* reject */ |
513 | return ICALL_REJECT; | 518 | return ICALL_REJECT; |
514 | case 3: /* incomplete */ | 519 | case 3: /* incomplete */ |
515 | warn("LL requested unsupported feature: Incomplete Number"); | 520 | dev_warn(cs->dev, |
521 | "LL requested unsupported feature: Incomplete Number\n"); | ||
516 | return ICALL_IGNORE; | 522 | return ICALL_IGNORE; |
517 | case 4: /* proceeding */ | 523 | case 4: /* proceeding */ |
518 | /* Gigaset will send ALERTING anyway. | 524 | /* Gigaset will send ALERTING anyway. |
@@ -520,10 +526,11 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
520 | */ | 526 | */ |
521 | return ICALL_ACCEPT; | 527 | return ICALL_ACCEPT; |
522 | case 5: /* deflect */ | 528 | case 5: /* deflect */ |
523 | warn("LL requested unsupported feature: Call Deflection"); | 529 | dev_warn(cs->dev, |
530 | "LL requested unsupported feature: Call Deflection\n"); | ||
524 | return ICALL_IGNORE; | 531 | return ICALL_IGNORE; |
525 | default: | 532 | default: |
526 | err("LL error %d on ICALL", retval); | 533 | dev_err(cs->dev, "LL error %d on ICALL\n", retval); |
527 | return ICALL_IGNORE; | 534 | return ICALL_IGNORE; |
528 | } | 535 | } |
529 | } | 536 | } |
@@ -533,7 +540,7 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) | |||
533 | { | 540 | { |
534 | isdn_if *iif = &cs->iif; | 541 | isdn_if *iif = &cs->iif; |
535 | 542 | ||
536 | dbg(DEBUG_ANY, "Register driver capabilities to LL"); | 543 | gig_dbg(DEBUG_ANY, "Register driver capabilities to LL"); |
537 | 544 | ||
538 | //iif->id[sizeof(iif->id) - 1]=0; | 545 | //iif->id[sizeof(iif->id) - 1]=0; |
539 | //strncpy(iif->id, isdnid, sizeof(iif->id) - 1); | 546 | //strncpy(iif->id, isdnid, sizeof(iif->id) - 1); |
@@ -542,26 +549,26 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) | |||
542 | return -ENOMEM; //FIXME EINVAL/...?? | 549 | return -ENOMEM; //FIXME EINVAL/...?? |
543 | 550 | ||
544 | iif->owner = THIS_MODULE; | 551 | iif->owner = THIS_MODULE; |
545 | iif->channels = cs->channels; /* I am supporting just one channel *//* I was supporting...*/ | 552 | iif->channels = cs->channels; |
546 | iif->maxbufsize = MAX_BUF_SIZE; | 553 | iif->maxbufsize = MAX_BUF_SIZE; |
547 | iif->features = ISDN_FEATURE_L2_TRANS | /* Our device is very advanced, therefore */ | 554 | iif->features = ISDN_FEATURE_L2_TRANS | |
548 | ISDN_FEATURE_L2_HDLC | | 555 | ISDN_FEATURE_L2_HDLC | |
549 | #ifdef GIG_X75 | 556 | #ifdef GIG_X75 |
550 | ISDN_FEATURE_L2_X75I | | 557 | ISDN_FEATURE_L2_X75I | |
551 | #endif | 558 | #endif |
552 | ISDN_FEATURE_L3_TRANS | | 559 | ISDN_FEATURE_L3_TRANS | |
553 | ISDN_FEATURE_P_EURO; | 560 | ISDN_FEATURE_P_EURO; |
554 | iif->hl_hdrlen = HW_HDR_LEN; /* Area for storing ack */ | 561 | iif->hl_hdrlen = HW_HDR_LEN; /* Area for storing ack */ |
555 | iif->command = command_from_LL; | 562 | iif->command = command_from_LL; |
556 | iif->writebuf_skb = writebuf_from_LL; | 563 | iif->writebuf_skb = writebuf_from_LL; |
557 | iif->writecmd = NULL; /* Don't support isdnctrl */ | 564 | iif->writecmd = NULL; /* Don't support isdnctrl */ |
558 | iif->readstat = NULL; /* Don't support isdnctrl */ | 565 | iif->readstat = NULL; /* Don't support isdnctrl */ |
559 | iif->rcvcallb_skb = NULL; /* Will be set by LL */ | 566 | iif->rcvcallb_skb = NULL; /* Will be set by LL */ |
560 | iif->statcallb = NULL; /* Will be set by LL */ | 567 | iif->statcallb = NULL; /* Will be set by LL */ |
561 | 568 | ||
562 | if (!register_isdn(iif)) | 569 | if (!register_isdn(iif)) |
563 | return 0; | 570 | return 0; |
564 | 571 | ||
565 | cs->myid = iif->channels; /* Set my device id */ | 572 | cs->myid = iif->channels; /* Set my device id */ |
566 | return 1; | 573 | return 1; |
567 | } | 574 | } |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 3a81d9c65141..08e4c4eea14d 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * published by the Free Software Foundation; either version 2 of | 9 | * published by the Free Software Foundation; either version 2 of |
10 | * the License, or (at your option) any later version. | 10 | * the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * Version: $Id: interface.c,v 1.14.4.15 2006/02/04 18:28:16 hjlipp Exp $ | ||
13 | * ===================================================================== | ||
14 | */ | 12 | */ |
15 | 13 | ||
16 | #include "gigaset.h" | 14 | #include "gigaset.h" |
@@ -24,7 +22,7 @@ static int if_lock(struct cardstate *cs, int *arg) | |||
24 | { | 22 | { |
25 | int cmd = *arg; | 23 | int cmd = *arg; |
26 | 24 | ||
27 | dbg(DEBUG_IF, "%u: if_lock (%d)", cs->minor_index, cmd); | 25 | gig_dbg(DEBUG_IF, "%u: if_lock (%d)", cs->minor_index, cmd); |
28 | 26 | ||
29 | if (cmd > 1) | 27 | if (cmd > 1) |
30 | return -EINVAL; | 28 | return -EINVAL; |
@@ -35,7 +33,7 @@ static int if_lock(struct cardstate *cs, int *arg) | |||
35 | } | 33 | } |
36 | 34 | ||
37 | if (!cmd && atomic_read(&cs->mstate) == MS_LOCKED | 35 | if (!cmd && atomic_read(&cs->mstate) == MS_LOCKED |
38 | && atomic_read(&cs->connected)) { | 36 | && cs->connected) { |
39 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); | 37 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); |
40 | cs->ops->baud_rate(cs, B115200); | 38 | cs->ops->baud_rate(cs, B115200); |
41 | cs->ops->set_line_ctrl(cs, CS8); | 39 | cs->ops->set_line_ctrl(cs, CS8); |
@@ -44,12 +42,12 @@ static int if_lock(struct cardstate *cs, int *arg) | |||
44 | 42 | ||
45 | cs->waiting = 1; | 43 | cs->waiting = 1; |
46 | if (!gigaset_add_event(cs, &cs->at_state, EV_IF_LOCK, | 44 | if (!gigaset_add_event(cs, &cs->at_state, EV_IF_LOCK, |
47 | NULL, cmd, NULL)) { | 45 | NULL, cmd, NULL)) { |
48 | cs->waiting = 0; | 46 | cs->waiting = 0; |
49 | return -ENOMEM; | 47 | return -ENOMEM; |
50 | } | 48 | } |
51 | 49 | ||
52 | dbg(DEBUG_CMD, "scheduling IF_LOCK"); | 50 | gig_dbg(DEBUG_CMD, "scheduling IF_LOCK"); |
53 | gigaset_schedule_event(cs); | 51 | gigaset_schedule_event(cs); |
54 | 52 | ||
55 | wait_event(cs->waitqueue, !cs->waiting); | 53 | wait_event(cs->waitqueue, !cs->waiting); |
@@ -68,7 +66,7 @@ static int if_version(struct cardstate *cs, unsigned arg[4]) | |||
68 | static const unsigned compat[4] = GIG_COMPAT; | 66 | static const unsigned compat[4] = GIG_COMPAT; |
69 | unsigned cmd = arg[0]; | 67 | unsigned cmd = arg[0]; |
70 | 68 | ||
71 | dbg(DEBUG_IF, "%u: if_version (%d)", cs->minor_index, cmd); | 69 | gig_dbg(DEBUG_IF, "%u: if_version (%d)", cs->minor_index, cmd); |
72 | 70 | ||
73 | switch (cmd) { | 71 | switch (cmd) { |
74 | case GIGVER_DRIVER: | 72 | case GIGVER_DRIVER: |
@@ -80,12 +78,12 @@ static int if_version(struct cardstate *cs, unsigned arg[4]) | |||
80 | case GIGVER_FWBASE: | 78 | case GIGVER_FWBASE: |
81 | cs->waiting = 1; | 79 | cs->waiting = 1; |
82 | if (!gigaset_add_event(cs, &cs->at_state, EV_IF_VER, | 80 | if (!gigaset_add_event(cs, &cs->at_state, EV_IF_VER, |
83 | NULL, 0, arg)) { | 81 | NULL, 0, arg)) { |
84 | cs->waiting = 0; | 82 | cs->waiting = 0; |
85 | return -ENOMEM; | 83 | return -ENOMEM; |
86 | } | 84 | } |
87 | 85 | ||
88 | dbg(DEBUG_CMD, "scheduling IF_VER"); | 86 | gig_dbg(DEBUG_CMD, "scheduling IF_VER"); |
89 | gigaset_schedule_event(cs); | 87 | gigaset_schedule_event(cs); |
90 | 88 | ||
91 | wait_event(cs->waitqueue, !cs->waiting); | 89 | wait_event(cs->waitqueue, !cs->waiting); |
@@ -101,7 +99,7 @@ static int if_version(struct cardstate *cs, unsigned arg[4]) | |||
101 | 99 | ||
102 | static int if_config(struct cardstate *cs, int *arg) | 100 | static int if_config(struct cardstate *cs, int *arg) |
103 | { | 101 | { |
104 | dbg(DEBUG_IF, "%u: if_config (%d)", cs->minor_index, *arg); | 102 | gig_dbg(DEBUG_IF, "%u: if_config (%d)", cs->minor_index, *arg); |
105 | 103 | ||
106 | if (*arg != 1) | 104 | if (*arg != 1) |
107 | return -EINVAL; | 105 | return -EINVAL; |
@@ -109,6 +107,11 @@ static int if_config(struct cardstate *cs, int *arg) | |||
109 | if (atomic_read(&cs->mstate) != MS_LOCKED) | 107 | if (atomic_read(&cs->mstate) != MS_LOCKED) |
110 | return -EBUSY; | 108 | return -EBUSY; |
111 | 109 | ||
110 | if (!cs->connected) { | ||
111 | err("not connected!"); | ||
112 | return -ENODEV; | ||
113 | } | ||
114 | |||
112 | *arg = 0; | 115 | *arg = 0; |
113 | return gigaset_enterconfigmode(cs); | 116 | return gigaset_enterconfigmode(cs); |
114 | } | 117 | } |
@@ -119,7 +122,7 @@ static int if_config(struct cardstate *cs, int *arg) | |||
119 | static int if_open(struct tty_struct *tty, struct file *filp); | 122 | static int if_open(struct tty_struct *tty, struct file *filp); |
120 | static void if_close(struct tty_struct *tty, struct file *filp); | 123 | static void if_close(struct tty_struct *tty, struct file *filp); |
121 | static int if_ioctl(struct tty_struct *tty, struct file *file, | 124 | static int if_ioctl(struct tty_struct *tty, struct file *file, |
122 | unsigned int cmd, unsigned long arg); | 125 | unsigned int cmd, unsigned long arg); |
123 | static int if_write_room(struct tty_struct *tty); | 126 | static int if_write_room(struct tty_struct *tty); |
124 | static int if_chars_in_buffer(struct tty_struct *tty); | 127 | static int if_chars_in_buffer(struct tty_struct *tty); |
125 | static void if_throttle(struct tty_struct *tty); | 128 | static void if_throttle(struct tty_struct *tty); |
@@ -127,9 +130,9 @@ static void if_unthrottle(struct tty_struct *tty); | |||
127 | static void if_set_termios(struct tty_struct *tty, struct termios *old); | 130 | static void if_set_termios(struct tty_struct *tty, struct termios *old); |
128 | static int if_tiocmget(struct tty_struct *tty, struct file *file); | 131 | static int if_tiocmget(struct tty_struct *tty, struct file *file); |
129 | static int if_tiocmset(struct tty_struct *tty, struct file *file, | 132 | static int if_tiocmset(struct tty_struct *tty, struct file *file, |
130 | unsigned int set, unsigned int clear); | 133 | unsigned int set, unsigned int clear); |
131 | static int if_write(struct tty_struct *tty, | 134 | static int if_write(struct tty_struct *tty, |
132 | const unsigned char *buf, int count); | 135 | const unsigned char *buf, int count); |
133 | 136 | ||
134 | static struct tty_operations if_ops = { | 137 | static struct tty_operations if_ops = { |
135 | .open = if_open, | 138 | .open = if_open, |
@@ -153,8 +156,8 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
153 | struct cardstate *cs; | 156 | struct cardstate *cs; |
154 | unsigned long flags; | 157 | unsigned long flags; |
155 | 158 | ||
156 | dbg(DEBUG_IF, "%d+%d: %s()", tty->driver->minor_start, tty->index, | 159 | gig_dbg(DEBUG_IF, "%d+%d: %s()", |
157 | __FUNCTION__); | 160 | tty->driver->minor_start, tty->index, __func__); |
158 | 161 | ||
159 | tty->driver_data = NULL; | 162 | tty->driver_data = NULL; |
160 | 163 | ||
@@ -162,7 +165,7 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
162 | if (!cs) | 165 | if (!cs) |
163 | return -ENODEV; | 166 | return -ENODEV; |
164 | 167 | ||
165 | if (down_interruptible(&cs->sem)) | 168 | if (mutex_lock_interruptible(&cs->mutex)) |
166 | return -ERESTARTSYS; // FIXME -EINTR? | 169 | return -ERESTARTSYS; // FIXME -EINTR? |
167 | tty->driver_data = cs; | 170 | tty->driver_data = cs; |
168 | 171 | ||
@@ -173,10 +176,9 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
173 | cs->tty = tty; | 176 | cs->tty = tty; |
174 | spin_unlock_irqrestore(&cs->lock, flags); | 177 | spin_unlock_irqrestore(&cs->lock, flags); |
175 | tty->low_latency = 1; //FIXME test | 178 | tty->low_latency = 1; //FIXME test |
176 | //FIXME | ||
177 | } | 179 | } |
178 | 180 | ||
179 | up(&cs->sem); | 181 | mutex_unlock(&cs->mutex); |
180 | return 0; | 182 | return 0; |
181 | } | 183 | } |
182 | 184 | ||
@@ -187,30 +189,29 @@ static void if_close(struct tty_struct *tty, struct file *filp) | |||
187 | 189 | ||
188 | cs = (struct cardstate *) tty->driver_data; | 190 | cs = (struct cardstate *) tty->driver_data; |
189 | if (!cs) { | 191 | if (!cs) { |
190 | err("cs==NULL in %s", __FUNCTION__); | 192 | err("cs==NULL in %s", __func__); |
191 | return; | 193 | return; |
192 | } | 194 | } |
193 | 195 | ||
194 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 196 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
195 | 197 | ||
196 | down(&cs->sem); | 198 | mutex_lock(&cs->mutex); |
197 | 199 | ||
198 | if (!cs->open_count) | 200 | if (!cs->open_count) |
199 | warn("%s: device not opened", __FUNCTION__); | 201 | warn("%s: device not opened", __func__); |
200 | else { | 202 | else { |
201 | if (!--cs->open_count) { | 203 | if (!--cs->open_count) { |
202 | spin_lock_irqsave(&cs->lock, flags); | 204 | spin_lock_irqsave(&cs->lock, flags); |
203 | cs->tty = NULL; | 205 | cs->tty = NULL; |
204 | spin_unlock_irqrestore(&cs->lock, flags); | 206 | spin_unlock_irqrestore(&cs->lock, flags); |
205 | //FIXME | ||
206 | } | 207 | } |
207 | } | 208 | } |
208 | 209 | ||
209 | up(&cs->sem); | 210 | mutex_unlock(&cs->mutex); |
210 | } | 211 | } |
211 | 212 | ||
212 | static int if_ioctl(struct tty_struct *tty, struct file *file, | 213 | static int if_ioctl(struct tty_struct *tty, struct file *file, |
213 | unsigned int cmd, unsigned long arg) | 214 | unsigned int cmd, unsigned long arg) |
214 | { | 215 | { |
215 | struct cardstate *cs; | 216 | struct cardstate *cs; |
216 | int retval = -ENODEV; | 217 | int retval = -ENODEV; |
@@ -220,17 +221,17 @@ static int if_ioctl(struct tty_struct *tty, struct file *file, | |||
220 | 221 | ||
221 | cs = (struct cardstate *) tty->driver_data; | 222 | cs = (struct cardstate *) tty->driver_data; |
222 | if (!cs) { | 223 | if (!cs) { |
223 | err("cs==NULL in %s", __FUNCTION__); | 224 | err("cs==NULL in %s", __func__); |
224 | return -ENODEV; | 225 | return -ENODEV; |
225 | } | 226 | } |
226 | 227 | ||
227 | dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __FUNCTION__, cmd); | 228 | gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd); |
228 | 229 | ||
229 | if (down_interruptible(&cs->sem)) | 230 | if (mutex_lock_interruptible(&cs->mutex)) |
230 | return -ERESTARTSYS; // FIXME -EINTR? | 231 | return -ERESTARTSYS; // FIXME -EINTR? |
231 | 232 | ||
232 | if (!cs->open_count) | 233 | if (!cs->open_count) |
233 | warn("%s: device not opened", __FUNCTION__); | 234 | warn("%s: device not opened", __func__); |
234 | else { | 235 | else { |
235 | retval = 0; | 236 | retval = 0; |
236 | switch (cmd) { | 237 | switch (cmd) { |
@@ -250,37 +251,40 @@ static int if_ioctl(struct tty_struct *tty, struct file *file, | |||
250 | break; | 251 | break; |
251 | case GIGASET_BRKCHARS: | 252 | case GIGASET_BRKCHARS: |
252 | //FIXME test if MS_LOCKED | 253 | //FIXME test if MS_LOCKED |
253 | gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS", | 254 | if (!cs->connected) { |
254 | 6, (const unsigned char *) arg, 1); | 255 | gig_dbg(DEBUG_ANY, |
255 | if (!atomic_read(&cs->connected)) { | 256 | "can't communicate with unplugged device"); |
256 | dbg(DEBUG_ANY, "can't communicate with unplugged device"); | ||
257 | retval = -ENODEV; | 257 | retval = -ENODEV; |
258 | break; | 258 | break; |
259 | } | 259 | } |
260 | retval = copy_from_user(&buf, | 260 | retval = copy_from_user(&buf, |
261 | (const unsigned char __user *) arg, 6) | 261 | (const unsigned char __user *) arg, 6) |
262 | ? -EFAULT : 0; | 262 | ? -EFAULT : 0; |
263 | if (retval >= 0) | 263 | if (retval >= 0) { |
264 | gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS", | ||
265 | 6, (const unsigned char *) arg); | ||
264 | retval = cs->ops->brkchars(cs, buf); | 266 | retval = cs->ops->brkchars(cs, buf); |
267 | } | ||
265 | break; | 268 | break; |
266 | case GIGASET_VERSION: | 269 | case GIGASET_VERSION: |
267 | retval = copy_from_user(version, (unsigned __user *) arg, | 270 | retval = copy_from_user(version, |
268 | sizeof version) ? -EFAULT : 0; | 271 | (unsigned __user *) arg, sizeof version) |
272 | ? -EFAULT : 0; | ||
269 | if (retval >= 0) | 273 | if (retval >= 0) |
270 | retval = if_version(cs, version); | 274 | retval = if_version(cs, version); |
271 | if (retval >= 0) | 275 | if (retval >= 0) |
272 | retval = copy_to_user((unsigned __user *) arg, version, | 276 | retval = copy_to_user((unsigned __user *) arg, |
273 | sizeof version) | 277 | version, sizeof version) |
274 | ? -EFAULT : 0; | 278 | ? -EFAULT : 0; |
275 | break; | 279 | break; |
276 | default: | 280 | default: |
277 | dbg(DEBUG_ANY, "%s: arg not supported - 0x%04x", | 281 | gig_dbg(DEBUG_ANY, "%s: arg not supported - 0x%04x", |
278 | __FUNCTION__, cmd); | 282 | __func__, cmd); |
279 | retval = -ENOIOCTLCMD; | 283 | retval = -ENOIOCTLCMD; |
280 | } | 284 | } |
281 | } | 285 | } |
282 | 286 | ||
283 | up(&cs->sem); | 287 | mutex_unlock(&cs->mutex); |
284 | 288 | ||
285 | return retval; | 289 | return retval; |
286 | } | 290 | } |
@@ -292,25 +296,25 @@ static int if_tiocmget(struct tty_struct *tty, struct file *file) | |||
292 | 296 | ||
293 | cs = (struct cardstate *) tty->driver_data; | 297 | cs = (struct cardstate *) tty->driver_data; |
294 | if (!cs) { | 298 | if (!cs) { |
295 | err("cs==NULL in %s", __FUNCTION__); | 299 | err("cs==NULL in %s", __func__); |
296 | return -ENODEV; | 300 | return -ENODEV; |
297 | } | 301 | } |
298 | 302 | ||
299 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 303 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
300 | 304 | ||
301 | if (down_interruptible(&cs->sem)) | 305 | if (mutex_lock_interruptible(&cs->mutex)) |
302 | return -ERESTARTSYS; // FIXME -EINTR? | 306 | return -ERESTARTSYS; // FIXME -EINTR? |
303 | 307 | ||
304 | // FIXME read from device? | 308 | // FIXME read from device? |
305 | retval = cs->control_state & (TIOCM_RTS|TIOCM_DTR); | 309 | retval = cs->control_state & (TIOCM_RTS|TIOCM_DTR); |
306 | 310 | ||
307 | up(&cs->sem); | 311 | mutex_unlock(&cs->mutex); |
308 | 312 | ||
309 | return retval; | 313 | return retval; |
310 | } | 314 | } |
311 | 315 | ||
312 | static int if_tiocmset(struct tty_struct *tty, struct file *file, | 316 | static int if_tiocmset(struct tty_struct *tty, struct file *file, |
313 | unsigned int set, unsigned int clear) | 317 | unsigned int set, unsigned int clear) |
314 | { | 318 | { |
315 | struct cardstate *cs; | 319 | struct cardstate *cs; |
316 | int retval; | 320 | int retval; |
@@ -318,18 +322,18 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file, | |||
318 | 322 | ||
319 | cs = (struct cardstate *) tty->driver_data; | 323 | cs = (struct cardstate *) tty->driver_data; |
320 | if (!cs) { | 324 | if (!cs) { |
321 | err("cs==NULL in %s", __FUNCTION__); | 325 | err("cs==NULL in %s", __func__); |
322 | return -ENODEV; | 326 | return -ENODEV; |
323 | } | 327 | } |
324 | 328 | ||
325 | dbg(DEBUG_IF, | 329 | gig_dbg(DEBUG_IF, "%u: %s(0x%x, 0x%x)", |
326 | "%u: %s(0x%x, 0x%x)", cs->minor_index, __FUNCTION__, set, clear); | 330 | cs->minor_index, __func__, set, clear); |
327 | 331 | ||
328 | if (down_interruptible(&cs->sem)) | 332 | if (mutex_lock_interruptible(&cs->mutex)) |
329 | return -ERESTARTSYS; // FIXME -EINTR? | 333 | return -ERESTARTSYS; // FIXME -EINTR? |
330 | 334 | ||
331 | if (!atomic_read(&cs->connected)) { | 335 | if (!cs->connected) { |
332 | dbg(DEBUG_ANY, "can't communicate with unplugged device"); | 336 | gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); |
333 | retval = -ENODEV; | 337 | retval = -ENODEV; |
334 | } else { | 338 | } else { |
335 | mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR); | 339 | mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR); |
@@ -337,7 +341,7 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file, | |||
337 | cs->control_state = mc; | 341 | cs->control_state = mc; |
338 | } | 342 | } |
339 | 343 | ||
340 | up(&cs->sem); | 344 | mutex_unlock(&cs->mutex); |
341 | 345 | ||
342 | return retval; | 346 | return retval; |
343 | } | 347 | } |
@@ -349,29 +353,29 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
349 | 353 | ||
350 | cs = (struct cardstate *) tty->driver_data; | 354 | cs = (struct cardstate *) tty->driver_data; |
351 | if (!cs) { | 355 | if (!cs) { |
352 | err("cs==NULL in %s", __FUNCTION__); | 356 | err("cs==NULL in %s", __func__); |
353 | return -ENODEV; | 357 | return -ENODEV; |
354 | } | 358 | } |
355 | 359 | ||
356 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 360 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
357 | 361 | ||
358 | if (down_interruptible(&cs->sem)) | 362 | if (mutex_lock_interruptible(&cs->mutex)) |
359 | return -ERESTARTSYS; // FIXME -EINTR? | 363 | return -ERESTARTSYS; // FIXME -EINTR? |
360 | 364 | ||
361 | if (!cs->open_count) | 365 | if (!cs->open_count) |
362 | warn("%s: device not opened", __FUNCTION__); | 366 | warn("%s: device not opened", __func__); |
363 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { | 367 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { |
364 | warn("can't write to unlocked device"); | 368 | warn("can't write to unlocked device"); |
365 | retval = -EBUSY; | 369 | retval = -EBUSY; |
366 | } else if (!atomic_read(&cs->connected)) { | 370 | } else if (!cs->connected) { |
367 | dbg(DEBUG_ANY, "can't write to unplugged device"); | 371 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); |
368 | retval = -EBUSY; //FIXME | 372 | retval = -EBUSY; //FIXME |
369 | } else { | 373 | } else { |
370 | retval = cs->ops->write_cmd(cs, buf, count, | 374 | retval = cs->ops->write_cmd(cs, buf, count, |
371 | &cs->if_wake_tasklet); | 375 | &cs->if_wake_tasklet); |
372 | } | 376 | } |
373 | 377 | ||
374 | up(&cs->sem); | 378 | mutex_unlock(&cs->mutex); |
375 | 379 | ||
376 | return retval; | 380 | return retval; |
377 | } | 381 | } |
@@ -383,27 +387,27 @@ static int if_write_room(struct tty_struct *tty) | |||
383 | 387 | ||
384 | cs = (struct cardstate *) tty->driver_data; | 388 | cs = (struct cardstate *) tty->driver_data; |
385 | if (!cs) { | 389 | if (!cs) { |
386 | err("cs==NULL in %s", __FUNCTION__); | 390 | err("cs==NULL in %s", __func__); |
387 | return -ENODEV; | 391 | return -ENODEV; |
388 | } | 392 | } |
389 | 393 | ||
390 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 394 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
391 | 395 | ||
392 | if (down_interruptible(&cs->sem)) | 396 | if (mutex_lock_interruptible(&cs->mutex)) |
393 | return -ERESTARTSYS; // FIXME -EINTR? | 397 | return -ERESTARTSYS; // FIXME -EINTR? |
394 | 398 | ||
395 | if (!cs->open_count) | 399 | if (!cs->open_count) |
396 | warn("%s: device not opened", __FUNCTION__); | 400 | warn("%s: device not opened", __func__); |
397 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { | 401 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { |
398 | warn("can't write to unlocked device"); | 402 | warn("can't write to unlocked device"); |
399 | retval = -EBUSY; //FIXME | 403 | retval = -EBUSY; //FIXME |
400 | } else if (!atomic_read(&cs->connected)) { | 404 | } else if (!cs->connected) { |
401 | dbg(DEBUG_ANY, "can't write to unplugged device"); | 405 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); |
402 | retval = -EBUSY; //FIXME | 406 | retval = -EBUSY; //FIXME |
403 | } else | 407 | } else |
404 | retval = cs->ops->write_room(cs); | 408 | retval = cs->ops->write_room(cs); |
405 | 409 | ||
406 | up(&cs->sem); | 410 | mutex_unlock(&cs->mutex); |
407 | 411 | ||
408 | return retval; | 412 | return retval; |
409 | } | 413 | } |
@@ -415,27 +419,27 @@ static int if_chars_in_buffer(struct tty_struct *tty) | |||
415 | 419 | ||
416 | cs = (struct cardstate *) tty->driver_data; | 420 | cs = (struct cardstate *) tty->driver_data; |
417 | if (!cs) { | 421 | if (!cs) { |
418 | err("cs==NULL in %s", __FUNCTION__); | 422 | err("cs==NULL in %s", __func__); |
419 | return -ENODEV; | 423 | return -ENODEV; |
420 | } | 424 | } |
421 | 425 | ||
422 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 426 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
423 | 427 | ||
424 | if (down_interruptible(&cs->sem)) | 428 | if (mutex_lock_interruptible(&cs->mutex)) |
425 | return -ERESTARTSYS; // FIXME -EINTR? | 429 | return -ERESTARTSYS; // FIXME -EINTR? |
426 | 430 | ||
427 | if (!cs->open_count) | 431 | if (!cs->open_count) |
428 | warn("%s: device not opened", __FUNCTION__); | 432 | warn("%s: device not opened", __func__); |
429 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { | 433 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { |
430 | warn("can't write to unlocked device"); | 434 | warn("can't write to unlocked device"); |
431 | retval = -EBUSY; | 435 | retval = -EBUSY; |
432 | } else if (!atomic_read(&cs->connected)) { | 436 | } else if (!cs->connected) { |
433 | dbg(DEBUG_ANY, "can't write to unplugged device"); | 437 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); |
434 | retval = -EBUSY; //FIXME | 438 | retval = -EBUSY; //FIXME |
435 | } else | 439 | } else |
436 | retval = cs->ops->chars_in_buffer(cs); | 440 | retval = cs->ops->chars_in_buffer(cs); |
437 | 441 | ||
438 | up(&cs->sem); | 442 | mutex_unlock(&cs->mutex); |
439 | 443 | ||
440 | return retval; | 444 | return retval; |
441 | } | 445 | } |
@@ -446,21 +450,21 @@ static void if_throttle(struct tty_struct *tty) | |||
446 | 450 | ||
447 | cs = (struct cardstate *) tty->driver_data; | 451 | cs = (struct cardstate *) tty->driver_data; |
448 | if (!cs) { | 452 | if (!cs) { |
449 | err("cs==NULL in %s", __FUNCTION__); | 453 | err("cs==NULL in %s", __func__); |
450 | return; | 454 | return; |
451 | } | 455 | } |
452 | 456 | ||
453 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 457 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
454 | 458 | ||
455 | down(&cs->sem); | 459 | mutex_lock(&cs->mutex); |
456 | 460 | ||
457 | if (!cs->open_count) | 461 | if (!cs->open_count) |
458 | warn("%s: device not opened", __FUNCTION__); | 462 | warn("%s: device not opened", __func__); |
459 | else { | 463 | else { |
460 | //FIXME | 464 | //FIXME |
461 | } | 465 | } |
462 | 466 | ||
463 | up(&cs->sem); | 467 | mutex_unlock(&cs->mutex); |
464 | } | 468 | } |
465 | 469 | ||
466 | static void if_unthrottle(struct tty_struct *tty) | 470 | static void if_unthrottle(struct tty_struct *tty) |
@@ -469,21 +473,21 @@ static void if_unthrottle(struct tty_struct *tty) | |||
469 | 473 | ||
470 | cs = (struct cardstate *) tty->driver_data; | 474 | cs = (struct cardstate *) tty->driver_data; |
471 | if (!cs) { | 475 | if (!cs) { |
472 | err("cs==NULL in %s", __FUNCTION__); | 476 | err("cs==NULL in %s", __func__); |
473 | return; | 477 | return; |
474 | } | 478 | } |
475 | 479 | ||
476 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 480 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
477 | 481 | ||
478 | down(&cs->sem); | 482 | mutex_lock(&cs->mutex); |
479 | 483 | ||
480 | if (!cs->open_count) | 484 | if (!cs->open_count) |
481 | warn("%s: device not opened", __FUNCTION__); | 485 | warn("%s: device not opened", __func__); |
482 | else { | 486 | else { |
483 | //FIXME | 487 | //FIXME |
484 | } | 488 | } |
485 | 489 | ||
486 | up(&cs->sem); | 490 | mutex_unlock(&cs->mutex); |
487 | } | 491 | } |
488 | 492 | ||
489 | static void if_set_termios(struct tty_struct *tty, struct termios *old) | 493 | static void if_set_termios(struct tty_struct *tty, struct termios *old) |
@@ -496,21 +500,21 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
496 | 500 | ||
497 | cs = (struct cardstate *) tty->driver_data; | 501 | cs = (struct cardstate *) tty->driver_data; |
498 | if (!cs) { | 502 | if (!cs) { |
499 | err("cs==NULL in %s", __FUNCTION__); | 503 | err("cs==NULL in %s", __func__); |
500 | return; | 504 | return; |
501 | } | 505 | } |
502 | 506 | ||
503 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 507 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
504 | 508 | ||
505 | down(&cs->sem); | 509 | mutex_lock(&cs->mutex); |
506 | 510 | ||
507 | if (!cs->open_count) { | 511 | if (!cs->open_count) { |
508 | warn("%s: device not opened", __FUNCTION__); | 512 | warn("%s: device not opened", __func__); |
509 | goto out; | 513 | goto out; |
510 | } | 514 | } |
511 | 515 | ||
512 | if (!atomic_read(&cs->connected)) { | 516 | if (!cs->connected) { |
513 | dbg(DEBUG_ANY, "can't communicate with unplugged device"); | 517 | gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); |
514 | goto out; | 518 | goto out; |
515 | } | 519 | } |
516 | 520 | ||
@@ -518,8 +522,8 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
518 | iflag = tty->termios->c_iflag; | 522 | iflag = tty->termios->c_iflag; |
519 | cflag = tty->termios->c_cflag; | 523 | cflag = tty->termios->c_cflag; |
520 | old_cflag = old ? old->c_cflag : cflag; //FIXME? | 524 | old_cflag = old ? old->c_cflag : cflag; //FIXME? |
521 | dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", cs->minor_index, | 525 | gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", |
522 | iflag, cflag, old_cflag); | 526 | cs->minor_index, iflag, cflag, old_cflag); |
523 | 527 | ||
524 | /* get a local copy of the current port settings */ | 528 | /* get a local copy of the current port settings */ |
525 | control_state = cs->control_state; | 529 | control_state = cs->control_state; |
@@ -531,14 +535,15 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
531 | * Premature optimization is the root of all evil. | 535 | * Premature optimization is the root of all evil. |
532 | */ | 536 | */ |
533 | 537 | ||
534 | /* reassert DTR and (maybe) RTS on transition from B0 */ | 538 | /* reassert DTR and (maybe) RTS on transition from B0 */ |
535 | if ((old_cflag & CBAUD) == B0) { | 539 | if ((old_cflag & CBAUD) == B0) { |
536 | new_state = control_state | TIOCM_DTR; | 540 | new_state = control_state | TIOCM_DTR; |
537 | /* don't set RTS if using hardware flow control */ | 541 | /* don't set RTS if using hardware flow control */ |
538 | if (!(old_cflag & CRTSCTS)) | 542 | if (!(old_cflag & CRTSCTS)) |
539 | new_state |= TIOCM_RTS; | 543 | new_state |= TIOCM_RTS; |
540 | dbg(DEBUG_IF, "%u: from B0 - set DTR%s", cs->minor_index, | 544 | gig_dbg(DEBUG_IF, "%u: from B0 - set DTR%s", |
541 | (new_state & TIOCM_RTS) ? " only" : "/RTS"); | 545 | cs->minor_index, |
546 | (new_state & TIOCM_RTS) ? " only" : "/RTS"); | ||
542 | cs->ops->set_modem_ctrl(cs, control_state, new_state); | 547 | cs->ops->set_modem_ctrl(cs, control_state, new_state); |
543 | control_state = new_state; | 548 | control_state = new_state; |
544 | } | 549 | } |
@@ -547,7 +552,7 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
547 | 552 | ||
548 | if ((cflag & CBAUD) == B0) { | 553 | if ((cflag & CBAUD) == B0) { |
549 | /* Drop RTS and DTR */ | 554 | /* Drop RTS and DTR */ |
550 | dbg(DEBUG_IF, "%u: to B0 - drop DTR/RTS", cs->minor_index); | 555 | gig_dbg(DEBUG_IF, "%u: to B0 - drop DTR/RTS", cs->minor_index); |
551 | new_state = control_state & ~(TIOCM_DTR | TIOCM_RTS); | 556 | new_state = control_state & ~(TIOCM_DTR | TIOCM_RTS); |
552 | cs->ops->set_modem_ctrl(cs, control_state, new_state); | 557 | cs->ops->set_modem_ctrl(cs, control_state, new_state); |
553 | control_state = new_state; | 558 | control_state = new_state; |
@@ -567,15 +572,17 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
567 | * Just do what we have seen with SniffUSB on Win98. | 572 | * Just do what we have seen with SniffUSB on Win98. |
568 | */ | 573 | */ |
569 | /* Drop DTR/RTS if no flow control otherwise assert */ | 574 | /* Drop DTR/RTS if no flow control otherwise assert */ |
570 | dbg(DEBUG_IF, "%u: control_state %x", cs->minor_index, control_state); | 575 | gig_dbg(DEBUG_IF, "%u: control_state %x", |
576 | cs->minor_index, control_state); | ||
571 | new_state = control_state; | 577 | new_state = control_state; |
572 | if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) | 578 | if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) |
573 | new_state |= TIOCM_DTR | TIOCM_RTS; | 579 | new_state |= TIOCM_DTR | TIOCM_RTS; |
574 | else | 580 | else |
575 | new_state &= ~(TIOCM_DTR | TIOCM_RTS); | 581 | new_state &= ~(TIOCM_DTR | TIOCM_RTS); |
576 | if (new_state != control_state) { | 582 | if (new_state != control_state) { |
577 | dbg(DEBUG_IF, "%u: new_state %x", cs->minor_index, new_state); | 583 | gig_dbg(DEBUG_IF, "%u: new_state %x", |
578 | gigaset_set_modem_ctrl(cs, control_state, new_state); // FIXME: mct_u232.c sets the old state here. is this a bug? | 584 | cs->minor_index, new_state); |
585 | gigaset_set_modem_ctrl(cs, control_state, new_state); | ||
579 | control_state = new_state; | 586 | control_state = new_state; |
580 | } | 587 | } |
581 | #endif | 588 | #endif |
@@ -584,7 +591,7 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
584 | cs->control_state = control_state; | 591 | cs->control_state = control_state; |
585 | 592 | ||
586 | out: | 593 | out: |
587 | up(&cs->sem); | 594 | mutex_unlock(&cs->mutex); |
588 | } | 595 | } |
589 | 596 | ||
590 | 597 | ||
@@ -600,7 +607,7 @@ static void if_wake(unsigned long data) | |||
600 | 607 | ||
601 | if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && | 608 | if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && |
602 | tty->ldisc.write_wakeup) { | 609 | tty->ldisc.write_wakeup) { |
603 | dbg(DEBUG_IF, "write wakeup call"); | 610 | gig_dbg(DEBUG_IF, "write wakeup call"); |
604 | tty->ldisc.write_wakeup(tty); | 611 | tty->ldisc.write_wakeup(tty); |
605 | } | 612 | } |
606 | 613 | ||
@@ -635,14 +642,14 @@ void gigaset_if_free(struct cardstate *cs) | |||
635 | } | 642 | } |
636 | 643 | ||
637 | void gigaset_if_receive(struct cardstate *cs, | 644 | void gigaset_if_receive(struct cardstate *cs, |
638 | unsigned char *buffer, size_t len) | 645 | unsigned char *buffer, size_t len) |
639 | { | 646 | { |
640 | unsigned long flags; | 647 | unsigned long flags; |
641 | struct tty_struct *tty; | 648 | struct tty_struct *tty; |
642 | 649 | ||
643 | spin_lock_irqsave(&cs->lock, flags); | 650 | spin_lock_irqsave(&cs->lock, flags); |
644 | if ((tty = cs->tty) == NULL) | 651 | if ((tty = cs->tty) == NULL) |
645 | dbg(DEBUG_ANY, "receive on closed device"); | 652 | gig_dbg(DEBUG_ANY, "receive on closed device"); |
646 | else { | 653 | else { |
647 | tty_buffer_request_room(tty, len); | 654 | tty_buffer_request_room(tty, len); |
648 | tty_insert_flip_string(tty, buffer, len); | 655 | tty_insert_flip_string(tty, buffer, len); |
@@ -655,13 +662,13 @@ EXPORT_SYMBOL_GPL(gigaset_if_receive); | |||
655 | /* gigaset_if_initdriver | 662 | /* gigaset_if_initdriver |
656 | * Initialize tty interface. | 663 | * Initialize tty interface. |
657 | * parameters: | 664 | * parameters: |
658 | * drv Driver | 665 | * drv Driver |
659 | * procname Name of the driver (e.g. for /proc/tty/drivers) | 666 | * procname Name of the driver (e.g. for /proc/tty/drivers) |
660 | * devname Name of the device files (prefix without minor number) | 667 | * devname Name of the device files (prefix without minor number) |
661 | * devfsname Devfs name of the device files without %d | 668 | * devfsname Devfs name of the device files without %d |
662 | */ | 669 | */ |
663 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | 670 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, |
664 | const char *devname, const char *devfsname) | 671 | const char *devname, const char *devfsname) |
665 | { | 672 | { |
666 | unsigned minors = drv->minors; | 673 | unsigned minors = drv->minors; |
667 | int ret; | 674 | int ret; |
@@ -696,7 +703,7 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | |||
696 | warn("failed to register tty driver (error %d)", ret); | 703 | warn("failed to register tty driver (error %d)", ret); |
697 | goto error; | 704 | goto error; |
698 | } | 705 | } |
699 | dbg(DEBUG_IF, "tty driver initialized"); | 706 | gig_dbg(DEBUG_IF, "tty driver initialized"); |
700 | drv->have_tty = 1; | 707 | drv->have_tty = 1; |
701 | return; | 708 | return; |
702 | 709 | ||
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 5744eb91b315..45f017ed6e8c 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c | |||
@@ -10,10 +10,6 @@ | |||
10 | * published by the Free Software Foundation; either version 2 of | 10 | * published by the Free Software Foundation; either version 2 of |
11 | * the License, or (at your option) any later version. | 11 | * the License, or (at your option) any later version. |
12 | * ===================================================================== | 12 | * ===================================================================== |
13 | * ToDo: ... | ||
14 | * ===================================================================== | ||
15 | * Version: $Id: isocdata.c,v 1.2.2.5 2005/11/13 23:05:19 hjlipp Exp $ | ||
16 | * ===================================================================== | ||
17 | */ | 13 | */ |
18 | 14 | ||
19 | #include "gigaset.h" | 15 | #include "gigaset.h" |
@@ -87,14 +83,14 @@ static inline int isowbuf_startwrite(struct isowbuf_t *iwb) | |||
87 | { | 83 | { |
88 | if (!atomic_dec_and_test(&iwb->writesem)) { | 84 | if (!atomic_dec_and_test(&iwb->writesem)) { |
89 | atomic_inc(&iwb->writesem); | 85 | atomic_inc(&iwb->writesem); |
90 | dbg(DEBUG_ISO, | 86 | gig_dbg(DEBUG_ISO, "%s: couldn't acquire iso write semaphore", |
91 | "%s: couldn't acquire iso write semaphore", __func__); | 87 | __func__); |
92 | return 0; | 88 | return 0; |
93 | } | 89 | } |
94 | #ifdef CONFIG_GIGASET_DEBUG | 90 | #ifdef CONFIG_GIGASET_DEBUG |
95 | dbg(DEBUG_ISO, | 91 | gig_dbg(DEBUG_ISO, |
96 | "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d", | 92 | "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d", |
97 | __func__, iwb->data[atomic_read(&iwb->write)], iwb->wbits); | 93 | __func__, iwb->data[atomic_read(&iwb->write)], iwb->wbits); |
98 | #endif | 94 | #endif |
99 | return 1; | 95 | return 1; |
100 | } | 96 | } |
@@ -147,7 +143,7 @@ static inline void isowbuf_putflag(struct isowbuf_t *iwb) | |||
147 | /* recover the idle flag byte */ | 143 | /* recover the idle flag byte */ |
148 | write = atomic_read(&iwb->write); | 144 | write = atomic_read(&iwb->write); |
149 | iwb->idle = iwb->data[write]; | 145 | iwb->idle = iwb->data[write]; |
150 | dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle); | 146 | gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle); |
151 | /* mask extraneous bits in buffer */ | 147 | /* mask extraneous bits in buffer */ |
152 | iwb->data[write] &= (1 << iwb->wbits) - 1; | 148 | iwb->data[write] &= (1 << iwb->wbits) - 1; |
153 | } | 149 | } |
@@ -166,15 +162,14 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
166 | read = atomic_read(&iwb->nextread); | 162 | read = atomic_read(&iwb->nextread); |
167 | write = atomic_read(&iwb->write); | 163 | write = atomic_read(&iwb->write); |
168 | if (likely(read == write)) { | 164 | if (likely(read == write)) { |
169 | //dbg(DEBUG_STREAM, "%s: send buffer empty", __func__); | ||
170 | /* return idle frame */ | 165 | /* return idle frame */ |
171 | return read < BAS_OUTBUFPAD ? | 166 | return read < BAS_OUTBUFPAD ? |
172 | BAS_OUTBUFSIZE : read - BAS_OUTBUFPAD; | 167 | BAS_OUTBUFSIZE : read - BAS_OUTBUFPAD; |
173 | } | 168 | } |
174 | 169 | ||
175 | limit = read + size; | 170 | limit = read + size; |
176 | dbg(DEBUG_STREAM, | 171 | gig_dbg(DEBUG_STREAM, "%s: read=%d write=%d limit=%d", |
177 | "%s: read=%d write=%d limit=%d", __func__, read, write, limit); | 172 | __func__, read, write, limit); |
178 | #ifdef CONFIG_GIGASET_DEBUG | 173 | #ifdef CONFIG_GIGASET_DEBUG |
179 | if (unlikely(size < 0 || size > BAS_OUTBUFPAD)) { | 174 | if (unlikely(size < 0 || size > BAS_OUTBUFPAD)) { |
180 | err("invalid size %d", size); | 175 | err("invalid size %d", size); |
@@ -196,11 +191,12 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
196 | return -EBUSY; | 191 | return -EBUSY; |
197 | /* write position could have changed */ | 192 | /* write position could have changed */ |
198 | if (limit >= (write = atomic_read(&iwb->write))) { | 193 | if (limit >= (write = atomic_read(&iwb->write))) { |
199 | pbyte = iwb->data[write]; /* save partial byte */ | 194 | pbyte = iwb->data[write]; /* save |
195 | partial byte */ | ||
200 | limit = write + BAS_OUTBUFPAD; | 196 | limit = write + BAS_OUTBUFPAD; |
201 | dbg(DEBUG_STREAM, | 197 | gig_dbg(DEBUG_STREAM, |
202 | "%s: filling %d->%d with %02x", | 198 | "%s: filling %d->%d with %02x", |
203 | __func__, write, limit, iwb->idle); | 199 | __func__, write, limit, iwb->idle); |
204 | if (write + BAS_OUTBUFPAD < BAS_OUTBUFSIZE) | 200 | if (write + BAS_OUTBUFPAD < BAS_OUTBUFSIZE) |
205 | memset(iwb->data + write, iwb->idle, | 201 | memset(iwb->data + write, iwb->idle, |
206 | BAS_OUTBUFPAD); | 202 | BAS_OUTBUFPAD); |
@@ -211,9 +207,11 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
211 | - write); | 207 | - write); |
212 | limit = 0; | 208 | limit = 0; |
213 | } | 209 | } |
214 | dbg(DEBUG_STREAM, "%s: restoring %02x at %d", | 210 | gig_dbg(DEBUG_STREAM, |
215 | __func__, pbyte, limit); | 211 | "%s: restoring %02x at %d", |
216 | iwb->data[limit] = pbyte; /* restore partial byte */ | 212 | __func__, pbyte, limit); |
213 | iwb->data[limit] = pbyte; /* restore | ||
214 | partial byte */ | ||
217 | atomic_set(&iwb->write, limit); | 215 | atomic_set(&iwb->write, limit); |
218 | } | 216 | } |
219 | isowbuf_donewrite(iwb); | 217 | isowbuf_donewrite(iwb); |
@@ -242,19 +240,17 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
242 | * write hex bytes to syslog for debugging | 240 | * write hex bytes to syslog for debugging |
243 | */ | 241 | */ |
244 | static inline void dump_bytes(enum debuglevel level, const char *tag, | 242 | static inline void dump_bytes(enum debuglevel level, const char *tag, |
245 | unsigned char *bytes, int count) | 243 | unsigned char *bytes, int count) |
246 | { | 244 | { |
247 | #ifdef CONFIG_GIGASET_DEBUG | 245 | #ifdef CONFIG_GIGASET_DEBUG |
248 | unsigned char c; | 246 | unsigned char c; |
249 | static char dbgline[3 * 32 + 1]; | 247 | static char dbgline[3 * 32 + 1]; |
250 | static const char hexdigit[] = "0123456789abcdef"; | 248 | static const char hexdigit[] = "0123456789abcdef"; |
251 | int i = 0; | 249 | int i = 0; |
252 | IFNULLRET(tag); | ||
253 | IFNULLRET(bytes); | ||
254 | while (count-- > 0) { | 250 | while (count-- > 0) { |
255 | if (i > sizeof(dbgline) - 4) { | 251 | if (i > sizeof(dbgline) - 4) { |
256 | dbgline[i] = '\0'; | 252 | dbgline[i] = '\0'; |
257 | dbg(level, "%s:%s", tag, dbgline); | 253 | gig_dbg(level, "%s:%s", tag, dbgline); |
258 | i = 0; | 254 | i = 0; |
259 | } | 255 | } |
260 | c = *bytes++; | 256 | c = *bytes++; |
@@ -264,7 +260,7 @@ static inline void dump_bytes(enum debuglevel level, const char *tag, | |||
264 | dbgline[i++] = hexdigit[c & 0x0f]; | 260 | dbgline[i++] = hexdigit[c & 0x0f]; |
265 | } | 261 | } |
266 | dbgline[i] = '\0'; | 262 | dbgline[i] = '\0'; |
267 | dbg(level, "%s:%s", tag, dbgline); | 263 | gig_dbg(level, "%s:%s", tag, dbgline); |
268 | #endif | 264 | #endif |
269 | } | 265 | } |
270 | 266 | ||
@@ -380,7 +376,7 @@ static u16 stufftab[5 * 256] = { | |||
380 | */ | 376 | */ |
381 | 377 | ||
382 | static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin, | 378 | static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin, |
383 | int ones) | 379 | int ones) |
384 | { | 380 | { |
385 | u16 stuff; | 381 | u16 stuff; |
386 | int shiftinc, newones; | 382 | int shiftinc, newones; |
@@ -422,7 +418,7 @@ static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin, | |||
422 | */ | 418 | */ |
423 | 419 | ||
424 | static inline int hdlc_buildframe(struct isowbuf_t *iwb, | 420 | static inline int hdlc_buildframe(struct isowbuf_t *iwb, |
425 | unsigned char *in, int count) | 421 | unsigned char *in, int count) |
426 | { | 422 | { |
427 | int ones; | 423 | int ones; |
428 | u16 fcs; | 424 | u16 fcs; |
@@ -431,8 +427,8 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb, | |||
431 | 427 | ||
432 | if (isowbuf_freebytes(iwb) < count + count / 5 + 6 || | 428 | if (isowbuf_freebytes(iwb) < count + count / 5 + 6 || |
433 | !isowbuf_startwrite(iwb)) { | 429 | !isowbuf_startwrite(iwb)) { |
434 | dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN", | 430 | gig_dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN", |
435 | __func__, isowbuf_freebytes(iwb)); | 431 | __func__, isowbuf_freebytes(iwb)); |
436 | return -EAGAIN; | 432 | return -EAGAIN; |
437 | } | 433 | } |
438 | 434 | ||
@@ -484,11 +480,11 @@ static inline int trans_buildframe(struct isowbuf_t *iwb, | |||
484 | 480 | ||
485 | if (isowbuf_freebytes(iwb) < count || | 481 | if (isowbuf_freebytes(iwb) < count || |
486 | !isowbuf_startwrite(iwb)) { | 482 | !isowbuf_startwrite(iwb)) { |
487 | dbg(DEBUG_ISO, "can't put %d bytes", count); | 483 | gig_dbg(DEBUG_ISO, "can't put %d bytes", count); |
488 | return -EAGAIN; | 484 | return -EAGAIN; |
489 | } | 485 | } |
490 | 486 | ||
491 | dbg(DEBUG_STREAM, "put %d bytes", count); | 487 | gig_dbg(DEBUG_STREAM, "put %d bytes", count); |
492 | write = atomic_read(&iwb->write); | 488 | write = atomic_read(&iwb->write); |
493 | do { | 489 | do { |
494 | c = gigaset_invtab[*in++]; | 490 | c = gigaset_invtab[*in++]; |
@@ -508,11 +504,13 @@ int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len) | |||
508 | switch (bcs->proto2) { | 504 | switch (bcs->proto2) { |
509 | case ISDN_PROTO_L2_HDLC: | 505 | case ISDN_PROTO_L2_HDLC: |
510 | result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len); | 506 | result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len); |
511 | dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d", __func__, len, result); | 507 | gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d", |
508 | __func__, len, result); | ||
512 | break; | 509 | break; |
513 | default: /* assume transparent */ | 510 | default: /* assume transparent */ |
514 | result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len); | 511 | result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len); |
515 | dbg(DEBUG_ISO, "%s: %d bytes trans -> %d", __func__, len, result); | 512 | gig_dbg(DEBUG_ISO, "%s: %d bytes trans -> %d", |
513 | __func__, len, result); | ||
516 | } | 514 | } |
517 | return result; | 515 | return result; |
518 | } | 516 | } |
@@ -528,13 +526,13 @@ static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs) | |||
528 | return; | 526 | return; |
529 | } | 527 | } |
530 | if (unlikely(bcs->skb->len == SBUFSIZE)) { | 528 | if (unlikely(bcs->skb->len == SBUFSIZE)) { |
531 | warn("received oversized packet discarded"); | 529 | dev_warn(bcs->cs->dev, "received oversized packet discarded\n"); |
532 | bcs->hw.bas->giants++; | 530 | bcs->hw.bas->giants++; |
533 | dev_kfree_skb_any(bcs->skb); | 531 | dev_kfree_skb_any(bcs->skb); |
534 | bcs->skb = NULL; | 532 | bcs->skb = NULL; |
535 | return; | 533 | return; |
536 | } | 534 | } |
537 | *gigaset_skb_put_quick(bcs->skb, 1) = c; | 535 | *__skb_put(bcs->skb, 1) = c; |
538 | } | 536 | } |
539 | 537 | ||
540 | /* hdlc_flush | 538 | /* hdlc_flush |
@@ -549,7 +547,7 @@ static inline void hdlc_flush(struct bc_state *bcs) | |||
549 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 547 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
550 | skb_reserve(bcs->skb, HW_HDR_LEN); | 548 | skb_reserve(bcs->skb, HW_HDR_LEN); |
551 | else | 549 | else |
552 | err("could not allocate skb"); | 550 | dev_err(bcs->cs->dev, "could not allocate skb\n"); |
553 | } | 551 | } |
554 | 552 | ||
555 | /* reset packet state */ | 553 | /* reset packet state */ |
@@ -571,23 +569,25 @@ static inline void hdlc_done(struct bc_state *bcs) | |||
571 | 569 | ||
572 | if ((procskb = bcs->skb) == NULL) { | 570 | if ((procskb = bcs->skb) == NULL) { |
573 | /* previous error */ | 571 | /* previous error */ |
574 | dbg(DEBUG_ISO, "%s: skb=NULL", __func__); | 572 | gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__); |
575 | gigaset_rcv_error(NULL, bcs->cs, bcs); | 573 | gigaset_rcv_error(NULL, bcs->cs, bcs); |
576 | } else if (procskb->len < 2) { | 574 | } else if (procskb->len < 2) { |
577 | notice("received short frame (%d octets)", procskb->len); | 575 | dev_notice(bcs->cs->dev, "received short frame (%d octets)\n", |
576 | procskb->len); | ||
578 | bcs->hw.bas->runts++; | 577 | bcs->hw.bas->runts++; |
579 | gigaset_rcv_error(procskb, bcs->cs, bcs); | 578 | gigaset_rcv_error(procskb, bcs->cs, bcs); |
580 | } else if (bcs->fcs != PPP_GOODFCS) { | 579 | } else if (bcs->fcs != PPP_GOODFCS) { |
581 | notice("frame check error (0x%04x)", bcs->fcs); | 580 | dev_notice(bcs->cs->dev, "frame check error (0x%04x)\n", |
581 | bcs->fcs); | ||
582 | bcs->hw.bas->fcserrs++; | 582 | bcs->hw.bas->fcserrs++; |
583 | gigaset_rcv_error(procskb, bcs->cs, bcs); | 583 | gigaset_rcv_error(procskb, bcs->cs, bcs); |
584 | } else { | 584 | } else { |
585 | procskb->len -= 2; /* subtract FCS */ | 585 | procskb->len -= 2; /* subtract FCS */ |
586 | procskb->tail -= 2; | 586 | procskb->tail -= 2; |
587 | dbg(DEBUG_ISO, | 587 | gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", |
588 | "%s: good frame (%d octets)", __func__, procskb->len); | 588 | __func__, procskb->len); |
589 | dump_bytes(DEBUG_STREAM, | 589 | dump_bytes(DEBUG_STREAM, |
590 | "rcv data", procskb->data, procskb->len); | 590 | "rcv data", procskb->data, procskb->len); |
591 | bcs->hw.bas->goodbytes += procskb->len; | 591 | bcs->hw.bas->goodbytes += procskb->len; |
592 | gigaset_rcv_skb(procskb, bcs->cs, bcs); | 592 | gigaset_rcv_skb(procskb, bcs->cs, bcs); |
593 | } | 593 | } |
@@ -595,7 +595,7 @@ static inline void hdlc_done(struct bc_state *bcs) | |||
595 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 595 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
596 | skb_reserve(bcs->skb, HW_HDR_LEN); | 596 | skb_reserve(bcs->skb, HW_HDR_LEN); |
597 | else | 597 | else |
598 | err("could not allocate skb"); | 598 | dev_err(bcs->cs->dev, "could not allocate skb\n"); |
599 | bcs->fcs = PPP_INITFCS; | 599 | bcs->fcs = PPP_INITFCS; |
600 | } | 600 | } |
601 | 601 | ||
@@ -610,14 +610,14 @@ static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits) | |||
610 | return; | 610 | return; |
611 | } | 611 | } |
612 | 612 | ||
613 | notice("received partial byte (%d bits)", inbits); | 613 | dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits); |
614 | bcs->hw.bas->alignerrs++; | 614 | bcs->hw.bas->alignerrs++; |
615 | gigaset_rcv_error(bcs->skb, bcs->cs, bcs); | 615 | gigaset_rcv_error(bcs->skb, bcs->cs, bcs); |
616 | 616 | ||
617 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 617 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
618 | skb_reserve(bcs->skb, HW_HDR_LEN); | 618 | skb_reserve(bcs->skb, HW_HDR_LEN); |
619 | else | 619 | else |
620 | err("could not allocate skb"); | 620 | dev_err(bcs->cs->dev, "could not allocate skb\n"); |
621 | bcs->fcs = PPP_INITFCS; | 621 | bcs->fcs = PPP_INITFCS; |
622 | } | 622 | } |
623 | 623 | ||
@@ -659,16 +659,12 @@ static unsigned char bitcounts[256] = { | |||
659 | * bcs receiving B channel structure | 659 | * bcs receiving B channel structure |
660 | */ | 660 | */ |
661 | static inline void hdlc_unpack(unsigned char *src, unsigned count, | 661 | static inline void hdlc_unpack(unsigned char *src, unsigned count, |
662 | struct bc_state *bcs) | 662 | struct bc_state *bcs) |
663 | { | 663 | { |
664 | struct bas_bc_state *ubc; | 664 | struct bas_bc_state *ubc = bcs->hw.bas; |
665 | int inputstate; | 665 | int inputstate; |
666 | unsigned seqlen, inbyte, inbits; | 666 | unsigned seqlen, inbyte, inbits; |
667 | 667 | ||
668 | IFNULLRET(bcs); | ||
669 | ubc = bcs->hw.bas; | ||
670 | IFNULLRET(ubc); | ||
671 | |||
672 | /* load previous state: | 668 | /* load previous state: |
673 | * inputstate = set of flag bits: | 669 | * inputstate = set of flag bits: |
674 | * - INS_flag_hunt: no complete opening flag received since connection setup or last abort | 670 | * - INS_flag_hunt: no complete opening flag received since connection setup or last abort |
@@ -856,7 +852,7 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count, | |||
856 | * bcs receiving B channel structure | 852 | * bcs receiving B channel structure |
857 | */ | 853 | */ |
858 | static inline void trans_receive(unsigned char *src, unsigned count, | 854 | static inline void trans_receive(unsigned char *src, unsigned count, |
859 | struct bc_state *bcs) | 855 | struct bc_state *bcs) |
860 | { | 856 | { |
861 | struct sk_buff *skb; | 857 | struct sk_buff *skb; |
862 | int dobytes; | 858 | int dobytes; |
@@ -870,7 +866,7 @@ static inline void trans_receive(unsigned char *src, unsigned count, | |||
870 | if (unlikely((skb = bcs->skb) == NULL)) { | 866 | if (unlikely((skb = bcs->skb) == NULL)) { |
871 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); | 867 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); |
872 | if (!skb) { | 868 | if (!skb) { |
873 | err("could not allocate skb"); | 869 | dev_err(bcs->cs->dev, "could not allocate skb\n"); |
874 | return; | 870 | return; |
875 | } | 871 | } |
876 | skb_reserve(skb, HW_HDR_LEN); | 872 | skb_reserve(skb, HW_HDR_LEN); |
@@ -888,7 +884,8 @@ static inline void trans_receive(unsigned char *src, unsigned count, | |||
888 | gigaset_rcv_skb(skb, bcs->cs, bcs); | 884 | gigaset_rcv_skb(skb, bcs->cs, bcs); |
889 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); | 885 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); |
890 | if (!skb) { | 886 | if (!skb) { |
891 | err("could not allocate skb"); | 887 | dev_err(bcs->cs->dev, |
888 | "could not allocate skb\n"); | ||
892 | return; | 889 | return; |
893 | } | 890 | } |
894 | skb_reserve(bcs->skb, HW_HDR_LEN); | 891 | skb_reserve(bcs->skb, HW_HDR_LEN); |
@@ -921,8 +918,8 @@ static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf) | |||
921 | case '\r': | 918 | case '\r': |
922 | case '\n': | 919 | case '\n': |
923 | /* end of line */ | 920 | /* end of line */ |
924 | dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", | 921 | gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", |
925 | __func__, cbytes); | 922 | __func__, cbytes); |
926 | cs->cbytes = cbytes; | 923 | cs->cbytes = cbytes; |
927 | gigaset_handle_modem_response(cs); | 924 | gigaset_handle_modem_response(cs); |
928 | cbytes = 0; | 925 | cbytes = 0; |
@@ -932,7 +929,7 @@ static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf) | |||
932 | if (cbytes < MAX_RESP_SIZE - 1) | 929 | if (cbytes < MAX_RESP_SIZE - 1) |
933 | cbytes++; | 930 | cbytes++; |
934 | else | 931 | else |
935 | warn("response too large"); | 932 | dev_warn(cs->dev, "response too large\n"); |
936 | } | 933 | } |
937 | } | 934 | } |
938 | 935 | ||
@@ -951,27 +948,27 @@ void gigaset_isoc_input(struct inbuf_t *inbuf) | |||
951 | 948 | ||
952 | head = atomic_read(&inbuf->head); | 949 | head = atomic_read(&inbuf->head); |
953 | while (head != (tail = atomic_read(&inbuf->tail))) { | 950 | while (head != (tail = atomic_read(&inbuf->tail))) { |
954 | dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | 951 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); |
955 | if (head > tail) | 952 | if (head > tail) |
956 | tail = RBUFSIZE; | 953 | tail = RBUFSIZE; |
957 | src = inbuf->data + head; | 954 | src = inbuf->data + head; |
958 | numbytes = tail - head; | 955 | numbytes = tail - head; |
959 | dbg(DEBUG_INTR, "processing %u bytes", numbytes); | 956 | gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); |
960 | 957 | ||
961 | if (atomic_read(&cs->mstate) == MS_LOCKED) { | 958 | if (atomic_read(&cs->mstate) == MS_LOCKED) { |
962 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", | 959 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", |
963 | numbytes, src, 0); | 960 | numbytes, src); |
964 | gigaset_if_receive(inbuf->cs, src, numbytes); | 961 | gigaset_if_receive(inbuf->cs, src, numbytes); |
965 | } else { | 962 | } else { |
966 | gigaset_dbg_buffer(DEBUG_CMD, "received response", | 963 | gigaset_dbg_buffer(DEBUG_CMD, "received response", |
967 | numbytes, src, 0); | 964 | numbytes, src); |
968 | cmd_loop(src, numbytes, inbuf); | 965 | cmd_loop(src, numbytes, inbuf); |
969 | } | 966 | } |
970 | 967 | ||
971 | head += numbytes; | 968 | head += numbytes; |
972 | if (head == RBUFSIZE) | 969 | if (head == RBUFSIZE) |
973 | head = 0; | 970 | head = 0; |
974 | dbg(DEBUG_INTR, "setting head to %u", head); | 971 | gig_dbg(DEBUG_INTR, "setting head to %u", head); |
975 | atomic_set(&inbuf->head, head); | 972 | atomic_set(&inbuf->head, head); |
976 | } | 973 | } |
977 | } | 974 | } |
@@ -992,18 +989,18 @@ void gigaset_isoc_input(struct inbuf_t *inbuf) | |||
992 | */ | 989 | */ |
993 | int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb) | 990 | int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb) |
994 | { | 991 | { |
995 | int len; | 992 | int len = skb->len; |
996 | 993 | unsigned long flags; | |
997 | IFNULLRETVAL(bcs, -EFAULT); | ||
998 | IFNULLRETVAL(skb, -EFAULT); | ||
999 | len = skb->len; | ||
1000 | 994 | ||
1001 | skb_queue_tail(&bcs->squeue, skb); | 995 | skb_queue_tail(&bcs->squeue, skb); |
1002 | dbg(DEBUG_ISO, | 996 | gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d", |
1003 | "%s: skb queued, qlen=%d", __func__, skb_queue_len(&bcs->squeue)); | 997 | __func__, skb_queue_len(&bcs->squeue)); |
1004 | 998 | ||
1005 | /* tasklet submits URB if necessary */ | 999 | /* tasklet submits URB if necessary */ |
1006 | tasklet_schedule(&bcs->hw.bas->sent_tasklet); | 1000 | spin_lock_irqsave(&bcs->cs->lock, flags); |
1001 | if (bcs->cs->connected) | ||
1002 | tasklet_schedule(&bcs->hw.bas->sent_tasklet); | ||
1003 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
1007 | 1004 | ||
1008 | return len; /* ok so far */ | 1005 | return len; /* ok so far */ |
1009 | } | 1006 | } |
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c index c6915fa2be6c..d267a636b53c 100644 --- a/drivers/isdn/gigaset/proc.c +++ b/drivers/isdn/gigaset/proc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Stuff used by all variants of the driver | 2 | * Stuff used by all variants of the driver |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de>, | 4 | * Copyright (c) 2001 by Stefan Eilers, |
5 | * Hansjoerg Lipp <hjlipp@web.de>, | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Tilman Schmidt <tilman@imap.cc>. | 6 | * Tilman Schmidt <tilman@imap.cc>. |
7 | * | 7 | * |
@@ -11,26 +11,29 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: proc.c,v 1.5.2.13 2006/02/04 18:28:16 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
21 | #include <linux/ctype.h> | 17 | #include <linux/ctype.h> |
22 | 18 | ||
23 | static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, char *buf) | 19 | static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, |
20 | char *buf) | ||
24 | { | 21 | { |
25 | struct usb_interface *intf = to_usb_interface(dev); | 22 | int ret; |
26 | struct cardstate *cs = usb_get_intfdata(intf); | 23 | unsigned long flags; |
27 | return sprintf(buf, "%d\n", atomic_read(&cs->cidmode)); // FIXME use scnprintf for 13607 bit architectures (if PAGE_SIZE==4096) | 24 | struct cardstate *cs = dev_get_drvdata(dev); |
25 | |||
26 | spin_lock_irqsave(&cs->lock, flags); | ||
27 | ret = sprintf(buf, "%u\n", cs->cidmode); | ||
28 | spin_unlock_irqrestore(&cs->lock, flags); | ||
29 | |||
30 | return ret; | ||
28 | } | 31 | } |
29 | 32 | ||
30 | static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 33 | static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, |
34 | const char *buf, size_t count) | ||
31 | { | 35 | { |
32 | struct usb_interface *intf = to_usb_interface(dev); | 36 | struct cardstate *cs = dev_get_drvdata(dev); |
33 | struct cardstate *cs = usb_get_intfdata(intf); | ||
34 | long int value; | 37 | long int value; |
35 | char *end; | 38 | char *end; |
36 | 39 | ||
@@ -41,23 +44,23 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, co | |||
41 | if (value < 0 || value > 1) | 44 | if (value < 0 || value > 1) |
42 | return -EINVAL; | 45 | return -EINVAL; |
43 | 46 | ||
44 | if (down_interruptible(&cs->sem)) | 47 | if (mutex_lock_interruptible(&cs->mutex)) |
45 | return -ERESTARTSYS; // FIXME -EINTR? | 48 | return -ERESTARTSYS; // FIXME -EINTR? |
46 | 49 | ||
47 | cs->waiting = 1; | 50 | cs->waiting = 1; |
48 | if (!gigaset_add_event(cs, &cs->at_state, EV_PROC_CIDMODE, | 51 | if (!gigaset_add_event(cs, &cs->at_state, EV_PROC_CIDMODE, |
49 | NULL, value, NULL)) { | 52 | NULL, value, NULL)) { |
50 | cs->waiting = 0; | 53 | cs->waiting = 0; |
51 | up(&cs->sem); | 54 | mutex_unlock(&cs->mutex); |
52 | return -ENOMEM; | 55 | return -ENOMEM; |
53 | } | 56 | } |
54 | 57 | ||
55 | dbg(DEBUG_CMD, "scheduling PROC_CIDMODE"); | 58 | gig_dbg(DEBUG_CMD, "scheduling PROC_CIDMODE"); |
56 | gigaset_schedule_event(cs); | 59 | gigaset_schedule_event(cs); |
57 | 60 | ||
58 | wait_event(cs->waitqueue, !cs->waiting); | 61 | wait_event(cs->waitqueue, !cs->waiting); |
59 | 62 | ||
60 | up(&cs->sem); | 63 | mutex_unlock(&cs->mutex); |
61 | 64 | ||
62 | return count; | 65 | return count; |
63 | } | 66 | } |
@@ -65,17 +68,15 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, co | |||
65 | static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); | 68 | static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); |
66 | 69 | ||
67 | /* free sysfs for device */ | 70 | /* free sysfs for device */ |
68 | void gigaset_free_dev_sysfs(struct usb_interface *interface) | 71 | void gigaset_free_dev_sysfs(struct cardstate *cs) |
69 | { | 72 | { |
70 | dbg(DEBUG_INIT, "removing sysfs entries"); | 73 | gig_dbg(DEBUG_INIT, "removing sysfs entries"); |
71 | device_remove_file(&interface->dev, &dev_attr_cidmode); | 74 | device_remove_file(cs->dev, &dev_attr_cidmode); |
72 | } | 75 | } |
73 | EXPORT_SYMBOL_GPL(gigaset_free_dev_sysfs); | ||
74 | 76 | ||
75 | /* initialize sysfs for device */ | 77 | /* initialize sysfs for device */ |
76 | void gigaset_init_dev_sysfs(struct usb_interface *interface) | 78 | void gigaset_init_dev_sysfs(struct cardstate *cs) |
77 | { | 79 | { |
78 | dbg(DEBUG_INIT, "setting up sysfs"); | 80 | gig_dbg(DEBUG_INIT, "setting up sysfs"); |
79 | device_create_file(&interface->dev, &dev_attr_cidmode); | 81 | device_create_file(cs->dev, &dev_attr_cidmode); |
80 | } | 82 | } |
81 | EXPORT_SYMBOL_GPL(gigaset_init_dev_sysfs); | ||
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index 323fc7349dec..bfb73fd5077e 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * USB driver for Gigaset 307x directly or using M105 Data. | 2 | * USB driver for Gigaset 307x directly or using M105 Data. |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de> | 4 | * Copyright (c) 2001 by Stefan Eilers |
5 | * and Hansjoerg Lipp <hjlipp@web.de>. | 5 | * and Hansjoerg Lipp <hjlipp@web.de>. |
6 | * | 6 | * |
7 | * This driver was derived from the USB skeleton driver by | 7 | * This driver was derived from the USB skeleton driver by |
@@ -13,10 +13,6 @@ | |||
13 | * published by the Free Software Foundation; either version 2 of | 13 | * published by the Free Software Foundation; either version 2 of |
14 | * the License, or (at your option) any later version. | 14 | * the License, or (at your option) any later version. |
15 | * ===================================================================== | 15 | * ===================================================================== |
16 | * ToDo: ... | ||
17 | * ===================================================================== | ||
18 | * Version: $Id: usb-gigaset.c,v 1.85.4.18 2006/02/04 18:28:16 hjlipp Exp $ | ||
19 | * ===================================================================== | ||
20 | */ | 16 | */ |
21 | 17 | ||
22 | #include "gigaset.h" | 18 | #include "gigaset.h" |
@@ -29,7 +25,7 @@ | |||
29 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
30 | 26 | ||
31 | /* Version Information */ | 27 | /* Version Information */ |
32 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers <Eilers.Stefan@epost.de>" | 28 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers" |
33 | #define DRIVER_DESC "USB Driver for Gigaset 307x using M105" | 29 | #define DRIVER_DESC "USB Driver for Gigaset 307x using M105" |
34 | 30 | ||
35 | /* Module parameters */ | 31 | /* Module parameters */ |
@@ -62,10 +58,6 @@ static struct usb_device_id gigaset_table [] = { | |||
62 | 58 | ||
63 | MODULE_DEVICE_TABLE(usb, gigaset_table); | 59 | MODULE_DEVICE_TABLE(usb, gigaset_table); |
64 | 60 | ||
65 | /* Get a minor range for your devices from the usb maintainer */ | ||
66 | #define USB_SKEL_MINOR_BASE 200 | ||
67 | |||
68 | |||
69 | /* | 61 | /* |
70 | * Control requests (empty fields: 00) | 62 | * Control requests (empty fields: 00) |
71 | * | 63 | * |
@@ -114,7 +106,7 @@ MODULE_DEVICE_TABLE(usb, gigaset_table); | |||
114 | */ | 106 | */ |
115 | 107 | ||
116 | static int gigaset_probe(struct usb_interface *interface, | 108 | static int gigaset_probe(struct usb_interface *interface, |
117 | const struct usb_device_id *id); | 109 | const struct usb_device_id *id); |
118 | static void gigaset_disconnect(struct usb_interface *interface); | 110 | static void gigaset_disconnect(struct usb_interface *interface); |
119 | 111 | ||
120 | static struct gigaset_driver *driver = NULL; | 112 | static struct gigaset_driver *driver = NULL; |
@@ -122,29 +114,29 @@ static struct cardstate *cardstate = NULL; | |||
122 | 114 | ||
123 | /* usb specific object needed to register this driver with the usb subsystem */ | 115 | /* usb specific object needed to register this driver with the usb subsystem */ |
124 | static struct usb_driver gigaset_usb_driver = { | 116 | static struct usb_driver gigaset_usb_driver = { |
125 | .name = GIGASET_MODULENAME, | 117 | .name = GIGASET_MODULENAME, |
126 | .probe = gigaset_probe, | 118 | .probe = gigaset_probe, |
127 | .disconnect = gigaset_disconnect, | 119 | .disconnect = gigaset_disconnect, |
128 | .id_table = gigaset_table, | 120 | .id_table = gigaset_table, |
129 | }; | 121 | }; |
130 | 122 | ||
131 | struct usb_cardstate { | 123 | struct usb_cardstate { |
132 | struct usb_device *udev; /* save off the usb device pointer */ | 124 | struct usb_device *udev; /* usb device pointer */ |
133 | struct usb_interface *interface; /* the interface for this device */ | 125 | struct usb_interface *interface; /* interface for this device */ |
134 | atomic_t busy; /* bulk output in progress */ | 126 | atomic_t busy; /* bulk output in progress */ |
135 | 127 | ||
136 | /* Output buffer for commands (M105: and data)*/ | 128 | /* Output buffer */ |
137 | unsigned char *bulk_out_buffer; /* the buffer to send data */ | 129 | unsigned char *bulk_out_buffer; |
138 | int bulk_out_size; /* the size of the send buffer */ | 130 | int bulk_out_size; |
139 | __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ | 131 | __u8 bulk_out_endpointAddr; |
140 | struct urb *bulk_out_urb; /* the urb used to transmit data */ | 132 | struct urb *bulk_out_urb; |
141 | 133 | ||
142 | /* Input buffer for command responses (M105: and data)*/ | 134 | /* Input buffer */ |
143 | int rcvbuf_size; /* the size of the receive buffer */ | 135 | int rcvbuf_size; |
144 | struct urb *read_urb; /* the urb used to receive data */ | 136 | struct urb *read_urb; |
145 | __u8 int_in_endpointAddr; /* the address of the bulk in endpoint */ | 137 | __u8 int_in_endpointAddr; |
146 | 138 | ||
147 | char bchars[6]; /* req. 0x19 */ | 139 | char bchars[6]; /* for request 0x19 */ |
148 | }; | 140 | }; |
149 | 141 | ||
150 | struct usb_bc_state {}; | 142 | struct usb_bc_state {}; |
@@ -157,19 +149,20 @@ static inline unsigned tiocm_to_gigaset(unsigned state) | |||
157 | #ifdef CONFIG_GIGASET_UNDOCREQ | 149 | #ifdef CONFIG_GIGASET_UNDOCREQ |
158 | /* WARNING: EXPERIMENTAL! */ | 150 | /* WARNING: EXPERIMENTAL! */ |
159 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | 151 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, |
160 | unsigned new_state) | 152 | unsigned new_state) |
161 | { | 153 | { |
154 | struct usb_device *udev = cs->hw.usb->udev; | ||
162 | unsigned mask, val; | 155 | unsigned mask, val; |
163 | int r; | 156 | int r; |
164 | 157 | ||
165 | mask = tiocm_to_gigaset(old_state ^ new_state); | 158 | mask = tiocm_to_gigaset(old_state ^ new_state); |
166 | val = tiocm_to_gigaset(new_state); | 159 | val = tiocm_to_gigaset(new_state); |
167 | 160 | ||
168 | dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask); | 161 | gig_dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask); |
169 | r = usb_control_msg(cs->hw.usb->udev, | 162 | // don't use this in an interrupt/BH |
170 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 7, 0x41, | 163 | r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 7, 0x41, |
171 | (val & 0xff) | ((mask & 0xff) << 8), 0, | 164 | (val & 0xff) | ((mask & 0xff) << 8), 0, |
172 | NULL, 0, 2000 /*timeout??*/); // don't use this in an interrupt/BH | 165 | NULL, 0, 2000 /* timeout? */); |
173 | if (r < 0) | 166 | if (r < 0) |
174 | return r; | 167 | return r; |
175 | //.. | 168 | //.. |
@@ -178,30 +171,29 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | |||
178 | 171 | ||
179 | static int set_value(struct cardstate *cs, u8 req, u16 val) | 172 | static int set_value(struct cardstate *cs, u8 req, u16 val) |
180 | { | 173 | { |
174 | struct usb_device *udev = cs->hw.usb->udev; | ||
181 | int r, r2; | 175 | int r, r2; |
182 | 176 | ||
183 | dbg(DEBUG_USBREQ, "request %02x (%04x)", (unsigned)req, (unsigned)val); | 177 | gig_dbg(DEBUG_USBREQ, "request %02x (%04x)", |
184 | r = usb_control_msg(cs->hw.usb->udev, | 178 | (unsigned)req, (unsigned)val); |
185 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 0x12, 0x41, | 179 | r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x12, 0x41, |
186 | 0xf /*?*/, 0, | 180 | 0xf /*?*/, 0, NULL, 0, 2000 /*?*/); |
187 | NULL, 0, 2000 /*?*/); /* no idea, what this does */ | 181 | /* no idea what this does */ |
188 | if (r < 0) { | 182 | if (r < 0) { |
189 | err("error %d on request 0x12", -r); | 183 | dev_err(&udev->dev, "error %d on request 0x12\n", -r); |
190 | return r; | 184 | return r; |
191 | } | 185 | } |
192 | 186 | ||
193 | r = usb_control_msg(cs->hw.usb->udev, | 187 | r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), req, 0x41, |
194 | usb_sndctrlpipe(cs->hw.usb->udev, 0), req, 0x41, | 188 | val, 0, NULL, 0, 2000 /*?*/); |
195 | val, 0, | ||
196 | NULL, 0, 2000 /*?*/); | ||
197 | if (r < 0) | 189 | if (r < 0) |
198 | err("error %d on request 0x%02x", -r, (unsigned)req); | 190 | dev_err(&udev->dev, "error %d on request 0x%02x\n", |
191 | -r, (unsigned)req); | ||
199 | 192 | ||
200 | r2 = usb_control_msg(cs->hw.usb->udev, | 193 | r2 = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, |
201 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 0x19, 0x41, | 194 | 0, 0, cs->hw.usb->bchars, 6, 2000 /*?*/); |
202 | 0, 0, cs->hw.usb->bchars, 6, 2000 /*?*/); | ||
203 | if (r2 < 0) | 195 | if (r2 < 0) |
204 | err("error %d on request 0x19", -r2); | 196 | dev_err(&udev->dev, "error %d on request 0x19\n", -r2); |
205 | 197 | ||
206 | return r < 0 ? r : (r2 < 0 ? r2 : 0); | 198 | return r < 0 ? r : (r2 < 0 ? r2 : 0); |
207 | } | 199 | } |
@@ -229,8 +221,8 @@ static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) | |||
229 | case B115200: rate = 115200; break; | 221 | case B115200: rate = 115200; break; |
230 | default: | 222 | default: |
231 | rate = 9600; | 223 | rate = 9600; |
232 | err("unsupported baudrate request 0x%x," | 224 | dev_err(cs->dev, "unsupported baudrate request 0x%x," |
233 | " using default of B9600", cflag); | 225 | " using default of B9600\n", cflag); |
234 | } | 226 | } |
235 | 227 | ||
236 | val = 0x383fff / rate + 1; | 228 | val = 0x383fff / rate + 1; |
@@ -259,7 +251,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | |||
259 | case CS8: | 251 | case CS8: |
260 | val |= 8 << 8; break; | 252 | val |= 8 << 8; break; |
261 | default: | 253 | default: |
262 | err("CSIZE was not CS5-CS8, using default of 8"); | 254 | dev_err(cs->dev, "CSIZE was not CS5-CS8, using default of 8\n"); |
263 | val |= 8 << 8; | 255 | val |= 8 << 8; |
264 | break; | 256 | break; |
265 | } | 257 | } |
@@ -277,7 +269,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | |||
277 | 269 | ||
278 | #else | 270 | #else |
279 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | 271 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, |
280 | unsigned new_state) | 272 | unsigned new_state) |
281 | { | 273 | { |
282 | return -EINVAL; | 274 | return -EINVAL; |
283 | } | 275 | } |
@@ -309,15 +301,12 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
309 | return 0; | 301 | return 0; |
310 | } | 302 | } |
311 | 303 | ||
312 | //void send_ack_to_LL(void *data); | ||
313 | static int write_modem(struct cardstate *cs); | 304 | static int write_modem(struct cardstate *cs); |
314 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb); | 305 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb); |
315 | 306 | ||
316 | 307 | ||
317 | /* Handling of send queue. If there is already a skb opened, put data to | 308 | /* Write tasklet handler: Continue sending current skb, or send command, or |
318 | * the transfer buffer by calling "write_modem". Otherwise take a new skb out of the queue. | 309 | * start sending an skb from the send queue. |
319 | * This function will be called by the ISR via "transmit_chars" (USB: B-Channel Bulk callback handler | ||
320 | * via immediate task queue) or by writebuf_from_LL if the LL wants to transmit data. | ||
321 | */ | 310 | */ |
322 | static void gigaset_modem_fill(unsigned long data) | 311 | static void gigaset_modem_fill(unsigned long data) |
323 | { | 312 | { |
@@ -327,10 +316,10 @@ static void gigaset_modem_fill(unsigned long data) | |||
327 | unsigned long flags; | 316 | unsigned long flags; |
328 | int again; | 317 | int again; |
329 | 318 | ||
330 | dbg(DEBUG_OUTPUT, "modem_fill"); | 319 | gig_dbg(DEBUG_OUTPUT, "modem_fill"); |
331 | 320 | ||
332 | if (atomic_read(&cs->hw.usb->busy)) { | 321 | if (atomic_read(&cs->hw.usb->busy)) { |
333 | dbg(DEBUG_OUTPUT, "modem_fill: busy"); | 322 | gig_dbg(DEBUG_OUTPUT, "modem_fill: busy"); |
334 | return; | 323 | return; |
335 | } | 324 | } |
336 | 325 | ||
@@ -341,26 +330,27 @@ static void gigaset_modem_fill(unsigned long data) | |||
341 | cb = cs->cmdbuf; | 330 | cb = cs->cmdbuf; |
342 | spin_unlock_irqrestore(&cs->cmdlock, flags); | 331 | spin_unlock_irqrestore(&cs->cmdlock, flags); |
343 | if (cb) { /* commands to send? */ | 332 | if (cb) { /* commands to send? */ |
344 | dbg(DEBUG_OUTPUT, "modem_fill: cb"); | 333 | gig_dbg(DEBUG_OUTPUT, "modem_fill: cb"); |
345 | if (send_cb(cs, cb) < 0) { | 334 | if (send_cb(cs, cb) < 0) { |
346 | dbg(DEBUG_OUTPUT, | 335 | gig_dbg(DEBUG_OUTPUT, |
347 | "modem_fill: send_cb failed"); | 336 | "modem_fill: send_cb failed"); |
348 | again = 1; /* no callback will be called! */ | 337 | again = 1; /* no callback will be |
338 | called! */ | ||
349 | } | 339 | } |
350 | } else { /* skbs to send? */ | 340 | } else { /* skbs to send? */ |
351 | bcs->tx_skb = skb_dequeue(&bcs->squeue); | 341 | bcs->tx_skb = skb_dequeue(&bcs->squeue); |
352 | if (bcs->tx_skb) | 342 | if (bcs->tx_skb) |
353 | dbg(DEBUG_INTR, | 343 | gig_dbg(DEBUG_INTR, |
354 | "Dequeued skb (Adr: %lx)!", | 344 | "Dequeued skb (Adr: %lx)!", |
355 | (unsigned long) bcs->tx_skb); | 345 | (unsigned long) bcs->tx_skb); |
356 | } | 346 | } |
357 | } | 347 | } |
358 | 348 | ||
359 | if (bcs->tx_skb) { | 349 | if (bcs->tx_skb) { |
360 | dbg(DEBUG_OUTPUT, "modem_fill: tx_skb"); | 350 | gig_dbg(DEBUG_OUTPUT, "modem_fill: tx_skb"); |
361 | if (write_modem(cs) < 0) { | 351 | if (write_modem(cs) < 0) { |
362 | dbg(DEBUG_OUTPUT, | 352 | gig_dbg(DEBUG_OUTPUT, |
363 | "modem_fill: write_modem failed"); | 353 | "modem_fill: write_modem failed"); |
364 | // FIXME should we tell the LL? | 354 | // FIXME should we tell the LL? |
365 | again = 1; /* no callback will be called! */ | 355 | again = 1; /* no callback will be called! */ |
366 | } | 356 | } |
@@ -371,88 +361,85 @@ static void gigaset_modem_fill(unsigned long data) | |||
371 | /** | 361 | /** |
372 | * gigaset_read_int_callback | 362 | * gigaset_read_int_callback |
373 | * | 363 | * |
374 | * It is called if the data was received from the device. This is almost similiar to | 364 | * It is called if the data was received from the device. |
375 | * the interrupt service routine in the serial device. | ||
376 | */ | 365 | */ |
377 | static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs) | 366 | static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs) |
378 | { | 367 | { |
368 | struct inbuf_t *inbuf = urb->context; | ||
369 | struct cardstate *cs = inbuf->cs; | ||
379 | int resubmit = 0; | 370 | int resubmit = 0; |
380 | int r; | 371 | int r; |
381 | struct cardstate *cs; | ||
382 | unsigned numbytes; | 372 | unsigned numbytes; |
383 | unsigned char *src; | 373 | unsigned char *src; |
384 | //unsigned long flags; | 374 | unsigned long flags; |
385 | struct inbuf_t *inbuf; | ||
386 | |||
387 | IFNULLRET(urb); | ||
388 | inbuf = (struct inbuf_t *) urb->context; | ||
389 | IFNULLRET(inbuf); | ||
390 | //spin_lock_irqsave(&inbuf->lock, flags); | ||
391 | cs = inbuf->cs; | ||
392 | IFNULLGOTO(cs, exit); | ||
393 | IFNULLGOTO(cardstate, exit); | ||
394 | |||
395 | if (!atomic_read(&cs->connected)) { | ||
396 | err("%s: disconnected", __func__); | ||
397 | goto exit; | ||
398 | } | ||
399 | 375 | ||
400 | if (!urb->status) { | 376 | if (!urb->status) { |
377 | if (!cs->connected) { | ||
378 | err("%s: disconnected", __func__); /* should never happen */ | ||
379 | return; | ||
380 | } | ||
381 | |||
401 | numbytes = urb->actual_length; | 382 | numbytes = urb->actual_length; |
402 | 383 | ||
403 | if (numbytes) { | 384 | if (numbytes) { |
404 | src = inbuf->rcvbuf; | 385 | src = inbuf->rcvbuf; |
405 | if (unlikely(*src)) | 386 | if (unlikely(*src)) |
406 | warn("%s: There was no leading 0, but 0x%02x!", | 387 | dev_warn(cs->dev, |
407 | __func__, (unsigned) *src); | 388 | "%s: There was no leading 0, but 0x%02x!\n", |
389 | __func__, (unsigned) *src); | ||
408 | ++src; /* skip leading 0x00 */ | 390 | ++src; /* skip leading 0x00 */ |
409 | --numbytes; | 391 | --numbytes; |
410 | if (gigaset_fill_inbuf(inbuf, src, numbytes)) { | 392 | if (gigaset_fill_inbuf(inbuf, src, numbytes)) { |
411 | dbg(DEBUG_INTR, "%s-->BH", __func__); | 393 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); |
412 | gigaset_schedule_event(inbuf->cs); | 394 | gigaset_schedule_event(inbuf->cs); |
413 | } | 395 | } |
414 | } else | 396 | } else |
415 | dbg(DEBUG_INTR, "Received zero block length"); | 397 | gig_dbg(DEBUG_INTR, "Received zero block length"); |
416 | resubmit = 1; | 398 | resubmit = 1; |
417 | } else { | 399 | } else { |
418 | /* The urb might have been killed. */ | 400 | /* The urb might have been killed. */ |
419 | dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", | 401 | gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", |
420 | __func__, urb->status); | 402 | __func__, urb->status); |
421 | if (urb->status != -ENOENT) /* not killed */ | 403 | if (urb->status != -ENOENT) { /* not killed */ |
404 | if (!cs->connected) { | ||
405 | err("%s: disconnected", __func__); /* should never happen */ | ||
406 | return; | ||
407 | } | ||
422 | resubmit = 1; | 408 | resubmit = 1; |
409 | } | ||
423 | } | 410 | } |
424 | exit: | 411 | |
425 | //spin_unlock_irqrestore(&inbuf->lock, flags); | ||
426 | if (resubmit) { | 412 | if (resubmit) { |
427 | r = usb_submit_urb(urb, SLAB_ATOMIC); | 413 | spin_lock_irqsave(&cs->lock, flags); |
414 | r = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | ||
415 | spin_unlock_irqrestore(&cs->lock, flags); | ||
428 | if (r) | 416 | if (r) |
429 | err("error %d when resubmitting urb.", -r); | 417 | dev_err(cs->dev, "error %d when resubmitting urb.\n", |
418 | -r); | ||
430 | } | 419 | } |
431 | } | 420 | } |
432 | 421 | ||
433 | 422 | ||
434 | /* This callback routine is called when data was transmitted to a B-Channel. | 423 | /* This callback routine is called when data was transmitted to the device. */ |
435 | * Therefore it has to check if there is still data to transmit. This | ||
436 | * happens by calling modem_fill via task queue. | ||
437 | * | ||
438 | */ | ||
439 | static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs) | 424 | static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs) |
440 | { | 425 | { |
441 | struct cardstate *cs = (struct cardstate *) urb->context; | 426 | struct cardstate *cs = urb->context; |
427 | unsigned long flags; | ||
442 | 428 | ||
443 | IFNULLRET(cs); | ||
444 | #ifdef CONFIG_GIGASET_DEBUG | ||
445 | if (!atomic_read(&cs->connected)) { | ||
446 | err("%s:not connected", __func__); | ||
447 | return; | ||
448 | } | ||
449 | #endif | ||
450 | if (urb->status) | 429 | if (urb->status) |
451 | err("bulk transfer failed (status %d)", -urb->status); /* That's all we can do. Communication problems | 430 | dev_err(cs->dev, "bulk transfer failed (status %d)\n", |
452 | are handeled by timeouts or network protocols */ | 431 | -urb->status); |
432 | /* That's all we can do. Communication problems | ||
433 | are handled by timeouts or network protocols. */ | ||
453 | 434 | ||
454 | atomic_set(&cs->hw.usb->busy, 0); | 435 | spin_lock_irqsave(&cs->lock, flags); |
455 | tasklet_schedule(&cs->write_tasklet); | 436 | if (!cs->connected) { |
437 | err("%s: not connected", __func__); | ||
438 | } else { | ||
439 | atomic_set(&cs->hw.usb->busy, 0); | ||
440 | tasklet_schedule(&cs->write_tasklet); | ||
441 | } | ||
442 | spin_unlock_irqrestore(&cs->lock, flags); | ||
456 | } | 443 | } |
457 | 444 | ||
458 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | 445 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) |
@@ -469,8 +456,8 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | |||
469 | 456 | ||
470 | spin_lock_irqsave(&cs->cmdlock, flags); | 457 | spin_lock_irqsave(&cs->cmdlock, flags); |
471 | cs->cmdbytes -= cs->curlen; | 458 | cs->cmdbytes -= cs->curlen; |
472 | dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left", | 459 | gig_dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left", |
473 | cs->curlen, cs->cmdbytes); | 460 | cs->curlen, cs->cmdbytes); |
474 | cs->cmdbuf = cb = cb->next; | 461 | cs->cmdbuf = cb = cb->next; |
475 | if (cb) { | 462 | if (cb) { |
476 | cb->prev = NULL; | 463 | cb->prev = NULL; |
@@ -487,52 +474,51 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | |||
487 | } | 474 | } |
488 | if (cb) { | 475 | if (cb) { |
489 | count = min(cb->len, ucs->bulk_out_size); | 476 | count = min(cb->len, ucs->bulk_out_size); |
477 | gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count); | ||
478 | |||
490 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, | 479 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, |
491 | usb_sndbulkpipe(ucs->udev, | 480 | usb_sndbulkpipe(ucs->udev, |
492 | ucs->bulk_out_endpointAddr & 0x0f), | 481 | ucs->bulk_out_endpointAddr & 0x0f), |
493 | cb->buf + cb->offset, count, | 482 | cb->buf + cb->offset, count, |
494 | gigaset_write_bulk_callback, cs); | 483 | gigaset_write_bulk_callback, cs); |
495 | 484 | ||
496 | cb->offset += count; | 485 | cb->offset += count; |
497 | cb->len -= count; | 486 | cb->len -= count; |
498 | atomic_set(&ucs->busy, 1); | 487 | atomic_set(&ucs->busy, 1); |
499 | dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count); | ||
500 | 488 | ||
501 | status = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); | 489 | spin_lock_irqsave(&cs->lock, flags); |
490 | status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC) : -ENODEV; | ||
491 | spin_unlock_irqrestore(&cs->lock, flags); | ||
492 | |||
502 | if (status) { | 493 | if (status) { |
503 | atomic_set(&ucs->busy, 0); | 494 | atomic_set(&ucs->busy, 0); |
504 | err("could not submit urb (error %d).", | 495 | err("could not submit urb (error %d)\n", |
505 | -status); | 496 | -status); |
506 | cb->len = 0; /* skip urb => remove cb+wakeup in next loop cycle */ | 497 | cb->len = 0; /* skip urb => remove cb+wakeup |
498 | in next loop cycle */ | ||
507 | } | 499 | } |
508 | } | 500 | } |
509 | } while (cb && status); /* bei Fehler naechster Befehl //FIXME: ist das OK? */ | 501 | } while (cb && status); /* next command on error */ |
510 | 502 | ||
511 | return status; | 503 | return status; |
512 | } | 504 | } |
513 | 505 | ||
514 | /* Write string into transbuf and send it to modem. | 506 | /* Send command to device. */ |
515 | */ | ||
516 | static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, | 507 | static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, |
517 | int len, struct tasklet_struct *wake_tasklet) | 508 | int len, struct tasklet_struct *wake_tasklet) |
518 | { | 509 | { |
519 | struct cmdbuf_t *cb; | 510 | struct cmdbuf_t *cb; |
520 | unsigned long flags; | 511 | unsigned long flags; |
521 | 512 | ||
522 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? | 513 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? |
523 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 514 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
524 | "CMD Transmit", len, buf, 0); | 515 | "CMD Transmit", len, buf); |
525 | |||
526 | if (!atomic_read(&cs->connected)) { | ||
527 | err("%s: not connected", __func__); | ||
528 | return -ENODEV; | ||
529 | } | ||
530 | 516 | ||
531 | if (len <= 0) | 517 | if (len <= 0) |
532 | return 0; | 518 | return 0; |
533 | 519 | ||
534 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { | 520 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { |
535 | err("%s: out of memory", __func__); | 521 | dev_err(cs->dev, "%s: out of memory\n", __func__); |
536 | return -ENOMEM; | 522 | return -ENOMEM; |
537 | } | 523 | } |
538 | 524 | ||
@@ -554,7 +540,10 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, | |||
554 | cs->lastcmdbuf = cb; | 540 | cs->lastcmdbuf = cb; |
555 | spin_unlock_irqrestore(&cs->cmdlock, flags); | 541 | spin_unlock_irqrestore(&cs->cmdlock, flags); |
556 | 542 | ||
557 | tasklet_schedule(&cs->write_tasklet); | 543 | spin_lock_irqsave(&cs->lock, flags); |
544 | if (cs->connected) | ||
545 | tasklet_schedule(&cs->write_tasklet); | ||
546 | spin_unlock_irqrestore(&cs->lock, flags); | ||
558 | return len; | 547 | return len; |
559 | } | 548 | } |
560 | 549 | ||
@@ -578,11 +567,12 @@ static int gigaset_chars_in_buffer(struct cardstate *cs) | |||
578 | static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) | 567 | static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) |
579 | { | 568 | { |
580 | #ifdef CONFIG_GIGASET_UNDOCREQ | 569 | #ifdef CONFIG_GIGASET_UNDOCREQ |
581 | gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf, 0); | 570 | struct usb_device *udev = cs->hw.usb->udev; |
571 | |||
572 | gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf); | ||
582 | memcpy(cs->hw.usb->bchars, buf, 6); | 573 | memcpy(cs->hw.usb->bchars, buf, 6); |
583 | return usb_control_msg(cs->hw.usb->udev, | 574 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, |
584 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 0x19, 0x41, | 575 | 0, 0, &buf, 6, 2000); |
585 | 0, 0, &buf, 6, 2000); | ||
586 | #else | 576 | #else |
587 | return -EINVAL; | 577 | return -EINVAL; |
588 | #endif | 578 | #endif |
@@ -604,7 +594,6 @@ static int gigaset_initbcshw(struct bc_state *bcs) | |||
604 | if (!bcs->hw.usb) | 594 | if (!bcs->hw.usb) |
605 | return 0; | 595 | return 0; |
606 | 596 | ||
607 | //bcs->hw.usb->trans_flg = READY_TO_TRNSMIT; /* B-Channel ready to transmit */ | ||
608 | return 1; | 597 | return 1; |
609 | } | 598 | } |
610 | 599 | ||
@@ -614,7 +603,6 @@ static void gigaset_reinitbcshw(struct bc_state *bcs) | |||
614 | 603 | ||
615 | static void gigaset_freecshw(struct cardstate *cs) | 604 | static void gigaset_freecshw(struct cardstate *cs) |
616 | { | 605 | { |
617 | //FIXME | ||
618 | tasklet_kill(&cs->write_tasklet); | 606 | tasklet_kill(&cs->write_tasklet); |
619 | kfree(cs->hw.usb); | 607 | kfree(cs->hw.usb); |
620 | } | 608 | } |
@@ -639,33 +627,21 @@ static int gigaset_initcshw(struct cardstate *cs) | |||
639 | //ucs->urb_cmd_out = NULL; | 627 | //ucs->urb_cmd_out = NULL; |
640 | ucs->read_urb = NULL; | 628 | ucs->read_urb = NULL; |
641 | tasklet_init(&cs->write_tasklet, | 629 | tasklet_init(&cs->write_tasklet, |
642 | &gigaset_modem_fill, (unsigned long) cs); | 630 | &gigaset_modem_fill, (unsigned long) cs); |
643 | 631 | ||
644 | return 1; | 632 | return 1; |
645 | } | 633 | } |
646 | 634 | ||
647 | /* Writes the data of the current open skb into the modem. | 635 | /* Send data from current skb to the device. */ |
648 | * We have to protect against multiple calls until the | ||
649 | * callback handler () is called , due to the fact that we | ||
650 | * are just allowed to send data once to an endpoint. Therefore | ||
651 | * we using "trans_flg" to synchonize ... | ||
652 | */ | ||
653 | static int write_modem(struct cardstate *cs) | 636 | static int write_modem(struct cardstate *cs) |
654 | { | 637 | { |
655 | int ret; | 638 | int ret = 0; |
656 | int count; | 639 | int count; |
657 | struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ | 640 | struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ |
658 | struct usb_cardstate *ucs = cs->hw.usb; | 641 | struct usb_cardstate *ucs = cs->hw.usb; |
659 | //unsigned long flags; | 642 | unsigned long flags; |
660 | |||
661 | IFNULLRETVAL(bcs->tx_skb, -EINVAL); | ||
662 | |||
663 | dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); | ||
664 | 643 | ||
665 | ret = -ENODEV; | 644 | gig_dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); |
666 | IFNULLGOTO(ucs->bulk_out_buffer, error); | ||
667 | IFNULLGOTO(ucs->bulk_out_urb, error); | ||
668 | ret = 0; | ||
669 | 645 | ||
670 | if (!bcs->tx_skb->len) { | 646 | if (!bcs->tx_skb->len) { |
671 | dev_kfree_skb_any(bcs->tx_skb); | 647 | dev_kfree_skb_any(bcs->tx_skb); |
@@ -679,40 +655,42 @@ static int write_modem(struct cardstate *cs) | |||
679 | count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); | 655 | count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); |
680 | memcpy(ucs->bulk_out_buffer, bcs->tx_skb->data, count); | 656 | memcpy(ucs->bulk_out_buffer, bcs->tx_skb->data, count); |
681 | skb_pull(bcs->tx_skb, count); | 657 | skb_pull(bcs->tx_skb, count); |
682 | |||
683 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, | ||
684 | usb_sndbulkpipe(ucs->udev, | ||
685 | ucs->bulk_out_endpointAddr & 0x0f), | ||
686 | ucs->bulk_out_buffer, count, | ||
687 | gigaset_write_bulk_callback, cs); | ||
688 | atomic_set(&ucs->busy, 1); | 658 | atomic_set(&ucs->busy, 1); |
689 | dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); | 659 | gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); |
660 | |||
661 | spin_lock_irqsave(&cs->lock, flags); | ||
662 | if (cs->connected) { | ||
663 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, | ||
664 | usb_sndbulkpipe(ucs->udev, | ||
665 | ucs->bulk_out_endpointAddr & 0x0f), | ||
666 | ucs->bulk_out_buffer, count, | ||
667 | gigaset_write_bulk_callback, cs); | ||
668 | ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); | ||
669 | } else { | ||
670 | ret = -ENODEV; | ||
671 | } | ||
672 | spin_unlock_irqrestore(&cs->lock, flags); | ||
690 | 673 | ||
691 | ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); | ||
692 | if (ret) { | 674 | if (ret) { |
693 | err("could not submit urb (error %d).", -ret); | 675 | err("could not submit urb (error %d)\n", -ret); |
694 | atomic_set(&ucs->busy, 0); | 676 | atomic_set(&ucs->busy, 0); |
695 | } | 677 | } |
678 | |||
696 | if (!bcs->tx_skb->len) { | 679 | if (!bcs->tx_skb->len) { |
697 | /* skb sent completely */ | 680 | /* skb sent completely */ |
698 | gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0? | 681 | gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0? |
699 | 682 | ||
700 | dbg(DEBUG_INTR, | 683 | gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!", |
701 | "kfree skb (Adr: %lx)!", (unsigned long) bcs->tx_skb); | 684 | (unsigned long) bcs->tx_skb); |
702 | dev_kfree_skb_any(bcs->tx_skb); | 685 | dev_kfree_skb_any(bcs->tx_skb); |
703 | bcs->tx_skb = NULL; | 686 | bcs->tx_skb = NULL; |
704 | } | 687 | } |
705 | 688 | ||
706 | return ret; | 689 | return ret; |
707 | error: | ||
708 | dev_kfree_skb_any(bcs->tx_skb); | ||
709 | bcs->tx_skb = NULL; | ||
710 | return ret; | ||
711 | |||
712 | } | 690 | } |
713 | 691 | ||
714 | static int gigaset_probe(struct usb_interface *interface, | 692 | static int gigaset_probe(struct usb_interface *interface, |
715 | const struct usb_device_id *id) | 693 | const struct usb_device_id *id) |
716 | { | 694 | { |
717 | int retval; | 695 | int retval; |
718 | struct usb_device *udev = interface_to_usbdev(interface); | 696 | struct usb_device *udev = interface_to_usbdev(interface); |
@@ -720,16 +698,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
720 | struct usb_host_interface *hostif; | 698 | struct usb_host_interface *hostif; |
721 | struct cardstate *cs = NULL; | 699 | struct cardstate *cs = NULL; |
722 | struct usb_cardstate *ucs = NULL; | 700 | struct usb_cardstate *ucs = NULL; |
723 | //struct usb_interface_descriptor *iface_desc; | ||
724 | struct usb_endpoint_descriptor *endpoint; | 701 | struct usb_endpoint_descriptor *endpoint; |
725 | //isdn_ctrl command; | ||
726 | int buffer_size; | 702 | int buffer_size; |
727 | int alt; | 703 | int alt; |
728 | //unsigned long flags; | ||
729 | 704 | ||
730 | info("%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", | 705 | gig_dbg(DEBUG_ANY, |
731 | __func__, le16_to_cpu(udev->descriptor.idVendor), | 706 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", |
732 | le16_to_cpu(udev->descriptor.idProduct)); | 707 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
708 | le16_to_cpu(udev->descriptor.idProduct)); | ||
733 | 709 | ||
734 | retval = -ENODEV; //FIXME | 710 | retval = -ENODEV; //FIXME |
735 | 711 | ||
@@ -744,7 +720,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
744 | ifnum = hostif->desc.bInterfaceNumber; // FIXME ? | 720 | ifnum = hostif->desc.bInterfaceNumber; // FIXME ? |
745 | 721 | ||
746 | if (alt != 0 || ifnum != 0) { | 722 | if (alt != 0 || ifnum != 0) { |
747 | warn("ifnum %d, alt %d", ifnum, alt); | 723 | dev_warn(&udev->dev, "ifnum %d, alt %d\n", ifnum, alt); |
748 | return -ENODEV; | 724 | return -ENODEV; |
749 | } | 725 | } |
750 | 726 | ||
@@ -752,42 +728,29 @@ static int gigaset_probe(struct usb_interface *interface, | |||
752 | * | 728 | * |
753 | */ | 729 | */ |
754 | if (hostif->desc.bInterfaceClass != 255) { | 730 | if (hostif->desc.bInterfaceClass != 255) { |
755 | info("%s: Device matched, but iface_desc[%d]->bInterfaceClass==%d !", | 731 | dev_info(&udev->dev, |
756 | __func__, ifnum, hostif->desc.bInterfaceClass); | 732 | "%s: Device matched but iface_desc[%d]->bInterfaceClass==%d!\n", |
733 | __func__, ifnum, hostif->desc.bInterfaceClass); | ||
757 | return -ENODEV; | 734 | return -ENODEV; |
758 | } | 735 | } |
759 | 736 | ||
760 | info("%s: Device matched ... !", __func__); | 737 | dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); |
761 | 738 | ||
762 | cs = gigaset_getunassignedcs(driver); | 739 | cs = gigaset_getunassignedcs(driver); |
763 | if (!cs) { | 740 | if (!cs) { |
764 | warn("No free cardstate!"); | 741 | dev_warn(&udev->dev, "no free cardstate\n"); |
765 | return -ENODEV; | 742 | return -ENODEV; |
766 | } | 743 | } |
767 | ucs = cs->hw.usb; | 744 | ucs = cs->hw.usb; |
768 | 745 | ||
769 | #if 0 | 746 | /* save off device structure ptrs for later use */ |
770 | if (usb_set_configuration(udev, udev->config[0].desc.bConfigurationValue) < 0) { | 747 | usb_get_dev(udev); |
771 | warn("set_configuration failed"); | 748 | ucs->udev = udev; |
772 | goto error; | 749 | ucs->interface = interface; |
773 | } | 750 | cs->dev = &interface->dev; |
774 | |||
775 | |||
776 | if (usb_set_interface(udev, ifnum/*==0*/, alt/*==0*/) < 0) { | ||
777 | warn("usb_set_interface failed, device %d interface %d altsetting %d", | ||
778 | udev->devnum, ifnum, alt); | ||
779 | goto error; | ||
780 | } | ||
781 | #endif | ||
782 | 751 | ||
783 | /* set up the endpoint information */ | 752 | /* save address of controller structure */ |
784 | /* check out the endpoints */ | 753 | usb_set_intfdata(interface, cs); // dev_set_drvdata(&interface->dev, cs); |
785 | /* We will get 2 endpoints: One for sending commands to the device (bulk out) and one to | ||
786 | * poll messages from the device(int in). | ||
787 | * Therefore we will have an almost similiar situation as with our serial port handler. | ||
788 | * If an connection will be established, we will have to create data in/out pipes | ||
789 | * dynamically... | ||
790 | */ | ||
791 | 754 | ||
792 | endpoint = &hostif->endpoint[0].desc; | 755 | endpoint = &hostif->endpoint[0].desc; |
793 | 756 | ||
@@ -796,14 +759,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
796 | ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress; | 759 | ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress; |
797 | ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); | 760 | ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); |
798 | if (!ucs->bulk_out_buffer) { | 761 | if (!ucs->bulk_out_buffer) { |
799 | err("Couldn't allocate bulk_out_buffer"); | 762 | dev_err(cs->dev, "Couldn't allocate bulk_out_buffer\n"); |
800 | retval = -ENOMEM; | 763 | retval = -ENOMEM; |
801 | goto error; | 764 | goto error; |
802 | } | 765 | } |
803 | 766 | ||
804 | ucs->bulk_out_urb = usb_alloc_urb(0, SLAB_KERNEL); | 767 | ucs->bulk_out_urb = usb_alloc_urb(0, SLAB_KERNEL); |
805 | if (!ucs->bulk_out_urb) { | 768 | if (!ucs->bulk_out_urb) { |
806 | err("Couldn't allocate bulk_out_buffer"); | 769 | dev_err(cs->dev, "Couldn't allocate bulk_out_urb\n"); |
807 | retval = -ENOMEM; | 770 | retval = -ENOMEM; |
808 | goto error; | 771 | goto error; |
809 | } | 772 | } |
@@ -811,12 +774,10 @@ static int gigaset_probe(struct usb_interface *interface, | |||
811 | endpoint = &hostif->endpoint[1].desc; | 774 | endpoint = &hostif->endpoint[1].desc; |
812 | 775 | ||
813 | atomic_set(&ucs->busy, 0); | 776 | atomic_set(&ucs->busy, 0); |
814 | ucs->udev = udev; | ||
815 | ucs->interface = interface; | ||
816 | 777 | ||
817 | ucs->read_urb = usb_alloc_urb(0, SLAB_KERNEL); | 778 | ucs->read_urb = usb_alloc_urb(0, SLAB_KERNEL); |
818 | if (!ucs->read_urb) { | 779 | if (!ucs->read_urb) { |
819 | err("No free urbs available"); | 780 | dev_err(cs->dev, "No free urbs available\n"); |
820 | retval = -ENOMEM; | 781 | retval = -ENOMEM; |
821 | goto error; | 782 | goto error; |
822 | } | 783 | } |
@@ -825,38 +786,33 @@ static int gigaset_probe(struct usb_interface *interface, | |||
825 | ucs->int_in_endpointAddr = endpoint->bEndpointAddress; | 786 | ucs->int_in_endpointAddr = endpoint->bEndpointAddress; |
826 | cs->inbuf[0].rcvbuf = kmalloc(buffer_size, GFP_KERNEL); | 787 | cs->inbuf[0].rcvbuf = kmalloc(buffer_size, GFP_KERNEL); |
827 | if (!cs->inbuf[0].rcvbuf) { | 788 | if (!cs->inbuf[0].rcvbuf) { |
828 | err("Couldn't allocate rcvbuf"); | 789 | dev_err(cs->dev, "Couldn't allocate rcvbuf\n"); |
829 | retval = -ENOMEM; | 790 | retval = -ENOMEM; |
830 | goto error; | 791 | goto error; |
831 | } | 792 | } |
832 | /* Fill the interrupt urb and send it to the core */ | 793 | /* Fill the interrupt urb and send it to the core */ |
833 | usb_fill_int_urb(ucs->read_urb, udev, | 794 | usb_fill_int_urb(ucs->read_urb, udev, |
834 | usb_rcvintpipe(udev, | 795 | usb_rcvintpipe(udev, |
835 | endpoint->bEndpointAddress & 0x0f), | 796 | endpoint->bEndpointAddress & 0x0f), |
836 | cs->inbuf[0].rcvbuf, buffer_size, | 797 | cs->inbuf[0].rcvbuf, buffer_size, |
837 | gigaset_read_int_callback, | 798 | gigaset_read_int_callback, |
838 | cs->inbuf + 0, endpoint->bInterval); | 799 | cs->inbuf + 0, endpoint->bInterval); |
839 | 800 | ||
840 | retval = usb_submit_urb(ucs->read_urb, SLAB_KERNEL); | 801 | retval = usb_submit_urb(ucs->read_urb, SLAB_KERNEL); |
841 | if (retval) { | 802 | if (retval) { |
842 | err("Could not submit URB!"); | 803 | dev_err(cs->dev, "Could not submit URB (error %d)\n", -retval); |
843 | goto error; | 804 | goto error; |
844 | } | 805 | } |
845 | 806 | ||
846 | /* tell common part that the device is ready */ | 807 | /* tell common part that the device is ready */ |
847 | if (startmode == SM_LOCKED) | 808 | if (startmode == SM_LOCKED) |
848 | atomic_set(&cs->mstate, MS_LOCKED); | 809 | atomic_set(&cs->mstate, MS_LOCKED); |
810 | |||
849 | if (!gigaset_start(cs)) { | 811 | if (!gigaset_start(cs)) { |
850 | tasklet_kill(&cs->write_tasklet); | 812 | tasklet_kill(&cs->write_tasklet); |
851 | retval = -ENODEV; //FIXME | 813 | retval = -ENODEV; //FIXME |
852 | goto error; | 814 | goto error; |
853 | } | 815 | } |
854 | |||
855 | /* save address of controller structure */ | ||
856 | usb_set_intfdata(interface, cs); | ||
857 | |||
858 | /* set up device sysfs */ | ||
859 | gigaset_init_dev_sysfs(interface); | ||
860 | return 0; | 816 | return 0; |
861 | 817 | ||
862 | error: | 818 | error: |
@@ -868,48 +824,45 @@ error: | |||
868 | kfree(cs->inbuf[0].rcvbuf); | 824 | kfree(cs->inbuf[0].rcvbuf); |
869 | if (ucs->read_urb != NULL) | 825 | if (ucs->read_urb != NULL) |
870 | usb_free_urb(ucs->read_urb); | 826 | usb_free_urb(ucs->read_urb); |
827 | usb_set_intfdata(interface, NULL); | ||
871 | ucs->read_urb = ucs->bulk_out_urb = NULL; | 828 | ucs->read_urb = ucs->bulk_out_urb = NULL; |
872 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; | 829 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; |
830 | usb_put_dev(ucs->udev); | ||
831 | ucs->udev = NULL; | ||
832 | ucs->interface = NULL; | ||
873 | gigaset_unassign(cs); | 833 | gigaset_unassign(cs); |
874 | return retval; | 834 | return retval; |
875 | } | 835 | } |
876 | 836 | ||
877 | /** | ||
878 | * skel_disconnect | ||
879 | */ | ||
880 | static void gigaset_disconnect(struct usb_interface *interface) | 837 | static void gigaset_disconnect(struct usb_interface *interface) |
881 | { | 838 | { |
882 | struct cardstate *cs; | 839 | struct cardstate *cs; |
883 | struct usb_cardstate *ucs; | 840 | struct usb_cardstate *ucs; |
884 | 841 | ||
885 | cs = usb_get_intfdata(interface); | 842 | cs = usb_get_intfdata(interface); |
886 | |||
887 | /* clear device sysfs */ | ||
888 | gigaset_free_dev_sysfs(interface); | ||
889 | |||
890 | usb_set_intfdata(interface, NULL); | ||
891 | ucs = cs->hw.usb; | 843 | ucs = cs->hw.usb; |
892 | usb_kill_urb(ucs->read_urb); | 844 | usb_kill_urb(ucs->read_urb); |
893 | //info("GigaSet USB device #%d will be disconnected", minor); | ||
894 | 845 | ||
895 | gigaset_stop(cs); | 846 | gigaset_stop(cs); |
896 | 847 | ||
848 | usb_set_intfdata(interface, NULL); | ||
897 | tasklet_kill(&cs->write_tasklet); | 849 | tasklet_kill(&cs->write_tasklet); |
898 | 850 | ||
899 | usb_kill_urb(ucs->bulk_out_urb); /* FIXME: nur, wenn noetig */ | 851 | usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */ |
900 | //usb_kill_urb(ucs->urb_cmd_out); /* FIXME: nur, wenn noetig */ | ||
901 | 852 | ||
902 | kfree(ucs->bulk_out_buffer); | 853 | kfree(ucs->bulk_out_buffer); |
903 | if (ucs->bulk_out_urb != NULL) | 854 | if (ucs->bulk_out_urb != NULL) |
904 | usb_free_urb(ucs->bulk_out_urb); | 855 | usb_free_urb(ucs->bulk_out_urb); |
905 | //if(ucs->urb_cmd_out != NULL) | ||
906 | // usb_free_urb(ucs->urb_cmd_out); | ||
907 | kfree(cs->inbuf[0].rcvbuf); | 856 | kfree(cs->inbuf[0].rcvbuf); |
908 | if (ucs->read_urb != NULL) | 857 | if (ucs->read_urb != NULL) |
909 | usb_free_urb(ucs->read_urb); | 858 | usb_free_urb(ucs->read_urb); |
910 | ucs->read_urb = ucs->bulk_out_urb/*=ucs->urb_cmd_out*/=NULL; | 859 | ucs->read_urb = ucs->bulk_out_urb = NULL; |
911 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; | 860 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; |
912 | 861 | ||
862 | usb_put_dev(ucs->udev); | ||
863 | ucs->interface = NULL; | ||
864 | ucs->udev = NULL; | ||
865 | cs->dev = NULL; | ||
913 | gigaset_unassign(cs); | 866 | gigaset_unassign(cs); |
914 | } | 867 | } |
915 | 868 | ||
@@ -942,9 +895,9 @@ static int __init usb_gigaset_init(void) | |||
942 | 895 | ||
943 | /* allocate memory for our driver state and intialize it */ | 896 | /* allocate memory for our driver state and intialize it */ |
944 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 897 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
945 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 898 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
946 | GIGASET_DEVFSNAME, &ops, | 899 | GIGASET_DEVFSNAME, &ops, |
947 | THIS_MODULE)) == NULL) | 900 | THIS_MODULE)) == NULL) |
948 | goto error; | 901 | goto error; |
949 | 902 | ||
950 | /* allocate memory for our device state and intialize it */ | 903 | /* allocate memory for our device state and intialize it */ |
@@ -981,8 +934,8 @@ error: if (cardstate) | |||
981 | static void __exit usb_gigaset_exit(void) | 934 | static void __exit usb_gigaset_exit(void) |
982 | { | 935 | { |
983 | gigaset_blockdriver(driver); /* => probe will fail | 936 | gigaset_blockdriver(driver); /* => probe will fail |
984 | * => no gigaset_start any more | 937 | * => no gigaset_start any more |
985 | */ | 938 | */ |
986 | 939 | ||
987 | gigaset_shutdown(cardstate); | 940 | gigaset_shutdown(cardstate); |
988 | /* from now on, no isdn callback should be possible */ | 941 | /* from now on, no isdn callback should be possible */ |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 2c4f20b7f021..3f5b64794542 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -14,13 +14,7 @@ config LEDS_CLASS | |||
14 | This option enables the led sysfs class in /sys/class/leds. You'll | 14 | This option enables the led sysfs class in /sys/class/leds. You'll |
15 | need this to do anything useful with LEDs. If unsure, say N. | 15 | need this to do anything useful with LEDs. If unsure, say N. |
16 | 16 | ||
17 | config LEDS_TRIGGERS | 17 | comment "LED drivers" |
18 | bool "LED Trigger support" | ||
19 | depends NEW_LEDS | ||
20 | help | ||
21 | This option enables trigger support for the leds class. | ||
22 | These triggers allow kernel events to drive the LEDs and can | ||
23 | be configured via sysfs. If unsure, say Y. | ||
24 | 18 | ||
25 | config LEDS_CORGI | 19 | config LEDS_CORGI |
26 | tristate "LED Support for the Sharp SL-C7x0 series" | 20 | tristate "LED Support for the Sharp SL-C7x0 series" |
@@ -59,6 +53,23 @@ config LEDS_TOSA | |||
59 | This option enables support for the LEDs on Sharp Zaurus | 53 | This option enables support for the LEDs on Sharp Zaurus |
60 | SL-6000 series. | 54 | SL-6000 series. |
61 | 55 | ||
56 | config LEDS_S3C24XX | ||
57 | tristate "LED Support for Samsung S3C24XX GPIO LEDs" | ||
58 | depends on LEDS_CLASS && ARCH_S3C2410 | ||
59 | help | ||
60 | This option enables support for LEDs connected to GPIO lines | ||
61 | on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. | ||
62 | |||
63 | comment "LED Triggers" | ||
64 | |||
65 | config LEDS_TRIGGERS | ||
66 | bool "LED Trigger support" | ||
67 | depends NEW_LEDS | ||
68 | help | ||
69 | This option enables trigger support for the leds class. | ||
70 | These triggers allow kernel events to drive the LEDs and can | ||
71 | be configured via sysfs. If unsure, say Y. | ||
72 | |||
62 | config LEDS_TRIGGER_TIMER | 73 | config LEDS_TRIGGER_TIMER |
63 | tristate "LED Timer Trigger" | 74 | tristate "LED Timer Trigger" |
64 | depends LEDS_TRIGGERS | 75 | depends LEDS_TRIGGERS |
@@ -67,7 +78,7 @@ config LEDS_TRIGGER_TIMER | |||
67 | via sysfs. If unsure, say Y. | 78 | via sysfs. If unsure, say Y. |
68 | 79 | ||
69 | config LEDS_TRIGGER_IDE_DISK | 80 | config LEDS_TRIGGER_IDE_DISK |
70 | bool "LED Timer Trigger" | 81 | bool "LED IDE Disk Trigger" |
71 | depends LEDS_TRIGGERS && BLK_DEV_IDEDISK | 82 | depends LEDS_TRIGGERS && BLK_DEV_IDEDISK |
72 | help | 83 | help |
73 | This allows LEDs to be controlled by IDE disk activity. | 84 | This allows LEDs to be controlled by IDE disk activity. |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 40699d3cabbf..40f042633bf5 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o | |||
10 | obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o | 10 | obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o |
11 | obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o | 11 | obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o |
12 | obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o | 12 | obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o |
13 | obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o | ||
13 | 14 | ||
14 | # LED Triggers | 15 | # LED Triggers |
15 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o | 16 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o |
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c new file mode 100644 index 000000000000..650cf72dc675 --- /dev/null +++ b/drivers/leds/leds-s3c24xx.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* drivers/leds/leds-s3c24xx.c | ||
2 | * | ||
3 | * (c) 2006 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C24XX - LEDs GPIO driver | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/leds.h> | ||
19 | |||
20 | #include <asm/arch/hardware.h> | ||
21 | #include <asm/arch/regs-gpio.h> | ||
22 | #include <asm/arch/leds-gpio.h> | ||
23 | |||
24 | /* our context */ | ||
25 | |||
26 | struct s3c24xx_gpio_led { | ||
27 | struct led_classdev cdev; | ||
28 | struct s3c24xx_led_platdata *pdata; | ||
29 | }; | ||
30 | |||
31 | static inline struct s3c24xx_gpio_led *pdev_to_gpio(struct platform_device *dev) | ||
32 | { | ||
33 | return platform_get_drvdata(dev); | ||
34 | } | ||
35 | |||
36 | static inline struct s3c24xx_gpio_led *to_gpio(struct led_classdev *led_cdev) | ||
37 | { | ||
38 | return container_of(led_cdev, struct s3c24xx_gpio_led, cdev); | ||
39 | } | ||
40 | |||
41 | static void s3c24xx_led_set(struct led_classdev *led_cdev, | ||
42 | enum led_brightness value) | ||
43 | { | ||
44 | struct s3c24xx_gpio_led *led = to_gpio(led_cdev); | ||
45 | struct s3c24xx_led_platdata *pd = led->pdata; | ||
46 | |||
47 | /* there will be a sort delay between setting the output and | ||
48 | * going from output to input when using tristate. */ | ||
49 | |||
50 | s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^ | ||
51 | (pd->flags & S3C24XX_LEDF_ACTLOW)); | ||
52 | |||
53 | if (pd->flags & S3C24XX_LEDF_TRISTATE) | ||
54 | s3c2410_gpio_cfgpin(pd->gpio, | ||
55 | value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT); | ||
56 | |||
57 | } | ||
58 | |||
59 | static int s3c24xx_led_remove(struct platform_device *dev) | ||
60 | { | ||
61 | struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); | ||
62 | |||
63 | led_classdev_unregister(&led->cdev); | ||
64 | kfree(led); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static int s3c24xx_led_probe(struct platform_device *dev) | ||
70 | { | ||
71 | struct s3c24xx_led_platdata *pdata = dev->dev.platform_data; | ||
72 | struct s3c24xx_gpio_led *led; | ||
73 | int ret; | ||
74 | |||
75 | led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL); | ||
76 | if (led == NULL) { | ||
77 | dev_err(&dev->dev, "No memory for device\n"); | ||
78 | return -ENOMEM; | ||
79 | } | ||
80 | |||
81 | platform_set_drvdata(dev, led); | ||
82 | |||
83 | led->cdev.brightness_set = s3c24xx_led_set; | ||
84 | led->cdev.default_trigger = pdata->def_trigger; | ||
85 | led->cdev.name = pdata->name; | ||
86 | |||
87 | led->pdata = pdata; | ||
88 | |||
89 | /* no point in having a pull-up if we are always driving */ | ||
90 | |||
91 | if (pdata->flags & S3C24XX_LEDF_TRISTATE) { | ||
92 | s3c2410_gpio_setpin(pdata->gpio, 0); | ||
93 | s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_INPUT); | ||
94 | } else { | ||
95 | s3c2410_gpio_pullup(pdata->gpio, 0); | ||
96 | s3c2410_gpio_setpin(pdata->gpio, 0); | ||
97 | s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_OUTPUT); | ||
98 | } | ||
99 | |||
100 | /* register our new led device */ | ||
101 | |||
102 | ret = led_classdev_register(&dev->dev, &led->cdev); | ||
103 | if (ret < 0) { | ||
104 | dev_err(&dev->dev, "led_classdev_register failed\n"); | ||
105 | goto exit_err1; | ||
106 | } | ||
107 | |||
108 | return 0; | ||
109 | |||
110 | exit_err1: | ||
111 | kfree(led); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | |||
116 | #ifdef CONFIG_PM | ||
117 | static int s3c24xx_led_suspend(struct platform_device *dev, pm_message_t state) | ||
118 | { | ||
119 | struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); | ||
120 | |||
121 | led_classdev_suspend(&led->cdev); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int s3c24xx_led_resume(struct platform_device *dev) | ||
126 | { | ||
127 | struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); | ||
128 | |||
129 | led_classdev_resume(&led->cdev); | ||
130 | return 0; | ||
131 | } | ||
132 | #else | ||
133 | #define s3c24xx_led_suspend NULL | ||
134 | #define s3c24xx_led_resume NULL | ||
135 | #endif | ||
136 | |||
137 | static struct platform_driver s3c24xx_led_driver = { | ||
138 | .probe = s3c24xx_led_probe, | ||
139 | .remove = s3c24xx_led_remove, | ||
140 | .suspend = s3c24xx_led_suspend, | ||
141 | .resume = s3c24xx_led_resume, | ||
142 | .driver = { | ||
143 | .name = "s3c24xx_led", | ||
144 | .owner = THIS_MODULE, | ||
145 | }, | ||
146 | }; | ||
147 | |||
148 | static int __init s3c24xx_led_init(void) | ||
149 | { | ||
150 | return platform_driver_register(&s3c24xx_led_driver); | ||
151 | } | ||
152 | |||
153 | static void __exit s3c24xx_led_exit(void) | ||
154 | { | ||
155 | platform_driver_unregister(&s3c24xx_led_driver); | ||
156 | } | ||
157 | |||
158 | module_init(s3c24xx_led_init); | ||
159 | module_exit(s3c24xx_led_exit); | ||
160 | |||
161 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
162 | MODULE_DESCRIPTION("S3C24XX LED driver"); | ||
163 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index fd2aae150ccc..ac25a48362ac 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig | |||
@@ -139,11 +139,12 @@ config MD_RAID5_RESHAPE | |||
139 | is online. However it is still EXPERIMENTAL code. It should | 139 | is online. However it is still EXPERIMENTAL code. It should |
140 | work, but please be sure that you have backups. | 140 | work, but please be sure that you have backups. |
141 | 141 | ||
142 | You will need a version of mdadm newer than 2.3.1. During the | 142 | You will need mdadm verion 2.4.1 or later to use this |
143 | early stage of reshape there is a critical section where live data | 143 | feature safely. During the early stage of reshape there is |
144 | is being over-written. A crash during this time needs extra care | 144 | a critical section where live data is being over-written. A |
145 | for recovery. The newer mdadm takes a copy of the data in the | 145 | crash during this time needs extra care for recovery. The |
146 | critical section and will restore it, if necessary, after a crash. | 146 | newer mdadm takes a copy of the data in the critical section |
147 | and will restore it, if necessary, after a crash. | ||
147 | 148 | ||
148 | The mdadm usage is e.g. | 149 | The mdadm usage is e.g. |
149 | mdadm --grow /dev/md1 --raid-disks=6 | 150 | mdadm --grow /dev/md1 --raid-disks=6 |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 4092a5e37ffc..b3ea2d63db9b 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -84,4 +84,4 @@ obj-$(CONFIG_USB_IBMCAM) += usbvideo/ | |||
84 | obj-$(CONFIG_USB_KONICAWC) += usbvideo/ | 84 | obj-$(CONFIG_USB_KONICAWC) += usbvideo/ |
85 | obj-$(CONFIG_USB_VICAM) += usbvideo/ | 85 | obj-$(CONFIG_USB_VICAM) += usbvideo/ |
86 | 86 | ||
87 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 87 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile index 94350f21cdc0..db641a36b197 100644 --- a/drivers/media/video/bt8xx/Makefile +++ b/drivers/media/video/bt8xx/Makefile | |||
@@ -9,4 +9,4 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ | |||
9 | obj-$(CONFIG_VIDEO_BT848) += bttv.o | 9 | obj-$(CONFIG_VIDEO_BT848) += bttv.o |
10 | 10 | ||
11 | EXTRA_CFLAGS += -I$(src)/.. | 11 | EXTRA_CFLAGS += -I$(src)/.. |
12 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
diff --git a/drivers/media/video/cx25840/Makefile b/drivers/media/video/cx25840/Makefile index 32a896c23d1e..6e8665be8954 100644 --- a/drivers/media/video/cx25840/Makefile +++ b/drivers/media/video/cx25840/Makefile | |||
@@ -3,4 +3,4 @@ cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \ | |||
3 | 3 | ||
4 | obj-$(CONFIG_VIDEO_CX25840) += cx25840.o | 4 | obj-$(CONFIG_VIDEO_CX25840) += cx25840.o |
5 | 5 | ||
6 | EXTRA_CFLAGS += -I$(src)/.. | 6 | EXTRA_CFLAGS += -Idrivers/media/video |
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 6482b9aa6a1f..0dcd09b9b727 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
@@ -8,9 +8,9 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o | |||
8 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o | 8 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o |
9 | obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o | 9 | obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o |
10 | 10 | ||
11 | EXTRA_CFLAGS += -I$(src)/.. | 11 | EXTRA_CFLAGS += -Idrivers/media/video |
12 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
13 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends | 13 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
14 | 14 | ||
15 | extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 | 15 | extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 |
16 | extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1 | 16 | extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1 |
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile index da457a05b0dd..826d0e340753 100644 --- a/drivers/media/video/em28xx/Makefile +++ b/drivers/media/video/em28xx/Makefile | |||
@@ -3,4 +3,4 @@ em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \ | |||
3 | 3 | ||
4 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o | 4 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o |
5 | 5 | ||
6 | EXTRA_CFLAGS += -I$(src)/.. | 6 | EXTRA_CFLAGS += -Idrivers/media/video |
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index 1ba998424bbd..be7b9ee697d6 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile | |||
@@ -11,9 +11,9 @@ obj-$(CONFIG_VIDEO_SAA7134_OSS) += saa7134-oss.o | |||
11 | 11 | ||
12 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o | 12 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o |
13 | 13 | ||
14 | EXTRA_CFLAGS += -I$(src)/.. | 14 | EXTRA_CFLAGS += -Idrivers/media/video |
15 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 15 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
16 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends | 16 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
17 | 17 | ||
18 | extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 | 18 | extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 |
19 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 | 19 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index c98571c9d5a6..13de05532e0a 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/dma-mapping.h> | ||
35 | 36 | ||
36 | #include "saa7134-reg.h" | 37 | #include "saa7134-reg.h" |
37 | #include "saa7134.h" | 38 | #include "saa7134.h" |
@@ -870,7 +871,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
870 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 871 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
871 | dev->pci_lat,pci_resource_start(pci_dev,0)); | 872 | dev->pci_lat,pci_resource_start(pci_dev,0)); |
872 | pci_set_master(pci_dev); | 873 | pci_set_master(pci_dev); |
873 | if (!pci_dma_supported(pci_dev,0xffffffff)) { | 874 | if (!pci_dma_supported(pci_dev, DMA_32BIT_MASK)) { |
874 | printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); | 875 | printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); |
875 | err = -EIO; | 876 | err = -EIO; |
876 | goto fail1; | 877 | goto fail1; |
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index dd628cb51e31..7fac438b5c32 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig | |||
@@ -129,8 +129,8 @@ config MTDRAM_ABS_POS | |||
129 | allocating space from Linux's available memory. Otherwise, leave | 129 | allocating space from Linux's available memory. Otherwise, leave |
130 | this set to zero. Most people will want to leave this as zero. | 130 | this set to zero. Most people will want to leave this as zero. |
131 | 131 | ||
132 | config MTD_BLKMTD | 132 | config MTD_BLOCK2MTD |
133 | tristate "MTD emulation using block device" | 133 | tristate "MTD using block device" |
134 | depends on MTD | 134 | depends on MTD |
135 | help | 135 | help |
136 | This driver allows a block device to appear as an MTD. It would | 136 | This driver allows a block device to appear as an MTD. It would |
@@ -141,15 +141,6 @@ config MTD_BLKMTD | |||
141 | Testing MTD users (eg JFFS2) on large media and media that might | 141 | Testing MTD users (eg JFFS2) on large media and media that might |
142 | be removed during a write (using the floppy drive). | 142 | be removed during a write (using the floppy drive). |
143 | 143 | ||
144 | config MTD_BLOCK2MTD | ||
145 | tristate "MTD using block device (rewrite)" | ||
146 | depends on MTD && EXPERIMENTAL | ||
147 | help | ||
148 | This driver is basically the same at MTD_BLKMTD above, but | ||
149 | experienced some interface changes plus serious speedups. In | ||
150 | the long term, it should replace MTD_BLKMTD. Right now, you | ||
151 | shouldn't entrust important data to it yet. | ||
152 | |||
153 | comment "Disk-On-Chip Device Drivers" | 144 | comment "Disk-On-Chip Device Drivers" |
154 | 145 | ||
155 | config MTD_DOC2000 | 146 | config MTD_DOC2000 |
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index 7c5ed2178380..b6573670316f 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile | |||
@@ -21,7 +21,6 @@ obj-$(CONFIG_MTD_PMC551) += pmc551.o | |||
21 | obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o | 21 | obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o |
22 | obj-$(CONFIG_MTD_MTDRAM) += mtdram.o | 22 | obj-$(CONFIG_MTD_MTDRAM) += mtdram.o |
23 | obj-$(CONFIG_MTD_LART) += lart.o | 23 | obj-$(CONFIG_MTD_LART) += lart.o |
24 | obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o | ||
25 | obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o | 24 | obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o |
26 | obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o | 25 | obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o |
27 | obj-$(CONFIG_MTD_M25P80) += m25p80.o | 26 | obj-$(CONFIG_MTD_M25P80) += m25p80.o |
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c deleted file mode 100644 index 79f2e1f23ebd..000000000000 --- a/drivers/mtd/devices/blkmtd.c +++ /dev/null | |||
@@ -1,819 +0,0 @@ | |||
1 | /* | ||
2 | * $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $ | ||
3 | * | ||
4 | * blkmtd.c - use a block device as a fake MTD | ||
5 | * | ||
6 | * Author: Simon Evans <spse@secret.org.uk> | ||
7 | * | ||
8 | * Copyright (C) 2001,2002 Simon Evans | ||
9 | * | ||
10 | * Licence: GPL | ||
11 | * | ||
12 | * How it works: | ||
13 | * The driver uses raw/io to read/write the device and the page | ||
14 | * cache to cache access. Writes update the page cache with the | ||
15 | * new data and mark it dirty and add the page into a BIO which | ||
16 | * is then written out. | ||
17 | * | ||
18 | * It can be loaded Read-Only to prevent erases and writes to the | ||
19 | * medium. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/config.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/fs.h> | ||
26 | #include <linux/blkdev.h> | ||
27 | #include <linux/bio.h> | ||
28 | #include <linux/pagemap.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/mount.h> | ||
32 | #include <linux/mtd/mtd.h> | ||
33 | #include <linux/mutex.h> | ||
34 | |||
35 | #define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) | ||
36 | #define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) | ||
37 | #define warn(format, arg...) printk(KERN_WARNING "blkmtd: " format "\n" , ## arg) | ||
38 | #define crit(format, arg...) printk(KERN_CRIT "blkmtd: " format "\n" , ## arg) | ||
39 | |||
40 | |||
41 | /* Default erase size in K, always make it a multiple of PAGE_SIZE */ | ||
42 | #define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */ | ||
43 | #define VERSION "$Revision: 1.27 $" | ||
44 | |||
45 | /* Info for the block device */ | ||
46 | struct blkmtd_dev { | ||
47 | struct list_head list; | ||
48 | struct block_device *blkdev; | ||
49 | struct mtd_info mtd_info; | ||
50 | struct mutex wrbuf_mutex; | ||
51 | }; | ||
52 | |||
53 | |||
54 | /* Static info about the MTD, used in cleanup_module */ | ||
55 | static LIST_HEAD(blkmtd_device_list); | ||
56 | |||
57 | |||
58 | static void blkmtd_sync(struct mtd_info *mtd); | ||
59 | |||
60 | #define MAX_DEVICES 4 | ||
61 | |||
62 | /* Module parameters passed by insmod/modprobe */ | ||
63 | static char *device[MAX_DEVICES]; /* the block device to use */ | ||
64 | static int erasesz[MAX_DEVICES]; /* optional default erase size */ | ||
65 | static int ro[MAX_DEVICES]; /* optional read only flag */ | ||
66 | static int sync; | ||
67 | |||
68 | |||
69 | MODULE_LICENSE("GPL"); | ||
70 | MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>"); | ||
71 | MODULE_DESCRIPTION("Emulate an MTD using a block device"); | ||
72 | module_param_array(device, charp, NULL, 0); | ||
73 | MODULE_PARM_DESC(device, "block device to use"); | ||
74 | module_param_array(erasesz, int, NULL, 0); | ||
75 | MODULE_PARM_DESC(erasesz, "optional erase size to use in KiB. eg 4=4KiB."); | ||
76 | module_param_array(ro, bool, NULL, 0); | ||
77 | MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors"); | ||
78 | module_param(sync, bool, 0); | ||
79 | MODULE_PARM_DESC(sync, "1=Synchronous writes"); | ||
80 | |||
81 | |||
82 | /* completion handler for BIO reads */ | ||
83 | static int bi_read_complete(struct bio *bio, unsigned int bytes_done, int error) | ||
84 | { | ||
85 | if (bio->bi_size) | ||
86 | return 1; | ||
87 | |||
88 | complete((struct completion*)bio->bi_private); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | |||
93 | /* completion handler for BIO writes */ | ||
94 | static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error) | ||
95 | { | ||
96 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | ||
97 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | ||
98 | |||
99 | if (bio->bi_size) | ||
100 | return 1; | ||
101 | |||
102 | if(!uptodate) | ||
103 | err("bi_write_complete: not uptodate\n"); | ||
104 | |||
105 | do { | ||
106 | struct page *page = bvec->bv_page; | ||
107 | DEBUG(3, "Cleaning up page %ld\n", page->index); | ||
108 | if (--bvec >= bio->bi_io_vec) | ||
109 | prefetchw(&bvec->bv_page->flags); | ||
110 | |||
111 | if (uptodate) { | ||
112 | SetPageUptodate(page); | ||
113 | } else { | ||
114 | ClearPageUptodate(page); | ||
115 | SetPageError(page); | ||
116 | } | ||
117 | clear_page_dirty(page); | ||
118 | unlock_page(page); | ||
119 | page_cache_release(page); | ||
120 | } while (bvec >= bio->bi_io_vec); | ||
121 | |||
122 | complete((struct completion*)bio->bi_private); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | |||
127 | /* read one page from the block device */ | ||
128 | static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page) | ||
129 | { | ||
130 | struct bio *bio; | ||
131 | struct completion event; | ||
132 | int err = -ENOMEM; | ||
133 | |||
134 | if(PageUptodate(page)) { | ||
135 | DEBUG(2, "blkmtd: readpage page %ld is already upto date\n", page->index); | ||
136 | unlock_page(page); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | ClearPageUptodate(page); | ||
141 | ClearPageError(page); | ||
142 | |||
143 | bio = bio_alloc(GFP_KERNEL, 1); | ||
144 | if(bio) { | ||
145 | init_completion(&event); | ||
146 | bio->bi_bdev = dev->blkdev; | ||
147 | bio->bi_sector = page->index << (PAGE_SHIFT-9); | ||
148 | bio->bi_private = &event; | ||
149 | bio->bi_end_io = bi_read_complete; | ||
150 | if(bio_add_page(bio, page, PAGE_SIZE, 0) == PAGE_SIZE) { | ||
151 | submit_bio(READ_SYNC, bio); | ||
152 | wait_for_completion(&event); | ||
153 | err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; | ||
154 | bio_put(bio); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | if(err) | ||
159 | SetPageError(page); | ||
160 | else | ||
161 | SetPageUptodate(page); | ||
162 | flush_dcache_page(page); | ||
163 | unlock_page(page); | ||
164 | return err; | ||
165 | } | ||
166 | |||
167 | |||
168 | /* write out the current BIO and wait for it to finish */ | ||
169 | static int blkmtd_write_out(struct bio *bio) | ||
170 | { | ||
171 | struct completion event; | ||
172 | int err; | ||
173 | |||
174 | if(!bio->bi_vcnt) { | ||
175 | bio_put(bio); | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | init_completion(&event); | ||
180 | bio->bi_private = &event; | ||
181 | bio->bi_end_io = bi_write_complete; | ||
182 | submit_bio(WRITE_SYNC, bio); | ||
183 | wait_for_completion(&event); | ||
184 | DEBUG(3, "submit_bio completed, bi_vcnt = %d\n", bio->bi_vcnt); | ||
185 | err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; | ||
186 | bio_put(bio); | ||
187 | return err; | ||
188 | } | ||
189 | |||
190 | |||
191 | /** | ||
192 | * blkmtd_add_page - add a page to the current BIO | ||
193 | * @bio: bio to add to (NULL to alloc initial bio) | ||
194 | * @blkdev: block device | ||
195 | * @page: page to add | ||
196 | * @pagecnt: pages left to add | ||
197 | * | ||
198 | * Adds a page to the current bio, allocating it if necessary. If it cannot be | ||
199 | * added, the current bio is written out and a new one is allocated. Returns | ||
200 | * the new bio to add or NULL on error | ||
201 | */ | ||
202 | static struct bio *blkmtd_add_page(struct bio *bio, struct block_device *blkdev, | ||
203 | struct page *page, int pagecnt) | ||
204 | { | ||
205 | |||
206 | retry: | ||
207 | if(!bio) { | ||
208 | bio = bio_alloc(GFP_KERNEL, pagecnt); | ||
209 | if(!bio) | ||
210 | return NULL; | ||
211 | bio->bi_sector = page->index << (PAGE_SHIFT-9); | ||
212 | bio->bi_bdev = blkdev; | ||
213 | } | ||
214 | |||
215 | if(bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) { | ||
216 | blkmtd_write_out(bio); | ||
217 | bio = NULL; | ||
218 | goto retry; | ||
219 | } | ||
220 | return bio; | ||
221 | } | ||
222 | |||
223 | |||
224 | /** | ||
225 | * write_pages - write block of data to device via the page cache | ||
226 | * @dev: device to write to | ||
227 | * @buf: data source or NULL if erase (output is set to 0xff) | ||
228 | * @to: offset into output device | ||
229 | * @len: amount to data to write | ||
230 | * @retlen: amount of data written | ||
231 | * | ||
232 | * Grab pages from the page cache and fill them with the source data. | ||
233 | * Non page aligned start and end result in a readin of the page and | ||
234 | * part of the page being modified. Pages are added to the bio and then written | ||
235 | * out. | ||
236 | */ | ||
237 | static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, | ||
238 | size_t len, size_t *retlen) | ||
239 | { | ||
240 | int pagenr, offset; | ||
241 | size_t start_len = 0, end_len; | ||
242 | int pagecnt = 0; | ||
243 | int err = 0; | ||
244 | struct bio *bio = NULL; | ||
245 | size_t thislen = 0; | ||
246 | |||
247 | pagenr = to >> PAGE_SHIFT; | ||
248 | offset = to & ~PAGE_MASK; | ||
249 | |||
250 | DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %zd pagenr = %d offset = %d\n", | ||
251 | buf, (long)to, len, pagenr, offset); | ||
252 | |||
253 | /* see if we have to do a partial write at the start */ | ||
254 | if(offset) { | ||
255 | start_len = ((offset + len) > PAGE_SIZE) ? PAGE_SIZE - offset : len; | ||
256 | len -= start_len; | ||
257 | } | ||
258 | |||
259 | /* calculate the length of the other two regions */ | ||
260 | end_len = len & ~PAGE_MASK; | ||
261 | len -= end_len; | ||
262 | |||
263 | if(start_len) | ||
264 | pagecnt++; | ||
265 | |||
266 | if(len) | ||
267 | pagecnt += len >> PAGE_SHIFT; | ||
268 | |||
269 | if(end_len) | ||
270 | pagecnt++; | ||
271 | |||
272 | mutex_lock(&dev->wrbuf_mutex); | ||
273 | |||
274 | DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n", | ||
275 | start_len, len, end_len, pagecnt); | ||
276 | |||
277 | if(start_len) { | ||
278 | /* do partial start region */ | ||
279 | struct page *page; | ||
280 | |||
281 | DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %zd offset = %d\n", | ||
282 | pagenr, start_len, offset); | ||
283 | |||
284 | BUG_ON(!buf); | ||
285 | page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); | ||
286 | lock_page(page); | ||
287 | if(PageDirty(page)) { | ||
288 | err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", | ||
289 | to, start_len, len, end_len, pagenr); | ||
290 | BUG(); | ||
291 | } | ||
292 | memcpy(page_address(page)+offset, buf, start_len); | ||
293 | set_page_dirty(page); | ||
294 | SetPageUptodate(page); | ||
295 | buf += start_len; | ||
296 | thislen = start_len; | ||
297 | bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); | ||
298 | if(!bio) { | ||
299 | err = -ENOMEM; | ||
300 | err("bio_add_page failed\n"); | ||
301 | goto write_err; | ||
302 | } | ||
303 | pagecnt--; | ||
304 | pagenr++; | ||
305 | } | ||
306 | |||
307 | /* Now do the main loop to a page aligned, n page sized output */ | ||
308 | if(len) { | ||
309 | int pagesc = len >> PAGE_SHIFT; | ||
310 | DEBUG(3, "blkmtd: write: whole pages start = %d, count = %d\n", | ||
311 | pagenr, pagesc); | ||
312 | while(pagesc) { | ||
313 | struct page *page; | ||
314 | |||
315 | /* see if page is in the page cache */ | ||
316 | DEBUG(3, "blkmtd: write: grabbing page %d from page cache\n", pagenr); | ||
317 | page = grab_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr); | ||
318 | if(PageDirty(page)) { | ||
319 | BUG(); | ||
320 | } | ||
321 | if(!page) { | ||
322 | warn("write: cannot grab cache page %d", pagenr); | ||
323 | err = -ENOMEM; | ||
324 | goto write_err; | ||
325 | } | ||
326 | if(!buf) { | ||
327 | memset(page_address(page), 0xff, PAGE_SIZE); | ||
328 | } else { | ||
329 | memcpy(page_address(page), buf, PAGE_SIZE); | ||
330 | buf += PAGE_SIZE; | ||
331 | } | ||
332 | bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); | ||
333 | if(!bio) { | ||
334 | err = -ENOMEM; | ||
335 | err("bio_add_page failed\n"); | ||
336 | goto write_err; | ||
337 | } | ||
338 | pagenr++; | ||
339 | pagecnt--; | ||
340 | set_page_dirty(page); | ||
341 | SetPageUptodate(page); | ||
342 | pagesc--; | ||
343 | thislen += PAGE_SIZE; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | if(end_len) { | ||
348 | /* do the third region */ | ||
349 | struct page *page; | ||
350 | DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %zd\n", | ||
351 | pagenr, end_len); | ||
352 | BUG_ON(!buf); | ||
353 | page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); | ||
354 | lock_page(page); | ||
355 | if(PageDirty(page)) { | ||
356 | err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", | ||
357 | to, start_len, len, end_len, pagenr); | ||
358 | BUG(); | ||
359 | } | ||
360 | memcpy(page_address(page), buf, end_len); | ||
361 | set_page_dirty(page); | ||
362 | SetPageUptodate(page); | ||
363 | DEBUG(3, "blkmtd: write: writing out partial end\n"); | ||
364 | thislen += end_len; | ||
365 | bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); | ||
366 | if(!bio) { | ||
367 | err = -ENOMEM; | ||
368 | err("bio_add_page failed\n"); | ||
369 | goto write_err; | ||
370 | } | ||
371 | pagenr++; | ||
372 | } | ||
373 | |||
374 | DEBUG(3, "blkmtd: write: got %d vectors to write\n", bio->bi_vcnt); | ||
375 | write_err: | ||
376 | if(bio) | ||
377 | blkmtd_write_out(bio); | ||
378 | |||
379 | DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err); | ||
380 | mutex_unlock(&dev->wrbuf_mutex); | ||
381 | |||
382 | if(retlen) | ||
383 | *retlen = thislen; | ||
384 | return err; | ||
385 | } | ||
386 | |||
387 | |||
388 | /* erase a specified part of the device */ | ||
389 | static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr) | ||
390 | { | ||
391 | struct blkmtd_dev *dev = mtd->priv; | ||
392 | struct mtd_erase_region_info *einfo = mtd->eraseregions; | ||
393 | int numregions = mtd->numeraseregions; | ||
394 | size_t from; | ||
395 | u_long len; | ||
396 | int err = -EIO; | ||
397 | size_t retlen; | ||
398 | |||
399 | instr->state = MTD_ERASING; | ||
400 | from = instr->addr; | ||
401 | len = instr->len; | ||
402 | |||
403 | /* check erase region has valid start and length */ | ||
404 | DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%zx len = 0x%lx\n", | ||
405 | mtd->name+9, from, len); | ||
406 | while(numregions) { | ||
407 | DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%x\n", | ||
408 | einfo->offset, einfo->erasesize, einfo->numblocks); | ||
409 | if(from >= einfo->offset | ||
410 | && from < einfo->offset + (einfo->erasesize * einfo->numblocks)) { | ||
411 | if(len == einfo->erasesize | ||
412 | && ( (from - einfo->offset) % einfo->erasesize == 0)) | ||
413 | break; | ||
414 | } | ||
415 | numregions--; | ||
416 | einfo++; | ||
417 | } | ||
418 | |||
419 | if(!numregions) { | ||
420 | /* Not a valid erase block */ | ||
421 | err("erase: invalid erase request 0x%lX @ 0x%08zX", len, from); | ||
422 | instr->state = MTD_ERASE_FAILED; | ||
423 | err = -EIO; | ||
424 | } | ||
425 | |||
426 | if(instr->state != MTD_ERASE_FAILED) { | ||
427 | /* do the erase */ | ||
428 | DEBUG(3, "Doing erase from = %zd len = %ld\n", from, len); | ||
429 | err = write_pages(dev, NULL, from, len, &retlen); | ||
430 | if(err || retlen != len) { | ||
431 | err("erase failed err = %d", err); | ||
432 | instr->state = MTD_ERASE_FAILED; | ||
433 | } else { | ||
434 | instr->state = MTD_ERASE_DONE; | ||
435 | } | ||
436 | } | ||
437 | |||
438 | DEBUG(3, "blkmtd: erase: checking callback\n"); | ||
439 | mtd_erase_callback(instr); | ||
440 | DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err); | ||
441 | return err; | ||
442 | } | ||
443 | |||
444 | |||
445 | /* read a range of the data via the page cache */ | ||
446 | static int blkmtd_read(struct mtd_info *mtd, loff_t from, size_t len, | ||
447 | size_t *retlen, u_char *buf) | ||
448 | { | ||
449 | struct blkmtd_dev *dev = mtd->priv; | ||
450 | int err = 0; | ||
451 | int offset; | ||
452 | int pagenr, pages; | ||
453 | size_t thislen = 0; | ||
454 | |||
455 | DEBUG(2, "blkmtd: read: dev = `%s' from = %lld len = %zd buf = %p\n", | ||
456 | mtd->name+9, from, len, buf); | ||
457 | |||
458 | if(from > mtd->size) | ||
459 | return -EINVAL; | ||
460 | if(from + len > mtd->size) | ||
461 | len = mtd->size - from; | ||
462 | |||
463 | pagenr = from >> PAGE_SHIFT; | ||
464 | offset = from - (pagenr << PAGE_SHIFT); | ||
465 | |||
466 | pages = (offset+len+PAGE_SIZE-1) >> PAGE_SHIFT; | ||
467 | DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %d\n", | ||
468 | pagenr, offset, pages); | ||
469 | |||
470 | while(pages) { | ||
471 | struct page *page; | ||
472 | int cpylen; | ||
473 | |||
474 | DEBUG(3, "blkmtd: read: looking for page: %d\n", pagenr); | ||
475 | page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); | ||
476 | if(IS_ERR(page)) { | ||
477 | err = -EIO; | ||
478 | goto readerr; | ||
479 | } | ||
480 | |||
481 | cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE; | ||
482 | if(offset+cpylen > PAGE_SIZE) | ||
483 | cpylen = PAGE_SIZE-offset; | ||
484 | |||
485 | memcpy(buf + thislen, page_address(page) + offset, cpylen); | ||
486 | offset = 0; | ||
487 | len -= cpylen; | ||
488 | thislen += cpylen; | ||
489 | pagenr++; | ||
490 | pages--; | ||
491 | if(!PageDirty(page)) | ||
492 | page_cache_release(page); | ||
493 | } | ||
494 | |||
495 | readerr: | ||
496 | if(retlen) | ||
497 | *retlen = thislen; | ||
498 | DEBUG(2, "blkmtd: end read: retlen = %zd, err = %d\n", thislen, err); | ||
499 | return err; | ||
500 | } | ||
501 | |||
502 | |||
503 | /* write data to the underlying device */ | ||
504 | static int blkmtd_write(struct mtd_info *mtd, loff_t to, size_t len, | ||
505 | size_t *retlen, const u_char *buf) | ||
506 | { | ||
507 | struct blkmtd_dev *dev = mtd->priv; | ||
508 | int err; | ||
509 | |||
510 | if(!len) | ||
511 | return 0; | ||
512 | |||
513 | DEBUG(2, "blkmtd: write: dev = `%s' to = %lld len = %zd buf = %p\n", | ||
514 | mtd->name+9, to, len, buf); | ||
515 | |||
516 | if(to >= mtd->size) { | ||
517 | return -ENOSPC; | ||
518 | } | ||
519 | |||
520 | if(to + len > mtd->size) { | ||
521 | len = mtd->size - to; | ||
522 | } | ||
523 | |||
524 | err = write_pages(dev, buf, to, len, retlen); | ||
525 | if(err > 0) | ||
526 | err = 0; | ||
527 | DEBUG(2, "blkmtd: write: end, err = %d\n", err); | ||
528 | return err; | ||
529 | } | ||
530 | |||
531 | |||
532 | /* sync the device - wait until the write queue is empty */ | ||
533 | static void blkmtd_sync(struct mtd_info *mtd) | ||
534 | { | ||
535 | /* Currently all writes are synchronous */ | ||
536 | } | ||
537 | |||
538 | |||
539 | static void free_device(struct blkmtd_dev *dev) | ||
540 | { | ||
541 | DEBUG(2, "blkmtd: free_device() dev = %p\n", dev); | ||
542 | if(dev) { | ||
543 | kfree(dev->mtd_info.eraseregions); | ||
544 | kfree(dev->mtd_info.name); | ||
545 | if(dev->blkdev) { | ||
546 | invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping); | ||
547 | close_bdev_excl(dev->blkdev); | ||
548 | } | ||
549 | kfree(dev); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | |||
554 | /* For a given size and initial erase size, calculate the number | ||
555 | * and size of each erase region. Goes round the loop twice, | ||
556 | * once to find out how many regions, then allocates space, | ||
557 | * then round the loop again to fill it in. | ||
558 | */ | ||
559 | static struct mtd_erase_region_info *calc_erase_regions( | ||
560 | size_t erase_size, size_t total_size, int *regions) | ||
561 | { | ||
562 | struct mtd_erase_region_info *info = NULL; | ||
563 | |||
564 | DEBUG(2, "calc_erase_regions, es = %zd size = %zd regions = %d\n", | ||
565 | erase_size, total_size, *regions); | ||
566 | /* Make any user specified erasesize be a power of 2 | ||
567 | and at least PAGE_SIZE */ | ||
568 | if(erase_size) { | ||
569 | int es = erase_size; | ||
570 | erase_size = 1; | ||
571 | while(es != 1) { | ||
572 | es >>= 1; | ||
573 | erase_size <<= 1; | ||
574 | } | ||
575 | if(erase_size < PAGE_SIZE) | ||
576 | erase_size = PAGE_SIZE; | ||
577 | } else { | ||
578 | erase_size = CONFIG_MTD_BLKDEV_ERASESIZE; | ||
579 | } | ||
580 | |||
581 | *regions = 0; | ||
582 | |||
583 | do { | ||
584 | int tot_size = total_size; | ||
585 | int er_size = erase_size; | ||
586 | int count = 0, offset = 0, regcnt = 0; | ||
587 | |||
588 | while(tot_size) { | ||
589 | count = tot_size / er_size; | ||
590 | if(count) { | ||
591 | tot_size = tot_size % er_size; | ||
592 | if(info) { | ||
593 | DEBUG(2, "adding to erase info off=%d er=%d cnt=%d\n", | ||
594 | offset, er_size, count); | ||
595 | (info+regcnt)->offset = offset; | ||
596 | (info+regcnt)->erasesize = er_size; | ||
597 | (info+regcnt)->numblocks = count; | ||
598 | (*regions)++; | ||
599 | } | ||
600 | regcnt++; | ||
601 | offset += (count * er_size); | ||
602 | } | ||
603 | while(er_size > tot_size) | ||
604 | er_size >>= 1; | ||
605 | } | ||
606 | if(info == NULL) { | ||
607 | info = kmalloc(regcnt * sizeof(struct mtd_erase_region_info), GFP_KERNEL); | ||
608 | if(!info) | ||
609 | break; | ||
610 | } | ||
611 | } while(!(*regions)); | ||
612 | DEBUG(2, "calc_erase_regions done, es = %zd size = %zd regions = %d\n", | ||
613 | erase_size, total_size, *regions); | ||
614 | return info; | ||
615 | } | ||
616 | |||
617 | |||
618 | static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) | ||
619 | { | ||
620 | struct block_device *bdev; | ||
621 | int mode; | ||
622 | struct blkmtd_dev *dev; | ||
623 | |||
624 | if(!devname) | ||
625 | return NULL; | ||
626 | |||
627 | /* Get a handle on the device */ | ||
628 | |||
629 | |||
630 | #ifdef MODULE | ||
631 | mode = (readonly) ? O_RDONLY : O_RDWR; | ||
632 | bdev = open_bdev_excl(devname, mode, NULL); | ||
633 | #else | ||
634 | mode = (readonly) ? FMODE_READ : FMODE_WRITE; | ||
635 | bdev = open_by_devnum(name_to_dev_t(devname), mode); | ||
636 | #endif | ||
637 | if(IS_ERR(bdev)) { | ||
638 | err("error: cannot open device %s", devname); | ||
639 | DEBUG(2, "blkmtd: opening bdev returned %ld\n", PTR_ERR(bdev)); | ||
640 | return NULL; | ||
641 | } | ||
642 | |||
643 | DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n", | ||
644 | MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); | ||
645 | |||
646 | if(MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { | ||
647 | err("attempting to use an MTD device as a block device"); | ||
648 | blkdev_put(bdev); | ||
649 | return NULL; | ||
650 | } | ||
651 | |||
652 | dev = kmalloc(sizeof(struct blkmtd_dev), GFP_KERNEL); | ||
653 | if(dev == NULL) { | ||
654 | blkdev_put(bdev); | ||
655 | return NULL; | ||
656 | } | ||
657 | |||
658 | memset(dev, 0, sizeof(struct blkmtd_dev)); | ||
659 | dev->blkdev = bdev; | ||
660 | if(!readonly) { | ||
661 | mutex_init(&dev->wrbuf_mutex); | ||
662 | } | ||
663 | |||
664 | dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; | ||
665 | |||
666 | /* Setup the MTD structure */ | ||
667 | /* make the name contain the block device in */ | ||
668 | dev->mtd_info.name = kmalloc(sizeof("blkmtd: ") + strlen(devname), GFP_KERNEL); | ||
669 | if(dev->mtd_info.name == NULL) | ||
670 | goto devinit_err; | ||
671 | |||
672 | sprintf(dev->mtd_info.name, "blkmtd: %s", devname); | ||
673 | dev->mtd_info.eraseregions = calc_erase_regions(erase_size, dev->mtd_info.size, | ||
674 | &dev->mtd_info.numeraseregions); | ||
675 | if(dev->mtd_info.eraseregions == NULL) | ||
676 | goto devinit_err; | ||
677 | |||
678 | dev->mtd_info.erasesize = dev->mtd_info.eraseregions->erasesize; | ||
679 | DEBUG(1, "blkmtd: init: found %d erase regions\n", | ||
680 | dev->mtd_info.numeraseregions); | ||
681 | |||
682 | if(readonly) { | ||
683 | dev->mtd_info.type = MTD_ROM; | ||
684 | dev->mtd_info.flags = MTD_CAP_ROM; | ||
685 | } else { | ||
686 | dev->mtd_info.type = MTD_RAM; | ||
687 | dev->mtd_info.flags = MTD_CAP_RAM; | ||
688 | dev->mtd_info.erase = blkmtd_erase; | ||
689 | dev->mtd_info.write = blkmtd_write; | ||
690 | dev->mtd_info.writev = default_mtd_writev; | ||
691 | dev->mtd_info.sync = blkmtd_sync; | ||
692 | } | ||
693 | dev->mtd_info.read = blkmtd_read; | ||
694 | dev->mtd_info.readv = default_mtd_readv; | ||
695 | dev->mtd_info.priv = dev; | ||
696 | dev->mtd_info.owner = THIS_MODULE; | ||
697 | |||
698 | list_add(&dev->list, &blkmtd_device_list); | ||
699 | if (add_mtd_device(&dev->mtd_info)) { | ||
700 | /* Device didnt get added, so free the entry */ | ||
701 | list_del(&dev->list); | ||
702 | goto devinit_err; | ||
703 | } else { | ||
704 | info("mtd%d: [%s] erase_size = %dKiB %s", | ||
705 | dev->mtd_info.index, dev->mtd_info.name + strlen("blkmtd: "), | ||
706 | dev->mtd_info.erasesize >> 10, | ||
707 | readonly ? "(read-only)" : ""); | ||
708 | } | ||
709 | |||
710 | return dev; | ||
711 | |||
712 | devinit_err: | ||
713 | free_device(dev); | ||
714 | return NULL; | ||
715 | } | ||
716 | |||
717 | |||
718 | /* Cleanup and exit - sync the device and kill of the kernel thread */ | ||
719 | static void __devexit cleanup_blkmtd(void) | ||
720 | { | ||
721 | struct list_head *temp1, *temp2; | ||
722 | |||
723 | /* Remove the MTD devices */ | ||
724 | list_for_each_safe(temp1, temp2, &blkmtd_device_list) { | ||
725 | struct blkmtd_dev *dev = list_entry(temp1, struct blkmtd_dev, | ||
726 | list); | ||
727 | blkmtd_sync(&dev->mtd_info); | ||
728 | del_mtd_device(&dev->mtd_info); | ||
729 | info("mtd%d: [%s] removed", dev->mtd_info.index, | ||
730 | dev->mtd_info.name + strlen("blkmtd: ")); | ||
731 | list_del(&dev->list); | ||
732 | free_device(dev); | ||
733 | } | ||
734 | } | ||
735 | |||
736 | #ifndef MODULE | ||
737 | |||
738 | /* Handle kernel boot params */ | ||
739 | |||
740 | |||
741 | static int __init param_blkmtd_device(char *str) | ||
742 | { | ||
743 | int i; | ||
744 | |||
745 | for(i = 0; i < MAX_DEVICES; i++) { | ||
746 | device[i] = str; | ||
747 | DEBUG(2, "blkmtd: device setup: %d = %s\n", i, device[i]); | ||
748 | strsep(&str, ","); | ||
749 | } | ||
750 | return 1; | ||
751 | } | ||
752 | |||
753 | |||
754 | static int __init param_blkmtd_erasesz(char *str) | ||
755 | { | ||
756 | int i; | ||
757 | for(i = 0; i < MAX_DEVICES; i++) { | ||
758 | char *val = strsep(&str, ","); | ||
759 | if(val) | ||
760 | erasesz[i] = simple_strtoul(val, NULL, 0); | ||
761 | DEBUG(2, "blkmtd: erasesz setup: %d = %d\n", i, erasesz[i]); | ||
762 | } | ||
763 | |||
764 | return 1; | ||
765 | } | ||
766 | |||
767 | |||
768 | static int __init param_blkmtd_ro(char *str) | ||
769 | { | ||
770 | int i; | ||
771 | for(i = 0; i < MAX_DEVICES; i++) { | ||
772 | char *val = strsep(&str, ","); | ||
773 | if(val) | ||
774 | ro[i] = simple_strtoul(val, NULL, 0); | ||
775 | DEBUG(2, "blkmtd: ro setup: %d = %d\n", i, ro[i]); | ||
776 | } | ||
777 | |||
778 | return 1; | ||
779 | } | ||
780 | |||
781 | |||
782 | static int __init param_blkmtd_sync(char *str) | ||
783 | { | ||
784 | if(str[0] == '1') | ||
785 | sync = 1; | ||
786 | return 1; | ||
787 | } | ||
788 | |||
789 | __setup("blkmtd_device=", param_blkmtd_device); | ||
790 | __setup("blkmtd_erasesz=", param_blkmtd_erasesz); | ||
791 | __setup("blkmtd_ro=", param_blkmtd_ro); | ||
792 | __setup("blkmtd_sync=", param_blkmtd_sync); | ||
793 | |||
794 | #endif | ||
795 | |||
796 | |||
797 | /* Startup */ | ||
798 | static int __init init_blkmtd(void) | ||
799 | { | ||
800 | int i; | ||
801 | |||
802 | info("version " VERSION); | ||
803 | /* Check args - device[0] is the bare minimum*/ | ||
804 | if(!device[0]) { | ||
805 | err("error: missing `device' name\n"); | ||
806 | return -EINVAL; | ||
807 | } | ||
808 | |||
809 | for(i = 0; i < MAX_DEVICES; i++) | ||
810 | add_device(device[i], ro[i], erasesz[i] << 10); | ||
811 | |||
812 | if(list_empty(&blkmtd_device_list)) | ||
813 | return -EINVAL; | ||
814 | |||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | module_init(init_blkmtd); | ||
819 | module_exit(cleanup_blkmtd); | ||
diff --git a/drivers/net/chelsio/Makefile b/drivers/net/chelsio/Makefile index 91e927827c43..54c78d94f48b 100644 --- a/drivers/net/chelsio/Makefile +++ b/drivers/net/chelsio/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_CHELSIO_T1) += cxgb.o | 5 | obj-$(CONFIG_CHELSIO_T1) += cxgb.o |
6 | 6 | ||
7 | EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/chelsio $(DEBUG_FLAGS) | 7 | EXTRA_CFLAGS += -Idrivers/net/chelsio $(DEBUG_FLAGS) |
8 | 8 | ||
9 | 9 | ||
10 | cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o | 10 | cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o |
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 6e2ec56cde0b..606243d11793 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Filename: irda-usb.c | 3 | * Filename: irda-usb.c |
4 | * Version: 0.9b | 4 | * Version: 0.10 |
5 | * Description: IrDA-USB Driver | 5 | * Description: IrDA-USB Driver |
6 | * Status: Experimental | 6 | * Status: Experimental |
7 | * Author: Dag Brattli <dag@brattli.net> | 7 | * Author: Dag Brattli <dag@brattli.net> |
@@ -9,6 +9,9 @@ | |||
9 | * Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at> | 9 | * Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at> |
10 | * Copyright (C) 2001, Dag Brattli <dag@brattli.net> | 10 | * Copyright (C) 2001, Dag Brattli <dag@brattli.net> |
11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> | 11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> |
12 | * Copyright (C) 2004, SigmaTel, Inc. <irquality@sigmatel.com> | ||
13 | * Copyright (C) 2005, Milan Beno <beno@pobox.sk> | ||
14 | * Copyright (C) 2006, Nick Fedchik <nick@fedchik.org.ua> | ||
12 | * | 15 | * |
13 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
@@ -61,6 +64,7 @@ | |||
61 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
62 | #include <linux/rtnetlink.h> | 65 | #include <linux/rtnetlink.h> |
63 | #include <linux/usb.h> | 66 | #include <linux/usb.h> |
67 | #include <linux/firmware.h> | ||
64 | 68 | ||
65 | #include "irda-usb.h" | 69 | #include "irda-usb.h" |
66 | 70 | ||
@@ -78,8 +82,12 @@ static struct usb_device_id dongles[] = { | |||
78 | { USB_DEVICE(0x50f, 0x180), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, | 82 | { USB_DEVICE(0x50f, 0x180), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, |
79 | /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */ | 83 | /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */ |
80 | { USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, | 84 | { USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, |
85 | /* SigmaTel STIR4210/4220/4116 USB IrDA (VFIR) Bridge */ | ||
86 | { USB_DEVICE(0x66f, 0x4210), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, | ||
87 | { USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, | ||
88 | { USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, | ||
81 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | | 89 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | |
82 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | 90 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, |
83 | .bInterfaceClass = USB_CLASS_APP_SPEC, | 91 | .bInterfaceClass = USB_CLASS_APP_SPEC, |
84 | .bInterfaceSubClass = USB_CLASS_IRDA, | 92 | .bInterfaceSubClass = USB_CLASS_IRDA, |
85 | .driver_info = IUC_DEFAULT, }, | 93 | .driver_info = IUC_DEFAULT, }, |
@@ -99,6 +107,7 @@ MODULE_DEVICE_TABLE(usb, dongles); | |||
99 | 107 | ||
100 | /*------------------------------------------------------------------*/ | 108 | /*------------------------------------------------------------------*/ |
101 | 109 | ||
110 | static void irda_usb_init_qos(struct irda_usb_cb *self) ; | ||
102 | static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf); | 111 | static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf); |
103 | static void irda_usb_disconnect(struct usb_interface *intf); | 112 | static void irda_usb_disconnect(struct usb_interface *intf); |
104 | static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); | 113 | static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); |
@@ -141,7 +150,24 @@ static void irda_usb_build_header(struct irda_usb_cb *self, | |||
141 | __u8 *header, | 150 | __u8 *header, |
142 | int force) | 151 | int force) |
143 | { | 152 | { |
144 | /* Set the negotiated link speed */ | 153 | /* Here we check if we have an STIR421x chip, |
154 | * and if either speed or xbofs (or both) needs | ||
155 | * to be changed. | ||
156 | */ | ||
157 | if (self->capability & IUC_STIR_4210 && | ||
158 | ((self->new_speed != -1) || (self->new_xbofs != -1))) { | ||
159 | |||
160 | /* With STIR421x, speed and xBOFs must be set at the same | ||
161 | * time, even if only one of them changes. | ||
162 | */ | ||
163 | if (self->new_speed == -1) | ||
164 | self->new_speed = self->speed ; | ||
165 | |||
166 | if (self->new_xbofs == -1) | ||
167 | self->new_xbofs = self->xbofs ; | ||
168 | } | ||
169 | |||
170 | /* Set the link speed */ | ||
145 | if (self->new_speed != -1) { | 171 | if (self->new_speed != -1) { |
146 | /* Hum... Ugly hack :-( | 172 | /* Hum... Ugly hack :-( |
147 | * Some device are not compliant with the spec and change | 173 | * Some device are not compliant with the spec and change |
@@ -191,7 +217,11 @@ static void irda_usb_build_header(struct irda_usb_cb *self, | |||
191 | *header = SPEED_4000000; | 217 | *header = SPEED_4000000; |
192 | self->new_xbofs = 0; | 218 | self->new_xbofs = 0; |
193 | break; | 219 | break; |
194 | } | 220 | case 16000000: |
221 | *header = SPEED_16000000; | ||
222 | self->new_xbofs = 0; | ||
223 | break; | ||
224 | } | ||
195 | } else | 225 | } else |
196 | /* No change */ | 226 | /* No change */ |
197 | *header = 0; | 227 | *header = 0; |
@@ -235,6 +265,32 @@ static void irda_usb_build_header(struct irda_usb_cb *self, | |||
235 | } | 265 | } |
236 | } | 266 | } |
237 | 267 | ||
268 | /* | ||
269 | * calculate turnaround time for SigmaTel header | ||
270 | */ | ||
271 | static __u8 get_turnaround_time(struct sk_buff *skb) | ||
272 | { | ||
273 | int turnaround_time = irda_get_mtt(skb); | ||
274 | |||
275 | if ( turnaround_time == 0 ) | ||
276 | return 0; | ||
277 | else if ( turnaround_time <= 10 ) | ||
278 | return 1; | ||
279 | else if ( turnaround_time <= 50 ) | ||
280 | return 2; | ||
281 | else if ( turnaround_time <= 100 ) | ||
282 | return 3; | ||
283 | else if ( turnaround_time <= 500 ) | ||
284 | return 4; | ||
285 | else if ( turnaround_time <= 1000 ) | ||
286 | return 5; | ||
287 | else if ( turnaround_time <= 5000 ) | ||
288 | return 6; | ||
289 | else | ||
290 | return 7; | ||
291 | } | ||
292 | |||
293 | |||
238 | /*------------------------------------------------------------------*/ | 294 | /*------------------------------------------------------------------*/ |
239 | /* | 295 | /* |
240 | * Send a command to change the speed of the dongle | 296 | * Send a command to change the speed of the dongle |
@@ -262,12 +318,18 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) | |||
262 | /* Set the new speed and xbofs in this fake frame */ | 318 | /* Set the new speed and xbofs in this fake frame */ |
263 | irda_usb_build_header(self, frame, 1); | 319 | irda_usb_build_header(self, frame, 1); |
264 | 320 | ||
321 | if ( self->capability & IUC_STIR_4210 ) { | ||
322 | if (frame[0] == 0) return ; // do nothing if no change | ||
323 | frame[1] = 0; // other parameters don't change here | ||
324 | frame[2] = 0; | ||
325 | } | ||
326 | |||
265 | /* Submit the 0 length IrDA frame to trigger new speed settings */ | 327 | /* Submit the 0 length IrDA frame to trigger new speed settings */ |
266 | usb_fill_bulk_urb(urb, self->usbdev, | 328 | usb_fill_bulk_urb(urb, self->usbdev, |
267 | usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), | 329 | usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), |
268 | frame, IRDA_USB_SPEED_MTU, | 330 | frame, IRDA_USB_SPEED_MTU, |
269 | speed_bulk_callback, self); | 331 | speed_bulk_callback, self); |
270 | urb->transfer_buffer_length = USB_IRDA_HEADER; | 332 | urb->transfer_buffer_length = self->header_length; |
271 | urb->transfer_flags = 0; | 333 | urb->transfer_flags = 0; |
272 | 334 | ||
273 | /* Irq disabled -> GFP_ATOMIC */ | 335 | /* Irq disabled -> GFP_ATOMIC */ |
@@ -383,16 +445,35 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
383 | * allocation will be done lower in skb_push(). | 445 | * allocation will be done lower in skb_push(). |
384 | * Also, we don't use directly skb_cow(), because it require | 446 | * Also, we don't use directly skb_cow(), because it require |
385 | * headroom >= 16, which force unnecessary copies - Jean II */ | 447 | * headroom >= 16, which force unnecessary copies - Jean II */ |
386 | if (skb_headroom(skb) < USB_IRDA_HEADER) { | 448 | if (skb_headroom(skb) < self->header_length) { |
387 | IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); | 449 | IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); |
388 | if (skb_cow(skb, USB_IRDA_HEADER)) { | 450 | if (skb_cow(skb, self->header_length)) { |
389 | IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); | 451 | IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); |
390 | goto drop; | 452 | goto drop; |
391 | } | 453 | } |
392 | } | 454 | } |
393 | 455 | ||
394 | /* Change setting for next frame */ | 456 | /* Change setting for next frame */ |
395 | irda_usb_build_header(self, skb_push(skb, USB_IRDA_HEADER), 0); | 457 | |
458 | if ( self->capability & IUC_STIR_4210 ) { | ||
459 | __u8 turnaround_time; | ||
460 | __u8* frame; | ||
461 | turnaround_time = get_turnaround_time( skb ); | ||
462 | frame= skb_push(skb, self->header_length); | ||
463 | irda_usb_build_header(self, frame, 0); | ||
464 | frame[2] = turnaround_time; | ||
465 | if ((skb->len != 0) && | ||
466 | ((skb->len % 128) == 0) && | ||
467 | ((skb->len % 512) != 0)) { | ||
468 | /* add extra byte for special SigmaTel feature */ | ||
469 | frame[1] = 1; | ||
470 | skb_put(skb, 1); | ||
471 | } else { | ||
472 | frame[1] = 0; | ||
473 | } | ||
474 | } else { | ||
475 | irda_usb_build_header(self, skb_push(skb, self->header_length), 0); | ||
476 | } | ||
396 | 477 | ||
397 | /* FIXME: Make macro out of this one */ | 478 | /* FIXME: Make macro out of this one */ |
398 | ((struct irda_skb_cb *)skb->cb)->context = self; | 479 | ((struct irda_skb_cb *)skb->cb)->context = self; |
@@ -795,7 +876,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
795 | } | 876 | } |
796 | 877 | ||
797 | /* Check for empty frames */ | 878 | /* Check for empty frames */ |
798 | if (urb->actual_length <= USB_IRDA_HEADER) { | 879 | if (urb->actual_length <= self->header_length) { |
799 | IRDA_WARNING("%s(), empty frame!\n", __FUNCTION__); | 880 | IRDA_WARNING("%s(), empty frame!\n", __FUNCTION__); |
800 | goto done; | 881 | goto done; |
801 | } | 882 | } |
@@ -816,7 +897,11 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
816 | docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD); | 897 | docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD); |
817 | 898 | ||
818 | /* Allocate a new skb */ | 899 | /* Allocate a new skb */ |
819 | newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU); | 900 | if ( self->capability & IUC_STIR_4210 ) |
901 | newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU + USB_IRDA_SIGMATEL_HEADER); | ||
902 | else | ||
903 | newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU); | ||
904 | |||
820 | if (!newskb) { | 905 | if (!newskb) { |
821 | self->stats.rx_dropped++; | 906 | self->stats.rx_dropped++; |
822 | /* We could deliver the current skb, but this would stall | 907 | /* We could deliver the current skb, but this would stall |
@@ -845,7 +930,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
845 | 930 | ||
846 | /* Set proper length on skb & remove USB-IrDA header */ | 931 | /* Set proper length on skb & remove USB-IrDA header */ |
847 | skb_put(dataskb, urb->actual_length); | 932 | skb_put(dataskb, urb->actual_length); |
848 | skb_pull(dataskb, USB_IRDA_HEADER); | 933 | skb_pull(dataskb, self->header_length); |
849 | 934 | ||
850 | /* Ask the networking layer to queue the packet for the IrDA stack */ | 935 | /* Ask the networking layer to queue the packet for the IrDA stack */ |
851 | dataskb->dev = self->netdev; | 936 | dataskb->dev = self->netdev; |
@@ -937,6 +1022,191 @@ static int irda_usb_is_receiving(struct irda_usb_cb *self) | |||
937 | return 0; /* For now */ | 1022 | return 0; /* For now */ |
938 | } | 1023 | } |
939 | 1024 | ||
1025 | |||
1026 | #define STIR421X_PATCH_PRODUCT_VERSION_STR "Product Version: " | ||
1027 | #define STIR421X_PATCH_COMPONENT_VERSION_STR "Component Version: " | ||
1028 | #define STIR421X_PATCH_DATA_TAG_STR "STMP" | ||
1029 | #define STIR421X_PATCH_FILE_VERSION_MAX_OFFSET 512 /* version info is before here */ | ||
1030 | #define STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET 512 /* patch image starts before here */ | ||
1031 | #define STIR421X_PATCH_FILE_END_OF_HEADER_TAG 0x1A /* marks end of patch file header (PC DOS text file EOF character) */ | ||
1032 | |||
1033 | /* | ||
1034 | * Known firmware patches for STIR421x dongles | ||
1035 | */ | ||
1036 | static char * stir421x_patches[] = { | ||
1037 | "42101001.sb", | ||
1038 | "42101002.sb", | ||
1039 | }; | ||
1040 | |||
1041 | static int stir421x_get_patch_version(unsigned char * patch, const unsigned long patch_len) | ||
1042 | { | ||
1043 | unsigned int version_offset; | ||
1044 | unsigned long version_major, version_minor, version_build; | ||
1045 | unsigned char * version_start; | ||
1046 | int version_found = 0; | ||
1047 | |||
1048 | for (version_offset = 0; | ||
1049 | version_offset < STIR421X_PATCH_FILE_END_OF_HEADER_TAG; | ||
1050 | version_offset++) { | ||
1051 | if (!memcmp(patch + version_offset, | ||
1052 | STIR421X_PATCH_PRODUCT_VERSION_STR, | ||
1053 | sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1)) { | ||
1054 | version_found = 1; | ||
1055 | version_start = patch + | ||
1056 | version_offset + | ||
1057 | sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1; | ||
1058 | break; | ||
1059 | } | ||
1060 | } | ||
1061 | |||
1062 | /* We couldn't find a product version on this patch */ | ||
1063 | if (!version_found) | ||
1064 | return -EINVAL; | ||
1065 | |||
1066 | /* Let's check if the product version is dotted */ | ||
1067 | if (version_start[3] != '.' || | ||
1068 | version_start[7] != '.') | ||
1069 | return -EINVAL; | ||
1070 | |||
1071 | version_major = simple_strtoul(version_start, NULL, 10); | ||
1072 | version_minor = simple_strtoul(version_start + 4, NULL, 10); | ||
1073 | version_build = simple_strtoul(version_start + 8, NULL, 10); | ||
1074 | |||
1075 | IRDA_DEBUG(2, "%s(), Major: %ld Minor: %ld Build: %ld\n", | ||
1076 | __FUNCTION__, | ||
1077 | version_major, version_minor, version_build); | ||
1078 | |||
1079 | return (((version_major) << 12) + | ||
1080 | ((version_minor) << 8) + | ||
1081 | ((version_build / 10) << 4) + | ||
1082 | (version_build % 10)); | ||
1083 | |||
1084 | } | ||
1085 | |||
1086 | |||
1087 | static int stir421x_upload_patch (struct irda_usb_cb *self, | ||
1088 | unsigned char * patch, | ||
1089 | const unsigned int patch_len) | ||
1090 | { | ||
1091 | int retval = 0; | ||
1092 | int actual_len; | ||
1093 | unsigned int i = 0, download_amount = 0; | ||
1094 | unsigned char * patch_chunk; | ||
1095 | |||
1096 | IRDA_DEBUG (2, "%s(), Uploading STIR421x Patch\n", __FUNCTION__); | ||
1097 | |||
1098 | patch_chunk = kzalloc(STIR421X_MAX_PATCH_DOWNLOAD_SIZE, GFP_KERNEL); | ||
1099 | if (patch_chunk == NULL) | ||
1100 | return -ENOMEM; | ||
1101 | |||
1102 | /* break up patch into 1023-byte sections */ | ||
1103 | for (i = 0; retval >= 0 && i < patch_len; i += download_amount) { | ||
1104 | download_amount = patch_len - i; | ||
1105 | if (download_amount > STIR421X_MAX_PATCH_DOWNLOAD_SIZE) | ||
1106 | download_amount = STIR421X_MAX_PATCH_DOWNLOAD_SIZE; | ||
1107 | |||
1108 | /* download the patch section */ | ||
1109 | memcpy(patch_chunk, patch + i, download_amount); | ||
1110 | |||
1111 | retval = usb_bulk_msg (self->usbdev, | ||
1112 | usb_sndbulkpipe (self->usbdev, | ||
1113 | self->bulk_out_ep), | ||
1114 | patch_chunk, download_amount, | ||
1115 | &actual_len, msecs_to_jiffies (500)); | ||
1116 | IRDA_DEBUG (2, "%s(), Sent %u bytes\n", __FUNCTION__, | ||
1117 | actual_len); | ||
1118 | if (retval == 0) | ||
1119 | mdelay(10); | ||
1120 | } | ||
1121 | |||
1122 | kfree(patch_chunk); | ||
1123 | |||
1124 | if (i != patch_len) { | ||
1125 | IRDA_ERROR ("%s(), Pushed %d bytes (!= patch_len (%d))\n", | ||
1126 | __FUNCTION__, i, patch_len); | ||
1127 | retval = -EIO; | ||
1128 | } | ||
1129 | |||
1130 | if (retval < 0) | ||
1131 | /* todo - mark device as not ready */ | ||
1132 | IRDA_ERROR ("%s(), STIR421x patch upload failed (%d)\n", | ||
1133 | __FUNCTION__, retval); | ||
1134 | |||
1135 | return retval; | ||
1136 | } | ||
1137 | |||
1138 | |||
1139 | static int stir421x_patch_device(struct irda_usb_cb *self) | ||
1140 | { | ||
1141 | unsigned int i, patch_found = 0, data_found = 0, data_offset; | ||
1142 | int patch_version, ret = 0; | ||
1143 | const struct firmware *fw_entry; | ||
1144 | |||
1145 | for (i = 0; i < ARRAY_SIZE(stir421x_patches); i++) { | ||
1146 | if(request_firmware(&fw_entry, stir421x_patches[i], &self->usbdev->dev) != 0) { | ||
1147 | IRDA_ERROR( "%s(), Patch %s is not available\n", __FUNCTION__, stir421x_patches[i]); | ||
1148 | continue; | ||
1149 | } | ||
1150 | |||
1151 | /* We found a patch from userspace */ | ||
1152 | patch_version = stir421x_get_patch_version (fw_entry->data, fw_entry->size); | ||
1153 | |||
1154 | if (patch_version < 0) { | ||
1155 | /* Couldn't fetch a version, let's move on to the next file */ | ||
1156 | IRDA_ERROR("%s(), version parsing failed\n", __FUNCTION__); | ||
1157 | ret = patch_version; | ||
1158 | release_firmware(fw_entry); | ||
1159 | continue; | ||
1160 | } | ||
1161 | |||
1162 | if (patch_version != self->usbdev->descriptor.bcdDevice) { | ||
1163 | /* Patch version and device don't match */ | ||
1164 | IRDA_ERROR ("%s(), wrong patch version (%d <-> %d)\n", | ||
1165 | __FUNCTION__, | ||
1166 | patch_version, self->usbdev->descriptor.bcdDevice); | ||
1167 | ret = -EINVAL; | ||
1168 | release_firmware(fw_entry); | ||
1169 | continue; | ||
1170 | } | ||
1171 | |||
1172 | /* If we're here, we've found a correct patch */ | ||
1173 | patch_found = 1; | ||
1174 | break; | ||
1175 | |||
1176 | } | ||
1177 | |||
1178 | /* We couldn't find a valid firmware, let's leave */ | ||
1179 | if (!patch_found) | ||
1180 | return ret; | ||
1181 | |||
1182 | /* The actual image starts after the "STMP" keyword */ | ||
1183 | for (data_offset = 0; data_offset < STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET; data_offset++) { | ||
1184 | if (!memcmp(fw_entry->data + data_offset, | ||
1185 | STIR421X_PATCH_DATA_TAG_STR, | ||
1186 | sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))) { | ||
1187 | IRDA_DEBUG(2, "%s(), found patch data for STIR421x at offset %d\n", | ||
1188 | __FUNCTION__, data_offset); | ||
1189 | data_found = 1; | ||
1190 | break; | ||
1191 | } | ||
1192 | } | ||
1193 | |||
1194 | /* We couldn't find "STMP" from the header */ | ||
1195 | if (!data_found) | ||
1196 | return -EINVAL; | ||
1197 | |||
1198 | /* Let's upload the patch to the target */ | ||
1199 | ret = stir421x_upload_patch(self, | ||
1200 | &fw_entry->data[data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET)], | ||
1201 | fw_entry->size - (data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))); | ||
1202 | |||
1203 | release_firmware(fw_entry); | ||
1204 | |||
1205 | return ret; | ||
1206 | |||
1207 | } | ||
1208 | |||
1209 | |||
940 | /********************** IRDA DEVICE CALLBACKS **********************/ | 1210 | /********************** IRDA DEVICE CALLBACKS **********************/ |
941 | /* | 1211 | /* |
942 | * Main calls from the IrDA/Network subsystem. | 1212 | * Main calls from the IrDA/Network subsystem. |
@@ -972,6 +1242,11 @@ static int irda_usb_net_open(struct net_device *netdev) | |||
972 | return -1; | 1242 | return -1; |
973 | } | 1243 | } |
974 | 1244 | ||
1245 | if(self->needspatch) { | ||
1246 | IRDA_WARNING("%s(), device needs patch\n", __FUNCTION__) ; | ||
1247 | return -EIO ; | ||
1248 | } | ||
1249 | |||
975 | /* Initialise default speed and xbofs value | 1250 | /* Initialise default speed and xbofs value |
976 | * (IrLAP will change that soon) */ | 1251 | * (IrLAP will change that soon) */ |
977 | self->speed = -1; | 1252 | self->speed = -1; |
@@ -1050,7 +1325,7 @@ static int irda_usb_net_close(struct net_device *netdev) | |||
1050 | del_timer(&self->rx_defer_timer); | 1325 | del_timer(&self->rx_defer_timer); |
1051 | 1326 | ||
1052 | /* Deallocate all the Rx path buffers (URBs and skb) */ | 1327 | /* Deallocate all the Rx path buffers (URBs and skb) */ |
1053 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1328 | for (i = 0; i < self->max_rx_urb; i++) { |
1054 | struct urb *urb = self->rx_urb[i]; | 1329 | struct urb *urb = self->rx_urb[i]; |
1055 | struct sk_buff *skb = (struct sk_buff *) urb->context; | 1330 | struct sk_buff *skb = (struct sk_buff *) urb->context; |
1056 | /* Cancel the receive command */ | 1331 | /* Cancel the receive command */ |
@@ -1426,8 +1701,22 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
1426 | spin_lock_init(&self->lock); | 1701 | spin_lock_init(&self->lock); |
1427 | init_timer(&self->rx_defer_timer); | 1702 | init_timer(&self->rx_defer_timer); |
1428 | 1703 | ||
1704 | self->capability = id->driver_info; | ||
1705 | self->needspatch = ((self->capability & IUC_STIR_4210) != 0) ; | ||
1706 | |||
1429 | /* Create all of the needed urbs */ | 1707 | /* Create all of the needed urbs */ |
1430 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1708 | if (self->capability & IUC_STIR_4210) { |
1709 | self->max_rx_urb = IU_SIGMATEL_MAX_RX_URBS; | ||
1710 | self->header_length = USB_IRDA_SIGMATEL_HEADER; | ||
1711 | } else { | ||
1712 | self->max_rx_urb = IU_MAX_RX_URBS; | ||
1713 | self->header_length = USB_IRDA_HEADER; | ||
1714 | } | ||
1715 | |||
1716 | self->rx_urb = kzalloc(self->max_rx_urb * sizeof(struct urb *), | ||
1717 | GFP_KERNEL); | ||
1718 | |||
1719 | for (i = 0; i < self->max_rx_urb; i++) { | ||
1431 | self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); | 1720 | self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); |
1432 | if (!self->rx_urb[i]) { | 1721 | if (!self->rx_urb[i]) { |
1433 | goto err_out_1; | 1722 | goto err_out_1; |
@@ -1479,17 +1768,28 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
1479 | goto err_out_3; | 1768 | goto err_out_3; |
1480 | } | 1769 | } |
1481 | 1770 | ||
1771 | self->usbdev = dev; | ||
1772 | |||
1482 | /* Find IrDA class descriptor */ | 1773 | /* Find IrDA class descriptor */ |
1483 | irda_desc = irda_usb_find_class_desc(intf); | 1774 | irda_desc = irda_usb_find_class_desc(intf); |
1484 | ret = -ENODEV; | 1775 | ret = -ENODEV; |
1485 | if (irda_desc == NULL) | 1776 | if (irda_desc == NULL) |
1486 | goto err_out_3; | 1777 | goto err_out_3; |
1487 | 1778 | ||
1779 | if (self->needspatch) { | ||
1780 | ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0), | ||
1781 | 0x02, 0x40, 0, 0, 0, 0, msecs_to_jiffies(500)); | ||
1782 | if (ret < 0) { | ||
1783 | IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret); | ||
1784 | goto err_out_3; | ||
1785 | } else { | ||
1786 | mdelay(10); | ||
1787 | } | ||
1788 | } | ||
1789 | |||
1488 | self->irda_desc = irda_desc; | 1790 | self->irda_desc = irda_desc; |
1489 | self->present = 1; | 1791 | self->present = 1; |
1490 | self->netopen = 0; | 1792 | self->netopen = 0; |
1491 | self->capability = id->driver_info; | ||
1492 | self->usbdev = dev; | ||
1493 | self->usbintf = intf; | 1793 | self->usbintf = intf; |
1494 | 1794 | ||
1495 | /* Allocate the buffer for speed changes */ | 1795 | /* Allocate the buffer for speed changes */ |
@@ -1508,6 +1808,28 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
1508 | 1808 | ||
1509 | IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); | 1809 | IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); |
1510 | usb_set_intfdata(intf, self); | 1810 | usb_set_intfdata(intf, self); |
1811 | |||
1812 | if (self->needspatch) { | ||
1813 | /* Now we fetch and upload the firmware patch */ | ||
1814 | ret = stir421x_patch_device(self); | ||
1815 | self->needspatch = (ret < 0); | ||
1816 | if (ret < 0) { | ||
1817 | printk("patch_device failed\n"); | ||
1818 | goto err_out_4; | ||
1819 | } | ||
1820 | |||
1821 | /* replace IrDA class descriptor with what patched device is now reporting */ | ||
1822 | irda_desc = irda_usb_find_class_desc (self->usbintf); | ||
1823 | if (irda_desc == NULL) { | ||
1824 | ret = -ENODEV; | ||
1825 | goto err_out_4; | ||
1826 | } | ||
1827 | if (self->irda_desc) | ||
1828 | kfree (self->irda_desc); | ||
1829 | self->irda_desc = irda_desc; | ||
1830 | irda_usb_init_qos(self); | ||
1831 | } | ||
1832 | |||
1511 | return 0; | 1833 | return 0; |
1512 | 1834 | ||
1513 | err_out_4: | 1835 | err_out_4: |
@@ -1518,7 +1840,7 @@ err_out_3: | |||
1518 | err_out_2: | 1840 | err_out_2: |
1519 | usb_free_urb(self->tx_urb); | 1841 | usb_free_urb(self->tx_urb); |
1520 | err_out_1: | 1842 | err_out_1: |
1521 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1843 | for (i = 0; i < self->max_rx_urb; i++) { |
1522 | if (self->rx_urb[i]) | 1844 | if (self->rx_urb[i]) |
1523 | usb_free_urb(self->rx_urb[i]); | 1845 | usb_free_urb(self->rx_urb[i]); |
1524 | } | 1846 | } |
@@ -1571,7 +1893,7 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
1571 | /*netif_device_detach(self->netdev);*/ | 1893 | /*netif_device_detach(self->netdev);*/ |
1572 | netif_stop_queue(self->netdev); | 1894 | netif_stop_queue(self->netdev); |
1573 | /* Stop all the receive URBs. Must be synchronous. */ | 1895 | /* Stop all the receive URBs. Must be synchronous. */ |
1574 | for (i = 0; i < IU_MAX_RX_URBS; i++) | 1896 | for (i = 0; i < self->max_rx_urb; i++) |
1575 | usb_kill_urb(self->rx_urb[i]); | 1897 | usb_kill_urb(self->rx_urb[i]); |
1576 | /* Cancel Tx and speed URB. | 1898 | /* Cancel Tx and speed URB. |
1577 | * Make sure it's synchronous to avoid races. */ | 1899 | * Make sure it's synchronous to avoid races. */ |
@@ -1586,8 +1908,9 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
1586 | self->usbintf = NULL; | 1908 | self->usbintf = NULL; |
1587 | 1909 | ||
1588 | /* Clean up our urbs */ | 1910 | /* Clean up our urbs */ |
1589 | for (i = 0; i < IU_MAX_RX_URBS; i++) | 1911 | for (i = 0; i < self->max_rx_urb; i++) |
1590 | usb_free_urb(self->rx_urb[i]); | 1912 | usb_free_urb(self->rx_urb[i]); |
1913 | kfree(self->rx_urb); | ||
1591 | /* Clean up Tx and speed URB */ | 1914 | /* Clean up Tx and speed URB */ |
1592 | usb_free_urb(self->tx_urb); | 1915 | usb_free_urb(self->tx_urb); |
1593 | usb_free_urb(self->speed_urb); | 1916 | usb_free_urb(self->speed_urb); |
@@ -1648,6 +1971,6 @@ module_exit(usb_irda_cleanup); | |||
1648 | */ | 1971 | */ |
1649 | module_param(qos_mtt_bits, int, 0); | 1972 | module_param(qos_mtt_bits, int, 0); |
1650 | MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); | 1973 | MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); |
1651 | MODULE_AUTHOR("Roman Weissgaerber <weissg@vienna.at>, Dag Brattli <dag@brattli.net> and Jean Tourrilhes <jt@hpl.hp.com>"); | 1974 | MODULE_AUTHOR("Roman Weissgaerber <weissg@vienna.at>, Dag Brattli <dag@brattli.net>, Jean Tourrilhes <jt@hpl.hp.com> and Nick Fedchik <nick@fedchik.org.ua>"); |
1652 | MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); | 1975 | MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); |
1653 | MODULE_LICENSE("GPL"); | 1976 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index 4026af42dd47..d833db52cebf 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Filename: irda-usb.h | 3 | * Filename: irda-usb.h |
4 | * Version: 0.9b | 4 | * Version: 0.10 |
5 | * Description: IrDA-USB Driver | 5 | * Description: IrDA-USB Driver |
6 | * Status: Experimental | 6 | * Status: Experimental |
7 | * Author: Dag Brattli <dag@brattli.net> | 7 | * Author: Dag Brattli <dag@brattli.net> |
@@ -9,6 +9,9 @@ | |||
9 | * Copyright (C) 2001, Roman Weissgaerber <weissg@vienna.at> | 9 | * Copyright (C) 2001, Roman Weissgaerber <weissg@vienna.at> |
10 | * Copyright (C) 2000, Dag Brattli <dag@brattli.net> | 10 | * Copyright (C) 2000, Dag Brattli <dag@brattli.net> |
11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> | 11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> |
12 | * Copyright (C) 2004, SigmaTel, Inc. <irquality@sigmatel.com> | ||
13 | * Copyright (C) 2005, Milan Beno <beno@pobox.sk> | ||
14 | * Copyright (C) 2006, Nick FEdchik <nick@fedchik.org.ua> | ||
12 | * | 15 | * |
13 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
@@ -31,6 +34,9 @@ | |||
31 | #include <net/irda/irda.h> | 34 | #include <net/irda/irda.h> |
32 | #include <net/irda/irda_device.h> /* struct irlap_cb */ | 35 | #include <net/irda/irda_device.h> /* struct irlap_cb */ |
33 | 36 | ||
37 | #define PATCH_FILE_SIZE_MAX 65536 | ||
38 | #define PATCH_FILE_SIZE_MIN 80 | ||
39 | |||
34 | #define RX_COPY_THRESHOLD 200 | 40 | #define RX_COPY_THRESHOLD 200 |
35 | #define IRDA_USB_MAX_MTU 2051 | 41 | #define IRDA_USB_MAX_MTU 2051 |
36 | #define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ | 42 | #define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ |
@@ -79,15 +85,16 @@ | |||
79 | /* Inbound header */ | 85 | /* Inbound header */ |
80 | #define MEDIA_BUSY 0x80 | 86 | #define MEDIA_BUSY 0x80 |
81 | 87 | ||
82 | #define SPEED_2400 0x01 | 88 | #define SPEED_2400 0x01 |
83 | #define SPEED_9600 0x02 | 89 | #define SPEED_9600 0x02 |
84 | #define SPEED_19200 0x03 | 90 | #define SPEED_19200 0x03 |
85 | #define SPEED_38400 0x04 | 91 | #define SPEED_38400 0x04 |
86 | #define SPEED_57600 0x05 | 92 | #define SPEED_57600 0x05 |
87 | #define SPEED_115200 0x06 | 93 | #define SPEED_115200 0x06 |
88 | #define SPEED_576000 0x07 | 94 | #define SPEED_576000 0x07 |
89 | #define SPEED_1152000 0x08 | 95 | #define SPEED_1152000 0x08 |
90 | #define SPEED_4000000 0x09 | 96 | #define SPEED_4000000 0x09 |
97 | #define SPEED_16000000 0x0a | ||
91 | 98 | ||
92 | /* Basic capabilities */ | 99 | /* Basic capabilities */ |
93 | #define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ | 100 | #define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ |
@@ -100,11 +107,14 @@ | |||
100 | #define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ | 107 | #define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ |
101 | #define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ | 108 | #define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ |
102 | #define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ | 109 | #define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ |
110 | #define IUC_STIR_4210 0x80 /* SigmaTel 4210/4220/4116 VFIR */ | ||
103 | 111 | ||
104 | /* USB class definitions */ | 112 | /* USB class definitions */ |
105 | #define USB_IRDA_HEADER 0x01 | 113 | #define USB_IRDA_HEADER 0x01 |
106 | #define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ | 114 | #define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ |
107 | #define USB_DT_IRDA 0x21 | 115 | #define USB_DT_IRDA 0x21 |
116 | #define USB_IRDA_SIGMATEL_HEADER 0x03 | ||
117 | #define IU_SIGMATEL_MAX_RX_URBS (IU_MAX_ACTIVE_RX_URBS + USB_IRDA_SIGMATEL_HEADER) | ||
108 | 118 | ||
109 | struct irda_class_desc { | 119 | struct irda_class_desc { |
110 | __u8 bLength; | 120 | __u8 bLength; |
@@ -123,6 +133,7 @@ struct irda_class_desc { | |||
123 | * (6.2.5, USB-IrDA class spec 1.0) */ | 133 | * (6.2.5, USB-IrDA class spec 1.0) */ |
124 | 134 | ||
125 | #define IU_REQ_GET_CLASS_DESC 0x06 | 135 | #define IU_REQ_GET_CLASS_DESC 0x06 |
136 | #define STIR421X_MAX_PATCH_DOWNLOAD_SIZE 1023 | ||
126 | 137 | ||
127 | struct irda_usb_cb { | 138 | struct irda_usb_cb { |
128 | struct irda_class_desc *irda_desc; | 139 | struct irda_class_desc *irda_desc; |
@@ -136,7 +147,8 @@ struct irda_usb_cb { | |||
136 | __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ | 147 | __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ |
137 | __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ | 148 | __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ |
138 | 149 | ||
139 | struct urb *rx_urb[IU_MAX_RX_URBS]; /* URBs used to receive data frames */ | 150 | __u8 max_rx_urb; |
151 | struct urb **rx_urb; /* URBs used to receive data frames */ | ||
140 | struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ | 152 | struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ |
141 | struct urb *tx_urb; /* URB used to send data frames */ | 153 | struct urb *tx_urb; /* URB used to send data frames */ |
142 | struct urb *speed_urb; /* URB used to send speed commands */ | 154 | struct urb *speed_urb; /* URB used to send speed commands */ |
@@ -157,6 +169,9 @@ struct irda_usb_cb { | |||
157 | __u32 speed; /* Current speed */ | 169 | __u32 speed; /* Current speed */ |
158 | __s32 new_speed; /* speed we need to set */ | 170 | __s32 new_speed; /* speed we need to set */ |
159 | 171 | ||
172 | __u8 header_length; /* USB-IrDA frame header size */ | ||
173 | int needspatch; /* device needs firmware patch */ | ||
174 | |||
160 | struct timer_list rx_defer_timer; /* Wait for Rx error to clear */ | 175 | struct timer_list rx_defer_timer; /* Wait for Rx error to clear */ |
161 | }; | 176 | }; |
162 | 177 | ||
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index ec94ecdb103d..bbcfc8ec35a1 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * Copyright (c) 2002 Daniele Peri | 11 | * Copyright (c) 2002 Daniele Peri |
12 | * All Rights Reserved. | 12 | * All Rights Reserved. |
13 | * Copyright (c) 2002 Jean Tourrilhes | 13 | * Copyright (c) 2002 Jean Tourrilhes |
14 | * Copyright (c) 2006 Linus Walleij | ||
14 | * | 15 | * |
15 | * | 16 | * |
16 | * Based on smc-ircc.c: | 17 | * Based on smc-ircc.c: |
@@ -61,6 +62,9 @@ | |||
61 | 62 | ||
62 | #include <linux/spinlock.h> | 63 | #include <linux/spinlock.h> |
63 | #include <linux/pm.h> | 64 | #include <linux/pm.h> |
65 | #ifdef CONFIG_PCI | ||
66 | #include <linux/pci.h> | ||
67 | #endif | ||
64 | 68 | ||
65 | #include <net/irda/wrapper.h> | 69 | #include <net/irda/wrapper.h> |
66 | #include <net/irda/irda.h> | 70 | #include <net/irda/irda.h> |
@@ -100,6 +104,22 @@ MODULE_PARM_DESC(ircc_transceiver, "Transceiver type"); | |||
100 | 104 | ||
101 | /* Types */ | 105 | /* Types */ |
102 | 106 | ||
107 | #ifdef CONFIG_PCI | ||
108 | struct smsc_ircc_subsystem_configuration { | ||
109 | unsigned short vendor; /* PCI vendor ID */ | ||
110 | unsigned short device; /* PCI vendor ID */ | ||
111 | unsigned short subvendor; /* PCI subsystem vendor ID */ | ||
112 | unsigned short subdevice; /* PCI sybsystem device ID */ | ||
113 | unsigned short sir_io; /* I/O port for SIR */ | ||
114 | unsigned short fir_io; /* I/O port for FIR */ | ||
115 | unsigned char fir_irq; /* FIR IRQ */ | ||
116 | unsigned char fir_dma; /* FIR DMA */ | ||
117 | unsigned short cfg_base; /* I/O port for chip configuration */ | ||
118 | int (*preconfigure)(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); /* Preconfig function */ | ||
119 | const char *name; /* name shown as info */ | ||
120 | }; | ||
121 | #endif | ||
122 | |||
103 | struct smsc_transceiver { | 123 | struct smsc_transceiver { |
104 | char *name; | 124 | char *name; |
105 | void (*set_for_speed)(int fir_base, u32 speed); | 125 | void (*set_for_speed)(int fir_base, u32 speed); |
@@ -202,6 +222,16 @@ static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned shor | |||
202 | static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); | 222 | static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); |
203 | static int __init smsc_superio_fdc(unsigned short cfg_base); | 223 | static int __init smsc_superio_fdc(unsigned short cfg_base); |
204 | static int __init smsc_superio_lpc(unsigned short cfg_base); | 224 | static int __init smsc_superio_lpc(unsigned short cfg_base); |
225 | #ifdef CONFIG_PCI | ||
226 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); | ||
227 | static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | ||
228 | static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | ||
229 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | ||
230 | unsigned short ircc_fir, | ||
231 | unsigned short ircc_sir, | ||
232 | unsigned char ircc_dma, | ||
233 | unsigned char ircc_irq); | ||
234 | #endif | ||
205 | 235 | ||
206 | /* Transceivers specific functions */ | 236 | /* Transceivers specific functions */ |
207 | 237 | ||
@@ -353,6 +383,13 @@ static int __init smsc_ircc_init(void) | |||
353 | return ret; | 383 | return ret; |
354 | } | 384 | } |
355 | 385 | ||
386 | #ifdef CONFIG_PCI | ||
387 | if (smsc_ircc_preconfigure_subsystems(ircc_cfg, ircc_fir, ircc_sir, ircc_dma, ircc_irq) < 0) { | ||
388 | /* Ignore errors from preconfiguration */ | ||
389 | IRDA_ERROR("%s, Preconfiguration failed !\n", driver_name); | ||
390 | } | ||
391 | #endif | ||
392 | |||
356 | dev_count = 0; | 393 | dev_count = 0; |
357 | 394 | ||
358 | if (ircc_fir > 0 && ircc_sir > 0) { | 395 | if (ircc_fir > 0 && ircc_sir > 0) { |
@@ -2285,6 +2322,280 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) | |||
2285 | return ret; | 2322 | return ret; |
2286 | } | 2323 | } |
2287 | 2324 | ||
2325 | /* | ||
2326 | * Look for some specific subsystem setups that need | ||
2327 | * pre-configuration not properly done by the BIOS (especially laptops) | ||
2328 | * This code is based in part on smcinit.c, tosh1800-smcinit.c | ||
2329 | * and tosh2450-smcinit.c. The table lists the device entries | ||
2330 | * for ISA bridges with an LPC (Local Peripheral Configurator) | ||
2331 | * that are in turn used to configure the SMSC device with default | ||
2332 | * SIR and FIR I/O ports, DMA and IRQ. | ||
2333 | */ | ||
2334 | #ifdef CONFIG_PCI | ||
2335 | #define PCIID_VENDOR_INTEL 0x8086 | ||
2336 | #define PCIID_VENDOR_ALI 0x10b9 | ||
2337 | static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __devinitdata = { | ||
2338 | { | ||
2339 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ | ||
2340 | .device = 0x24cc, | ||
2341 | .subvendor = 0x103c, | ||
2342 | .subdevice = 0x088c, | ||
2343 | .sir_io = 0x02f8, /* Quite certain these are the same for nc8000 as for nc6000 */ | ||
2344 | .fir_io = 0x0130, | ||
2345 | .fir_irq = 0x09, | ||
2346 | .fir_dma = 0x03, | ||
2347 | .cfg_base = 0x004e, | ||
2348 | .preconfigure = preconfigure_through_82801, | ||
2349 | .name = "HP nc8000", | ||
2350 | }, | ||
2351 | { | ||
2352 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ | ||
2353 | .device = 0x24cc, | ||
2354 | .subvendor = 0x103c, | ||
2355 | .subdevice = 0x0890, | ||
2356 | .sir_io = 0x02f8, | ||
2357 | .fir_io = 0x0130, | ||
2358 | .fir_irq = 0x09, | ||
2359 | .fir_dma = 0x03, | ||
2360 | .cfg_base = 0x004e, | ||
2361 | .preconfigure = preconfigure_through_82801, | ||
2362 | .name = "HP nc6000", | ||
2363 | }, | ||
2364 | { | ||
2365 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ | ||
2366 | .device = 0x24c0, | ||
2367 | .subvendor = 0x1179, | ||
2368 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | ||
2369 | .sir_io = 0x03f8, | ||
2370 | .fir_io = 0x0130, | ||
2371 | .fir_irq = 0x07, | ||
2372 | .fir_dma = 0x01, | ||
2373 | .cfg_base = 0x002e, | ||
2374 | .preconfigure = preconfigure_through_82801, | ||
2375 | .name = "Toshiba Satellite 2450", | ||
2376 | }, | ||
2377 | { | ||
2378 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */ | ||
2379 | .device = 0x248c, /* Some use 24cc? */ | ||
2380 | .subvendor = 0x1179, | ||
2381 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | ||
2382 | .sir_io = 0x03f8, | ||
2383 | .fir_io = 0x0130, | ||
2384 | .fir_irq = 0x03, | ||
2385 | .fir_dma = 0x03, | ||
2386 | .cfg_base = 0x002e, | ||
2387 | .preconfigure = preconfigure_through_82801, | ||
2388 | .name = "Toshiba Satellite 5100/5200, Tecra 9100", | ||
2389 | }, | ||
2390 | { | ||
2391 | .vendor = PCIID_VENDOR_ALI, /* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */ | ||
2392 | .device = 0x1533, | ||
2393 | .subvendor = 0x1179, | ||
2394 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | ||
2395 | .sir_io = 0x02e8, | ||
2396 | .fir_io = 0x02f8, | ||
2397 | .fir_irq = 0x07, | ||
2398 | .fir_dma = 0x03, | ||
2399 | .cfg_base = 0x002e, | ||
2400 | .preconfigure = preconfigure_through_ali, | ||
2401 | .name = "Toshiba Satellite 1800", | ||
2402 | }, | ||
2403 | { } // Terminator | ||
2404 | }; | ||
2405 | |||
2406 | |||
2407 | /* | ||
2408 | * This sets up the basic SMSC parameters (FIR port, SIR port, FIR DMA, FIR IRQ) | ||
2409 | * through the chip configuration port. | ||
2410 | */ | ||
2411 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf) | ||
2412 | { | ||
2413 | unsigned short iobase = conf->cfg_base; | ||
2414 | unsigned char tmpbyte; | ||
2415 | |||
2416 | outb(LPC47N227_CFGACCESSKEY, iobase); // enter configuration state | ||
2417 | outb(SMSCSIOFLAT_DEVICEID_REG, iobase); // set for device ID | ||
2418 | tmpbyte = inb(iobase +1); // Read device ID | ||
2419 | IRDA_DEBUG(0, "Detected Chip id: 0x%02x, setting up registers...\n",tmpbyte); | ||
2420 | |||
2421 | /* Disable UART1 and set up SIR I/O port */ | ||
2422 | outb(0x24, iobase); // select CR24 - UART1 base addr | ||
2423 | outb(0x00, iobase + 1); // disable UART1 | ||
2424 | outb(SMSCSIOFLAT_UART2BASEADDR_REG, iobase); // select CR25 - UART2 base addr | ||
2425 | outb( (conf->sir_io >> 2), iobase + 1); // bits 2-9 of 0x3f8 | ||
2426 | tmpbyte = inb(iobase + 1); | ||
2427 | if (tmpbyte != (conf->sir_io >> 2) ) { | ||
2428 | IRDA_WARNING("ERROR: could not configure SIR ioport.\n"); | ||
2429 | return -ENXIO; | ||
2430 | } | ||
2431 | |||
2432 | /* Set up FIR IRQ channel for UART2 */ | ||
2433 | outb(SMSCSIOFLAT_UARTIRQSELECT_REG, iobase); // select CR28 - UART1,2 IRQ select | ||
2434 | tmpbyte = inb(iobase + 1); | ||
2435 | tmpbyte &= SMSCSIOFLAT_UART1IRQSELECT_MASK; // Do not touch the UART1 portion | ||
2436 | tmpbyte |= (conf->fir_irq & SMSCSIOFLAT_UART2IRQSELECT_MASK); | ||
2437 | outb(tmpbyte, iobase + 1); | ||
2438 | tmpbyte = inb(iobase + 1) & SMSCSIOFLAT_UART2IRQSELECT_MASK; | ||
2439 | if (tmpbyte != conf->fir_irq) { | ||
2440 | IRDA_WARNING("ERROR: could not configure FIR IRQ channel.\n"); | ||
2441 | return -ENXIO; | ||
2442 | } | ||
2443 | |||
2444 | /* Set up FIR I/O port */ | ||
2445 | outb(SMSCSIOFLAT_FIRBASEADDR_REG, iobase); // CR2B - SCE (FIR) base addr | ||
2446 | outb((conf->fir_io >> 3), iobase + 1); | ||
2447 | tmpbyte = inb(iobase + 1); | ||
2448 | if (tmpbyte != (conf->fir_io >> 3) ) { | ||
2449 | IRDA_WARNING("ERROR: could not configure FIR I/O port.\n"); | ||
2450 | return -ENXIO; | ||
2451 | } | ||
2452 | |||
2453 | /* Set up FIR DMA channel */ | ||
2454 | outb(SMSCSIOFLAT_FIRDMASELECT_REG, iobase); // CR2C - SCE (FIR) DMA select | ||
2455 | outb((conf->fir_dma & LPC47N227_FIRDMASELECT_MASK), iobase + 1); // DMA | ||
2456 | tmpbyte = inb(iobase + 1) & LPC47N227_FIRDMASELECT_MASK; | ||
2457 | if (tmpbyte != (conf->fir_dma & LPC47N227_FIRDMASELECT_MASK)) { | ||
2458 | IRDA_WARNING("ERROR: could not configure FIR DMA channel.\n"); | ||
2459 | return -ENXIO; | ||
2460 | } | ||
2461 | |||
2462 | outb(SMSCSIOFLAT_UARTMODE0C_REG, iobase); // CR0C - UART mode | ||
2463 | tmpbyte = inb(iobase + 1); | ||
2464 | tmpbyte &= ~SMSCSIOFLAT_UART2MODE_MASK | SMSCSIOFLAT_UART2MODE_VAL_IRDA; | ||
2465 | outb(tmpbyte, iobase + 1); // enable IrDA (HPSIR) mode, high speed | ||
2466 | |||
2467 | outb(LPC47N227_APMBOOTDRIVE_REG, iobase); // CR07 - Auto Pwr Mgt/boot drive sel | ||
2468 | tmpbyte = inb(iobase + 1); | ||
2469 | outb(tmpbyte | LPC47N227_UART2AUTOPWRDOWN_MASK, iobase + 1); // enable UART2 autopower down | ||
2470 | |||
2471 | /* This one was not part of tosh1800 */ | ||
2472 | outb(0x0a, iobase); // CR0a - ecp fifo / ir mux | ||
2473 | tmpbyte = inb(iobase + 1); | ||
2474 | outb(tmpbyte | 0x40, iobase + 1); // send active device to ir port | ||
2475 | |||
2476 | outb(LPC47N227_UART12POWER_REG, iobase); // CR02 - UART 1,2 power | ||
2477 | tmpbyte = inb(iobase + 1); | ||
2478 | outb(tmpbyte | LPC47N227_UART2POWERDOWN_MASK, iobase + 1); // UART2 power up mode, UART1 power down | ||
2479 | |||
2480 | outb(LPC47N227_FDCPOWERVALIDCONF_REG, iobase); // CR00 - FDC Power/valid config cycle | ||
2481 | tmpbyte = inb(iobase + 1); | ||
2482 | outb(tmpbyte | LPC47N227_VALID_MASK, iobase + 1); // valid config cycle done | ||
2483 | |||
2484 | outb(LPC47N227_CFGEXITKEY, iobase); // Exit configuration | ||
2485 | |||
2486 | return 0; | ||
2487 | } | ||
2488 | |||
2489 | /* 82801CAM registers */ | ||
2490 | #define VID 0x00 | ||
2491 | #define DID 0x02 | ||
2492 | #define PIRQA_ROUT 0x60 | ||
2493 | #define PCI_DMA_C 0x90 | ||
2494 | #define COM_DEC 0xe0 | ||
2495 | #define LPC_EN 0xe6 | ||
2496 | #define GEN2_DEC 0xec | ||
2497 | /* | ||
2498 | * Sets up the I/O range using the 82801CAM ISA bridge, 82801DBM LPC bridge or | ||
2499 | * Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. They all work the same way! | ||
2500 | */ | ||
2501 | static int __init preconfigure_through_82801(struct pci_dev *dev, | ||
2502 | struct smsc_ircc_subsystem_configuration *conf) | ||
2503 | { | ||
2504 | unsigned short tmpword; | ||
2505 | int ret; | ||
2506 | |||
2507 | IRDA_MESSAGE("Setting up the SMSC device via the 82801 controller.\n"); | ||
2508 | pci_write_config_byte(dev, COM_DEC, 0x10); | ||
2509 | |||
2510 | /* Enable LPC */ | ||
2511 | pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */ | ||
2512 | tmpword &= 0xfffd; /* mask bit 1 */ | ||
2513 | tmpword |= 0x0001; /* set bit 0 : COMA addr range enable */ | ||
2514 | pci_write_config_word(dev, LPC_EN, tmpword); | ||
2515 | |||
2516 | /* Setup DMA */ | ||
2517 | pci_write_config_word(dev, PCI_DMA_C, 0xc0c0); /* LPC I/F DMA on, channel 3 -- rtm (?? PCI DMA ?) */ | ||
2518 | pci_write_config_word(dev, GEN2_DEC, 0x131); /* LPC I/F 2nd decode range */ | ||
2519 | |||
2520 | /* Pre-configure chip */ | ||
2521 | ret = preconfigure_smsc_chip(conf); | ||
2522 | |||
2523 | /* Disable LPC */ | ||
2524 | pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */ | ||
2525 | tmpword &= 0xfffc; /* mask bit 1 and bit 0, COMA addr range disable */ | ||
2526 | pci_write_config_word(dev, LPC_EN, tmpword); | ||
2527 | return ret; | ||
2528 | } | ||
2529 | |||
2530 | static int __init preconfigure_through_ali(struct pci_dev *dev, | ||
2531 | struct smsc_ircc_subsystem_configuration *conf) | ||
2532 | { | ||
2533 | /* TODO: put in ALi 1533 configuration here. */ | ||
2534 | IRDA_MESSAGE("SORRY: %s has an unsupported bridge controller (ALi): not pre-configured.\n", conf->name); | ||
2535 | return -ENODEV; | ||
2536 | } | ||
2537 | |||
2538 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | ||
2539 | unsigned short ircc_fir, | ||
2540 | unsigned short ircc_sir, | ||
2541 | unsigned char ircc_dma, | ||
2542 | unsigned char ircc_irq) | ||
2543 | { | ||
2544 | struct pci_dev *dev = NULL; | ||
2545 | unsigned short ss_vendor = 0x0000; | ||
2546 | unsigned short ss_device = 0x0000; | ||
2547 | int ret = 0; | ||
2548 | |||
2549 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
2550 | |||
2551 | while (dev != NULL) { | ||
2552 | struct smsc_ircc_subsystem_configuration *conf; | ||
2553 | |||
2554 | /* | ||
2555 | * Cache the subsystem vendor/device: some manufacturers fail to set | ||
2556 | * this for all components, so we save it in case there is just | ||
2557 | * 0x0000 0x0000 on the device we want to check. | ||
2558 | */ | ||
2559 | if (dev->subsystem_vendor != 0x0000U) { | ||
2560 | ss_vendor = dev->subsystem_vendor; | ||
2561 | ss_device = dev->subsystem_device; | ||
2562 | } | ||
2563 | conf = subsystem_configurations; | ||
2564 | for( ; conf->subvendor; conf++) { | ||
2565 | if(conf->vendor == dev->vendor && | ||
2566 | conf->device == dev->device && | ||
2567 | conf->subvendor == ss_vendor && /* Sometimes these are cached values */ | ||
2568 | (conf->subdevice == ss_device || conf->subdevice == 0xffff)) { | ||
2569 | struct smsc_ircc_subsystem_configuration tmpconf; | ||
2570 | |||
2571 | memcpy(&tmpconf, conf, sizeof(struct smsc_ircc_subsystem_configuration)); | ||
2572 | |||
2573 | /* Override the default values with anything passed in as parameter */ | ||
2574 | if (ircc_cfg != 0) | ||
2575 | tmpconf.cfg_base = ircc_cfg; | ||
2576 | if (ircc_fir != 0) | ||
2577 | tmpconf.fir_io = ircc_fir; | ||
2578 | if (ircc_sir != 0) | ||
2579 | tmpconf.sir_io = ircc_sir; | ||
2580 | if (ircc_dma != 0xff) | ||
2581 | tmpconf.fir_dma = ircc_dma; | ||
2582 | if (ircc_irq != 0xff) | ||
2583 | tmpconf.fir_irq = ircc_irq; | ||
2584 | |||
2585 | IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); | ||
2586 | if (conf->preconfigure) | ||
2587 | ret = conf->preconfigure(dev, &tmpconf); | ||
2588 | else | ||
2589 | ret = -ENODEV; | ||
2590 | } | ||
2591 | } | ||
2592 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
2593 | } | ||
2594 | |||
2595 | return ret; | ||
2596 | } | ||
2597 | #endif // CONFIG_PCI | ||
2598 | |||
2288 | /************************************************ | 2599 | /************************************************ |
2289 | * | 2600 | * |
2290 | * Transceivers specific functions | 2601 | * Transceivers specific functions |
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 75b35ad760de..66e74f740261 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c | |||
@@ -87,6 +87,7 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) | |||
87 | } | 87 | } |
88 | 88 | ||
89 | static struct console netconsole = { | 89 | static struct console netconsole = { |
90 | .name = "netcon", | ||
90 | .flags = CON_ENABLED | CON_PRINTBUFFER, | 91 | .flags = CON_ENABLED | CON_PRINTBUFFER, |
91 | .write = write_msg | 92 | .write = write_msg |
92 | }; | 93 | }; |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0b5358072172..73e271e59c6a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -497,21 +497,20 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) | |||
497 | unsigned long flags; | 497 | unsigned long flags; |
498 | 498 | ||
499 | spin_lock_irqsave(&tp->indirect_lock, flags); | 499 | spin_lock_irqsave(&tp->indirect_lock, flags); |
500 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 500 | if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { |
501 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 501 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
502 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | ||
502 | 503 | ||
503 | /* Always leave this as zero. */ | 504 | /* Always leave this as zero. */ |
504 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 505 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
505 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 506 | } else { |
506 | } | 507 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); |
508 | tw32_f(TG3PCI_MEM_WIN_DATA, val); | ||
507 | 509 | ||
508 | static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) | 510 | /* Always leave this as zero. */ |
509 | { | 511 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); |
510 | /* If no workaround is needed, write to mem space directly */ | 512 | } |
511 | if (tp->write32 != tg3_write_indirect_reg32) | 513 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
512 | tw32(NIC_SRAM_WIN_BASE + off, val); | ||
513 | else | ||
514 | tg3_write_mem(tp, off, val); | ||
515 | } | 514 | } |
516 | 515 | ||
517 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | 516 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) |
@@ -519,11 +518,19 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | |||
519 | unsigned long flags; | 518 | unsigned long flags; |
520 | 519 | ||
521 | spin_lock_irqsave(&tp->indirect_lock, flags); | 520 | spin_lock_irqsave(&tp->indirect_lock, flags); |
522 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 521 | if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { |
523 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 522 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
523 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | ||
524 | 524 | ||
525 | /* Always leave this as zero. */ | 525 | /* Always leave this as zero. */ |
526 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 526 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
527 | } else { | ||
528 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); | ||
529 | *val = tr32(TG3PCI_MEM_WIN_DATA); | ||
530 | |||
531 | /* Always leave this as zero. */ | ||
532 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); | ||
533 | } | ||
527 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 534 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
528 | } | 535 | } |
529 | 536 | ||
@@ -1367,12 +1374,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) | |||
1367 | } | 1374 | } |
1368 | } | 1375 | } |
1369 | 1376 | ||
1377 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | ||
1378 | |||
1370 | /* Finally, set the new power state. */ | 1379 | /* Finally, set the new power state. */ |
1371 | pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); | 1380 | pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); |
1372 | udelay(100); /* Delay after power state change */ | 1381 | udelay(100); /* Delay after power state change */ |
1373 | 1382 | ||
1374 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | ||
1375 | |||
1376 | return 0; | 1383 | return 0; |
1377 | } | 1384 | } |
1378 | 1385 | ||
@@ -5828,10 +5835,14 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5828 | GRC_MODE_NO_TX_PHDR_CSUM | | 5835 | GRC_MODE_NO_TX_PHDR_CSUM | |
5829 | GRC_MODE_NO_RX_PHDR_CSUM); | 5836 | GRC_MODE_NO_RX_PHDR_CSUM); |
5830 | tp->grc_mode |= GRC_MODE_HOST_SENDBDS; | 5837 | tp->grc_mode |= GRC_MODE_HOST_SENDBDS; |
5831 | if (tp->tg3_flags & TG3_FLAG_NO_TX_PSEUDO_CSUM) | 5838 | |
5832 | tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; | 5839 | /* Pseudo-header checksum is done by hardware logic and not |
5833 | if (tp->tg3_flags & TG3_FLAG_NO_RX_PSEUDO_CSUM) | 5840 | * the offload processers, so make the chip do the pseudo- |
5834 | tp->grc_mode |= GRC_MODE_NO_RX_PHDR_CSUM; | 5841 | * header checksums on receive. For transmit it is more |
5842 | * convenient to do the pseudo-header checksum in software | ||
5843 | * as Linux does that on transmit for us in all cases. | ||
5844 | */ | ||
5845 | tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; | ||
5835 | 5846 | ||
5836 | tw32(GRC_MODE, | 5847 | tw32(GRC_MODE, |
5837 | tp->grc_mode | | 5848 | tp->grc_mode | |
@@ -6535,11 +6546,11 @@ static void tg3_timer(unsigned long __opaque) | |||
6535 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { | 6546 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { |
6536 | u32 val; | 6547 | u32 val; |
6537 | 6548 | ||
6538 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, | 6549 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, |
6539 | FWCMD_NICDRV_ALIVE2); | 6550 | FWCMD_NICDRV_ALIVE2); |
6540 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); | 6551 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); |
6541 | /* 5 seconds timeout */ | 6552 | /* 5 seconds timeout */ |
6542 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); | 6553 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); |
6543 | val = tr32(GRC_RX_CPU_EVENT); | 6554 | val = tr32(GRC_RX_CPU_EVENT); |
6544 | val |= (1 << 14); | 6555 | val |= (1 << 14); |
6545 | tw32(GRC_RX_CPU_EVENT, val); | 6556 | tw32(GRC_RX_CPU_EVENT, val); |
@@ -8034,9 +8045,13 @@ static int tg3_test_nvram(struct tg3 *tp) | |||
8034 | for (i = 0; i < size; i++) | 8045 | for (i = 0; i < size; i++) |
8035 | csum8 += buf8[i]; | 8046 | csum8 += buf8[i]; |
8036 | 8047 | ||
8037 | if (csum8 == 0) | 8048 | if (csum8 == 0) { |
8038 | return 0; | 8049 | err = 0; |
8039 | return -EIO; | 8050 | goto out; |
8051 | } | ||
8052 | |||
8053 | err = -EIO; | ||
8054 | goto out; | ||
8040 | } | 8055 | } |
8041 | 8056 | ||
8042 | /* Bootstrap checksum at offset 0x10 */ | 8057 | /* Bootstrap checksum at offset 0x10 */ |
@@ -9531,8 +9546,11 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
9531 | tp->led_ctrl = LED_CTRL_MODE_PHY_1; | 9546 | tp->led_ctrl = LED_CTRL_MODE_PHY_1; |
9532 | 9547 | ||
9533 | /* Do not even try poking around in here on Sun parts. */ | 9548 | /* Do not even try poking around in here on Sun parts. */ |
9534 | if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) | 9549 | if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { |
9550 | /* All SUN chips are built-in LOMs. */ | ||
9551 | tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; | ||
9535 | return; | 9552 | return; |
9553 | } | ||
9536 | 9554 | ||
9537 | tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); | 9555 | tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); |
9538 | if (val == NIC_SRAM_DATA_SIG_MAGIC) { | 9556 | if (val == NIC_SRAM_DATA_SIG_MAGIC) { |
@@ -9630,9 +9648,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
9630 | tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) | 9648 | tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) |
9631 | tp->led_ctrl = LED_CTRL_MODE_PHY_2; | 9649 | tp->led_ctrl = LED_CTRL_MODE_PHY_2; |
9632 | 9650 | ||
9633 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) && | 9651 | if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) |
9634 | (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) && | ||
9635 | (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)) | ||
9636 | tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; | 9652 | tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; |
9637 | 9653 | ||
9638 | if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { | 9654 | if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { |
@@ -10257,6 +10273,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
10257 | pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); | 10273 | pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); |
10258 | } | 10274 | } |
10259 | 10275 | ||
10276 | if (tp->write32 == tg3_write_indirect_reg32 || | ||
10277 | ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && | ||
10278 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || | ||
10279 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) || | ||
10280 | (tp->tg3_flags2 & TG3_FLG2_SUN_570X)) | ||
10281 | tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; | ||
10282 | |||
10260 | /* Get eeprom hw config before calling tg3_set_power_state(). | 10283 | /* Get eeprom hw config before calling tg3_set_power_state(). |
10261 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be | 10284 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be |
10262 | * determined before calling tg3_set_power_state() so that | 10285 | * determined before calling tg3_set_power_state() so that |
@@ -10299,15 +10322,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
10299 | if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) | 10322 | if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) |
10300 | tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; | 10323 | tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; |
10301 | 10324 | ||
10302 | /* Pseudo-header checksum is done by hardware logic and not | ||
10303 | * the offload processers, so make the chip do the pseudo- | ||
10304 | * header checksums on receive. For transmit it is more | ||
10305 | * convenient to do the pseudo-header checksum in software | ||
10306 | * as Linux does that on transmit for us in all cases. | ||
10307 | */ | ||
10308 | tp->tg3_flags |= TG3_FLAG_NO_TX_PSEUDO_CSUM; | ||
10309 | tp->tg3_flags &= ~TG3_FLAG_NO_RX_PSEUDO_CSUM; | ||
10310 | |||
10311 | /* Derive initial jumbo mode from MTU assigned in | 10325 | /* Derive initial jumbo mode from MTU assigned in |
10312 | * ether_setup() via the alloc_etherdev() call | 10326 | * ether_setup() via the alloc_etherdev() call |
10313 | */ | 10327 | */ |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index c43cc3264202..8c8b987d1250 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -2171,8 +2171,7 @@ struct tg3 { | |||
2171 | #define TG3_FLAG_PCIX_MODE 0x00020000 | 2171 | #define TG3_FLAG_PCIX_MODE 0x00020000 |
2172 | #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 | 2172 | #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 |
2173 | #define TG3_FLAG_PCI_32BIT 0x00080000 | 2173 | #define TG3_FLAG_PCI_32BIT 0x00080000 |
2174 | #define TG3_FLAG_NO_TX_PSEUDO_CSUM 0x00100000 | 2174 | #define TG3_FLAG_SRAM_USE_CONFIG 0x00100000 |
2175 | #define TG3_FLAG_NO_RX_PSEUDO_CSUM 0x00200000 | ||
2176 | #define TG3_FLAG_SERDES_WOL_CAP 0x00400000 | 2175 | #define TG3_FLAG_SERDES_WOL_CAP 0x00400000 |
2177 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 | 2176 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 |
2178 | #define TG3_FLAG_10_100_ONLY 0x01000000 | 2177 | #define TG3_FLAG_10_100_ONLY 0x01000000 |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index d121644646b9..98b83a85c60e 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -100,8 +100,6 @@ static struct pci_device_id parport_serial_pci_tbl[] = { | |||
100 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | 100 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, |
101 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, | 101 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, |
102 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | 102 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, |
103 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, | ||
104 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | ||
105 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, | 103 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, |
106 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | 104 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, |
107 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, | 105 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 929dd8090578..65d090dbef46 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -147,6 +147,16 @@ config RTC_DRV_SA1100 | |||
147 | To compile this driver as a module, choose M here: the | 147 | To compile this driver as a module, choose M here: the |
148 | module will be called rtc-sa1100. | 148 | module will be called rtc-sa1100. |
149 | 149 | ||
150 | config RTC_DRV_VR41XX | ||
151 | tristate "NEC VR41XX" | ||
152 | depends on RTC_CLASS && CPU_VR41XX | ||
153 | help | ||
154 | If you say Y here you will get access to the real time clock | ||
155 | built into your NEC VR41XX CPU. | ||
156 | |||
157 | To compile this driver as a module, choose M here: the | ||
158 | module will be called rtc-vr41xx. | ||
159 | |||
150 | config RTC_DRV_TEST | 160 | config RTC_DRV_TEST |
151 | tristate "Test driver/device" | 161 | tristate "Test driver/device" |
152 | depends on RTC_CLASS | 162 | depends on RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 8d4c7fe88d58..a9ca0f171686 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -19,3 +19,4 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | |||
19 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 19 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
20 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 20 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
21 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 21 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
22 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | ||
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 8533936d50d8..413c7d54ea10 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -96,6 +96,8 @@ exit_idr: | |||
96 | idr_remove(&rtc_idr, id); | 96 | idr_remove(&rtc_idr, id); |
97 | 97 | ||
98 | exit: | 98 | exit: |
99 | dev_err(dev, "rtc core: unable to register %s, err = %d\n", | ||
100 | name, err); | ||
99 | return ERR_PTR(err); | 101 | return ERR_PTR(err); |
100 | } | 102 | } |
101 | EXPORT_SYMBOL_GPL(rtc_device_register); | 103 | EXPORT_SYMBOL_GPL(rtc_device_register); |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 358695a416f3..9be81fd4737c 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * An rtc/i2c driver for the Dallas DS1672 | 2 | * An rtc/i2c driver for the Dallas DS1672 |
3 | * Copyright 2005 Alessandro Zummo | 3 | * Copyright 2005-06 Tower Technologies |
4 | * | ||
5 | * Author: Alessandro Zummo <a.zummo@towertech.it> | ||
4 | * | 6 | * |
5 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -11,7 +13,7 @@ | |||
11 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
12 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
13 | 15 | ||
14 | #define DRV_VERSION "0.2" | 16 | #define DRV_VERSION "0.3" |
15 | 17 | ||
16 | /* Addresses to scan: none. This chip cannot be detected. */ | 18 | /* Addresses to scan: none. This chip cannot be detected. */ |
17 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; | 19 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; |
@@ -25,6 +27,7 @@ I2C_CLIENT_INSMOD; | |||
25 | #define DS1672_REG_CONTROL 4 | 27 | #define DS1672_REG_CONTROL 4 |
26 | #define DS1672_REG_TRICKLE 5 | 28 | #define DS1672_REG_TRICKLE 5 |
27 | 29 | ||
30 | #define DS1672_REG_CONTROL_EOSC 0x80 | ||
28 | 31 | ||
29 | /* Prototypes */ | 32 | /* Prototypes */ |
30 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind); | 33 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind); |
@@ -53,8 +56,7 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
53 | 56 | ||
54 | dev_dbg(&client->dev, | 57 | dev_dbg(&client->dev, |
55 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n" | 58 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n" |
56 | __FUNCTION__, | 59 | __FUNCTION__, buf[0], buf[1], buf[2], buf[3]); |
57 | buf[0], buf[1], buf[2], buf[3]); | ||
58 | 60 | ||
59 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | 61 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; |
60 | 62 | ||
@@ -62,8 +64,7 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
62 | 64 | ||
63 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 65 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
64 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 66 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
65 | __FUNCTION__, | 67 | __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, |
66 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
67 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 68 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
68 | 69 | ||
69 | return 0; | 70 | return 0; |
@@ -72,16 +73,17 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
72 | static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) | 73 | static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) |
73 | { | 74 | { |
74 | int xfer; | 75 | int xfer; |
75 | unsigned char buf[5]; | 76 | unsigned char buf[6]; |
76 | 77 | ||
77 | buf[0] = DS1672_REG_CNT_BASE; | 78 | buf[0] = DS1672_REG_CNT_BASE; |
78 | buf[1] = secs & 0x000000FF; | 79 | buf[1] = secs & 0x000000FF; |
79 | buf[2] = (secs & 0x0000FF00) >> 8; | 80 | buf[2] = (secs & 0x0000FF00) >> 8; |
80 | buf[3] = (secs & 0x00FF0000) >> 16; | 81 | buf[3] = (secs & 0x00FF0000) >> 16; |
81 | buf[4] = (secs & 0xFF000000) >> 24; | 82 | buf[4] = (secs & 0xFF000000) >> 24; |
83 | buf[5] = 0; /* set control reg to enable counting */ | ||
82 | 84 | ||
83 | xfer = i2c_master_send(client, buf, 5); | 85 | xfer = i2c_master_send(client, buf, 6); |
84 | if (xfer != 5) { | 86 | if (xfer != 6) { |
85 | dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer); | 87 | dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer); |
86 | return -EIO; | 88 | return -EIO; |
87 | } | 89 | } |
@@ -120,6 +122,40 @@ static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs) | |||
120 | return ds1672_set_mmss(to_i2c_client(dev), secs); | 122 | return ds1672_set_mmss(to_i2c_client(dev), secs); |
121 | } | 123 | } |
122 | 124 | ||
125 | static int ds1672_get_control(struct i2c_client *client, u8 *status) | ||
126 | { | ||
127 | unsigned char addr = DS1672_REG_CONTROL; | ||
128 | |||
129 | struct i2c_msg msgs[] = { | ||
130 | { client->addr, 0, 1, &addr }, /* setup read ptr */ | ||
131 | { client->addr, I2C_M_RD, 1, status }, /* read control */ | ||
132 | }; | ||
133 | |||
134 | /* read control register */ | ||
135 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | ||
136 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | ||
137 | return -EIO; | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | /* following are the sysfs callback functions */ | ||
144 | static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf) | ||
145 | { | ||
146 | struct i2c_client *client = to_i2c_client(dev); | ||
147 | u8 control; | ||
148 | int err; | ||
149 | |||
150 | err = ds1672_get_control(client, &control); | ||
151 | if (err) | ||
152 | return err; | ||
153 | |||
154 | return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC) | ||
155 | ? "disabled" : "enabled"); | ||
156 | } | ||
157 | static DEVICE_ATTR(control, S_IRUGO, show_control, NULL); | ||
158 | |||
123 | static struct rtc_class_ops ds1672_rtc_ops = { | 159 | static struct rtc_class_ops ds1672_rtc_ops = { |
124 | .read_time = ds1672_rtc_read_time, | 160 | .read_time = ds1672_rtc_read_time, |
125 | .set_time = ds1672_rtc_set_time, | 161 | .set_time = ds1672_rtc_set_time, |
@@ -128,7 +164,6 @@ static struct rtc_class_ops ds1672_rtc_ops = { | |||
128 | 164 | ||
129 | static int ds1672_attach(struct i2c_adapter *adapter) | 165 | static int ds1672_attach(struct i2c_adapter *adapter) |
130 | { | 166 | { |
131 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | ||
132 | return i2c_probe(adapter, &addr_data, ds1672_probe); | 167 | return i2c_probe(adapter, &addr_data, ds1672_probe); |
133 | } | 168 | } |
134 | 169 | ||
@@ -137,8 +172,6 @@ static int ds1672_detach(struct i2c_client *client) | |||
137 | int err; | 172 | int err; |
138 | struct rtc_device *rtc = i2c_get_clientdata(client); | 173 | struct rtc_device *rtc = i2c_get_clientdata(client); |
139 | 174 | ||
140 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
141 | |||
142 | if (rtc) | 175 | if (rtc) |
143 | rtc_device_unregister(rtc); | 176 | rtc_device_unregister(rtc); |
144 | 177 | ||
@@ -162,6 +195,7 @@ static struct i2c_driver ds1672_driver = { | |||
162 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) | 195 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) |
163 | { | 196 | { |
164 | int err = 0; | 197 | int err = 0; |
198 | u8 control; | ||
165 | struct i2c_client *client; | 199 | struct i2c_client *client; |
166 | struct rtc_device *rtc; | 200 | struct rtc_device *rtc; |
167 | 201 | ||
@@ -195,13 +229,23 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) | |||
195 | 229 | ||
196 | if (IS_ERR(rtc)) { | 230 | if (IS_ERR(rtc)) { |
197 | err = PTR_ERR(rtc); | 231 | err = PTR_ERR(rtc); |
198 | dev_err(&client->dev, | ||
199 | "unable to register the class device\n"); | ||
200 | goto exit_detach; | 232 | goto exit_detach; |
201 | } | 233 | } |
202 | 234 | ||
203 | i2c_set_clientdata(client, rtc); | 235 | i2c_set_clientdata(client, rtc); |
204 | 236 | ||
237 | /* read control register */ | ||
238 | err = ds1672_get_control(client, &control); | ||
239 | if (err) | ||
240 | goto exit_detach; | ||
241 | |||
242 | if (control & DS1672_REG_CONTROL_EOSC) | ||
243 | dev_warn(&client->dev, "Oscillator not enabled. " | ||
244 | "Set time to enable.\n"); | ||
245 | |||
246 | /* Register sysfs hooks */ | ||
247 | device_create_file(&client->dev, &dev_attr_control); | ||
248 | |||
205 | return 0; | 249 | return 0; |
206 | 250 | ||
207 | exit_detach: | 251 | exit_detach: |
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 0dd80ea686a9..e1a1169e4664 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c | |||
@@ -67,7 +67,6 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) | |||
67 | 67 | ||
68 | ep93xx_get_swcomp(dev, &preload, &delete); | 68 | ep93xx_get_swcomp(dev, &preload, &delete); |
69 | 69 | ||
70 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
71 | seq_printf(seq, "preload\t\t: %d\n", preload); | 70 | seq_printf(seq, "preload\t\t: %d\n", preload); |
72 | seq_printf(seq, "delete\t\t: %d\n", delete); | 71 | seq_printf(seq, "delete\t\t: %d\n", delete); |
73 | 72 | ||
@@ -110,7 +109,6 @@ static int __devinit ep93xx_rtc_probe(struct platform_device *dev) | |||
110 | &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); | 109 | &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); |
111 | 110 | ||
112 | if (IS_ERR(rtc)) { | 111 | if (IS_ERR(rtc)) { |
113 | dev_err(&dev->dev, "unable to register\n"); | ||
114 | return PTR_ERR(rtc); | 112 | return PTR_ERR(rtc); |
115 | } | 113 | } |
116 | 114 | ||
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index db445c872b1b..f6e7ee04f3dc 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #define M48T86_REG_SECALRM 0x01 | 23 | #define M48T86_REG_SECALRM 0x01 |
24 | #define M48T86_REG_MIN 0x02 | 24 | #define M48T86_REG_MIN 0x02 |
25 | #define M48T86_REG_MINALRM 0x03 | 25 | #define M48T86_REG_MINALRM 0x03 |
26 | #define M48T86_REG_HOUR 0x04 | 26 | #define M48T86_REG_HOUR 0x04 |
27 | #define M48T86_REG_HOURALRM 0x05 | 27 | #define M48T86_REG_HOURALRM 0x05 |
28 | #define M48T86_REG_DOW 0x06 /* 1 = sunday */ | 28 | #define M48T86_REG_DOW 0x06 /* 1 = sunday */ |
29 | #define M48T86_REG_DOM 0x07 | 29 | #define M48T86_REG_DOM 0x07 |
@@ -127,9 +127,6 @@ static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq) | |||
127 | 127 | ||
128 | reg = ops->readb(M48T86_REG_B); | 128 | reg = ops->readb(M48T86_REG_B); |
129 | 129 | ||
130 | seq_printf(seq, "24hr\t\t: %s\n", | ||
131 | (reg & M48T86_REG_B_H24) ? "yes" : "no"); | ||
132 | |||
133 | seq_printf(seq, "mode\t\t: %s\n", | 130 | seq_printf(seq, "mode\t\t: %s\n", |
134 | (reg & M48T86_REG_B_DM) ? "binary" : "bcd"); | 131 | (reg & M48T86_REG_B_DM) ? "binary" : "bcd"); |
135 | 132 | ||
@@ -154,10 +151,8 @@ static int __devinit m48t86_rtc_probe(struct platform_device *dev) | |||
154 | struct rtc_device *rtc = rtc_device_register("m48t86", | 151 | struct rtc_device *rtc = rtc_device_register("m48t86", |
155 | &dev->dev, &m48t86_rtc_ops, THIS_MODULE); | 152 | &dev->dev, &m48t86_rtc_ops, THIS_MODULE); |
156 | 153 | ||
157 | if (IS_ERR(rtc)) { | 154 | if (IS_ERR(rtc)) |
158 | dev_err(&dev->dev, "unable to register\n"); | ||
159 | return PTR_ERR(rtc); | 155 | return PTR_ERR(rtc); |
160 | } | ||
161 | 156 | ||
162 | platform_set_drvdata(dev, rtc); | 157 | platform_set_drvdata(dev, rtc); |
163 | 158 | ||
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index d857d45bdbe8..ba9a583b7b68 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -227,14 +227,7 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
227 | return pcf8563_set_datetime(to_i2c_client(dev), tm); | 227 | return pcf8563_set_datetime(to_i2c_client(dev), tm); |
228 | } | 228 | } |
229 | 229 | ||
230 | static int pcf8563_rtc_proc(struct device *dev, struct seq_file *seq) | ||
231 | { | ||
232 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static struct rtc_class_ops pcf8563_rtc_ops = { | 230 | static struct rtc_class_ops pcf8563_rtc_ops = { |
237 | .proc = pcf8563_rtc_proc, | ||
238 | .read_time = pcf8563_rtc_read_time, | 231 | .read_time = pcf8563_rtc_read_time, |
239 | .set_time = pcf8563_rtc_set_time, | 232 | .set_time = pcf8563_rtc_set_time, |
240 | }; | 233 | }; |
@@ -297,8 +290,6 @@ static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) | |||
297 | 290 | ||
298 | if (IS_ERR(rtc)) { | 291 | if (IS_ERR(rtc)) { |
299 | err = PTR_ERR(rtc); | 292 | err = PTR_ERR(rtc); |
300 | dev_err(&client->dev, | ||
301 | "unable to register the class device\n"); | ||
302 | goto exit_detach; | 293 | goto exit_detach; |
303 | } | 294 | } |
304 | 295 | ||
@@ -321,8 +312,6 @@ static int pcf8563_detach(struct i2c_client *client) | |||
321 | int err; | 312 | int err; |
322 | struct rtc_device *rtc = i2c_get_clientdata(client); | 313 | struct rtc_device *rtc = i2c_get_clientdata(client); |
323 | 314 | ||
324 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
325 | |||
326 | if (rtc) | 315 | if (rtc) |
327 | rtc_device_unregister(rtc); | 316 | rtc_device_unregister(rtc); |
328 | 317 | ||
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index 90b8a97a0919..cef5f5a3bbf9 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -71,6 +71,8 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) | |||
71 | alrm.pending ? "yes" : "no"); | 71 | alrm.pending ? "yes" : "no"); |
72 | } | 72 | } |
73 | 73 | ||
74 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
75 | |||
74 | if (ops->proc) | 76 | if (ops->proc) |
75 | ops->proc(class_dev->dev, seq); | 77 | ops->proc(class_dev->dev, seq); |
76 | 78 | ||
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 396c8681f66c..7553d797603f 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -151,9 +151,8 @@ static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq) | |||
151 | { | 151 | { |
152 | int err, osc, trim; | 152 | int err, osc, trim; |
153 | 153 | ||
154 | seq_printf(seq, "24hr\t\t: yes\n"); | 154 | err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim); |
155 | 155 | if (err == 0) { | |
156 | if ((err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim)) == 0) { | ||
157 | seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000); | 156 | seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000); |
158 | seq_printf(seq, "trim\t: %d\n", trim); | 157 | seq_printf(seq, "trim\t: %d\n", trim); |
159 | } | 158 | } |
@@ -170,30 +169,31 @@ static struct rtc_class_ops rs5c372_rtc_ops = { | |||
170 | static ssize_t rs5c372_sysfs_show_trim(struct device *dev, | 169 | static ssize_t rs5c372_sysfs_show_trim(struct device *dev, |
171 | struct device_attribute *attr, char *buf) | 170 | struct device_attribute *attr, char *buf) |
172 | { | 171 | { |
173 | int trim; | 172 | int err, trim; |
174 | 173 | ||
175 | if (rs5c372_get_trim(to_i2c_client(dev), NULL, &trim) == 0) | 174 | err = rs5c372_get_trim(to_i2c_client(dev), NULL, &trim); |
176 | return sprintf(buf, "0x%2x\n", trim); | 175 | if (err) |
176 | return err; | ||
177 | 177 | ||
178 | return 0; | 178 | return sprintf(buf, "0x%2x\n", trim); |
179 | } | 179 | } |
180 | static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL); | 180 | static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL); |
181 | 181 | ||
182 | static ssize_t rs5c372_sysfs_show_osc(struct device *dev, | 182 | static ssize_t rs5c372_sysfs_show_osc(struct device *dev, |
183 | struct device_attribute *attr, char *buf) | 183 | struct device_attribute *attr, char *buf) |
184 | { | 184 | { |
185 | int osc; | 185 | int err, osc; |
186 | 186 | ||
187 | if (rs5c372_get_trim(to_i2c_client(dev), &osc, NULL) == 0) | 187 | err = rs5c372_get_trim(to_i2c_client(dev), &osc, NULL); |
188 | return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000); | 188 | if (err) |
189 | return err; | ||
189 | 190 | ||
190 | return 0; | 191 | return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000); |
191 | } | 192 | } |
192 | static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL); | 193 | static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL); |
193 | 194 | ||
194 | static int rs5c372_attach(struct i2c_adapter *adapter) | 195 | static int rs5c372_attach(struct i2c_adapter *adapter) |
195 | { | 196 | { |
196 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | ||
197 | return i2c_probe(adapter, &addr_data, rs5c372_probe); | 197 | return i2c_probe(adapter, &addr_data, rs5c372_probe); |
198 | } | 198 | } |
199 | 199 | ||
@@ -233,8 +233,6 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) | |||
233 | 233 | ||
234 | if (IS_ERR(rtc)) { | 234 | if (IS_ERR(rtc)) { |
235 | err = PTR_ERR(rtc); | 235 | err = PTR_ERR(rtc); |
236 | dev_err(&client->dev, | ||
237 | "unable to register the class device\n"); | ||
238 | goto exit_detach; | 236 | goto exit_detach; |
239 | } | 237 | } |
240 | 238 | ||
@@ -260,8 +258,6 @@ static int rs5c372_detach(struct i2c_client *client) | |||
260 | int err; | 258 | int err; |
261 | struct rtc_device *rtc = i2c_get_clientdata(client); | 259 | struct rtc_device *rtc = i2c_get_clientdata(client); |
262 | 260 | ||
263 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
264 | |||
265 | if (rtc) | 261 | if (rtc) |
266 | rtc_device_unregister(rtc); | 262 | rtc_device_unregister(rtc); |
267 | 263 | ||
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 83b2bb480a16..a23ec54989f6 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -160,19 +160,19 @@ static int sa1100_rtc_open(struct device *dev) | |||
160 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT, | 160 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT, |
161 | "rtc 1Hz", dev); | 161 | "rtc 1Hz", dev); |
162 | if (ret) { | 162 | if (ret) { |
163 | printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz); | 163 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); |
164 | goto fail_ui; | 164 | goto fail_ui; |
165 | } | 165 | } |
166 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT, | 166 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT, |
167 | "rtc Alrm", dev); | 167 | "rtc Alrm", dev); |
168 | if (ret) { | 168 | if (ret) { |
169 | printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm); | 169 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); |
170 | goto fail_ai; | 170 | goto fail_ai; |
171 | } | 171 | } |
172 | ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, | 172 | ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, |
173 | "rtc timer", dev); | 173 | "rtc timer", dev); |
174 | if (ret) { | 174 | if (ret) { |
175 | printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1); | 175 | dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); |
176 | goto fail_pi; | 176 | goto fail_pi; |
177 | } | 177 | } |
178 | return 0; | 178 | return 0; |
@@ -332,7 +332,7 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
332 | */ | 332 | */ |
333 | if (RTTR == 0) { | 333 | if (RTTR == 0) { |
334 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | 334 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); |
335 | printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n"); | 335 | dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n"); |
336 | /* The current RTC value probably doesn't make sense either */ | 336 | /* The current RTC value probably doesn't make sense either */ |
337 | RCNR = 0; | 337 | RCNR = 0; |
338 | } | 338 | } |
@@ -340,15 +340,11 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
340 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, | 340 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
341 | THIS_MODULE); | 341 | THIS_MODULE); |
342 | 342 | ||
343 | if (IS_ERR(rtc)) { | 343 | if (IS_ERR(rtc)) |
344 | dev_err(&pdev->dev, "Unable to register the RTC device\n"); | ||
345 | return PTR_ERR(rtc); | 344 | return PTR_ERR(rtc); |
346 | } | ||
347 | 345 | ||
348 | platform_set_drvdata(pdev, rtc); | 346 | platform_set_drvdata(pdev, rtc); |
349 | 347 | ||
350 | dev_info(&pdev->dev, "SA11xx/PXA2xx RTC Registered\n"); | ||
351 | |||
352 | return 0; | 348 | return 0; |
353 | } | 349 | } |
354 | 350 | ||
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 43d107487820..e1f7e8e86daf 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -49,7 +49,6 @@ static int test_rtc_proc(struct device *dev, struct seq_file *seq) | |||
49 | { | 49 | { |
50 | struct platform_device *plat_dev = to_platform_device(dev); | 50 | struct platform_device *plat_dev = to_platform_device(dev); |
51 | 51 | ||
52 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
53 | seq_printf(seq, "test\t\t: yes\n"); | 52 | seq_printf(seq, "test\t\t: yes\n"); |
54 | seq_printf(seq, "id\t\t: %d\n", plat_dev->id); | 53 | seq_printf(seq, "id\t\t: %d\n", plat_dev->id); |
55 | 54 | ||
@@ -120,8 +119,6 @@ static int test_probe(struct platform_device *plat_dev) | |||
120 | &test_rtc_ops, THIS_MODULE); | 119 | &test_rtc_ops, THIS_MODULE); |
121 | if (IS_ERR(rtc)) { | 120 | if (IS_ERR(rtc)) { |
122 | err = PTR_ERR(rtc); | 121 | err = PTR_ERR(rtc); |
123 | dev_err(&plat_dev->dev, | ||
124 | "unable to register the class device\n"); | ||
125 | return err; | 122 | return err; |
126 | } | 123 | } |
127 | device_create_file(&plat_dev->dev, &dev_attr_irq); | 124 | device_create_file(&plat_dev->dev, &dev_attr_irq); |
diff --git a/drivers/char/vr41xx_rtc.c b/drivers/rtc/rtc-vr41xx.c index b109d9a502d6..4d49fd501198 100644 --- a/drivers/char/vr41xx_rtc.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for NEC VR4100 series Real Time Clock unit. | 2 | * Driver for NEC VR4100 series Real Time Clock unit. |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2003-2006 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -17,23 +17,18 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
22 | #include <linux/init.h> | 21 | #include <linux/init.h> |
23 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
24 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
25 | #include <linux/mc146818rtc.h> | ||
26 | #include <linux/miscdevice.h> | ||
27 | #include <linux/module.h> | 24 | #include <linux/module.h> |
28 | #include <linux/poll.h> | 25 | #include <linux/platform_device.h> |
29 | #include <linux/rtc.h> | 26 | #include <linux/rtc.h> |
30 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
31 | #include <linux/types.h> | 28 | #include <linux/types.h> |
32 | #include <linux/wait.h> | ||
33 | 29 | ||
34 | #include <asm/div64.h> | 30 | #include <asm/div64.h> |
35 | #include <asm/io.h> | 31 | #include <asm/io.h> |
36 | #include <asm/time.h> | ||
37 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
38 | #include <asm/vr41xx/vr41xx.h> | 33 | #include <asm/vr41xx/vr41xx.h> |
39 | 34 | ||
@@ -99,27 +94,11 @@ static void __iomem *rtc2_base; | |||
99 | 94 | ||
100 | static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ | 95 | static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ |
101 | 96 | ||
102 | static spinlock_t rtc_task_lock; | 97 | static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; |
103 | static wait_queue_head_t rtc_wait; | ||
104 | static unsigned long rtc_irq_data; | ||
105 | static struct fasync_struct *rtc_async_queue; | ||
106 | static rtc_task_t *rtc_callback; | ||
107 | static char rtc_name[] = "RTC"; | 98 | static char rtc_name[] = "RTC"; |
108 | static unsigned long periodic_frequency; | 99 | static unsigned long periodic_frequency; |
109 | static unsigned long periodic_count; | 100 | static unsigned long periodic_count; |
110 | 101 | ||
111 | typedef enum { | ||
112 | RTC_RELEASE, | ||
113 | RTC_OPEN, | ||
114 | } rtc_status_t; | ||
115 | |||
116 | static rtc_status_t rtc_status; | ||
117 | |||
118 | typedef enum { | ||
119 | FUNCTION_RTC_IOCTL, | ||
120 | FUNCTION_RTC_CONTROL, | ||
121 | } rtc_callfrom_t; | ||
122 | |||
123 | struct resource rtc_resource[2] = { | 102 | struct resource rtc_resource[2] = { |
124 | { .name = rtc_name, | 103 | { .name = rtc_name, |
125 | .flags = IORESOURCE_MEM, }, | 104 | .flags = IORESOURCE_MEM, }, |
@@ -129,7 +108,9 @@ struct resource rtc_resource[2] = { | |||
129 | 108 | ||
130 | static inline unsigned long read_elapsed_second(void) | 109 | static inline unsigned long read_elapsed_second(void) |
131 | { | 110 | { |
111 | |||
132 | unsigned long first_low, first_mid, first_high; | 112 | unsigned long first_low, first_mid, first_high; |
113 | |||
133 | unsigned long second_low, second_mid, second_high; | 114 | unsigned long second_low, second_mid, second_high; |
134 | 115 | ||
135 | do { | 116 | do { |
@@ -156,50 +137,36 @@ static inline void write_elapsed_second(unsigned long sec) | |||
156 | spin_unlock_irq(&rtc_lock); | 137 | spin_unlock_irq(&rtc_lock); |
157 | } | 138 | } |
158 | 139 | ||
159 | static void set_alarm(struct rtc_time *time) | 140 | static void vr41xx_rtc_release(struct device *dev) |
160 | { | 141 | { |
161 | unsigned long alarm_sec; | ||
162 | |||
163 | alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, | ||
164 | time->tm_hour, time->tm_min, time->tm_sec); | ||
165 | |||
166 | spin_lock_irq(&rtc_lock); | ||
167 | |||
168 | rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); | ||
169 | rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); | ||
170 | rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); | ||
171 | |||
172 | spin_unlock_irq(&rtc_lock); | ||
173 | } | ||
174 | |||
175 | static void read_alarm(struct rtc_time *time) | ||
176 | { | ||
177 | unsigned long low, mid, high; | ||
178 | 142 | ||
179 | spin_lock_irq(&rtc_lock); | 143 | spin_lock_irq(&rtc_lock); |
180 | 144 | ||
181 | low = rtc1_read(ECMPLREG); | 145 | rtc1_write(ECMPLREG, 0); |
182 | mid = rtc1_read(ECMPMREG); | 146 | rtc1_write(ECMPMREG, 0); |
183 | high = rtc1_read(ECMPHREG); | 147 | rtc1_write(ECMPHREG, 0); |
148 | rtc1_write(RTCL1LREG, 0); | ||
149 | rtc1_write(RTCL1HREG, 0); | ||
184 | 150 | ||
185 | spin_unlock_irq(&rtc_lock); | 151 | spin_unlock_irq(&rtc_lock); |
186 | 152 | ||
187 | to_tm((high << 17) | (mid << 1) | (low >> 15), time); | 153 | disable_irq(ELAPSEDTIME_IRQ); |
188 | time->tm_year -= 1900; | 154 | disable_irq(RTCLONG1_IRQ); |
189 | } | 155 | } |
190 | 156 | ||
191 | static void read_time(struct rtc_time *time) | 157 | static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time) |
192 | { | 158 | { |
193 | unsigned long epoch_sec, elapsed_sec; | 159 | unsigned long epoch_sec, elapsed_sec; |
194 | 160 | ||
195 | epoch_sec = mktime(epoch, 1, 1, 0, 0, 0); | 161 | epoch_sec = mktime(epoch, 1, 1, 0, 0, 0); |
196 | elapsed_sec = read_elapsed_second(); | 162 | elapsed_sec = read_elapsed_second(); |
197 | 163 | ||
198 | to_tm(epoch_sec + elapsed_sec, time); | 164 | rtc_time_to_tm(epoch_sec + elapsed_sec, time); |
199 | time->tm_year -= 1900; | 165 | |
166 | return 0; | ||
200 | } | 167 | } |
201 | 168 | ||
202 | static void set_time(struct rtc_time *time) | 169 | static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time) |
203 | { | 170 | { |
204 | unsigned long epoch_sec, current_sec; | 171 | unsigned long epoch_sec, current_sec; |
205 | 172 | ||
@@ -208,73 +175,49 @@ static void set_time(struct rtc_time *time) | |||
208 | time->tm_hour, time->tm_min, time->tm_sec); | 175 | time->tm_hour, time->tm_min, time->tm_sec); |
209 | 176 | ||
210 | write_elapsed_second(current_sec - epoch_sec); | 177 | write_elapsed_second(current_sec - epoch_sec); |
178 | |||
179 | return 0; | ||
211 | } | 180 | } |
212 | 181 | ||
213 | static ssize_t rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | 182 | static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) |
214 | { | 183 | { |
215 | DECLARE_WAITQUEUE(wait, current); | 184 | unsigned long low, mid, high; |
216 | unsigned long irq_data; | 185 | struct rtc_time *time = &wkalrm->time; |
217 | int retval = 0; | ||
218 | |||
219 | if (count != sizeof(unsigned int) && count != sizeof(unsigned long)) | ||
220 | return -EINVAL; | ||
221 | |||
222 | add_wait_queue(&rtc_wait, &wait); | ||
223 | |||
224 | do { | ||
225 | __set_current_state(TASK_INTERRUPTIBLE); | ||
226 | 186 | ||
227 | spin_lock_irq(&rtc_lock); | 187 | spin_lock_irq(&rtc_lock); |
228 | irq_data = rtc_irq_data; | ||
229 | rtc_irq_data = 0; | ||
230 | spin_unlock_irq(&rtc_lock); | ||
231 | 188 | ||
232 | if (irq_data != 0) | 189 | low = rtc1_read(ECMPLREG); |
233 | break; | 190 | mid = rtc1_read(ECMPMREG); |
191 | high = rtc1_read(ECMPHREG); | ||
234 | 192 | ||
235 | if (file->f_flags & O_NONBLOCK) { | 193 | spin_unlock_irq(&rtc_lock); |
236 | retval = -EAGAIN; | ||
237 | break; | ||
238 | } | ||
239 | 194 | ||
240 | if (signal_pending(current)) { | 195 | rtc_time_to_tm((high << 17) | (mid << 1) | (low >> 15), time); |
241 | retval = -ERESTARTSYS; | ||
242 | break; | ||
243 | } | ||
244 | } while (1); | ||
245 | 196 | ||
246 | if (retval == 0) { | 197 | return 0; |
247 | if (count == sizeof(unsigned int)) { | 198 | } |
248 | retval = put_user(irq_data, (unsigned int __user *)buf); | ||
249 | if (retval == 0) | ||
250 | retval = sizeof(unsigned int); | ||
251 | } else { | ||
252 | retval = put_user(irq_data, (unsigned long __user *)buf); | ||
253 | if (retval == 0) | ||
254 | retval = sizeof(unsigned long); | ||
255 | } | ||
256 | 199 | ||
257 | } | 200 | static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) |
201 | { | ||
202 | unsigned long alarm_sec; | ||
203 | struct rtc_time *time = &wkalrm->time; | ||
258 | 204 | ||
259 | __set_current_state(TASK_RUNNING); | 205 | alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, |
260 | remove_wait_queue(&rtc_wait, &wait); | 206 | time->tm_hour, time->tm_min, time->tm_sec); |
261 | 207 | ||
262 | return retval; | 208 | spin_lock_irq(&rtc_lock); |
263 | } | ||
264 | 209 | ||
265 | static unsigned int rtc_poll(struct file *file, struct poll_table_struct *table) | 210 | rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); |
266 | { | 211 | rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); |
267 | poll_wait(file, &rtc_wait, table); | 212 | rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); |
268 | 213 | ||
269 | if (rtc_irq_data != 0) | 214 | spin_unlock_irq(&rtc_lock); |
270 | return POLLIN | POLLRDNORM; | ||
271 | 215 | ||
272 | return 0; | 216 | return 0; |
273 | } | 217 | } |
274 | 218 | ||
275 | static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from) | 219 | static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
276 | { | 220 | { |
277 | struct rtc_time time; | ||
278 | unsigned long count; | 221 | unsigned long count; |
279 | 222 | ||
280 | switch (cmd) { | 223 | switch (cmd) { |
@@ -290,33 +233,6 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from | |||
290 | case RTC_PIE_OFF: | 233 | case RTC_PIE_OFF: |
291 | disable_irq(RTCLONG1_IRQ); | 234 | disable_irq(RTCLONG1_IRQ); |
292 | break; | 235 | break; |
293 | case RTC_ALM_SET: | ||
294 | if (copy_from_user(&time, (struct rtc_time __user *)arg, | ||
295 | sizeof(struct rtc_time))) | ||
296 | return -EFAULT; | ||
297 | |||
298 | set_alarm(&time); | ||
299 | break; | ||
300 | case RTC_ALM_READ: | ||
301 | memset(&time, 0, sizeof(struct rtc_time)); | ||
302 | read_alarm(&time); | ||
303 | break; | ||
304 | case RTC_RD_TIME: | ||
305 | memset(&time, 0, sizeof(struct rtc_time)); | ||
306 | read_time(&time); | ||
307 | if (copy_to_user((void __user *)arg, &time, sizeof(struct rtc_time))) | ||
308 | return -EFAULT; | ||
309 | break; | ||
310 | case RTC_SET_TIME: | ||
311 | if (capable(CAP_SYS_TIME) == 0) | ||
312 | return -EACCES; | ||
313 | |||
314 | if (copy_from_user(&time, (struct rtc_time __user *)arg, | ||
315 | sizeof(struct rtc_time))) | ||
316 | return -EFAULT; | ||
317 | |||
318 | set_time(&time); | ||
319 | break; | ||
320 | case RTC_IRQP_READ: | 236 | case RTC_IRQP_READ: |
321 | return put_user(periodic_frequency, (unsigned long __user *)arg); | 237 | return put_user(periodic_frequency, (unsigned long __user *)arg); |
322 | break; | 238 | break; |
@@ -324,8 +240,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from | |||
324 | if (arg > MAX_PERIODIC_RATE) | 240 | if (arg > MAX_PERIODIC_RATE) |
325 | return -EINVAL; | 241 | return -EINVAL; |
326 | 242 | ||
327 | if (from == FUNCTION_RTC_IOCTL && arg > MAX_USER_PERIODIC_RATE && | 243 | if (arg > MAX_USER_PERIODIC_RATE && capable(CAP_SYS_RESOURCE) == 0) |
328 | capable(CAP_SYS_RESOURCE) == 0) | ||
329 | return -EACCES; | 244 | return -EACCES; |
330 | 245 | ||
331 | periodic_frequency = arg; | 246 | periodic_frequency = arg; |
@@ -361,205 +276,46 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from | |||
361 | return 0; | 276 | return 0; |
362 | } | 277 | } |
363 | 278 | ||
364 | static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
365 | unsigned long arg) | ||
366 | { | ||
367 | return rtc_do_ioctl(cmd, arg, FUNCTION_RTC_IOCTL); | ||
368 | } | ||
369 | |||
370 | static int rtc_open(struct inode *inode, struct file *file) | ||
371 | { | ||
372 | spin_lock_irq(&rtc_lock); | ||
373 | |||
374 | if (rtc_status == RTC_OPEN) { | ||
375 | spin_unlock_irq(&rtc_lock); | ||
376 | return -EBUSY; | ||
377 | } | ||
378 | |||
379 | rtc_status = RTC_OPEN; | ||
380 | rtc_irq_data = 0; | ||
381 | |||
382 | spin_unlock_irq(&rtc_lock); | ||
383 | |||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static int rtc_release(struct inode *inode, struct file *file) | ||
388 | { | ||
389 | if (file->f_flags & FASYNC) | ||
390 | (void)fasync_helper(-1, file, 0, &rtc_async_queue); | ||
391 | |||
392 | spin_lock_irq(&rtc_lock); | ||
393 | |||
394 | rtc1_write(ECMPLREG, 0); | ||
395 | rtc1_write(ECMPMREG, 0); | ||
396 | rtc1_write(ECMPHREG, 0); | ||
397 | rtc1_write(RTCL1LREG, 0); | ||
398 | rtc1_write(RTCL1HREG, 0); | ||
399 | |||
400 | rtc_status = RTC_RELEASE; | ||
401 | |||
402 | spin_unlock_irq(&rtc_lock); | ||
403 | |||
404 | disable_irq(ELAPSEDTIME_IRQ); | ||
405 | disable_irq(RTCLONG1_IRQ); | ||
406 | |||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | static int rtc_fasync(int fd, struct file *file, int on) | ||
411 | { | ||
412 | return fasync_helper(fd, file, on, &rtc_async_queue); | ||
413 | } | ||
414 | |||
415 | static struct file_operations rtc_fops = { | ||
416 | .owner = THIS_MODULE, | ||
417 | .llseek = no_llseek, | ||
418 | .read = rtc_read, | ||
419 | .poll = rtc_poll, | ||
420 | .ioctl = rtc_ioctl, | ||
421 | .open = rtc_open, | ||
422 | .release = rtc_release, | ||
423 | .fasync = rtc_fasync, | ||
424 | }; | ||
425 | |||
426 | static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 279 | static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
427 | { | 280 | { |
428 | spin_lock(&rtc_lock); | 281 | struct platform_device *pdev = (struct platform_device *)dev_id; |
429 | rtc2_write(RTCINTREG, ELAPSEDTIME_INT); | 282 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
430 | |||
431 | rtc_irq_data += 0x100; | ||
432 | rtc_irq_data &= ~0xff; | ||
433 | rtc_irq_data |= RTC_AF; | ||
434 | spin_unlock(&rtc_lock); | ||
435 | 283 | ||
436 | spin_lock(&rtc_lock); | 284 | rtc2_write(RTCINTREG, ELAPSEDTIME_INT); |
437 | if (rtc_callback) | ||
438 | rtc_callback->func(rtc_callback->private_data); | ||
439 | spin_unlock(&rtc_lock); | ||
440 | |||
441 | wake_up_interruptible(&rtc_wait); | ||
442 | 285 | ||
443 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); | 286 | rtc_update_irq(&rtc->class_dev, 1, RTC_AF); |
444 | 287 | ||
445 | return IRQ_HANDLED; | 288 | return IRQ_HANDLED; |
446 | } | 289 | } |
447 | 290 | ||
448 | static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 291 | static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
449 | { | 292 | { |
293 | struct platform_device *pdev = (struct platform_device *)dev_id; | ||
294 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
450 | unsigned long count = periodic_count; | 295 | unsigned long count = periodic_count; |
451 | 296 | ||
452 | spin_lock(&rtc_lock); | ||
453 | rtc2_write(RTCINTREG, RTCLONG1_INT); | 297 | rtc2_write(RTCINTREG, RTCLONG1_INT); |
454 | 298 | ||
455 | rtc1_write(RTCL1LREG, count); | 299 | rtc1_write(RTCL1LREG, count); |
456 | rtc1_write(RTCL1HREG, count >> 16); | 300 | rtc1_write(RTCL1HREG, count >> 16); |
457 | 301 | ||
458 | rtc_irq_data += 0x100; | 302 | rtc_update_irq(&rtc->class_dev, 1, RTC_PF); |
459 | rtc_irq_data &= ~0xff; | ||
460 | rtc_irq_data |= RTC_PF; | ||
461 | spin_unlock(&rtc_lock); | ||
462 | |||
463 | spin_lock(&rtc_task_lock); | ||
464 | if (rtc_callback) | ||
465 | rtc_callback->func(rtc_callback->private_data); | ||
466 | spin_unlock(&rtc_task_lock); | ||
467 | |||
468 | wake_up_interruptible(&rtc_wait); | ||
469 | |||
470 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); | ||
471 | 303 | ||
472 | return IRQ_HANDLED; | 304 | return IRQ_HANDLED; |
473 | } | 305 | } |
474 | 306 | ||
475 | int rtc_register(rtc_task_t *task) | 307 | static struct rtc_class_ops vr41xx_rtc_ops = { |
476 | { | 308 | .release = vr41xx_rtc_release, |
477 | if (task == NULL || task->func == NULL) | 309 | .ioctl = vr41xx_rtc_ioctl, |
478 | return -EINVAL; | 310 | .read_time = vr41xx_rtc_read_time, |
479 | 311 | .set_time = vr41xx_rtc_set_time, | |
480 | spin_lock_irq(&rtc_lock); | 312 | .read_alarm = vr41xx_rtc_read_alarm, |
481 | if (rtc_status == RTC_OPEN) { | 313 | .set_alarm = vr41xx_rtc_set_alarm, |
482 | spin_unlock_irq(&rtc_lock); | ||
483 | return -EBUSY; | ||
484 | } | ||
485 | |||
486 | spin_lock(&rtc_task_lock); | ||
487 | if (rtc_callback != NULL) { | ||
488 | spin_unlock(&rtc_task_lock); | ||
489 | spin_unlock_irq(&rtc_task_lock); | ||
490 | return -EBUSY; | ||
491 | } | ||
492 | |||
493 | rtc_callback = task; | ||
494 | spin_unlock(&rtc_task_lock); | ||
495 | |||
496 | rtc_status = RTC_OPEN; | ||
497 | |||
498 | spin_unlock_irq(&rtc_lock); | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | EXPORT_SYMBOL_GPL(rtc_register); | ||
504 | |||
505 | int rtc_unregister(rtc_task_t *task) | ||
506 | { | ||
507 | spin_lock_irq(&rtc_task_lock); | ||
508 | if (task == NULL || rtc_callback != task) { | ||
509 | spin_unlock_irq(&rtc_task_lock); | ||
510 | return -ENXIO; | ||
511 | } | ||
512 | |||
513 | spin_lock(&rtc_lock); | ||
514 | |||
515 | rtc1_write(ECMPLREG, 0); | ||
516 | rtc1_write(ECMPMREG, 0); | ||
517 | rtc1_write(ECMPHREG, 0); | ||
518 | rtc1_write(RTCL1LREG, 0); | ||
519 | rtc1_write(RTCL1HREG, 0); | ||
520 | |||
521 | rtc_status = RTC_RELEASE; | ||
522 | |||
523 | spin_unlock(&rtc_lock); | ||
524 | |||
525 | rtc_callback = NULL; | ||
526 | |||
527 | spin_unlock_irq(&rtc_task_lock); | ||
528 | |||
529 | disable_irq(ELAPSEDTIME_IRQ); | ||
530 | disable_irq(RTCLONG1_IRQ); | ||
531 | |||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | EXPORT_SYMBOL_GPL(rtc_unregister); | ||
536 | |||
537 | int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) | ||
538 | { | ||
539 | int retval = 0; | ||
540 | |||
541 | spin_lock_irq(&rtc_task_lock); | ||
542 | |||
543 | if (rtc_callback != task) | ||
544 | retval = -ENXIO; | ||
545 | else | ||
546 | rtc_do_ioctl(cmd, arg, FUNCTION_RTC_CONTROL); | ||
547 | |||
548 | spin_unlock_irq(&rtc_task_lock); | ||
549 | |||
550 | return retval; | ||
551 | } | ||
552 | |||
553 | EXPORT_SYMBOL_GPL(rtc_control); | ||
554 | |||
555 | static struct miscdevice rtc_miscdevice = { | ||
556 | .minor = RTC_MINOR, | ||
557 | .name = rtc_name, | ||
558 | .fops = &rtc_fops, | ||
559 | }; | 314 | }; |
560 | 315 | ||
561 | static int __devinit rtc_probe(struct platform_device *pdev) | 316 | static int __devinit rtc_probe(struct platform_device *pdev) |
562 | { | 317 | { |
318 | struct rtc_device *rtc; | ||
563 | unsigned int irq; | 319 | unsigned int irq; |
564 | int retval; | 320 | int retval; |
565 | 321 | ||
@@ -577,13 +333,13 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
577 | return -EBUSY; | 333 | return -EBUSY; |
578 | } | 334 | } |
579 | 335 | ||
580 | retval = misc_register(&rtc_miscdevice); | 336 | rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE); |
581 | if (retval < 0) { | 337 | if (IS_ERR(rtc)) { |
582 | iounmap(rtc1_base); | 338 | iounmap(rtc1_base); |
583 | iounmap(rtc2_base); | 339 | iounmap(rtc2_base); |
584 | rtc1_base = NULL; | 340 | rtc1_base = NULL; |
585 | rtc2_base = NULL; | 341 | rtc2_base = NULL; |
586 | return retval; | 342 | return PTR_ERR(rtc); |
587 | } | 343 | } |
588 | 344 | ||
589 | spin_lock_irq(&rtc_lock); | 345 | spin_lock_irq(&rtc_lock); |
@@ -594,24 +350,20 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
594 | rtc1_write(RTCL1LREG, 0); | 350 | rtc1_write(RTCL1LREG, 0); |
595 | rtc1_write(RTCL1HREG, 0); | 351 | rtc1_write(RTCL1HREG, 0); |
596 | 352 | ||
597 | rtc_status = RTC_RELEASE; | ||
598 | rtc_irq_data = 0; | ||
599 | |||
600 | spin_unlock_irq(&rtc_lock); | 353 | spin_unlock_irq(&rtc_lock); |
601 | 354 | ||
602 | init_waitqueue_head(&rtc_wait); | ||
603 | |||
604 | irq = ELAPSEDTIME_IRQ; | 355 | irq = ELAPSEDTIME_IRQ; |
605 | retval = request_irq(irq, elapsedtime_interrupt, SA_INTERRUPT, | 356 | retval = request_irq(irq, elapsedtime_interrupt, SA_INTERRUPT, |
606 | "elapsed_time", NULL); | 357 | "elapsed_time", pdev); |
607 | if (retval == 0) { | 358 | if (retval == 0) { |
608 | irq = RTCLONG1_IRQ; | 359 | irq = RTCLONG1_IRQ; |
609 | retval = request_irq(irq, rtclong1_interrupt, SA_INTERRUPT, | 360 | retval = request_irq(irq, rtclong1_interrupt, SA_INTERRUPT, |
610 | "rtclong1", NULL); | 361 | "rtclong1", pdev); |
611 | } | 362 | } |
612 | 363 | ||
613 | if (retval < 0) { | 364 | if (retval < 0) { |
614 | printk(KERN_ERR "rtc: IRQ%d is busy\n", irq); | 365 | printk(KERN_ERR "rtc: IRQ%d is busy\n", irq); |
366 | rtc_device_unregister(rtc); | ||
615 | if (irq == RTCLONG1_IRQ) | 367 | if (irq == RTCLONG1_IRQ) |
616 | free_irq(ELAPSEDTIME_IRQ, NULL); | 368 | free_irq(ELAPSEDTIME_IRQ, NULL); |
617 | iounmap(rtc1_base); | 369 | iounmap(rtc1_base); |
@@ -621,23 +373,25 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
621 | return retval; | 373 | return retval; |
622 | } | 374 | } |
623 | 375 | ||
376 | platform_set_drvdata(pdev, rtc); | ||
377 | |||
624 | disable_irq(ELAPSEDTIME_IRQ); | 378 | disable_irq(ELAPSEDTIME_IRQ); |
625 | disable_irq(RTCLONG1_IRQ); | 379 | disable_irq(RTCLONG1_IRQ); |
626 | 380 | ||
627 | spin_lock_init(&rtc_task_lock); | ||
628 | |||
629 | printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n"); | 381 | printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n"); |
630 | 382 | ||
631 | return 0; | 383 | return 0; |
632 | } | 384 | } |
633 | 385 | ||
634 | static int __devexit rtc_remove(struct platform_device *dev) | 386 | static int __devexit rtc_remove(struct platform_device *pdev) |
635 | { | 387 | { |
636 | int retval; | 388 | struct rtc_device *rtc; |
637 | 389 | ||
638 | retval = misc_deregister(&rtc_miscdevice); | 390 | rtc = platform_get_drvdata(pdev); |
639 | if (retval < 0) | 391 | if (rtc != NULL) |
640 | return retval; | 392 | rtc_device_unregister(rtc); |
393 | |||
394 | platform_set_drvdata(pdev, NULL); | ||
641 | 395 | ||
642 | free_irq(ELAPSEDTIME_IRQ, NULL); | 396 | free_irq(ELAPSEDTIME_IRQ, NULL); |
643 | free_irq(RTCLONG1_IRQ, NULL); | 397 | free_irq(RTCLONG1_IRQ, NULL); |
@@ -651,7 +405,7 @@ static int __devexit rtc_remove(struct platform_device *dev) | |||
651 | 405 | ||
652 | static struct platform_device *rtc_platform_device; | 406 | static struct platform_device *rtc_platform_device; |
653 | 407 | ||
654 | static struct platform_driver rtc_device_driver = { | 408 | static struct platform_driver rtc_platform_driver = { |
655 | .probe = rtc_probe, | 409 | .probe = rtc_probe, |
656 | .remove = __devexit_p(rtc_remove), | 410 | .remove = __devexit_p(rtc_remove), |
657 | .driver = { | 411 | .driver = { |
@@ -686,7 +440,7 @@ static int __init vr41xx_rtc_init(void) | |||
686 | } | 440 | } |
687 | 441 | ||
688 | rtc_platform_device = platform_device_alloc("RTC", -1); | 442 | rtc_platform_device = platform_device_alloc("RTC", -1); |
689 | if (!rtc_platform_device) | 443 | if (rtc_platform_device == NULL) |
690 | return -ENOMEM; | 444 | return -ENOMEM; |
691 | 445 | ||
692 | retval = platform_device_add_resources(rtc_platform_device, | 446 | retval = platform_device_add_resources(rtc_platform_device, |
@@ -700,7 +454,7 @@ static int __init vr41xx_rtc_init(void) | |||
700 | return retval; | 454 | return retval; |
701 | } | 455 | } |
702 | 456 | ||
703 | retval = platform_driver_register(&rtc_device_driver); | 457 | retval = platform_driver_register(&rtc_platform_driver); |
704 | if (retval < 0) | 458 | if (retval < 0) |
705 | platform_device_unregister(rtc_platform_device); | 459 | platform_device_unregister(rtc_platform_device); |
706 | 460 | ||
@@ -709,7 +463,7 @@ static int __init vr41xx_rtc_init(void) | |||
709 | 463 | ||
710 | static void __exit vr41xx_rtc_exit(void) | 464 | static void __exit vr41xx_rtc_exit(void) |
711 | { | 465 | { |
712 | platform_driver_unregister(&rtc_device_driver); | 466 | platform_driver_unregister(&rtc_platform_driver); |
713 | platform_device_unregister(rtc_platform_device); | 467 | platform_device_unregister(rtc_platform_device); |
714 | } | 468 | } |
715 | 469 | ||
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 621d17afc0d9..788b6d1f8f2f 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/rtc.h> | 19 | #include <linux/rtc.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | 21 | ||
22 | #define DRV_VERSION "1.0.6" | 22 | #define DRV_VERSION "1.0.7" |
23 | 23 | ||
24 | /* Addresses to scan: none. This chip is located at | 24 | /* Addresses to scan: none. This chip is located at |
25 | * 0x6f and uses a two bytes register addressing. | 25 | * 0x6f and uses a two bytes register addressing. |
@@ -451,8 +451,6 @@ static int x1205_rtc_proc(struct device *dev, struct seq_file *seq) | |||
451 | { | 451 | { |
452 | int err, dtrim, atrim; | 452 | int err, dtrim, atrim; |
453 | 453 | ||
454 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
455 | |||
456 | if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0) | 454 | if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0) |
457 | seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim); | 455 | seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim); |
458 | 456 | ||
@@ -473,30 +471,31 @@ static struct rtc_class_ops x1205_rtc_ops = { | |||
473 | static ssize_t x1205_sysfs_show_atrim(struct device *dev, | 471 | static ssize_t x1205_sysfs_show_atrim(struct device *dev, |
474 | struct device_attribute *attr, char *buf) | 472 | struct device_attribute *attr, char *buf) |
475 | { | 473 | { |
476 | int atrim; | 474 | int err, atrim; |
477 | 475 | ||
478 | if (x1205_get_atrim(to_i2c_client(dev), &atrim) == 0) | 476 | err = x1205_get_atrim(to_i2c_client(dev), &atrim); |
479 | return sprintf(buf, "%d.%02d pF\n", | 477 | if (err) |
480 | atrim / 1000, atrim % 1000); | 478 | return err; |
481 | return 0; | 479 | |
480 | return sprintf(buf, "%d.%02d pF\n", atrim / 1000, atrim % 1000); | ||
482 | } | 481 | } |
483 | static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL); | 482 | static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL); |
484 | 483 | ||
485 | static ssize_t x1205_sysfs_show_dtrim(struct device *dev, | 484 | static ssize_t x1205_sysfs_show_dtrim(struct device *dev, |
486 | struct device_attribute *attr, char *buf) | 485 | struct device_attribute *attr, char *buf) |
487 | { | 486 | { |
488 | int dtrim; | 487 | int err, dtrim; |
489 | 488 | ||
490 | if (x1205_get_dtrim(to_i2c_client(dev), &dtrim) == 0) | 489 | err = x1205_get_dtrim(to_i2c_client(dev), &dtrim); |
491 | return sprintf(buf, "%d ppm\n", dtrim); | 490 | if (err) |
491 | return err; | ||
492 | 492 | ||
493 | return 0; | 493 | return sprintf(buf, "%d ppm\n", dtrim); |
494 | } | 494 | } |
495 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); | 495 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); |
496 | 496 | ||
497 | static int x1205_attach(struct i2c_adapter *adapter) | 497 | static int x1205_attach(struct i2c_adapter *adapter) |
498 | { | 498 | { |
499 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | ||
500 | return i2c_probe(adapter, &addr_data, x1205_probe); | 499 | return i2c_probe(adapter, &addr_data, x1205_probe); |
501 | } | 500 | } |
502 | 501 | ||
@@ -545,8 +544,6 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) | |||
545 | 544 | ||
546 | if (IS_ERR(rtc)) { | 545 | if (IS_ERR(rtc)) { |
547 | err = PTR_ERR(rtc); | 546 | err = PTR_ERR(rtc); |
548 | dev_err(&client->dev, | ||
549 | "unable to register the class device\n"); | ||
550 | goto exit_detach; | 547 | goto exit_detach; |
551 | } | 548 | } |
552 | 549 | ||
@@ -585,8 +582,6 @@ static int x1205_detach(struct i2c_client *client) | |||
585 | int err; | 582 | int err; |
586 | struct rtc_device *rtc = i2c_get_clientdata(client); | 583 | struct rtc_device *rtc = i2c_get_clientdata(client); |
587 | 584 | ||
588 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
589 | |||
590 | if (rtc) | 585 | if (rtc) |
591 | rtc_device_unregister(rtc); | 586 | rtc_device_unregister(rtc); |
592 | 587 | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 0a9f12c4e911..a3bfebcf31ef 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -1257,25 +1257,28 @@ __dasd_start_head(struct dasd_device * device) | |||
1257 | if (list_empty(&device->ccw_queue)) | 1257 | if (list_empty(&device->ccw_queue)) |
1258 | return; | 1258 | return; |
1259 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1259 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); |
1260 | /* check FAILFAST */ | 1260 | if (cqr->status != DASD_CQR_QUEUED) |
1261 | return; | ||
1262 | /* Non-temporary stop condition will trigger fail fast */ | ||
1261 | if (device->stopped & ~DASD_STOPPED_PENDING && | 1263 | if (device->stopped & ~DASD_STOPPED_PENDING && |
1262 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && | 1264 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && |
1263 | (!dasd_eer_enabled(device))) { | 1265 | (!dasd_eer_enabled(device))) { |
1264 | cqr->status = DASD_CQR_FAILED; | 1266 | cqr->status = DASD_CQR_FAILED; |
1265 | dasd_schedule_bh(device); | 1267 | dasd_schedule_bh(device); |
1268 | return; | ||
1266 | } | 1269 | } |
1267 | if ((cqr->status == DASD_CQR_QUEUED) && | 1270 | /* Don't try to start requests if device is stopped */ |
1268 | (!device->stopped)) { | 1271 | if (device->stopped) |
1269 | /* try to start the first I/O that can be started */ | 1272 | return; |
1270 | rc = device->discipline->start_IO(cqr); | 1273 | |
1271 | if (rc == 0) | 1274 | rc = device->discipline->start_IO(cqr); |
1272 | dasd_set_timer(device, cqr->expires); | 1275 | if (rc == 0) |
1273 | else if (rc == -EACCES) { | 1276 | dasd_set_timer(device, cqr->expires); |
1274 | dasd_schedule_bh(device); | 1277 | else if (rc == -EACCES) { |
1275 | } else | 1278 | dasd_schedule_bh(device); |
1276 | /* Hmpf, try again in 1/2 sec */ | 1279 | } else |
1277 | dasd_set_timer(device, 50); | 1280 | /* Hmpf, try again in 1/2 sec */ |
1278 | } | 1281 | dasd_set_timer(device, 50); |
1279 | } | 1282 | } |
1280 | 1283 | ||
1281 | /* | 1284 | /* |
@@ -1968,7 +1971,7 @@ int | |||
1968 | dasd_generic_set_offline (struct ccw_device *cdev) | 1971 | dasd_generic_set_offline (struct ccw_device *cdev) |
1969 | { | 1972 | { |
1970 | struct dasd_device *device; | 1973 | struct dasd_device *device; |
1971 | int max_count; | 1974 | int max_count, open_count; |
1972 | 1975 | ||
1973 | device = dasd_device_from_cdev(cdev); | 1976 | device = dasd_device_from_cdev(cdev); |
1974 | if (IS_ERR(device)) | 1977 | if (IS_ERR(device)) |
@@ -1985,10 +1988,16 @@ dasd_generic_set_offline (struct ccw_device *cdev) | |||
1985 | * in the other openers. | 1988 | * in the other openers. |
1986 | */ | 1989 | */ |
1987 | max_count = device->bdev ? 0 : -1; | 1990 | max_count = device->bdev ? 0 : -1; |
1988 | if (atomic_read(&device->open_count) > max_count) { | 1991 | open_count = (int) atomic_read(&device->open_count); |
1989 | printk (KERN_WARNING "Can't offline dasd device with open" | 1992 | if (open_count > max_count) { |
1990 | " count = %i.\n", | 1993 | if (open_count > 0) |
1991 | atomic_read(&device->open_count)); | 1994 | printk (KERN_WARNING "Can't offline dasd device with " |
1995 | "open count = %i.\n", | ||
1996 | open_count); | ||
1997 | else | ||
1998 | printk (KERN_WARNING "%s", | ||
1999 | "Can't offline dasd device due to internal " | ||
2000 | "use\n"); | ||
1992 | clear_bit(DASD_FLAG_OFFLINE, &device->flags); | 2001 | clear_bit(DASD_FLAG_OFFLINE, &device->flags); |
1993 | dasd_put_device(device); | 2002 | dasd_put_device(device); |
1994 | return -EBUSY; | 2003 | return -EBUSY; |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 1aa3c261718a..ad23aede356c 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -294,23 +294,40 @@ out_error: | |||
294 | #endif /* CONFIG_DASD_PROFILE */ | 294 | #endif /* CONFIG_DASD_PROFILE */ |
295 | } | 295 | } |
296 | 296 | ||
297 | /* | ||
298 | * Create dasd proc-fs entries. | ||
299 | * In case creation failed, cleanup and return -ENOENT. | ||
300 | */ | ||
297 | int | 301 | int |
298 | dasd_proc_init(void) | 302 | dasd_proc_init(void) |
299 | { | 303 | { |
300 | dasd_proc_root_entry = proc_mkdir("dasd", &proc_root); | 304 | dasd_proc_root_entry = proc_mkdir("dasd", &proc_root); |
305 | if (!dasd_proc_root_entry) | ||
306 | goto out_nodasd; | ||
301 | dasd_proc_root_entry->owner = THIS_MODULE; | 307 | dasd_proc_root_entry->owner = THIS_MODULE; |
302 | dasd_devices_entry = create_proc_entry("devices", | 308 | dasd_devices_entry = create_proc_entry("devices", |
303 | S_IFREG | S_IRUGO | S_IWUSR, | 309 | S_IFREG | S_IRUGO | S_IWUSR, |
304 | dasd_proc_root_entry); | 310 | dasd_proc_root_entry); |
311 | if (!dasd_devices_entry) | ||
312 | goto out_nodevices; | ||
305 | dasd_devices_entry->proc_fops = &dasd_devices_file_ops; | 313 | dasd_devices_entry->proc_fops = &dasd_devices_file_ops; |
306 | dasd_devices_entry->owner = THIS_MODULE; | 314 | dasd_devices_entry->owner = THIS_MODULE; |
307 | dasd_statistics_entry = create_proc_entry("statistics", | 315 | dasd_statistics_entry = create_proc_entry("statistics", |
308 | S_IFREG | S_IRUGO | S_IWUSR, | 316 | S_IFREG | S_IRUGO | S_IWUSR, |
309 | dasd_proc_root_entry); | 317 | dasd_proc_root_entry); |
318 | if (!dasd_statistics_entry) | ||
319 | goto out_nostatistics; | ||
310 | dasd_statistics_entry->read_proc = dasd_statistics_read; | 320 | dasd_statistics_entry->read_proc = dasd_statistics_read; |
311 | dasd_statistics_entry->write_proc = dasd_statistics_write; | 321 | dasd_statistics_entry->write_proc = dasd_statistics_write; |
312 | dasd_statistics_entry->owner = THIS_MODULE; | 322 | dasd_statistics_entry->owner = THIS_MODULE; |
313 | return 0; | 323 | return 0; |
324 | |||
325 | out_nostatistics: | ||
326 | remove_proc_entry("devices", dasd_proc_root_entry); | ||
327 | out_nodevices: | ||
328 | remove_proc_entry("dasd", &proc_root); | ||
329 | out_nodasd: | ||
330 | return -ENOENT; | ||
314 | } | 331 | } |
315 | 332 | ||
316 | void | 333 | void |
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 6badd8403409..d4d2ff0a9da2 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c | |||
@@ -54,7 +54,7 @@ kbd_alloc(void) { | |||
54 | if (!kbd) | 54 | if (!kbd) |
55 | goto out; | 55 | goto out; |
56 | kbd->key_maps = kzalloc(sizeof(key_maps), GFP_KERNEL); | 56 | kbd->key_maps = kzalloc(sizeof(key_maps), GFP_KERNEL); |
57 | if (!key_maps) | 57 | if (!kbd->key_maps) |
58 | goto out_kbd; | 58 | goto out_kbd; |
59 | for (i = 0; i < ARRAY_SIZE(key_maps); i++) { | 59 | for (i = 0; i < ARRAY_SIZE(key_maps); i++) { |
60 | if (key_maps[i]) { | 60 | if (key_maps[i]) { |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 5c65cf3e5cc0..b70d92690242 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -432,8 +432,8 @@ tapeblock_ioctl( | |||
432 | ) { | 432 | ) { |
433 | int rc; | 433 | int rc; |
434 | int minor; | 434 | int minor; |
435 | struct gendisk *disk = inode->i_bdev->bd_disk; | 435 | struct gendisk *disk; |
436 | struct tape_device *device = disk->private_data; | 436 | struct tape_device *device; |
437 | 437 | ||
438 | rc = 0; | 438 | rc = 0; |
439 | disk = inode->i_bdev->bd_disk; | 439 | disk = inode->i_bdev->bd_disk; |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 389ee2c0f443..e6e4086d3224 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -210,18 +210,14 @@ tape_state_set(struct tape_device *device, enum tape_state newstate) | |||
210 | return; | 210 | return; |
211 | } | 211 | } |
212 | DBF_EVENT(4, "ts. dev: %x\n", device->first_minor); | 212 | DBF_EVENT(4, "ts. dev: %x\n", device->first_minor); |
213 | if (device->tape_state < TO_SIZE && device->tape_state >= 0) | 213 | DBF_EVENT(4, "old ts:\t\n"); |
214 | str = tape_state_verbose[device->tape_state]; | 214 | if (device->tape_state < TS_SIZE && device->tape_state >=0 ) |
215 | else | ||
216 | str = "UNKNOWN TS"; | ||
217 | DBF_EVENT(4, "old ts: %s\n", str); | ||
218 | if (device->tape_state < TO_SIZE && device->tape_state >=0 ) | ||
219 | str = tape_state_verbose[device->tape_state]; | 215 | str = tape_state_verbose[device->tape_state]; |
220 | else | 216 | else |
221 | str = "UNKNOWN TS"; | 217 | str = "UNKNOWN TS"; |
222 | DBF_EVENT(4, "%s\n", str); | 218 | DBF_EVENT(4, "%s\n", str); |
223 | DBF_EVENT(4, "new ts:\t\n"); | 219 | DBF_EVENT(4, "new ts:\t\n"); |
224 | if (newstate < TO_SIZE && newstate >= 0) | 220 | if (newstate < TS_SIZE && newstate >= 0) |
225 | str = tape_state_verbose[newstate]; | 221 | str = tape_state_verbose[newstate]; |
226 | else | 222 | else |
227 | str = "UNKNOWN TS"; | 223 | str = "UNKNOWN TS"; |
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index cb8e2e672b68..0960bef7b199 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c | |||
@@ -414,11 +414,11 @@ cio_ignore_proc_init (void) | |||
414 | entry = create_proc_entry ("cio_ignore", S_IFREG | S_IRUGO | S_IWUSR, | 414 | entry = create_proc_entry ("cio_ignore", S_IFREG | S_IRUGO | S_IWUSR, |
415 | &proc_root); | 415 | &proc_root); |
416 | if (!entry) | 416 | if (!entry) |
417 | return 0; | 417 | return -ENOENT; |
418 | 418 | ||
419 | entry->proc_fops = &cio_ignore_proc_fops; | 419 | entry->proc_fops = &cio_ignore_proc_fops; |
420 | 420 | ||
421 | return 1; | 421 | return 0; |
422 | } | 422 | } |
423 | 423 | ||
424 | __initcall (cio_ignore_proc_init); | 424 | __initcall (cio_ignore_proc_init); |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index cbb86fa5f293..5b20d8c9c025 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -67,7 +67,7 @@ cio_debug_init (void) | |||
67 | goto out_unregister; | 67 | goto out_unregister; |
68 | debug_register_view (cio_debug_msg_id, &debug_sprintf_view); | 68 | debug_register_view (cio_debug_msg_id, &debug_sprintf_view); |
69 | debug_set_level (cio_debug_msg_id, 2); | 69 | debug_set_level (cio_debug_msg_id, 2); |
70 | cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 8); | 70 | cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 16); |
71 | if (!cio_debug_trace_id) | 71 | if (!cio_debug_trace_id) |
72 | goto out_unregister; | 72 | goto out_unregister; |
73 | debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); | 73 | debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); |
diff --git a/drivers/s390/cio/cio_debug.h b/drivers/s390/cio/cio_debug.h index 6af8b27d366b..f88844adae1b 100644 --- a/drivers/s390/cio/cio_debug.h +++ b/drivers/s390/cio/cio_debug.h | |||
@@ -3,6 +3,11 @@ | |||
3 | 3 | ||
4 | #include <asm/debug.h> | 4 | #include <asm/debug.h> |
5 | 5 | ||
6 | /* for use of debug feature */ | ||
7 | extern debug_info_t *cio_debug_msg_id; | ||
8 | extern debug_info_t *cio_debug_trace_id; | ||
9 | extern debug_info_t *cio_debug_crw_id; | ||
10 | |||
6 | #define CIO_TRACE_EVENT(imp, txt) do { \ | 11 | #define CIO_TRACE_EVENT(imp, txt) do { \ |
7 | debug_text_event(cio_debug_trace_id, imp, txt); \ | 12 | debug_text_event(cio_debug_trace_id, imp, txt); \ |
8 | } while (0) | 13 | } while (0) |
@@ -15,18 +20,19 @@ | |||
15 | debug_sprintf_event(cio_debug_crw_id, imp , ##args); \ | 20 | debug_sprintf_event(cio_debug_crw_id, imp , ##args); \ |
16 | } while (0) | 21 | } while (0) |
17 | 22 | ||
18 | #define CIO_HEX_EVENT(imp, args...) do { \ | 23 | static inline void |
19 | debug_event(cio_debug_trace_id, imp, ##args); \ | 24 | CIO_HEX_EVENT(int level, void *data, int length) |
20 | } while (0) | 25 | { |
26 | while (length > 0) { | ||
27 | debug_event(cio_debug_trace_id, level, data, length); | ||
28 | length -= cio_debug_trace_id->buf_size; | ||
29 | data += cio_debug_trace_id->buf_size; | ||
30 | } | ||
31 | } | ||
21 | 32 | ||
22 | #define CIO_DEBUG(printk_level,event_level,msg...) ({ \ | 33 | #define CIO_DEBUG(printk_level,event_level,msg...) ({ \ |
23 | if (cio_show_msg) printk(printk_level msg); \ | 34 | if (cio_show_msg) printk(printk_level msg); \ |
24 | CIO_MSG_EVENT (event_level, msg); \ | 35 | CIO_MSG_EVENT (event_level, msg); \ |
25 | }) | 36 | }) |
26 | 37 | ||
27 | /* for use of debug feature */ | ||
28 | extern debug_info_t *cio_debug_msg_id; | ||
29 | extern debug_info_t *cio_debug_trace_id; | ||
30 | extern debug_info_t *cio_debug_crw_id; | ||
31 | |||
32 | #endif | 38 | #endif |
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 25f678d0780b..e8e41e6eb42a 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c | |||
@@ -1508,10 +1508,12 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id, | |||
1508 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; | 1508 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; |
1509 | void *buf; | 1509 | void *buf; |
1510 | unsigned int transfer_len; | 1510 | unsigned int transfer_len; |
1511 | unsigned long flags = 0; | ||
1511 | 1512 | ||
1512 | if (cmd->use_sg) { | 1513 | if (cmd->use_sg) { |
1513 | struct scatterlist *sg = | 1514 | struct scatterlist *sg = |
1514 | (struct scatterlist *)cmd->request_buffer; | 1515 | (struct scatterlist *)cmd->request_buffer; |
1516 | local_irq_save(flags); | ||
1515 | buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; | 1517 | buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; |
1516 | transfer_len = min(sg->length, len); | 1518 | transfer_len = min(sg->length, len); |
1517 | } else { | 1519 | } else { |
@@ -1526,6 +1528,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id, | |||
1526 | 1528 | ||
1527 | sg = (struct scatterlist *)cmd->request_buffer; | 1529 | sg = (struct scatterlist *)cmd->request_buffer; |
1528 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | 1530 | kunmap_atomic(buf - sg->offset, KM_IRQ0); |
1531 | local_irq_restore(flags); | ||
1529 | } | 1532 | } |
1530 | } | 1533 | } |
1531 | 1534 | ||
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index ff48066d4c4f..20fc0846e0be 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -207,7 +207,6 @@ static struct scsi_host_template ahci_sht = { | |||
207 | .name = DRV_NAME, | 207 | .name = DRV_NAME, |
208 | .ioctl = ata_scsi_ioctl, | 208 | .ioctl = ata_scsi_ioctl, |
209 | .queuecommand = ata_scsi_queuecmd, | 209 | .queuecommand = ata_scsi_queuecmd, |
210 | .eh_strategy_handler = ata_scsi_error, | ||
211 | .can_queue = ATA_DEF_QUEUE, | 210 | .can_queue = ATA_DEF_QUEUE, |
212 | .this_id = ATA_SHT_THIS_ID, | 211 | .this_id = ATA_SHT_THIS_ID, |
213 | .sg_tablesize = AHCI_MAX_SG, | 212 | .sg_tablesize = AHCI_MAX_SG, |
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 83839706f5e0..62dabf74188e 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -209,7 +209,6 @@ static struct scsi_host_template piix_sht = { | |||
209 | .name = DRV_NAME, | 209 | .name = DRV_NAME, |
210 | .ioctl = ata_scsi_ioctl, | 210 | .ioctl = ata_scsi_ioctl, |
211 | .queuecommand = ata_scsi_queuecmd, | 211 | .queuecommand = ata_scsi_queuecmd, |
212 | .eh_strategy_handler = ata_scsi_error, | ||
213 | .can_queue = ATA_DEF_QUEUE, | 212 | .can_queue = ATA_DEF_QUEUE, |
214 | .this_id = ATA_SHT_THIS_ID, | 213 | .this_id = ATA_SHT_THIS_ID, |
215 | .sg_tablesize = LIBATA_MAX_PRD, | 214 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index ef57f253031c..dfcb96f3e60c 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -294,18 +294,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
294 | if (sht->unchecked_isa_dma && privsize) | 294 | if (sht->unchecked_isa_dma && privsize) |
295 | gfp_mask |= __GFP_DMA; | 295 | gfp_mask |= __GFP_DMA; |
296 | 296 | ||
297 | /* Check to see if this host has any error handling facilities */ | ||
298 | if (!sht->eh_strategy_handler && !sht->eh_abort_handler && | ||
299 | !sht->eh_device_reset_handler && !sht->eh_bus_reset_handler && | ||
300 | !sht->eh_host_reset_handler) { | ||
301 | printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\n" | ||
302 | "ERROR: This is not a safe way to run your " | ||
303 | "SCSI host\n" | ||
304 | "ERROR: The error handling must be added to " | ||
305 | "this driver\n", sht->proc_name); | ||
306 | dump_stack(); | ||
307 | } | ||
308 | |||
309 | shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask); | 297 | shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask); |
310 | if (!shost) | 298 | if (!shost) |
311 | return NULL; | 299 | return NULL; |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index c9c001490293..5ae7613bc157 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -98,6 +98,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { | |||
98 | * It just needs the eh_timed_out hook. | 98 | * It just needs the eh_timed_out hook. |
99 | */ | 99 | */ |
100 | struct scsi_transport_template ata_scsi_transport_template = { | 100 | struct scsi_transport_template ata_scsi_transport_template = { |
101 | .eh_strategy_handler = ata_scsi_error, | ||
101 | .eh_timed_out = ata_scsi_timed_out, | 102 | .eh_timed_out = ata_scsi_timed_out, |
102 | }; | 103 | }; |
103 | 104 | ||
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c index 1364b1da9e2a..b9a3c566f833 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c | |||
@@ -143,7 +143,6 @@ static struct scsi_host_template adma_ata_sht = { | |||
143 | .name = DRV_NAME, | 143 | .name = DRV_NAME, |
144 | .ioctl = ata_scsi_ioctl, | 144 | .ioctl = ata_scsi_ioctl, |
145 | .queuecommand = ata_scsi_queuecmd, | 145 | .queuecommand = ata_scsi_queuecmd, |
146 | .eh_strategy_handler = ata_scsi_error, | ||
147 | .can_queue = ATA_DEF_QUEUE, | 146 | .can_queue = ATA_DEF_QUEUE, |
148 | .this_id = ATA_SHT_THIS_ID, | 147 | .this_id = ATA_SHT_THIS_ID, |
149 | .sg_tablesize = LIBATA_MAX_PRD, | 148 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index e9152f850003..4aabc759fcec 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -378,7 +378,6 @@ static struct scsi_host_template mv_sht = { | |||
378 | .name = DRV_NAME, | 378 | .name = DRV_NAME, |
379 | .ioctl = ata_scsi_ioctl, | 379 | .ioctl = ata_scsi_ioctl, |
380 | .queuecommand = ata_scsi_queuecmd, | 380 | .queuecommand = ata_scsi_queuecmd, |
381 | .eh_strategy_handler = ata_scsi_error, | ||
382 | .can_queue = MV_USE_Q_DEPTH, | 381 | .can_queue = MV_USE_Q_DEPTH, |
383 | .this_id = ATA_SHT_THIS_ID, | 382 | .this_id = ATA_SHT_THIS_ID, |
384 | .sg_tablesize = MV_MAX_SG_CT / 2, | 383 | .sg_tablesize = MV_MAX_SG_CT / 2, |
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index c92fbd0989bd..3a70875be8ba 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c | |||
@@ -201,7 +201,6 @@ static struct scsi_host_template nv_sht = { | |||
201 | .name = DRV_NAME, | 201 | .name = DRV_NAME, |
202 | .ioctl = ata_scsi_ioctl, | 202 | .ioctl = ata_scsi_ioctl, |
203 | .queuecommand = ata_scsi_queuecmd, | 203 | .queuecommand = ata_scsi_queuecmd, |
204 | .eh_strategy_handler = ata_scsi_error, | ||
205 | .can_queue = ATA_DEF_QUEUE, | 204 | .can_queue = ATA_DEF_QUEUE, |
206 | .this_id = ATA_SHT_THIS_ID, | 205 | .this_id = ATA_SHT_THIS_ID, |
207 | .sg_tablesize = LIBATA_MAX_PRD, | 206 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 000844a4129f..ddbc0c6dd9fe 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -111,7 +111,6 @@ static struct scsi_host_template pdc_ata_sht = { | |||
111 | .name = DRV_NAME, | 111 | .name = DRV_NAME, |
112 | .ioctl = ata_scsi_ioctl, | 112 | .ioctl = ata_scsi_ioctl, |
113 | .queuecommand = ata_scsi_queuecmd, | 113 | .queuecommand = ata_scsi_queuecmd, |
114 | .eh_strategy_handler = ata_scsi_error, | ||
115 | .can_queue = ATA_DEF_QUEUE, | 114 | .can_queue = ATA_DEF_QUEUE, |
116 | .this_id = ATA_SHT_THIS_ID, | 115 | .this_id = ATA_SHT_THIS_ID, |
117 | .sg_tablesize = LIBATA_MAX_PRD, | 116 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index 0b5446ada5ca..259c2dec4e21 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
@@ -132,7 +132,6 @@ static struct scsi_host_template qs_ata_sht = { | |||
132 | .name = DRV_NAME, | 132 | .name = DRV_NAME, |
133 | .ioctl = ata_scsi_ioctl, | 133 | .ioctl = ata_scsi_ioctl, |
134 | .queuecommand = ata_scsi_queuecmd, | 134 | .queuecommand = ata_scsi_queuecmd, |
135 | .eh_strategy_handler = ata_scsi_error, | ||
136 | .can_queue = ATA_DEF_QUEUE, | 135 | .can_queue = ATA_DEF_QUEUE, |
137 | .this_id = ATA_SHT_THIS_ID, | 136 | .this_id = ATA_SHT_THIS_ID, |
138 | .sg_tablesize = QS_MAX_PRD, | 137 | .sg_tablesize = QS_MAX_PRD, |
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index f29c3e733a00..c9333577330e 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -146,7 +146,6 @@ static struct scsi_host_template sil_sht = { | |||
146 | .name = DRV_NAME, | 146 | .name = DRV_NAME, |
147 | .ioctl = ata_scsi_ioctl, | 147 | .ioctl = ata_scsi_ioctl, |
148 | .queuecommand = ata_scsi_queuecmd, | 148 | .queuecommand = ata_scsi_queuecmd, |
149 | .eh_strategy_handler = ata_scsi_error, | ||
150 | .can_queue = ATA_DEF_QUEUE, | 149 | .can_queue = ATA_DEF_QUEUE, |
151 | .this_id = ATA_SHT_THIS_ID, | 150 | .this_id = ATA_SHT_THIS_ID, |
152 | .sg_tablesize = LIBATA_MAX_PRD, | 151 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 646756abb10e..9aa7493ea146 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -281,7 +281,6 @@ static struct scsi_host_template sil24_sht = { | |||
281 | .name = DRV_NAME, | 281 | .name = DRV_NAME, |
282 | .ioctl = ata_scsi_ioctl, | 282 | .ioctl = ata_scsi_ioctl, |
283 | .queuecommand = ata_scsi_queuecmd, | 283 | .queuecommand = ata_scsi_queuecmd, |
284 | .eh_strategy_handler = ata_scsi_error, | ||
285 | .can_queue = ATA_DEF_QUEUE, | 284 | .can_queue = ATA_DEF_QUEUE, |
286 | .this_id = ATA_SHT_THIS_ID, | 285 | .this_id = ATA_SHT_THIS_ID, |
287 | .sg_tablesize = LIBATA_MAX_PRD, | 286 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index eb3cf5b534dc..3097821688dc 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c | |||
@@ -87,7 +87,6 @@ static struct scsi_host_template sis_sht = { | |||
87 | .name = DRV_NAME, | 87 | .name = DRV_NAME, |
88 | .ioctl = ata_scsi_ioctl, | 88 | .ioctl = ata_scsi_ioctl, |
89 | .queuecommand = ata_scsi_queuecmd, | 89 | .queuecommand = ata_scsi_queuecmd, |
90 | .eh_strategy_handler = ata_scsi_error, | ||
91 | .can_queue = ATA_DEF_QUEUE, | 90 | .can_queue = ATA_DEF_QUEUE, |
92 | .this_id = ATA_SHT_THIS_ID, | 91 | .this_id = ATA_SHT_THIS_ID, |
93 | .sg_tablesize = ATA_MAX_PRD, | 92 | .sg_tablesize = ATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index a20bc8154753..e15c693e0539 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
@@ -290,7 +290,6 @@ static struct scsi_host_template k2_sata_sht = { | |||
290 | .name = DRV_NAME, | 290 | .name = DRV_NAME, |
291 | .ioctl = ata_scsi_ioctl, | 291 | .ioctl = ata_scsi_ioctl, |
292 | .queuecommand = ata_scsi_queuecmd, | 292 | .queuecommand = ata_scsi_queuecmd, |
293 | .eh_strategy_handler = ata_scsi_error, | ||
294 | .can_queue = ATA_DEF_QUEUE, | 293 | .can_queue = ATA_DEF_QUEUE, |
295 | .this_id = ATA_SHT_THIS_ID, | 294 | .this_id = ATA_SHT_THIS_ID, |
296 | .sg_tablesize = LIBATA_MAX_PRD, | 295 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 801ac3787d5d..a669d0589889 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -182,7 +182,6 @@ static struct scsi_host_template pdc_sata_sht = { | |||
182 | .name = DRV_NAME, | 182 | .name = DRV_NAME, |
183 | .ioctl = ata_scsi_ioctl, | 183 | .ioctl = ata_scsi_ioctl, |
184 | .queuecommand = ata_scsi_queuecmd, | 184 | .queuecommand = ata_scsi_queuecmd, |
185 | .eh_strategy_handler = ata_scsi_error, | ||
186 | .can_queue = ATA_DEF_QUEUE, | 185 | .can_queue = ATA_DEF_QUEUE, |
187 | .this_id = ATA_SHT_THIS_ID, | 186 | .this_id = ATA_SHT_THIS_ID, |
188 | .sg_tablesize = LIBATA_MAX_PRD, | 187 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index 513dd78ea6fe..15f81bfc30f0 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c | |||
@@ -81,7 +81,6 @@ static struct scsi_host_template uli_sht = { | |||
81 | .name = DRV_NAME, | 81 | .name = DRV_NAME, |
82 | .ioctl = ata_scsi_ioctl, | 82 | .ioctl = ata_scsi_ioctl, |
83 | .queuecommand = ata_scsi_queuecmd, | 83 | .queuecommand = ata_scsi_queuecmd, |
84 | .eh_strategy_handler = ata_scsi_error, | ||
85 | .can_queue = ATA_DEF_QUEUE, | 84 | .can_queue = ATA_DEF_QUEUE, |
86 | .this_id = ATA_SHT_THIS_ID, | 85 | .this_id = ATA_SHT_THIS_ID, |
87 | .sg_tablesize = LIBATA_MAX_PRD, | 86 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index de4e0eb224bb..17aefab5f42f 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c | |||
@@ -94,7 +94,6 @@ static struct scsi_host_template svia_sht = { | |||
94 | .name = DRV_NAME, | 94 | .name = DRV_NAME, |
95 | .ioctl = ata_scsi_ioctl, | 95 | .ioctl = ata_scsi_ioctl, |
96 | .queuecommand = ata_scsi_queuecmd, | 96 | .queuecommand = ata_scsi_queuecmd, |
97 | .eh_strategy_handler = ata_scsi_error, | ||
98 | .can_queue = ATA_DEF_QUEUE, | 97 | .can_queue = ATA_DEF_QUEUE, |
99 | .this_id = ATA_SHT_THIS_ID, | 98 | .this_id = ATA_SHT_THIS_ID, |
100 | .sg_tablesize = LIBATA_MAX_PRD, | 99 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index cecc1f76256b..9646c3932129 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -263,7 +263,6 @@ static struct scsi_host_template vsc_sata_sht = { | |||
263 | .name = DRV_NAME, | 263 | .name = DRV_NAME, |
264 | .ioctl = ata_scsi_ioctl, | 264 | .ioctl = ata_scsi_ioctl, |
265 | .queuecommand = ata_scsi_queuecmd, | 265 | .queuecommand = ata_scsi_queuecmd, |
266 | .eh_strategy_handler = ata_scsi_error, | ||
267 | .can_queue = ATA_DEF_QUEUE, | 266 | .can_queue = ATA_DEF_QUEUE, |
268 | .this_id = ATA_SHT_THIS_ID, | 267 | .this_id = ATA_SHT_THIS_ID, |
269 | .sg_tablesize = LIBATA_MAX_PRD, | 268 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 5f0fdfb2618c..1c75646f9689 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1537,8 +1537,8 @@ int scsi_error_handler(void *data) | |||
1537 | * what we need to do to get it up and online again (if we can). | 1537 | * what we need to do to get it up and online again (if we can). |
1538 | * If we fail, we end up taking the thing offline. | 1538 | * If we fail, we end up taking the thing offline. |
1539 | */ | 1539 | */ |
1540 | if (shost->hostt->eh_strategy_handler) | 1540 | if (shost->transportt->eh_strategy_handler) |
1541 | shost->hostt->eh_strategy_handler(shost); | 1541 | shost->transportt->eh_strategy_handler(shost); |
1542 | else | 1542 | else |
1543 | scsi_unjam_host(shost); | 1543 | scsi_unjam_host(shost); |
1544 | 1544 | ||
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index 93449a1a0065..0b49ff78efc1 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/dma-mapping.h> | ||
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
15 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
@@ -619,9 +620,9 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
619 | pci_set_master(pdev); | 620 | pci_set_master(pdev); |
620 | 621 | ||
621 | #ifdef USE_64BIT_DMA | 622 | #ifdef USE_64BIT_DMA |
622 | ret = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); | 623 | ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK); |
623 | if (!ret) { | 624 | if (!ret) { |
624 | ret = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); | 625 | ret = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); |
625 | if (ret < 0) { | 626 | if (ret < 0) { |
626 | printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA " | 627 | printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA " |
627 | "for consistent allocations\n", | 628 | "for consistent allocations\n", |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 495db5755df9..5cf2b80add7a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard | 28 | 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard |
29 | 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes | 29 | 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes |
30 | wants to send >2000 bytes. | 30 | wants to send >2000 bytes. |
31 | 2006-04-10 v0.4.2 fixed two array overrun errors :-/ | ||
31 | 32 | ||
32 | Work sponsored by: Sigos GmbH, Germany <info@sigos.de> | 33 | Work sponsored by: Sigos GmbH, Germany <info@sigos.de> |
33 | 34 | ||
@@ -582,14 +583,14 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
582 | portdata = usb_get_serial_port_data(port); | 583 | portdata = usb_get_serial_port_data(port); |
583 | 584 | ||
584 | /* Do indat endpoints first */ | 585 | /* Do indat endpoints first */ |
585 | for (j = 0; j <= N_IN_URB; ++j) { | 586 | for (j = 0; j < N_IN_URB; ++j) { |
586 | portdata->in_urbs[j] = option_setup_urb (serial, | 587 | portdata->in_urbs[j] = option_setup_urb (serial, |
587 | port->bulk_in_endpointAddress, USB_DIR_IN, port, | 588 | port->bulk_in_endpointAddress, USB_DIR_IN, port, |
588 | portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); | 589 | portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); |
589 | } | 590 | } |
590 | 591 | ||
591 | /* outdat endpoints */ | 592 | /* outdat endpoints */ |
592 | for (j = 0; j <= N_OUT_URB; ++j) { | 593 | for (j = 0; j < N_OUT_URB; ++j) { |
593 | portdata->out_urbs[j] = option_setup_urb (serial, | 594 | portdata->out_urbs[j] = option_setup_urb (serial, |
594 | port->bulk_out_endpointAddress, USB_DIR_OUT, port, | 595 | port->bulk_out_endpointAddress, USB_DIR_OUT, port, |
595 | portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); | 596 | portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index f87c0171f4ec..9060e7137441 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -961,7 +961,7 @@ config FB_ATY128 | |||
961 | 961 | ||
962 | config FB_ATY | 962 | config FB_ATY |
963 | tristate "ATI Mach64 display support" if PCI || ATARI | 963 | tristate "ATI Mach64 display support" if PCI || ATARI |
964 | depends on FB | 964 | depends on FB && !SPARC32 |
965 | select FB_CFB_FILLRECT | 965 | select FB_CFB_FILLRECT |
966 | select FB_CFB_COPYAREA | 966 | select FB_CFB_COPYAREA |
967 | select FB_CFB_IMAGEBLIT | 967 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index b39e72d5413b..d9d7d3c4cae2 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -3400,7 +3400,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi | |||
3400 | struct atyfb_par *par; | 3400 | struct atyfb_par *par; |
3401 | int i, rc = -ENOMEM; | 3401 | int i, rc = -ENOMEM; |
3402 | 3402 | ||
3403 | for (i = ARRAY_SIZE(aty_chips); i >= 0; i--) | 3403 | for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--) |
3404 | if (pdev->device == aty_chips[i].pci_id) | 3404 | if (pdev->device == aty_chips[i].pci_id) |
3405 | break; | 3405 | break; |
3406 | 3406 | ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 944855b3e4af..8d8eadb64853 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -435,6 +435,11 @@ int fb_prepare_logo(struct fb_info *info, int rotate) | |||
435 | depth = info->var.green.length; | 435 | depth = info->var.green.length; |
436 | } | 436 | } |
437 | 437 | ||
438 | if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) { | ||
439 | /* assume console colormap */ | ||
440 | depth = 4; | ||
441 | } | ||
442 | |||
438 | if (depth >= 8) { | 443 | if (depth >= 8) { |
439 | switch (info->fix.visual) { | 444 | switch (info->fix.visual) { |
440 | case FB_VISUAL_TRUECOLOR: | 445 | case FB_VISUAL_TRUECOLOR: |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 8982e540214c..b0b9acfdd430 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -57,7 +57,7 @@ static unsigned short *pmi_base = NULL; | |||
57 | static void (*pmi_start)(void); | 57 | static void (*pmi_start)(void); |
58 | static void (*pmi_pal)(void); | 58 | static void (*pmi_pal)(void); |
59 | static int depth; | 59 | static int depth; |
60 | 60 | static int vga_compat; | |
61 | /* --------------------------------------------------------------------- */ | 61 | /* --------------------------------------------------------------------- */ |
62 | 62 | ||
63 | static int vesafb_pan_display(struct fb_var_screeninfo *var, | 63 | static int vesafb_pan_display(struct fb_var_screeninfo *var, |
@@ -83,9 +83,10 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, | |||
83 | static void vesa_setpalette(int regno, unsigned red, unsigned green, | 83 | static void vesa_setpalette(int regno, unsigned red, unsigned green, |
84 | unsigned blue) | 84 | unsigned blue) |
85 | { | 85 | { |
86 | int shift = 16 - depth; | ||
87 | |||
86 | #ifdef __i386__ | 88 | #ifdef __i386__ |
87 | struct { u_char blue, green, red, pad; } entry; | 89 | struct { u_char blue, green, red, pad; } entry; |
88 | int shift = 16 - depth; | ||
89 | 90 | ||
90 | if (pmi_setpal) { | 91 | if (pmi_setpal) { |
91 | entry.red = red >> shift; | 92 | entry.red = red >> shift; |
@@ -101,14 +102,20 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green, | |||
101 | "d" (regno), /* EDX */ | 102 | "d" (regno), /* EDX */ |
102 | "D" (&entry), /* EDI */ | 103 | "D" (&entry), /* EDI */ |
103 | "S" (&pmi_pal)); /* ESI */ | 104 | "S" (&pmi_pal)); /* ESI */ |
104 | } else { | 105 | return; |
105 | /* without protected mode interface, try VGA registers... */ | 106 | } |
107 | #endif | ||
108 | |||
109 | /* | ||
110 | * without protected mode interface and if VGA compatible, | ||
111 | * try VGA registers... | ||
112 | */ | ||
113 | if (vga_compat) { | ||
106 | outb_p(regno, dac_reg); | 114 | outb_p(regno, dac_reg); |
107 | outb_p(red >> shift, dac_val); | 115 | outb_p(red >> shift, dac_val); |
108 | outb_p(green >> shift, dac_val); | 116 | outb_p(green >> shift, dac_val); |
109 | outb_p(blue >> shift, dac_val); | 117 | outb_p(blue >> shift, dac_val); |
110 | } | 118 | } |
111 | #endif | ||
112 | } | 119 | } |
113 | 120 | ||
114 | static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, | 121 | static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, |
@@ -214,6 +221,7 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
214 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) | 221 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) |
215 | return -ENODEV; | 222 | return -ENODEV; |
216 | 223 | ||
224 | vga_compat = (screen_info.capabilities & 2) ? 0 : 1; | ||
217 | vesafb_fix.smem_start = screen_info.lfb_base; | 225 | vesafb_fix.smem_start = screen_info.lfb_base; |
218 | vesafb_defined.bits_per_pixel = screen_info.lfb_depth; | 226 | vesafb_defined.bits_per_pixel = screen_info.lfb_depth; |
219 | if (15 == vesafb_defined.bits_per_pixel) | 227 | if (15 == vesafb_defined.bits_per_pixel) |
@@ -318,6 +326,12 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
318 | } | 326 | } |
319 | } | 327 | } |
320 | 328 | ||
329 | if (vesafb_defined.bits_per_pixel == 8 && !pmi_setpal && !vga_compat) { | ||
330 | printk(KERN_WARNING "vesafb: hardware palette is unchangeable,\n" | ||
331 | " colors may be incorrect\n"); | ||
332 | vesafb_fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; | ||
333 | } | ||
334 | |||
321 | vesafb_defined.xres_virtual = vesafb_defined.xres; | 335 | vesafb_defined.xres_virtual = vesafb_defined.xres; |
322 | vesafb_defined.yres_virtual = vesafb_fix.smem_len / vesafb_fix.line_length; | 336 | vesafb_defined.yres_virtual = vesafb_fix.smem_len / vesafb_fix.line_length; |
323 | if (ypan && vesafb_defined.yres_virtual > vesafb_defined.yres) { | 337 | if (ypan && vesafb_defined.yres_virtual > vesafb_defined.yres) { |
@@ -354,7 +368,8 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
354 | printk(KERN_INFO "vesafb: %s: " | 368 | printk(KERN_INFO "vesafb: %s: " |
355 | "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", | 369 | "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", |
356 | (vesafb_defined.bits_per_pixel > 8) ? | 370 | (vesafb_defined.bits_per_pixel > 8) ? |
357 | "Truecolor" : "Pseudocolor", | 371 | "Truecolor" : (vga_compat || pmi_setpal) ? |
372 | "Pseudocolor" : "Static Pseudocolor", | ||
358 | screen_info.rsvd_size, | 373 | screen_info.rsvd_size, |
359 | screen_info.red_size, | 374 | screen_info.red_size, |
360 | screen_info.green_size, | 375 | screen_info.green_size, |